diff --git a/.github/workflows/.notify.yml b/.github/workflows/.notify.yml index dfd308f2040..2e5aeef61a2 100644 --- a/.github/workflows/.notify.yml +++ b/.github/workflows/.notify.yml @@ -9,20 +9,34 @@ on: job_result: required: true type: string + secrets: + SLACK_BOT_TOKEN: + required: false jobs: notify_slack: runs-on: ubuntu-latest + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} steps: - name: Notify slack fail - if: ${{ inputs.job_result == 'failure' && github.repository == 'OpenSIPS/opensips' }} - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1 + if: ${{ inputs.job_result == 'failure' && github.repository == 'OpenSIPS/opensips' && env.SLACK_BOT_TOKEN != '' }} + uses: slackapi/slack-github-action@v3.0.3 with: - channel: devel - status: FAILED - color: danger + method: chat.postMessage + token: ${{ env.SLACK_BOT_TOKEN }} + payload: | + channel: devel + text: ":x: ${{ inputs.job_name }} failed in ${{ github.repository }}" + blocks: + - type: section + text: + type: mrkdwn + text: ":x: *${{ inputs.job_name }}* failed in *${{ github.repository }}*" + - type: context + elements: + - type: mrkdwn + text: "<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Open this run in GitHub Actions>" - name: Post Fail if: ${{ inputs.job_result == 'failure' }} diff --git a/.github/workflows/.rtp.io.yml b/.github/workflows/.rtp.io.yml deleted file mode 100644 index fc139b3baa3..00000000000 --- a/.github/workflows/.rtp.io.yml +++ /dev/null @@ -1,285 +0,0 @@ -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'`" - _BUILD_OS="`echo ${BUILD_OS} | 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' }} - permissions: - packages: read - 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: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - 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'`" - _BUILD_OS="`echo ${BUILD_OS} | 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 2f60a309818..8f4238f4534 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -66,7 +66,7 @@ jobs: apt-get install -y git lsb-release gnupg2 wget # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: recursive @@ -84,4 +84,6 @@ jobs: with: job_name: "Main CI" job_result: ${{ needs.build.result }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} if: ${{ always() }} diff --git a/.github/workflows/multiarch.yml b/.github/workflows/multiarch.yml index 654dc07059d..5bd5d22013c 100644 --- a/.github/workflows/multiarch.yml +++ b/.github/workflows/multiarch.yml @@ -38,13 +38,13 @@ jobs: apt-get install -y git lsb-release gnupg2 wget # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: recursive # Cache the compiler cache - name: Cache the compiler cache - uses: actions/cache@v4 + uses: actions/cache@v5 if: endsWith(matrix.compiler, '-qemu-cross') with: path: ccache @@ -76,4 +76,6 @@ jobs: with: job_name: "Multi-Architecture Build" job_result: ${{ needs.build_multiarch.result }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} if: ${{ always() }} diff --git a/.github/workflows/rtp.io.yml b/.github/workflows/rtp.io.yml deleted file mode 100644 index 5d252f59847..00000000000 --- a/.github/workflows/rtp.io.yml +++ /dev/null @@ -1,140 +0,0 @@ -# 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] - - all_done: - needs: build_test_rtp_io_dock - uses: ./.github/workflows/.notify.yml - with: - job_name: "rtp.io" - job_result: ${{ needs.build_test_rtp_io_dock.result }} - if: ${{ always() }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 40cc6026071..141b2160bc9 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -13,7 +13,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v4 + - uses: actions/stale@v10 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'Any updates here? No progress has been made in the last 15 days, marking as stale. Will close this issue if no further updates are made in the next 30 days.' diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index 7351a7fc28c..ecc84f69918 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -68,12 +68,12 @@ jobs: apt-get install -y git lsb-release gnupg2 wget # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: recursive - name: Cache the compiler cache - uses: actions/cache@v4 + uses: actions/cache@v5 if: endsWith(matrix.compiler, '-qemu-cross') with: path: ccache @@ -113,7 +113,7 @@ jobs: run: script -e unit_tests.log -c 'sh -x scripts/build/do_build.sh DEFS_EXTRA_OPTS="-DUNIT_TESTS -fPIE -fPIC"' - name: Collect test logs - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: unit_tests-logs_${{ matrix.os }}_${{ matrix.compiler }} path: | @@ -125,4 +125,6 @@ jobs: with: job_name: "Unit Tests" job_result: ${{ needs.build_and_test.result }} + secrets: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} if: ${{ always() }} diff --git a/.gitignore b/.gitignore index fc30c3a7291..2387d942379 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,8 @@ cscope* /.svnrevision /.gitrevision -# /doc/ -/doc/database +# /docs/ +/docs/database # /menuconfig/ /menuconfig/configure @@ -34,4 +34,4 @@ core.* out log *.log -*.html \ No newline at end of file +*.html diff --git a/.lgtm.yml b/.lgtm.yml index 7d584c77283..87a6605e453 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -22,7 +22,7 @@ extraction: - libldap2-dev - libcurl4-gnutls-dev - libgeoip-dev - - libpcre3-dev + - libpcre2-dev - libmemcached-dev - libmicrohttpd-dev - librabbitmq-dev @@ -33,6 +33,7 @@ extraction: before_index: - export FASTER=1 - export NICER=0 + - export PCRE_LIB=pcre index: build_command: make exclude_modules="db_oracle osp sngtc cachedb_cassandra cachedb_couchbase cachedb_mongodb auth_jwt" all diff --git a/ChangeLog b/ChangeLog index 163095ab6fd..88877112cb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1979 @@ +=========================== Release 3.6.7 ============================== + +2026-06-17 Liviu Chircu + * [85207da3bb] : + + cfgutils: Fix SHM leak with re.subst and $shv() variables + + The re.subst transformation stores replacement-side PV specs by value inside + its cached subst_expr. When the cached expression is replaced, the embedded + $shv() spec could leave behind its shared-memory pvv buffer. + + This can be triggered with a dynamic substitution expression such as: + + $var(re) = "/^s=before/s=$shv(voip_sdp_session)\r/g"; + $var(sdp) = $(var(sdp){re.subst,$var(re)}); + + Track pvv ownership, mark $shv() buffers as SHM-owned, and release them when + freeing cached re.subst replacement specs. + + Fixes #3872 + + (cherry picked from commit 09ec06179c8c40d034e8eb27fe814f15418f58b6) + + +2026-06-17 Bogdan-Andrei Iancu + * [d967744fb8] : + + [clusterer] fix stack overflow in receiving MI params over BIN + + Reported by Hu Xinyao ( huxinyao0011@gmail.com ) + https://github.com/OpenSIPS/opensips/security/advisories/GHSA-p96q-v5qf-w24h + + (cherry picked from commit 94bd74a651ca72d670678b35b0306e2c5c6efb27) + + +2026-06-17 Bogdan-Andrei Iancu + * [3ec7d0c30e] : + + [msilo] fix malformed body for non plain/text content + + When sending stored messaged, do not attempt to add any extra text info to the body, unless is text/plain. Any other type, like cpim, will result into a broken body (as syntax, as cpim is xml) + Reported by Robert Dyck + + (cherry picked from commit 73115759a1570560b737862e48fa1479e6e161ff) + + +2026-06-16 Stefan Darius + * [0fa1146886] : + + docs: add generated module README files for 3.6 (#3927) + + * docs: add generated README.md files + + * docs: add generated manual [skip ci] + +2026-06-16 Razvan Crainea + * [ec25c321d0] : + + docs: rename doc directory to docs [skip ci] + + +2026-06-15 Liviu Chircu + * [1703868201] : + + registrar: Add few GRUU unit tests for ;+sip.instance= + + Follow-up of #3886 + + (cherry picked from commit 303888a89552394ab48b9efbccb451261d4972b9) + + +2026-06-15 Damien Sandras + * [04d5367ab4] : + + opensips: Fix SIP Instance according to RFC 5626 + + It should be surrounded by angle brackets following section 4.1 from RFC + 5626: + + [RFC3840] defines equality rules for callee capabilities parameters, + and according to that specification, the "sip.instance" media feature + tag will be compared by case- sensitive string comparison. This means + that the URN will be encapsulated by angle brackets ("<" and ">") when + it is placed within the quoted string value of the "+sip.instance" + Contact header field parameter. + + +2026-06-15 Bogdan-Andrei Iancu + * [f8935fe12a] : + + fixed stack buffer overflow in $(cT[*]) pvar + + Credits for reporting and fixing go to Yiyi Wang, Tsinghua University (wangyiyi25@mails.tsinghua.edu.cn) + https://github.com/OpenSIPS/opensips/security/advisories/GHSA-w522-9gcp-274p + + (cherry picked from commit fbef00a7bb4dfc5f0f24528d123beac128462827) + + +2026-06-15 Razvan Crainea + * [5a91d8ac1d] : + + proto_bin: validate stream packet lengths + + Reject BIN packets with advertised sizes outside the protocol bounds before marking the request complete. This prevents zero-length frames from being repeatedly dispatched without consuming input. + + Reported-by: Hu Xinyao (@ZwCrazyThursday) + (cherry picked from commit 6caec74f56623f13bf503dabccc0439b5bc84a79) + + +2026-06-15 Razvan Crainea + * [584f826db1] : + + rtp_relay: parse reply To header + + (cherry picked from commit 2daa6238f0b180cb6d62643e20afd627ae15b574) + + +2026-06-15 Bogdan-Andrei Iancu + * [3925140275] : + + [stir-shaken] fix heap-buffer-overflow in stir_shaken_disengagement() + + Credits for reporting and fixing go to Yukimura Aneha from BroadBand Security, Inc (yuk_aneha@bbsec.co.jp) + https://github.com/OpenSIPS/opensips/security/advisories/GHSA-qr87-6xwg-29p3 + + (cherry picked from commit 5bd393d0151e4636cdfe78f4317ecf3ac447dd9a) + + +2026-06-14 OpenSIPS + * [a686b62ae1] : + + Rebuild documentation + + +2026-06-12 Bogdan Andrei IANCU + * [382d02be28] : + + Merge pull request #3920 from ovidiusas/master_in_dialog_PRACK + + dialog: handle late PRACK received in conversation + (cherry picked from commit d8586fa694d924e465fa0599a78cb71dbea14e02) + + +2026-06-11 Bogdan-Andrei Iancu + * [b17f7fda5f] : + + [pua_dialoginfo] fix some backport syntax issues + + related to prev commit + + +2026-06-11 Bogdan Andrei IANCU + * [3489076916] : + + Merge pull request #3915 from NormB/fix/pua-dialoginfo-early-lifetime + + pua_dialoginfo: fix early state lifetime and clean up dangling early branches + + (cherry picked from commit 6755c14afc60f3bfc92e06d825742d6b6ca9a013) + + +2026-06-10 Bogdan-Andrei Iancu + * [0430f1d6c3] : + + fix rewrite_ruri() + RW_RURI_PREFIX with empty string prefix + + If an empty string prefix was provided, a malformed URI was generated (like "sip:@host.com") + Reported by @thuroc and @FlyingDutchfrog + Fixes #3691 + + (cherry picked from commit 4ddb8f0ed93e099ecd548a53d2219fd38fe2f246) + + +2026-06-10 Bogdan-Andrei Iancu + * [457f09d0ea] : + + [uac_registrant] fix extracting the min-expires upon 423 reply + + This is a regression due to 2cd2a45a025aac256d758d3bac44b3d35eb4ab90 + Reported by @sindy39 + Fixes #3910 + + (cherry picked from commit ee7af98143e4d970f3ca64c2c6f51b4ff443814f) + + +2026-06-09 Razvan Crainea + * [f372f2f209] : + + github: inherit SLACK token in reusable workflows + + (cherry picked from commit c7528472d4290f0b84fd68bfb914c326ecbd56ce) + + +2026-06-09 Bogdan Andrei IANCU + * [3ef7955ae1] : + + Merge pull request #3912 from sippy/pr_rtpproxy_nsock_drain_3.6 + + rtpproxy: drain timeout notification sockets (merge of #3911 into 3.6) + +2026-06-08 Maksym Sobolyev + * [1dc7d08617] : + + rtpproxy: drain timeout notification sockets + + RTPProxy may keep the notification connection open while writing a burst of + timeout events. The rtpproxy notification callback only performed a single + read per reactor wakeup, so already-buffered notifications could be left + pending with no further event to wake the process. + + Set notification sockets nonblocking and drain them until EAGAIN, preserving + partial commands between callbacks. Also centralize notification connection + cleanup so error, EOF and handler failure paths consistently unregister the fd, + free pending data and close the socket. + + +2026-06-08 Razvan Crainea + * [dc328f2c9b] : + + github: migrate slack notify to official action + + (cherry picked from commit fcf1668c5b50966eb2e18e13a241936db6370fbc) + + +2026-06-07 OpenSIPS + * [53d0e33329] : + + Rebuild documentation + + +2026-06-05 Razvan Crainea + * [d6a21d5436] : + + b2b_sca: fix potential heap/buffer overflow in uri + + If the display name needs to be escaped, we need way more space to fit + it, and if we don't allocate that much, it can lead to mem corruption. + + Credits go to R4mbb of KRsecurity() for reporting + it and providing a fix. + + (cherry picked from commit 8f1be98346769100cbd43cc4124b24cf24a6b0d1) + + +2026-06-05 Ovidiu Sas + * [b3953c20c4] : + + core: implement FAST_LOCK for aarch64 (#3892) + + (cherry picked from commit ecc8dbb5bbf98ba40e04cce3933c944358366bc8) + + +2026-06-04 Bogdan-Andrei Iancu + * [2d8f046871] : + + [uac_registrant] store the configured "expires" and use it for each re-REGISTER + + ...in order to avoid decreasing it if the registar is reducing it. + Reported by @sindy39 + Fixes #3659 + + (cherry picked from commit 2cd2a45a025aac256d758d3bac44b3d35eb4ab90) + + +2026-06-04 Bogdan-Andrei Iancu + * [4f6c86c0ef] : + + [b2b_entities] avoid sending 408 on a completed transaction + + upon entities cleanup, is the UAS/UPDATE transactions are completed, just unref without sending a 408. + Reported by @davegreeko2023 + Fixes #3899 + + (cherry picked from commit 6ab5ee16460a1ff74a328ff39b0eb39195a190b8) + + +2026-06-03 Razvan Crainea + * [c2a655a27b] : + + tls_wolfssl: align wolfSSL shm allocations + + wolfSSL may require allocations aligned beyond the default shm allocator guarantee on builds that enable aligned cryptographic data. Keep the existing allocator path unchanged unless wolfSSL advertises such a requirement, and use an aligned shm-backed wrapper only then. + + The wrapper follows the issue patch by over-allocating, storing the raw shm pointer before the aligned address, and using memmove after shm_realloc when the aligned offset changes so data is preserved before writing the back-pointer. + + Reported-and-tested-by: @volga629-1 + + Fixed-by: @NormB + + Suggested-by: @space88man + + Closes #3814 + + +2026-06-03 Razvan Crainea + * [0a078e4a0a] : + + rtp_relay: clarify peer pvar scope + + Thanks to @sindy39 for the suggestion. + + Refs #3884 + + +2026-06-02 Razvan Crainea + * [b596d3faf5] : + + dialog: avoid clearing locked_by after final db cleanup unref + + The DB cleanup path temporarily sets locked_by, calls + unref_dlg_unsafe(), and then clears the field again. If that unref drops + the last reference, the dialog is destroyed before the final assignment, + so the reset writes into freed memory. Only clear locked_by when another + reference still exists. + + (cherry picked from commit fbf3c0bd02aff11d35acab59d6f478aa639e3ce6) + + +2026-06-02 Razvan Crainea + * [5cce875c73] : + + rtp_relay: use the opposite tag when creating the peer leg in request + + When request_route lazily creates the peer leg for an unestablished RTP + relay session, the local leg is already matched by the From tag. The + peer leg therefore needs the opposite tag (To tag) so the internal leg + map stays consistent. + + Thanks to @sindy39 on GitHub for reporting it in #3884. + + (cherry picked from commit aca9a9a2b81e79c7dc15d002bc8d1aa3f474bd8d) + + +2026-05-31 OpenSIPS + * [b20ae9e460] : + + Rebuild documentation + + +2026-05-29 Razvan Crainea + * [d6427ec4bc] : + + dialog: fix stats transitions for replicated dlgs + + (cherry picked from commit 4857fbd04e2a95d9c594f07935d84d914aff5077) + + +2026-05-27 Liviu Chircu + * [5dbbd997f7] : + + registrar: Honor pn_refresh_timeout for PN branch waits + + pn_refresh_timeout was only limiting the EBR subscription lifetime. For + initial INVITEs to PN-only contacts, the TM phony branch created by + t_wait_for_new_branches() could remain pending until fr_inv_timeout + after the PN refresh window had already expired. + + Add opt-in EBR expiry notifications for function-based NOTIFY subs and + use them from registrar PN handling. On subscription expiry, release + the associated TM phony branch through a new TM bind which can resolve + the EBR remote transaction reference and generate a local 408 for that + branch. Matching contact updates continue to inject the refreshed + branch as before. + + This caps the PN-only INVITE wait at pn_refresh_timeout without + shortening timers for real branches in mixed lookups. + + +2026-05-26 Bogdan-Andrei Iancu + * [b10c6af6c8] : + + [drouting] fix hashing the carrier sort algorithm + + Credits go to @Sippy-Soft + Fixes #3897 + + (cherry picked from commit 86742f5f88d04bf75c4f24b3759ebd6026e3a85c) + + +2026-05-26 Bogdan-Andrei Iancu + * [70e8fc0b02] : + + Merge branch 'NormB-fix/dialog-cluster-sipi-crash' + + (cherry picked from commit 3b307e6057e04e2422f40f25d66305e8eba08fbb) + + +2026-05-26 Razvan Crainea + * [1dffc0d4b0] : + + rtpproxy: guard for null message in command + + (cherry picked from commit d3b092457414dcda7a80676e14e4958863b2b29f) + + +2026-05-24 OpenSIPS + * [83ca84c181] : + + Rebuild documentation + + +=========================== Release 3.6.6 ============================== + +2026-05-20 Razvan Crainea + * [6542037c93] : + + bin: fix packet size log format + + (cherry picked from commit ab8a84249c28a369d639fbd69bf693cd158819f1) + + +2026-05-20 Razvan Crainea + * [af97ed5d75] : + + build: use -Wno-atomic-alignment only for clang + + (cherry picked from commit fac6a9f17b9fa5f0a4db29971a3971e7faf7a432) + (cherry picked from commit 510ce80f081a1b645a814bbe1ec26f080c95884b) + + +2026-05-20 Razvan Crainea + * [d4d7e2a937] : + + bin: use portable size print + + (cherry picked from commit 13827e1a941201bc41f79f7edabe1ad6f2a534a4) + (cherry picked from commit f9ee95a8e9950171ef4ff813c8f0333e8ba09336) + + +2026-05-20 Razvan Crainea + * [520c36ab53] : + + rtpengine: properly reset pvar + + (cherry picked from commit d08cfc5104c0d85fb5ad5c0ca6424930d8595635) + (cherry picked from commit a6f2cf7b874a726aa9c33453f4d6c442558524c2) + + +2026-05-20 Razvan Crainea + * [72a9d6bbcc] : + + httpd: fix return value + + +2026-05-19 Razvan Crainea + * [b23299a835] : + + compression: fix decompression bounds checks + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit e78608619b9ebe7454e0c9ce43e5d56762f9c47a) + + +2026-05-19 Razvan Crainea + * [dc241fb006] : + + proto_smpp: harden SMPP string bounds + + Reported-by: Haruto Kimura (Stella) + Reported-by: jming912 + Fixes #3847 + Fixes #3848 + + (cherry picked from commit ad715b5dc1d5e7aecf27e11839f99d510bdeaea6) + + +2026-05-19 Razvan Crainea + * [aa3b1bec04] : + + usrloc: fix cachedb contact match key size + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 47e027c038d1c699bb1e5ed33731054f58aeffcc) + + +2026-05-19 Razvan Crainea + * [33f4682915] : + + bin: validate received packet bounds + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 76b61fefdb0ae125583030be5f999b74756a056c) + + +2026-05-19 Razvan Crainea + * [ba31dfae3c] : + + pi_http: avoid POST argument OOB access + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 3ac1244805d96ab5e717a9c5e6c1c3af453efb18) + + +2026-05-19 Razvan Crainea + * [245c8ad107] : + + sdp: bound parsed SDP line count + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 34d244171aa0aba7892c5567708cd4179aebb341) + + +2026-05-19 Razvan Crainea + * [85da0c33a1] : + + registrar: dinamically grow temporary GRUU buffer + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 7a51936e08705eec202be5dced2ab3c22bc9fd14) + + +2026-05-19 Razvan Crainea + * [570076257e] : + + aaa_diameter: bound accounting AVP collection + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 9c2c5ff8ecb3e43d2f0e495f26d62b99cd04b0fb) + + +2026-05-19 Razvan Crainea + * [83c02c65d4] : + + clusterer: bound topology packet counts + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 93c286af60ad8101d56198d5a0e4a6e6efbe5e52) + + +2026-05-19 Razvan Crainea + * [8fe61f9a93] : + + b2b_logic: stop oversized Replaces rewrite + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 381604899574713d1406210b1b066063a16216ee) + + +2026-05-19 Razvan Crainea + * [e7a0377d17] : + + b2b_entities: bound generated RAck headers + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 7761e3c1e9039d1b6e37ed9c20ee74700a7137a9) + + +2026-05-19 Razvan Crainea + * [9148a16f6b] : + + topology_hiding: bound encoded contact lengths + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 4195754ca32c9d7e639a334d8d0550b3c30aa826) + + +2026-05-19 Razvan Crainea + * [11ab0a0953] : + + rr: bound maddr URI construction + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 02ca6f06492fa92d5ae7583908e84b682a0c34a3) + + +2026-05-19 Razvan Crainea + * [789281285a] : + + proto_hep: reject HEPv3 frames without payload + + Treat HEPv3 packets without a payload chunk as malformed before + callbacks or SIP message parsing can consume the zero-initialized + payload pointer and length. Also route UDP unpacking failures through + the existing cleanup path. + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 8fd2109b06b9841627965c42852efdc47c8cf5b4) + + +2026-05-19 Razvan Crainea + * [11a09c71f5] : + + proto_hep: validate HEPv3 chunk lengths + + Reject malformed HEPv3 packet and chunk lengths before parsing + chunk-specific data. This prevents zero-length chunks from stalling the + parser loop and avoids length underflow while walking the advertised + packet body. + + Reported-by: Haruto Kimura (Stella) + (cherry picked from commit 41756b8a77cdf69bc3aaeb8e88b734a7fa87a26e) + + +2026-05-19 Liviu Chircu + * [784938e42c] : + + Merge branch 'compression_overflow' of github.com:john08burke/opensips into john08burke-compression_overflow + + mc_compact() calculated the output size of preserved headers using the + normalized parser fields: header name, ": ", body and CRLF. + + However, for preserved long-form headers, it wrote the original raw header + span instead. If the input header contained extra whitespace after the + colon, such as "Supported: 100rel", the writer emitted more bytes than + the size calculation reserved, causing a buffer overflow and later memory + corruption. + + Always rebuild preserved headers from the same normalized fields used by + the length calculation, instead of mixing normalized accounting with raw + header copying. + + (cherry picked from commit d016658049fe5e2fa1061d16365507de0816fdce) + (cherry picked from commit 9a8499142c5e11600ab227e6244b7a8d610f50f0) + + +2026-05-17 OpenSIPS + * [5dfe21bd0e] : + + Rebuild documentation + + +2026-05-15 Liviu Chircu + * [da22f8d15c] : + + usrloc cluster: Fix possible SHM memory leak + + Commit 343f452c15 included a possible memory leak whenever the + .kv_storage field was already allocated in the urecord_t structure. + + (cherry picked from commit 1c505c5e3f61e173bb5a89bb316315173e6e6330) + + +2026-05-13 Razvan Crainea + * [d1590b0dd4] : + + xmpp: validate resolved IPv4 addresses + + (cherry picked from commit 15ed7355c6c888082d75fa08667c975a61459360) + + +2026-05-13 Razvan Crainea + * [9f988787d4] : + + jabber: validate resolved address family + + (cherry picked from commit 4103862c7c9728f555f515b0628c3755e298bccc) + + +2026-05-13 Razvan Crainea + * [0d015c4759] : + + rtpengine: allow IPv6 destinations in sockets + + (cherry picked from commit afec9c857e773c0707ceaa1bb13753de72639e71) + + +2026-05-13 Razvan Crainea + * [ec38f4f01f] : + + presence: handle case when Content-Type is missing + + Also properly test the mime type, incorporating both type and subtype + + (cherry picked from commit a03b8a82e96d591adf4f8ef81978497e6036cbfd) + + +2026-05-13 Razvan Crainea + * [de5071a480] : + + presence: make sure Content-Type is parsed + + (cherry picked from commit 5949135249019720b9078773bbf78f6317e3b8bf) + + +2026-05-13 Razvan Crainea + * [1237093899] : + + imc: centralize user body formatting + + (cherry picked from commit 3571c128760af9ac64065710c767ce7cda47a940) + + +2026-05-13 Razvan Crainea + * [303fb58a61] : + + imc: reject oversized unknown command replies + + (cherry picked from commit 07d54dbc966347148e7ca5b86671843a01ff7f7d) + + +2026-05-13 Razvan Crainea + * [2fae6df7b8] : + + imc: fix member list buffer overflow + + Build #list replies in an exact-sized pkg buffer instead of the fixed module buffer. Check length arithmetic before copying member URIs so large rooms cannot overflow the response body. + + (cherry picked from commit 76afe34203d571bb8709eeaca00ef9a300187617) + + +2026-05-13 Razvan Crainea + * [068a4b53cc] : + + mem: drop unused q_malloc counter + + (cherry picked from commit e95fbffcec303891601607282d41dc3b9b890b14) + + +2026-05-13 Razvan Crainea + * [8fe74b01f6] : + + sdp: reject malformed bandwidth lines + + (cherry picked from commit 38d0e6ea07c4f4441f00f4e3723432fe557f961d) + + +2026-05-13 Razvan Crainea + * [eb8b580498] : + + presence: drop unused variable + + (cherry picked from commit f86942e32ca1986e622caf52cbf00f0abc3b22b9) + + +2026-05-13 Razvan Crainea + * [c5970d3ee2] : + + presence: fix winfo XML overflow on long URIs + + (cherry picked from commit eeb331cd57d096ad7c767d9c0ef25010d020941a) + + +2026-05-13 Tristan <1075304+TristanInSec@users.noreply.github.com> + * [4d23613b65] : + + core: enforce bounds checks on input-derived lengths (#3888) + + - transformations: account for base64 4/3 expansion in b64encode + output length check + - parser/parse_body: validate remaining buffer length before delimiter + comparison in multipart boundary search + - net/proto_tcp: validate Content-Length value before multiplication + to prevent integer wraparound + - sipmsgops: enforce header name length limit in sip_to_json + conversion + - msg_translator: validate total URI length in construct_uri before + writing components + + (cherry picked from commit bd32a79eb38429995e30bf7c3859e3ed5b085c49) + + +2026-05-13 volga629-1 <59034879+volga629-1@users.noreply.github.com> + * [d8b5c5d6ca] : + + proto_smpp: bound sm_length against buffer overflow (#3891) + + Clamp attacker-controlled sm_length to MAX_SMS_CHARACTERS in + parse_submit_or_deliver_body() and reject oversized or odd UCS2 + lengths in recv_smpp_msg() before they reach copy_fixed_str() + or the GSM7/UCS2 decoders. + + Fixes a stack/heap buffer overflow reachable from a malicious + SMSC peer sending submit_sm/deliver_sm with sm_length > 254. + + Signed-off-by: NetworkLab Dev + (cherry picked from commit 6089db4ab94ba2ea09f8a88fd792c64949198ba4) + + +2026-05-13 Razvan Crainea + * [e8fd9862f5] : + + add inttypes format for i686 architectures + + (cherry picked from commit feccfa614f1059073eea4363bf6d7170906fe922) + + +2026-05-12 Peter Lemenkov + * [1e0b8714ce] : + + Fix format specifier warnings on 32-bit architectures (i686) (#3791) + + During compilation on i686 (32-bit) architecture with GCC 15, format + specifier warnings appear due to type size differences between 32-bit + and 64-bit platforms. + + ``` + server.c: In function 'on_frame_recv_callback': + warning: format '%ld' expects argument of type 'long int', but argument 14 + has type 'size_t' {aka 'unsigned int'} [-Wformat=] + 638 | LM_DBG("h2 header [%d], %p %ld\n", frame->hd.type, frame->headers.nva, frame->headers.nvlen); + + dm_impl.c: In function 'dm_avps2json': + warning: format '%ld' expects argument of type 'long int', but argument 15 + has type 'int64_t' {aka 'long long int'} [-Wformat=] + 484 | LM_DBG("%2d. got int64 AVP %s (%u), value: %ld\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->i64); + + warning: format '%lu' expects argument of type 'long unsigned int', but argument 15 + has type 'uint64_t' {aka 'long long unsigned int'} [-Wformat=] + 494 | LM_DBG("%2d. got uint64 AVP %s (%u), value: %lu\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->u64); + ``` + + Type sizes differ between 32-bit and 64-bit architectures: + + **On x86_64 (64-bit):** + - `size_t` = `unsigned long` (8 bytes) + - `int64_t` = `long int` (8 bytes) + + **On i686 (32-bit):** + - `size_t` = `unsigned int` (4 bytes) + - `int64_t` = `long long int` (8 bytes) + - `uint64_t` = `unsigned long long int` (8 bytes) + + Use portable C99 format specifiers that work correctly on all + architectures: + + - `%zu` for `size_t` (modules/http2d/server.c line 638) + - `%" PRId64` for `int64_t` (modules/aaa_diameter/dm_impl.c line 484) + - `%" PRIu64` for `uint64_t` (modules/aaa_diameter/dm_impl.c line 494) + + Assisted-by: Claude (Anthropic) + + Signed-off-by: Peter Lemenkov + (cherry picked from commit 672e4dd4d3338f4045fb8f914cf76b47d1a0a148) + + +2026-05-11 Razvan Crainea + * [88b534330e] : + + github: bump actions versions to avoid deprecation + + (cherry picked from commit 0d62134d29cc0b12c32fd8ee687078af5b8cd838) + + +2026-05-11 Razvan Crainea + * [14fd58cf5f] : + + presence: remove deprecated xmlMemoryDump() + + (cherry picked from commit 7ea25d91355b165a7b08d68e99898ed506b9b69b) + + +2026-05-10 OpenSIPS + * [74148845a4] : + + Rebuild documentation + + +2026-05-08 Razvan Crainea + * [c0197e4010] : + + rtpengine: avoid looping when a server is enforced + + (cherry picked from commit 0665f671d811ab44559e1033651964286e6a6b08) + + +2026-05-07 Jarrod Baumann + * [bfcdd43eab] : + + cgrates: add missing { NULL, NULL } terminator to modparam deps array + + (cherry picked from commit 7358018a857cec0d35fccce9dceb8d735773f3ba) + + +=========================== Release 3.6.5 ============================== + +2026-05-06 Liviu Chircu + * [24e3e379d7] : + + PN Support: Add few unit tests for t_wait_for_new_branches() + + (cherry picked from commit 5358eee98523c186d113e077661710e636eb6625) + + +2026-05-06 Liviu Chircu + * [f4d21babe8] : + + registrar: Improve error handling + + (cherry picked from commit 1875c584795952cbf9b2c4bf35777683e6ac0091) + + +2026-05-06 Liviu Chircu + * [c64f5b3470] : + + PN Support: Complete commit e7cf1d595 + + The fix in e7cf1d595 was not complete, as we must add both PN, non-PN + branches as well as any pre-existing append_branches() into the + t_wait_for_new_branches() wait count, otherwise the UAC-side transaction + could end prematurely, before the PN-branch gets a chance to deliver and + connect the call. + + (cherry picked from commit 6b058932285bfe95ab440ea61b8a34e2d8d6d722) + + +2026-05-06 Razvan Crainea + * [cabd8920f0] : + + debian: enforce explicit python path + + (cherry picked from commit ca8940e0777eb26ee04e97a969d0ae3d22ee2900) + + +2026-04-26 OpenSIPS + * [1898621b5a] : + + Rebuild documentation + + +2026-04-24 Liviu Chircu + * [b612d0509b] : + + python: Improve compatibility with Debian 13 + + The "python" binary is no longer provided by default -> adjust Makefile. + + (cherry picked from commit 70003cf10784a28f4fb18b6d446b30c6a07a8027) + + +2026-04-24 Norm Brandinger + * [66cca03849] : + + tls_openssl: fix per-thread state double-free across fork() + + Register a pthread_atfork prepare handler that calls OPENSSL_thread_stop() + before each fork(). CRYPTO_set_mem_functions() routes all OpenSSL allocations + to shared memory, but per-thread structures (ERR_STATE, DRBG) use thread-local + storage pointers inherited across fork(). Without cleanup, child processes + inherit a stale pointer to the parent per-thread state; if the parent frees or + re-creates that state, the child next OpenSSL call triggers a double-free + (detected by QM_MALLOC_DBG as SIGABRT). + + After OPENSSL_thread_stop() the thread-local pointer is NULL. Both parent and + child lazily allocate fresh per-thread state on the next OpenSSL call. + + This complements the existing on_exit(_exit) handler which covers the same + class of double-free at process exit time. + + (cherry picked from commit c8d148c1ea0b018964dc24cfce01ac0cf3e8940e) + + +2026-04-23 Liviu Chircu + * [605392dde7] : + + aaa_diameter: fix reply cJSON ownership in dm_send_request() paths + + _dm_get_message_response() detached cond->rpl.json into a temporary + reply object before wrapper cleanup ran. Now, cleanup frees only + cond->rpl.json, so the SHM-backed cJSON reply tree leaked. + + +2026-04-21 Ross Henderson + * [bf9f69f97a] : + + #3798 Don't require certificate for TLS clients + + +2026-04-19 OpenSIPS + * [9f9a11deaf] : + + Rebuild documentation + + +2026-04-17 Liviu Chircu + * [ae432e1b1c] : + + aaa_diameter: Fix possible PKG/SHM mixup across multiple threads + + Despite quite safe at a first glance, the following sequence is actually + NOT safe to use in the modules/aaa_diameter multi-threaded codebase: + + cJSON_InitHooks(&shm_mem_hooks); + ... perform lib/cJSON.c API operations ... + cJSON_InitHooks(NULL); + + Example: the "diameter-peer" multi-threaded process (35 threads!) + processes two dm_receive_msg() in parallel. The 1st thread resets the + "shm_mem_hooks" back to PKG using the NULL argument, while the 2nd + thread still assumes they are set to SHM functions, and mixes up memory. + + (cherry picked from commit ce2c9642d8727f700133461c26e1a4826ddc303d) + + +2026-04-17 Liviu Chircu + * [4d7ed1d8e8] : + + aaa_diameter: Fix race condition with async dm_send_request() + + - Avoid reading the @dmsg after it has been put on the queue, as it + might get freed meanwhile. + + * aaa_diameter: Fix race condition on pending async replies + + It was possible for the dm_send_request_async_tout() async timeout + function to ran concurrently with a late Diameter server reply, leading + to a use-after-free bug on the @cond struct. + + * Add refcounting to the "cond" object + + The SHM-stored @cond object is effectively referenced by two separate + processes/threads, which run concurrently: + - dm_send_request_async_tout(), the reactor async timeout callback + - dm_receive_msg(), the libfdcore receiver thread(s) + + (cherry picked from commit 01489359c8b528d1cbb5eab1a5c452071a35060a) + + +2026-04-17 Norm Brandinger + * [32c1cba6a1] : + + rtpengine: fix use-after-free of flags string in bencode dictionary (#3816) + + parse_flags() stores pointers into the pkg-allocated flags_nt.s buffer + via bencode_str() and bencode_dictionary_add_len(), which hold references + (not copies). The buffer was freed via pkg_free() before + send_rtpe_command() serialized the dictionary, causing garbled output + for key=value flags like media-address. + + Fix by deferring the free via bencode_buffer_destroy_add(), which + ensures the buffer lives until bencode_buffer_free() is called after + the command is sent. + + Fixes: https://github.com/OpenSIPS/opensips/issues/3784 + (cherry picked from commit c78b9e908b2896efbef3f7b0f9a111c4399ac34a) + + +2026-04-17 Razvan Crainea + * [2042792a3e] : + + event_rabbitmq: avoid double free on guest usage + + (cherry picked from commit 22c93a984319f8e6ac13aab8ddd8805b87d23ee6) + + +2026-04-17 Norm Brandinger + * [4545e55960] : + + event_rabbitmq: fix dupl_string() NUL-inclusive len corrupting AMQP shortstr (#3834) + + dupl_string() incremented dst->len after NUL-terminating the unescaped + string, causing .len to include the trailing NUL byte. This made + amqp_basic_publish() encode exchange and routing-key shortstr fields + with an extra 0x00, breaking broker routing. + + Remove the len++ and all downstream compensations (tls_dom_name.len--, + and the - 1 adjustments in rmq_print() for address, exchange, routing + key, and user). Also fix the un_escape() error path to free the + already-allocated shm buffer, and fix the default-user allocation to + explicitly NUL-terminate. + + Closes #3828 + + (cherry picked from commit cc801a4e01cd9ee7c21b0d34d9b7a7aa32f6c3a3) + + +2026-04-17 Ravitez Dondeti + * [e40d21e7aa] : + + db_mysql: recover from ER_UNKNOWN_STMT_HANDLER (1243) (#3865) + + The prepared-statement execute wrapper treats MySQL error 1243 + (ER_UNKNOWN_STMT_HANDLER) as a hard failure and skips the existing + reconnect + re-prepare path. This surfaces in production when the + backing database is replaced underneath a live client connection - + for example during an AWS Aurora zero-downtime minor-version upgrade, + which preserves the TCP connection but drops the server-side + prepared-statement cache. The next stmt_execute returns 1243, OpenSIPS + logs CRITICAL and the query fails instead of transparently recovering. + + Add the case to wrapper_single_mysql_stmt_execute so it funnels into + the same switch_state_to_disconnected -> connect_with_retry -> + re_init_statement recovery path that already handles CR_SERVER_GONE_ERROR + and friends. + + ER_NEED_REPREPARE (1615) is intentionally not added: libmysqlclient + auto-reprepare already handles that case. 1243 bypasses auto-reprepare + because the server has no record of the handle at all. + + The companion prepare wrapper is not modified: it starts from a fresh + mysql_stmt_init() handle that carries no server-side ID, so the server + cannot return 1243 in response to a prepare request. + + Reported-by: Sasmita Panda + (cherry picked from commit 9453ee09412c3a49a664bccad21757311d419688) + + +2026-04-14 Danielzt + * [097b530247] : + + core: fix fd memory leak in reactor_proc_add_fd, causing too many open files (#3830) + + rtpproxy: Fix in timeout scenarios, leading crash due to memory leak and too many open files + (cherry picked from commit 0296e26ffe2939b7c009de701b3b420d44d75e6f) + + +2026-04-14 davidtrihy-genesys <116663213+davidtrihy-genesys@users.noreply.github.com> + * [1c90d5dbdf] : + + Compiling with DISABLE_NAGLE does not propogate tcp_proto_no and never sets TCP_NODELAY (#3859) + +2026-04-12 OpenSIPS + * [8cfbb70357] : + + Rebuild documentation + + +2026-04-08 Liviu Chircu + * [e7cf1d5951] : + + PN Support: Improve default handling for failed calls + + Avoid relying on the "fr_inv_timeout" by default in order to complete + the transaction when the call is rejected (wait_for_new_branches...), as + the default (120s) is quite high, and can lead to stalling INVITEs. + + (cherry picked from commit 45dcfd73a47244663aff0e4e5079cd0431ba2447) + + +2026-04-07 Liviu Chircu + * [163cb72215] : + + janus: Simplify prev commit 2453e8f78a2c + + (cherry picked from commit 89055ff3a2fea8ec409304105d38214ac46a612c) + + +2026-04-07 rdondeti + * [5fd25d424b] : + + janus: fix pkg memory leaks in populate_janus_handler_id() + + The janus module uses cJSON_InitHooks() to route cJSON allocations + through pkg_malloc. In populate_janus_handler_id(), four calls to + cJSON_Print(request) are embedded directly in LM_ERR() format arguments. + The pkg-allocated return values are never stored or freed, leaking + ~100-500 bytes per error path hit. + + Store the cJSON_Print() result, use it in the log message, and free it + afterward. Also handle the case where cJSON_Print() returns NULL. + + This follows up on the janus leak fixes in commit f9fb3ea3e, which + addressed similar leaks in janus_raise_event(), + handle_janus_json_request(), and janus_ipc_send_request() but missed + populate_janus_handler_id(). + + (cherry picked from commit 2453e8f78a2c69a5f207681805d0e5866eb0b5ae) + + +2026-04-07 rdondeti + * [8e1512e30d] : + + aaa_diameter: fix NULL deref in dm_receive_req() via init_str() + + cJSON_PrintUnformatted() can return NULL on allocation failure (using shm + hooks). The return value is passed directly to init_str(), which calls + strlen() on it, causing a crash. + + Replace the init_str() call with an explicit NULL check and manual + assignment, following the existing error-handling pattern in the function + (goto error, which properly cleans up via cJSON_Delete and + cJSON_PurgeString). + + Found during a systematic audit of cJSON return value handling across + modules, following the janus leak fixes in commit f9fb3ea3e. + + (cherry picked from commit c304b6ef00566dac8e51858d7ba1ec97bbf53601) + + +2026-04-07 rdondeti + * [c48de598e0] : + + rtpengine: fix NULL deref from unchecked cJSON_PrintUnformatted() + + In rtpengine_raise_event(), cJSON_PrintUnformatted() can return NULL on + allocation failure. The return value is passed directly to strlen() and + then to cJSON_PurgeString(), both of which will crash on a NULL pointer. + + Add a NULL check before using the return value, and skip the parameter + on failure. + + Found during a systematic audit of cJSON return value handling across + modules, following the janus leak fixes in commit f9fb3ea3e. + + (cherry picked from commit cf5fb629cc08fc4c20b105df0a6131f5574e7f66) + + +2026-04-07 rdondeti + * [dbc832f7fc] : + + jsonrpc: fix NULL deref and object leak in jsonrpc_handle_cmd() + + cJSON_Print() can return NULL on allocation failure. The existing code + passes the return value directly to strlen() without a NULL check, + causing a crash on two separate code paths (error and result handling). + + Add NULL checks after both cJSON_Print() calls. + + Additionally, the cJSON tree allocated by cJSON_Parse() at the start of + the function is never freed. Add cJSON_Delete(obj) to the cleanup path. + + Found during a systematic audit of cJSON return value handling across + modules, following the janus leak fixes in commit f9fb3ea3e. + + (cherry picked from commit 6fc6acac8e8a669655d92346a8ad61af16671274) + + +2026-04-07 rdondeti + * [e7c8bf089a] : + + cachedb_cassandra: fix NULL deref when cass_cluster_new() returns NULL + + cass_cluster_new() can return NULL on allocation failure. The existing code + has a NULL check, but it comes after cass_cluster_set_credentials() already + uses the pointer (when credentials are configured), so a NULL return causes + a crash before the check is reached. + + Move the NULL check to immediately after cass_cluster_new(), before any use + of the returned pointer. + + Found during a systematic audit of cachedb backends following the + cachedb_redis NULL-deref fix in commit 8fb569cb3. + + (cherry picked from commit 8f959e73c79bf42d06ce2ee7406a80ab9edb8ca1) + + +2026-04-07 rdondeti + * [b747385d40] : + + cachedb_memcached: fix NULL deref when memcached_create() returns NULL + + memcached_create(NULL) can return NULL on allocation failure. The existing + code never checks the return value, so a NULL memc pointer falls through to + memcached_server_push(NULL, ...) which dereferences the NULL pointer. + + Add an explicit NULL check after memcached_create(), following the existing + error-handling pattern in the function (pkg_free + return 0). + + Found during a systematic audit of cachedb backends following the + cachedb_redis NULL-deref fix in commit 8fb569cb3. + + (cherry picked from commit 9fea57eeaf5c687f49a952692b2b7530ec66a7ee) + + +2026-04-07 Bogdan-Andrei Iancu + * [eb0b0e4195] : + + [sip_i] fix wrong ISUP msg type on 200 OK INVITE + + Credits go to @aldotms70 + Closes #3857 + + (cherry picked from commit bc5a87a28a9b269cc6596dc0e42ddb45344b57ec) + + +2026-04-05 OpenSIPS + * [169c1fa060] : + + Rebuild documentation + + +2026-04-02 Liviu Chircu + * [f050f59dc3] : + + db_sqlite: Improve error handling + + * avoid dangling PS pointers + * avoid leaking the PS object on NULL "result" + + (cherry picked from commit bdd97c5047b8a9a45ae520e293ecc94f0194d904) + + +2026-04-01 Liviu Chircu + * [04a7867ad9] : + + db_sqlite: Fix interaction with sql_cacher + + The .query API endpoint in db/db.h is meant to return 0 on success, yet + the current implementation in db_sqlite was returning "number of rows" + on success, leading to: + + ERROR:sql_cacher:load_entire_table: Failure to issue query to SQL DB... + ERROR:sql_cacher:cache_init_load: Failed to cache the entire table... + (cherry picked from commit 5abc95adbb087303620677f4802970686f6c3227) + + +2026-03-29 OpenSIPS + * [7f4fa3ac42] : + + Rebuild documentation + + +2026-03-26 Razvan Crainea + * [41515d9454] : + + rtp_relay: do not run indialog for non-SDP requests + + (cherry picked from commit d816345da35b2432f41fcd20578c0a14bcc2a3f9) + + +2026-03-23 Razvan Crainea + * [e1e09bcc76] : + + b2b_logic: turn of bridge initiator in case transfer fails + + (cherry picked from commit 381e725f6708de09cf7c386c625e57355047f76c) + + +2026-03-22 OpenSIPS + * [5133261aa9] : + + Rebuild documentation + + +2026-03-17 Norm Brandinger + * [f9fb3ea3ed] : + + janus: fix pkg memory leaks in cJSON_Print/cJSON_Parse paths + + The janus module uses cJSON_InitHooks() to route all cJSON allocations + through OpenSIPS pkg_malloc. Three call sites had missing cleanup: + + - janus_ipc_send_request(): cJSON_Print() result was copied to shm via + shm_nt_str_dup() but the pkg-allocated original was never freed. + Also added a NULL check -- under pkg exhaustion cJSON_Print returns + NULL and the subsequent strlen(NULL) causes a crash. + + - w_janus_send_request(): the cJSON tree from cJSON_Parse() was passed + to janus_ipc_send_request() (which serializes it to shm) but + cJSON_Delete() was never called afterward. Also added cleanup on the + get_janus_connection_by_id() failure path. + + - janus_raise_event() and handle_janus_json_request(): added NULL + checks after cJSON_Print(). Fixed missing pkg_free(full_json) on + the shm_strdup() failure path in handle_janus_json_request(). + + Together these leak ~350 bytes of pkg memory per janus_send_request() + call, leading to SIP worker pkg exhaustion and crash under sustained + load. + + Fixes #3712 + + (cherry picked from commit 43b696d85eeef9ad233d03070624fcc204d078e8) + + +2026-03-15 OpenSIPS + * [63784c3165] : + + Rebuild documentation + + +2026-03-10 Bogdan Andrei IANCU + * [251fd00ce0] : + + Merge pull request #3842 from NormB/fix/cachedb-redis-null-deref + + cachedb_redis: fix NULL deref when redisConnect returns NULL + + (cherry picked from commit f0f53a61504538909070335cd0b37b987f773d0a) + + +2026-03-08 OpenSIPS + * [f2cc686995] : + + Rebuild documentation + + +2026-03-06 Liviu Chircu + * [f47c2f47bb] : + + registrars: Allow accepting Re-REGISTERs with equal CSeq + + New module setting for both registrar and mid-registrar which controls + the policy on handling same Call-ID REGISTERs, with the same CSeq. + + modparam: allow_dup_cseq + default: false (100% backwards-compatible) + + Ultimately, this boils down to a trade-off between interoperability and + RFC strictness. More info in the modparam documentation. + + (cherry picked from commit dda9010efb6149c44a98cb2029215d0e28ee3f89) + + +2026-03-06 Liviu Chircu + * [960ab38e85] : + + mid_registrar: Fix mem management bugs around "max contacts" + + * avoid UAF of the @uc pointer during iteration + * fix logic so that the current @c cannot be freed by trim_contacts() + itself, yet again leading to UAF type of bugs + + usrloc: Fix rare memleak edge-case + (cherry picked from commit 2642e14fb17fcc1ed24eab51bd0568bb743f51e2) + + +2026-03-03 Bogdan-Andrei Iancu + * [d1777c7dc4] : + + [tcp] fixed potential buffer overflow due to insane large Content-Len values + + Check and limit the Content-Lenght to the size of the reading buffer, makes no sense to accept anything higher. + + (cherry picked from commit 09e787799c6f808df948bcd159060ca89e7fa91e) + + +2026-03-02 Razvan Crainea + * [afc8f9a15b] : + + b2b_entities: make sure last_method is updated before req + + (cherry picked from commit b1482d83697d0be1c0ffe850b358755e28674fc2) + + +2026-03-01 OpenSIPS + * [68825c777b] : + + Rebuild documentation + + +2026-02-26 Razvan Crainea + * [a68179cc6c] : + + b2b_entities: convert ERR in DBG + + (cherry picked from commit 5964710b0a6aba5c22d366ea1b60ace1df42ab25) + + +2026-02-24 Remi Collet + * [85149d8d4b] : + + support for libmongc/libbson version 2 (#3829) + + (cherry picked from commit 55982fb456963fc8d0fff2eabbbb91849d1dee25) + + +2026-02-23 Bogdan-Andrei Iancu + * [43d965ab44] : + + Merge pull request #3821 from NormB/fix/tm-async-rd-reversion + + tm: fix $rd reversion after chained async() resume + + Cherry pick of 2a1c511265d82648c984807c02c4b50ed073ca42 + + +2026-02-22 OpenSIPS + * [7c4ce06cf3] : + + Rebuild documentation + + +2026-02-20 Razvan Crainea + * [36c6eb883e] : + + packaging/redhat: fix bug introduced in 1ea06905 + + +2026-02-19 Razvan Crainea + * [96b4520cc2] : + + readme: drop lgtm badges, as the service no longer exists + + (cherry picked from commit 4e3a0b7c3c025f6b2121f216e790ab8d03dc240d) + + +2026-02-19 Razvan Crainea + * [e0ecfcbd62] : + + regex: fix broken merge + + (cherry picked from commit b0c1bcafa284977e53fc6b2ac6c659365f88404c) + + +2026-02-19 Razvan Crainea + * [90260cec0d] : + + build: python-dev-is-python3 should be available in 20.04 + + (cherry picked from commit 2a8a298f7bf85a8a63f60f367186ed48540bfa41) + + +2026-02-19 Razvan Crainea + * [f9d6d2216f] : + + build: restore libmysqlclient-dev removed in 1cb16e08 + + (cherry picked from commit 6da1f76b790eafccb2d700e060496bd2b7eec6e8) + + +2026-02-19 Razvan Crainea + * [184b712027] : + + regex: make module work with both pcre2 and pcre3, not just compile + + (cherry picked from commit bbc1a75d5ba25c0f26afcd208b0f5c7e1fffd3b7) + + +2026-02-19 Razvan Crainea + * [4ebd27d2c4] : + + packaging: fix redhat pcre-devel name + + +2026-02-18 Razvan Crainea + * [1967e32107] : + + debian: proper replacement libcurl4 gnutls with openssl + + Please enter the commit message for your changes. Lines starting + + +2026-02-18 Razvan Crainea + * [49ff938efa] : + + Revert "debian: fully replace libcurl4 gnutls with openssl" + + This reverts commit 5021266bf0baacb7aa7b95524a3dc0d36e820148. + + +2026-02-18 Razvan Crainea + * [7c441c7a20] : + + packaging: skip wolfssl errors + + +2026-02-18 Razvan Crainea + * [c4126ff1b5] : + + packaging: fix .swp matching + + +2026-02-18 Razvan Crainea + * [5021266bf0] : + + debian: fully replace libcurl4 gnutls with openssl + + (cherry picked from commit c51e2dd0284055926559d79807aed0e7eb9624f4) + + +2026-02-18 Razvan Crainea + * [7ff18f94bf] : + + debian: replace libcurl4 gnutls with openssl + + The reason is that librkafka depends on libcurl4-openssl-dev, which + conflicts with libcurl4-gnutls-dev + + (cherry picked from commit 7d9aadc01efd9d9b4e52f571cd6b884ad1359658) + + +2026-02-18 Razvan Crainea + * [1ea0690570] : + + packaging: force libpcre3 for stable version + + except for Debian 13, which is new package and cannot run with libpcre3 + + +2026-02-18 Razvan Crainea + * [1682927ee3] : + + regex: allow pcre3 library + + +2026-02-18 Steve Ayre + * [e706726c4d] : + + update regex module for pcre2 + + (cherry picked from commit 3cc28d166b5a3d7db2cd2d944406480e5a1474f5) + + +2026-02-18 Razvan Crainea + * [2d2d06ee0c] : + + dialplan: make module work with both pcre2 and pcre3 libs + + (cherry picked from commit 67483a5a27ce656eaf9409f7710cf67798e70aac) + + +2026-02-18 Razvan Crainea + * [dd0e53e394] : + + dialplan: fix copying subst's out vector + + (cherry picked from commit 30825e4e0809a1a61f06cec964589c825645b62b) + + +2026-02-18 Ken Rice + * [c48acc8354] : + + Makefile tweaks to avoid $(shell ...) expansions from failing + + Fixes #3717 + + (cherry picked from commit a3ae498d8726894753483738e801dfc0e63e3ba9) + + +2026-02-18 Steve Ayre + * [405bffdb6e] : + + create pcre2 compile context once instead of for each compile + + (cherry picked from commit 6082b43fa8b44cbfea7de8afb38998354b54d1fb) + + +2026-02-18 Steve Ayre + * [bc71bf02c5] : + + update dialplan module for pcre2 + + (cherry picked from commit c58e3af0cc7b44ceb304ac1b6d2c8b45feca4b5b) + + +2026-02-18 Steve Ayre + * [ea37bcf8dd] : + + require libpcre2 + + (cherry picked from commit 1cb16e082e9ba1cd63f04996eecd75632682df7c) + + +=========================== Release 3.6.4 ============================== + +2026-02-18 Liviu Chircu + * [9cb4214382] : + + proto_wss: free ws_data on TLS domain lookup failure + + (cherry picked from commit 2cde87bac5dadeb13ca7430d5a6d40c2457a734d) + + +2026-02-18 Razvan Crainea + * [f3bb041ae1] : + + auth_db: fix documentation regarding default credentials value + + Reported by Evgeniy (@gostkov on GitHub) in #3813 + + +2026-02-18 Razvan Crainea + * [ca3dc83d52] : + + tm: fix EXTRA_DEBUG logging for local cancel timer + + (cherry picked from commit 71541c911d39f98978e4882e9d16065c1dd5f97c) + + +2026-02-15 OpenSIPS + * [462fe92be5] : + + Rebuild documentation + + +2026-02-10 Liviu Chircu + * [0e56b0ca4f] : + + rest_client: Fix async transfers with re-used TCP conns + + Fix the edge-case with async cURL where it re-uses an existing TCP + connection. Here, the @connect variable holds a 0 value, thus the + transfer runs in blocking mode unless we relax the condition. + + Patch provided by Nuno Almeida from Five9. + + (cherry picked from commit aad6b856835a53d660215834e3c16c4591cf2375) + + +2026-02-10 Razvan Crainea + * [a5ac425516] : + + event_rabbitmq: avoid using released memory + + Reset the `tmp.s` pointer when assigning it to a structure, to avoid + freeing it when the `tmp` is reused. + + Many thanks to Andrey F(@kertor) for reporting it and + Nick Altmann(@nikbyte) for fixing it. + + Close #3808 + + (cherry picked from commit 5595a924bff552de914de11615121350acd5da4b) + + +2026-02-09 Razvan Crainea + * [34b0766e9a] : + + siprec: make sure there is a dlg/SDP to notify SRS with + + (cherry picked from commit 8e948d26eb6a21fd4a67a6eb51065da1259f6989) + + +2026-02-09 Razvan Crainea + * [bbad39d750] : + + siprec: avoid accessing invalid dialog/rtp context + + reset dialog when it has been terminated - this prevents being accessed + after the dialog was deleted. + + (cherry picked from commit ee7435662c761e8512af84a46d6db4595a4d6519) + + +2026-02-08 OpenSIPS + * [9a71a3dbfb] : + + Rebuild documentation + + +2026-02-02 Liviu Chircu + * [a6866fe56d] : + + mid_registrar: Fix the `tcp_persistent_flag` feature + + Make sure to NOT adjust the @e_max with -get_act_time(), similar to + registrar codebase, to avoid setting MAX_INT on the TCP conn lifetime... + + (cherry picked from commit 7935e2e927b523a21bf23e58f5b652ae7db71b46) + + +2026-02-02 pavelkohout396 + * [2ce53bf26e] : + + Fix SQL injection in auth_jwt module via unescaped tag claim (#3807) + + The jwt_db_authorize() function... + The jwt_db_authorize() function in the auth_jwt module decodes JWT tokens + without signature verification to extract the 'tag' claim, then interpolates + this claim directly into a raw SQL query without escaping. An attacker can + craft a malicious JWT with SQL injection payload in the tag claim (e.g., + "' UNION SELECT 'admin','attacker_secret' --") to inject their own secret + into the query result. Since the injected secret is then used to verify the + JWT signature, the attacker can sign their token with this known secret and + achieve authentication bypass. + + Reported-by: Pavel Kohout, Aisle Research, www.aisle.com + (cherry picked from commit 3822d33c1c6b25832fdd88da1d23eed74be55b05) + + +2026-02-02 Bogdan-Andrei Iancu + * [71a3239e61] : + + [b2b_entities] fix cseq to be used upon 200OK/CANCEL race + + When generating the ACK+BYE upon 200 OK (from callee) racing a CANCEL (from caller), take care and use the correct cdeq values from the 200 OK (the b2b entity is not properly updated anymore, as it is already terminated by the CANCEL) + + (cherry picked from commit a4e700d598c70caacf27c342b3c664ccfcf5ba5b) + + +2026-02-02 Bogdan Andrei IANCU + * [f954669468] : + + Merge pull request #3806 from ovidiusas/master + + trie: fix defaults for trie_table parameter + (cherry picked from commit 556d22b3da58c1230c2a22d9eabfa34cf3004366) + + +2026-02-01 OpenSIPS + * [2dac9ed5ec] : + + Rebuild documentation + + +2026-01-30 Razvan Crainea + * [bf333d2ca5] : + + aaa_diameter: proper handing of _dm_send_message error + + Avoid double free of the JSON message + + (cherry picked from commit 2ad991b638d6cab4d226139e3a2d0f5b0c30c7db) + + +2026-01-29 Bogdan Andrei IANCU + * [0a4b8803ce] : + + Merge pull request #3716 from jasonshugart/master + + Ignore extra headers in MSRP + + (cherry picked from commit 1669166458afe05e97ad36288023c38518ffbd64) + + +2026-01-28 Razvan Crainea + * [2b07612d4b] : + + b2b_entities: fix possible leak on error cases + + On some error cases, the serialization buffer was not released, leading + to a leak in pkg memory. + + (cherry picked from commit f92c5f2e279ad5b2823151cc45fd5d2cedadaa4f) + + +2026-01-27 Peter Lemenkov + * [707405eb4e] : + + Fix libbson deprecated API warning with version compatibility (#3792) + + During compilation of cachedb_mongodb module, numerous deprecation + warnings appear on systems with mongo-c-driver >= 1.29.0: + + ``` + Compiling cachedb_mongodb_dbase.c + gcc -fPIC -DPIC -O2 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Wno-complain-wrong-lang -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -march=x86-64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -mtls-dialect=gnu2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -DMOD_NAME='cachedb_mongodb' -DPKG_MALLOC -DSHM_MMAP -DUSE_MCAST -DDISABLE_NAGLE -DSTATISTICS -DHAVE_RESOLV_RES -DF_MALLOC -DQ_MALLOC -DHP_MALLOC -DDBG_MALLOC -DF_PARALLEL_MALLOC -DHAVE_STDATOMIC -DHAVE_GENERICS -DNAME='"opensips"' -DVERSION='"3.6.2"' -DARCH='"x86_64"' -DOS='"linux"' -DCOMPILER='"gcc 15"' -D__CPU_x86_64 -D__OS_linux -D__SMP_yes -DCFG_DIR='"/etc/opensips/"' -DVERSIONTYPE='"git"' -DTHISREVISION='"994bcd690"' -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H -DHAVE_TIMEGM -DHAVE_EPOLL -DHAVE_SIGIO_RT -DHAVE_SELECT -I/usr/include/json-c -I/usr/include/json-c -DJSON_PKG_MAJOR=0 -DJSON_PKG_MINOR=18 -DJSON_PKG_MICRO=0 -DUTF8PROC_EXPORTS -I/usr/include/libmongoc-1.0 -I/usr/include/libbson-1.0 -c cachedb_mongodb_dbase.c -o cachedb_mongodb_dbase.o + cachedb_mongodb_dbase.c: In function ‘mongo_con_set’: + cachedb_mongodb_dbase.c:315:9: warning: ‘bson_as_json’ is deprecated: Use bson_as_legacy_extended_json instead [-Wdeprecated-declarations] + 315 | dbg_bson("query: ", query); + | ^~~~~~~~ + In file included from /usr/include/libmongoc-1.0/mongoc/mongoc.h:22, + from /usr/include/libmongoc-1.0/mongoc.h:18, + from cachedb_mongodb_dbase.h:30, + from cachedb_mongodb_dbase.c:22: + /usr/include/libbson-1.0/bson/bson.h:535:1: note: declared here + 535 | bson_as_json (const bson_t *bson, size_t *length) BSON_GNUC_DEPRECATED_FOR (bson_as_legacy_extended_json); + | ^~~~~~~~~~~~ + ``` + + The MongoDB C driver (libbson) deprecated bson_as_json() in version + 1.29.0 (October 2024) in favor of bson_as_legacy_extended_json() to + clarify which JSON format is being produced (legacy vs. canonical + extended JSON). + + We added compatibility macro at the top of cachedb_mongodb_dbase.c - for + mongo-c-driver < 1.29.0, define bson_as_legacy_extended_json as an alias + to bson_as_json, allowing the code to use the new API name while + maintaining backward compatibility. + + This change maintains compatibility with all mongo-c-driver versions. + The new function name is used on >= 1.29.0, while older versions + transparently use the original bson_as_json() through the macro alias. + + No behavioral changes - the replacement is functionally identical and + produces the same JSON output format. The new name simply makes it + explicit that the legacy extended JSON format is being used. + + Note: mongo-c-driver 1.29.0 was released in October 2024. Many LTS + distributions still ship earlier versions (e.g., RHEL 8/9, Ubuntu + 20.04/22.04, Debian 11/12), making the compatibility macro necessary. + + Assisted-by: Claude (Anthropic) + + Signed-off-by: Peter Lemenkov + (cherry picked from commit dead516b7f4b0881f99afbee4b48969ceaab1d73) + + +2026-01-27 Bogdan Andrei IANCU + * [ea6e69cf52] : + + Merge pull request #3733 from hafkensite/feature/dns-cache-cname + + resolve: fix CNAME chain resolution with caching #3709 + (cherry picked from commit 401957bd8ddbf050d9c2f65c8a51021ea78391d7) + + +2026-01-26 Bogdan-Andrei Iancu + * [f5de0a361a] : + + Discard forced socket if AF incompatible + + ... and force selection of a different outbound socket, based on protocol and AF + Based on a report from Ihor Olkhovskyi + + (cherry picked from commit b8e28c5294a1b1627b8076d31d0a00e49c8587f4) + + +2026-01-25 OpenSIPS + * [fb2557ddaa] : + + Rebuild documentation + + +2026-01-23 Bogdan Andrei IANCU + * [9d1832b40d] : + + Merge pull request #3804 from purecloudlabs/sipmsg_validate_all_contacts + + Sipmsg validate all contacts + + (cherry picked from commit 18fdeaf32bb12e31ceb7876726865faaa8c91c7f) + + +2026-01-23 Bogdan Andrei IANCU + * [e98e729e04] : + + Merge pull request #3803 from purecloudlabs/dialog_contact_crash_fix + + Dialog module crash when Contact header is * + + (cherry picked from commit a3fcb81d6bbea42c88a2da51a4438a6f41e48a7f) + + +2026-01-22 Liviu Chircu + * [067caa135c] : + + launch(): Fix edge-case with report_route $param(1) not set + + Some async functions (e.g. rest_post()) may report an ASYNC_SYNC status, + when the operation completed inline. This case wasn't properly handled + in the launch() support, as the report_route $param(1) was always NULL. + + Many thanks to Nuno Ferreira from Five9 for a full report and + troubleshooting on this one! + + +2026-01-20 Bogdan-Andrei Iancu + * [aa4ddd17be] : + + [TCP] fixed bad handling upon "max async postponed chunks" + + In such case, mark the conn as timed out, to force its sending back to TCP main for closing. + Also fix some bad ref counting when handling bad cons in ASYNC WRITE. + Add more hist logs to conn, to easy the debugging process. + + (cherry picked from commit 4afd1c8af1ca24ba642f5ad7ecd3d5b14eb7dafe) + + +2026-01-20 Liviu Chircu + * [e65c545804] : + + b2b_entities: Zero DB handles after module destroy + + Since B2B destroys before tm, this should help prevent some shutdown + crashes in B2B due to cascaded module cleanups (e.g. tm cleanups going + into dialog, siprec then back again into B2B). + + (cherry picked from commit c482249acffc84d4e5d818fc3e24b8fb9f833962) + + +2026-01-20 Liviu Chircu + * [a4cbe17b2a] : + + Fix reply relaying after launch() from onreply_route + + This commit prevents SIP replies from being absorbed (bug?!) by OpenSIPS + after a launch() operation from onreply_route, with no further replies + to upstream side on that T. Follow-up on a711924f9, see tm/t_reply.c. + + Such launch() calls are completely decoupled from the T, do not + interfere with the script logic and can safely be done in parallel. + + (cherry picked from commit 11e37d129eaf0d0a064ef50075c9f1bf96b588f8) + + +2026-01-11 OpenSIPS + * [e78b3e99af] : + + Rebuild documentation + + +2026-01-09 Razvan Crainea + * [76b7fa7a0e] : + + b2b_logic: also replicate in_sdp for created entity + + (cherry picked from commit b88203c1e8f13dc5eaf3ff38a7724d2d6ec6d85c) + + +2025-12-21 OpenSIPS + * [288bdfa936] : + + Rebuild documentation + + +2025-12-19 Liviu Chircu + * [b1dd39c118] : + + GitHub Workflows: Run rtp.io build tests only on `master` + + * fixes the build on 3.6 branch, due to old Clang (see commit e6caba06a) + * the rtp.io code is identical on 3.6 and master branches, no need to + run duplicate checks. If it diverges, we can revert this commit. + + =========================== Release 3.6.3 ============================== 2025-12-18 Liviu Chircu diff --git a/INSTALL b/INSTALL index 6c1f251d674..abb0d6832b0 100644 --- a/INSTALL +++ b/INSTALL @@ -25,7 +25,6 @@ TOC B) Disclaimers C) Quick Start D) opensips with Persistent Data Storage - E) menuconfig installation 4. Troubleshooting @@ -78,8 +77,8 @@ Requirements: - libldap libs and devel headers v2.1 or greater - if you want LDAP support - libconfuse and devel headers - if you want to compile the carrierroute module -- libncurses5-dev and m4 - if you want to use the menuconfig graphical user interface - for configuring OpenSIPS compilation & cfg file options +- libncurses5-dev - required to build the bundled ncurses utilities +- m4 - if you want to use M4 templating OS Notes: @@ -87,6 +86,27 @@ OS Notes: - Solaris: as above; you can use Solaris's yacc instead of bison. You might need also gtar and ginstall. +Build configuration is stored in Makefile.conf. The first make invocation +copies Makefile.conf.template when Makefile.conf does not exist. You may also +create it explicitly: + +cp Makefile.conf.template Makefile.conf + +Edit Makefile.conf before compiling: + +- exclude_modules lists modules omitted from the normal modules and all + targets. Add names to exclude more modules. +- include_modules forces named modules into the build, including modules from + exclude_modules. Install each module's external dependencies first. +- DEFS controls OpenSIPS compile-time definitions. The template documents the + available definitions. +- CC_EXTRA_OPTS and LD_EXTRA_OPTS add compiler and linker flags. +- PREFIX controls the default installation prefix and defaults to /usr/local/. + Use the same prefix while building and installing. + +Run make proper before rebuilding after changing DEFS, compiler flags, or +linker flags. + 2. Howto Build opensips From Source Distribution ------------------------------------------- @@ -214,11 +234,6 @@ That applies to other make parameters as well (for example parameters "modules" or "excluded_modules"). -Start graphical user interface: - -make menuconfig - - 3. Quick-Start Installation Guide ---------------------------------------------- @@ -372,48 +387,6 @@ proceed, you need to make sure MySQL is installed on your box. /etc/init.d/opensips restart 7) you can now start managing the server using the opensips-cli utility -E) menuconfig installation - -The Interface allows the user to do the following : - -1. Configure OpenSIPS compilation related options such as : - - Compilation Flags. For example, the user can now easily compile in TCP - support from within the GUI, or enable memory allocation debugging, etc. - Each compilation flag functionality is explained in short in the GUI. - - Module Compilation Selection. The user can now easily select to compile - modules that have external dependencies, and that are not compiled in - by default. For example, the user can choose to also enable the MySQL - support by enabling the db_mysql module. The interface will also notify - the user about the dependencies that must be installed based on the modules - that the user has selected. - - Installation Prefix. The user can use the GUI to configure the OpenSIPS - installation path to be used - -2. Install OpenSIPS and Cleanup OpenSIPS sources - - Upon configuring OpenSIPS related options from above, - the user can choose to install OpenSIPS directly from the GUI. - -3. Generate OpenSIPS config files - - The tool can also generate OpenSIPS configuration files based on the - user's preferences. So far, we have defined three main classes of OpenSIPS - configuration files : - - Residential - - Trunking - - Load-balancer - - For each type of configuration file, the user can choose to enable/disable - certain options. For example, for the Residential script, the user can choose - to enable presence support, to handle NAT, and many more. After the user has - properly configured it's desired OpenSIPS script in the GUI, it will have the - option to generate and obtain the final OpenSIPS cfg. - - -If you have installed OpenSIPS from packages ( debs, rpms, etc ) and not from sources, -you will still be able to use the graphical interface for generating configuration files, -by running - osipsconfig - - 4. Troubleshooting ------------------ diff --git a/Makefile b/Makefile index 8cb7576bab1..5daa0da92e1 100644 --- a/Makefile +++ b/Makefile @@ -88,14 +88,6 @@ static_defs=$(foreach mod, $(static_modules), \ override extra_defs+=$(static_defs) $(EXTRA_DEFS) export extra_defs -# If modules is supplied, only do those. If not, use all modules when -# building documentation. -ifeq ($(modules),) - doc_modules=$(all_modules) -else - doc_modules=$(modules) -endif - # Take subset of all modules, excluding the exclude_modules and the # static_modules. modules=$(filter-out $(addprefix modules/, \ @@ -225,155 +217,42 @@ gen_misclibs: $(MAKE) -C $$r ; \ done -.PHONY: tool-docbook2pdf -tool-docbook2pdf: - @if [ -z "$(DBXML2PDF)" ]; then \ - echo "error: docbook2pdf not found"; exit 1; \ - fi - -.PHONY: tool-lynx -tool-lynx: - @if [ -z "$(DBHTML2TXT)" ]; then \ - echo "error: lynx not found"; exit 1; \ - fi - -.PHONY: tool-xsltproc -tool-xsltproc: - @if [ -z "$(DBXML2HTML)" ]; then \ - echo "error: xsltproc not found"; exit 1; \ - fi - @if [ -z "$(DBHTMLXSL)" ]; then \ - echo "error: docbook.xsl not found (docbook-xsl)"; exit 1; \ - fi - .PHONY: git-dir git-dir: @if [ ! -r .git ]; then \ echo "error: Not a git repo! (.git dir not found)"; exit 1; \ fi -.PHONY: modules-contrib -modules-contrib: git-dir - @set -e; ./doc/build-contrib.sh $(modules) - -.PHONY: modules-readme -modules-readme: tool-lynx tool-xsltproc - @set -e; \ - for mod in $(doc_modules); do \ - r=`basename $$mod`;\ - echo "Reading directory $$mod for module $$r";\ - if [ ! -d "$$mod/doc" ]; then \ - continue; \ - fi; \ - cd "$$mod/doc"; \ - if [ -f "$$r".xml ]; then \ - echo "docbook xml to html: $$r.xml"; \ - $(DBXML2HTML) -o $$r.html $(DBXML2HTMLPARAMS) $(DBHTMLXSL) \ - $$r.xml; \ - echo "docbook html to txt: $$r.html"; \ - $(DBHTML2TXT) $(DBHTML2TXTPARAMS) $$r.html >$$r.txt; \ - echo "docbook txt to readme: $$r.txt"; \ - rm $$r.html; \ - mv $$r.txt ../README; \ - echo ""; \ - fi; \ - cd ../../..; \ - done - -.PHONY: modules-docbook-txt -modules-docbook-txt: tool-lynx tool-xsltproc - @set -e; \ - for mod in $(doc_modules); do \ - r=`basename $$mod`;\ - echo "Reading directory $$mod for module $$r";\ - if [ ! -d "$$mod/doc" ]; then \ - continue; \ - fi; \ - cd "$$mod/doc"; \ - if [ -f "$$r".xml ]; then \ - echo ""; \ - echo "docbook xml to html: $$r.xml"; \ - $(DBXML2HTML) -o $$r.html $(DBXML2HTMLPARAMS) $(DBHTMLXSL) \ - $$r.xml; \ - echo "docbook html to txt: $$r.html"; \ - $(DBHTML2TXT) $(DBHTML2TXTPARAMS) $$r.html >$$r.txt; \ - rm $$r.html; \ - echo ""; \ - fi; \ - cd ../../..; \ - done - -.PHONY: modules-docbook-html -modules-docbook-html: tool-xsltproc - @set -e; \ - for mod in $(doc_modules); do \ - r=`basename $$mod`;\ - echo "Reading directory $$mod for module $$r";\ - if [ ! -d "$$mod/doc" ]; then \ - continue; \ - fi; \ - cd "$$mod/doc"; \ - if [ -f "$$r".xml ]; then \ - echo ""; \ - echo "docbook xml to html: $$r.xml"; \ - $(DBXML2HTML) -o $$r.html $(DBXML2HTMLPARAMS) $(DBHTMLXSL) \ - $$r.xml; \ - echo ""; \ - fi; \ - cd ../../..; \ - done - -.PHONY: modules-docbook-pdf -modules-docbook-pdf: tool-docbook2pdf - @set -e; \ - for mod in $(doc_modules); do \ - r=`basename $$mod`;\ - echo "Reading directory $$mod for module $$r";\ - if [ ! -d "$$mod/doc" ]; then \ - continue; \ - fi; \ - cd "$$mod/doc"; \ - if [ -f "$$r".xml ]; then \ - echo ""; \ - echo "docbook xml to pdf: $$r.xml"; \ - $(DBXML2PDF) "$$r".xml; \ - fi; \ - cd ../../..; \ - done - -.PHONY: modules-docbook -modules-docbook: modules-docbook-txt modules-docbook-html modules-docbook-pdf - .PHONY: dbschema-docbook-txt dbschema-docbook-txt: dbschema @set -e; \ - for r in $(wildcard doc/database/*.sgml) "" ; do \ + for r in $(wildcard docs/database/*.sgml) "" ; do \ if [ -f "$$r" ]; then \ echo "" ; \ echo "docbook2txt $$r" ; \ - docbook2txt -o "doc/database/" "$$r" ; \ + docbook2txt -o "docs/database/" "$$r" ; \ fi ; \ done .PHONY: dbschema-docbook-html dbschema-docbook-html: dbschema @set -e; \ - for r in $(wildcard doc/database/*.sgml) "" ; do \ + for r in $(wildcard docs/database/*.sgml) "" ; do \ if [ -f "$$r" ]; then \ echo "" ; \ echo "docbook2html $$r" ; \ - docbook2html --nochunks -o "doc/database/" "$$r" ; \ + docbook2html --nochunks -o "docs/database/" "$$r" ; \ fi ; \ done .PHONY: dbschema-docbook-pdf dbschema-docbook-pdf: dbschema @set -e; \ - for r in $(wildcard doc/database/*.sgml) "" ; do \ + for r in $(wildcard docs/database/*.sgml) "" ; do \ if [ -f "$$r" ]; then \ echo "" ; \ echo "docbook2pdf $$r" ; \ - docbook2pdf -o "doc/database/" "$$r" ; \ + docbook2pdf -o "docs/database/" "$$r" ; \ fi ; \ done @@ -452,7 +331,7 @@ deb: dpkg-buildpackage \ -I.git -I.gitignore \ -I*.swp -I*~ \ - -i\\.git\|debian\|^\\.\\w+\\.swp\|lex\\.yy\\.c\|cfg\\.tab\\.\(c\|h\)\|\\w+\\.patch \ + -i\\.git\|debian\|\\.\\w+\\.swp\|lex\\.yy\\.c\|cfg\\.tab\\.\(c\|h\)\|\\w+\\.patch \ -rfakeroot -tc $(DEBBUILD_EXTRA_OPTIONS) rm -rf debian @@ -472,18 +351,29 @@ sunpkg: rm -rf tmp/$(NAME)_sun_pkg -.PHONY: install-app install-modules-all install +.PHONY: install-app install-config-templates install-modules-all install # Install app only, excluding console, modules and module docs install-app: mk-install-dirs install-cfg install-bin \ - install-app-doc install-man + install-app-doc install-man install-config-templates -# Install all module stuff (except modules-docbook?) +# Install all module stuff install-modules-files: install-modules install-modules-doc install-modules-all: install-modules-files install-modules-dbschema -# Install everything (except modules-docbook?) +# Install everything install: install-app install-modules-all +install-config-templates: $(data_prefix)/$(data_dir) + mkdir -p $(data_prefix)/$(data_dir)/examples/templates/ + $(INSTALL_TOUCH) examples/templates/*.m4 examples/templates/README.md \ + $(data_prefix)/$(data_dir)/examples/templates/ + $(INSTALL_CFG) examples/templates/*.m4 \ + $(data_prefix)/$(data_dir)/examples/templates/ + $(INSTALL_DOC) examples/templates/README.md \ + $(data_prefix)/$(data_dir)/examples/templates/README.md + sed -i -e "s#/usr/.*lib/$(NAME)/modules/#$(modules_target)#" \ + $(data_prefix)/$(data_dir)/examples/templates/*.m4 + opensipsmc: $(cfg_prefix)/$(cfg_dir) $(data_prefix)/$(data_dir) $(MAKE) -C menuconfig proper $(MAKE) -C menuconfig \ @@ -577,9 +467,9 @@ install-app-doc: $(doc_prefix)/$(doc_dir) install-modules-doc: $(doc_prefix)/$(doc_dir) -@for r in $(modules_basenames) "" ; do \ if [ -n "$$r" ]; then \ - if [ -f modules/"$$r"/README ]; then \ + if [ -f modules/"$$r"/README.md ]; then \ $(INSTALL_TOUCH) $(doc_prefix)/$(doc_dir)/README."$$r" ; \ - $(INSTALL_DOC) modules/"$$r"/README \ + $(INSTALL_DOC) modules/"$$r"/README.md \ $(doc_prefix)/$(doc_dir)/README."$$r" ; \ fi ; \ fi ; \ @@ -600,33 +490,10 @@ install-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5 < $(NAME).cfg.5 > $(man_prefix)/$(man_dir)/man5/$(NAME).cfg.5 chmod 644 $(man_prefix)/$(man_dir)/man5/$(NAME).cfg.5 -install-modules-docbook: $(doc_prefix)/$(doc_dir) - -@for r in $(modules_basenames) "" ; do \ - if [ -n "$$r" ]; then \ - if [ -d modules/"$$r"/doc ]; then \ - if [ -f modules/"$$r"/doc/"$$r".txt ]; then \ - $(INSTALL_TOUCH) $(doc_prefix)/$(doc_dir)/"$$r".txt ; \ - $(INSTALL_DOC) modules/"$$r"/doc/"$$r".txt \ - $(doc_prefix)/$(doc_dir)/"$$r".txt ; \ - fi ; \ - if [ -f modules/"$$r"/doc/"$$r".html ]; then \ - $(INSTALL_TOUCH) $(doc_prefix)/$(doc_dir)/"$$r".html ; \ - $(INSTALL_DOC) modules/"$$r"/doc/"$$r".html \ - $(doc_prefix)/$(doc_dir)/"$$r".html ; \ - fi ; \ - if [ -f modules/"$$r"/doc/"$$r".pdf ]; then \ - $(INSTALL_TOUCH) $(doc_prefix)/$(doc_dir)/"$$r".pdf ; \ - $(INSTALL_DOC) modules/"$$r"/doc/"$$r".pdf \ - $(doc_prefix)/$(doc_dir)/"$$r".pdf ; \ - fi ; \ - fi ; \ - fi ; \ - done - doxygen: -@echo "Create Doxygen documentation" # disable call graphes, because of the DOT dependencies - (cat doc/doxygen/opensips-doxygen; \ + (cat docs/doxygen/opensips-doxygen; \ echo "HAVE_DOT=no" ;\ echo "PROJECT_NUMBER=$(NAME)-$(RELEASE)" )| doxygen - -@echo "Doxygen documentation created" diff --git a/Makefile.conf.template b/Makefile.conf.template index ed7bc257a35..09be000c39d 100644 --- a/Makefile.conf.template +++ b/Makefile.conf.template @@ -19,13 +19,13 @@ #db_postgres= Provides Postgres connectivity for OpenSIPS | PostgreSQL library and development library - typically libpq5 and libpq-dev #db_sqlite= Provides SQLite connectivity for OpenSIPS | SQLite library and development library - typically libsqlite3 and libsqlite3-dev #db_unixodbc= Allows to use the unixodbc package with OpenSIPS | ODBC library and ODBC development library -#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, typically libpcre-dev +#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, typically libpcre2-dev #emergency= Provides emergency call treatment for OpenSIPS | CURL dev library - typically libcurl4-openssl-dev #event_rabbitmq= Provides the implementation of a RabbitMQ client for the Event Interface | RabbitMQ development library, librabbitmq-dev #event_sqs= Provides the implementation of a Amazon SQS client for the Event Interface | AWS SDK C++, aws-sdk-cpp #event_kafka= Provides the implementation of an Apache Kafka producer for the Event Interface | Kafka development library, librdkafka-dev #h350= Enables access to SIP account data stored in an LDAP [RFC4510] directory containing H.350 commObjects | OpenLDAP library & development files, typically libldap and libldap-dev -#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, typically libpcre-dev +#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, typically libpcre2-dev #identity= Adds support for SIP Identity (see RFC 4474). | SSL library, typically libssl #jabber= Integrates XODE XML parser for parsing Jabber messages | Expat library. #json= Introduces a new type of variable that provides both serialization and de-serialization from JSON format. | JSON library, libjson @@ -73,7 +73,6 @@ #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 -# the below definition must be one single line (no wrapping) to make the "menuconfig" tool happy 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 rtp.io siprec sngtc snmpstats stir_shaken tls_mgm tls_openssl tls_wolfssl uuid xcap xcap_client xml xmpp include_modules?= diff --git a/Makefile.defs b/Makefile.defs index d5f2a607ec6..4b8c49c8b3b 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -66,7 +66,7 @@ MAIN_NAME=opensips #version number VERSION_MAJOR = 3 VERSION_MINOR = 6 -VERSION_SUBMINOR = 3 +VERSION_SUBMINOR = 7 VERSION_BUILD = ifneq (,$(VERSION_BUILD)) @@ -538,46 +538,6 @@ REGENERATE_MEM_STATS=remove-mem-stats endif endif -ifeq ($(DBXML2HTML),) -DBXML2HTML = $(shell which xsltproc) -endif - -ifneq ($(DBXML2HTML),) -ifeq ($(DBHTMLCSS),) -DBHTMLCSS = ../../../doc/module-docbook.css -endif -#DBHTMLXSL = /usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl -# On CentOS, this is the right path: -#DBHTMLXSL = /usr/share/sgml/docbook/xsl-stylesheets/xhtml/docbook.xsl - -DBHTMLXSL=$(shell \ - if [ -e /usr/share/xml/docbook/xsl-stylesheets-1.79.2-nons/xhtml/docbook.xsl ]; then \ - echo "/usr/share/xml/docbook/xsl-stylesheets-1.79.2-nons/xhtml/docbook.xsl"; \ - elif [ -e /usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl ]; then \ - echo "/usr/share/xml/docbook/stylesheet/nwalsh/html/docbook.xsl"; \ - elif [ -e /usr/share/sgml/docbook/xsl-stylesheets/xhtml/docbook.xsl ]; then \ - echo "/usr/share/sgml/docbook/xsl-stylesheets/xhtml/docbook.xsl"; \ - elif [ -e /usr/share/xml/docbook/xsl-stylesheets*/xhtml/docbook.xsl ]; then \ - ls -1 /usr/share/xml/docbook/xsl-stylesheets*/xhtml/docbook.xsl; \ - fi) -DBXML2HTMLPARAMS = --stringparam section.autolabel 1 -DBXML2HTMLPARAMS += --stringparam section.label.includes.component.label 1 -DBXML2HTMLPARAMS += --stringparam generate.toc "book toc,title,figure,table,example" -DBXML2HTMLPARAMS += --stringparam html.stylesheet $(DBHTMLCSS) -endif - -ifeq ($(DBHTML2TXT),) -DBHTML2TXT = $(shell which lynx) -endif - -ifneq ($(DBHTML2TXT),) -DBHTML2TXTPARAMS = -force_html -dump -nolist -width=72 -endif - -ifeq ($(DBXML2PDF),) -DBXML2PDF = $(shell which docbook2pdf) -endif - MKTAGS=ctags -R . # compile-time options diff --git a/Makefile.rules b/Makefile.rules index fd76a97e768..3fe140302bf 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -125,29 +125,17 @@ dosetrev: @echo "$(THISREVISION)" >.$(VERSIONTYPE)revision -.PHONY: docbook-clean -docbook-clean: - -@for r in $(modules) $(static_modules_path) "" ; do \ - if [ -d "$$r" ]; then \ - if [ -d "$$r"/doc ]; then \ - rm -f "$$r"/doc/*.txt ; \ - rm -f "$$r"/doc/*.html ; \ - rm -f "$$r"/doc/*.pdf ; \ - fi ; \ - fi ; \ - done - .PHONY: dbschema-docbook-clean dbschema-docbook-clean: - -@if [ -d doc/database ] ; then \ - rm -f doc/database/*.txt ; \ - rm -f doc/database/*.html ; \ - rm -f doc/database/*.pdf ; \ + -@if [ -d docs/database ] ; then \ + rm -f docs/database/*.txt ; \ + rm -f docs/database/*.html ; \ + rm -f docs/database/*.pdf ; \ $(MAKE) -C db/schema docbook_clean; \ fi .PHONY: clean -clean: docbook-clean dbschema-docbook-clean +clean: dbschema-docbook-clean -@rm -f $(objs) $(NAME) $(objs:.o=.il) 2>/dev/null -@for r in $(all_modules) $(all_utils) $(all_misclibs); do \ if [ -d "$$r" -a -f "$$r/Makefile" ]; then \ diff --git a/README.md b/README.md index 0836d8e4c2b..0edd1a8b84b 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ [![OSS-Fuzz](https://github.com/OpenSIPS/opensips/actions/workflows/cifuzz.yml/badge.svg?branch=master)](https://github.com/OpenSIPS/opensips/actions/workflows/cifuzz.yml?query=branch%3Amaster++) [![Cross Platform Builds](https://github.com/OpenSIPS/opensips/actions/workflows/multiarch.yml/badge.svg?branch=master)](https://github.com/OpenSIPS/opensips/actions/workflows/multiarch.yml?query=branch%3Amaster++) [![Coverity Scan Build Status](https://scan.coverity.com/projects/7580/badge.svg)](https://scan.coverity.com/projects/opensips-opensips) -[![Code Quality: Cpp](https://img.shields.io/lgtm/grade/cpp/g/OpenSIPS/opensips.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSIPS/opensips/context:cpp) -[![Total Alerts](https://img.shields.io/lgtm/alerts/g/OpenSIPS/opensips.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/OpenSIPS/opensips/alerts) # Welcome to OpenSIPS Project diff --git a/async.c b/async.c index 173aba0fe25..42330ab58e4 100644 --- a/async.c +++ b/async.c @@ -369,6 +369,8 @@ int async_script_launch(struct sip_msg *msg, struct action* a, } } + async_status = ASYNC_DONE; + /* done, return to the script */ return 1; sync: @@ -396,12 +398,21 @@ int async_script_launch(struct sip_msg *msg, struct action* a, return -1; } + if (report_route_param) + route_params_push_level( + sroutes->request[report_route->idx].name, + report_route_param, NULL, + launch_route_param_get); + bak_avps = set_avp_list(&report_avps); - swap_route_type( bk_rt, REQUEST_ROUTE); + swap_route_type( bk_rt, REQUEST_ROUTE); run_top_route( sroutes->request[report_route->idx], req); - set_route_type( bk_rt ); + + if (report_route_param) + route_params_pop_level(); + destroy_avp_list(&report_avps); set_avp_list(bak_avps); diff --git a/bin_interface.c b/bin_interface.c index b6e2e50781d..68e9d7081c8 100644 --- a/bin_interface.c +++ b/bin_interface.c @@ -439,6 +439,16 @@ void call_callbacks(char* buffer, struct receive_info *rcv) str capability; memcpy(&pkg_len, buffer + BIN_PACKET_MARKER_SIZE, sizeof(unsigned int)); + if (pkg_len < HEADER_SIZE + LEN_FIELD_SIZE + CMD_FIELD_SIZE) { + LM_ERR("invalid BIN packet size %u\n", pkg_len); + return; + } + if (pkg_len > BIN_MAX_BUF_LEN) { + LM_ERR("BIN packet size %u exceeds max size %zu\n", + pkg_len, (size_t)BIN_MAX_BUF_LEN); + return; + } + //add extra size so a realloc wont trigger after small altering of the packet packet.buffer.s = pkg_malloc(pkg_len + 50); if (!packet.buffer.s) { @@ -452,6 +462,13 @@ void call_callbacks(char* buffer, struct receive_info *rcv) memcpy(packet.buffer.s, buffer, pkg_len); bin_get_capability(&packet, &capability); + if ((unsigned int)capability.len > + pkg_len - HEADER_SIZE - LEN_FIELD_SIZE - CMD_FIELD_SIZE) { + LM_ERR("invalid BIN packet capability length %d for packet size %u\n", + capability.len, pkg_len); + bin_free_packet(&packet); + return; + } packet.front_pointer = capability.s + capability.len + CMD_FIELD_SIZE; memcpy(&packet.type, capability.s + capability.len, sizeof(int)); diff --git a/cfg_reload.c b/cfg_reload.c index 3fce021c7b1..849e9301175 100644 --- a/cfg_reload.c +++ b/cfg_reload.c @@ -56,6 +56,7 @@ struct script_reload_ctx { rw_lock_t *rw_lock; unsigned int seq_no; unsigned int next_seq_no; + str reloaded_cfg_buf; str cfg_buf; enum proc_reload_status *proc_status; }; @@ -139,8 +140,9 @@ int init_script_reload(void) static inline void reset_script_reload_ctx(void) { - if (srr_ctx->cfg_buf.s) - shm_free(srr_ctx->cfg_buf.s); + if (srr_ctx->reloaded_cfg_buf.s) + shm_free(srr_ctx->reloaded_cfg_buf.s); + srr_ctx->reloaded_cfg_buf = srr_ctx->cfg_buf; srr_ctx->cfg_buf.s = NULL; srr_ctx->cfg_buf.len = 0; @@ -353,6 +355,47 @@ static void routes_switch_per_proc(int sender, void *param) } +int self_update_routing_script(void) +{ + int ret = 0; + + /* be sure we do not overlap with a script reload */ + lock_get( &srr_ctx->lock ); + if (srr_ctx->seq_no!=0) { + LM_INFO("Reload already in progress, cannot update now\n"); + lock_release( &srr_ctx->lock ); + return -1; + } + srr_ctx->seq_no = srr_ctx->next_seq_no++; + lock_release( &srr_ctx->lock ); + + /* anything to reload? */ + if (srr_ctx->reloaded_cfg_buf.s==NULL) + goto done; + + /* put the last reloaded buffer in the right place as for a reload */ + srr_ctx->cfg_buf = srr_ctx->reloaded_cfg_buf; + + routes_reload_per_proc( process_no, (void*)(long)srr_ctx->seq_no); + if (srr_ctx->proc_status[process_no] != RELOAD_SUCCESS) { + LM_ERR("failed to update to the last reloaded cfg :(\n"); + ret = -1; + goto done; + } + + routes_switch_per_proc( process_no, (void*)(long)srr_ctx->seq_no); + +done: + srr_ctx->cfg_buf.s = NULL; + srr_ctx->cfg_buf.len = 0; + /* this must be the last as it will allow the ctx reusage + * for another reload */ + srr_ctx->seq_no = 0; + + return ret; +} + + /* This is the trigger point for script reloading */ int reload_routing_script(void) diff --git a/cfg_reload.h b/cfg_reload.h index 182cf30285c..aa960c8b331 100644 --- a/cfg_reload.h +++ b/cfg_reload.h @@ -30,6 +30,8 @@ int init_script_reload(void); int reload_routing_script(void); +int self_update_routing_script(void); + /* sets as active the old/previous cfg (after a reload) */ void reload_swap_old_script(void); diff --git a/db/schema/Makefile b/db/schema/Makefile index 6666fa6ff78..3414d6eaf0d 100644 --- a/db/schema/Makefile +++ b/db/schema/Makefile @@ -3,7 +3,7 @@ TABLES := $(patsubst opensips-%.xml,%,$(wildcard opensips-*.xml)) ROOT=../.. -STYLESHEETS=$(ROOT)/doc/dbschema/xsl +STYLESHEETS=$(ROOT)/docs/dbschema/xsl # Stylesheet used to generate db_table nodes for pi_framework XML schema PI_FRAMEWORK_TABLE_XSL = $(STYLESHEETS)/pi_framework_table.xsl @@ -40,7 +40,7 @@ VALIDATE = 0 VERBOSE = 0 # XML Catalog used to resolve entities -CATALOG = $(ROOT)/doc/dbschema/catalog.xml +CATALOG = $(ROOT)/docs/dbschema/catalog.xml XSLTPROC = /usr/bin/xsltproc XSLTPROC_FLAGS = --xinclude @@ -190,33 +190,33 @@ db_berkeley_clean: docbook: for FILE in $(TABLES); do \ XML_CATALOG_FILES=$(CATALOG) $(XSLTPROC) $(XSLTPROC_FLAGS) \ - --stringparam dir "$(ROOT)/doc/database" \ + --stringparam dir "$(ROOT)/docs/database" \ --stringparam prefix "$$FILE-" \ $(DOCBOOK_XSL) opensips-"$$FILE".xml ; \ done ; \ # link all documents to one file, to get nicer output - echo " "$(ROOT)/doc/database/tables.sgml" + echo " "$(ROOT)/docs/database/tables.sgml" # create entities, as xi:include is not available in sgml docbook # substitute '-' for '_', docbook smgl don't like this - for FILE in $(wildcard $(ROOT)/doc/database/*.xml); do \ - echo " " >> "$(ROOT)/doc/database/tables.sgml" ; \ + for FILE in $(wildcard $(ROOT)/docs/database/*.xml); do \ + echo " " >> "$(ROOT)/docs/database/tables.sgml" ; \ done ; \ #Include general documentation entities - echo " %docentities;" >> "$(ROOT)/doc/database/tables.sgml" ; \ - echo "]>" >> "$(ROOT)/doc/database/tables.sgml" + echo " %docentities;" >> "$(ROOT)/docs/database/tables.sgml" ; \ + echo "]>" >> "$(ROOT)/docs/database/tables.sgml" # add bookinfo - cat "$(ROOT)/doc/dbschema/bookinfo.xml" >> "$(ROOT)/doc/database/tables.sgml" + cat "$(ROOT)/docs/dbschema/bookinfo.xml" >> "$(ROOT)/docs/database/tables.sgml" # actually include the entities - for FILE in $(wildcard $(ROOT)/doc/database/*.xml); do \ - echo " &`basename "$$FILE" | sed -e 's#_#-#g'`" >> "$(ROOT)/doc/database/tables.sgml" ; \ + for FILE in $(wildcard $(ROOT)/docs/database/*.xml); do \ + echo " &`basename "$$FILE" | sed -e 's#_#-#g'`" >> "$(ROOT)/docs/database/tables.sgml" ; \ done ; \ - echo "" >> "$(ROOT)/doc/database/tables.sgml" + echo "" >> "$(ROOT)/docs/database/tables.sgml" docbook_clean: - -@rm -f $(ROOT)/doc/database/*.xml - -@rm -f $(ROOT)/doc/database/tables.sgml + -@rm -f $(ROOT)/docs/database/*.xml + -@rm -f $(ROOT)/docs/database/tables.sgml .PHONY: clean diff --git a/db/schema/template.xml b/db/schema/template.xml index 32c456598cf..12b69dcf9bb 100644 --- a/db/schema/template.xml +++ b/db/schema/template.xml @@ -17,7 +17,7 @@ id - int + int &table_id_len; diff --git a/doc/authors.xml b/doc/authors.xml deleted file mode 100644 index 7653a82779b..00000000000 --- a/doc/authors.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - Anca Vamanu, <anca at opensips dot org> - - - Ancuta Onofrei, <ancuta at voice-system dot ro> - - - Andreas Granig, <andreas dot granig at inode dot info> - - - Elena-Ramona Modroiu, <ramona at rosdeve dot ro> - - - Bastian Friedrich, <bastian dot friedrich at collax dot com> - - - Bogdan-Andrei Iancu, <bogdan at opensips dot org> - - - Christian Schlatter, <cs at unc dot edu> - - - Dan Pascu, <dan at ag-projects dot com> - - - Di-Shi Sun, <di-shi at transnexus dot com> - - - Elias Baixas, <elias dot baixas at voztele dot com> - - - Daniel-Constantin Mierla, <miconda at gmail dot com> - - - Henning Westerholt, <henning dot westerholt at 1und1 dot de> - - - Dmitry Isakbayev, <isakdim at gmail dot com> - - - Jesus Rodriguez, <jesusr at voztele dot com> - - - Juha Heinanen, <jh at tutpro dot com> - - - Julien Blache, <jblache at debian dot org> - - - Klaus Darilion, <klaus dot mailinglists at pernau dot at> - - - Jan Ondrej, <ondrejj at salstar dot sk> - - - Will Quan, <wiquan at employees dot org> - - - Ovidiu Sas, <osas at voipembedded dot com> - - - Razvan Crainea, <razvan at opensips dot org> - - - Vlad Paiu, <vladpaiu at opensips dot org> - - Maxim Sobolev, <sobomax at sippysoft dot com> - - - diff --git a/doc/build-contrib.sh b/doc/build-contrib.sh deleted file mode 100755 index f4436756b3a..00000000000 --- a/doc/build-contrib.sh +++ /dev/null @@ -1,1052 +0,0 @@ -#!/bin/bash -# scan the git log, apply exceptions and generate the proper project -# commmit statistics since September 2001 -# -# Copyright (C) 2018 OpenSIPS Solutions -# -# 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 - -### global OpenSIPS commit stats, self-generated on each "rebuild-proj-stats" -__PROJ_COMMITS=22438 -__PROJ_LINES_ADD=2669737 -__PROJ_LINES_DEL=1359428 -__LAST_REBUILD_SHA=eb9a3007c236220b53d880dd4cc768cbe7e80110 - -TMP_FILE=/var/tmp/.opensips-build-contrib.tmp - -# be more verbose -DEBUG=${DEBUG-} - -# display author emails in the resulting HTML -SHOW_AUTHOR_EMAIL=${SHOW_AUTHOR_EMAIL-} - -# process all arguments (modules) supplied to build-contrib.sh in parallel -PARALLEL_BUILD=${PARALLEL_BUILD-yes} - -# formatting settings -TABLE_SIZE_COMMITS=${TABLE_SIZE_COMMITS:-10} -TABLE_SIZE_ACTIVITY=${TABLE_SIZE_ACTIVITY:-10} - -# Update the display name of an author, create a name-only referencing shortcut -# or link multiple emails of an author under a single identity -declare -A author_aliases -author_aliases=( - ["AgalyaR "]="Agalya Ramachandran " - ["Alessio Garzi "]="Alessio Garzi " - ["Anca Vamanu"]="Anca Vamanu " - ["Andreas Granig "]="Andreas Granig " - ["Andreas Heise"]="Andreas Heise " - ["Andrei Pelinescu-Onciul"]="Andrei Pelinescu-Onciul " - ["Bogdan Andrei IANCU "]="Bogdan-Andrei Iancu " - ["Bogdan-Andrei Iancu "]="Bogdan-Andrei Iancu " - ["Bogdan Iancu "]="Bogdan-Andrei Iancu " - ["Carsten Bock"]="Carsten Bock " - ["Cerghit Ionel "]="Ionel Cerghit " - ["Christian Schlatter "]="Christian Schlatter " - ["Christophe Sollet"]="Christophe Sollet " - ["Daniel-Constantin Mierla "]="Daniel-Constantin Mierla " - ["Daniel-Constantin Mierla "]="Daniel-Constantin Mierla " - ["davesidwell "]="Dave Sidwell " - ["Eric Tamme "]="Eric Tamme " - ["Fabian Gast "]="Fabian Gast " - ["Henning Westerholt"]="Henning Westerholt " - ["Ionut Ionita "]="Ionut Ionita " - ["Ionut Ionita "]="Ionut Ionita " - ["Jan Janak"]="Jan Janak " - ["Jarrod Baumann "]="Jarrod Baumann " - ["John Riordan"]="John Riordan " - ["Juha Heinanen"]="Juha Heinanen " - ["Kobi Eshun"]="Kobi Eshun " - ["Maxim Sobolev "]="Maksym Sobolyev " - ["NAME "]="Anonymous" - ["Norm Brandinger "]="Norman Brandinger " - ["Norman Brandinger"]="Norman Brandinger " - ["Nick Altmann "]="Nick Altmann " - ["Nick Altmann "]="Nick Altmann " - ["Ovidiu Sas "]="Ovidiu Sas " - ["Oliver Mulelid-Tynes"]="Oliver Severin Mulelid-Tynes " - ["Oliver Severin Mulelid-Tynes"]="Oliver Severin Mulelid-Tynes " - ["Parantido De Rica "]="Parantido Julius De Rica " - ["Peter Lemenkov"]="Peter Lemenkov " - ["pasandev "]="Pasan Meemaduma " - ["Ryan Bullock"]="Ryan Bullock " - ["Răzvan Crainea "]="Razvan Crainea " - ["Răzvan Crainea "]="Razvan Crainea " - ["Răzvan Crainea "]="Razvan Crainea " - ["Rob Gagnon "]="Rob Gagnon " - ["Sergey KHripchenko "]="Sergey Khripchenko " - ["shripchenko "]="Sergey Khripchenko " - ["rgagnon24 "]="Rob Gagnon " - ["Saúl Ibarra Corretgé "]="Saúl Ibarra Corretgé " - ["Stéphane Alnet"]="Stéphane Alnet " - ["Vladut Paiu "]="Vlad Paiu " - ["Walter Doekes"]="Walter Doekes " - ["boris_t "]="Boris Talovikov " - ["csollet "]="Christophe Sollet " - ["ionutrazvanionita "]="Ionut Ionita " - ["liviuchircu "]="Liviu Chircu " - ["root "]="Evandro Villaron " - ["root "]="Robison Tesini " - ["root "]="Vlad Paiu " - ["root "]="Chad Attermann " - ["root "]="Bogdan-Andrei Iancu " - ["rvlad-patrascu "]="Vlad Patrascu " - ["rvlad-patrascu "]="Vlad Patrascu " - ["Vlad Pătrașcu "]="Vlad Patrascu " - ["tallicamike "]="Mihai Tiganus " -) - -# Associate a GitHub handle with an author or an author alias (same effect). - -# ProTip: there is no need to include the email if the "name " token is -# already present in "author_aliases" above (either LHS or RHS works) -declare -A github_handles -github_handles=( - ["Agalya Ramachandran"]="AgalyaR" - ["Alessio Garzi"]="Ozzyboshi" - ["Alexandr Dubovikov "]="adubovikov" - ["Alexey Vasilyev "]="vasilevalex" - ["Andrei Datcu "]="andrei-datcu" - ["Andrey Vorobiev "]="andrey-vorobiev" - ["Andriy Pylypenko "]="bambyster" - ["Aron Podrigal "]="ar45" - ["Björn Esser "]="besser82" - ["Bogdan-Andrei Iancu"]="bogdan-iancu" - ["Callum Guy "]="spacetourist" - ["Chad Attermann"]="attermann" - ["Christophe Sollet"]="csollet" - ["Damien Sandras "]="dsandras" - ["Daniel-Constantin Mierla"]="miconda" - ["Dan Pascu "]="danpascu" - ["Dave Sidwell"]="davesidwell" - ["Di-Shi Sun "]="di-shi" - ["Dusan Klinec "]="ph4r05" - ["Eric Tamme"]="etamme" - ["Eseanu Marius Cristian "]="eseanucristian" - ["Evandro Villaron"]="evillaron" - ["Ezequiel Lovelle "]="lovelle" - ["Fabian Gast"]="fgast" - ["Federico Edorna "]="fedorna" - ["Gohar Ahmed "]="goharahmed" - ["Henning Westerholt"]="henningw" - ["Ionel Cerghit"]="ionel-cerghit" - ["Ionut Ionita"]="ionutrazvanionita" - ["Italo Rossi "]="italorossi" - ["jamesabravo"]="jamesabravo" - ["Jan Janak"]="janakj" - ["Jarrod Baumann"]="jarrodb" - ["Jasper Hafkenscheid "]="hafkensite" - ["Jeremy Martinez "]="JeremyMartinez51" - ["Jiri Kuthan "]="jiriatipteldotorg" - ["John Burke "]="john08burke" - ["John Kiniston "]="SB-JohnK" - ["Juha Heinanen"]="juha-h" - ["Kobi Eshun "]="ekobi" - ["Liviu Chircu"]="liviuchircu" - ["Maksym Sobolyev"]="sobomax" - ["Mihai Tiganus"]="tallicamike" - ["Nick Altmann"]="nikbyte" - ["Norman Brandinger"]="NormB" - ["Oliver Mulelid-Tynes"]="olivermt" - ["Ovidiu Sas"]="ovidiusas" - ["Parantido Julius De Rica"]="Parantido" - ["Pasan Meemaduma"]="pasanmdev" - ["Peter Lemenkov"]="lemenkov" - ["Razvan Crainea"]="razvancrainea" - ["Rob Gagnon"]="rgagnon24" - ["Robison Tesini"]="rtesini" - ["Ryan Bullock"]="rrb3942" - ["Saúl Ibarra Corretgé"]="saghul" - ["Sergey Khripchenko"]="shripchenko" - ["Stefan Pologov"]="sisoftrg" - ["Stéphane Alnet"]="shimaore" - ["Victor Ciurel "]="victor-ciurel" - ["Vlad Paiu"]="vladpaiu" - ["Vlad Patrascu"]="rvlad-patrascu" - ["Walter Doekes"]="wdoekes" - ["Zero King "]="l2dy" -) - -# Commits which have been done on behalf of the original authors -# (ideally, PRs will for-always solve this problem, -# and we won't ever have to edit this array) -# -# (in some cases, the committer may have also added their own minor tweaks on -# top of the provided patch, so fully re-attributing the commit to the original -# author is still not completely fair. If you have a "split credits" idea and -# want to put more time into this, I will happily review your PR!) -declare -A fix_authors -fix_authors=( - # global, "across multiple modules" changes (will get properly counted for each module) - ["0de42c5b2b9f35a983f59c925a10ccf08a544ca6"]="Edson Gellert Schubert <4lists@gmail.com>" - ["7ef17c650772b635ede8bbb7ac061c49abce584a"]="Edson Gellert Schubert <4lists@gmail.com>" - ["9394da66657f23d11bc35396bec4ae8e108a92ad"]="UnixDev" - ["c8c8263bbce3449c6ed140e832eb4b971dc7be77"]="Andreas Granig" - ["cd6142cb65c0104e49f27812ef14c1c89cf8cca7"]="John Riordan" - ["7740840eec2be4c786537c905374f5568561b878"]="Walter Doekes" - ["14a626b000d1788c5cb1649b12f708712d11d8d9"]="Ancuta Onofrei " - ["c4c6ac5947eab0d9e5dec05529aefce3c61c3ff6"]="Norman Brandinger" - ["e65227a9c8f3c8fac0564ae8d0bba71617e034e0"]="Vallimamod Abdullah" - ["6097c7bba18be247cdf9c72327e6bb89c7751f59"]="Walter Doekes" - ["4db2b711486eef5a330806095d11bb4f191ab9be"]="Walter Doekes" - ["40f53d8f4043427258e5c2eb338739e3b43f139b"]="Angel Marin" - ["fe1e5ce3e4113da6f6645419236dfef958edaeaa"]="Stanislaw Pitucha" - ["401d799e64ec71f6774e3a70dde8d86aef667915"]="Stanislaw Pitucha" - ["13637069128558a04d3bf70bfb28f045ce3a97c3"]="Iouri Kharon " - ["42f9066ebf4b1c459be35b2597eda4a5937a8866"]="Andreas Heise" - ["2b1f7934628e99db96be759dc81eb3b8204b2174"]="Jeffrey Magder " - ["e0fe570fe75c78d0573aa5185ae8986dba0c91da"]="Shlomi Gutman " - ["5346d6f2118818f51512c777fb5ee7b089c8e2fb"]="Phil D'Amore" - ["ee0221187d8f3d57b63e3cbd615c448a5a508667"]="Marcus Hunger " - ["45e4b0bc8b1d4198f72859d02c3ccb5f9c2cadd2"]="Marcus Hunger " - ["0ddde446698a62566fa94d9da74549f3acd5a9ae"]="Juha Heinanen" - ["baa5e19b90931b3d84813e4c585c4361e9fd69ca"]="Klaus Darilion" - - # aaa_radius - ["2296c4953ce85b9cffab3a74e2c98ce3186c96db"]="Boris Ratner" - ["77cc5af653240f7b5b2355e100082434a5dcb2ed"]="Boris Ratner" - ["46124d967074e981afa46a200c278529cdf731cb"]="Matt Lehner" - ["5e138604958a7b8d5c0ccb01ed8a24010e338a39"]="Авдиенко Михаил" - ["9870f06530ba72145733bace69f15f2e802c9a3c"]="Alex Massover" - - # acc - ["77d77188b35de71c06e5cf3c4787166888e5ff80"]="Ryan Bullock" - ["95dc05f3ba606f80ffc1b767b8e4d47ad667584b"]="Ryan Bullock" - ["829eaa2e409a2398842f72fe40829ef8ba3f6939"]="Alex Massover" - ["ce4ba967cbc5c186e63993ae51181b85517a1157"]="Ovidiu Sas" - ["eb2854457a428b3de08142a8e7c8bf0825785c3b"]="Ovidiu Sas" - ["bdb07d33492551a2893fc1d49d453c1658b2e04b"]="Peter Nixon" - - # alias_db - ["7c308080e1c0f9edb07a19afde45534abd681b37"]="Vladimir Romanov" - - # auth - ["26599d25cbc140373a5c24759dce688235e57589"]="Anatoly Pidruchny" - - # auth_db - ["dbf3497f4d09a6b1158a536d6843f8402704fd6b"]="Richard Revels" - ["13e9a5cbe14050e622a3ef65cd34b72260a74f01"]="Kennard White" - ["26599d25cbc140373a5c24759dce688235e57589"]="Anatoly Pidruchny" - - # sqlops - ["37eba4b6d38f379a227040397c569f0d0fe99c9c"]="Kennard White" - ["d129377f64f13e85ea0baf6d215092b4b4776f6e"]="Norman Brandinger" - ["b9247c08af07662c6e712179dc57bcc5f16794aa"]="Kobi Eshun" - ["bbbaaeca433fc5d03eca587d0a33f53d7720bec5"]="Olle E. Johansson" - ["80eee1a046ea1da637a2c8b55d3aa22cb6f16d82"]="Andrei Pelinescu-Onciul" - - # b2b_entities - ["ec7b4e54bf7f09fb6ff56e8f8497563cf13719e8"]="@DMOsipov" - ["cdd3c519fcbdadf351ab76bf2efbc75d35ba2803"]="Ryan Bullock" - ["4135804ae488d8c574611298488540b5e868dd4d"]="Nick Altmann" - ["65df3af5781c21ba8a41f23983e060badf7d9b48"]="Stéphane Alnet" - ["ee8ca9e979e87506d6eb9260a26a7a2fee45e026"]="Henk Hesselink" - ["fe1e5ce3e4113da6f6645419236dfef958edaeaa"]="Stanislaw Pitucha" - - # b2b_logic - ["5a3b6ac30c4b9dd68e3ebc5cbe83e31eb1175b77"]="Nick Altmann" - ["4135804ae488d8c574611298488540b5e868dd4d"]="Nick Altmann" - ["1a45f19c7911bae211a83883874e6408842afceb"]="Nick Altmann" - ["4822b9c83a7da4191eb9c67ae5e739598f2fbee8"]="Nick Altmann" - ["28135f150c6d5268bf1d99ff6be68e9eb8f78e00"]="Nick Altmann" - ["099adbe9f944afcd3cfc16ea1a470ea25e76860e"]="Nick Altmann" - ["2c35387a83353a6d3e7a1cdc1ee1853c167e44b4"]="Ovidiu Sas" - ["2e15877aab36ce18d71d06700dd7578c7831fa69"]="Ovidiu Sas" - - # benchmark - ["6409da30683a081671eddaba08bdfcc5f5aaee00"]="David Sanders" - ["db65db5b74d24731394027cda7ceed94efb76d7b"]="David Sanders" - ["daaeafc070c62ce5fd21db07358573a9005442df"]="Stanislaw Pitucha" - ["737f38461ca5478841d455d7114aff63e65fa4a7"]="Stanislaw Pitucha" - ["567edd786e8a71ba831ce596603e1cba62dbeed8"]="Stanislaw Pitucha" - - # cachedb_mongodb - ["18045793ada31f8f9f36d2b68b36e566456687dd"]="@jalung" - - # cachedb_redis - ["e6847255b104518d53c1d04716a3520872053dd7"]="Ezequiel Lovelle" - - # call_control - ["4a4c9535f8b08b88d242e83c0bccce1298eb9dc8"]="Mauro Davi" - - # carrierroute - ["84041cb08d95061da268d303342946b3e6f29f96"]="Jonas Appel " - ["fb3e4e46d9f884aa4d2371e4b767c728305f27c1"]="Henning Westerholt" - ["38ecf98329ecfddfd3dbc3c8a4879139e8e602ac"]="Henning Westerholt" - ["7817142c27a5a59bb2403dd4b6390231b8c35881"]="Sergio Gutierrez" - ["d99f65c970fa3198477a30cdb3e84a10faf049cd"]="Henning Westerholt" - ["81660a52292d1bd7c5d998a14ce7949cf6b8d744"]="Hardy Kahl " - ["deb8125173f975c7f03519e40df3ca5606f5771d"]="Hardy Kahl " - ["7290013a0d30210840c23c5ea266645b586ab28b"]="Hardy Kahl " - ["992e8826987ec398be637ddcb0ad4324f1f6bd13"]="Bob Atkins" - ["3bdc5208ea7503205fc0b353ce37f537383ccad3"]="Carsten Bock" - - # db_berkeley - ["cf8c99620c843cf8dfca76dc3dbc2c5928c968a1"]="William Quan" - ["2b52b8d594680488f77e9d511c7bf9937797a42d"]="Jan Janak" - - # db_mysql - ["46b2af2bb646a52fc7072247876cb96e0da0c71a"]="Norman Brandinger" - - # db_oracle - ["e67fb5b8fb4b16e77b9d7c3e2da2c81b74f24635"]="Peter Lemenkov" - ["5c2b21794d6cbe597cc123fdbb75874ee3ab1d8c"]="Peter Lemenkov" - ["85d55c5225b8c60e16d171298c56aac696a3b05e"]="Peter Lemenkov" - ["b0c03645f34a81851d53ee8b0a02ef83a1144f57"]="Peter Lemenkov" - - # db_postgres - ["9e6730ec4d2e876f6b2372f1b5fb5703112079fc"]="Ruslan Bukin" - ["2d80fcf1cfed82680a016fe723da03a303f73aff"]="Norman Brandinger" - - # db_text - ["e8c8262d23b26bdb45b8074c6e518825ea0ca6de"]="Henning Westerholt" - ["9391890a8123bc5c7fef594163e0179d334d5bde"]="Chris Heiser" - - # db_unixodbc - ["659d79da476ef7eed6d39a3bc8f5ec995930afe7"]="Marco Lorrai " - ["09134cc7343b21ac9c7e06d8d202dc55be1433b0"]="Alex Massover" - ["a3eca3ca69531a6bd00dca2f921c32262a17fae3"]="Carsten Bock" - - # dialog - ["b200e11cf0308ab12c9562c552d69b1a78c52576"]="Nick Altmann" - ["0468b6afabd2c343910c151411607ee29961921b"]="Ryan Bullock" - ["70c7f34692e3b6652e412da3f6de1328c0cfcde0"]="Walter Doekes" - ["477997f42f00321cd43310c29c56361bec6c95b0"]="Alex Massover" - ["fd0634ff51108722f97731e4c5bf709067d79667"]="John Riordan" - ["9cc90e6bd51ab940788fc77e23e3420dbae36228"]="John Riordan" - ["25faec5c54950288aa49f412f043caaa559fbd39"]="John Riordan" - ["afa190d872003e9c259c8e4424040fa9b55835f3"]="Hugues Mitonneau" - ["c264a11b0c29060b4658ea40428c41ec9d731a5b"]="Hugues Mitonneau" - ["1ae905901b94d8be0c44f9cb5e73ad81def63721"]="Richard Revels" - ["26fe61533a2a4144c6a985ddf399daefebd8b855"]="Hugues Mitonneau" - ["7937df2a9a3ed5961b34a5e43210b262f71116c0"]="Alex Hermann" - ["c008a1b0d1695abc184762b08bff4520bdd1b546"]="Henning Westerholt" - ["8e9ce5dc3e29a132ff1dbf58a51a44e09be097f4"]="Carsten Bock" - ["b1fa1bf71de29cc35e9476ee06bdea687db98070"]="Carsten Bock" - ["4685d0c026f6523d5563f1235dc1b41f02839ca3"]="Ovidiu Sas" - ["76a86f7c9f9d61efa83163f09d879961090db4a1"]="Carsten Bock" - ["937e6a88db9f41b93f57f805097c5513fca3a11f"]="Jerome Martin" - ["08fe6e2f97ae48a47d8d4041b540ad464f68bb4b"]="Jerome Martin" - ["aaed9b11cfd138e64f7152b2f1bb9d5e868ff271"]="Tavis Paquette " # 3x - ["cb5322df66ecd2baff2ea501b49ca111dc89a000"]="Michel Bensoussan " # 2x - ["0359f75caa06cb58b09e96e1322573c13aea81dd"]="Eliot Gable " # 2x - ["b2b4305dd5217696d41dfbccc9477d0f2408f777"]="Andy Pyles" - ["8be8f9df614c327a48e88356b3eb8c30774a84dc"]="Ron Winacott " - - # dialplan - ["0a7ef1191c25b81d52898dc78bdb87b7be0b1958"]="Rudy Pedraza" - ["67c04b2ded9ff89ee3f39def4769d735044edb74"]="Sergio Gutierrez" - ["e10369ed4237fdb66a85e162db3b84dd8ab89d44"]="Paul Wise" - ["69b37814c291ff02b9528f041b4ae0b569a6adec"]="Henning Westerholt" - - # dispatcher - ["83ec071d880400bb5c29ad6ab1df1a625f2b2020"]="Nick Altmann" - ["d1887831d1488d7ab96c76e3cc207095a35052bf"]="Walter Doekes" - ["fbda02ff646e321874fba85232e230c454e37c89"]="Stanislaw Pitucha" - ["820f0750fbd772cc8ac7a732203c69c511ab335d"]="Kevin McAllister" # really? - ["3f93ea0590cbb9c313ed00172b6d38ff68ef9d6f"]="Carsten Bock" - ["0de42c5b2b9f35a983f59c925a10ccf08a544ca6"]="Konstantin Bokarius" - ["897bfced489fd078b12c1c6f53f83d6e6d7d9780"]="Carsten Bock" - ["50e5eaed15c8ce97770f27401908c8e94369cabb"]="Carsten Bock" - ["8154621da217f1f36f3064c0fa4dc14e57014288"]="Federico Cabiddu" - ["42e1a8a845af64d6cce226bb8278425ce9e1508a"]="Carsten Bock" - - # domain - ["6a6a595095d8983561b1b36357f4d47ccb13bf81"]="Juha Heinanen" - ["f62684327c13f29f273ac8a97e0041f79d97621c"]="@coxx" - - # drouting - ["64da0da6fb2406eed788fa69522545dbddfeeb19"]="Nick Altmann" - ["23f8ae3bd60018a0acbe68bc16c37c27bb661e01"]="Matt Lehner" - - # emergency - ["e1bbbe5ea4b87b6c127a1200e50d56f2ff0947d4"]="Evandro Villaron" - - # enum - ["2bbf6364bf30a2aaaef3259ede8bf90c44036d8c"]="Juha Heinanen" - ["f089ca434dc5416d0a86ad663aab1fbe879b9eae"]="Greg Fausak " - ["85b05c11d3390bb00e6cc096d329eeb24571f774"]="Klaus Darilion" - - # event_xmlrpc - ["0a69df1a113bd288aad2952ace55c42a8dfe1214"]="Ryan Bullock" - - # exec - ["66c27dd0a37a2a083990c77e85b4f0574a0ff4b0"]="Dror Wald" - - # gflags - ["5a2468d1c38a8459cee1c0e923ebfd1c3972d77c"]="Richard Revels" - - # identity - ["3cbf9b62a88738da14a367a64896308b5878e622"]="Alexander Christ" - - # jabber - ["e9f3bbf62c7adabad87a209653885a12eba6a596"]="Peter Lemenkov" - - # json - ["596271ae13bb28669a4d907885c0303165b708fb"]="Nick Altmann" - - # ldap - ["faea9a5e2025b5f10d147888fcf380a6cb1ebe64"]="Christian Schlatter" - - # load_balancer - ["df5956eb76347611ec50a98e64a3c6c138ea94b6"]="James Van Vleet" - - # lua - ["b95f0d139e7e2b74c258582cb6b9b727c95f7ca2"]="Arnaud Chong + Eric Gouyer" - - # mediaproxy - ["08c743ac8e90dcb04cd58daae5e28ef4ea6ecc1f"]="Sergio Gutierrez" - - # mi_datagram - ["6cf68d21fbee033eebb17966bb8aa74f037f70d7"]="Ancuta Onofrei " - - # mi_fifo - ["dccde2318d302463cc0e3439b0ff3d8c4a5a9d25"]="Jerome Martin" - - # mmgeoip - ["8ecf19894a61acbfce0b5f3dc36b3bf6ce925118"]="Kobi Eshun" - - # msilo - ["fe1e5ce3e4113da6f6645419236dfef958edaeaa"]="Stanislaw Pitucha" - ["7b371e11fda16ae247d1068e1d1ce4ba25406f61"]="Aron Rosenberg" - ["d9c5d5ed9e7c4a14889d60394f8bcd5c21899aef"]="Juha Heinanen" - ["f81018ef34d1afe789c015b801bfec0b5142c2b0"]="Andrea Giordana" - - # nathelper - ["d8a8c377163ad466238bb3f621b49de622966b58"]="John Riordan" - ["a3eb777997fd62f66f0e7b1f6eabe9bfe472845d"]="Emmanuel Buu" - ["53358d7798d88db9e843d7ffb557aa9cc5cc2a5f"]="Christophe Sollet" - ["8d105420558f2b204142b9b9312264c2ea31507b"]="Carsten Bock" - ["fde24edbe45f98961de48fabde64b0e5fd201726"]="Ancuta Onofrei " - ["e306d9832e85455d56b38276e2d4fe0bdeb50ab4"]="Ancuta Onofrei " - ["22f8a8c7f336d6ee7cdbbd03d16f8f1ea13adbf2"]="Jeremie Le Hen" - ["a2b31ed575d436b94cec2e2a732b2a13ac08250f"]="Laurent Schweizer " - ["c20047dbd0657d7ef3d84d3dd35f9fe0c1557da9"]="Bayan Towfiq " - ["201e8120c654ff7f175ab9a43ea08978b6680e8b"]="Andrei Pelinescu-Onciul" - - # nat_traversal - ["ffb830f588bd57239474f8d6ef786b2e1a92b51a"]="Stéphane Alnet" - - # perl - ["743879030d9174f12b187ae3095628b016317d71"]="Boris Ratner" - ["0ad2cfad20f4f16717f9c2e5e56632fd1acbec34"]="Julien Blache" - - # permissions - ["97973e49590ef69e8ec86f2fa929d08a1a3d5ef7"]="Saúl Ibarra Corretgé" - - # pike - ["78e97babb5511cde3b37846e5ea7c61613d4e784"]="Andrei Pelinescu-Onciul" - - # presence - ["3c8f45538412e1544fa4fb551d1d5804995074aa"]="Walter Doekes" - ["ec31054f89e769e68bec060cec8a63788afcb238"]="Walter Doekes" - ["25914e36b19ac167d57156037c4aa178b8781598"]="Ovidiu Sas" - ["e28be091719ec84f0afd0f90a24e5d1f82d76e56"]="Kennard White" - ["8fc84e33d370898ca7b576324ee036dfa24b1c9d"]="Vasil Kolev" - ["23017aa50be8ec71d23d6e79df53c8b644defece"]="Kobi Eshun" - ["b478c4d8e5b12cbad21079cf7e2194699ccf05ae"]="Klaus Darilion" - ["8800e14409aaf4b27557f4325b40edb578b268bf"]="Kobi Eshun" - ["79dfdd2f11323ce1a1da311b4f56b415a2f6fcf1"]="Denis Bilenko " - ["a143ee8d8c7113994a66429c9f1ab1255a0ce5a5"]="Stanislaw Pitucha" - ["f7159bb5a483bb535f9c892faf7a5be78922b75c"]="Benny Prijono" - - # presence_xml - ["09717cf71cb28e9cb7b7747b170c45bb49d540df"]="Kennard White" - - # proto_smpp - ["09b42266130943905938566752bf2e7855c13355"]="Victor Ciurel " - - # pua - ["2fb5fb43c22513ca50f2d84135339c7f7dd6b7a8"]="Alex Hermann" - ["1639775961bdedec0a89269330324297f675d54a"]="Denis Bilenko " - ["02258a0c8ef1050019f3852ad4251f32183de6be"]="Denis Bilenko " - - # pua_dialoginfo - ["6d213ecdd514c76c4c2a5cddca3959c2bda6e619"]="Vallimamod Abdullah" - - # ratelimit - ["684b452b8137200902d037f76b7a345d82bb1986"]="Stanislaw Pitucha" - ["d31fa0623948c7db2b3c93b844a8048f46ec1b82"]="Arnaud Boussus" - ["964397d5a9ecd0773aceed8652d20e477b719b09"]="Sergio Gutierrez" - - # regex - ["8ae90ece51d3ebf014fa87793234462a9faeee7c"]="Marius Zbihlei " - - # registrar - ["c2a0e7e7164d2fc7bba79351dcf126af4f2e79c2"]="@jalung" - ["e5cb9805bcae7b9fb0d5391e3c5cc0f54eb65107"]="Nick Altmann" - ["54e027adfa486cfcf993828512b2e273aeb163c2"]="Tolga Tarhan" - ["03b5a2a19d9ace2ba7877c943d41b7bdc506bf9c"]="Nick Altmann" - ["313208b7e0fa47801637a99bbc6868c0cf4bbe12"]="Ruslan Bukin" - ["94143b0943a2219fa245bc4978f529927b66ad59"]="Kobi Eshun" - ["32d0696642d14c0f100baf46b9a6ed2efc5a3b97"]="Carsten Bock" - ["7c0b5a2759dddb6a162de001582aaa3d7f3551ed"]="Andreas Granig" - ["f93722815873572e90d5c038df7a57964bd06522"]="Dmitry Semyonov" - - # rr - ["ec83f6af09176aef1e09aaa969067b87e175e915"]="Ovidiu Sas" - - # rtpproxy - ["1e5a965fc10f3fb7016d929d661e11c6484a2e62"]="Maxim Sobolev" - ["d4b0b7e31fa9dd602751c372ca3557536982e540"]="Ryan Bullock" - ["643ac134a0b8f0cf4e6f24215dce1356f68ad792"]="Peter Lemenkov" - ["7d6e628a49f4c0348ab84cda9f4baffcbb5f0701"]="Peter Lemenkov" - ["35d7cbe54d601b2d08d767a1385439c5b63e70a4"]="Walter Doekes" - ["fbade8479291ea91d73b5dde5aa990d39dd7054d"]="Christophe Sollet" - - # sipmsgops - ["3b37b827746459a538fb86507414d4a26481a946"]="Jarrod Baumann" - ["bcc2fe8a63f03e48bce665bd140bf45114711281"]="Boris Ratner" - ["e3d7a468db8794330b9297c70c98e290c0e1535a"]="Nick Altmann" - ["75c1e8f10ca29eaef3044d3aaad7751fe8b3cbe7"]="Peter Lemenkov" - ["9df587143764ec86958244a29ddfbceeed323d66"]="Walter Doekes" - - # siptrace - ["3d39c0b6fcc2ae698dd7ee7f3cd2646f07fcd4af"]="Sergio Gutierrez" - - # sl - ["86a3afd75396c3ce3e748c8d1e316115c9503317"]="Andreas Heise" - - # snmpstats - ["ac87253a439ac390c3433b34a6e9cb3e6e50ad6c"]="Sergio Gutierrez" - ["237bb3d33158722e240fe5ffc2b42d735643b15b"]="Anca Vamanu" - ["8e6edeaf362d17af67fba1f87e3ad6369e5fa2b8"]="Ovidiu Sas" - ["3f42350b554c293cc8a46cf55f3e59e1d258dbd4"]="Ovidiu Sas" - - # sst - ["1f14961143343b80e682f8436b353921b7309fb1"]="Christophe Sollet" - ["034e61d1fed5c2e7ef3917f7e827a562486a0bf7"]="Ron Winacott " - - # stir_shaken - ["129834d125e3179ae60e56e4fc485b1ad74f9cc7"]="John Burke " - - # textops - ["ad7f17082aef12211d85d2f1ec0694c4ff21bbef"]="Christophe Sollet" - ["ca2a72ee03ce7886a3e47af78da72a8967100db5"]="Hugues Mitonneau" - ["cf883b8921664ac38aa3ea4b1a61c4db8d99e9e9"]="Andreas Granig" - ["f214c9d3329b66649c79d5f73714324b4c0ede93"]="Marc Haisenko " - - # tm - ["1e2275aeb9df0b7406b0eea3d34229e7fbf44df0"]="Christophe Sollet" - ["b78774d0074a3e24c53854537a829c94b9281599"]="Saúl Ibarra Corretgé" - ["076d4e559d2cab8f790920adf2cd9cf68023e1d2"]="Anonymous" - ["04697ee81923ca1a663fdc36c5afc04eff6b544b"]="Mark Dalby" - ["428c1118a63845da5494e99568ce20bf83d9608e"]="Ovidiu Sas" - ["b63e314d87816e7cfa0b65d5bd6eb3007102b25f"]="Christophe Sollet" - ["87b5a216c842ebfd3e51f24b3377ae3219acc562"]="Marcus Hunger " - ["0b0529ceabacacde96c856a5c25ffcb78ca58d3e"]="Marcus Hunger " - ["28f22ad32259f27e285bb7cc45384fe755fe6878"]="Elias Baixas " - ["1bae4b932a5b59302d10daac518906a812eef97e"]="Jeffrey Magder " - ["57cdee3e9b1c6c763e2c663129421d26eab28f89"]="Juha Heinanen" - ["ce2c9565ee35964066052302ce2ccce95e043b97"]="Juha Heinanen" - ["964531fd56eef000f4f11558c1cba94ae2ac10f3"]="Daniel Hsueh " - ["f176f04b8e2158c9afdcb50cf72499a3360d35c5"]="Ingo Wolfsberger " - ["4e75ee84ca601eb33747a2fbe544d210c4249d1b"]="Andrei Pelinescu-Onciul" - ["0f0f44c4d48e0ce60ac226efde221a44702969e7"]="Maksym Sobolyev " - ["2f43c7326f5b87b6db41b244415070efdcbfdccb"]="Jan Janak " - - # uac - ["d53ed37767b4b02e26ea68c49dfcac960ac193ab"]="Andreas Heise" - ["a4c4924c60b9d29f126c5a283c1b901b6c30afa4"]="Andreas Heise" - - # userblacklist - ["c3448532a15113ff930df13a6c2ef33fd85d8420"]="Ruslan Bukin" - ["55ce032dcdbe6253f973a3e0dca834ab3bce4751"]="Hardy Kahl " - - # usrloc - ["de0e58a5952df7c482e78920b5ee67e5bfd0635e"]="@jalung" - ["f434101fbe7f704f10cd55c24cc3d624b9e44771"]="Iouri Kharon " - ["41d3799f1cbd36ea04135e9b322c0f60de64cba7"]="Matthew M. Boedicker " - ["fe11b2a681da77ddc5ddf02ffa9453d5d87879e2"]="Jeffrey Magder " - ["b8ffcb70fbb66f9f873692d611a20402f53459ee"]="Klaus Darilion" - - # xcap_client - ["eae1d5a75118f919e4d0f707a8272e5301552a42"]="Romanov Vladimir " -) - -# Commits which should be ignored: merge commits, auto-generated -# files, copy-pasted libraries, etc. -declare -A skip_commits -skip_commits=( - ["d88a1e2f6df5e591dd4162e2fa2e6e08d93e1c96"]=1 # 13 Jun 2005, initial import - ["a5b72648f928547d87c06c269b3118ae97b97aa4"]=1 # 13 Jun 2005, cherry-pick - ["33b4d7c82f186e66311c9f215b76d55324f45adc"]=1 # 15 Jun 2005, cherry-pick - ["251cc10f454050dba8f31653ee3e4c4cda87a74a"]=1 # 15 Jun 2005, cherry-pick - ["b1ff52999c48688ae228e76ffa64e64f75d57b0d"]=1 # 16 Jun 2005, merge w/ SER - ["d41d30a8af8b79f00947dfc9600699f62b210d4d"]=1 # 16 Jun 2005, merge w/ SER - ["d55ce8ffc86dd433f4860d5867d03d484312d954"]=1 # 16 Jun 2005, merge w/ SER - ["442a83e55bb475637e75fc904f998e6d585bd437"]=1 # 16 Jun 2005, merge w/ SER - ["8fe24ec1990a1c468fcf8490228c2fcd42a15121"]=1 # Jan 2017, import FS ESL -) - -# "git log" cannot properly follow an entire directory throughout all its -# historical renames, so we use this array in order to solve the problem -# -# []= provision such an entry for each rename -# (if a -> b -> c, then you need 2 entries) -declare -A mod_renames -mod_renames=( - [db_mysql]=mysql - [db_postgres]=postgres - [db_text]=dbtext - [db_flatstore]=flatstore - [db_unixodbc]=unixodbc - [db_perlvdb]=perlvdb - [cpl_c]=cpl-c - [auth_aaa]=auth_radius - [cachedb_local]=localcache - [uac_registrant]=registrant - [tracer]=siptrace - [stir_shaken]=stir - [mi_http]=mi_json:1540473075: # old_module:new_module_since:old_module_until - [mi_html]=mi_http::1540473075 - [event_stream]=event_jsonrpc - [b2b_logic]=b2b_logic:1605638778 - [b2b_logic_xml]=b2b_logic::1605638778 - [sqlops]=dbops - [dbops]=avpops - [event_rabbitmq]=rabbitmq -) - -mk_git_handle() { - if [[ "$1" =~ ^@ ]]; then - echo "$1" - elif [ -n "${github_handles["$1"]}" ]; then - echo " (@${github_handles["$1"]})" - fi -} - -normalize_arrays() { - # enrich the "author_aliases" array with all name-only variants - for author in "${!author_aliases[@]}"; do - auth_name=$(grep -oE "^[^<]*" <<< "$author" | sed 's/\s\+$//g') - [[ ! "$auth_name" =~ ^(root|NAME)$ ]] && \ - author_aliases["$auth_name"]=${author_aliases["$author"]} - - auth_name_rhs=$(grep -oE "^[^<]*" <<< "${author_aliases["$author"]}" | sed 's/\s\+$//g') - [[ ! "$auth_name_rhs" =~ ^(root|NAME)$ ]] && \ - author_aliases["$auth_name_rhs"]=${author_aliases["$author"]} - done - - # normalize the "github_handles" array (include aliases) - for author in "${!github_handles[@]}"; do - [ -n "${author_aliases[$author]}" ] && \ - github_handles["${author_aliases[$author]}"]="${github_handles[$author]}" - done - - if [ -n "$DEBUG" ]; then - for author in "${!author_aliases[@]}"; do - echo "$author: ${author_aliases["$author"]}" - done | sort - fi -} - -# $1 (optional) - git SHA to be taken as a starting point -rebuild_proj_commit_stats() { - __PROJ_COMMITS=0 - __PROJ_LINES_ADD=0 - __PROJ_LINES_DEL=0 - - [ -n "$1" ] && commit_range="$1..HEAD" - - echo "Summing up all OpenSIPS commits! :-O" - - for sha in $(git log --reverse --format=%H $commit_range); do - [ -n "${skip_commits[$sha]}" ] && continue - - lines=($(git show $sha --format= --numstat \ - | awk '{a+=$1; r+=$2}END{print a" "r}')) - [ -z "${lines[0]}" ] && continue - - __PROJ_COMMITS=$((__PROJ_COMMITS + 1)) - __PROJ_LINES_ADD=$(($__PROJ_LINES_ADD + ${lines[0]})) - __PROJ_LINES_DEL=$(($__PROJ_LINES_DEL + ${lines[1]})) - echo -en "\rProcessing commit #$__PROJ_COMMITS" - done - - if [ -n "$1" ]; then - echo "Commits: $__PROJ_COMMITS" - echo "Lines++: $__PROJ_LINES_ADD" - echo "Lines--: $__PROJ_LINES_DEL" - echo " ... since: $1" - return - fi - - sed -i "s/^__PROJ_COMMITS.*/__PROJ_COMMITS=$__PROJ_COMMITS/" $0 - sed -i "s/^__PROJ_LINES_ADD=.*/__PROJ_LINES_ADD=$__PROJ_LINES_ADD/" $0 - sed -i "s/^__PROJ_LINES_DEL=.*/__PROJ_LINES_DEL=$__PROJ_LINES_DEL/" $0 - sed -i "s/^__LAST_REBUILD_SHA=.*/__LAST_REBUILD_SHA=$(git log -1 --format=%H)/" $0 -} - -count_dir_changes() { - for sha in $(git log --reverse --format=%H $2 modules/$1); do - [ -n "${skip_commits[$sha]}" ] && continue - - show="$(git log $sha -b --no-walk --find-renames --format="$(echo -e "%an <%ae>")" --numstat | grep -vE "modules/.*(README|contributors\.xml|\.html|\.sw[po])")" - - # grab the overrided author or just the commit author - if [ -n "${fix_authors[$sha]}" ]; then - author=${fix_authors[$sha]} - else - author=$(echo "$show" | head -1) - fi - - # convert any author aliases - [ -n "${author_aliases[$author]}" ] && author="${author_aliases[$author]}" - - commit_date=$(git show --format=%aD --no-patch $sha | awk '{print $2","$3","$4}') - - added="$(echo "$show" | grep -E "modules/$1" | awk '{s+=$1}END{print s}')" - deleted="$(echo "$show" | grep -E "modules/$1" | awk '{s+=$2}END{print s}')" - [ -z "$added" -a -z "$deleted" ] && continue - - echo "$1: $sha - ${commit_date//,/ } - $author - ${added:-0}++ ${deleted:-0}--" - - commits["$author"]=$((${commits["$author"]:-0} + 1)) - add["$author"]=$((${add["$author"]:-0} + ${added:-0})) - del["$author"]=$((${del["$author"]:-0} + ${deleted:-0})) - - [ -z "${first_commit["$author"]}" ] && first_commit["$author"]="$commit_date" - last_commit["$author"]="$commit_date" - done -} - -_count_module_changes() { - if [ -n "${mod_renames[$1]}" ]; then - IFS=':'; local arr=(${mod_renames[$1]}) - local old_mod="${arr[0]}"; local since="${arr[1]}"; local until="${arr[2]}" - unset IFS - - # deal with renames, e.g.: - # * mi_html->mi_http, mi_http->mi_json - # * b2b_logic->b2b_logic_xml, NEW_MOD->b2b_logic - [[ $1 != $old_mod ]] && [ -z "$3" -o -z "$since" ] && \ - _count_module_changes "$old_mod" "$2" "recurse" "$until" - fi - - if [ -n "$4" ]; then - time_cond="--until $4" - elif [ -z "$3" -a -n "$since" ]; then - time_cond="--since $since" - else - time_cond= - fi - - mkdir -p modules/$1$2 - count_dir_changes "$1$2" "$time_cond" - if [ "$3" == "recurse" -a -z "$time_cond" ]; then - rm -r modules/$1 - fi -} - -count_module_changes() { _count_module_changes "$1" ""; } -count_module_doc_changes() { _count_module_changes "$1" "/doc"; } - -# $1 - module name, e.g.: "tm", "cachedb_mongodb" -gen_module_contributors() { -unset score -unset commits -unset add -unset del -unset first_commit -unset last_commit - -declare -A score -declare -A commits -declare -A add -declare -A del -declare -A first_commit -declare -A last_commit - -tmp_file=$(mktemp $TMP_FILE.XXXXXXXXXXX) - -count_module_changes $1 - -for i in "${!commits[@]}"; do - score[$i]=$(python -c "from math import ceil; print(int(${commits[$i]} + ceil(${add[$i]} / ($__PROJ_LINES_ADD/float($__PROJ_COMMITS))) + ceil(${del[$i]} / ($__PROJ_LINES_DEL/float($__PROJ_COMMITS)))))") -done - -declare -A sorted_scores - -( - export LC_ALL=C - for i in "${!score[@]}"; do - echo "$i,${score[$i]},${commits[$i]},${add[$i]},${del[$i]},${first_commit[$i]},${last_commit[$i]}" - done | sort -t, -k2nr -k3nr -k4nr -k5nr -k1 >$tmp_file -) - -####### Generate table #1 (by commit statistics) - -cat <modules/$1/doc/contributors.xml - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - -EOF - -mk_author_xml_str() { - author="$1" - gh=$(mk_git_handle "$author") - [[ "$author" =~ ^@ ]] && author= - - if [ -n "$SHOW_AUTHOR_EMAIL" ]; then - echo "$(echo "$author" | sed 's//\>/g')$gh" - else - echo "$(echo "$author" | grep -oE "^[^<]*" | sed 's/\s\+$//')$gh" - fi -} - -index=1 -side_authors= -while read line; do - author_str=$(mk_author_xml_str "$(echo $line | awk -F'[,]' '{print $1}')") - - if [ $index -gt $TABLE_SIZE_COMMITS ]; then - side_authors+="$author_str, " - continue - fi - - cat <>modules/$1/doc/contributors.xml - - $index. - $author_str - $(echo $line | awk -F, '{print $2}') - $(echo $line | awk -F, '{print $3}') - $(echo $line | awk -F, '{print $4}') - $(echo $line | awk -F, '{print $5}') - -EOF - index=$(($index+1)) -done < $tmp_file - -if [ -n "$side_authors" ]; then - side_authors_para="All remaining contributors: ${side_authors::-2}." -else - side_authors_para= -fi - -cat <>modules/$1/doc/contributors.xml - - -
-$side_authors_para - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -EOF - -####### Generate table #2 (by commit activity) -cat <>modules/$1/doc/contributors.xml -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - -EOF - -( - export LC_ALL=C - for i in "${!score[@]}"; do - echo "$i,${first_commit[$i]},${last_commit[$i]}" - done | sort -s -t, -k7.1,7.4nr -k6.1,6.3fMr -k5nr -k4.1,4.4n -k3.1,3.3fM -k2n -k1 >$tmp_file -) - -index=1 -side_authors= -while read line; do - author_str=$(mk_author_xml_str "$(echo $line | awk -F'[,]' '{print $1}')") - - if [ $index -gt $TABLE_SIZE_ACTIVITY ]; then - side_authors+="$author_str, " - continue - fi - - cat <>modules/$1/doc/contributors.xml - - $index. - $author_str - $(echo $line | awk -F, '{print $3" "$4" - "$6" "$7}') - -EOF - index=$(($index+1)) -done < $tmp_file - -if [ -n "$side_authors" ]; then - side_authors_para="All remaining contributors: ${side_authors::-2}." -else - side_authors_para= -fi - -cat <>modules/$1/doc/contributors.xml - - -
-$side_authors_para - - (1) including any documentation-related commits, excluding merge commits - -
- -
-EOF - -####### Generate "documentation authors" list - -unset first_commit -unset last_commit -declare -A first_commit -declare -A last_commit - -count_module_doc_changes $1 - -( - export LC_ALL=C - for i in "${!first_commit[@]}"; do - echo "$i,${first_commit[$i]},${last_commit[$i]}" - done | sort -s -t, -k7.1,7.4nr -k6.1,6.3fMr -k5nr -k4.1,4.4n -k3.1,3.3fM -k2n -k1 >$tmp_file -) - -doc_authors= -while read line; do - doc_authors+="$(mk_author_xml_str "$(echo $line | awk -F'[,]' '{print $1}')"), " -done < $tmp_file - -if [ -n "$doc_authors" ]; then - doc_authors_para="Last edited by: ${doc_authors::-2}." -else - doc_authors_para= -fi - -cat <>modules/$1/doc/contributors.xml - - Documentation -
- Contributors - $doc_authors_para -
- -
-EOF - -rm $tmp_file -} - -graceful_exit() { - set +e - # stop all jobs - if [ -n "$PARALLEL_BUILD" ]; then - for pid in ${pids[@]}; do - killall -q $pid - wait $pid - done - fi - - rm $TMP_FILE* - exit 1 -} - -############################################################################### - -set -e - -if [ ! -r .git ]; then - echo "Please run this script from the root opensips directory!" - exit 1 -fi - -if [ $# -eq 0 ]; then - echo "Usage: $0 ([, [, ...]] | rebuild-proj-stats)" - echo "For best results, please run with git 2.7.4+" - exit 0 -fi - -normalize_arrays - -# if not already done, graft the entire git history of the SER project -if [[ ! $(git log --reverse --format=%H | head -1) =~ ^f06ade ]]; then - remote=$(git remote -v | grep -i "OpenSIPS/opensips.git.*fetch" | awk '{print $1}') - git fetch ${remote:-origin} 'refs/replace/*:refs/replace/*' -fi - -if [[ "$1" =~ rebuild-proj-stats ]]; then - rebuild_proj_commit_stats "$2" - exit 0 -fi - -trap graceful_exit INT TERM - -pids=() -while [ -n "$1" ]; do - mod="$(basename $1)" - - if [ -n "$PARALLEL_BUILD" ]; then - gen_module_contributors "$mod" & - pids+=($!) - echo -en "\rForked job #${#pids[@]}" - else - gen_module_contributors "$mod" - - if [ -n "$DEBUG" ]; then - make modules-docbook-html modules=modules/$mod - xdg-open "file://$(pwd)/modules/$mod/doc/$mod.html#contributors" - fi - fi - - shift -done - -if [ -n "$PARALLEL_BUILD" ]; then - for pid in ${pids[@]}; do - wait $pid - done -fi - -if [ -n "$DEBUG" ]; then - echo "Total: $__PROJ_COMMITS commits. $__PROJ_LINES_ADD++, ${__PROJ_LINES_DEL}--" -fi diff --git a/doc/module-docbook.css b/doc/module-docbook.css deleted file mode 100644 index 0534ed83bcf..00000000000 --- a/doc/module-docbook.css +++ /dev/null @@ -1,290 +0,0 @@ -BODY { - padding: 20px; - margin: 5px 50px 5px 50px; - background: #ffffff; - color: #000000; - width: 700px; - border: solid 2px #888888; - font-family: Helvetica,Arial; -} - -P { - font-family: Helvetica,Arial; - font-size: 12; - text-align: justify; -} - -P.C2 { - COLOR: #ffffff ; - BACKGROUND-color: #a0a0d0; - BORDER: solid 1px #606090; - PADDING: 1px -} - -A { - color: #041fc5; - text-decoration: none; -} - -A:hover { - color: #990000; - text-decoration: underline; -} - -DIV.ABSTRACT { - border: solid 2px; - padding-left: 10pt; - padding-right: 10pt; -} -PRE.SCREEN { - font-family:monospace; - white-space: pre; - background-color: #fefeee; - border:solid; - color: #000000; - border-color: #99CCCC; - border-left: solid #99CCCC 1px; - border-right: solid #99CCCC 1px; - border-top: solid #99CCCC 1px; - border-bottom: solid #99CCCC 1px; - padding-left: 15pt; -} - -PRE.PROGRAMLISTING { - font-family:monospace; - white-space: pre; - background-color: #fefeee; - border:solid; - color: #000000; - border-color: #99CCCC; - border-left: solid #99CCCC 1px; - border-right: solid #99CCCC 1px; - border-top: solid #99CCCC 1px; - border-bottom: solid #99CCCC 1px; - padding-left: 15pt; -} - -H1 { - color: #000000; - border: solid 2px #a0a0a0; - background-color: #DCDCDC; - font-variant: small-caps; - font-size: 16; - padding-left: 5px; -} - -.TITLE a { - color: #000000; - text-decoration: none; -} - -.TITLE a:active { - color: #000000; - text-decoration: none; -} - -.TITLE a:visited { - color: #000000; - text-decoration: none; -} - -H2 { - COLOR: #000000 ; - font-style: italic; - border: solid 1px #b0b0b0; - background-color: #ECECEC; - padding-left: 5px; - font-family: Helvetica,Arial; - font-weight: bold; - font-size: 14; -} - -H2 a { - color: #000000; - text-decoration: none; -} - -H2 a:active { - color: #000000; - text-decoration: none; -} - -H2 a:visited { - color: #000000; - text-decoration: none; -} - -H2 a:hover { - color: #000000; - text-decoration: none; -} - -H3.SECTION { - COLOR: #000000 ; - font-style: italic; - border: solid 1px #c0c0c0; - background-color: #F2F2F2; - padding-left: 5px; - font-family: Helvetica,Arial; - font-weight: bold; - font-size: 13; -} - -H3 a { - color: #000000; - text-decoration: none; -} - -H3 a:active { - color: #000000; - text-decoration: none; -} - -H3 a:visited { - color: #000000; - text-decoration: none; -} - -H3 a:hover { - color: #000000; - text-decoration: none; -} - -H3.AUTHOR { - font-family: Helvetica,Arial; - font-weight: bold; - font-size: 13; -} - -H3.EDITOR { - font-family: Helvetica,Arial; - font-weight: bold; - font-style: italic; - font-size: 11; -} - -H4 { - font-family: Helvetica,Arial; - font-weight: bold; - font-size: 12; -} - -table { - border-collapse: collapse; -} - -/* -table, th, td { - border: 1px solid black; -} -*/ - -th, td { - padding: 5px; -} - -th { - background-color: #d5f3f3; - color: black; -} - -tr:hover {background-color: #f5f5f5;} -tr:nth-child(even) {background-color: #fefeee;} - -TABLE.IMPORTANT { - font-style:italic; - border: solid 2px #ff0000; - width: 70%; - margin-left: 15%; -} - -TABLE.CAUTION { - font-style:italic; - border: ridge 2px #ffff00; - width: 70%; - margin-left: 15%; -} - -TABLE.NOTE { - font-style:italic; - border: solid 1px #000000; - width: 70%; - margin-left: 15%; -} - -TABLE.TIP { - font-style:italic; - border: solid 1px #000000; - width: 70%; - margin-left: 15%; -} - -TABLE.WARNING { - font-style:italic; - font-weight: bold; - border: ridge 4px #ff0000; - width: 70%; - margin-left: 15%; -} - -DIV.VARIABLELIST { - font-family: sans-serif; - font-style: normal; - font-weight: normal; - padding-left: 20px; -} - -.VARLISTENTRY { - font-weight: bold; - margin-top: 10px; - COLOR: #ffffff ; - BACKGROUND-color: #a0a0d0; - BORDER: solid 1px #606090; - PADDING: 1px -} - -DIV.NAVFOOTER { - color: #000000; - background-color: #EFEFF8; - padding: 5px; - margin-top: 10px; - width: 100%; - border: thin solid #a0a0d0; -} - -DIV.NUKEFOOTER { - color: #000000; - background-color: #B0E0E6; - padding: 5px; - margin-top: 10px; - width: 100%; - border: thin solid #a0a0d0; -} - -DIV.NAVHEADER { - color: #000000; - background-color: #EFEFF8; - padding: 5px; - margin-bottom: 10px; - width: 100%; - border: thin solid #a0a0d0; -} - -DIV.SECT1,DIV.SECT2,DIV.SECT3 { - margin-left: 20px; -} - -DIV.EXAMPLE,DIV.TOC { - border: thin dotted #70AAE5; - padding-left: 10px; - padding-right: 10px; - color: #000000; - background-color: #EFF8F8; -} - -DIV.TOC { - margin-left: 20px; - margin-right: 20px; -} - - diff --git a/doc/module_faq.xml b/doc/module_faq.xml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/doc/dbschema/bookinfo.xml b/docs/dbschema/bookinfo.xml similarity index 100% rename from doc/dbschema/bookinfo.xml rename to docs/dbschema/bookinfo.xml diff --git a/doc/dbschema/catalog.xml b/docs/dbschema/catalog.xml similarity index 100% rename from doc/dbschema/catalog.xml rename to docs/dbschema/catalog.xml diff --git a/doc/dbschema/dtd/dbschema.dtd b/docs/dbschema/dtd/dbschema.dtd similarity index 100% rename from doc/dbschema/dtd/dbschema.dtd rename to docs/dbschema/dtd/dbschema.dtd diff --git a/doc/dbschema/xsl/common.xsl b/docs/dbschema/xsl/common.xsl similarity index 100% rename from doc/dbschema/xsl/common.xsl rename to docs/dbschema/xsl/common.xsl diff --git a/doc/dbschema/xsl/db_berkeley.xsl b/docs/dbschema/xsl/db_berkeley.xsl similarity index 100% rename from doc/dbschema/xsl/db_berkeley.xsl rename to docs/dbschema/xsl/db_berkeley.xsl diff --git a/doc/dbschema/xsl/dbschema2docbook.xsl b/docs/dbschema/xsl/dbschema2docbook.xsl similarity index 100% rename from doc/dbschema/xsl/dbschema2docbook.xsl rename to docs/dbschema/xsl/dbschema2docbook.xsl diff --git a/doc/dbschema/xsl/dbtext.xsl b/docs/dbschema/xsl/dbtext.xsl similarity index 100% rename from doc/dbschema/xsl/dbtext.xsl rename to docs/dbschema/xsl/dbtext.xsl diff --git a/doc/dbschema/xsl/docbook.xsl b/docs/dbschema/xsl/docbook.xsl similarity index 100% rename from doc/dbschema/xsl/docbook.xsl rename to docs/dbschema/xsl/docbook.xsl diff --git a/doc/dbschema/xsl/mysql.xsl b/docs/dbschema/xsl/mysql.xsl similarity index 100% rename from doc/dbschema/xsl/mysql.xsl rename to docs/dbschema/xsl/mysql.xsl diff --git a/doc/dbschema/xsl/oracle.xsl b/docs/dbschema/xsl/oracle.xsl similarity index 100% rename from doc/dbschema/xsl/oracle.xsl rename to docs/dbschema/xsl/oracle.xsl diff --git a/doc/dbschema/xsl/pi_framework_mod.xsl b/docs/dbschema/xsl/pi_framework_mod.xsl similarity index 100% rename from doc/dbschema/xsl/pi_framework_mod.xsl rename to docs/dbschema/xsl/pi_framework_mod.xsl diff --git a/doc/dbschema/xsl/pi_framework_table.xsl b/docs/dbschema/xsl/pi_framework_table.xsl similarity index 100% rename from doc/dbschema/xsl/pi_framework_table.xsl rename to docs/dbschema/xsl/pi_framework_table.xsl diff --git a/doc/dbschema/xsl/postgres.xsl b/docs/dbschema/xsl/postgres.xsl similarity index 100% rename from doc/dbschema/xsl/postgres.xsl rename to docs/dbschema/xsl/postgres.xsl diff --git a/doc/dbschema/xsl/sql.xsl b/docs/dbschema/xsl/sql.xsl similarity index 100% rename from doc/dbschema/xsl/sql.xsl rename to docs/dbschema/xsl/sql.xsl diff --git a/doc/dbschema/xsl/sqlite.xsl b/docs/dbschema/xsl/sqlite.xsl similarity index 100% rename from doc/dbschema/xsl/sqlite.xsl rename to docs/dbschema/xsl/sqlite.xsl diff --git a/doc/doxygen/opensips-doxygen b/docs/doxygen/opensips-doxygen similarity index 100% rename from doc/doxygen/opensips-doxygen rename to docs/doxygen/opensips-doxygen diff --git a/doc/entities.xml b/docs/entities.xml similarity index 100% rename from doc/entities.xml rename to docs/entities.xml diff --git a/docs/manual/Configure-File.md b/docs/manual/Configure-File.md new file mode 100644 index 00000000000..e1b32250d52 --- /dev/null +++ b/docs/manual/Configure-File.md @@ -0,0 +1,47 @@ +--- +title: "Configuration File" +description: "The OpenSIPS configuration file contains all the parameters that control the OpenSIPS core and modules, along with the actual routing logic that OpenSIPS wil..." +--- + +The OpenSIPS configuration file contains all the parameters that control the OpenSIPS core and modules, along with the actual routing logic that OpenSIPS will use to route the SIP traffic. + + + +Upon installation, the default configuration file path is : + +```text + +[INSTALL_PATH]/etc/opensips/opensips.cfg + +``` + + + +The configuration file is text-based, written in an OpenSIPS custom language, very similar to the C language. You will find different variables ( each with different scopes - explained further down the manual ), you can do the classical constructs like if / while / switch, etc, and you can also call sub-routines with parameters, so the script should be fairly easily read-able by somebody with some SIP & programming skills. + + + +> [!IMPORTANT] +> If you do any change to the configuration file, in order for them to take effect, you MUST restart OpenSIPS + + + +Due to the fact that you must restart OpenSIPS every time you make a change to the configuration file, it is of vital importance to ensure that all the changes you have made are correct according to the OpenSIPS language syntax. + +You can check the OpenSIPS configuration file validity by running + + + +```text + +[INSTALL_PATH]/sbin/opensips -C [PATH_TO_CFG] + +``` + + + +When checking the configuration file for validity, If the cfg is OK, OpenSIPS will return 0. + + + +If the config file contains any errors, they will be displayed in the console and OpenSIPS will return -1 diff --git a/docs/manual/Conformance-Tests.md b/docs/manual/Conformance-Tests.md new file mode 100644 index 00000000000..b5ce4100a53 --- /dev/null +++ b/docs/manual/Conformance-Tests.md @@ -0,0 +1,54 @@ +--- +title: "Conformance Tests" +description: "Conformance/Conformity tests are being run in order to validate OpenSIPS behavior in certain scenarios. The goal is to provide insurance that any change to O..." +--- + +Conformance/Conformity tests are being run in order to validate OpenSIPS behavior in certain scenarios. The goal is to provide insurance that any change to OpenSIPS' code (either due to bug fixes or new features) are running according to the desired specifications and that there are no regressions. + +To this end, we have developed a set of tests set that execute OpenSIPS in different scenarios with different SIP flows, and validate that all the involved components (OpenSIPS as well as databases, provisioning, SIP UAs) are inter-operating correctly and their behavior is the expected one. + +--- + +## Setup + +The first requirement is to install [SIPssert](https://github.com/OpenSIPS/SIPssert) - a testing framework capable of orchestrating complex conformance scenarios and verify their execution. You can follow the [install instructions](https://github.com/OpenSIPS/SIPssert#installation) on the project's page. + +Next, we need to fetch the tests available. For the initial setup, we need to clone the repository: +```bash + +git clone git@github.com:OpenSIPS/sipssert-opensips-tests.git + +``` + +If you are targeting a stable release, make sure you specify the OpenSIPS branch/version you need: +```bash + +git clone -b 3.6 git@github.com:OpenSIPS/sipssert-opensips-tests.git + +``` + +Navigate to the tests' directory. If the repository has been previously cloned, make sure you keep it up to date by running: +```bash + +git pull --rebase + +``` + +--- + +## Testing + +Once SIPssert is in place and the tests repository is cloned, you need to navigate to the tests repository and run: +```bash + +sipssert * + +``` + +This command will run all the available tests sets, with the default configuration. If you want to test only a specific tests set, or only a specific test, you may provide additional arguments to the `sipssert` tool. See [Instructions](https://github.com/OpenSIPS/SIPssert#usage) page for more information. + +--- + +## Development + +There is always place for developing new tests, either to ensure old code behaves properly, either to prove that it does not - any contribution is welcome. Therefore, if you have a new test you want to include, feel free to open a pull request on the [project's tracker](https://github.com/OpenSIPS/sipssert-opensips-tests/pulls). diff --git a/docs/manual/Function-Index.md b/docs/manual/Function-Index.md new file mode 100644 index 00000000000..8850c96e630 --- /dev/null +++ b/docs/manual/Function-Index.md @@ -0,0 +1,528 @@ +--- +title: "Function Index" +description: "" +--- + +*Note: Core functions are not included. You can find them [here](Script-CoreFunctions.md).* + +| **Function** | **Module** | +| --- | --- | +| [aaa_does_uri_exist](../../modules/auth_aaa/README.md#func_aaa_does_uri_exist) | [auth_aaa](../../modules/auth_aaa/README.md) | +| [aaa_does_uri_user_exist](../../modules/auth_aaa/README.md#func_aaa_does_uri_user_exist) | [auth_aaa](../../modules/auth_aaa/README.md) | +| [aaa_is_user_in](../../modules/group/README.md#func_aaa_is_user_in) | [group](../../modules/group/README.md) | +| [aaa_proxy_authorize](../../modules/auth_aaa/README.md#func_aaa_proxy_authorize) | [auth_aaa](../../modules/auth_aaa/README.md) | +| [aaa_www_authorize](../../modules/auth_aaa/README.md#func_aaa_www_authorize) | [auth_aaa](../../modules/auth_aaa/README.md) | +| [abort](../../modules/cfgutils/README.md#func_abort) | [cfgutils](../../modules/cfgutils/README.md) | +| [acc_aaa_request](../../modules/acc/README.md#func_acc_aaa_request) | [acc](../../modules/acc/README.md) | +| [acc_db_request](../../modules/acc/README.md#func_acc_db_request) | [acc](../../modules/acc/README.md) | +| [acc_evi_request](../../modules/acc/README.md#func_acc_evi_request) | [acc](../../modules/acc/README.md) | +| [acc_load_ctx_from_dlg](../../modules/acc/README.md#func_acc_load_ctx_from_dlg) | [acc](../../modules/acc/README.md) | +| [acc_log_request](../../modules/acc/README.md#func_acc_log_request) | [acc](../../modules/acc/README.md) | +| [acc_new_leg](../../modules/acc/README.md#func_acc_new_leg) | [acc](../../modules/acc/README.md) | +| [acc_unload_ctx_from_dlg](../../modules/acc/README.md#func_acc_unload_ctx_from_dlg) | [acc](../../modules/acc/README.md) | +| [add_body_part](../../modules/sipmsgops/README.md#func_add_body_part) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [add_diversion](../../modules/diversion/README.md#func_add_diversion) | [diversion](../../modules/diversion/README.md) | +| [add_isup_part](../../modules/sip_i/README.md#func_add_isup_part) | [sip_i](../../modules/sip_i/README.md) | +| [add_path](../../modules/path/README.md#func_add_path) | [path](../../modules/path/README.md) | +| [add_path_received](../../modules/path/README.md#func_add_path_received) | [path](../../modules/path/README.md) | +| [add_rcv_param](../../modules/nathelper/README.md#func_add_rcv_param) | [nathelper](../../modules/nathelper/README.md) | +| [add_rr_param](../../modules/rr/README.md#func_add_rr_param) | [rr](../../modules/rr/README.md) | +| [add_sock_hdr](../../modules/registrar/README.md#func_add_sock_hdr) | [registrar](../../modules/registrar/README.md) | +| [aka_av_add](../../modules/auth_aka/README.md#func_aka_av_add) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_av_drop](../../modules/auth_aka/README.md#func_aka_av_drop) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_av_drop_all](../../modules/auth_aka/README.md#func_aka_av_drop_all) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_av_fail](../../modules/auth_aka/README.md#func_aka_av_fail) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_proxy_authorize](../../modules/auth_aka/README.md#func_aka_proxy_authorize) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_proxy_challenge](../../modules/auth_aka/README.md#func_aka_proxy_challenge) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_www_authorize](../../modules/auth_aka/README.md#func_aka_www_authorize) | [auth_aka](../../modules/auth_aka/README.md) | +| [aka_www_challenge](../../modules/auth_aka/README.md#func_aka_www_challenge) | [auth_aka](../../modules/auth_aka/README.md) | +| [alias_db_find](../../modules/alias_db/README.md#func_alias_db_find) | [alias_db](../../modules/alias_db/README.md) | +| [alias_db_lookup](../../modules/alias_db/README.md#func_alias_db_lookup) | [alias_db](../../modules/alias_db/README.md) | +| [allow_register](../../modules/permissions/README.md#func_allow_register) | [permissions](../../modules/permissions/README.md) | +| [allow_routing](../../modules/permissions/README.md#func_allow_routing_2) | [permissions](../../modules/permissions/README.md) | +| [allow_uri](../../modules/permissions/README.md#func_allow_uri) | [permissions](../../modules/permissions/README.md) | +| [append_body_to_reply](../../modules/sipmsgops/README.md#func_append_body_to_reply) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [append_hf](../../modules/sipmsgops/README.md#func_append_hf) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [append_rpid_hf](../../modules/auth/README.md#func_append_rpid_hf_2) | [auth](../../modules/auth/README.md) | +| [append_time](../../modules/sipmsgops/README.md#func_append_time) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [append_to_reply](../../modules/sipmsgops/README.md#func_append_to_reply) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [append_urihf](../../modules/sipmsgops/README.md#func_append_urihf) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [authservice](../../modules/identity/README.md#func_authservice) | [identity](../../modules/identity/README.md) | +| [avp_db_delete](../../modules/avpops/README.md#func_avp_db_delete) | [avpops](../../modules/avpops/README.md) | +| [avp_db_load](../../modules/avpops/README.md#func_avp_db_load) | [avpops](../../modules/avpops/README.md) | +| [avp_db_query](../../modules/avpops/README.md#func_avp_db_query) | [avpops](../../modules/avpops/README.md) | +| [avp_db_store](../../modules/avpops/README.md#func_avp_db_store) | [avpops](../../modules/avpops/README.md) | +| [b2b_bridge](../../modules/b2b_logic/README.md#func_b2b_bridge) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_bridge_request](../../modules/b2b_logic_xml/README.md#func_b2b_bridge_request) | [b2b_logic_xml](../../modules/b2b_logic_xml/README.md) | +| [b2b_bridge_retry](../../modules/b2b_logic/README.md#func_b2b_bridge_retry) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_client_new](../../modules/b2b_logic/README.md#func_b2b_client_new) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_delete_entity](../../modules/b2b_logic/README.md#func_b2b_delete_entity) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_end_dlg_leg](../../modules/b2b_logic/README.md#func_b2b_end_dlg_leg) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_handle_reply](../../modules/b2b_logic/README.md#func_b2b_handle_reply) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_init_request](../../modules/b2b_logic_xml/README.md#func_b2b_init_request) | [b2b_logic_xml](../../modules/b2b_logic_xml/README.md) | +| [b2b_pass_request](../../modules/b2b_logic/README.md#func_b2b_pass_request) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_sdp_demux](../../modules/b2b_sdp_demux/README.md#func_b2b_sdp_demux) | [b2b_sdp_demux](../../modules/b2b_sdp_demux/README.md) | +| [b2b_send_reply](../../modules/b2b_logic/README.md#func_b2b_send_reply) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_server_new](../../modules/b2b_logic/README.md#func_b2b_server_new) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [b2b_trigger_scenario](../../modules/b2b_logic/README.md#func_b2b_trigger_scenario) | [b2b_logic](../../modules/b2b_logic/README.md) | +| [bla_handle_notify](../../modules/pua_bla/README.md#func_bla_handle_notify) | [pua_bla](../../modules/pua_bla/README.md) | +| [bla_set_flag](../../modules/pua_bla/README.md#func_bla_set_flag) | [pua_bla](../../modules/pua_bla/README.md) | +| [bm_log_timer](../../modules/benchmark/README.md#func_bm_log_timer) | [benchmark](../../modules/benchmark/README.md) | +| [bm_start_timer](../../modules/benchmark/README.md#func_bm_start_timer) | [benchmark](../../modules/benchmark/README.md) | +| [cache_remove_chunk](../../modules/cachedb_local/README.md#func_cache_remove_chunk) | [cachedb_local](../../modules/cachedb_local/README.md) | +| [call_blind_replace](../../modules/callops/README.md#func_call_blind_replace) | [callops](../../modules/callops/README.md) | +| [call_control](../../modules/call_control/README.md#func_call_control) | [call_control](../../modules/call_control/README.md) | +| [call_transfer](../../modules/callops/README.md#func_call_transfer_2) | [callops](../../modules/callops/README.md) | +| [call_transfer_notify](../../modules/callops/README.md#func_call_transfer_notify) | [callops](../../modules/callops/README.md) | +| [cc_agent_login](../../modules/call_center/README.md#func_cc_agent_login) | [call_center](../../modules/call_center/README.md) | +| [cc_handle_call](../../modules/call_center/README.md#func_cc_handle_call) | [call_center](../../modules/call_center/README.md) | +| [cgrates_acc](../../modules/cgrates/README.md#func_cgrates_acc) | [cgrates](../../modules/cgrates/README.md) | +| [cgrates_auth](../../modules/cgrates/README.md#func_cgrates_auth) | [cgrates](../../modules/cgrates/README.md) | +| [cgrates_cmd](../../modules/cgrates/README.md#func_cgrates_cmd) | [cgrates](../../modules/cgrates/README.md) | +| [change_reply_status](../../modules/sipmsgops/README.md#func_change_reply_status) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [check_address](../../modules/permissions/README.md#func_check_address) | [permissions](../../modules/permissions/README.md) | +| [check_blacklist](../../modules/userblacklist/README.md#func_check_blacklist) | [userblacklist](../../modules/userblacklist/README.md) | +| [check_fraud](../../modules/fraud_detection/README.md#func_check_fraud) | [fraud_detection](../../modules/fraud_detection/README.md) | +| [check_route_param](../../modules/rr/README.md#func_check_route_param) | [rr](../../modules/rr/README.md) | +| [check_source_address](../../modules/permissions/README.md#func_check_source_address) | [permissions](../../modules/permissions/README.md) | +| [check_time_rec](../../modules/cfgutils/README.md#func_check_time_rec) | [cfgutils](../../modules/cfgutils/README.md) | +| [check_user_blacklist](../../modules/userblacklist/README.md#func_check_user_blacklist) | [userblacklist](../../modules/userblacklist/README.md) | +| [checkcallingtranslation](../../modules/osp/README.md#func_checkcallingtranslation) | [osp](../../modules/osp/README.md) | +| [checkospheader](../../modules/osp/README.md#func_checkospheader) | [osp](../../modules/osp/README.md) | +| [checkosproute](../../modules/osp/README.md#func_checkosproute) | [osp](../../modules/osp/README.md) | +| [client_nat_test](../../modules/nat_traversal/README.md#func_client_nat_test) | [nat_traversal](../../modules/nat_traversal/README.md) | +| [cluster_broadcast_req](../../modules/clusterer/README.md#func_cluster_broadcast_req) | [clusterer](../../modules/clusterer/README.md) | +| [cluster_check_addr](../../modules/clusterer/README.md#func_cluster_check_addr) | [clusterer](../../modules/clusterer/README.md) | +| [cluster_send_req](../../modules/clusterer/README.md#func_cluster_send_req) | [clusterer](../../modules/clusterer/README.md) | +| [cluster_send_rpl](../../modules/clusterer/README.md#func_cluster_send_rpl) | [clusterer](../../modules/clusterer/README.md) | +| [codec_delete](../../modules/sipmsgops/README.md#func_codec_delete) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_delete_except_re](../../modules/sipmsgops/README.md#func_codec_delete_except_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_delete_re](../../modules/sipmsgops/README.md#func_codec_delete_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_exists](../../modules/sipmsgops/README.md#func_codec_exists) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_exists_re](../../modules/sipmsgops/README.md#func_codec_exists_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_move_down](../../modules/sipmsgops/README.md#func_codec_move_down) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_move_down_re](../../modules/sipmsgops/README.md#func_codec_move_down_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_move_up](../../modules/sipmsgops/README.md#func_codec_move_up) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [codec_move_up_re](../../modules/sipmsgops/README.md#func_codec_move_up_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [consume_credentials](../../modules/auth/README.md#func_consume_credentials) | [auth](../../modules/auth/README.md) | +| [correlate](../../modules/proto_hep/README.md#func_correlate) | [proto_hep](../../modules/proto_hep/README.md) | +| [cost_based_filtering](../../modules/rate_cacher/README.md#func_cost_based_filtering) | [rate_cacher](../../modules/rate_cacher/README.md) | +| [cost_based_ordering](../../modules/rate_cacher/README.md#func_cost_based_ordering) | [rate_cacher](../../modules/rate_cacher/README.md) | +| [cpl_process_register](../../modules/cpl_c/README.md#func_cpl_process_register) | [cpl_c](../../modules/cpl_c/README.md) | +| [cpl_process_register_norpl](../../modules/cpl_c/README.md#func_cpl_process_register_norpl) | [cpl_c](../../modules/cpl_c/README.md) | +| [cpl_run_script](../../modules/cpl_c/README.md#func_cpl_run_script) | [cpl_c](../../modules/cpl_c/README.md) | +| [cr_next_domain](../../modules/carrierroute/README.md#func_cr_next_domain) | [carrierroute](../../modules/carrierroute/README.md) | +| [cr_prime_route](../../modules/carrierroute/README.md#func_cr_prime_route) | [carrierroute](../../modules/carrierroute/README.md) | +| [cr_route](../../modules/carrierroute/README.md#func_cr_route) | [carrierroute](../../modules/carrierroute/README.md) | +| [cr_user_carrier](../../modules/carrierroute/README.md#func_cr_user_carrier) | [carrierroute](../../modules/carrierroute/README.md) | +| [create_dialog](../../modules/dialog/README.md#func_create_dialog) | [dialog](../../modules/dialog/README.md) | +| [db_avp_delete](../../modules/dbops/README.md#func_db_avp_delete) | [dbops](../../modules/dbops/README.md) | +| [db_avp_load](../../modules/dbops/README.md#func_db_avp_load) | [dbops](../../modules/dbops/README.md) | +| [db_avp_store](../../modules/dbops/README.md#func_db_avp_store) | [dbops](../../modules/dbops/README.md) | +| [db_delete](../../modules/dbops/README.md#func_db_delete) | [dbops](../../modules/dbops/README.md) | +| [db_does_uri_exist](../../modules/auth_db/README.md#func_db_does_uri_exist) | [auth_db](../../modules/auth_db/README.md) | +| [db_get_auth_id](../../modules/auth_db/README.md#func_db_get_auth_id) | [auth_db](../../modules/auth_db/README.md) | +| [db_get_user_group](../../modules/group/README.md#func_db_get_user_group) | [group](../../modules/group/README.md) | +| [db_insert](../../modules/dbops/README.md#func_db_insert) | [dbops](../../modules/dbops/README.md) | +| [db_is_from_authorized](../../modules/auth_db/README.md#func_db_is_from_authorized) | [auth_db](../../modules/auth_db/README.md) | +| [db_is_to_authorized](../../modules/auth_db/README.md#func_db_is_to_authorized) | [auth_db](../../modules/auth_db/README.md) | +| [db_is_user_in](../../modules/group/README.md#func_db_is_user_in) | [group](../../modules/group/README.md) | +| [db_query](../../modules/dbops/README.md#func_db_query) | [dbops](../../modules/dbops/README.md) | +| [db_query_one](../../modules/dbops/README.md#func_db_query_one) | [dbops](../../modules/dbops/README.md) | +| [db_replace](../../modules/dbops/README.md#func_db_replace) | [dbops](../../modules/dbops/README.md) | +| [db_select](../../modules/dbops/README.md#func_db_select) | [dbops](../../modules/dbops/README.md) | +| [db_select_one](../../modules/dbops/README.md#func_db_select_one) | [dbops](../../modules/dbops/README.md) | +| [db_update](../../modules/dbops/README.md#func_db_update) | [dbops](../../modules/dbops/README.md) | +| [decode_contact](../../modules/mangler/README.md#func_decode_contact) | [mangler](../../modules/mangler/README.md) | +| [decode_contact_header](../../modules/mangler/README.md#func_decode_contact_header) | [mangler](../../modules/mangler/README.md) | +| [dialoginfo_mute_branch](../../modules/pua_dialoginfo/README.md#func_dialoginfo_mute_branch) | [pua_dialoginfo](../../modules/pua_dialoginfo/README.md) | +| [dialoginfo_set](../../modules/pua_dialoginfo/README.md#func_dialoginfo_set) | [pua_dialoginfo](../../modules/pua_dialoginfo/README.md) | +| [dialoginfo_set_branch_callee](../../modules/pua_dialoginfo/README.md#func_dialoginfo_set_branch_callee) | [pua_dialoginfo](../../modules/pua_dialoginfo/README.md) | +| [dlg_inc_cseq](../../modules/dialog/README.md#func_dlg_inc_cseq) | [dialog](../../modules/dialog/README.md) | +| [dlg_on_answer](../../modules/dialog/README.md#func_dlg_on_answer) | [dialog](../../modules/dialog/README.md) | +| [dlg_on_hangup](../../modules/dialog/README.md#func_dlg_on_hangup) | [dialog](../../modules/dialog/README.md) | +| [dlg_on_timeout](../../modules/dialog/README.md#func_dlg_on_timeout) | [dialog](../../modules/dialog/README.md) | +| [dlg_send_sequential](../../modules/dialog/README.md#func_dlg_send_sequential) | [dialog](../../modules/dialog/README.md) | +| [dm_send_answer](../../modules/aaa_diameter/README.md#func_dm_send_answer) | [aaa_diameter](../../modules/aaa_diameter/README.md) | +| [dm_send_request](../../modules/aaa_diameter/README.md#func_dm_send_request) | [aaa_diameter](../../modules/aaa_diameter/README.md) | +| [do_accounting](../../modules/acc/README.md#func_do_accounting) | [acc](../../modules/acc/README.md) | +| [do_routing](../../modules/drouting/README.md#func_do_routing) | [drouting](../../modules/drouting/README.md) | +| [dp_apply_policy](../../modules/domainpolicy/README.md#func_dp_apply_policy) | [domainpolicy](../../modules/domainpolicy/README.md) | +| [dp_can_connect](../../modules/domainpolicy/README.md#func_dp_can_connect) | [domainpolicy](../../modules/domainpolicy/README.md) | +| [dp_translate](../../modules/dialplan/README.md#func_dp_translate) | [dialplan](../../modules/dialplan/README.md) | +| [dr_disable](../../modules/drouting/README.md#func_dr_disable) | [drouting](../../modules/drouting/README.md) | +| [dr_is_gw](../../modules/drouting/README.md#func_dr_is_gw) | [drouting](../../modules/drouting/README.md) | +| [dr_match](../../modules/drouting/README.md#func_dr_match) | [drouting](../../modules/drouting/README.md) | +| [drop_accounting](../../modules/acc/README.md#func_drop_accounting) | [acc](../../modules/acc/README.md) | +| [ds_count](../../modules/dispatcher/README.md#func_ds_count) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_get_script_attrs](../../modules/dispatcher/README.md#func_ds_get_script_attrs) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_is_in_list](../../modules/dispatcher/README.md#func_ds_is_in_list) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_mark_dst](../../modules/dispatcher/README.md#func_ds_mark_dst) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_next_domain](../../modules/dispatcher/README.md#func_ds_next_domain) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_next_dst](../../modules/dispatcher/README.md#func_ds_next_dst) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_push_script_attrs](../../modules/dispatcher/README.md#func_ds_push_script_attrs) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_select_domain](../../modules/dispatcher/README.md#func_ds_select_domain) | [dispatcher](../../modules/dispatcher/README.md) | +| [ds_select_dst](../../modules/dispatcher/README.md#func_ds_select_dst) | [dispatcher](../../modules/dispatcher/README.md) | +| [emergency_call](../../modules/emergency/README.md#func_emergency_call) | [emergency](../../modules/emergency/README.md) | +| [encode_contact](../../modules/mangler/README.md#func_encode_contact) | [mangler](../../modules/mangler/README.md) | +| [end_media_session](../../modules/mediaproxy/README.md#func_end_media_session) | [mediaproxy](../../modules/mediaproxy/README.md) | +| [engage_media_proxy](../../modules/mediaproxy/README.md#func_engage_media_proxy) | [mediaproxy](../../modules/mediaproxy/README.md) | +| [enum_query](../../modules/enum/README.md#func_enum_query) | [enum](../../modules/enum/README.md) | +| [example](../../modules/example/README.md#func_example) | [example](../../modules/example/README.md) | +| [example_int](../../modules/example/README.md#func_example_int) | [example](../../modules/example/README.md) | +| [example_str](../../modules/example/README.md#func_example_str) | [example](../../modules/example/README.md) | +| [exec](../../modules/exec/README.md#func_exec) | [exec](../../modules/exec/README.md) | +| [extract_pub_key_from_cert](../../modules/auth_jwt/README.md#func_extract_pub_key_from_cert) | [auth_jwt](../../modules/auth_jwt/README.md) | +| [failure](../../modules/emergency/README.md#func_failure) | [emergency](../../modules/emergency/README.md) | +| [fetch_dlg_value](../../modules/dialog/README.md#func_fetch_dlg_value) | [dialog](../../modules/dialog/README.md) | +| [fix_contact](../../modules/nat_traversal/README.md#func_fix_contact) | [nat_traversal](../../modules/nat_traversal/README.md) | +| [fix_nated_contact](../../modules/nathelper/README.md#func_fix_nated_contact) | [nathelper](../../modules/nathelper/README.md) | +| [fix_nated_register](../../modules/nathelper/README.md#func_fix_nated_register) | [nathelper](../../modules/nathelper/README.md) | +| [fix_nated_sdp](../../modules/nathelper/README.md#func_fix_nated_sdp) | [nathelper](../../modules/nathelper/README.md) | +| [fix_route_dialog](../../modules/dialog/README.md#func_fix_route_dialog) | [dialog](../../modules/dialog/README.md) | +| [freeswitch_esl](../../modules/freeswitch_scripting/README.md#func_freeswitch_esl) | [freeswitch_scripting](../../modules/freeswitch_scripting/README.md) | +| [get_accurate_time](../../modules/cfgutils/README.md#func_get_accurate_time) | [cfgutils](../../modules/cfgutils/README.md) | +| [get_client_price](../../modules/rate_cacher/README.md#func_get_client_price) | [rate_cacher](../../modules/rate_cacher/README.md) | +| [get_dialog_info](../../modules/dialog/README.md#func_get_dialog_info) | [dialog](../../modules/dialog/README.md) | +| [get_dialog_vals](../../modules/dialog/README.md#func_get_dialog_vals) | [dialog](../../modules/dialog/README.md) | +| [get_dialogs_by_profile](../../modules/dialog/README.md#func_get_dialogs_by_profile) | [dialog](../../modules/dialog/README.md) | +| [get_dialogs_by_val](../../modules/dialog/README.md#func_get_dialogs_by_val) | [dialog](../../modules/dialog/README.md) | +| [get_dynamic_lock](../../modules/cfgutils/README.md#func_get_dynamic_lock) | [cfgutils](../../modules/cfgutils/README.md) | +| [get_glob_headers_values](../../modules/sipmsgops/README.md#func_get_glob_headers_values) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [get_profile_size](../../modules/dialog/README.md#func_get_profile_size) | [dialog](../../modules/dialog/README.md) | +| [get_redirects](../../modules/uac_redirect/README.md#func_get_redirects) | [uac_redirect](../../modules/uac_redirect/README.md) | +| [get_source_group](../../modules/permissions/README.md#func_get_source_group) | [permissions](../../modules/permissions/README.md) | +| [get_static_lock](../../modules/cfgutils/README.md#func_get_static_lock) | [cfgutils](../../modules/cfgutils/README.md) | +| [get_updated_body_part](../../modules/sipmsgops/README.md#func_get_updated_body_part) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [get_vendor_price](../../modules/rate_cacher/README.md#func_get_vendor_price) | [rate_cacher](../../modules/rate_cacher/README.md) | +| [getlocaladdress](../../modules/osp/README.md#func_getlocaladdress) | [osp](../../modules/osp/README.md) | +| [goes_to_gw](../../modules/drouting/README.md#func_goes_to_gw) | [drouting](../../modules/drouting/README.md) | +| [handle_publish](../../modules/presence/README.md#func_handle_publish) | [presence](../../modules/presence/README.md) | +| [handle_subscribe](../../modules/presence/README.md#func_handle_subscribe) | [presence](../../modules/presence/README.md) | +| [has_body_part](../../modules/sipmsgops/README.md#func_has_body_part) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [has_totag](../../modules/sipmsgops/README.md#func_has_totag) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [hep_del](../../modules/sipcapture/README.md#func_hep_del) | [sipcapture](../../modules/sipcapture/README.md) | +| [hep_get](../../modules/sipcapture/README.md#func_hep_get) | [sipcapture](../../modules/sipcapture/README.md) | +| [hep_relay](../../modules/sipcapture/README.md#func_hep_relay) | [sipcapture](../../modules/sipcapture/README.md) | +| [hep_resume_sip](../../modules/sipcapture/README.md#func_hep_resume_sip) | [sipcapture](../../modules/sipcapture/README.md) | +| [hep_set](../../modules/sipcapture/README.md#func_hep_set) | [sipcapture](../../modules/sipcapture/README.md) | +| [http2_send_response](../../modules/http2d/README.md#func_http2_send_response) | [http2d](../../modules/http2d/README.md) | +| [i_enum_query](../../modules/enum/README.md#func_i_enum_query) | [enum](../../modules/enum/README.md) | +| [imc_manager](../../modules/imc/README.md#func_imc_manager) | [imc](../../modules/imc/README.md) | +| [insert_hf](../../modules/sipmsgops/README.md#func_insert_hf_2) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [ipsec_create](../../modules/proto_ipsec/README.md#func_ipsec_create) | [proto_ipsec](../../modules/proto_ipsec/README.md) | +| [is_audio_on_hold](../../modules/sipmsgops/README.md#func_is_audio_on_hold) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [is_contact_registered](../../modules/registrar/README.md#func_is_contact_registered) | [registrar](../../modules/registrar/README.md) | +| [is_direction](../../modules/rr/README.md#func_is_direction) | [rr](../../modules/rr/README.md) | +| [is_dlg_flag_set](../../modules/dialog/README.md#func_is_dlg_flag_set) | [dialog](../../modules/dialog/README.md) | +| [is_domain_local](../../modules/domain/README.md#func_is_domain_local) | [domain](../../modules/domain/README.md) | +| [is_from_gw](../../modules/drouting/README.md#func_is_from_gw) | [drouting](../../modules/drouting/README.md) | +| [is_from_local](../../modules/domain/README.md#func_is_from_local) | [domain](../../modules/domain/README.md) | +| [is_from_user_enum](../../modules/enum/README.md#func_is_from_user_enum) | [enum](../../modules/enum/README.md) | +| [is_gflag](../../modules/gflags/README.md#func_is_gflag) | [gflags](../../modules/gflags/README.md) | +| [is_in_profile](../../modules/dialog/README.md#func_is_in_profile) | [dialog](../../modules/dialog/README.md) | +| [is_ip_registered](../../modules/registrar/README.md#func_is_ip_registered) | [registrar](../../modules/registrar/README.md) | +| [is_maxfwd_lt](../../modules/maxfwd/README.md#func_is_maxfwd_lt) | [maxfwd](../../modules/maxfwd/README.md) | +| [is_method](../../modules/sipmsgops/README.md#func_is_method) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [is_peer_verified](../../modules/tls_mgm/README.md#func_is_peer_verified) | [tls_mgm](../../modules/tls_mgm/README.md) | +| [is_present_hf](../../modules/sipmsgops/README.md#func_is_present_hf) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [is_privacy](../../modules/sipmsgops/README.md#func_is_privacy) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [is_registered](../../modules/registrar/README.md#func_is_registered) | [registrar](../../modules/registrar/README.md) | +| [is_rpid_user_e164](../../modules/auth/README.md#func_is_rpid_user_e164) | [auth](../../modules/auth/README.md) | +| [is_uri_host_local](../../modules/domain/README.md#func_is_uri_host_local) | [domain](../../modules/domain/README.md) | +| [is_uri_user_e164](../../modules/sipmsgops/README.md#func_is_uri_user_e164) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [isn_query](../../modules/enum/README.md#func_isn_query) | [enum](../../modules/enum/README.md) | +| [jab_exit_jconf](../../modules/jabber/README.md#func_jab_exit_jconf) | [jabber](../../modules/jabber/README.md) | +| [jab_go_offline](../../modules/jabber/README.md#func_jab_go_offline) | [jabber](../../modules/jabber/README.md) | +| [jab_go_online](../../modules/jabber/README.md#func_jab_go_online) | [jabber](../../modules/jabber/README.md) | +| [jab_join_jconf](../../modules/jabber/README.md#func_jab_join_jconf) | [jabber](../../modules/jabber/README.md) | +| [jab_send_message](../../modules/jabber/README.md#func_jab_send_message) | [jabber](../../modules/jabber/README.md) | +| [janus_send_requeest](../../modules/janus/README.md#func_janus_send_requeest) | [janus](../../modules/janus/README.md) | +| [json_link](../../modules/json/README.md#func_json_link) | [json](../../modules/json/README.md) | +| [json_merge](../../modules/json/README.md#func_json_merge) | [json](../../modules/json/README.md) | +| [jsonrpc_notification](../../modules/jsonrpc/README.md#func_jsonrpc_notification) | [jsonrpc](../../modules/jsonrpc/README.md) | +| [jsonrpc_request](../../modules/jsonrpc/README.md#func_jsonrpc_request) | [jsonrpc](../../modules/jsonrpc/README.md) | +| [jwt_db_authorize](../../modules/auth_jwt/README.md#func_jwt_db_authorize) | [auth_jwt](../../modules/auth_jwt/README.md) | +| [jwt_script_authorize](../../modules/auth_jwt/README.md#func_jwt_script_authorize) | [auth_jwt](../../modules/auth_jwt/README.md) | +| [kafka_publish](../../modules/event_kafka/README.md#func_kafka_publish) | [event_kafka](../../modules/event_kafka/README.md) | +| [lb_count_call](../../modules/load_balancer/README.md#func_lb_count_call) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_disable_dst](../../modules/load_balancer/README.md#func_lb_disable_dst) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_is_destination](../../modules/load_balancer/README.md#func_lb_is_destination) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_is_started](../../modules/load_balancer/README.md#func_lb_is_started) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_next](../../modules/load_balancer/README.md#func_lb_next) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_reset](../../modules/load_balancer/README.md#func_lb_reset) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_start](../../modules/load_balancer/README.md#func_lb_start) | [load_balancer](../../modules/load_balancer/README.md) | +| [lb_start_or_next](../../modules/load_balancer/README.md#func_lb_start_or_next) | [load_balancer](../../modules/load_balancer/README.md) | +| [ld_feature_enabled](../../modules/launch_darkly/README.md#func_ld_feature_enabled) | [launch_darkly](../../modules/launch_darkly/README.md) | +| [list_hdr_add_option](../../modules/sipmsgops/README.md#func_list_hdr_add_option) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [list_hdr_has_option](../../modules/sipmsgops/README.md#func_list_hdr_has_option) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [list_hdr_remove_option](../../modules/sipmsgops/README.md#func_list_hdr_remove_option) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [load_balance](../../modules/load_balancer/README.md#func_load_balance) | [load_balancer](../../modules/load_balancer/README.md) | +| [load_dialog_ctx](../../modules/dialog/README.md#func_load_dialog_ctx) | [dialog](../../modules/dialog/README.md) | +| [lookup](../../modules/registrar/README.md#func_lookup) | [registrar](../../modules/registrar/README.md) | +| [loose_route](../../modules/rr/README.md#func_loose_route) | [rr](../../modules/rr/README.md) | +| [m_dump](../../modules/msilo/README.md#func_m_dump) | [msilo](../../modules/msilo/README.md) | +| [m_store](../../modules/msilo/README.md#func_m_store) | [msilo](../../modules/msilo/README.md) | +| [match_dialog](../../modules/dialog/README.md#func_match_dialog) | [dialog](../../modules/dialog/README.md) | +| [math_ceil](../../modules/mathops/README.md#func_math_ceil) | [mathops](../../modules/mathops/README.md) | +| [math_compare](../../modules/mathops/README.md#func_math_compare) | [mathops](../../modules/mathops/README.md) | +| [math_eval](../../modules/mathops/README.md#func_math_eval) | [mathops](../../modules/mathops/README.md) | +| [math_floor](../../modules/mathops/README.md#func_math_floor) | [mathops](../../modules/mathops/README.md) | +| [math_round](../../modules/mathops/README.md#func_math_round) | [mathops](../../modules/mathops/README.md) | +| [math_round_sf](../../modules/mathops/README.md#func_math_round_sf) | [mathops](../../modules/mathops/README.md) | +| [math_rpn](../../modules/mathops/README.md#func_math_rpn) | [mathops](../../modules/mathops/README.md) | +| [math_trunc](../../modules/mathops/README.md#func_math_trunc) | [mathops](../../modules/mathops/README.md) | +| [mc_compact](../../modules/compression/README.md#func_mc_compact) | [compression](../../modules/compression/README.md) | +| [mc_compress](../../modules/compression/README.md#func_mc_compress) | [compression](../../modules/compression/README.md) | +| [mc_decompress](../../modules/compression/README.md#func_mc_decompress) | [compression](../../modules/compression/README.md) | +| [media_exchange_from_uri](../../modules/media_exchange/README.md#func_media_exchange_from_uri) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_exchange_to_call](../../modules/media_exchange/README.md#func_media_exchange_to_call) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_fork_from_call](../../modules/media_exchange/README.md#func_media_fork_from_call) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_fork_pause](../../modules/media_exchange/README.md#func_media_fork_pause) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_fork_resume](../../modules/media_exchange/README.md#func_media_fork_resume) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_fork_to_uri](../../modules/media_exchange/README.md#func_media_fork_to_uri) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_handle_indialog](../../modules/media_exchange/README.md#func_media_handle_indialog) | [media_exchange](../../modules/media_exchange/README.md) | +| [media_terminate](../../modules/media_exchange/README.md#func_media_terminate) | [media_exchange](../../modules/media_exchange/README.md) | +| [mf_process_maxfwd_header](../../modules/maxfwd/README.md#func_mf_process_maxfwd_header) | [maxfwd](../../modules/maxfwd/README.md) | +| [mi](../../modules/mi_script/README.md#func_mi) | [mi_script](../../modules/mi_script/README.md) | +| [mid_registrar_lookup](../../modules/mid_registrar/README.md#func_mid_registrar_lookup) | [mid_registrar](../../modules/mid_registrar/README.md) | +| [mid_registrar_save](../../modules/mid_registrar/README.md#func_mid_registrar_save) | [mid_registrar](../../modules/mid_registrar/README.md) | +| [mmg_lookup](../../modules/mmgeoip/README.md#func_mmg_lookup) | [mmgeoip](../../modules/mmgeoip/README.md) | +| [mq_add](../../modules/mqueue/README.md#func_mq_add) | [mqueue](../../modules/mqueue/README.md) | +| [mq_fetch](../../modules/mqueue/README.md#func_mq_fetch) | [mqueue](../../modules/mqueue/README.md) | +| [mq_pv_free](../../modules/mqueue/README.md#func_mq_pv_free) | [mqueue](../../modules/mqueue/README.md) | +| [mq_size](../../modules/mqueue/README.md#func_mq_size) | [mqueue](../../modules/mqueue/README.md) | +| [msg_to_msrp](../../modules/msrp_gateway/README.md#func_msg_to_msrp) | [msrp_gateway](../../modules/msrp_gateway/README.md) | +| [msrp_gw_answer](../../modules/msrp_gateway/README.md#func_msrp_gw_answer) | [msrp_gateway](../../modules/msrp_gateway/README.md) | +| [msrp_ua_answer](../../modules/msrp_ua/README.md#func_msrp_ua_answer) | [msrp_ua](../../modules/msrp_ua/README.md) | +| [nat_keepalive](../../modules/nat_traversal/README.md#func_nat_keepalive) | [nat_traversal](../../modules/nat_traversal/README.md) | +| [nat_uac_test](../../modules/nathelper/README.md#func_nat_uac_test) | [nathelper](../../modules/nathelper/README.md) | +| [notify_on_event](../../modules/event_routing/README.md#func_notify_on_event) | [event_routing](../../modules/event_routing/README.md) | +| [options_reply](../../modules/options/README.md#func_options_reply) | [options](../../modules/options/README.md) | +| [pcre_match](../../modules/regex/README.md#func_pcre_match) | [regex](../../modules/regex/README.md) | +| [pcre_match_group](../../modules/regex/README.md#func_pcre_match_group) | [regex](../../modules/regex/README.md) | +| [perl_exec](../../modules/perl/README.md#func_perl_exec) | [perl](../../modules/perl/README.md) | +| [perl_exec_simple](../../modules/perl/README.md#func_perl_exec_simple) | [perl](../../modules/perl/README.md) | +| [pike_check_req](../../modules/pike/README.md#func_pike_check_req) | [pike](../../modules/pike/README.md) | +| [pkg_status](../../modules/cfgutils/README.md#func_pkg_status) | [cfgutils](../../modules/cfgutils/README.md) | +| [prepareallosproutes](../../modules/osp/README.md#func_prepareallosproutes) | [osp](../../modules/osp/README.md) | +| [prepareospresponse](../../modules/osp/README.md#func_prepareospresponse) | [osp](../../modules/osp/README.md) | +| [prepareosproute](../../modules/osp/README.md#func_prepareosproute) | [osp](../../modules/osp/README.md) | +| [processsubscribe](../../modules/osp/README.md#func_processsubscribe) | [osp](../../modules/osp/README.md) | +| [prometheus_declare_stat](../../modules/prometheus/README.md#func_prometheus_declare_stat) | [prometheus](../../modules/prometheus/README.md) | +| [prometheus_push_stat](../../modules/prometheus/README.md#func_prometheus_push_stat) | [prometheus](../../modules/prometheus/README.md) | +| [proxy_authorize](../../modules/auth_db/README.md#func_proxy_authorize) | [auth_db](../../modules/auth_db/README.md) | +| [proxy_challenge](../../modules/auth/README.md#func_proxy_challenge) | [auth](../../modules/auth/README.md) | +| [pua_set_publish](../../modules/pua_usrloc/README.md#func_pua_set_publish) | [pua_usrloc](../../modules/pua_usrloc/README.md) | +| [pua_update_contact](../../modules/pua/README.md#func_pua_update_contact) | [pua](../../modules/pua/README.md) | +| [pua_xmpp_notify](../../modules/pua_xmpp/README.md#func_pua_xmpp_notify) | [pua_xmpp](../../modules/pua_xmpp/README.md) | +| [pua_xmpp_req_winfo](../../modules/pua_xmpp/README.md#func_pua_xmpp_req_winfo) | [pua_xmpp](../../modules/pua_xmpp/README.md) | +| [pv_proxy_authorize](../../modules/auth/README.md#func_pv_proxy_authorize) | [auth](../../modules/auth/README.md) | +| [pv_www_authorize](../../modules/auth/README.md#func_pv_www_authorize) | [auth](../../modules/auth/README.md) | +| [python_exec](../../modules/python/README.md#func_python_exec) | [python](../../modules/python/README.md) | +| [qr_disable_dst](../../modules/qrouting/README.md#func_qr_disable_dst) | [qrouting](../../modules/qrouting/README.md) | +| [qr_enable_dst](../../modules/qrouting/README.md#func_qr_enable_dst) | [qrouting](../../modules/qrouting/README.md) | +| [qr_set_xstat](../../modules/qrouting/README.md#func_qr_set_xstat) | [qrouting](../../modules/qrouting/README.md) | +| [rabbitmq_publish](../../modules/event_rabbitmq/README.md#func_rabbitmq_publish) | [event_rabbitmq](../../modules/event_rabbitmq/README.md) | +| [radius_send_acct](../../modules/aaa_radius/README.md#func_radius_send_acct) | [aaa_radius](../../modules/aaa_radius/README.md) | +| [radius_send_auth](../../modules/aaa_radius/README.md#func_radius_send_auth) | [aaa_radius](../../modules/aaa_radius/README.md) | +| [rand_event](../../modules/cfgutils/README.md#func_rand_event) | [cfgutils](../../modules/cfgutils/README.md) | +| [rand_get_prob](../../modules/cfgutils/README.md#func_rand_get_prob) | [cfgutils](../../modules/cfgutils/README.md) | +| [rand_reset_prob](../../modules/cfgutils/README.md#func_rand_reset_prob) | [cfgutils](../../modules/cfgutils/README.md) | +| [rand_set_prob](../../modules/cfgutils/README.md#func_rand_set_prob) | [cfgutils](../../modules/cfgutils/README.md) | +| [record_route](../../modules/rr/README.md#func_record_route) | [rr](../../modules/rr/README.md) | +| [record_route_preset](../../modules/rr/README.md#func_record_route_preset) | [rr](../../modules/rr/README.md) | +| [release_dynamic_lock](../../modules/cfgutils/README.md#func_release_dynamic_lock) | [cfgutils](../../modules/cfgutils/README.md) | +| [release_static_lock](../../modules/cfgutils/README.md#func_release_static_lock) | [cfgutils](../../modules/cfgutils/README.md) | +| [remove](../../modules/registrar/README.md#func_remove) | [registrar](../../modules/registrar/README.md) | +| [remove_body_part](../../modules/sipmsgops/README.md#func_remove_body_part) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [remove_hf](../../modules/sipmsgops/README.md#func_remove_hf) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [remove_hf_glob](../../modules/sipmsgops/README.md#func_remove_hf_glob) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [remove_hf_re](../../modules/sipmsgops/README.md#func_remove_hf_re) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [remove_ip_port](../../modules/registrar/README.md#func_remove_ip_port) | [registrar](../../modules/registrar/README.md) | +| [replace](../../modules/textops/README.md#func_replace) | [textops](../../modules/textops/README.md) | +| [replace_all](../../modules/textops/README.md#func_replace_all) | [textops](../../modules/textops/README.md) | +| [replace_body](../../modules/textops/README.md#func_replace_body) | [textops](../../modules/textops/README.md) | +| [replace_body_all](../../modules/textops/README.md#func_replace_body_all) | [textops](../../modules/textops/README.md) | +| [replace_body_atonce](../../modules/textops/README.md#func_replace_body_atonce) | [textops](../../modules/textops/README.md) | +| [report_capture](../../modules/sipcapture/README.md#func_report_capture) | [sipcapture](../../modules/sipcapture/README.md) | +| [reportospusage](../../modules/osp/README.md#func_reportospusage) | [osp](../../modules/osp/README.md) | +| [requestosprouting](../../modules/osp/README.md#func_requestosprouting) | [osp](../../modules/osp/README.md) | +| [reset_dlg_flag](../../modules/dialog/README.md#func_reset_dlg_flag) | [dialog](../../modules/dialog/README.md) | +| [reset_gflag](../../modules/gflags/README.md#func_reset_gflag) | [gflags](../../modules/gflags/README.md) | +| [reset_stat](../../modules/statistics/README.md#func_reset_stat) | [statistics](../../modules/statistics/README.md) | +| [rest_append_hf](../../modules/rest_client/README.md#func_rest_append_hf) | [rest_client](../../modules/rest_client/README.md) | +| [rest_get](../../modules/rest_client/README.md#func_rest_get) | [rest_client](../../modules/rest_client/README.md) | +| [rest_init_client_tls](../../modules/rest_client/README.md#func_rest_init_client_tls) | [rest_client](../../modules/rest_client/README.md) | +| [rest_post](../../modules/rest_client/README.md#func_rest_post) | [rest_client](../../modules/rest_client/README.md) | +| [rest_put](../../modules/rest_client/README.md#func_rest_put) | [rest_client](../../modules/rest_client/README.md) | +| [rl_check](../../modules/ratelimit/README.md#func_rl_check) | [ratelimit](../../modules/ratelimit/README.md) | +| [rl_dec_count](../../modules/ratelimit/README.md#func_rl_dec_count) | [ratelimit](../../modules/ratelimit/README.md) | +| [rl_reset_count](../../modules/ratelimit/README.md#func_rl_reset_count) | [ratelimit](../../modules/ratelimit/README.md) | +| [rl_values](../../modules/ratelimit/README.md#func_rl_values) | [ratelimit](../../modules/ratelimit/README.md) | +| [rls_handle_notify](../../modules/rls/README.md#func_rls_handle_notify) | [rls](../../modules/rls/README.md) | +| [rls_handle_subscribe](../../modules/rls/README.md#func_rls_handle_subscribe) | [rls](../../modules/rls/README.md) | +| [route_to_carrier](../../modules/drouting/README.md#func_route_to_carrier) | [drouting](../../modules/drouting/README.md) | +| [route_to_gw](../../modules/drouting/README.md#func_route_to_gw) | [drouting](../../modules/drouting/README.md) | +| [rtp_relay_engage](../../modules/rtp_relay/README.md#func_rtp_relay_engage) | [rtp_relay](../../modules/rtp_relay/README.md) | +| [rtpengine_answer](../../modules/rtpengine/README.md#func_rtpengine_answer) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_block_dtmf](../../modules/rtpengine/README.md#func_rtpengine_block_dtmf) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_block_media](../../modules/rtpengine/README.md#func_rtpengine_block_media) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_delete](../../modules/rtpengine/README.md#func_rtpengine_delete) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_manage](../../modules/rtpengine/README.md#func_rtpengine_manage) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_offer](../../modules/rtpengine/README.md#func_rtpengine_offer) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_pause_recording](../../modules/rtpengine/README.md#func_rtpengine_pause_recording) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_play_dtmf](../../modules/rtpengine/README.md#func_rtpengine_play_dtmf) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_play_media](../../modules/rtpengine/README.md#func_rtpengine_play_media) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_start_forwarding](../../modules/rtpengine/README.md#func_rtpengine_start_forwarding) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_start_recording](../../modules/rtpengine/README.md#func_rtpengine_start_recording) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_stop_forwarding](../../modules/rtpengine/README.md#func_rtpengine_stop_forwarding) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_stop_media](../../modules/rtpengine/README.md#func_rtpengine_stop_media) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_stop_recording](../../modules/rtpengine/README.md#func_rtpengine_stop_recording) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_unblock_dtmf](../../modules/rtpengine/README.md#func_rtpengine_unblock_dtmf) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_unblock_media](../../modules/rtpengine/README.md#func_rtpengine_unblock_media) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpengine_use_set](../../modules/rtpengine/README.md#func_rtpengine_use_set) | [rtpengine](../../modules/rtpengine/README.md) | +| [rtpproxy_all_stats](../../modules/rtpproxy/README.md#func_rtpproxy_all_stats) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_answer](../../modules/rtpproxy/README.md#func_rtpproxy_answer) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_engage](../../modules/rtpproxy/README.md#func_rtpproxy_engage) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_offer](../../modules/rtpproxy/README.md#func_rtpproxy_offer) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_start_recording](../../modules/rtpproxy/README.md#func_rtpproxy_start_recording) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_stats](../../modules/rtpproxy/README.md#func_rtpproxy_stats) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_stop_stream2uac](../../modules/rtpproxy/README.md#func_rtpproxy_stop_stream2uac) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_stop_stream2uas](../../modules/rtpproxy/README.md#func_rtpproxy_stop_stream2uac) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_stream2uac](../../modules/rtpproxy/README.md#func_rtpproxy_stream2uac) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_stream2uas](../../modules/rtpproxy/README.md#func_rtpproxy_stream2uac) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [rtpproxy_unforce](../../modules/rtpproxy/README.md#func_rtpproxy_unforce) | [rtpproxy](../../modules/rtpproxy/README.md) | +| [ruri_add_param](../../modules/sipmsgops/README.md#func_ruri_add_param) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [ruri_del_param](../../modules/sipmsgops/README.md#func_ruri_del_param) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [ruri_has_param](../../modules/sipmsgops/README.md#func_ruri_has_param) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [ruri_tel2sip](../../modules/sipmsgops/README.md#func_ruri_tel2sip) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [save](../../modules/registrar/README.md#func_save) | [registrar](../../modules/registrar/README.md) | +| [sca_bridge_request](../../modules/b2b_sca/README.md#func_sca_bridge_request) | [b2b_sca](../../modules/b2b_sca/README.md) | +| [sca_init_request](../../modules/b2b_sca/README.md#func_sca_init_request) | [b2b_sca](../../modules/b2b_sca/README.md) | +| [sca_set_called_line](../../modules/presence_callinfo/README.md#func_sca_set_called_line) | [presence_callinfo](../../modules/presence_callinfo/README.md) | +| [sca_set_calling_line](../../modules/presence_callinfo/README.md#func_sca_set_calling_line) | [presence_callinfo](../../modules/presence_callinfo/README.md) | +| [sd_lookup](../../modules/speeddial/README.md#func_sd_lookup) | [speeddial](../../modules/speeddial/README.md) | +| [sdp_mangle_ip](../../modules/mangler/README.md#func_sdp_mangle_ip) | [mangler](../../modules/mangler/README.md) | +| [sdp_mangle_port](../../modules/mangler/README.md#func_sdp_mangle_port) | [mangler](../../modules/mangler/README.md) | +| [search](../../modules/textops/README.md#func_search) | [textops](../../modules/textops/README.md) | +| [search_append](../../modules/textops/README.md#func_search_append) | [textops](../../modules/textops/README.md) | +| [search_append_body](../../modules/textops/README.md#func_search_append_body) | [textops](../../modules/textops/README.md) | +| [search_body](../../modules/textops/README.md#func_search_body) | [textops](../../modules/textops/README.md) | +| [send_reply](../../modules/signaling/README.md#func_send_reply) | [signaling](../../modules/signaling/README.md) | +| [send_smpp_message](../../modules/proto_smpp/README.md#func_send_smpp_message) | [proto_smpp](../../modules/proto_smpp/README.md) | +| [set_accept_filter](../../modules/uac_redirect/README.md#func_set_accept_filter) | [uac_redirect](../../modules/uac_redirect/README.md) | +| [set_count](../../modules/cfgutils/README.md#func_set_count) | [cfgutils](../../modules/cfgutils/README.md) | +| [set_deny_filter](../../modules/uac_redirect/README.md#func_set_deny_filter) | [uac_redirect](../../modules/uac_redirect/README.md) | +| [set_dlg_flag](../../modules/dialog/README.md#func_set_dlg_flag) | [dialog](../../modules/dialog/README.md) | +| [set_dlg_profile](../../modules/dialog/README.md#func_set_dlg_profile) | [dialog](../../modules/dialog/README.md) | +| [set_dlg_sharing_tag](../../modules/dialog/README.md#func_set_dlg_sharing_tag) | [dialog](../../modules/dialog/README.md) | +| [set_gflag](../../modules/gflags/README.md#func_set_gflag) | [gflags](../../modules/gflags/README.md) | +| [set_select_weight](../../modules/cfgutils/README.md#func_set_select_weight) | [cfgutils](../../modules/cfgutils/README.md) | +| [setrequestdate](../../modules/osp/README.md#func_setrequestdate) | [osp](../../modules/osp/README.md) | +| [shm_status](../../modules/cfgutils/README.md#func_shm_status) | [cfgutils](../../modules/cfgutils/README.md) | +| [shuffle_avps](../../modules/cfgutils/README.md#func_shuffle_avps) | [cfgutils](../../modules/cfgutils/README.md) | +| [sip_capture](../../modules/sipcapture/README.md#func_sip_capture) | [sipcapture](../../modules/sipcapture/README.md) | +| [sip_to_json](../../modules/sipmsgops/README.md#func_sip_to_json) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [sipmsg_validate](../../modules/sipmsgops/README.md#func_sipmsg_validate) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [siprec_pause_recording](../../modules/siprec/README.md#func_siprec_pause_recording) | [siprec](../../modules/siprec/README.md) | +| [siprec_resume_recording](../../modules/siprec/README.md#func_siprec_resume_recording) | [siprec](../../modules/siprec/README.md) | +| [siprec_send_indialog](../../modules/siprec/README.md#func_siprec_send_indialog) | [siprec](../../modules/siprec/README.md) | +| [siprec_start_recording](../../modules/siprec/README.md#func_siprec_start_recording) | [siprec](../../modules/siprec/README.md) | +| [siprec_stop_recording](../../modules/siprec/README.md#func_siprec_stop_recording) | [siprec](../../modules/siprec/README.md) | +| [sl_reply_error](../../modules/sl/README.md#func_sl_reply_error) | [sl](../../modules/sl/README.md) | +| [sl_send_reply](../../modules/sl/README.md#func_sl_send_reply) | [sl](../../modules/sl/README.md) | +| [sleep](../../modules/cfgutils/README.md#func_sleep) | [cfgutils](../../modules/cfgutils/README.md) | +| [sngtc_callee_answer](../../modules/sngtc/README.md#func_sngtc_callee_answer) | [sngtc](../../modules/sngtc/README.md) | +| [sngtc_caller_answer](../../modules/sngtc/README.md#func_sngtc_caller_answer) | [sngtc](../../modules/sngtc/README.md) | +| [sngtc_offer](../../modules/sngtc/README.md#func_sngtc_offer) | [sngtc](../../modules/sngtc/README.md) | +| [sql_avp_delete](../../modules/sqlops/README.md#func_sql_avp_delete) | [sqlops](../../modules/sqlops/README.md) | +| [sql_avp_load](../../modules/sqlops/README.md#func_sql_avp_load) | [sqlops](../../modules/sqlops/README.md) | +| [sql_avp_store](../../modules/sqlops/README.md#func_sql_avp_store) | [sqlops](../../modules/sqlops/README.md) | +| [sql_cache_dump](../../modules/sql_cacher/README.md#func_sql_cache_dump) | [sql_cacher](../../modules/sql_cacher/README.md) | +| [sql_delete](../../modules/sqlops/README.md#func_sql_delete) | [sqlops](../../modules/sqlops/README.md) | +| [sql_insert](../../modules/sqlops/README.md#func_sql_insert) | [sqlops](../../modules/sqlops/README.md) | +| [sql_query](../../modules/sqlops/README.md#func_sql_query) | [sqlops](../../modules/sqlops/README.md) | +| [sql_query_one](../../modules/sqlops/README.md#func_sql_query_one) | [sqlops](../../modules/sqlops/README.md) | +| [sql_replace](../../modules/sqlops/README.md#func_sql_replace) | [sqlops](../../modules/sqlops/README.md) | +| [sql_select](../../modules/sqlops/README.md#func_sql_select) | [sqlops](../../modules/sqlops/README.md) | +| [sql_select_one](../../modules/sqlops/README.md#func_sql_select_one) | [sqlops](../../modules/sqlops/README.md) | +| [sql_update](../../modules/sqlops/README.md#func_sql_update) | [sqlops](../../modules/sqlops/README.md) | +| [sr_add_report](../../modules/status_report/README.md#func_sr_add_report) | [status_report](../../modules/status_report/README.md) | +| [sr_set_status](../../modules/status_report/README.md#func_sr_set_status) | [status_report](../../modules/status_report/README.md) | +| [sstCheckMin](../../modules/sst/README.md#func_sstCheckMin) | [sst](../../modules/sst/README.md) | +| [stat_iter_init](../../modules/statistics/README.md#func_stat_iter_init) | [statistics](../../modules/statistics/README.md) | +| [stat_iter_next](../../modules/statistics/README.md#func_stat_iter_next) | [statistics](../../modules/statistics/README.md) | +| [stir_shaken_auth](../../modules/stir_shaken/README.md#func_stir_shaken_auth) | [stir_shaken](../../modules/stir_shaken/README.md) | +| [stir_shaken_check](../../modules/stir_shaken/README.md#func_stir_shaken_check) | [stir_shaken](../../modules/stir_shaken/README.md) | +| [stir_shaken_check_cert](../../modules/stir_shaken/README.md#func_stir_shaken_check_cert) | [stir_shaken](../../modules/stir_shaken/README.md) | +| [stir_shaken_disengagement](../../modules/stir_shaken/README.md#func_stir_shaken_disengagement) | [stir_shaken](../../modules/stir_shaken/README.md) | +| [stir_shaken_verify](../../modules/stir_shaken/README.md#func_stir_shaken_verify) | [stir_shaken](../../modules/stir_shaken/README.md) | +| [store_dlg_value](../../modules/dialog/README.md#func_store_dlg_value) | [dialog](../../modules/dialog/README.md) | +| [stream_delete](../../modules/sipmsgops/README.md#func_stream_delete) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [stream_exists](../../modules/sipmsgops/README.md#func_stream_exists) | [sipmsgops](../../modules/sipmsgops/README.md) | +| [strings_share_lock](../../modules/cfgutils/README.md#func_strings_share_lock) | [cfgutils](../../modules/cfgutils/README.md) | +| [subst](../../modules/textops/README.md#func_subst) | [textops](../../modules/textops/README.md) | +| [subst_body](../../modules/textops/README.md#func_subst_body) | [textops](../../modules/textops/README.md) | +| [subst_uri](../../modules/textops/README.md#func_subst_uri) | [textops](../../modules/textops/README.md) | +| [subst_user](../../modules/textops/README.md#func_subst_user) | [textops](../../modules/textops/README.md) | +| [t_add_cancel_reason](../../modules/tm/README.md#func_t_add_cancel_reason) | [tm](../../modules/tm/README.md) | +| [t_add_hdrs](../../modules/tm/README.md#func_t_add_hdrs) | [tm](../../modules/tm/README.md) | +| [t_anycast_replicate](../../modules/tm/README.md#func_t_anycast_replicate) | [tm](../../modules/tm/README.md) | +| [t_cancel_branch](../../modules/tm/README.md#func_t_cancel_branch) | [tm](../../modules/tm/README.md) | +| [t_check_status](../../modules/tm/README.md#func_t_check_status) | [tm](../../modules/tm/README.md) | +| [t_check_trans](../../modules/tm/README.md#func_t_check_trans) | [tm](../../modules/tm/README.md) | +| [t_flush_flags](../../modules/tm/README.md#func_t_flush_flags) | [tm](../../modules/tm/README.md) | +| [t_get_branch_idx_by_attr](../../modules/tm/README.md#func_t_get_branch_idx_by_attr) | [tm](../../modules/tm/README.md) | +| [t_inject_branches](../../modules/tm/README.md#func_t_inject_branches) | [tm](../../modules/tm/README.md) | +| [t_local_replied](../../modules/tm/README.md#func_t_local_replied) | [tm](../../modules/tm/README.md) | +| [t_new_request](../../modules/tm/README.md#func_t_new_request) | [tm](../../modules/tm/README.md) | +| [t_newtran](../../modules/tm/README.md#func_t_newtran) | [tm](../../modules/tm/README.md) | +| [t_on_branch](../../modules/tm/README.md#func_t_on_branch) | [tm](../../modules/tm/README.md) | +| [t_on_failure](../../modules/tm/README.md#func_t_on_failure) | [tm](../../modules/tm/README.md) | +| [t_on_reply](../../modules/tm/README.md#func_t_on_reply) | [tm](../../modules/tm/README.md) | +| [t_relay](../../modules/tm/README.md#func_t_relay) | [tm](../../modules/tm/README.md) | +| [t_replicate](../../modules/tm/README.md#func_t_replicate) | [tm](../../modules/tm/README.md) | +| [t_reply](../../modules/tm/README.md#func_t_reply) | [tm](../../modules/tm/README.md) | +| [t_reply_by_callid](../../modules/tm/README.md#func_t_reply_by_callid) | [tm](../../modules/tm/README.md) | +| [t_reply_with_body](../../modules/tm/README.md#func_t_reply_with_body) | [tm](../../modules/tm/README.md) | +| [t_wait_for_new_branches](../../modules/tm/README.md#func_t_wait_for_new_branches) | [tm](../../modules/tm/README.md) | +| [t_wait_no_more_branches](../../modules/tm/README.md#func_t_wait_no_more_branches) | [tm](../../modules/tm/README.md) | +| [t_was_cancelled](../../modules/tm/README.md#func_t_was_cancelled) | [tm](../../modules/tm/README.md) | +| [t_write_req](../../modules/tm/README.md#func_t_write_req) | [tm](../../modules/tm/README.md) | +| [t_write_unix](../../modules/tm/README.md#func_t_write_req) | [tm](../../modules/tm/README.md) | +| [test_and_set_dlg_flag](../../modules/dialog/README.md#func_test_and_set_dlg_flag) | [dialog](../../modules/dialog/README.md) | +| [topology_hiding](../../modules/topology_hiding/README.md#func_topology_hiding) | [topology_hiding](../../modules/topology_hiding/README.md) | +| [topology_hiding_match](../../modules/topology_hiding/README.md#func_topology_hiding_match) | [topology_hiding](../../modules/topology_hiding/README.md) | +| [trace](../../modules/tracer/README.md#func_trace) | [tracer](../../modules/tracer/README.md) | +| [trie_search](../../modules/trie/README.md#func_trie_search) | [trie](../../modules/trie/README.md) | +| [ts_usec_delta](../../modules/cfgutils/README.md#func_ts_usec_delta) | [cfgutils](../../modules/cfgutils/README.md) | +| [ua_session_reply](../../modules/b2b_entities/README.md#func_ua_session_reply) | [b2b_entities](../../modules/b2b_entities/README.md) | +| [ua_session_server_init](../../modules/b2b_entities/README.md#func_ua_session_server_init) | [b2b_entities](../../modules/b2b_entities/README.md) | +| [ua_session_terminate](../../modules/b2b_entities/README.md#func_ua_session_terminate) | [b2b_entities](../../modules/b2b_entities/README.md) | +| [ua_session_update](../../modules/b2b_entities/README.md#func_ua_session_update) | [b2b_entities](../../modules/b2b_entities/README.md) | +| [uac_auth](../../modules/uac/README.md#func_uac_auth) | [uac](../../modules/uac/README.md) | +| [uac_inc_cseq](../../modules/uac/README.md#func_uac_inc_cseq) | [uac](../../modules/uac/README.md) | +| [uac_replace_from](../../modules/uac/README.md#func_uac_replace_from) | [uac](../../modules/uac/README.md) | +| [uac_replace_to](../../modules/uac/README.md#func_uac_replace_from) | [uac](../../modules/uac/README.md) | +| [uac_restore_from](../../modules/uac/README.md#func_uac_restore_from) | [uac](../../modules/uac/README.md) | +| [uac_restore_to](../../modules/uac/README.md#func_uac_restore_from) | [uac](../../modules/uac/README.md) | +| [ul_add_key](../../modules/usrloc/README.md#func_ul_add_key) | [usrloc](../../modules/usrloc/README.md) | +| [ul_del_key](../../modules/usrloc/README.md#func_ul_del_key) | [usrloc](../../modules/usrloc/README.md) | +| [ul_get_key](../../modules/usrloc/README.md#func_ul_get_key) | [usrloc](../../modules/usrloc/README.md) | +| [unload_dialog_ctx](../../modules/dialog/README.md#func_unload_dialog_ctx) | [dialog](../../modules/dialog/README.md) | +| [unset_dlg_profile](../../modules/dialog/README.md#func_unset_dlg_profile) | [dialog](../../modules/dialog/README.md) | +| [update_stat](../../modules/statistics/README.md#func_update_stat) | [statistics](../../modules/statistics/README.md) | +| [update_stat_series](../../modules/statistics/README.md#func_update_stat_series) | [statistics](../../modules/statistics/README.md) | +| [use_media_proxy](../../modules/mediaproxy/README.md#func_use_media_proxy) | [mediaproxy](../../modules/mediaproxy/README.md) | +| [use_next_gw](../../modules/drouting/README.md#func_use_next_gw) | [drouting](../../modules/drouting/README.md) | +| [usleep](../../modules/cfgutils/README.md#func_usleep) | [cfgutils](../../modules/cfgutils/README.md) | +| [uuid](../../modules/uuid/README.md#func_uuid) | [uuid](../../modules/uuid/README.md) | +| [validate_dialog](../../modules/dialog/README.md#func_validate_dialog) | [dialog](../../modules/dialog/README.md) | +| [validateospheader](../../modules/osp/README.md#func_validateospheader) | [osp](../../modules/osp/README.md) | +| [verifier](../../modules/identity/README.md#func_verifier) | [identity](../../modules/identity/README.md) | +| [verify_destination](../../modules/peering/README.md#func_verify_destination) | [peering](../../modules/peering/README.md) | +| [verify_source](../../modules/peering/README.md#func_verify_source) | [peering](../../modules/peering/README.md) | +| [www_authorize](../../modules/auth_db/README.md#func_www_authorize) | [auth_db](../../modules/auth_db/README.md) | +| [www_challenge](../../modules/auth/README.md#func_www_challenge) | [auth](../../modules/auth/README.md) | +| [xmpp_send_message](../../modules/xmpp/README.md#func_xmpp_send_message) | [xmpp](../../modules/xmpp/README.md) | diff --git a/docs/manual/Generating-Configs.md b/docs/manual/Generating-Configs.md new file mode 100644 index 00000000000..9e77c583328 --- /dev/null +++ b/docs/manual/Generating-Configs.md @@ -0,0 +1,57 @@ +--- +title: "Generating Config Files" +description: "Use the OpenSIPS GNU M4 templates to create residential, trunking, and load-balancer configurations." +--- + +OpenSIPS provides ready-to-use GNU M4 configuration templates under +`examples/templates/`: + +* `residential.m4` +* `trunking.m4` +* `loadbalancer.m4` + +They are installed as shared examples under +`$PREFIX/share/opensips/examples/templates/`. Distribution packages typically +use `/usr/share/opensips/examples/templates/`. + +Each template starts with definitions for its listening interface, database +URL, optional endpoints, and feature switches. Edit these definitions before +using the template. Feature switches accept `yes` or `no`. + +## Run a template directly + +Use `-f` to select the template and `-p m4` to preprocess it before OpenSIPS +parses it: + +```bash +opensips -C -f examples/templates/residential.m4 -p m4 +opensips -f examples/templates/residential.m4 -p m4 +``` + +The first command checks the generated configuration. The second starts +OpenSIPS. GNU M4 must be installed and available in `PATH`. + +For an installed distribution package, use the template from the shared +examples directory: + +```bash +opensips -f /usr/share/opensips/examples/templates/residential.m4 -p m4 +``` + +## Create a standalone configuration + +You can render a template into a regular configuration file: + +```bash +m4 examples/templates/residential.m4 > opensips.cfg +``` + +The resulting file no longer requires preprocessing. Edit it as needed, then +check or start it normally: + +```bash +opensips -C -f opensips.cfg +opensips -f opensips.cfg +``` + +See `examples/templates/README.md` for additional examples. diff --git a/docs/manual/Install-CompileAndInstall.md b/docs/manual/Install-CompileAndInstall.md new file mode 100644 index 00000000000..f5261f2df7a --- /dev/null +++ b/docs/manual/Install-CompileAndInstall.md @@ -0,0 +1,111 @@ +--- +title: "Compile And Install" +description: "Compile and install OpenSIPS from source using Makefile.conf." +--- + +This page is for users compiling OpenSIPS from source. Binary packages should +be installed with the package manager provided by the operating system. + +## Configure the build + +Build settings are stored in `Makefile.conf` at the repository root. The first +`make` invocation creates it from `Makefile.conf.template` if it does not +already exist. To prepare it explicitly: + +```bash +cp Makefile.conf.template Makefile.conf +``` + +Edit `Makefile.conf` before compiling. Keep this file for subsequent rebuilds; +it is intentionally not tracked by Git. + +### Select modules + +`exclude_modules` lists modules omitted from the normal `modules` and `all` +targets. The default list primarily contains modules with external +dependencies. Remove a module from this list after installing its development +dependencies, or add it to `include_modules` to force it into the build without +rewriting the default exclusion list: + +```make +include_modules += db_mysql json +``` + +You may explicitly exclude additional modules: + +```make +exclude_modules += cachedb_redis event_rabbitmq +``` + +`include_modules` takes precedence for the named modules. Module names are the +directory names under `modules/`. + +For a one-off build, the same variables may be supplied on the command line: + +```bash +make -j4 modules include_modules="db_mysql json" +make -j4 modules skip_modules="cachedb_redis event_rabbitmq" +``` + +### Tune compiler and linker flags + +Use `CC_EXTRA_OPTS` and `LD_EXTRA_OPTS` for additional compiler and linker +options: + +```make +CC_EXTRA_OPTS += -O2 -march=native +LD_EXTRA_OPTS += -Wl,--as-needed +``` + +Use `DEFS` for OpenSIPS compile-time definitions. `Makefile.conf.template` +contains the supported definitions with short descriptions. Enable a disabled +definition by uncommenting it, or add a definition explicitly: + +```make +DEFS += -DEXTRA_DEBUG +DEFS += -DSHM_EXTRA_STATS +``` + +Only enable flags whose behavior is understood. Some allocator and locking +definitions are mutually exclusive or materially affect runtime performance. +Run `make proper` before rebuilding after changing compiler flags or +compile-time definitions. + +### Configure the installation prefix + +Set `PREFIX` in `Makefile.conf` to change the default installation root: + +```make +PREFIX ?= /opt/opensips/ +``` + +Use the same prefix for compilation and installation because the default +configuration path is compiled into the OpenSIPS binary. + +## Compile + +Build the core and selected modules: + +```bash +make -j4 all +``` + +Useful narrower targets are: + +```bash +make -j1 # core binary only +make -j4 modules # selected modules only +make -j1 modules module=db_mysql +``` + +## Install + +Install the core, selected modules, documentation, and database schemas using +the settings from `Makefile.conf`: + +```bash +make install +``` + +Command-line variables override the corresponding configuration for a one-off +operation. Pass the same values to both build and install steps. diff --git a/docs/manual/Install-DBDeployment.md b/docs/manual/Install-DBDeployment.md new file mode 100644 index 00000000000..dafe57c104f --- /dev/null +++ b/docs/manual/Install-DBDeployment.md @@ -0,0 +1,46 @@ +--- +title: "Database Deployment" +description: "After installing your OpenSIPS, most likely you will need to also deploy a database that you could use for various reasons ( DB user authentication, persiste..." +--- + +After installing your OpenSIPS, most likely you will need to also deploy a database that you could use for various reasons ( DB user authentication, persistent registrations, dialogs, etc ). + +--- + +You can deploy the opensips database using the [opensips-cli](https://github.com/OpenSIPS/opensips-cli) tool. Before you do that, you should [install it](https://github.com/OpenSIPS/opensips-cli#install). + +## Configuring OpenSIPS CLI + +Open your OpenSIPS CLI configuration file and specify the following parameters: +* `database_schema_path` - (defaults to `/usr/share/opensips/`) set it to `[Install_Path]/share/opensips/` +* `database_url` - the URL to connect to your database (if not specified, you will be prompted for it during deploy) +* `database_name` - (defaults to `opensips`) the database to use +* `database_modules` - (defaults to standard modules) the modules you want to deploy. + +You can find more information about the OpenSIPS CLI tool configuration [here](https://github.com/OpenSIPS/opensips-cli/blob/master/docs/modules/database.md#configuration). + +> [!NOTE] +> OpenSIPS CLI searches for its configuration files in `~/.opensips-cli.cfg`, `/etc/opensips-cli.cfg`, `/etc/opensips/opensips-cli.cfg`, but you can also specify your own configuration file using the `-f` parameter. + +## Creating the Database + +In order to create the `database_name` database that you have provisioned above, run +```bash + +opensips-cli -x database create + +``` + +Later, if you decide to add a new module, for example presence, simply call: +```bash + +opensips-cli -x database add presence + +``` + +You can also specify a different name for the database, for example `opensips_test`, using: +```bash + +opensips-cli -x database create opensips_test + +``` diff --git a/docs/manual/Install-DBSchema.md b/docs/manual/Install-DBSchema.md new file mode 100644 index 00000000000..fe1007fd59d --- /dev/null +++ b/docs/manual/Install-DBSchema.md @@ -0,0 +1,6 @@ +--- +title: "DB schema" +description: "" +--- + + diff --git a/docs/manual/Install-Download.md b/docs/manual/Install-Download.md new file mode 100644 index 00000000000..ee2b113c681 --- /dev/null +++ b/docs/manual/Install-Download.md @@ -0,0 +1,20 @@ +--- +title: "Download OpenSIPS" +description: "OpenSIPS packages for various distributions are available for download in our repository." +--- + +**OpenSIPS 3.6** is a **stable** release, appropriate for production usage. + +--- + +## Packages download - preferred method + +OpenSIPS packages for various distributions are available for download in [our repository](https://www.opensips.org/Downloads/Downloads#osipmi). + +## GIT download + +GitHUB hosts the main repository for OpenSIPS. In order to checkout the latest version of OpenSIPS, you can run: + +```bash +git clone --recurse-submodules https://github.com/OpenSIPS/opensips.git -b 3.6 opensips-3.6 +``` diff --git a/docs/manual/Interface-Binary.md b/docs/manual/Interface-Binary.md new file mode 100644 index 00000000000..0fdf265ddf4 --- /dev/null +++ b/docs/manual/Interface-Binary.md @@ -0,0 +1,56 @@ +--- +title: "Binary Internal Interface" +description: "The Binary Internal Interface is an OpenSIPS core interface which offers an efficient way for communication between individual OpenSIPS instances. This is es..." +--- + +The **Binary Internal Interface** is an OpenSIPS core interface which offers an efficient way for communication between individual OpenSIPS instances. This is especially useful in scenarios where realtime data (such as dialogs) cannot be simply stored in a database anymore, because failover would require entire minutes to complete. This issue can be solved with the new internal binary interface by replicating all the events related to the runtime data (creation / updating / deletion) to a backup OpenSIPS instance. + +--- + +## Configuring the Binary Internal Interface listeners + +In order to listen for incoming Binary Packets, a **bin:** interface must be specified. Its number of listener processes can be tuned with *[tcp_workers](https://docs.opensips.org/manual/3-6/script-coreparameters#tcp_workers)* core parameter. + +```opensips + + listen = bin:10.0.0.150:5062 + ... + loadmodule "proto_bin.so" + +``` + +Examples of cluster-enabled modules which use the binary interface are **dialog** and **usrloc**, as they can now replicate all run-time events (creation/updating/deletion of dialogs/contacts) to one or more OpenSIPS instances. Configuration can be done as follows: + +```opensips + + modparam("dialog", "dialog_replication_cluster", 1) + modparam("dialog", "profile_replication_cluster", 2) + ... + modparam("usrloc", "location_cluster", 2) + +``` + +More details can be found in the [dialog](../../modules/dialog/README.md#dialog_clustering) and [usrloc](../../modules/usrloc/README.md#distributed_sip_user_location) documentation pages. + +--- + +## C Interface Overview (for module developers) + +The interface allows the module writer to build and send compact **Binary Packets** in an intuitive way. + +In order to **send packets**, the interface provides the following primitives: +* *int bin_init(str *mod_name, int packet_type)* - begins the construction of a new Binary Packet +* *int bin_push_str(const str *info)* - add a string to the Binary Packet that is currently being built +* *int bin_push_int(int info)* - add an integer to the Binary Packet that is currently being built +* *int bin_send(union sockaddr_union *de*[tcp_workers](https://docs.opensips.org/manual/3-6/script-coreparameters#tcp_workers) *core parameter.st)* - sends the Binary Packet to a given destination over UDP + + + +In order to **receive packets**, a module must first register a callback function to the interface: +* *int bin_register_cb(char *mod_name, void (*)(int packet_type))* + + + +Each time this callback is triggered, the information can be retrieved in the same order it was written using: +* *int bin_pop_str(str *info)* - retrieve a string from a received Binary Packet +* *int bin_pop_int(void *info)* - retrieve an integer from a received Binary Packet diff --git a/docs/manual/Interface-CoreEvents.md b/docs/manual/Interface-CoreEvents.md new file mode 100644 index 00000000000..f12aa52cf3e --- /dev/null +++ b/docs/manual/Interface-CoreEvents.md @@ -0,0 +1,105 @@ +--- +title: "Core Events" +description: "Events are exported by the OpenSIPS core through the Event Interface." +--- + +Events are exported by the **OpenSIPS** core through the Event Interface. + +--- + +## E_CORE_THRESHOLD + +Threshold limit exceeded. + +This event is triggered when a particular action takes longer than a specific threshold. It can be raised when a MySQL or DNS query takes too long, or a SIP message processing goes beyond a specific limit. For more information please see [this](http://lists.opensips.org/pipermail/users/2011-February/016918.html) post. + +Parameters: +* **source**: the source of the event: mysql module, core (for DNS or message processing warnings). +* **time**: the amount of time (in microseconds) spent by the operation +* **extra**: extra information, depending on the source of the event + +## E_CORE_PKG_THRESHOLD + +Private memory threshold exceeded. + +This event is triggered when the private memory usage goes above a threshold limit, specified by the **event_pkg_threshold** the core parameter. It warns external applications about low values of free private memory. + +Parameters: +* **usage**: the percentage of private memory usage. Can have values between **event_pkg_threshold** and 100. +* **threshold**: the **event_pkg_threshold** specified in the script. +* **used**: the amount of private memory used. +* **size**: the total amount of private memory. +* **pid**: the pid of the process that raises the event. + +> [!NOTE] +> If the event_pkg_threshold is not specified or 0, then this event is disabled. + +## E_CORE_SHM_THRESHOLD + +Shared memory threshold exceeded. + +This event is triggered when the shared memory usage goes above a threshold limit, specified by the **event_shm_threshold** the core parameter. It warns external applications about low values of free shared memory. + +Parameters: +* **usage**: the percentage of shared memory usage. Can have values between **event_shm_threshold** and 100. +* **threshold**: the **event_shm_threshold** specified in the script. +* **used**: the amount of shared memory used. +* **size**: the total amount of shared memory. + +> [!NOTE] +> If the event_shm_threshold is not specified or 0, then this event is disabled. + +## E_CORE_PROC_AUTO_SCALE + +Process Auto-Scaling (upscale and downscale). + +This event is triggered whenever a new process is created (forked) or a process is terminated due the auto-scaling logic. In order to have this event trigger, the [auto-scaling](https://docs.opensips.org/manual/3-6/script-coreparameters#auto_scaling_profile) must be enabled in your configuration. + +Parameters: +* **group_type**: the type/name of the scaling group (UDP/TCP/TIMER). +* **group_filter**: the filter (usually the socket/interface for UDP) of the scaling group. +* **group_load**: the load over the scaling group. +* **scale**: "up" or "down" +* **process_id**: the process ID (at OpenSIPS level) of the scaled (up or down) process. +* **pid**: the PID (OS level) of the scaled (up or down) process. + +## E_CORE_TCP_DISCONNECT + +TCP connection disconnected. + +This event is triggered when a TCP connection is terminated/disconnected. + +Parameters: +* **src_ip**: the source IP of the TCP connection +* **src_port**: the source PORT of the TCP connection +* **dst_ip**: the destination IP of the TCP connection +* **dst_port**: the destination PORT of the TCP connection +* **proto**: the protocol of the underlying TCP connection ( ie. tcp, tls, ws, wss, etc ) + +## E_CORE_SR_STATUS_CHANGED + +Status/Report status changed. + +This event is triggered the status of an SR identifier changes. + +Parameters: +* **group**: the name of the SR group +* **identifier**: the name of the SR identifier +* **status**: the new status (as numerical value) of the SR identifier +* **details**: the details/text attached to the new status +* **old_status**: the old status (as numerical value) of the SR identifier + +## E_CORE_LOG + +Log message produced. + +This event is triggered whenever a log message is produced by OpenSIPS. In order to have this event trigger, the [log_event_enabled](https://docs.opensips.org/manual/3-4/script-coreparameters#log_event_enabled) must be enabled in your configuration. + +Parameters: +* **time**: time when the log message was produced +* **pid**: the PID of the processes that produced this log message +* **level**: the log level of this message ("DBG", "INFO" etc.) +* **module**: module that produced this log message; absent for logs triggered from the script by the **xlog()** function +* **function**: internal function that produced this log message; absent for logs triggered from the script by the **xlog()** function +* **prefix**: logging prefix, configured via the [log_prefix](https://docs.opensips.org/manual/3-4/script-coreparameters#log_prefix) parameter. This parameter is absent if the parameter is not configured. +* **message**: the actual log message content diff --git a/docs/manual/Interface-CoreMI.md b/docs/manual/Interface-CoreMI.md new file mode 100644 index 00000000000..df9667425ee --- /dev/null +++ b/docs/manual/Interface-CoreMI.md @@ -0,0 +1,925 @@ +--- +title: "Core MI Functions" +description: "MI (management interface) functions which are exported by OpenSIPS core." +--- + +MI (management interface) functions which are exported by **OpenSIPS** core. + +## Core + +### arg +Returns the full list of arguments used when **OpenSIPS** was started. As in UNIX, the first argument is the name of executable binary. + +**Arguments**: none + +**Output**: an array with multiple strings representing the arguments. + +Example of usage: +```bash + + $ opensips-cli -x mi arg + [ + "./opensips", + "-f", + "/etc/openser/test.cfg" + ] + +``` + +### help +Prints MI command usage information. When *mi_cmd* is provided, the response includes the command description and the module which exports it. + +**Arguments**: +* *mi_cmd* (optional) - MI command name + +Examples of usage: +```bash + + $ opensips-cli -x mi help + $ opensips-cli -x mi help version + +``` + +### kill +The command will terminate **OpenSIPS** (and internal shutdown). + +**Arguments**: none + +**Output**: none + +Examples of usage: +```bash + + $ opensips-cli -x mi kill + +``` + +### log_level [level] [pid] +Get or set the logging level of one or all OpenSIPS processes. If no argument is passed to the **log_level** command, it will print a table with the current logging levels of all processes. If a logging **level** is given, it will be set for each process. If **pid** is also given, the logging level will change only for that process. + +**Arguments**: +* *level* (optional) - logging level (-3...4) (see [meaning of the values](Script-CoreParameters.md#log_level)) +* *pid* (optional) - Unix pid (validated by OpenSIPS) + +Examples of usage: +```bash + + $ opensips-cli -x mi log_level + { + "Processes": [ + { + "PID": 10670, + "Log level": 2, + "Type": "attendant" + }, + { + "PID": 10672, + "Log level": 3, + "Type": "MI FIFO" + }, + { + "PID": 10673, + "Log level": 1, + "Type": "SIP receiver udp:193.668.3.633:5060" + }, + ] + } + $ opensipsctl fifo log_level 1 + { + "New global log level": 1 + } + $ opensipsctl fifo log_level 4 10670 + { + "Log level": 1 + } + +``` + +### log_level_filter consumer [level_filter] +Get or set the level of the extra filtering applied to log messages for a specific logging "consumer"(*stderror*, *syslog* or *event*). If **log_level_filter** is not given, the command will print the current level filter for the specified consumer. + +**Arguments**: +* *consumer* (optional) - logging consumer: *stderror*, *syslog* or *event*; +* *log_level_filter* (optional) - the log level filter. + +Examples of usage: +```bash + + $ opensips-cli -x mi log_level_filter stderror + { + "Log level filter": 3 + } + $ opensips-cli -x mi log_level_filter stderror 1 + "OK" + +``` + +### log_mute_state consumer [mute_state] +Get or set the mute state (printing enabled/disabled) of a specific logging "consumer"(*stderror*, *syslog* or *event*). If **mute_state** is not given, the command will print the current mute state for the specified consumer. + +**Arguments**: +* *consumer* (optional) - logging consumer: *stderror*, *syslog* or *event*; +* *mute_state* (optional) - the new mute state: *1* - muted or *0* - unmuted (enabled) + +Examples of usage: +```bash + + $ opensips-cli -x mi log_mute_state syslog + { + "mmute state": 0 + } + $ opensips-cli -x mi log_mute_state syslog 1 + "OK" + +``` + +### ps +The command will list all all **OpenSIPS** processes, along with type and description. + +**Arguments**: none + +**Output**: multiple objects, each one containing a process ID (internal), PID (OS) and Type. + +Examples of usage: +```bash + + $ opensips-cli -x mi ps + { + "Processes": [ + { + "ID": 0, + "PID": 27271, + "Type": "attendant" + }, + { + "ID": 1, + "PID": 27272, + "Type": "MI FIFO" + }, + { + "ID": 2, + "PID": 27273, + "Type": "time_keeper" + }, + { + "ID": 3, + "PID": 27274, + "Type": "timer" + }, + { + "ID": 4, + "PID": 27275, + "Type": "SIP receiver udp:127.0.0.1:5060" + }, + { + "ID": 5, + "PID": 27276, + "Type": "Timer handler" + } + ] + } + +``` + +### pwd +Prints the working directory of **OpenSIPS** instance. + +**Arguments**: none + +**Output**: a single item containing the working directory full path. + +Examples of usage: +```bash + + $ opensips-cli -x mi pwd + { + "WD": "/" + } + +``` + +### reload_routes +Triggers the reload of the routing block (the routes) from the script during the runtime. +**Arguments**: none + +**Output**: none + +Please note that there are some limitations of when a reload is possible or not. Depending on the initial configuration of your modules, the reload may be rejected as the usage of the functions in the new script is not compatible with the original module setting and initialization. + +If the reload fails, take a look at the logs to understand why - it may have been a syntax error or maybe a module related constraint. Anyhow, if the reload fails, there is no impact on your running OpenSIPS. + +### uptime +Prints various time information about **OpenSIPS** - when it started to run, for how long it runs. + +**Arguments**: none + +**Output**: three items: "Now" - current time; "Up since" - start time ; "Up time" - number of seconds since started. + +Examples of usage: +```bash + + $ opensips-cli -x mi uptime + { + "Now": "Mon Jul 21 17:41:03 2008", + "Up since": "Mon Jul 21 17:36:33 2008", + "Up time": "270 [sec]" + } + +``` + +### version +Prints the version string of a running**OpenSIPS**. + +**Arguments**: none + +**Output**: one item (named "Server") containing the version string. + +Examples of usage: +```bash + + $ opensips-cli -x mi version + { + "Server": "OpenSIPS (3.6.0-dev (x86_64/linux))" + } + +``` + +### which +Prints all available MI commands from the queried **OpenSIPS**instance. + +**Arguments**: none + +**Output**: an array of the names of available MI commands. NOTE that the list of available MI commands may differ depending of what modules your **OpenSIPS** is using. + +Examples of usage: +```bash + + $ opensips-cli -x mi which + [ + "get_statistics", + "list_statistics", + "reset_statistics", + "uptime", + "version", + "pwd", + "arg", + "which", + "ps", + "kill", + "log_level", + "xlog_level", + "shm_check", + "cache_store", + "cache_fetch", + "cache_remove", + "event_subscribe", + "events_list", + ... + +``` + +### xlog_level [level] +Get or set the global xlogging level in OpenSIPS processes. If no argument is passed to the **xlog_level** command, it will print the current **xlog_level**. If a logging **level** is given, it will be globally set for all OpenSIPS processes. + +**Arguments**: +* *level* (optional) + +Example of usage: +```bash + + $ opensips-cli -x mi xlog_level -2 + +``` + +## Blacklists + +### list_blacklists +The command lists all the defined (static or learned) blacklists from **OpenSIPS**. + +**Arguments**: +* *name* (optional) - filter and print only rules in a specific blacklist +**Output**: an array with each object describing the list (name, owner, flags); the "Rules" item is an array with each object member describing the rules (blacklists) for each list (IP/mask, protocol, port, matching regexp, flags). + +Examples of usage: +```bash + + $ opensips-cli -x mi list_blacklists + +``` + +### check_blacklists +The command returns all the blacklists that match an proto:IP:port+pattern. + +**Arguments**: +* *proto* (optional) - protocol of the check rule - if missing, "any" protocol is used. Note that an "any" protocol check can only match an "any" protocol rule. +* *ip* - the mandatory IP that is used to match the rules +* *port* (optional) - the port of the check rule - if missing, 0/any port is used. Note that a 0 port will only match a 0 port rule. +* *pattern* (optional) - optional pattern to check against the rules +**Output**: an array with the names of each blacklist that matched. + +Examples of usage: +```bash + + $ opensips-cli -x mi check_blacklists 127.0.0.1 + $ opensips-cli -x mi check_blacklists udp 127.0.0.1 5060 + +``` + +### check_blacklist +The command check whether a proto:IP:port+pattern matches any rule of a blacklist. + +**Arguments**: +* *name* = the name of the blacklist to check against +* *proto* (optional) - protocol of the check rule - if missing, "any" protocol is used. Note that an "any" protocol check can only match an "any" protocol rule. +* *ip* - the mandatory IP that is used to match the rules +* *port* (optional) - the port of the check rule - if missing, 0/any port is used. Note that a 0 port will only match a 0 port rule. +* *pattern* (optional) - optional pattern to check against the rules +**Output**: an object containing the first rule that matched, or an error if nothing matched. + +Examples of usage: +```bash + + $ opensips-cli -x mi check_blacklist net_dynamic 127.0.0.1 + $ opensips-cli -x mi check_blacklists net_dynamic udp 127.0.0.1 5060 + +``` + +### add_blacklist_rule +Adds a rule to a non-readonly blacklist. + +**Arguments**: +* *name*- the name of the blacklist to add to +* *rule* - a string containing a blacklist rule, according to [**dst_blacklist**](https://docs.opensips.org/manual/3-6/script-coreparameters#dst_blacklist) parameter +* *expire* (optional) - indicates the number of seconds the rule should expire +**Output**: success or failed object. + +Examples of usage: +```bash + + $ opensips-cli -x mi add_blacklist_rule net_dynamic '!tcp,127.0.0.1,5060' + $ opensips-cli -x mi add_blacklist_rule net_dynamic '!tcp,127.0.0.1,5060' 3600 + +``` + +### del_blacklist_rule +Removes a rule from a non-readonly blacklist. + +**Arguments**: +* *name* - the name of the blacklist to remove from +* *rule* - a string containing a blacklist rule, according to [**dst_blacklist**](https://docs.opensips.org/manual/3-6/script-coreparameters#dst_blacklist) parameter +**Output**: success or failed object. + +Examples of usage: +```bash + + $ opensips-cli -x mi del_blacklist_rule net_dynamic '!tcp,127.0.0.1,5060' + +``` + +## TCP connections + +### list_tcp_conns +The command lists all ongoing TCP/TLS connection from **OpenSIPS**. + +**Arguments**: none + +**Output**: an array with one object per connection with the following attributes : ID, type, state, source, destination, lifetime, alias port. + +Examples of usage: +```bash + + $ opensips-cli -x mi list_tcp_conns + +``` + +## Status Report + +### sr_get_status +The MI equivalent of the [sr_check_status() script function](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) - to get the status of an 'status/report' identifier/group. + +**Arguments**: a mandatory *group* and optional *identifier*, see the parameters of the [sr_check_status() script function](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status). +**Output**: the readiness, the status and details of the identifier/group (see the aggregation note for the return code of the [sr_check_status() script function](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) + +Examples of usage: +```bash + +$ opensips-cli -x mi sr_get_status core +{ + "Readiness": true, + "Status": 1, + "Details": "running" +} + +$ opensips-cli -x mi sr_get_status drouting all +{ + "Readiness": true, + "Status": 1, + "Details": "aggregated" +} + +``` + +### sr_list_status +Command to list the status of the identifiers within one or all 'status/report' groups. + +**Arguments**: an optional 'status/report' *group*, see the [sr_check_status() script function](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) for more details. +**Output**: the readiness, the status and details for all the identifiers within the requested group, or within all defined/registered groups. + +Examples of usage: +```bash + +$ opensips-cli -x mi sr_list_status +[ + { + "Name": "drouting", + "Identifiers": [ + { + "Name": "Default", + "Readiness": true, + "Status": 1, + "Details": "data available" + } + ] + }, + { + "Name": "test", + "Identifiers": [ + { + "Name": "main", + "Readiness": true, + "Status": 1 + } + ] + }, + { + "Name": "core", + "Identifiers": [ + { + "Name": "main", + "Readiness": true, + "Status": 1, + "Details": "running" + } + ] + } +] + +``` + +### sr_list_reports +Command to list the full set of reports (logs) collected by 'status/report' identifiers. + +**Arguments**: +* an optional 'status/report' *group*, see the [sr_check_status() script function](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) for more details. If missing, all the groups will be listed. +* an optional 'identifier'. If missing, all the identifiers within the group will be listed. +**Output**: the reports/logs for the requested identifiers, or for all identifiers within the groups. + +Examples of usage: +```bash + +$ bin/opensips-cli -x mi sr_list_reports +[ + { + "Name": "drouting", + "Identifiers": [ + { + "Name": "Default", + "Reports": [ + { + "Timestamp": 1644396830, + "Date": "Wed Feb 9 10:53:50 2022", + "Log": "starting DB data loading" + }, + { + "Timestamp": 1644396830, + "Date": "Wed Feb 9 10:53:50 2022", + "Log": "DB data loading successfully completed" + }, + { + "Timestamp": 1644396830, + "Date": "Wed Feb 9 10:53:50 2022", + "Log": "2 gateways loaded (0 discarded), 2 carriers loaded (0 discarded), 1 rules loaded (0 discarded)" + } + ] + } + ] + }, + { + "Name": "test", + "Identifiers": [ + { + "Name": "main", + "Reports": [] + } + ] + }, + { + "Name": "core", + "Identifiers": [ + { + "Name": "main", + "Reports": [ + { + "Timestamp": 1644396830, + "Date": "Wed Feb 9 10:53:50 2022", + "Log": "initializing" + }, + { + "Timestamp": 1644396830, + "Date": "Wed Feb 9 10:53:50 2022", + "Log": "initialization completed, ready now" + } + ] + } + ] + } +] + +``` + +### sr_list_identifiers +Command to list all the existing identifiers in OpenSIPS or only from a certain group. + +**Arguments**: +* an optional 'status/report' *group*, see the [sr_check_status() script function](https://docs.opensips.org/manual/3-3/script-corefunctions#sr_check_status) for more details. If missing, the identifiers from all the groups will be listed. +**Output**: an array of groups, each group being an array of identifiers . + +Examples of usage: +```bash + +$ opensips-cli -x mi sr_list_identifiers +[ + { + "Group": "clusterer", + "Identifiers": [ + "sharing_tags" + ] + }, + { + "Group": "dispatcher", + "Identifiers": [ + "default;events", + "default" + ] + }, + { + "Group": "drouting", + "Identifiers": [ + "Default;events", + "Default" + ] + }, + { + "Group": "dialplan", + "Identifiers": [ + "default" + ] + }, + { + "Group": "core", + "Identifiers": [ + "main" + ] + } +] + +$ opensips-cli -x mi sr_list_identifiers drouting +{ + "Group": "drouting", + "Identifiers": [ + "Default;events", + "Default" + ] +} + +``` + +## Statistics + +### get_statistics +Prints the statistics (all, group or one) realtime values. + +**Arguments**: +* *statistics* - an array of the following possible values: + * "all" - print all available statistics; + * "group_name:" - print only statistics from a certain group named "group_name"; the **OpenSIPS** core defines the following groups: *core*, *shmem*; Modules export groups typically named like the module itself. + * "name" - print only the statistic named "name". +**Output**: an object containing the names and values of statistic variables. + +Examples of usage: +```bash + + $ opensips-cli -x mi get_statistics rcv_requests + { + "core:rcv_requests": 35243 + } + + $ opensipsc-cli -x mi get_statistics shmem: + { + "shmem:total_size": 1073741824, + "shmem:max_used_size": 3389232, + "shmem:free_size": 1070352592, + "shmem:used_size": 2808952, + "shmem:real_used_size": 3389232, + "shmem:fragments": 3769 + } + + $ opensips-cli -x mi get_statistics shmem: core: + .... + +``` + +### list_statistics +Prints a list of available statistics in the current configuration of OpenSIPS. +**Arguments**: +* *statistics* (optional) - an array of the same possible values as for **get_statistics** MI command, with the exception of "all". Omitting the parameter will list all available statistics. + +Examples of usage: +```bash + + $ opensips-cli -x mi list_statistics + { + "shmem:total_size": "non-incremental", + "shmem:max_used_size": "non-incremental", + "shmem:free_size": "non-incremental", + "shmem:used_size": "non-incremental", + "shmem:real_used_size": "non-incremental", + "shmem:fragments": "non-incremental", + "rpmem:rpm_total_size": "non-incremental", + "rpmem:rpm_used_size": "non-incremental", + ... + +``` + +### reset_statistics +Reset (to zero) the value of a statistic variable. Note that not all variables allow reset (depending of the nature of the information they carry - example "shmem:used_size"). + +**Arguments**: +* *statistics* - an array of the names of the variables to be reset. +**Output**: none. + +Examples of usage: +```bash + + $ opensips-cli -x mi get_statistics received_replies + { + "tm:received_replies": 14543 + } + + $ opensips-cli -x mi reset_statistics received_replies + $ opensips-cli -x mi get_statistics received_replies + { + "tm:received_replies": 0 + } + +``` + +### reset_all_statistics +Reset (to zero) the value of all statistic variables that can be reset. Note that not all variables allow reset (depending of the nature of the information they carry - example "shmem:used_size"). + +**Output**: none. + +Examples of usage: +```bash + + $ opensips-cli -x mi reset_all_statistics + +``` + +## CacheDB interface + +### cache_store +This command stores in a cache system a string value. + +**Arguments**: +* *system* - cache system to use - for the cache system implemented by **OpenSIPS** module 'localcache' the value of this parameter should be 'local'; +* *attr* - the label to be associated with this value; +* *value* - the string to be stored; +* *expire* (optional) - expire time for the stored value; +**Output**: none. + +Examples of usage: +```bash + + $ opensips-cli -x mi cache_store local password_user1 password + +``` + +### cache_fetch +This command queries for a stored value. + +**Arguments**: +* *system* - cache system to use - for the cache system implemented by **OpenSIPS** module 'localcache' the value of this parameter should be 'local' +* *attr* - the label associated with the value +**Output**: object containing the value if a record is found or 'Value not found' string otherwise. + +Examples of usage: +```bash + + $ opensips-cli -x mi cache_fetch local password_user1 + +``` + +### cache_remove +This command removes a record from the cache system. + +**Arguments**: +* *system* - cache system to use; +* *attr* - the label associated with the stored value; +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi cache_remove local password_user1 + +``` + +## Event Interface + +### event_subscribe +Subscribes an external application to a certain event. + +**Arguments**: +* *event* - event name +* *socket* - external application socket +* *expire* (optional) - expire time, in seconds - if absent, the subscription is valid only one hour (3600 s) +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi event_subscribe E_PIKE_BLOCKED udp:127.0.0.1:8888 1200 + +``` + +### events_list +Lists all the events published through the Event Interface. + +**Arguments**: None. + +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi events_list + { + "Events": [ + { + "name": "E_CORE_THRESHOLD", + "id": 0 + }, + { + "name": "E_CORE_SHM_THRESHOLD", + "id": 1 + }, + { + "name": "E_CORE_PKG_THRESHOLD", + "id": 2 + }, + ... + +``` + +### raise_event +Raises an event through the Event Interface using an MI command. + +**Arguments**: +* *event* - event name +* *params* (optional) - array of elements, or a string consisting of a JSON object containing key-value pairs +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi raise_event E_PIKE_BLOCKED 127.0.0.1 # array mode + $ opensips-cli -x -- mi -j raise_event event=E_PIKE_BLOCKED params='{"ip":"127.0.0.1"}' # json mode + +``` + +### subscribers_list +Lists information about the subscribers + +**Arguments**: +* *event* - event name +* *socket* (optional) - external application socket +**Output**: If no parameter is specified, then the command returns information about all events and their subscribers. If the event is specified, only the external applications subscribed for that event are returned. If the socket is also specified, only one subscriber information is returned. + +Examples of usage: +```bash + + $ opensips-cli -x mi subscribers_list + { + "Events": [ + { + "name": "E_RTPPROXY_STATUS", + "id": 1, + "subscribers": [ + ... + ] + }, + { + "name": "E_PIKE_BLOCKED", + "id": 2, + "subscribers": [ + ... + ] + } + ] + } + + $ opensips-cli -x mi subscribers_list E_RTPPROXY_STATUS + { + "Event": { + "name": "E_RTPPROXY_STATUS", + "id": 1, + "subscribers": [ + { + "socket": "unix:/tmp/event.sock", + "expire": "never", + }, + { + "socket": "udp:127.0.0.1:8888", + "expire": 1100, + "ttl": 1046 + } + ] + } + } + + $ opensips-cli -x mi subscribers_list E_RTPPROXY_STATUS unix:/tmp/event.sock + { + "Event": { + "name": "E_RTPPROXY_STATUS", + "id": 1, + "Subscriber": { + "socket": "unix:/tmp/event.sock", + "expire": "never" + } + } + } + +``` + +## Memory + +### mem_pkg_dump +Triggers a pkg memory dump for a given process. The memory dump will written to OpenSIPS's log (syslog or stderr) using the 'memdump' logging level. The global 'memdump' log level may be overwritten by a custom value provided as argument to this command. + +**Arguments**: +* *pid* - the PID of the process to perform the pkg dump +* *log_level* (optional) - a log level to be used for this dump +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi mem_pkg_dump 11854 -1 + +``` + +> [!IMPORTANT] +> The processes without IPC support (like timer and per-module processes) will not be able to generate a memory dump. + +### mem_rpm_dump +Triggers a restart-persistent memory dump. The memory dump is written to OpenSIPS's log (syslog or stderr) using the `memdump` logging level. The global `memdump` level may be overridden by the optional argument. + +**Arguments**: +* *log_level* (optional) - logging level used for this dump + +Examples of usage: +```bash + + $ opensips-cli -x mi mem_rpm_dump + $ opensips-cli -x mi mem_rpm_dump -1 + +``` + +### mem_shm_dump +Triggers a shm memory dump. The memory dump will written to OpenSIPS's log (syslog or stderr) using the 'memdump' logging level. The global 'memdump' log level may be overwritten by a custom value provided as argument to this command. + +**Arguments**: +* *log_level* (optional) - a log level to be used for this dump +**Output**: None. + +Examples of usage: +```bash + + $ opensips-cli -x mi mem_shm_dump -1 + +``` + +### shm_check +Only available with *QM_MALLOC* + *DBG_MALLOC*. Fully scans the shared memory pool in order to locate any inconsistencies. If any sign of memory corruption is detected, OpenSIPS will immediately abort. + +**Arguments**: None + +**Output**: current number of fragments. + +Example of usage: +```bash + + $ opensips-cli -x mi shm_check + +``` diff --git a/docs/manual/Interface-CoreStatistics.md b/docs/manual/Interface-CoreStatistics.md new file mode 100644 index 00000000000..9ed1a6c5750 --- /dev/null +++ b/docs/manual/Interface-CoreStatistics.md @@ -0,0 +1,562 @@ +--- +title: "Core Statistics" +description: "The OpenSIPS core exports several statistics, which are grouped into classes. To view all statistics which correspond to a class, fetch the \"class:\" statisti..." +--- + +The **OpenSIPS** core exports several statistics, which are grouped into **classes**. To view all statistics which correspond to a class, fetch the "class:" statistic (e.g. **opensips-cli -x mi get_statistics load: core: shmem:**) + +--- + +## "CORE" class + +### rcv_requests +Returns the total number of received requests by OpenSIPS. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics rcv_requests + +``` + +Example of usage from script +```opensips + +xlog("Total number of received requests = $stat(rcv_requests) \n"); + +``` + +### rcv_replies +Returns the total number of received replies by OpenSIPS. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics rcv_replies + +``` + +Example of usage from script +```opensips + +xlog("Total number of received replies = $stat(rcv_replies) \n"); + +``` + +### fwd_requests +Returns the number of stateless forwarded requests by OpenSIPS. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics fwd_requests + +``` + +Example of usage from script +```opensips + +xlog("Total number of forwarded requests = $stat(fwd_requests) \n"); + +``` + +### fwd_replies +Returns the number of stateless forwarded replies by OpenSIPS. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics fwd_replies + +``` + +Example of usage from script +```opensips + +xlog("Total number of forwarded replies = $stat(fwd_replies) \n"); + +``` + +### drop_requests +Returns the number of requests dropped even before entering the script routing logic. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics drop_requests + +``` + +Example of usage from script +```opensips + +xlog("Total number of dropped requests = $stat(drop_requests) \n"); + +``` + +### drop_replies +Returns the number of replies dropped even before entering the script routing logic, or explicitly dropped in the +onreply_route. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics drop_replies + +``` + +Example of usage from script +```opensips + +xlog("Total number of dropped replies = $stat(drop_replies) \n"); + +``` + +### err_requests +Returns the number of bogus requests from SIP point of view ( eg. : No VIA header found ) + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics err_requests + +``` + +Example of usage from script +```opensips + +xlog("Total number of error requests = $stat(err_requests) \n"); + +``` + +### err_replies +Returns the number of bogus replies from SIP point of view ( eg. : No VIA header found ) + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics err_replies + +``` + +Example of usage from script +```opensips + +xlog("Total number of error replies = $stat(err_replies) \n"); + +``` + +### bad_URIs_rcvd +Returns the number of URIs that OpenSIPS failed to parse. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics bad_URIs_rcvd + +``` + +Example of usage from script +```opensips + +xlog("Total number of bad URIs detected = $stat(bad_URIs_rcvd) \n"); + +``` + +Example of usage from script +```opensips + +xlog("Total number of unsupported methods detected = $stat(unsupported_methods) \n"); + +``` + +### bad_msg_hdr +Returns the number of SIP headers that OpenSIPS failed to parse. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics bad_msg_hdr + +``` + +Example of usage from script +```opensips + +xlog("Total number of headers that failed to parse = $stat(bad_msg_hdr) \n"); + +``` + +### timestamp +Returns the number of seconds elapsed from OpenSIPS starting. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics timestamp + +``` + +Example of usage from script +```opensips + +xlog("OpenSIPS has been alive for $stat(timestamp) seconds \n"); + +``` + +--- + +## "LOAD" class + +Statistics giving information about the OpenSIPS internal load. The load is defined as percentage of time spent in doing processing versus total time. Following the model of "top", there are three load values, calculated over different periods of time: +* realtime load - calculated over the last 1 second +* last minute load - calculated over the last 1 minute +* last 10 minutes load - calculated over the last 10 minutes + +All three load values are provided by OpenSIPS in a per-process manner (the load of each process) and globally (covering all processes). + +### load +The realtime load of entire OpenSIPS - this counts all the core processes of OpenSIPS; the additional processes requested by modules are not counted in this load. Also note that some core processes are not counted as they do not generate any kind of load; such processes are the attendant, the time keeper and the timer trigger. +This statistic is actually reflecting the load generated by processing the SIP traffic (as only the core active processes are counted). + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics load +load:load:: 24 + +``` + +Example of usage from script +```opensips + +xlog("The OpenSIPS processing load is $stat(load) \n"); + +``` + +### load1m +The last minute average load of core OpenSIPS (covering only core/SIP processes). For more, see [load](#load). + +### load10m +The last 10 minutes average load of core OpenSIPS (covering only core/SIP processes). For more, see [load](#load). + +### load-all +The realtime load of entire OpenSIPS, counting both core and module processes. Similar to [[#load|load], the processes not generating load at all are not counted. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics load-all +load:load-all:: 24 + +``` + +Example of usage from script +```opensips + +xlog("The overall OpenSIPS load is $stat(load-all) \n"); + +``` + +### load1m-all +The last minute average load of entire OpenSIPS (covering all processes). For more, see [load-all](#load-all). + +### load10m-all +The last 10 minutes average load of entire OpenSIPS (covering all processes). For more, see [load-all](#load-all). + +### load-proc-id +The realtime load of the process **ID**. To learn the IDs of the OpenSIPS processes (and their types), use the **ps** MI command. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics load-proc-5 +load:load-proc-5:: 79 + +``` + +Example of usage from script +```opensips + +xlog("The load of processes 5 is $stat(load-proc-5) \n"); + +``` + +### load1m-proc-id +The last minute average load of the process **ID**. For more, see [load-proc-id](#load-proc-id). + +### load10m-proc-id +The last 10 minutes average load of the process **ID**. For more, see [load-proc-id](#load-proc-id). + +--- + +## "NET" class + +Statistics giving information about UDP, TCP and TLS buffers on interfaces that OpenSIPS is listening on. + +### waiting_udp +Returns the number of bytes waiting to be consumed on UDP interfaces that OpenSIPS is listening on. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics waiting_udp + +``` + +Example of usage from script +```opensips + +xlog("The UDP waiting buffer size is $stat(waiting_udp) \n"); + +``` + +### waiting_tcp +Returns the number of bytes waiting to be consumed on TCP interfaces that OpenSIPS is listening on. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics waiting_tcp + +``` + +Example of usage from script +```opensips + +xlog("The TCP waiting buffer size is $stat(waiting_tcp) \n"); + +``` + +### waiting_tls +Returns the number of bytes waiting to be consumed on TLS interfaces that OpenSIPS is listening on. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics waiting_tls + +``` + +Example of usage from script +```opensips + +xlog("The TLS waiting buffer size is $stat(waiting_tls) \n"); + +``` + +--- + +## "SHMEM" class + +Statistics giving information on the shared memory that OpenSIPS is using. + +### total_size +Returns the total size of shared memory available to OpenSIPS processes. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics total_size + +``` + +Example of usage from script +```opensips + +xlog("Total size of SHMEM available is $stat(total_size) \n"); + +``` + +### used_size +Returns the amount of shared memory requested and used by OpenSIPS processes. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics used_size + +``` + +Example of usage from script +```opensips + +xlog("SHMEM in use = $stat(used_size) \n"); + +``` + +### real_used_size +Returns the amount of shared memory requested by OpenSIPS processes + malloc overhead + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics real_used_size + +``` + +Example of usage from script +```opensips + +xlog("Real SHMEM used size is $stat(real_used_size) \n"); + +``` + +### max_used_size +Returns the maximum amount of shared memory ever used by OpenSIPS processes. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics max_used_size + +``` + +Example of usage from script +```opensips + +xlog("The max SHMEM ever used is $stat(max_used_size) \n"); + +``` + +### free_size +Returns the free memory available. Computed as total_size - real_used_size + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics free_size + +``` + +Example of usage from script +```opensips + +xlog("Free SHMEM available is $stat(free_size) \n"); + +``` + +### fragments +Returns the total number of fragments in the shared memory. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics fragments + +``` + +Example of usage from script +```opensips + +xlog("The total number of SHMEM fragments is $stat(fragments) \n"); + +``` + +--- + +## "PKMEM" class + +Various private memory related statistics for each OpenSIPS process. Each "PKMEM" statistic is prefixed by a number, representing the index of an OpenSIPS process (0, 1, ...). + +### N-total_size +Returns the total size of private memory available to OpenSIPS process #N. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-total_size + +``` + +Example of usage from script +```opensips + +xlog("Total size of PKG memory available for process #0 is $stat(0-total_size) \n"); + +``` + +### N-used_size +Returns the amount of private memory requested and used by OpenSIPS process #N. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-used_size + +``` + +Example of usage from script +```opensips + +xlog("PKG mem in use for process #1 = $stat(1-used_size) \n"); + +``` + +### N-real_used_size +Returns the amount of private memory requested by OpenSIPS process #N, including allocator-specific metadata + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-real_used_size + +``` + +Example of usage from script +```opensips + +xlog("Process #0 actually uses $stat(0-real_used_size) bytes of private memory\n"); + +``` + +### N-max_used_size +Returns the maximum amount of private memory ever used by OpenSIPS process #N. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-max_used_size + +``` + +Example of usage from script +```opensips + +xlog("The max PKG memory ever used for process #0 is $stat(0-max_used_size) \n"); + +``` + +### N-free_size +Returns the free private memory available for OpenSIPS process #N. Computed as total_size - real_used_size + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-free_size + +``` + +Example of usage from script +```opensips + +xlog("Free PKG memory available for process #0 is $stat(0-free_size) \n"); + +``` + +### N-fragments +Returns the currently available number of free fragments in the private memory for OpenSIPS process #N. + +Example of usage through MI FIFO +```opensips + +opensips-cli -x mi get_statistics 0-fragments + +``` + +Example of usage from script +```opensips + +xlog("The total number of PKG fragments is $stat(0-fragments) \n"); + +``` diff --git a/docs/manual/Interface-Events.md b/docs/manual/Interface-Events.md new file mode 100644 index 00000000000..e70f9d9a7c1 --- /dev/null +++ b/docs/manual/Interface-Events.md @@ -0,0 +1,73 @@ +--- +title: "Events Interface" +description: "The Events Interface is an OpenSIPS interface that provides different ways to notify external applications about certain events triggered inside OpenSIPS." +--- + +The **Events Interface** is an OpenSIPS interface that provides different ways to notify external applications about certain events triggered inside OpenSIPS. + +## Overview + +In order to notify an external application about OpenSIPS internal events, the **Event Interface** provides the following functions: +* manages exported events +* manages subscriptions from different applications +* exports generic functions to raise an event (regardless the transport protocol used) +* communicates with different transport protocols to send the events + +More detailed information about **OpenSIPS Event Interface** can be found in the [Event Interface Tutorial](https://docs.opensips.org/tutorials/eventinterface/). + +--- + +## Events + +There are several types of events that can be exported by OpenSIPS: +* **Core events** - internal events that trigger changes of OpenSIPS core/global behavior. A full list of exported core events can be found [here](Interface-CoreEvents.md). +* **Modules events** - events triggered by each module, when loaded. Each module can export zero, one or more events. Details can be found in the [documentation page](Modules.md) of each module. +* **Custom events** - triggered from script using the [raise_event()](Script-CoreFunctions.md#raise_event) command. + +--- + +## Transport Protocols + +External applications can be notified about the events triggered using various transport protocols. While the interface itself is provided by OpenSIPS core, each transport protocol below is implemented by a separate OpenSIPS module. Multiple transport modules can be loaded simultaneously in order to provide different ways of notifications. + +Available transport protocols are : + +* [event_datagram](../../modules/event_datagram/README.md) - sends Datagrams over UDP or UNIX sockets +* [event_flastore](../../modules/event_flatstore/README.md) - writes to plain text files +* [event_kafka](../../modules/event_kafka/README.md) - sends events via Apache Kafka broker +* [event_rabbitmq](../../modules/event_rabbitmq/README.md) - sends an AMQP message to a RabbitMQ server +* [event_stream](../../modules/event_stream/README.md) - sends a JSON-RPC command/notification over TCP +* [event_virtual](../../modules/event_virtual/README.md) - aggregates event backends for failover and balancing +* [event_xmlrpc](../../modules/event_xmlrpc/README.md) - sends a XML-RPC command over TCP + +An external application can subscribe to any exported event and can be notified using any loaded transport module/protocol. Separately, the core Event Interface can run an `event_route` with the same name as the raised event, such as `event_route[E_PIKE_BLOCKED]`, without loading a dedicated transport module. + +--- + +## Events Subscription + +You can subscribe for an event either at startup (using the [subscribe_event()](Script-CoreFunctions.md#subscribe_event) command in the script) or during runtime, using the [event_subscribe](Interface-CoreMI.md#event_subscribe) MI command. + +--- + +## Examples + +In order to configure a RabbbitMQ server to be notified when a custom event is triggered, first you have to subscribe it to the event, using the [subscribe_event()](Script-CoreFunctions.md#subscribe_event) command: + +```opensips + + startup_route { + subscribe_event("E_SCRIPT_CUSTOM_EVENT", "rabbitmq:127.0.0.1/opensips"); + } + +``` + +Then, in order to trigger the event from the script, call the [raise_event()](Script-CoreFunctions.md#raise_event) command when needed: + +```opensips + + .... + raise_event("E_SCRIPT_CUSTOM_EVENT"); # raises an event without any parameters + ... + +``` diff --git a/docs/manual/Interface-MI.md b/docs/manual/Interface-MI.md new file mode 100644 index 00000000000..9d6424ff3d1 --- /dev/null +++ b/docs/manual/Interface-MI.md @@ -0,0 +1,140 @@ +--- +title: "Management Interface" +description: "The Management Interface (or MI) is an OpenSIPS interface that allows external applications to trigger predefined commands inside OpenSIPS." +--- + +The **Management Interface** (or **MI**) is an OpenSIPS interface that allows external applications to trigger predefined commands inside OpenSIPS. + +## Overview + +Such commands typically allows an external app to : +* push data into OpenSIPS (like setting debug level, registering a contact, etc) +* fetch data from OpenSIPS (see registered users, see ongoing calls, get statistics, etc) +* trigger an internal action in OpenSIPS (reloading data, sending a message, etc) + +The **MI** commands are provided by the OpenSIPS core (see [full list](Interface-CoreMI.md)) and also by modules (check the commands provided by [each module](Modules.md)). + +--- + +## Protocols + +The protocols available in order to connect (from external apps) to the OpenSIPS **MI** are JSON-RPC over several transports and XML-RPC. While the interface itself (tailored around the JSON format) is provided by the OpenSIPS core, each actual transport protocol is provided by a separate OpenSIPS module. You can load multiple MI modules in order to use multiple MI transport protocols at the same time. + +The majority of the MI backend modules only provide the transport, while the command parsing and response formatting (as **JSON-RPC**) is done by the OpenSIPS core. The only exceptions are the *mi_html* and *mi_xmlrpc_ng* modules, which use a different format. + +The available MI modules are: + +### [mi_fifo](../../modules/mi_fifo/README.md) +Provides the FIFO transport layer for the Management Interface. + +### [mi_datagram](../../modules/mi_datagram/README.md) +Provides the UNIX and UDP socket transport layer for the Management Interface. + +### [mi_http](../../modules/mi_http/README.md) +Provides the HTTP transport layer for the Management Interface. + +### [mi_html](../../modules/mi_html/README.md) +Provides a minimal web user interface for the Management Interface. + +### [mi_xmlrpc_ng](../../modules/mi_xmlrpc_ng/README.md) +Implements an XML-RPC server that handles XML-RPC requests and generates XML-RPC responses. + +### [mi_script](../../modules/mi_script/README.md) +Runs Management Interface commands directly from the OpenSIPS script and returns their JSON results. + +All protocols do allow multiple applications (clients) to connect at the same time to the MI interface. + +--- + +## Examples + +A few examples of JSON-RPC calls for OpenSIPS: + +```bash + +# Request with no parameters: +{ + "jsonrpc": "2.0", + "method": "ps", + "id": 10 +} + +# Response: +{ + "jsonrpc": "2.0", + "result": { + "Processes": [{ + "ID": 0, + "PID": 9467, + "Type": "attendant" + }, { + "ID": 1, + "PID": 9468, + "Type": "HTTPD 127.0.0.1:8008" + }, { + "ID": 3, + "PID": 9470, + "Type": "time_keeper" + }, { + "ID": 4, + "PID": 9471, + "Type": "timer" + }, { + "ID": 5, + "PID": 9472, + "Type": "SIP receiver udp:127.0.0.1:5060 " + }, { + "ID": 7, + "PID": 9483, + "Type": "Timer handler" + }, ] + }, + "id": 10 +} + +# Request with positional parameters: +{ + "jsonrpc": "2.0", + "method": "log_level", + "params": [4, 9472], + "id": 11 +} + +# Request with named parameters: +{ + "jsonrpc": "2.0", + "method": "log_level", + "params": { + "level": 4, + "pid": 9472 + }, + "id": 11 +} + +# Request with an array type of parameter: +{ + "jsonrpc": "2.0", + "method": "get_statistics", + "params": { + "statistics": ["shmem:", "core:"] + }, + "id": 11 +} + +``` + +A simple example of interacting with OpenSIPS via MI interfaces is the **opensips-cli** utility - it uses FIFO to push MI commands into OpenSIPS: + +```bash + + opensips-cli -x mi ps + opensips-cli -x mi log_level 4 9472 + +``` + +Example of sending a JSON-RPC OpenSIPS MI command from the command-line, using *curl*: +```bash + +$ curl -X POST localhost:8888/mi -H 'Content-Type: application/json' -d '{"jsonrpc": "2.0", "id": "1", "method": "ps"}' + +``` diff --git a/docs/manual/Interface-Statistics.md b/docs/manual/Interface-Statistics.md new file mode 100644 index 00000000000..4e9f43aa5cd --- /dev/null +++ b/docs/manual/Interface-Statistics.md @@ -0,0 +1,70 @@ +--- +title: "Statistics Interface" +description: "The Statistics Interface is an OpenSIPS interface that provides access to various internal statistics of OpenSIPS. The statistic provide useful information a..." +--- + +The **Statistics Interface** is an OpenSIPS interface that provides access to various internal statistics of OpenSIPS. The statistic provide useful information about what is going on inside OpenSIPS - this can be used by external applications, for monitoring purposes, load evaluation, realtime integration with other services. The values of statistic variables are exclusively numerical. + +--- + +## Overview + +**OpenSIPS** typically provides two types of statistic variables: +* counter like - variables that keep counting things that happened in OpenSIPS, like received requests, processed dialogs, failed DB queries, etc +* computed values - variables that are calculated in realtime, like how much memory is used, the current load, active dialogs, active transactions, etc + +The statistic variables are not restart persistent, they all start with a 0 value (the counter like variables). The *counter like* statistics can also be reset (to 0 value) during OpenSIPS runtime. + +In OpenSIPS, the statistics variables are grouped in different sets, depending on their purposes or how is providing them. For example, the OpenSIPS core provides the **shmem**, **load**, **net**, etc groups, while each OpenSIPS module provides its own group (typically the group has the same name as the module). + +All available statistic variables are listed and documented : statistics provided [by OpenSIPS core](Interface-CoreStatistics.md) or by [OpenSIPS modules](Modules.md) (see the Statistics chapter for each module). + +--- + +## Usage + +To get access to the statistics you have to use the [MI interface](Interface-MI.md) which provides (directly from OpenSIPS core) several MI functions for: +\ +**Fetching the value** of a statistic variable, of an entire group of variables or of all variables. The MI [get_statistics](Interface-CoreMI.md) command can be used here: +```bash + + # get one statistic variable, by name + > opensipsctl fifo get_statistics rcv_requests + > core:rcv_requests = 3428 + > opensipsctl fifo get_statistics real_used_size + > shmem:real_used_size = 2951864 + + # get various statistic variables, by list of names + > opensipsctl fifo get_statistics rcv_requests inuse_transactions + > core:rcv_requests = 453 + > tm:inuse_transactions = 10 + + # get all stats from a group + > opensipsctl fifo get_statistics shmem: + > shmem:total_size = 33554432 + > shmem:used_size = 2897024 + > shmem:real_used_size = 2951864 + > shmem:max_used_size = 2952304 + > shmem:free_size = 30602568 + > shmem:fragments = 26 + + # get all stats from OpenSIPS + > opensipsctl fifo get_statistics all + >........... + +``` + + +**Reseting the value** of a statistic variable (to 0 value), but only if it is counter-type variable. + +> [!IMPORTANT] +> Reseting a computed-value statistic will be ignored and have no effect. + + The MI [reset_statistics](Interface-CoreMI.md) command can be used here: + +```bash + + # reset one statistic variable, by name + > opensipsctl fifo reset_statistics rcv_requests + +``` diff --git a/docs/manual/Interface-StatusReport.md b/docs/manual/Interface-StatusReport.md new file mode 100644 index 00000000000..6d06a1f2c1c --- /dev/null +++ b/docs/manual/Interface-StatusReport.md @@ -0,0 +1,67 @@ +--- +title: "Status/Report Interface" +description: "The Status/Report (or SR) is an OpenSIPS framework that allows different components of OpenSIPS (like modules, parts of the core) to publish their status (in..." +--- + +The **Status/Report** (or **SR**) is an OpenSIPS framework that allows different components of OpenSIPS (like modules, parts of the core) to publish their status (in terms of readiness) and reports (logs) relevant to their activities. + +This framework is intended to be used in operational activities, to check the readiness of OpenSIPS when starting up, to monitor its status at runtime and to trace back its operations via the logs/reports. + +## Overview + +The base element in the **Status/Report** framework is the *identifier* - an status and some reports may be attached to an identifier. All the identifiers do exist within a **Status/Report** group. So, a group is a set of identifiers - a module or a core may be such groups. For example the *drouting* module publishes the *drouting* group where each routing partition is an *identifier*. + +As there are cases where the group (the modules) do not need multiple identifiers, there is a default *main* identifier - such identifier may be referred only by the name of the group. + +The information attached to an identifier is: +* **status** as integer value, translating if the identifier is ready for operation or not; a strict negative value means not-ready, while a strict positive value means it is ready; a zero value is not accepted. +* **status details** is a optional text to the status, providing some human friendly (or details) information in regards to the current status. +* **reports** is a fix-size array (rather a queue discarding the oldest records) of logs produced by the identifier. Each report/log is produced with a timestamp also. + +I most of the cases, the status and reports of an identifier are internally produced by the OpenSIPS code - the **Status/Report** interface just gives you access to the status / report information from outside the code, for monitoring purposes. + +--- + +## Scripting functions + +The SR Interface provides a script function to check the readiness status of an identifier (or of an entire group), see the [sr_check_status( group, \[identifier\])](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) function. + +--- + +## MI functions + +The SR Interface provides multiple functions to check/list the status of one/multiple identifiers and to list their reports: +* [sr_get_status](https://docs.opensips.org/manual/3-6/interface-coremi#sr_get_status) +* [sr_list_status](https://docs.opensips.org/manual/3-6/interface-coremi#sr_list_status) +* [sr_list_reports](https://docs.opensips.org/manual/3-6/interface-coremi#sr_list_reports) +* [sr_list_identifiers](https://docs.opensips.org/manual/3-6/interface-coremi#sr_list_identifiers) + +--- + +## Events + +The SR framework raises an event each time the status of a Status/Report identifier changes. See the [E_CORE_SR_STATUS_CHANGED event](https://docs.opensips.org/manual/3-6/interface-coreevents#E_CORE_SR_STATUS_CHANGED) for more details. + +--- + +## Core identifiers + +The OpenSIPS core provides the **core** group, with a "main" (default) identifier. The available status are: +* STATE_NONE (-100) - OpenSIPS just started +* STATE_TERMINATING (-2) - OpenSIPS is shutdown sequence +* STATE_INITIALIZING (-1) - OpenSIPS in startup sequence +* STATE_RUNNING (1) - OpenSIPS fully up and running + +Also the **auto-scaling** group is exposed (if auto-scaling feature enabled), where each auto-scaling group is a Status/Report identifier. Each identifier gets reports on the forking or ripping of processes in that auto-scaling group. + +--- + +## Modules identifiers + +The OpenSIPS modules may or may not provide their own groups and identifiers. For this you need to check the module's documentation. + +--- + +## Scripting identifiers + +The [status_report](../../modules/status_report/README.md) allow the creation of custom SR identifiers from script level. Even more, it is possible to set the status or to publish a report from script for such custom identifiers. diff --git a/docs/manual/Modules.md b/docs/manual/Modules.md new file mode 100644 index 00000000000..e62a053cb68 --- /dev/null +++ b/docs/manual/Modules.md @@ -0,0 +1,249 @@ +--- +title: "Modules" +description: "" +--- + +## SIP related modules + +### SIP signaling modules +* [**B2B_ENTITIES**](../../modules/b2b_entities/README.md) - Back-to-Back User Agent Entities, 🟢 **stable** +* [**B2B_LOGIC**](../../modules/b2b_logic/README.md) - Back-to-Back User Agent Logic, 🟢 **stable** +* [**CALL CENTER**](../../modules/call_center/README.md) - Inbound call center system , 🟢 **stable** +* [**DIALOG**](../../modules/dialog/README.md) - Dialog support module , 🟢 **stable** +* [**NAT_TRAVERSAL**](../../modules/nat_traversal/README.md) - NAT traversal module , 🟢 **stable** +* [**NATHELPER**](../../modules/nathelper/README.md) - NAT traversal helper module , 🟢 **stable** +* [**OPTIONS**](../../modules/options/README.md) - OPTIONS server replier module , 🟢 **stable** +* [**REGISTRAR**](../../modules/registrar/README.md) - SIP Registrar implementation module , 🟢 **stable** +* [**SIGNALING**](../../modules/signaling/README.md) - SIP signaling module , 🟢 **stable** +* [**UAC_REGISTRANT**](../../modules/uac_registrant/README.md) - SIP Registrant implementation module , 🟢 **stable** +* [**TM**](../../modules/tm/README.md) - Transaction (stateful) module , 🟢 **stable** +* [**SL**](../../modules/sl/README.md) - Stateless replier module , 🟢 **stable** +* [**MEDIA_EXCHANGE**](../../modules/media_exchange/README.md) - Module to exchange SDP bodies between different SIP calls, 🟢 **stable** +* [**CALLOPS**](../../modules/callops/README.md) - Module to trigger different call operations on ongoing SIP calls, 🟢 **stable** +* [**B2B_SDP_DEMUX**](../../modules/b2b_sdp_demux/README.md) - Module to de-multiplex calls with multiple media streams, 🟢 **stable** +* [**MSRP_UA**](../../modules/msrp_ua/README.md) - MSRP User Agent module, 🟢 **stable** + +### SIP Routing modules +* [**CARRIERROUTE**](../../modules/carrierroute/README.md) - routing extension suitable for carriers , 🟢 **stable** +* [**CPL_C**](../../modules/cpl_c/README.md) - CPL interpreter module , 🟢 **stable** +* [**DISPATCHER**](../../modules/dispatcher/README.md) - Dispatcher module , 🟢 **stable** +* [**DROUTING**](../../modules/drouting/README.md) - Dynamic Routing / LCR , 🟢 **stable** +* [**QROUTING**](../../modules/qrouting/README.md) - Quality-based Routing , 🟢 **stable** +* [**EMERGENCY**](../../modules/emergency/README.md) - Emergency module, 🟢 **stable** +* [**ENUM**](../../modules/enum/README.md) - ENUM lookup module , 🟢 **stable** +* [**JABBER**](../../modules/jabber/README.md) - JABBER IM and PRESENCE interconnection module , beta +* [**IMC**](../../modules/imc/README.md) - Instant Messaging Conferencing module , 🟢 **stable** +* [**LOAD_BALANCER**](../../modules/load_balancer/README.md) - Load Balancer (for calls) module, 🟢 **stable** +* [**MID_REGISTRAR**](../../modules/mid_registrar/README.md) - SIP registration front-end with traffic throttling , 🟢 **stable** +* [**MSILO**](../../modules/msilo/README.md) - SIP message silo module , 🟢 **stable** +* [**MSRP_GATEWAY**](../../modules/msrp_gateway/README.md) - SIP MESSAGE / MSRP gateway module, 🟢 **stable** +* [**RR**](../../modules/rr/README.md) - Record-Route and Route module , 🟢 **stable** +* [**SCRIPT_HELPER**](../../modules/script_helper/README.md) - Embedded SIP routing logic and dialog management, 🟢 **stable** +* [**OSP**](../../modules/osp/README.md) - OSP peering module , 🟢 **stable** + +### SIP messaging operations +* [**COMPRESSION**](../../modules/compression/README.md) - Message compression and compaction, 🟢 **stable** +* [**DIVERSION**](../../modules/diversion/README.md) - Diversion header insertion module , 🟢 **stable** +* [**IDENTITY**](../../modules/identity/README.md) - SIP Identity implementation, 🟢 **stable** +* [**MAXFWD**](../../modules/maxfwd/README.md) - Max-Forward processor module , 🟢 **stable** +* [**MANGLER**](../../modules/mangler/README.md) - SIP mangler module , 🟢 **stable** +* [**PATH**](../../modules/path/README.md) - Path support for SIP frontending , 🟢 **stable** +* [**SIP_I**](../../modules/sip_i/README.md) - ISUP manipulation module , 🟢 **stable** +* [**SIPMSGOPS**](../../modules/sipmsgops/README.md) - SIP operations module , 🟢 **stable** +* [**STIR_SHAKEN**](../../modules/stir_shaken/README.md) - STIR/SHAKEN support , 🟢 **stable** +* [**TOPOLOGY_HIDING**](../../modules/topology_hiding/README.md) - Provides Topology Hiding capabilities , 🟢 **stable** +* [**UAC**](../../modules/uac/README.md) - UAC functionalies (FROM mangling and UAC auth) , 🟢 **stable** +* [**UAC_AUTH**](../../modules/uac_auth/README.md) - UAC Authentication functionality, 🟢 **stable** +* [**UAC_REDIRECT**](../../modules/uac_redirect/README.md) - UAC redirection functionality , 🟢 **stable** +* [**SST**](../../modules/sst/README.md) - SIP Session Timer support , 🟢 **stable** + +### SIP Presence Modules +* [**PRESENCE**](../../modules/presence/README.md) - Presence server module - common API , 🟢 **stable** +* [**PRESENCE_CALLINFO**](../../modules/presence_callinfo/README.md) - Extension to Presence server for Call-Info, 🟢 **stable** +* [**PRESENCE_DIALOGINFO**](../../modules/presence_dialoginfo/README.md) - Extension to Presence server for Dialog Info, 🟢 **stable** +* [**PRESENCE_DFKS**](../../modules/presence_dfks/README.md) - Extension to Presence server for Device Feature Key Synchronization, 🟢 **stable** +* [**PRESENCE_MWI**](../../modules/presence_mwi/README.md) - Extension to Presence server for Message Waiting Indication , 🟢 **stable** +* [**PRESENCE_REGINFO**](../../modules/presence_reginfo/README.md) - Extension to Presence server for "reg"-events according to RFC 3680 , 🟢 **stable** +* [**PRESENCE_XCAPDIFF**](../../modules/presence_xcapdiff/README.md) - Extension to Presence server for XCAP-DIFF event, 🟢 **stable** +* [**PRESENCE_XML**](../../modules/presence_xml/README.md) - Presence server module - presence & watcher info and XCAP , 🟢 **stable** +* [**PUA**](../../modules/pua/README.md) - Common API for presence user agent client , 🟢 **stable** +* [**PUA_BLA**](../../modules/pua_bla/README.md) - BLA extension for PUA , 🟢 **stable** +* [**PUA_DIALOGINFO**](../../modules/pua_dialoginfo/README.md) - Dialog-Info extension for PUA , 🟢 **stable** +* [**PUA_MI**](../../modules/pua_mi/README.md) - MI extension for PUA , 🟢 **stable** +* [**PUA_REGINFO**](../../modules/pua_reginfo/README.md) - Publisher for "reg"-events according to RFC 3680 , 🟢 **stable** +* [**PUA_USRLOC**](../../modules/pua_usrloc/README.md) - USRLOC extension for PUA , 🟢 **stable** +* [**PUA_XMPP**](../../modules/pua_xmpp/README.md) - XMPP extension for PUA (SIMPLE-XMPP presence gateway) , 🟢 **stable** +* [**B2B_SCA**](../../modules/b2b_sca/README.md) - Back-to-Back Shared Call Appearance, 🟢 **stable** +* [**RLS**](../../modules/rls/README.md) - Resource List Server implementation , 🟢 **stable** +* [**XCAP**](../../modules/xcap/README.md) - XCAP API provider , 🟢 **stable** +* [**XCAP_CLIENT**](../../modules/xcap_client/README.md) - XCAP client implementation , 🟢 **stable** + +--- + +## Scripting modules + +### Script helper modules +* [**JSON**](../../modules/json/README.md) - Manipulate JSON objects in OpenSIPS script, 🟢 **stable** +* [**XML**](../../modules/xml/README.md) - Manipulate XML documents in OpenSIPS script, 🟢 **stable** +* [**CFGUTILS**](../../modules/cfgutils/README.md) - Various utility functions, 🟢 **stable** +* [**CONFIG**](../../modules/config/README.md) - DB backed runtime configuration, alpha / 🔵 **NEW** +* [**EXEC**](../../modules/exec/README.md) - External exec module , 🟢 **stable** +* [**TEXTOPS**](../../modules/textops/README.md) - Text operations module, 🟢 **stable** +* **AVPOPS** - renamed, see [SQLops module](../../modules/sqlops/README.md) +* [**SQLOPS**](../../modules/sqlops/README.md) - SQL DB operations module 🟢 **stable** +* [**REGEX**](../../modules/regex/README.md) - RegExp via PCRE library, 🟢 **stable** +* [**MATHOPS**](../../modules/mathops/README.md) - Floating point and rounding operations, 🟢 **stable** +* [**BENCHMARK**](../../modules/benchmark/README.md) - Script file benchmarking, 🟢 **stable** +* [**CARRIERROUTE**](../../modules/carrierroute/README.md) - routing extension suitable for carriers , 🟢 **stable** +* [**GFLAGS**](../../modules/gflags/README.md) - Global shared flags module, 🟢 **stable** +* [**PYTHON**](../../modules/python/README.md) - Python scripting support, 🟢 **stable** +* [**LUA**](../../modules/lua/README.md) - Call LUA scripts from OpenSIPS cfg, 🟢 **stable** +* [**PERL**](../../modules/perl/README.md) - embed execution of Perl function , 🟢 **stable** +* [**MMGEOIP**](../../modules/mmgeoip/README.md) - MaxMind GeoIP module, 🟢 **stable** +* [**UUID**](../../modules/uuid/README.md) - UUID generation, 🟢 **stable** +* [**MQUEUE**](../../modules/mqueue/README.md) - Message queue system inter-process communication using the config file, 🟢 **stable** + +### Auth modules +* [**AUTH_AAA**](../../modules/auth_aaa/README.md) - AAA-backend authentication module, 🟢 **stable** +* [**AUTH**](../../modules/auth/README.md) - Authentication Framework module, 🟢 **stable** +* [**AUTH_DB**](../../modules/auth_db/README.md) -Database-backend authentication module, 🟢 **stable** +* [**AUTH_JWT**](../../modules/auth_jwt/README.md) -Authentication over JSON Web Tokens, 🟢 **stable** +* [**AUTH_AKA**](../../modules/auth_aka/README.md) - Authentication using RFC 3310 AKA mechanism, beta +* [**AKA_AV_DIAMETER**](../../modules/aka_av_diameter/README.md) - Fetches RFC 3310 AKA AVs using Cx/Dx Diameter interface, beta +* [**PERMISSIONS**](../../modules/permissions/README.md) - Permissions control module , 🟢 **stable** + +### Accounting & Billing modules +* [**ACC**](../../modules/acc/README.md) - Accounting module, 🟢 **stable** +* [**CALL CONTROL**](../../modules/call_control/README.md) - PrePaid application module , 🟢 **stable** +* [**CGRATES**](../../modules/cgrates/README.md) - Connector to the CGRateS billing engine, 🟢 **stable** + +### Dialplan Modules +* [**ALIAS_DB**](../../modules/alias_db/README.md) - Database SIP aliases module, 🟢 **stable** +* [**DIALPLAN**](../../modules/dialplan/README.md) - Dialplan management , 🟢 **stable** +* [**DOMAIN**](../../modules/domain/README.md) - Multi-domain support module , 🟢 **stable** +* [**DOMAINPOLICY**](../../modules/domainpolicy/README.md) - Policies to connect federations , 🟢 **stable** +* [**GROUP**](../../modules/group/README.md) - User-groups module with DB-backend , 🟢 **stable** +* [**USERBLACKLIST**](../../modules/userblacklist/README.md) - User black/white listing , 🟢 **stable** +* [**SPEEDDIAL**](../../modules/speeddial/README.md) - Per-user speed-dial controller module , 🟢 **stable** +* [**PEERING**](../../modules/peering/README.md) - Radius peering module , 🟢 **stable** + +### Data caching +* [**DNS_CACHE**](../../modules/dns_cache/README.md) - Module for caching DNS records that can be used with any Key-Value back-end , 🟢 **stable** +* [**RATE_CACHER**](../../modules/rate_cacher/README.md) - Cache, Query, Reload or Update rates via MI, 🟢 **stable** +* [**SQL_CACHER**](../../modules/sql_cacher/README.md) - SQL Caching module, 🟢 **stable** +* [**TRIE**](../../modules/trie/README.md) - Fast, low memory cache with trie search for number, alpha / 🔵 **NEW** +* [**USRLOC**](../../modules/usrloc/README.md) - User location implementation module , 🟢 **stable** + +### Traffic shaping module +* [**PIKE**](../../modules/pike/README.md) - Flood detector module , 🟢 **stable** +* [**QOS**](../../modules/qos/README.md) - QOS (RTP) module , 🟢 **stable** +* [**RATELIMIT**](../../modules/ratelimit/README.md) - SIP traffic shaping module , 🟢 **stable** +* [**FRAUD_DETECTION**](../../modules/fraud_detection/README.md) - Detects fraudulent calls, 🟢 **stable** + +--- + +## Database modules + +### SQL modules +* [**DB_BERKELEY**](../../modules/db_berkeley/README.md) - Berkeley DB driver for DB API , 🟢 **stable** +* [**DB_CACHEDB**](../../modules/db_cachedb/README.md) - SQL to CacheDB translator , 🟢 **stable** +* [**DB_FLATSTORE**](../../modules/db_flatstore/README.md) - Fast writing-only text-backend for database module , 🟢 **stable** +* [**DB_HTTP**](../../modules/db_http/README.md) - HTTP-backend for DB API , 🟢 **stable** +* [**DB_MYSQL**](../../modules/db_mysql/README.md) - MYSQL-backend for database API module , 🟢 **stable** +* [**DB_ORACLE**](../../modules/db_oracle/README.md) - ORACLE-backend for database API module , 🟢 **stable** +* [**DB_PERLVDB**](../../modules/db_perlvdb/README.md) - Perl Virtual Database engine , 🟢 **stable** +* [**DB_POSTGRES**](../../modules/db_postgres/README.md) - POSTGRES-backend for database API module , 🟢 **stable** +* [**DB_SQLITE**](../../modules/db_sqlite/README.md) - SQLITE3-backend for database API module , 🟢 **stable** +* [**DB_TEXT**](../../modules/db_text/README.md) - Text-backend for database API module , 🟢 **stable** +* [**DB_UNIXODBC**](../../modules/db_unixodbc/README.md) - unixODBC driver module , 🟢 **stable** +* [**DB_VIRTUAL**](../../modules/db_virtual/README.md) - Middle-layer DB mixer, 🟢 **stable** + +### noSQL modules +* [**CACHEDB_CASSANDRA**](../../modules/cachedb_cassandra/README.md) - Cassandra Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_COUCHBASE**](../../modules/cachedb_couchbase/README.md) - CouchBase Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_DYNAMODB**](../../modules/cachedb_dynamodb/README.md) - AWS DynamoDB Implementation of CacheDB, alpha / 🔵 **NEW** +* [**CACHEDB_LOCAL**](../../modules/cachedb_local/README.md) - Local Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_MEMCACHED**](../../modules/cachedb_memcached/README.md) - Memcached Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_MONGODB**](../../modules/cachedb_mongodb/README.md) - MongoDB Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_REDIS**](../../modules/cachedb_redis/README.md) - Redis Implementation of CacheDB, 🟢 **stable** +* [**CACHEDB_SQL**](../../modules/cachedb_sql/README.md) - SQL-based Implementation of CacheDB, 🟢 **stable** + +--- + +## External Integration modules + +### OpenSIPS API modules +* [**EVENT_DATAGRAM**](../../modules/event_datagram/README.md) - Publish JSON-RPC notifications using UDP, 🟢 **stable** +* [**EVENT_FLATSTORE**](../../modules/event_flatstore/README.md) - Text/File backend for events, 🟢 **stable** +* [**EVENT_KAFKA**](../../modules/event_kafka/README.md) - Publish JSON-RPC notifications/generic messages to Apache Kafka , 🟢 **stable** +* [**EVENT_ROUTE**](../../modules/event_route/README.md) - Route triggering based on events, 🟢 **stable** +* [**EVENT_ROUTING**](../../modules/event_routing/README.md) - Event-based routing, 🟢 **stable** +* [**EVENT_RABBITMQ**](../../modules/event_rabbitmq/README.md) - Publish JSON-RPC notifications using AMQP over TCP , 🟢 **stable** +* [**EVENT_STREAM**](../../modules/event_stream/README.md) - Publish JSON-RPC notifications using TCP, 🟢 **stable** +* [**EVENT_SQS**](../../modules/event_sqs/README.md) - An implementation of an Amazon SQS producer, alpha / 🔵 **NEW** +* [**EVENT_VIRTUAL**](../../modules/event_virtual/README.md) - Aggregator of event backends (failover & balancing), 🟢 **stable** +* [**EVENT_XMLRPC**](../../modules/event_xmlrpc/README.md) - Event XMLRPC client module , 🟢 **stable** +* [**MI_DATAGRAM**](../../modules/mi_datagram/README.md) - DATAGRAM (unix and network) support for Management Interface , 🟢 **stable** +* [**MI_FIFO**](../../modules/mi_fifo/README.md) - FIFO support for Management Interface , 🟢 **stable** +* [**MI_HTML**](../../modules/mi_html/README.md) - Minimal web GUI for Management Interface , 🟢 **stable** +* [**MI_HTTP**](../../modules/mi_http/README.md) - HTTP support for Management Interface , 🟢 **stable** +* [**MI_SCRIPT**](../../modules/mi_script/README.md) - support for running Management Interface commands in script , 🟢 **stable** +* [**MI_XMLRPC_NG**](../../modules/mi_xmlrpc_ng/README.md) - XMLRPC support for Management Interface , 🟢 **stable** +* [**HTTPD**](../../modules/httpd/README.md) - Embedded HTTP server , 🟢 **stable** +* [**PI_HTTP**](../../modules/pi_http/README.md) - Provisioning Interface module , 🟢 **stable** +* [**RABBITMQ**](../../modules/rabbitmq/README.md) - Connector to a RabbitMQ message broker, 🟢 **stable** +* [**RABBITMQ_CONSUMER**](../../modules/rabbitmq_consumer/README.md) - Connect to RabbitMQ and receive events, 🟢 **stable** +* [**STATISTICS**](../../modules/statistics/README.md) - Script statistics support , 🟢 **stable** +* [**STATUS_REPORT**](../../modules/status_report/README.md) - Script Status/Report identifiers support , 🟢 **stable** + +### Media Relays +* [**MEDIAPROXY**](../../modules/mediaproxy/README.md) - NAT traversal module , 🟢 **stable** +* [**MSRP_RELAY**](../../modules/msrp_relay/README.md) - Implementation of a Relay for the MSRP protocol , 🟢 **stable** +* [**RTPENGINE**](../../modules/rtpengine/README.md) - Connector to RTPengine external RTP relay , 🟢 **stable** +* [**RTPPROXY**](../../modules/rtpproxy/README.md) - Connector to RTPproxy external RTP relay, 🟢 **stable** +* [**RTP.IO**](../../modules/rtp.io/README.md) - Builtin RTP relay module, alpha / 🔵 **NEW** +* [**RTP_RELAY**](../../modules/rtp_relay/README.md) - Interface for different RTP relay engines, 🟢 **stable** + +### External integration (non-SIP protocols) +* [**AAA_DIAMETER**](../../modules/aaa_diameter/README.md) - Diameter backend for the AAA API, 🟢 **stable** +* [**AAA_RADIUS**](../../modules/aaa_radius/README.md) - RADIUS backend for the AAA API, 🟢 **stable** +* [**FREESWITCH**](../../modules/freeswitch/README.md) - FreeSWITCH ESL connection manager, 🟢 **stable** +* [**FREESWITCH_SCRIPTING**](../../modules/freeswitch_scripting/README.md) - FreeSWITCH events & commands at OpenSIPS script level, 🟢 **stable** +* [**H350**](../../modules/h350/README.md) - H350 implementation , 🟢 **stable** +* [**HTTP2D**](../../modules/http2d/README.md) - Programmable HTTP/2 Server, beta +* [**JANUS**](../../modules/janus/README.md) - WEB Socket connector to Janus (for running commands), alpha / 🔵 **NEW** +* [**JSONRPC**](../../modules/jsonrpc/README.md) - Execute JSON-RPC commands, 🟢 **stable** +* [**LAUNCH_DARKLY**](../../modules/launch_darkly/README.md) - Launch Darkly integration, beta +* [**LDAP**](../../modules/ldap/README.md) - LDAP connector , 🟢 **stable** +* [**PROMETHEUS**](../../modules/prometheus/README.md) - export statistics to a [Prometheus](http://prometheus.io/) server, 🟢 **stable** +* [**REST_CLIENT**](../../modules/rest_client/README.md) - Implementation of an HTTP client , 🟢 **stable** +* [**SEAS**](../../modules/seas/README.md) - Sip Express Application Server (interface module) , 🟢 **stable** +* [**SIPCAPTURE**](../../modules/sipcapture/README.md) - SipCapture module , 🟢 **stable** +* [**SIPREC**](../../modules/siprec/README.md) - SIP Recording module , 🟢 **stable** +* [**TRACER**](../../modules/tracer/README.md) - Collects SIP, logs, DNS or REST queries and ships them to various backends , 🟢 **stable** +* [**SNGTC**](../../modules/sngtc/README.md) - Voice Transcoding in OpenSIPS using Sangoma hardware , 🟢 **stable** +* [**SNMPStats**](../../modules/snmpstats/README.md) - SNMP interface for statistics module , 🟢 **stable** +* [**STUN**](../../modules/stun/README.md) - Built-in STUN server , 🟢 **stable** - +* [**XMPP**](../../modules/xmpp/README.md) - SIP-to-XMPP Gateway (SIP to Jabber/Google Talk) , 🟢 **stable** + +--- + +## OpenSIPS protocols and infrastructure +* [**CLUSTERER**](../../modules/clusterer/README.md) - Define and configure an OpenSIPS cluster, 🟢 **stable** +* [**TLS_MGM**](../../modules/tls_mgm/README.md) - TLS management module , 🟢 **stable** +* [**TLS_OPENSSL**](../../modules/tls_openssl/README.md) - TLS operations implemented using the openSSL library , 🟢 **stable** +* [**TLS_WOLFSSL**](../../modules/tls_wolfssl/README.md) - TLS operations implemented using the wolfSSL library , 🟢 **stable** +* [**TCP_MGM**](../../modules/tcp_mgm/README.md) - TCP connections management module , 🟢 **stable** +* [**PROTO_BIN**](../../modules/proto_bin/README.md) - Binary INterface protocol module - implements inter-OPENSIPS communication , 🟢 **stable** +* [**PROTO_BINS**](../../modules/proto_bins/README.md) - Binary INterface over TLS protocol module - implements Secure inter-OPENSIPS communication , 🟢 **stable** +* [**PROTO_HEP**](../../modules/proto_hep/README.md) - HEP protocol module - implements HEP transport for SIP , 🟢 **stable** +* [**PROTO_IPSEC**](../../modules/proto_ipsec/README.md) - implements IMS IPSec protocol according to TS 33.203 specs, beta +* [**PROTO_MSRP**](../../modules/proto_msrp/README.md) - implements MSRP protocol stack, 🟢 **stable** +* [**PROTO_SCTP**](../../modules/proto_sctp/README.md) - SCTP protocol module - implements SCTP transport for SIP , 🟢 **stable** +* [**PROTO_TCP**](../../modules/proto_tcp/README.md) - TCP protocol module - implements TCP-plain transport for SIP , 🟢 **stable** +* [**PROTO_TLS**](../../modules/proto_tls/README.md) - TLS protocol module - implements TLS transport for SIP , 🟢 **stable** +* [**PROTO_UDP**](../../modules/proto_udp/README.md) - UDP protocol module - implements UDP-plain transport for SIP , 🟢 **stable** +* [**PROTO_WS**](../../modules/proto_ws/README.md) - WebSocket protocol module - implements WS transport for SIP , 🟢 **stable** +* [**PROTO_WSS**](../../modules/proto_wss/README.md) - WebSocket Secure protocol module - implements WSS transport for SIP , 🟢 **stable** +* [**PROTO_SMPP**](../../modules/proto_smpp/README.md) - SMPP (Short Message Peer-to-Peer) protocol module - implements transport for SMPP messages, 🟢 **stable** +* [**SOCKETS_MGM**](../../modules/sockets_mgm/README.md) - Dynamic SIP Sockets Management at runtime, alpha / 🔵 **NEW** diff --git a/docs/manual/README.md b/docs/manual/README.md new file mode 100644 index 00000000000..c234147834b --- /dev/null +++ b/docs/manual/README.md @@ -0,0 +1,38 @@ +--- +title: "Manual 3.6" +description: "" +--- + +* **Installation** + * [Download OpenSIPS](Install-Download.md) + * [Compile and Install OpenSIPS](Install-CompileAndInstall.md) + * [Database Deployment](Install-DBDeployment.md) + * [Database schema](Install-DBSchema.md) +* **Configuring** + * [Config file](Configure-File.md) + * [Generating opensips.cfg files](Generating-Configs.md) + * [Templating opensips.cfg files](Templating-Config-Files.md) +* **OpenSIPS scripting** + * [Script syntax](Script-Syntax.md) + * [Core parameters](Script-CoreParameters.md) + * [Types of routes](Script-Routes.md) + * [Script operators](Script-Operators.md) + * [Script statements](Script-Statements.md) + * [Core functions](Script-CoreFunctions.md) + * [Core variables](Script-CoreVar.md) + * [Scripting flags](Script-Flags.md) + * [Transformations](Script-Tran.md) + * [Asynchronous statements](Script-Async.md) + * [Modules documentation](Modules.md) + * [Function Index](Function-Index.md) +* **OpenSIPS Interfaces** + * [MI interface](Interface-MI.md) + * [Core MI commands](Interface-CoreMI.md) + * [Event Interface](Interface-Events.md) + * [Core Events](Interface-CoreEvents.md) + * [Statistics Interface](Interface-Statistics.md) + * [Core Statistics](Interface-CoreStatistics.md) + * [Status/Report Interface](Interface-StatusReport.md) + * [Binary Internal Interface](Interface-Binary.md) +* **OpenSIPS Testing** + * [Conformance Tests](Conformance-Tests.md) diff --git a/docs/manual/Script-Async.md b/docs/manual/Script-Async.md new file mode 100644 index 00000000000..e72dfb27706 --- /dev/null +++ b/docs/manual/Script-Async.md @@ -0,0 +1,190 @@ +--- +title: "Asynchronous Statements" +description: "Asynchronous statements are one of the key features of OpenSIPS. One of the main reasons to use them is that they allow the performance of the OpenSIPS s..." +--- + +## Description + +The ability to run various script functions in an asynchronous way is a key performance feature of OpenSIPS. This async handling allows the OpenSIPS script performance to scale with a high number of requests per second even when doing blocking, time consuming I/O operations such as DB queries, exec commands or HTTP queries. + +When it comes to scaling, the usage of the asynchronous *suspend-resume* logic instead of forking a large number of processes, has the advantage of optimizing the usage of system resources. By requiring less processes to complete the same amount of work in the same amount of time, process context switching is minimized and overall CPU usage is improved. Less processes will also eat up less system memory. + +## async() statement + +The **async()** statement of the OpenSIPS script can be used in situations where the script writer both needs to perform blocking I/O and also depends on the result of this operation. Some example scenarios: + +* fetch SIP authentication data from a database +* perform an HTTP/REST query and act upon its result +* pause script execution for X seconds +* execute an external script and use its result + +Not all the script functions may be executed in combination with the **async()** statement - each OpenSIPS module exposes a dedicated set of script functions to be used in async mode. For this, check the [module's documentation](Modules.md). + +### Requirements + +The **async()** statement depends on the transaction module ([**TM**](../../modules/tm/README.md)) - it must be loaded. The SIP transaction will be automatically and transparently created when an async operation is started, if necessary. This transaction contains all the necessary information to suspend script execution (e.g. it stores the updated SIP message, along with all `$avp` variables). + +### Script syntax and usage + +Usage is straightforward: if your blocking function supports asynchronous mode (read the module documentation for this), then you can just throw it in the following function call: +```opensips + +async(blocking_function(...), resume_route [,timeout]); + +``` +*Note that resume_route must be a **[simple route](Script-Routes.md#route)***. + + +Because the **async()** statement is *serial with script execution* (see below), the script will be immediately halted when calling it, so any code placed after the async() call will be ignored! The current OpenSIPS worker will launch the asynchronous operation, after which it will continue to process other pending tasks (queued SIP messages, timer jobs or possibly other async operations!). As soon as all data is available, it will run the `resume_route` - thus resuming script execution with a minimum of idle time. + +The return code of the function executed in async mode is available in the very beginning of the `resume_route` in the `$rc` or `$retcode` variable. Also, all output parameters (variables in function parameters used to carry output values) will be available in `resume_route`. + +The optional 'timeout' parameter is to control for how long the script should wait for the blocking function to complete (independently from its implementation). If the blocking I/O is not completed before the given timeout, the async layer will force the function to complete (with timeout) its I/O and to resume the script. + + +```opensips + +route +{ + /* preparation code */ + ... + async( sql_query("SELECT credit FROM users WHERE uid='$avp(uid)'", "$avp(credit)"), resume_credit); + /* script execution is paused right away! */ +} + +route [resume_credit] +{ + if ($rc < 0) { + xlog("error $rc in avp_db_query()\n"); + exit; + } + + xlog("Credit of user $avp(uid) is $avp(credit)\n"); + ... + t_relay(); +} + +``` + + +> [!IMPORTANT] +> Not all variables are preserved after an **async()** execution. Only some are inherited in the `resume_route`: +> +> * **all `$avp` variables** +> * **all changes in current SIP message** + + +## launch() statement + +The **launch()** statement of the OpenSIPS script can be used in situations where the script writer needs to perform blocking I/O, but does not depend on the result of this operation in order to continue the current SIP routing decision flow. Some example scenarios: + +* execute an external push notification trigger +* push data into a custom database (e.g. call statistics, CDRs, etc.) +* notify an HTTP service of the occurrence of an event (e.g. SIP traffic pattern, fraud detection, etc.) + +Basically, the **launch()** statement acts as a *parallel asynchronous operation* - the I/O operation is only launched from the script, but its execution may happen in parallel in a totally different OpenSIPS process/worker. + +The **launch()** statement comes with no additional module dependencies, being provided by the OpenSIPS core. + +### Script syntax and usage + +Similarly to the **async()** statement, if your blocking function supports asynchronous mode (read the [module's documentation](Modules.md) for this), then you can just throw it in the following function calls: +```opensips + +launch(blocking_function(...)); +or +launch(blocking_function(...), report_route); +route[report_route] {} +or +launch(blocking_function(...), report_route, "Something with $var(xx) to be passed to report route"); +route[report_route] { + xlog("received as input the <$param(1)> string\n"); +} + +``` +*Note that report_route must be a **[simple route](Script-Routes.md#route)***. + + +The **launch()** statement is both asynchronous and parallel with the script execution that follows it (see below). Note how the `report_route` can be omitted, as script execution does not depend on it. This route may be triggered at any of the following points in time: + +* right before the next code line following the **launch()** call +* during the routing of the current SIP message +* after the routing of the current SIP message + + +The return code of the function executed in async mode is available in the very beginning of the `report_route` in the `$rc` or `$retcode` variable. Also, only the output parameters (variables in function parameters used to carry output values) will be available inside this route. + + +```opensips + +route +{ + /* preparation code */ + ... + + # send a push notification asynchronously, in parallel + launch(exec("/usr/local/bin/send-google-pn.py"), pn_counter); + t_relay(); +} + +route [pn_counter] +{ + if ($rc < 0) { + xlog("error $rc in pn script!\n"); + update_stat("pn-failure", "1"); + exit; + } + + update_stat("pn-success", "1"); +} + +``` + +> [!IMPORTANT] +> The only data available after a **launch()** execution in the `report_route` is: +> +> * output variables set by the async function +> * the text parameter passed to the **launch()** statement + + +## Limitations + +### Async Engine Compatibility + +The async engine is heavily dependent on non-blocking I/O features exposed by the underlying libraries -- a blocking I/O operation, such as an HTTP or an SQL query can only be made asynchronous if the library additionally provides both: + +* a non-blocking equivalent of the same, originally blocking function +* after the non-blocking equivalent function is launched, the library must also provide a mechanism to extract a valid Linux file descriptor corresponding to the data transfer operation that has just been launched. The OpenSIPS async engine will poll on this fd, and will trigger internal state updates each time new data is available. When the blocking operation is finished, the `resume_route` gets called, and the async operation is finalized. + + +### TCP Connect Issues + +Although they provide async functionality, some libraries only do this for the "transfer" part of the I/O operation, and NOT the initial TCP connect. Consequently, on some corner-case scenarios (e.g. the TCP connect hangs due to an unresponsive server, an in-between firewall which drops packets instead of rejecting them, etc.) the async operation may actually block! + + +Examples of modules which are affected by this limitation: + +* rest_client - although it reuses TCP connections on further requests, libcurl will block until a TCP connection is established from a given OpenSIPS worker. Should these TCP connects ever hang, so will the corresponding OpenSIPS worker. + +* db_mysql - similar to rest_client: although it reuses DB connections heavily, establishing each connection is a blocking operation, and cannot be made async due to the nature of the library. + +**Mitigation**: depending on your specific setup, you may be severely impacted by these blocking TCP connects or hardly at all. For the former case, we suggest forking external processes responsible for your blocking operations, and invoking them asynchronously, using constructs such as: + +```opensips + async(exec("curl my_host", $var(response_body)), resume_route); +``` + +or + +```opensips + async(exec("mysql-query 'SELECT * FROM subscriber...'", $var(result_row)), resume_route); +``` + +### Allowed Routes + +Since the **async** operations are tightly coupled with the transactional engine, they can only be performed in routes where a SIP transaction is present and is awaiting completion: + +* request_route +* onreply_route + +On the other hand, the **launch** statement should work from **any route**, as it is not dependent on the underlying SIP transaction. diff --git a/docs/manual/Script-CoreFunctions.md b/docs/manual/Script-CoreFunctions.md new file mode 100644 index 00000000000..94cb9a74bb7 --- /dev/null +++ b/docs/manual/Script-CoreFunctions.md @@ -0,0 +1,1136 @@ +--- +title: "Core functions" +description: "This section lists the all the functions exported by OpenSIPS core for script usage (to be used in opensips.cfg)" +--- + +This section lists the all the functions exported by **OpenSIPS** core for script usage (to be used in opensips.cfg) + +## add_local_rport() + +Add 'rport' parameter to the Via header generated by server (see RFC3581 for its meaning). It affects only the current processed request. + +Example of usage: + +```opensips +add_local_rport(); +``` + +## assert(statement, [description]) + +Only works if [enable_asserts](https://docs.opensips.org/manual/3-6/script-coreparameters#memlog) is set to *true*. If the given expression evaluates to *false*, script execution is stopped and the [error_route](https://docs.opensips.org/manual/3-6/script-routes#error_route) is executed. If [abort_on_assert](https://docs.opensips.org/manual/3-6/script-coreparameters#dns_try_ipv6) is enabled, OpenSIPS will also shutdown. + +Example of usage: +```opensips + + $var(i) = "1"; + $var(i) += "11"; + assert($var(i) == "111"); + + $var(i) = 1; + $var(i) += 11; + assert($var(i) == 12); + + assert($ua != "friendly-scanner", "Forbidden UA: \"friendly-scanner\""); + +``` + +## append_branch_old([uri], [qvalue]) + +> [!WARNING] +> TO BECOME OBSOLETE, replaced by [append_msg_branch()](#append_msg_branch). + +Adds a new message branch, so it extends the destination set by a new entry. The difference is that current URI is taken as new entry. + +Without parameter, the function copies the current URI into a new branch. Thus, leaving the main branch (the URI) for further manipulation. + +With a parameter, the function copies the URI in the parameter into a new branch. Thus, the current URI is not manipulated. + +Note that it's not possible to append a new branch in "on_failure_route" block if a 6XX response has been previously received (it would be against RFC 3261). + +Parameters: +* *uri* (string, optional) +* *qvalue* (string, optional) + +Example of usage: +```opensips + + # if someone calls B, the call should be forwarded to C too. + # + if ($rm=="INVITE" && $ru=~"sip:B@xx.xxx.xx ") + { + # copy the current branch (branches[0]) into + # a new branch (branches[1]) + append_branch_old(); + # all URI manipulation functions work on branches[0] + # thus, URI manipulation does not touch the + # appended branch (branches[1]) + seturi("sip:C@domain"); + + # now: branch 0 = C@domain + # branch 1 = B@xx.xx.xx.xx + + # and if you need a third destination ... + + # copy the current branch (branches[0]) into + # a new branch (branches[2]) + append_branch_old(); + + # all URI manipulation functions work on branches[0] + # thus, URI manipulation does not touch the + # appended branch (branches[1-2]) + seturi("sip:D@domain"); + + # now: branch 0 = D@domain + # branch 1 = B@xx.xx.xx.xx + # branch 2 = C@domain + + t_relay(); + exit; + }; + + # You could also use append_branch_old("sip:C@domain") which adds a branch with the new URI: + + + if ($rm == "INVITE" && $ru =~ "sip:B@xx.xxx.xx ") { + # append a new branch with the second destination + append_branch_old("sip:user@domain"); + # now: branch 0 = B@xx.xx.xx.xx + # now: branch 1 = C@domain + + t_relay(); + exit; + } + +``` + +## append_msg_branch(uri, [qvalue], [flags]) + +Adds a new message branch. The minimal information is the SIP URI of the branch. Optional, a q value may be provided. + +The "inherite" optional flag may dictate if the other branch properties (duri, q, path, socket, bflags) are to be inherited from the RURI branch or not. If not, all those properties will be NULL in the newly created branch (and this branch will have only a RURI field, nothing more). + +## avp_print() + +Prints the list with all the AVPs from memory. This is only a helper/debug function. + +## cache_store(storage_id, attribute, value, [timeout]) + +This sets in a memory-cache-like storage system a new value for an attribute. If the attribute does not already exist in the memcache, it will be inserted with the given value; if already present, its value will be replaced with the new one. The function may optionally take an extra parameter, a timeout (or lifetime) value for the attribute - after the lifetime is exceeded, the attribute is automatically purged from memcache. If "timeout" is omitted or has a value or 0, the attribute/value pair will never expire. + +Function returns true if the new attribute was successfully inserted. + +Parameters: +* *storage_id* (string) +* *attribute* (string) +* *value* (string) +* *timeout* (int, optional) + +```opensips + +cache_store("local", "total_minutes_$fU", $avp(mins), 1200); + +# For a Redis-backed cache: +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_store("redis:cluster1", "passwd_$tu", $var(x)); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## cache_remove(storage_id, attribute) + +This removes an attribute from a memory-cache-like storage system. Function returns false only if the *storage_id* is invalid. + +Parameters: +* *storage_id* (string) +* *attribute* (string) + +```opensips + +cache_remove("local", "total_minutes_$fU"); + +# For a Redis-backed cache: +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_remove("redis:cluster1", "total_minutes_$fU"); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## cache_fetch(storage_id, attribute, result) + +Fetch the value of an attribute from a memory-cache-like storage system. On a successful fetch, the result will be stored in the variable specified by **result_pv**. + +Function returns *true* if the attribute was found and its value successfully returned. + +Parameters: +* *storage_id* (string) +* *attribute* (string) +* *result_pv* (var) + +```opensips + +cache_fetch("local", "credit_$fU", $var(ret)); + +# For a Redis-backed cache: +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_fetch("redis:cluster1", "credit_$fU", $var(ret)); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## cache_counter_fetch(storage_id, counter_attribute, result) + +This function fetches from a memory-cache-like storage system the value of a counter. The result (if any) will be stored in the variable specified by **result**. + +Function returns true if the attribute was found and its value returned. + +Parameters: +* *storage_id* (string) +* *attribute* (string) +* *result* (var) + +```opensips + +cache_counter_fetch("local", "my_counter", $var(counter_val)); + +# For a Redis-backed cache: +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_counter_fetch("redis:cluster1", "my_counter", $var(redis_counter_val)); + +``` + +## cache_add( storage_id, attribute, increment, expire, [new_val]) + +This increments an attribute in a memory-cache-like storage system that supports such an operation. If the attribute does not exit, it will be created with the value of **increment**. + +Function returns false if increment fails. + +Parameters: +* *storage_id* (string) +* *attribute* (string) +* *increment* (int) +* *expire* (int) - if greater than 0, the key will also expire in the specified number of seconds +* *new_val* (var, optional) - variable in which to fetch the new value of the counter. + +```opensips + +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_add("redis:cluster1", "my_counter", 5, 0); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## cache_sub(storage_id, attribute, decrement, expire, [new_val]) + +This decrements an attribute in a memory-cache-like storage system that supports such an operation. + +Function returns false if decrement fails. + +Parameters: +* *storage_id* (string) +* *attribute* (string) +* *increment* (int) +* *expire* (int) - if greater than 0, the key will also expire in the specified number of seconds +* *new_val* (var, optional) - variable in which to fetch the new value of the counter. + +```opensips + +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://192.168.4.134:6379/"); +cache_sub("redis:cluster1", "my_counter", 5, 0); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## cache_raw_query(storage_id, raw_query, result) + +The function runs the provided raw query (in the back-end dependent language) and returns the results (if any) in the AVP (or AVP list) provided in *result*. This parameter may be missing, if the query returns no results. + +Function returns false if query fails. + +Parameters: +* *storage_id* (string) +* *raw_query* (string) +* *result* (string, optional, no expand) + +```opensips + +cache_raw_query("mongodb", "{ \"op\" : \"count\",\"query\": { \"username\" : $rU} }", "$avp(mongo_count_result)"); + +``` + +More complex examples can be found in the [Key-Value Interface Tutorial](https://docs.opensips.org/tutorials/keyvalueinterface/). + +## break() + +Since v0.10.0-dev3, 'break' can no longer be used to stop the execution of a route. The only place to use is to end a 'case' block in a 'switch' statement. 'return' must be now used instead of old 'break'. + +'return' and 'break' have now a similar meaning as in c/shell. + +## construct_uri(proto,[user],domain,[port],[extra],result) +The function builds a valid sip uri based on the arguments it receives. The result (if any) will be stored in the **result** AVP variable. +If you want to omit a part of the sip uri, just omit the respective parameter. + +Parameters: +* *proto* (string) +* *user* (string, optional) +* *domain* (string) +* *port* (string, optional) +* *extra* (string, optional) +* *result* (var) + +Example usage: +```opensips + +construct_uri("$var(proto)", "vlad", "$var(domain)", "", "$var(params)",$avp(s:newuri)); +xlog("Constructed URI is <$avp(s:newuri)> \n"); + +``` + +## drop() + +Stop the execution of the configuration script and alter the implicit action which is done afterwards. + +If the function is called in a 'branch_route' then the branch is discarded (implicit action for 'branch_route' is to forward the request). + +If the function is called in a 'onreply_route' then any provisional reply is discarded (implicit action for 'onreply_route' is to send the reply upstream according to Via header). + +Example of usage: + +```opensips +onreply_route { +if($rs=="183") { +drop(); +} +} +``` + +## exit() + +Stop the execution of the configuration script -- it has the same behaviour as return(0). It does not affect the implicit action to be taken after script execution. + +```opensips +route { +if (route(CHECK_METHOD)) { +xlog("L_NOTICE","method $rm is INVITE\n"); +} else { +xlog("L_NOTICE","method is $rm\n"); +}; +} +``` + +```opensips +route[CHECK_METHOD] { +if (is_method("INVITE")) { +return(1); +} else if (is_method("REGISTER")) { +return(-1); +} else if (is_method("MESSAGE")) { +sl_send_reply(403, "IM not allowed"); +exit; +}; +} +``` + +## force_rport() +Force_rport() adds the rport parameter to the first Via header. Thus, **OpenSIPS** will add the received IP port to the top most via header in the SIP message, even if the client does not indicate support for rport. This enables subsequent SIP messages to return to the proper port later on in a SIP transaction. + +The rport parameter is defined in RFC 3581. + +Example of usage: + +```opensips +force_rport(); +``` + +## force_send_socket(proto:address[:port]) + +Force **OpenSIPS** to send the message from the specified socket (it _must_ be one of the sockets **OpenSIPS** listens on). If the protocol doesn't match (e.g. UDP message "forced" to a TCP socket) the closest socket of the same protocol is used. + +Parameters: +* *socket* (string) + +Example of usage: + +```opensips +force_send_socket("tcp:10.10.10.10:5060"); +``` + +## force_tcp_alias([port_alias]) + +Enables TCP connection reusage (RFC 5923) for the current TLS (or WSS, TCP, WS) connection (source IP + **source port** + transport), regardless if the Via header field contains an *";alias"* parameter or not. All backwards SIP requests, towards the same (source IP + **Via port** + transport) pair will be forced over this connection, for as long as it stays open. The main purpose of this function (and of RFC 5923) is to minimize the number of TLS connections a SIP proxy must set up, due to the significant CPU overhead of the TLS cipher negotiation phase. + +Parameters: +* *port_alias* (int, optional) + + + +> [!WARNING] +> Do not perform **force_tcp_alias()** for end-user initiated connections (who are most likely grouped by one or more public IPs), as this would create an open vector for call hijacking! + +## forward(destination) + +Forward the SIP request to the given destination in stateless mode. This has the format of [proto:]host[:port]. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core). +If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible). + +Parameters: +* *destination* (string, optional) - if missing, the forward will be done based on RURI. + +Example of usage: + +```opensips +forward("10.0.0.10:5060"); +#or +forward(); +``` + +## get_timestamp(sec_avp,usec_avp) + +Returns the current timestamp, seconds and microseconds of the current second, from a single system call. + +Parameters: +* *sec_avp* (var) +* *usec_avp* (var) + +Example of usage: + +```opensips +get_timestamp($avp(sec),$avp(usec)); +``` + +## isdsturiset() + +Test if the dst_uri field (next hop address) is set. + +Example of usage: + +```opensips +if(isdsturiset()) { +log("dst_uri is set\n"); +}; +``` + +## isflagset(string) + +Test if a flag is set for currently processed message. + +For more see [Flags Documentation](Script-Flags.md). + +Parameters: +* *flag* (string, static) + +Example of usage: + +```opensips + + if (isflagset("NAT_PING")) + log("flag NAT_PING is set\n"); + +``` + +## isbflagset(flag, [branch_idx]) + +Test if a flag is set for a specific branch. "branch_idx" identifies the branch for which the flags are tested - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default. + +For more about script flags, see [Flags Documentation](Script-Flags.md). + +Parameters: +* *flag* (string, static) +* *branch_idx* (int, optional) + +Example of usage: + +```opensips + + if (isbflagset("NAT_PING", 1)) + log("flag NAT_PING is set in branch 1\n"); + +``` + +## is_myself(host, [port]) + +Test if the host and optionally the port represent one of the addresses that OpenSIPS listens on. This checks the list of local IP addresses, hostnames and aliases that have been set in the OpenSIPS configuration file. + +Parameters: +* host (string) +* port (int, optional) + +Example of usage: + +```opensips +if (is_myself($rd, $rp)) { + xlog("the request is for local processing\n"); +} +``` + +## log([level,] string) + +Write text message to standard error terminal or syslog. You can specify the log level as first parameter. + +Example of usage: + +```opensips +log("just some text message\n"); +``` + +## move_msg_branch([src_idx], [dst_idx] [, keep]) + +Moves the whole information attached to the **src_idx** branch to the **dst_idx** branch. Both **src_idx** and **dst_idx** should be an integer value and should represent a valid branch index. If they are not provided, or have a negative value, the main/message branch is considered. +By default, the function removes the **src_idx** branch after moving it, and shifts all the remaining branches after it. If, however, the third parameter of the function is the **keep** string, the branch is not removed, and only copied to the **dst_idx** branch. + +## next_branches() + +Adds to the request a new destination set that includes all highest priority class contacts ('q' value based) from the serialized branches (see serialize_branches()). If called from a route block, it rewrites the request uri with first contact and adds the remaining contacts as parallel branches. If called from failure route block, adds all contacts as parallel branches. All used contacts are removes the serialized branches. + +Returns true if at least one contact was added for the request's destination set - returns 1 if other branches are still pending and return 2 if no other branches are left for future processing - shortly, if 2: this is the last branch, if 1: other will follow. False is return is nothing was done (no more serialized branches). + +Example of usage: + +```opensips +next_branches(); +``` + +## prefix(str) + +Add the string parameter in front of username in R-URI. + +Parameters: +* *str* (string) + +Example of usage: + +```opensips +prefix("00"); +``` + +## pv_printf(pv, fmt_str) + +Prints the formatted string 'fmt_str' in the AVP 'pv'. The 'fmt_str' parameter can include any pseudo-variable defined in **OpenSIPS**. The 'pv' can be any writable pseudo-variable -- e.g.,: AVPs, VARs, `$ru`, `$rU`, `$rd`, `$du`, `$br`, `$fs.` + +Parameters: +* *pv* (var) +* *string* (string) + +Example of usage: + +```opensips +pv_printf($var(x), "r-uri: $ru"); +pv_printf($avp(i:3), "from uri: $fu"); +``` + +## raise_event(event, [attrs], [vals]) + +Raises from script an event through OpenSIPS Event Interface. + +This function triggers an event for all subscribers for that event, regardless the transport module used. + +Parameters: +* *event* (string) - the name of the event which should be raised +* *attrs* (var, optional) - AVP containing the the names of the attributes; if this parameter is missing and *vals* is provided, the attributes will be written as array(positional) params in the JSON-RPC payload +* *vals* (var, optional) - AVP containing values attached to the event; if this parameter is missing, the raised event will not have any attributes, even if the *attrs* parameter is provided. + +Example of usage (raises an event with no attributes): + +```opensips + +raise_event("E_NO_PARAM"); + +``` + +Example of usage (raises an event with two attributes): + +```opensips + +$avp(attr-name) = "param1"; +$avp(attr-name) = "param2"; +$avp(attr-val) = 1; +$avp(attr-val) = "2"; +raise_event("E_TWO_PARAMS", $avp(attr-name), $avp(attr-val)); + +``` + +Example of usage (raises an event with two unnamed attributes): + +```opensips + +$avp(attr-val) = 1; +$avp(attr-val) = "2"; +raise_event("E_TWO_PARAMS", , $avp(attr-val)); + +``` + +## remove_msg_branch(branch_idx) + +Removes a given branch. +Once a branch is removed, all the subsequent branches are shifted (i.e. if branch n is removed, then the old n+1 branch becomes the new n branch, the old n+2 branch becomes n+1 and so on). + +Parameters: +* *branch_idx* (int) + +Example of usage (remove all branches with URI hostname "127.0.0.1"): + +```opensips + +$var(i) = 0; +while ($(branch(uri)[$var(i)]) != null) { + xlog("L_INFO","$$(branch(uri)[$var(i)])=[$(branch(uri)[$var(i)])]\n"); + if ($(branch(uri)[$var(i)]{uri.host}) == "127.0.0.1") { + xlog("L_INFO","removing branch $var(i) with URI=[$(branch(uri)[$var(i)])]\n"); + remove_msg_branch($var(i)); + } else { + $var(i) = $var(i) + 1; + } +} + +``` + +## return(int) + +The return() function allows you to return any integer value from a called route() block. +You can test the value returned by a route using "`$retcode`" variable. + +return(0) is same as "exit()"; + +In bool expressions: + + * Negative and ZERO is FALSE + * Positive is TRUE + +Example usage: + +```opensips + +route { + if (route(CHECK_METHOD)) { + xlog("L_NOTICE","method $rm is INVITE\n"); + } else { + xlog("L_NOTICE","method $rm is REGISTER\n"); + }; +} + +``` +```opensips + +route[CHECK_METHOD] { + if (is_method("INVITE")) { + return(1); + } else if (is_method("REGISTER")) { + return(-1); + } else { + return(0); + }; +} + +``` + +## resetdsturi() + +Set the value of dst_uri filed to NULL. dst_uri field is usually set after loose_route() or lookup("location") if the contact address is behind a NAT. + +Example of usage: + +```opensips +resetdsturi(); +``` + +## resetflag(flag) + +Reset a flag for currently processed message (unset its value). + +For more see [Flags Documentation](Script-Flags.md). + +Parameters: +* *flags* (string, static) + +Example of usage: + +```opensips + + resetflag("NAT_PING"); + +``` + +## resetbflag(flag, [branch_idx]) + +Reset a flag for a specific branch (unset its value). "branch_idx" identifies the branch for which the flag is reset - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default. + +Parameters: +* *flag* (string, static) +* *branch_idx* (int, optional) + +For more about script flags, see [Flags Documentation](Script-Flags.md). + +Example of usage: +```opensips + + resetbflag("NAT_PING", 1); + # or + resetbflag("NAT_PING"); # same as resetbflag("NAT_PING", 0) + +``` + +## revert_uri() + +Set the R-URI to the value of the R-URI as it was when the request was received by server (undo all changes of R-URI). + +Example of usage: + +```opensips +revert_uri(); +``` + +## set_via_handling(flags) + +Rewrite the domain part of the R-URI with the value of function's parameter. Other parts of the R-URI like username, port and URI parameters remain unchanged. + +Parameters: +* *flags* (string) - a comma separated list of named flags + * `force-rport` - adds the rport parameter to the first Via header; thus, **OpenSIPS** will add the received IP port to the top most via header in the SIP message, even if the client does not indicate support for rport. This enables subsequent SIP messages to return to the proper port later on in a SIP transaction. + * `add-local-rport `- add 'rport' parameter to the Via header generated by server (see RFC3581 for its meaning); it affects only the current processed request. + * `reply-to-via` - routes back the repies to the IP:port from the top VIA instead of the src IP:port of the requests + * `force-tcp-alias` - see [force_tcp_alias()](#force_tcp_alias) function + +Example of usage: + +```opensips +set_via_handling("force-rport,reply-to-via"); +``` + +## sethost(host) + +Rewrite the domain part of the R-URI with the value of function's parameter. Other parts of the R-URI like username, port and URI parameters remain unchanged. + +Parameters: +* *host* (string) + +Example of usage: + +```opensips +sethost("1.3.6.4"); +``` + +## sethostport(hostport) + +Rewrite the domain part and port of the R-URI with the value of function's parameter. Other parts of the R-URI like username and URI parameters remain unchanged. + +Parameters: +* *hostport* (string) + +Example of usage: + +```opensips +sethostport("1.3.6.4:5080"); +``` + +## setuser(user) + +Rewrite the user part of the R-URI with the value of function's parameter. + +Parameters: +* *user* (string) + +Example of usage: + +```opensips +setuser("newuser"); +``` + +## setuserpass(pass) + +Rewrite the password part of the R-URI with the value of function's parameter. + +Parameters: +* *pass* (string) + +Example of usage: + +```opensips +setuserpass("my_secret_passwd"); +``` + +## setport(port) + +Rewrites/sets the port part of the R-URI with the value of function's parameter. + +Parameters: +* *port* (string) + +Example of usage: + +```opensips +setport("5070"); +``` + +## seturi(str) + +Rewrite the request URI. + +Parameters: +* *uri* (string) + +Example of usage: + +```opensips +seturi("sip:test@opensips.org"); +``` + +## route(name [, param1 [, param2 [, ...] ] ] ) + +This function is used to run the code from the 'name' route, declared in the script. Optionally, it can receive several parameters (up to 7), that can be later retrieved using the '`$param(idx)`' pseudo-variable. + +The name of the route is an identifier format, whereas the parameters can be either int, string, or a pseudo-variable. + +Example of usage: + +```opensips +route(HANDLE_SEQUENTIALS); +route(HANDLE_SEQUENTIALS, 1, "param", $var(param)); +``` + +## script_trace([log_level, pv_format_string, [info]]) + +This function start the script tracing - this helps to better understand the flow of execution in the OpenSIPS script, like what function is executed, what line it is, etc. Moreover, you can also trace the values of pseudo-variables, as script execution progresses. + +The blocks of the script where script tracing is enabled will print a line for each individual action that is done (e.g. assignments, conditional tests, module functions, core functions, etc.). Multiple pseudo-variables can be monitored by specifying a **pv_format_string** (e.g. "`$ru`---`$avp(var1)`"). + +The logs produced by multiple/different traced regions of your script can be differentiated (tagged) by specifying an additional plain string - **info_string** - as the 3rd parameter. + +To disable script tracing, just do script_trace(). Otherwise, the tracing will automatically stop at the end the end of the top route. + +Parameters: +* *log_level* (int, optional) +* *pv_format_string* (string, optional) +* *info* (string, static, optional) + +Example of usage: +```opensips +script_trace( 1, "$rm from $si, ruri=$ru", "me"); +``` + +will produce: +```opensips + + [line 578][me][module consume_credentials] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org) + [line 581][me][core setbflag] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org) + [line 583][me][assign equal] -> (INVITE from 127.0.0.1 , ruri=sip:111211@opensips.org) + [line 592][me][core if] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) + [line 585][me][module is_avp_set] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) + [line 589][me][core if] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) + [line 586][me][module is_method] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) + [line 587][me][module trace_dialog] -> (INVITE 127.0.0.1 , ruri=sip:tester@opensips.org) + [line 590][me][core setflag] -> (INVITE from 127.0.0.1 , ruri=sip:tester@opensips.org) + +``` + +## send(destination [, headers]) + +Send the original SIP message to a specific destination in stateless mode. This is definied as [proto:]host[:port]. No changes are applied to received message, no Via header is added, unless headers parameter is specified. Host can be an IP or hostname; supported protocols are UDP, TCP and TLS. (For TLS, you need to compile the TLS support into core). If proto or port are not specified, NAPTR and SRV lookups will be used to determine them (if possible). The headers parameter should end in '\r\n'. + +Parameters: +* *destination* (string) +* *headers* (string, optional) + +Example of usage: + +```opensips +send("udp:10.10.10.10:5070"); +send("udp:10.10.10.10:5070", "Server: opensips\r\n"); +``` + +## serialize_branches(clear_previous[, keep_order]) + +Takes all currently added branches for parallel forking (e.g. with lookup() or append_msg_branch()), as well as the current branch (R-URI (`$ru`) / outbound Proxy (`$du`) / q value (`$ru_q`) / branch flags / forced Path headers / forced send socket), and prepares them for serial forking instead. The ordering is done in decreasing "q" order. The serialized branches are internally stored in the "`$avp(serial_branch)`" AVP - this allows them to be manipulated by the "next_branches()" function, usually within a failure route. + + + +NOTE that (according to RFC3261), the branches with the same "q" value will still be parallel forked during a certain step in the serial forking (it will result a combination of serial with parallel forking). In other words, this function will clear all added branches and keep re-adding them as long as they have identical highest "q" values, while throwing all other "lower-than-highest q" branches in the "`$avp(serial_branch)`". A similar grouping process takes place during each "next_branches()" function call. + + + +NOTE that this function is not altering the current branch (R-URI, outbound proxy, etc.) - it is just preparing a serial forking set with the above-mentioned branches. You may need to call "next_branches()" immediately after calling this function, see the example below. + +Parameters: +* *clear_previous* (int) - if set to non-zero, all previous results of another "serialize_branches()" (serial forking set which is no longer needed) will be deleted before starting a new set +* *keep_order* (int, optional) - if set to non-zero, the added branches as well as the current branch, will be serialized exactly in the order in which they are found. + +Example of usage: + +```opensips + + if (!lookup("location")) { + t_reply(480, "Temporarily Unavailable"); + exit; + } + + serialize_branches(1); + next_branches(); # Pop the R-URI from the serialized branches set + +``` + +## set_advertised_address(adv_addr) + +Same as 'advertised_address' but it affects only the current message. It has priority if 'advertised_address' is also set. + +Parameters: +* *adv_addr* (string) + +Example of usage: + +```opensips +set_advertised_address("opensips.org"); +``` + +## set_advertised_port(adv_port) + +Same as 'advertised_port' but it affects only the current message. It has priority over 'advertised_port'. + +Parameters: +* *adv_port* (string) + +Example of usage: + +```opensips +set_advertised_port("5080"); +``` + +## setdsturi(uri) + +Explicitely set the dst_uri field to the value of the paramater. The parameter has to be a valid SIP URI. + +Parameters: +* *uri* (string) + +Example of usage: + +```opensips +setdsturi("sip:10.10.10.10:5090"); +``` + +## setflag(flag) + +Set a flag for currently processed message. The flags are used to mark the message for special processing (e.g. pinging NAT'ed contacts, TCP connect behavior, etc.) or to keep some state (e.g. message authenticated). The OpenSIPS script supports, at most, 32 unique string flags. + +Parameters: +* *flag* (string, static) + +Example of usage: + +```opensips + + setflag("NAT_PING"); + +``` + +## setbflag(flag, [branch_idx]) + +Set a flag for a specific branch. "branch_idx" identifies the branch for which the flag is set - it must be a positive number. Branch index 0 refers to the RURI branch. If this parameter is missing, 0 branch index is used as default. The OpenSIPS script supports, at most, 32 unique string branch flags. + +For more about script flags, see [Flags Documentation](Script-Flags.md). + +Parameters: +* *flag* (string, static) +* *branch_idx* (int, optional) + +Example of usage: + +```opensips + + setbflag("NAT_PING", 1); + # or + setbflag("NAT_PING"); # same as setbflag("NAT_PING", 0) + +``` + +## sr_check_status( group, [identifier]) + +Function to check the status of an 'status/report' identifier. Such checking is very useful for determining at script level the readiness of a module or core component (if able to provide its full functionality). + +Parameters: +* *group* (string), the name of the 'status/report' group (the group exported by the OpenSIPS core is named "core", while the modules may export groups with their names. +* *identifier* (string, optional), the name of the identifier to be checked (what are the available identifiers, it depends on the party exporting the group). Possible values for this identifier are: + * (1) name of an identifier + * (2) NULL, to refer to the default (per group) identifier (converted internally into "main" identifier + * (3) "all" to refer to all the identifiers in the group + +The returned value, depending on the provided identifier value, may be: +* (1) the status of the given identifier +* (2) the status of the "main" identifier +* (3) the aggregated status over all identifiers, as -1 (if at least of identifier has a negative status) or 1 (if all identifiers have a positive status) + +Example of usage: + +```opensips + + # check if the "pstn" identifier (the "pstn" partition) from "drouting" module is ready (data is fully loaded) + if (sr_check_status( "drouting", "pstn") ) {} + + # check if the all identifiers (all partitions) from "drouting" module are ready (data is fully loaded) + if (sr_check_status( "drouting", "all") ) {} + + +``` + +## strip(n) + +Strip the first N-th characters from username of R-URI (N is the value of the parameter). + +Parameters: +* *n* (int) + +Example of usage: + +```text + + strip(3); + +``` + +## strip_tail(n) + +Strip the last N-th characters from username of R-URI (N is the value of the parameter). + +Parameters: +* *n* (int) + +Example of usage: + +```text +strip_tail(3); +``` + +## subscribe_event(string, string [, int]) + +Subscribes an external application for a certain event for the OpenSIPS Event Interface. This is used for transport protocols that cannot subscribe by themselves (example event_rabbitmq). This function should be called only once in the startup_route if the subscription doesn't expire, or in a timer route if the subscription should be renewed once in a while. + +Parameters: +* *event* (string) - the name of the event an external application should be notified for. +* *socket* (string) - the socket of the external application. Note that this socket should follow the syntax of an existing loaded Event Interface transport module (example: event_datagram, event_rabbitmq). +* *expire* (int, optional) - the expire time of the subscription. If it is not present, then the subscription does not expire at all. + +Example of usage (subscriber that never expires, notified by the RabbitMQ module): + +```opensips + +startup_route { + subscribe_event("E_PIKE_BLOCKED", "rabbitmq:127.0.0.1/pike"); +} + +``` + +Example of usage (subscriber expires every 5 seconds, notified through UDP): + +```opensips + +timer_route[SUBSCRIBE_EVENTS, 4] { + subscribe_event("E_PIKE_BLOCKED", "udp:127.0.0.1:5051", 5); +} + +``` + +## swap_msg_branches([br1_idx], [br2_idx]) + +Swaps the information between two branches, represented by the **br1_idx** and **br2_idx**. Both values should be an integer value and should represent a valid branch index. If they are not provided, or have a negative value, the main/message branch is considered. + +## use_blacklist(bl_name) + +Enables the DNS blacklist name received as parameter. Its primary purposes will be to prevent sending requests to critical IPs (like GWs) due DNS or to avoid sending to destinations that are known to be unavailable (temporary or permanent). + +Parameters: +* *bl_name* (string) + +```opensips + + use_blacklist("pstn-gws"); + +``` + +## unuse_blacklist(bl_name) + +Disables the DNS blacklist name received as parameter. + +Parameters: +* *bl_name* (string) + +```opensips + + unuse_blacklist("pstn-gws"); + +``` + +## check_blacklist_rule([bl_name], ip[, port [, proto]]) + +Checks whether a specific proto:ip:port+pattern matches a blacklist, or all if *bl_name* is not specified. + +Parameters: +* *bl_name* (string, optional) - if missing, the rule is matched against all used blacklists +* *ip* (string) - the IP to check against +* *port* (integer, optional) - the port to check against; if missing, 0 is considered, which will match only 0-port rules +* *proto* (string, optional) - the protocol to check against, or "any" if any protocol should be checked; if missing, "any" is considered, which will match only any proto rules +* *pattern* (string, optional) - the pattern to check against + +```opensips + + if (check_blacklist_rule("pstn-gws", $dd, $dp, $dP)) + xlog("REQUEST will be blocked\n"); + +``` + +## add_blacklist_rule([bl_name], ip[, port [, proto [, expire]]]) + +Adds a proto:ip:port+pattern rule to a blacklist. + +Parameters: +* *bl_name* (string) - the blacklist to add the rule to +* *ip* (string) - the IP to add; if the IP starts with '!', the entire rule is negated +* *port* (integer, optional) - the port to add; if missing, 0/any port is used +* *proto* (string, optional) - the protocol to add, or "any" for any protocol; if missing, "any" is used +* *pattern* (string, optional) - the pattern to add +* *expire* (integer, optional) - if specified, provides the expiration time in seconds for the rule + +```opensips + + add_blacklist_rule("filter", $si, $sp, "udp"); + +``` + +## del_blacklist_rule([bl_name], ip[, port [, proto]]) + +Removes a proto:ip:port+pattern rule from a blacklist. + +Parameters: +* *bl_name* (string) - the blacklist to remove the rule from +* *ip* (string) - the IP to remove; if the IP starts with '!', the entire rule is negated +* *port* (integer, optional) - the port to remove; if missing, 0/any port is used +* *proto* (string, optional) - the protocol to remove, or "any" for any protocol; if missing, "any" is used +* *pattern* (string, optional) - the pattern to remove + +```opensips + + del_blacklist_rule("filter", $si, $sp, "udp"); + +``` + +## xlog([log_level, ]format_string) + +Allows various debugging / runtime / critical messages to be printed as the execution of the OpenSIPS script is done. All pseudo-variables included in the *format_string* parameter will be expanded. There are several optional logging levels which can be specified. They work in accordance with the severity levels of syslog. The levels are named as follows: + +* L_ALERT (-3) +* L_CRIT (-2) +* L_ERR (-1) - this is used by default if log_level is omitted +* L_WARN (1) +* L_NOTICE (2) +* L_INFO (3) +* L_DBG (4) + + + +```opensips + + # a few xlog scripting examples + xlog("Received $rm from $fu (callid: $ci)\n"); + xlog("L_ERR", "key $var(username) not found in cache!\n"); + +``` diff --git a/docs/manual/Script-CoreParameters.md b/docs/manual/Script-CoreParameters.md new file mode 100644 index 00000000000..d990bf03f49 --- /dev/null +++ b/docs/manual/Script-CoreParameters.md @@ -0,0 +1,1532 @@ +--- +title: "Core Parameters" +description: "This section lists all parameters exported by OpenSIPS core for script usage (to be used in opensips.cfg)." +--- + +This section lists all parameters exported by **OpenSIPS** core for script usage (to be used in opensips.cfg). + +## Core parameters + +Global parameters available in the *opensips.cfg* configuration file. Accepted values depend on the parameter type: double-quoted strings, numbers or booleans (`true`/`false`). + +### abort_on_assert +Default value is `false`. + + + +Only relevant if [asserts](https://docs.opensips.org/manual/3-6/script-corefunctions#assert) are enabled. Set to `true` to make OpenSIPS shut down immediately when a script assert fails. + +Example of usage: +```opensips + + abort_on_assert = true + +``` + +### advertised_address + +This can be an IP address or string and represents the address advertised in the Via header and other destination lumps, such as Record-Route headers. If empty or not set, the socket address used to send the request is advertised. + +> [!WARNING] +> Do not set this unless you know what you are doing, for example when handling NAT traversal. +> OpenSIPS does not validate this value; for example, `foo.bar` is accepted even if it does not exist. + +Example of usage: +```opensips + + advertised_address = "opensips.org" + +``` + +> [!NOTE] +> Besides this global approach, you can also define an advertised IP and port per interface using the [socket](#socket) parameter. Per-interface advertised values are used only for traffic leaving that interface. + +### advertised_port + +The port advertised in the Via header and other destination lumps, such as Record-Route headers. If empty or not set, the port used to send the message is advertised. The same warnings as for [advertised_address](#advertised_address) apply. + +Example of usage: +```opensips + + advertised_port = 5080 + +``` + +> [!NOTE] +> Besides this global approach, you can also define an advertised IP and port per interface using the [socket](#socket) parameter. Per-interface advertised values are used only for traffic leaving that interface. + +### alias + +Sets alias hostnames for the server. It can be set multiple times, with each value added to the list used to match the hostname when `myself` is checked. + +If the `:port` part is omitted, **all** ports of the given hostname are considered aliases, similar to port `0`. + +It may take an optional **accept_subdomain** indicator to also match any subdomain of the defined domain. + +> [!IMPORTANT] +> It is necessary to include the port used in the `socket` definitions in the alias definition otherwise the `loose_route()` function will not work as expected for local forwards! + + +Example of usage: + +```opensips + + alias = udp:other.domain.com:5060 + alias = tcp:another.domain.com:5060 + # accept subdomains like sip.domainX.com + alias = udp:domainX.com:5060 accept_subdomain + +``` + +### auto_aliases + +This parameter controls whether aliases should be automatically discovered and added while fixing listening sockets. The auto-discovered aliases are the result of a DNS lookup, when the [socket](#socket) definition uses a hostname, or of a reverse DNS lookup on the socket IP. + +For backwards compatibility, the default value is `false`. + +Example of usage: +```opensips + + auto_aliases = true + +``` + +### auto_scaling_cycle +The number of seconds defining an auto-scaling cycle. During each cycle, the auto-scaling engine evaluates the internal load of the process groups and decides whether more processes need to be created or existing processes need to be terminated. See [auto_scaling_profile](#auto_scaling_profile) for more details on how auto-scaling works. + +The default value is `1` second. + +Example of usage: +```opensips + + auto_scaling_cycle = 3 # do auto-scaling checks once every 3 seconds + +``` + +### auto_scaling_profile +Defines the auto-scaling behavior: how many processes are allowed and when to create or terminate processes. These profiles may be used for UDP processes (see the [udp_workers](#udp_workers) or [socket](#socket) options), TCP processes (see the [tcp_workers](#tcp_workers) option) or timer processes (see the [timer_workers](#timer_workers) option). + +For more, see [this external description of auto-scaling](https://blog.opensips.org/2019/02/25/auto-process-scaling-a-cure-for-load-and-resources-concerns/). + +Example of usage: +```opensips + + auto_scaling_profile = PROFILE_SIP + scale up to 6 on 70% for 4 cycles within 5 + scale down to 2 on 18% for 10 cycles + +``` +This profile allows the group to fork up to 6 processes. A new process is forked when the overall load of the group is higher than 70% for more than 4 cycles during a 5-cycle monitoring window. A cycle is the monitoring time unit, as defined by [auto_scaling_cycle](#auto_scaling_cycle). + +The profile also allows the group to scale down to a minimum of 2 processes. A process is terminated when the overall load of the group is lower than 18% during 10 cycles. The down-scaling part of the profile is optional. If not defined, OpenSIPS will only scale up. + +### check_via + +Checks whether the address in the topmost Via header of replies is local. Default value is `false` (check disabled). + +Example of usage: + +```opensips + + check_via = true + +``` + +### chroot + +The value must be a valid path in the system. If set, **OpenSIPS** will chroot, changing its root directory to this path. + +Example of usage: + +```opensips + + chroot = "/other/fakeroot" + +``` + +### debug_mode +Enabling **debug_mode** is a fast way to debug **OpenSIPS**. This option automatically forces: +* foreground mode (do not detach from the console) +* logging level 4 (debug) +* logging to standard error +* core dumping +* UDP worker processes to 2, if UDP is enabled +* TCP worker processes to 2, or the maximum configured value if lower than 2, if TCP is enabled + +Default value is `false` (disabled). + +> [!NOTE] +> Enabling this option overrides individual parameters such as foreground mode, log level, `udp_workers` and `tcp_workers`. + +Example of usage: +```opensips + + debug_mode = true + +``` + +### db_version_table + +The name of the database table used by the DB API to check table versions. + +Default value is `"version"`. + +Example of usage: +```opensips + + db_version_table = "version_3_6" + +``` + +### db_default_url + +The default DB URL used by modules when no per-module URL is configured. + +Default value is `NULL` (not defined). + +Example of usage: +```opensips + + db_default_url = "mysql://opensips:opensipsrw@localhost/opensips" + +``` + +### db_max_async_connections + +Maximum number of TCP connections opened from a single OpenSIPS worker to each individual SQL backend. + +Default value is `10`. + +Individual backends are determined from DB URLs as follows: +```opensips + + [ scheme, user, pass, host, port, database ] + +``` + +Example of usage: +```opensips + + db_max_async_connections = 220 + +``` + +### disable_503_translation + +If set to `true`, OpenSIPS will not translate received 503 replies into 500 replies. RFC 3261 states that a proxy should never relay a 503 response, but transform it into a 500 response instead. + +Default value is `false` (translation enabled). + +Example of usage: +```opensips + + disable_503_translation = true + +``` + +### disable_core_dump + +If set to `true`, OpenSIPS disables core dumps by setting the core dump size limit to 0. By default, core dump limits are set to unlimited or to a high enough value. + +Default value is `false`. + +Example of usage: +```opensips + + disable_core_dump = true + +``` + +### disable_dns_blacklist + +When DNS failover is configured, the DNS resolver can temporarily blacklist failed destinations. This prevents **OpenSIPS**, for a limited time, from sending requests to destinations known to have failed. The blacklist acts as a memory for the DNS resolver. + +The temporary blacklist created by the DNS resolver is named `dns` and is selected by default for failover usage, so there is no need to call `use_blacklist()` for it. The rules in this list have a lifetime of 4 minutes; this can be changed at compile time in `resolve.c`. + +If set to `true`, this DNS blacklist is disabled. + +Default value is `true` (DNS blacklist disabled). + +Example of usage: +```opensips + + disable_dns_blacklist = false + +``` + +### disable_dns_failover + +If set to `true`, OpenSIPS disables DNS-based failover. This is a global option, affecting both the core and the modules. + +Default value is `false` (DNS-based failover enabled). + +Example of usage: +```opensips + + disable_dns_failover = true + +``` + +### disable_stateless_fwd + +Controls the handling of stateless replies: + +```opensips + + true - drop stateless replies if stateless forwarding functions, such as forward(), are not used in the script + false - forward stateless replies + +``` + +Default value is `true`. + +Example of usage: +```opensips + + disable_stateless_fwd = false + +``` + +### dns + +This parameter controls whether the SIP server should attempt to look up its own domain name in DNS. If this parameter is set to `true` and the domain name is not in DNS, a warning is printed to syslog and a `received=` field is added to the Via header. + +Default value is `false`. + +Example of usage: +```opensips + + dns = true + +``` + +### dns_retr_time + +Time in seconds before retrying a DNS request. Default value is system-specific and also depends on the `/etc/resolv.conf` content, usually 5 seconds. + +Example of usage: +```opensips + + dns_retr_time = 3 + +``` + +### dns_retr_no + +Number of DNS retransmissions before giving up. Default value is system-specific and also depends on the `/etc/resolv.conf` content, usually `4`. + +Example of usage: +```opensips + + dns_retr_no = 3 + +``` + +### dns_servers_no + +How many DNS servers from `/etc/resolv.conf` will be used. + +Default value is to use all of them. + +Example of usage: +```opensips + + dns_servers_no = 2 + +``` + +### dns_try_ipv6 + +If set to `true` and a DNS lookup fails, OpenSIPS retries the lookup for IPv6 using an AAAA record. + +Default value is `false`. + +Example of usage: +```opensips + + dns_try_ipv6 = true + +``` + +### dns_try_naptr + +Controls whether NAPTR lookups are performed when doing DNS-based routing for SIP requests. If disabled, DNS lookup starts with SRV lookups. + +Default value is `true`. + +Example of usage: +```opensips + + dns_try_naptr = false + +``` + +### dns_use_search_list + +If set to `false`, the search list in `/etc/resolv.conf` is ignored, which means fewer lookups and faster DNS failure handling. + +Default value is `true`. + +> [!NOTE] +> Even if you do not have a search list defined, setting this option to `false` can still be faster because an empty search list still causes two DNS queries, for example `foo.` and `foo`. + +Example of usage: +```opensips + + dns_use_search_list = false + +``` + +### dst_blacklist + +Defines an IP/destination blacklist. These lists can be selected from the script, at runtime, to filter outgoing requests based on IP, protocol, port, etc. + +The primary purpose is to prevent sending requests to critical IPs, such as gateways, because of bad DNS entries or to avoid sending requests to destinations known to be unavailable, either temporarily or permanently. + +The grammar for specifying a list is: + +```opensips + + dst_blacklist = id [/bl_flags] [: bl_rules] + +``` + +* **id** is a unique identifier of the blacklist. +* **bl_flags** contains a set of optional modifiers: + +```opensips + + bl_flags = bl_flag [, bl_flag]* + bl_flag = "expire" | "default" | "readonly" + +``` + +* **bl_rules** contains one or more blacklist rules: + +```opensips + + bl_rules = [!] ipnet | { bl_rule [, bl_rule]* } + bl_rule = [!] ( [bl_proto, ] ipnet [, port [, bl_pattern]] ) + +``` + +The blacklist modifiers have the following meanings: +* `expire`: the blacklist may contain entries that expire. +* `default`: the blacklist is used by default when sending requests, without having to explicitly set it using the `use_blacklist()` function. +* `readonly`: the blacklist is statically defined in the script and cannot change at runtime. + +When **bl_flags** is missing, the `readonly` flag is explicitly set. + +A rule has the following properties: +* if `!` is at the beginning of the rule, it negates the entire rule. +* **bl_proto**: any supported protocol, or `any` for any protocol; if missing, the default is `any`. +* **ipnet**: IP or IP/MASK that should match the rule. +* **port**: port number or `0` for any port. +* **bl_pattern**: filename-like matching, see `man 3 fnmatch`, applied on the outgoing request buffer (`first_line + hdrs + body`). + +Example of usage: +```opensips + + # filter out requests going to IPs of my gateways + dst_blacklist = gw:{(tcp, 192.168.3.100, 5060, ""), (any, 192.168.3.101, 0, "")} + # block requests going to "evil" networks + dst_blacklist = net_filter:{(any, 192.168.1.120/255.255.255.0, 0, "")} + # block message requests with nasty words + dst_blacklist = msg_filter:{(any, 192.168.20.0/255.255.255.0, 0, "MESSAGE*ugly_word")} + # block requests not going to a specific subnet + dst_blacklist = net_filter2:{!(any, 193.168.30.0/255.255.255.0, 0, "")} + # define a dynamic list that is built at runtime and has expiring entries + dst_blacklist = net_dynamic/expire + +``` + +### enable_asserts +Default value is `false`. + +Set to `true` to enable the [assert](https://docs.opensips.org/manual/3-6/script-corefunctions#assert) script statement. + +Example of usage: +```opensips + + enable_asserts = true + +``` + +### event_pkg_threshold + +A number representing the percentage threshold above which the E_CORE_PKG_THRESHOLD event is raised, warning about a low amount of free private memory. It accepts integer values between `0` and `100`. + +Default value is `0` (event disabled). + +Example of usage: +```opensips + + event_pkg_threshold = 90 + +``` + +### event_shm_threshold + +A number representing the percentage threshold above which the E_CORE_SHM_THRESHOLD event is raised, warning about a low amount of free shared memory. It accepts integer values between `0` and `100`. + +Default value is `0` (event disabled). + +Example of usage: +```opensips + + event_shm_threshold = 90 + +``` + +### exec_dns_threshold + +A number representing the maximum number of microseconds a DNS query is expected to take. Anything above the set number triggers a warning message to the logging facility. + +Default value is `0` (logging disabled). + +Example of usage: +```opensips + + exec_dns_threshold = 60000 + +``` + +### exec_msg_threshold + +A number representing the maximum number of microseconds the processing of a SIP message is expected to take. Anything above the set number triggers a warning message to the logging facility. Aside from the message and the processing time, the most time-consuming function calls from the script are also logged. + +Default value is `0` (logging disabled). + +Example of usage: +```opensips + + exec_msg_threshold = 60000 + +``` + +### include_file + +Can be called outside route blocks to load additional routes or blocks, or inside route blocks to load additional script actions. The file path can be relative or absolute. If the path is relative, OpenSIPS first tries to locate it relative to the directory from which OpenSIPS was started. If that fails, it tries the directory of the file that includes it. An error is raised if the file is not found. + +Example of usage: +```opensips + + include_file "proxy_regs.cfg" + +``` + +### import_file + +Alias for [include_file](#include_file). + +Example of usage: +```opensips + + import_file "proxy_regs.cfg" + +``` + +### listen + +> [!WARNING] +> Replaced in OpenSIPS 3.1. + +This parameter was replaced by the [socket](#socket) parameter, preserving exactly the same format and behavior. + +### log_facility + +> [!WARNING] +> Replaced in OpenSIPS 3.4. + +This parameter was replaced by the [syslog_facility](#syslog_facility) parameter, preserving exactly the same format and behavior. + +### log_event_enabled + +Enables the E_CORE_LOG event for every log message generated by OpenSIPS. + +Default value is `false`. + +Example of usage: +```opensips + + log_event_enabled = true + +``` + +### log_event_level_filter + +Extra log level filtering for the E_CORE_LOG event. This parameter is useful when different verbosity levels are desired between syslog/standard error logs and the logs delivered through E_CORE_LOG. + +The `log_event_level_filter` parameter should be used together with the [log_level](#log_level) parameter, with a value lower than `log_level`. + +Default value is `0` (no filtering). + +Example of usage: +```opensips + + log_event_level_filter = 3 + +``` + +### log_json_buf_size + +Size of the buffer used for printing the JSON document corresponding to a log message. This parameter makes sense when the `json` or `json_cee` log formats are used. If the buffer is too small, the log message is truncated. + +Default value is `6144` bytes. + +Example of usage: +```opensips + + log_json_buf_size = 8192 # given in bytes + +``` + +### log_level + +Sets the logging level, controlling how verbose OpenSIPS should be. Higher values make **OpenSIPS** print more messages. + +Default value is `2` (notice level). + +Example of usage: +```opensips + + # print only important messages, such as errors or more critical situations; + # recommended for running a proxy as a daemon + log_level = 1 + + # print many debug messages; use only during debugging sessions + log_level = 4 + +``` + +Actual values are: +* `-3`: alert level +* `-2`: critical level +* `-1`: error level +* `1`: warning level +* `2`: notice level +* `3`: info level +* `4`: debug level + +The value of the `log_level` parameter can also be read and set dynamically using the [log_level](Interface-CoreMI.md#log_level) Core MI function or the [`$log_level`](Script-CoreVar.md#log_level) script variable. + +### log_msg_buf_size + +Size of the buffer used for printing the log message payload. This is used for printing the `message` field from a JSON document when the `json` or `json_cee` log formats are used, or when the E_CORE_LOG event is raised, if enabled. If the buffer is too small, the log message is truncated. + +Default value is `4096` bytes. + +Example of usage: +```opensips + + log_msg_buf_size = 8192 # given in bytes + +``` + +### log_name + +> [!WARNING] +> Replaced in OpenSIPS 3.4. + +This parameter was replaced by the [syslog_name](#syslog_name) parameter, preserving exactly the same format and behavior. + +### log_stdout + +Controls whether OpenSIPS preserves standard output. This may be useful when trying to extract logs from third-party libraries. + +* `false` (default): drop all standard output logs. +* `true`: let all standard output logs pass through. + +Default value is `false`. + +Example of usage: +```opensips + + log_stdout = true + +``` + +### log_stderror + +> [!WARNING] +> Deprecated in OpenSIPS 3.4. + +This parameter is deprecated. Starting with OpenSIPS 3.4, its behavior is equivalent to setting [stderror_enabled](#stderror_enabled) and [syslog_enabled](#syslog_enabled) as follows: +* `false`: `stderror_enabled = false`, `syslog_enabled = true`. +* `true` (default): `stderror_enabled = true`, `syslog_enabled = false`. + +Example of usage: + +```opensips +log_stderror = true +``` + +### log_prefix + +A string prefix prepended to all logs produced by OpenSIPS, from both C code and script `xlog()` statements. A non-empty value automatically gets a trailing `:`. + +Default value is `""`. + +Example of usage: +```opensips + + log_prefix = "opensips-backup" + +``` + +### max_while_loops + +Sets the maximum number of loop iterations allowed within a `while` statement. This protects against infinite loops during configuration script execution. + +Default value is `10000`. + +Example of usage: +```opensips + + max_while_loops = 200 + +``` + +### maxbuffer + +The maximum receive buffer size, in bytes, that OpenSIPS will accept during the auto-probing procedure used to discover the maximum buffer size for receiving UDP messages. + +Default value is `262144` bytes. + +Example of usage: +```opensips + + maxbuffer = 65536 + +``` + +### mem-group + +Defines a group of modules, by name, for separate memory statistics. OpenSIPS provides per-group memory information: number of allocated fragments, amount of used memory and amount of real used memory, including memory manager overhead. This is useful when monitoring memory usage for a specific module or group of modules. + +This feature requires running `make generate-mem-stats` and compiling with the `SHM_EXTRA_STATS` variable defined. + +Example of usage: +```opensips + + mem-group = "interest": "core" "tm" + mem-group = "runtime": "dialog" "usrloc" "tm" + +``` + +For the above example, the generated statistics are named `shmem_group_interest:fragments`, `shmem_group_interest:memory_used` and `shmem_group_interest:real_used`. + +Multiple groups can be defined, but they must not have the same name. + +To generate statistics for the default group, which includes all modules not included in another group, compile with the `SHM_SHOW_DEFAULT_GROUP` variable defined. + +### mem_warming + +Only relevant when the `HP_MALLOC` compile flag is enabled. If set to `true`, on each startup, OpenSIPS attempts to restore the memory fragmentation pattern it had before the stop/restart. If no [mem_warming_pattern_file](#mem_warming_pattern_file) from a previous run is found, memory warming is skipped and the memory allocator starts with a large memory chunk, like all other allocators. + +Memory warming is useful when dealing with high volumes of traffic, such as thousands of CPS on multi-core machines. The more cores are used, the more useful memory warming becomes, because processes must mutually exclude themselves when chopping up the initial large memory chunk. By performing fragmentation on startup, OpenSIPS also behaves optimally in the first minutes after a restart. Fragmentation usually lasts a few seconds, for example about 5 seconds on an 8GB shared memory pool and 4.1GHz CPU; traffic is not processed during this period. + +Default value is `false`. + +Example of usage: +```opensips + + mem_warming = true + +``` + +### mem_warming_percentage + +How much of OpenSIPS memory should be fragmented with the pattern of the previous run, upon restart. Used at startup if [mem_warming](#mem_warming) is enabled. + +Default value is `75`. + +Example of usage: +```opensips + + mem_warming_percentage = 50 + +``` + +### mem_warming_pattern_file + +Only relevant if [mem_warming](#mem_warming) is enabled. It contains the memory fragmentation pattern of a previous OpenSIPS run. This file is overwritten during each OpenSIPS shutdown and is used during startup in order to restore service behavior as soon as possible. + +Default value is `"CFG_DIR/mem_warming_pattern"`. + +Example of usage: +```opensips + + mem_warming_pattern_file = "/var/tmp/my_memory_pattern" + +``` + +### memdump | mem_dump + +Log level used to print memory status information at runtime and shutdown. It must be lower than the value of the [log_level](#log_level) parameter in order for memory information to be logged. + +Default value is `14` (`L_DBG + 10`), which effectively disables memory dump logging because it is above the normal debug log level. + +Example of usage: +```opensips + + memdump = 2 + +``` + +> [!NOTE] +> Setting [memlog](#memlog--mem_log) also sets `memdump` to the same value. If you want different values for `memlog` and `memdump`, set `memlog` first, then set `memdump`. + +### memlog | mem_log + +Log level used to print memory debug information. It must be lower than the value of the [log_level](#log_level) parameter in order for memory debug information to be logged. + +Default value is `15` (`L_DBG + 11`), which effectively disables memory debug logging because it is above the normal debug log level. + +Example of usage: +```opensips + + memlog = 2 + +``` + +> [!NOTE] +> Setting `memlog` automatically sets `memdump` to the same value. + +### mcast_loopback + +If set to `true`, multicast datagrams are sent over loopback. + +Default value is `false`. + +Example of usage: +```opensips + + mcast_loopback = true + +``` + +### mcast_ttl + +Sets the multicast TTL. + +Default value is OS-specific, usually `1`. + +Example of usage: +```opensips + + mcast_ttl = 32 + +``` + +### mhomed + +If set to `true`, OpenSIPS tries to locate the outbound interface on multihomed hosts. This lookup is time-consuming, so it is disabled by default. + +Default value is `false`. + +Example of usage: +```opensips + + mhomed = true + +``` + +### mpath + +Sets the module search path. This can be used to simplify `loadmodule` statements. + +Example of usage: +```opensips + + mpath = "/usr/local/lib/opensips/modules" + loadmodule "mysql.so" + loadmodule "uri.so" + loadmodule "uri_db.so" + loadmodule "sl.so" + loadmodule "tm.so" + ... + +``` + +The parameter can be set multiple times, with paths evaluated in declaration order. + +### open_files_limit + +If set and greater than the current open file limit, **OpenSIPS** tries to increase its open file limit to this number. **OpenSIPS** must be started as root in order to increase a limit past the hard limit, which is `1024` on most systems for open files. + +Default value is `-1` (do not change the open file limit). + +Example of usage: +```opensips + + open_files_limit = 2048 + +``` + +### poll_method + +The poll method used by the internal I/O reactor. By default, the best method for the current OS is selected. + +Available values are `poll`, `epoll`, `sigio_rt`, `select`, `kqueue` and `/dev/poll`. + +Example of usage: +```opensips + + poll_method = select + +``` + +### pv_print_buf_size + +The maximum size, in bytes, of an expanded formatted string containing variables or pseudo-variables. + +Default value is `20000` bytes. + +Example of usage: +```opensips + + pv_print_buf_size = 60000 + +``` + +### query_buffer_size + +If set to a value greater than `1`, DB inserts are not flushed one by one. Rows to be inserted are kept in memory until they gather up to `query_buffer_size` rows, and only then are they flushed to the database. + +Default value is `0` (buffering disabled). + +Example of usage: +```opensips + + query_buffer_size = 5 + +``` + +### query_flush_time + +If [query_buffer_size](#query_buffer_size) is set to a value greater than `1`, a timer triggers once every `query_flush_time` seconds, ensuring that no row is kept in memory for too long. + +Default value is `0`. + +Example of usage: +```opensips + + query_flush_time = 10 + +``` + +### restart_persistency_cache_file + +The name of the cache file used to store restart persistency memory. + +Default value is `".restart_persistency.cache"`. + +Example of usage: +```opensips + + restart_persistency_cache_file = "/var/tmp/opensips_restart.cache" + +``` + +### restart_persistency_size + +The size of the restart persistency cache file, in megabytes. If this parameter is not specified, it defaults to the size of the shared memory. + +Default value is the shared memory size, `32` MB by default. + +Example of usage: +```opensips + + restart_persistency_size = 64 + +``` + +### rev_dns + +Controls whether the SIP server should attempt to look up its own IP address in DNS. If this parameter is set to `true` and the IP address is not in DNS, a warning is printed to syslog and a `received=` field is added to the Via header. + +Default value is `false`. + +Example of usage: +```opensips + + rev_dns = true + +``` + +### server_header + +The body of the Server header field generated by **OpenSIPS** when it sends a reply as UAS. + +Default value is `"Server: OpenSIPS ( (/))"`. + +Example of usage: +```opensips + + server_header = "Server: My Company SIP Proxy" + +``` + +> [!NOTE] +> The value must include the header name, `Server:`. Otherwise, **OpenSIPS** writes only the configured body. + +### server_signature + +Controls whether the Server header is added to locally generated messages. + +Default value is `true`. + +Example of usage: +```opensips + + server_signature = false + +``` + +When enabled, the generated header looks like: +```opensips + + Server: OpenSIPS (4.0.0 (x86_64/linux)) + +``` + +### shm_hash_split_percentage + +Only relevant when the `HP_MALLOC` compile flag is enabled. It controls how many memory buckets are optimized. For example, setting it to `2` optimizes the first `2%` of the most frequently used buckets. + +Default value is `1`. + +Example of usage: +```opensips + + shm_hash_split_percentage = 2 + +``` + +### shm_memlog_size + +Configures the maximum number of shared memory operations to keep in the in-memory history. A separate memory block, dedicated to this shared memory debug information, is allocated. As a result, **OpenSIPS** uses more system memory than the configured shared memory pool, set with the `-m` command-line option. For example, `shm_memlog_size = 1000000` uses approximately 750 MB more memory. This option is intended for debugging. + +Default value is `0` (disabled). + +Example of usage: +```opensips + + shm_memlog_size = 1000000 + +``` + +### shm_secondary_hash_size + +Only relevant when the `HP_MALLOC` compile flag is enabled. It represents the optimization factor of a single bucket. For example, setting it to `4` causes optimized buckets to be further split into `4`. + +Default value is `8`. + +Example of usage: +```opensips + + shm_secondary_hash_size = 4 + +``` + +### sip_warning + +If set to `true`, a Warning header is added to each reply generated by **OpenSIPS**. The header contains details that help troubleshooting using network traffic dumps. + +Default value is `false`. + +Example of usage: +```opensips + + sip_warning = true + +``` + +### socket + +Sets the network addresses/sockets the OpenSIPS server should listen on. Its syntax is `protocol:address[:port|portrange]`, where: +* **protocol**: one of the transport modules loaded in the configuration file, such as `udp`, `tcp`, `tls`, `bin` or `hep`. +* **address**: an IP address, hostname, network interface name or the `*` wildcard, which makes OpenSIPS listen on all possible interfaces for that protocol. +* **port**: optional listening socket port; if absent, the default port exported by the transport module is used. +* **portrange**: optional set of ports that should listen for the same IP address. + +This parameter can be set multiple times in the same configuration file, with the server listening on all specified sockets. + +The `socket` definition may accept several optional parameters: +* `as ip[:port]`: configure an advertised IP and port only for this interface. Example: `as 11.24.14.14:5060`. +* `use_workers n`: set a different number of workers for this socket only, for UDP, SCTP and HEP_UDP interfaces. This overrides the global `udp_workers` parameter. +* `anycast`: mark the socket as an anycast IP. +* `use_auto_scaling_profile PROFILE`: enforce an auto-scaling profile for this UDP socket. This option is only available for UDP sockets, and the per-socket profile overrides the global UDP auto-scaling profile. +* `tag ID`: set a non-SIP name/tag for the socket, used when replicating socket identity across an OpenSIPS cluster. +* `frag`: do not use PMTU discovery to determine whether fragmentation should be done; always allow fragmentation. +* `reuse_port`: for TCP-based sockets only, allow outgoing TCP connections to reuse the listening port as the source port instead of using an ephemeral port. +* `tos n`: optional TOS value to use when sending SIP traffic through this interface. This overrides the global [tos](#tos) core parameter. +* `accept_subdomain`: also match subdomains of this SIP domain, when the socket is defined as an FQDN. + +These options only affect the sockets they are configured for; if they are not defined for a given socket, the global values are used instead. + +Example of usage: +```opensips + + socket = udp:* + socket = udp:eth1 + socket = tcp:eth1:5062 + socket = tls:localhost:5061 + socket = hep_udp:10.10.10.10:5064 + socket = ws:127.0.0.1:5060 use_workers 5 + socket = sctp:127.0.0.1:5060 as 99.88.44.33:5060 use_workers 3 + socket = udp:10.10.10.10:5060 anycast + socket = udp:10.10.10.10:5060 use_workers 4 use_auto_scaling_profile PROFILE_SIP + +``` + +On startup, OpenSIPS reports all sockets that it is listening on. + +### stderror_enabled + +Enables writing log messages to standard error. + +Default value is `true`. + +Example of usage: +```opensips + + stderror_enabled = false + +``` + +### stderror_level_filter + +Extra log level filtering for messages written to standard error. This parameter is useful when different verbosity levels are desired for syslog and standard error logging. + +The `stderror_level_filter` parameter should be used together with the [log_level](#log_level) parameter, with a value lower than `log_level`. + +Default value is `0` (no filtering). + +Example of usage: +```opensips + + stderror_level_filter = 2 + +``` + +### syslog_enabled + +Enables writing log messages to syslog. + +Default value is `false`. + +Example of usage: +```opensips + + syslog_enabled = true + +``` + +### stderror_log_format + +Format of the log messages printed to standard error. Possible values are: +* `plain_text`: standard plain-text log message. +* `json`: basic JSON document. +* `json_cee`: JSON document following the [CEE (Common Event Expression)](https://cee.mitre.org/language/1.0-beta1/core-profile.html) schema. + +Default value is `plain_text`. + +Example of usage: +```opensips + + stderror_log_format = "json" + +``` + +### syslog_facility + +If **OpenSIPS** logs to syslog, this parameter controls the syslog facility. It is useful when diverting all **OpenSIPS** logs to a different log file. See `syslog(3)` for more details. + +Default value is `LOG_DAEMON`. + +Example of usage: +```opensips + + syslog_facility = LOG_LOCAL0 + +``` + +### syslog_level_filter + +Extra log level filtering for messages sent to syslog. This parameter is useful when different verbosity levels are desired for syslog and standard error logging. + +The `syslog_level_filter` parameter should be used together with the [log_level](#log_level) parameter, with a value lower than `log_level`. + +Default value is `0` (no filtering). + +Example of usage: +```opensips + + syslog_level_filter = 1 + +``` + +### syslog_log_format + +Format of the log messages sent to syslog. Possible values are: +* `plain_text`: standard plain-text log message. +* `json`: basic JSON document. +* `json_cee`: JSON document following the [CEE (Common Event Expression)](https://cee.mitre.org/language/1.0-beta1/core-profile.html) schema. + +Default value is `plain_text`. + +Example of usage: +```opensips + + syslog_log_format = "json" + +``` + +### syslog_name + +Sets the identifier printed in syslog. The value must be a string and has effect only when **OpenSIPS** runs in daemon mode, after daemonizing. + +Default value is `argv[0]`. + +Example of usage: +```opensips + + syslog_name = "osips-5070" + +``` + +### tcp_workers + +Number of worker processes created for reading from TCP connections. These workers handle traffic over any TCP-based protocol, such as SIP-TCP, SIP-TLS, SIP-WS, SIP-WSS, BIN or HEP. + +Default value is `8`. + +Optionally, you can define an auto-scaling profile to dynamically govern the number of TCP workers by creating or terminating processes depending on load. See [auto_scaling_profile](#auto_scaling_profile) for more details. + +Example of usage: +```opensips + + tcp_workers = 4 + tcp_workers = 3 use_auto_scaling_profile PROFILE_SIP + +``` + +### tcp_accept_aliases + +If set to `true`, OpenSIPS enforces RFC 5923 behavior when detecting an `;alias` Via header field parameter, and reuses any TCP, TLS, WS or WSS connection opened for such SIP requests when sending other SIP requests backwards towards the same source IP, Via port and protocol tuple. The purpose of RFC 5923 is to minimize the number of TLS connections a SIP proxy must open, due to the large CPU overhead of connection setup. + +Default value is `false`. + +On top of RFC 5923 connection reuse, TCP connections in OpenSIPS are also persistent across multiple SIP dialogs. This can be controlled with the [tcp_connection_lifetime](#tcp_connection_lifetime) global parameter. + +> [!WARNING] +> Enabling the global `tcp_accept_aliases` parameter for end-user initiated connections, which are most likely grouped by one or more public IPs, is an open vector for call hijacking. In such platforms, use the [force_tcp_alias()](https://docs.opensips.org/manual/3-6/script-corefunctions#force_tcp_alias) core function to employ RFC 5923 behavior only with adjacent SIP proxies. + +Example of usage: +```opensips + + tcp_accept_aliases = true + +``` + +### tcp_connect_timeout + +Time in milliseconds before an ongoing blocking connection attempt is aborted. + +Default value is `100` milliseconds. + +Example of usage: +```opensips + + tcp_connect_timeout = 100 + +``` + +### tcp_connection_lifetime + +Lifetime in seconds for TCP sessions. TCP sessions inactive for more than `tcp_connection_lifetime` seconds are closed by **OpenSIPS**. Setting this value to `0` closes TCP connections quickly. You can also set the TCP lifetime to the expire value of the REGISTER by using the `tcp_persistent_flag` parameter of the registrar module. + +Default value is `120` seconds. + +Example of usage: +```opensips + + tcp_connection_lifetime = 3600 + +``` + +### tcp_max_connections + +Maximum number of active TCP accepted connections, meaning connections initiated by remote endpoints. Once the limit is reached, new incoming TCP connections are rejected. There is currently no limit for outgoing TCP connections initiated by OpenSIPS. + +Default value is `2048`. + +Example of usage: +```opensips + + tcp_max_connections = 4096 + +``` + +### tcp_max_msg_time + +The maximum number of seconds that a SIP message is expected to take to fully arrive over TCP. If a single SIP packet is still not fully received after this number of seconds, the connection is dropped. This may happen when the connection is overloaded and traffic is highly fragmented, or during attacks that intentionally fragment traffic in order to reduce performance. + +Default value is `4` seconds. + +Example of usage: +```opensips + + tcp_max_msg_time = 8 + +``` + +### tcp_no_new_conn_bflag + +A branch flag used to instruct OpenSIPS not to open a new TCP connection when delivering a request, but only to reuse an existing one, if available. If no existing connection is available, a generic send error is returned. + +This is intended for NAT scenarios where opening a TCP connection towards a destination behind NAT makes no sense, for example when the TCP connection created during registration was lost and the device cannot be contacted until it re-registers. It can also be used to detect when a NATed registered user lost its TCP connection, so OpenSIPS can disable that registration as unusable. + +Example of usage: +```opensips + + tcp_no_new_conn_bflag = TCP_NO_CONNECT + ... + route { + ... + if (isflagset("DST_NATED") && $socket_in(proto) == "TCP") + setbflag("TCP_NO_CONNECT"); + ... + t_relay("no-auto-477"); + $var(retcode) = $rc; + if ($var(retcode) == -6) { + # send error + xlog("unable to send request to destination"); + send_reply(404, "Not Found"); + exit; + } else if ($var(retcode) < 0) { + sl_reply_error(); + exit; + } + } + +``` + +### tcp_no_new_conn_rplflag + +A message flag, similar to [tcp_no_new_conn_bflag](#tcp_no_new_conn_bflag), used to prevent OpenSIPS from opening a new TCP connection when sending back a reply for the current request. If no existing connection is available, sending the reply may fail at transport level. + +Example of usage: +```opensips + + tcp_no_new_conn_rplflag = TCP_NO_RPL_CONNECT + ... + route { + ... + # if source is detected as NATed, prevent opening TCP connections for replies + if (isflagset("SRC_NATED") && $socket_in(proto) == "TCP") + setflag("TCP_NO_RPL_CONNECT"); + ... + t_reply(302, "Redirected"); + } + +``` + +### tcp_socket_backlog + +The maximum length to which the queue of pending connections for TCP listening sockets may grow. If a connection request arrives when the queue is full, the client may receive an error such as `ECONNREFUSED`; if the underlying protocol supports retransmission, the request may be ignored so a later connection attempt can succeed. + +Default value is `10`. + +Example of usage: +```opensips + + tcp_socket_backlog = 20 + +``` + +### tcp_threshold + +A number representing the maximum number of microseconds sending a TCP request is expected to take. Anything above the set number triggers a warning message to the logging facility. + +Default value is `0` (logging disabled). + +Example of usage: +```opensips + + tcp_threshold = 60000 + +``` + +### tcp_keepalive + +Enables or disables TCP keepalive at OS level. + +Default value is `true` if TCP keepalive is supported by the OS, `false` otherwise. + +Example of usage: +```opensips + + tcp_keepalive = true + +``` + +### tcp_keepcount + +Number of keepalive probes to send before closing the connection. This option is available on Linux and other platforms with `TCP_KEEPCNT` support. The OS default can usually be found using `cat /proc/sys/net/ipv4/tcp_keepalive_probes`; a common value is `9`. + +Default value is OS-dependent. + +Setting `tcp_keepcount` to any value also enables [tcp_keepalive](#tcp_keepalive). + +Example of usage: +```opensips + + tcp_keepcount = 5 + +``` + +### tcp_keepidle + +Amount of idle time, in seconds, before OpenSIPS starts sending keepalive probes. This option is available on Linux and other platforms with `TCP_KEEPIDLE` support. The OS default can usually be found using `cat /proc/sys/net/ipv4/tcp_keepalive_time`; a common value is `7200` seconds. + +Default value is OS-dependent. + +Setting `tcp_keepidle` to any value also enables [tcp_keepalive](#tcp_keepalive). + +Example of usage: +```opensips + + tcp_keepidle = 30 + +``` + +### tcp_keepinterval + +Interval, in seconds, between keepalive probes when the previous probe failed. This option is available on Linux and other platforms with `TCP_KEEPINTVL` support. The OS default can usually be found using `cat /proc/sys/net/ipv4/tcp_keepalive_intvl`; a common value is `75` seconds. + +Default value is OS-dependent. + +Setting `tcp_keepinterval` to any value also enables [tcp_keepalive](#tcp_keepalive). + +Example of usage: +```opensips + + tcp_keepinterval = 10 + +``` + +### timer_workers + +The number of worker processes created exclusively for timer-related tasks. The minimum number is `1`. + +Default value is `1`. + +Optionally, you can define an auto-scaling profile to dynamically govern the number of timer workers by creating or terminating processes depending on load. See [auto_scaling_profile](#auto_scaling_profile) for more details. + +Example of usage: +```opensips + + timer_workers = 3 + timer_workers = 3 use_auto_scaling_profile PROFILE_TIMER + +``` + +### tos + +The TOS (Type Of Service) to be used for the sent IP packets, for both TCP and UDP. The default value is `IPTOS_LOWDELAY`. To disable TOS setting, use `0`. + +This global value may be overwritten by the per-socket `tos` option of the [socket](#socket) parameter. + +Example of usage: + +```opensips +tos = IPTOS_LOWDELAY +tos = 0x10 +``` + +### udp_workers + +Number of worker processes to be created for each UDP or SCTP interface. The default value is `8`. + +Optionally, you can define an auto-scaling profile to dynamically govern the number of UDP workers by creating or terminating processes depending on load. A per-interface auto-scaling profile overrides this global UDP auto-scaling profile. +See the [auto_scaling_profile](#auto_scaling_profile) parameter for more details. + +Example of usage: + +```opensips +udp_workers = 16 +udp_workers = 4 use_auto_scaling_profile PROFILE_SIP +``` + +> [!NOTE] +> This global value applies to all UDP/SCTP interfaces, but it can be overridden by setting a different number of workers in a specific interface definition. This allows defining a different number of workers for each interface; see the [socket](#socket) parameter for syntax. + +### user_agent_header + +The body of the User-Agent header field generated by **OpenSIPS** when it sends a request as UAC. It defaults to `OpenSIPS ( (/))`. + +Example of usage: + +```opensips +user_agent_header = "User-Agent: My Company SIP Proxy" +``` + +Please note that you have to include the `User-Agent:` header name, as **OpenSIPS** does not add it. Otherwise, you will get an erroneous header like: + +```opensips +My Company SIP Proxy +``` + +### wdir + +The working directory used by **OpenSIPS** at runtime. If not explicitly configured, **OpenSIPS** changes the working directory to `/`. + +Example of usage: + +```opensips +wdir = "/usr/local/opensips" +wdir = /usr/opensips_wd +``` + +### xlog_buf_size + +Size of the buffer used to print a single line through the selected **OpenSIPS** logging facility. If the buffer is too small, an overflow error will be printed and the line will be skipped. The default value is `4096` bytes. + +Usage example: + +```opensips +xlog_buf_size = 8388608 # given in bytes +``` + +### xlog_force_color + +Enables the use of [$C(xy)](Script-CoreVar.md#foreground-and-background-colors) color escape sequences in [xlog()](https://docs.opensips.org/manual/3-6/script-corefunctions#xlog). Otherwise, color escape sequences have no effect. The default value is `false`. + +Usage example: + +```opensips +xlog_force_color = true +``` + +### xlog_level + +Similar to [log_level](#log_level), this parameter independently controls the verbosity of the [xlog()](https://docs.opensips.org/manual/3-6/script-corefunctions#xlog) functions. This allows you to separately control the verbosity level for logs generated by code and logs generated by `xlog()`. The default value is `2` / `L_NOTICE`. + +Usage example: + +```opensips +xlog_level = 3 # L_DBG +``` + +### xlog_print_level + +Default level for printing logs generated by the [xlog()](https://docs.opensips.org/manual/3-6/script-corefunctions#xlog) core function when the `log_level` parameter is omitted. The default value is `2` / `L_NOTICE`. + +Usage example: + +```opensips +xlog_print_level = 2 # L_NOTICE +``` diff --git a/docs/manual/Script-CoreVar.md b/docs/manual/Script-CoreVar.md new file mode 100644 index 00000000000..e9db74d4d3f --- /dev/null +++ b/docs/manual/Script-CoreVar.md @@ -0,0 +1,1034 @@ +--- +title: "Core Variables" +description: "The OpenSIPS variables can be easily identified in the script as all their names (or notations) start with the $ sign." +--- + +**OpenSIPS** provides multiple types of variables to be used in the routing script. The difference between the types of variables comes from: +* *its context* - a variable is attached to a context, like the context of a SIP message, of a SIP transaction or dialog. The variable will be visible all the time within that context (across all the script routes where the context is present) +* *read-write status* - some types of variables are read-only +* *number of values* - some variables may keep multiple values at the same time + +The **OpenSIPS** variables can be easily identified in the script as all their names (or notations) start with the **$** sign. + +Syntax: + +The complete syntax for a pseudo variable is: +`$(`*``*`name`*`(subname)[index]{transformation}`*`)` + +The fields written in italics are optional. +The fields meaning is: +* **name**(mandatory) - the pseudo-variable name(type). +Ex: var, avp, ru, DLG_status, etc. +* **subname** - the identifier of a certain pv of a given type. +Ex: hdr(From), avp(name). +* **index** - a pv can store more than one value - it can refer to a list of values. You can access a certain value from the list if you specify its index. You can also specify indexes with negative values, -1 means the last inserted, -2 the value before the previous inserted one. +* **transformation** - a series of processing actions can be applied on pseudo-variable. You can find the whole list of possible transformations [here](Script-Tran.md). The transformations can be cascaded, using the output of one transformation as the input of another. +* **context** - the context in which the pseudo0variable will be evaluated. Now there are 2 pv contexts: reply and request. The reply context can be used in the failure route to request for the pseudo-variable to be evaluated in the context of the reply message. The request context can be used if in a reply route is desired for the pv to be evaluated in the context of the corresponding request. + +Usage examples: +* Only **name**: `$ru` +* **Name** and *'subname*: `$hdr(Contact)` +* **Name** and **index**: `$(ct[0])` +* **Name**, **subname** and **index**: `$(avp(caller_dids)[2])` +* **Context** + * `$(ru)` from a reply route will get the Request-URI from the request + * `$(hdr(Contact))` context can be used from failure route to access information from the reply + +Types of variables: + +* [**script variables**](#script_variables) - as the name says, these variables are strictly bound to the script routes. + +* [**AVP - Attribute Value Pair**](#avp_variables) - the AVPs are dynamic variables (as name) that can be created and attached to a SIP message or transaction (if stateful processing is used). So, you may see them as transaction level variables. + +* [**reference variables**](#reference_variables) - variables to provide access to information from the current context - the current SIP message, transaction, dialog, or from the current process (non SIP information). + +* [**escape sequences**](#escape_sequences) - escape sequences used to format the strings; they are actually not variables, but rather formatters. + + + +## Script variables + +**Naming**: `$var(name)` + +These variables are attached to the script, being persistent to the whole execution of a top route (including all its sub-routes). Once the execution of the top route ended, the script variables are lost, not to be used again. Also, be careful and initialize them when used for the first time (in a top route) as you may inherite garbage. +Script variables are read write and they can have integer or string values. +A script variable can only hold a single value. A new assignment (or write operation) will overwrite the existing value. + + +**Hints**: +* if you want to start using a script variable in a route, better initialize it with same value (or reset it), otherwise you may inherit a value from a previous route that was executed by the same process. +* a script variable can only hold one value. + +Example of usage: + +```opensips + +$var(a) = 2; # sets the value of variable 'a' to integer '2' +$var(a) = "2"; # sets the value of variable 'a' to string '2' +$var(a) = 3 + (7&(~2)); # arithmetic and bitwise operation +$var(a) = "sip:" + $au + "@" + $fd; # compose a value from authentication username and From URI domain + +# using a script variable for tests +if( [ $var(a) & 4 ] ) { + xlog("var a has third bit set\n"); +} + +``` + + +## AVP variables + +**Naming**: `$avp(name)` or `$(avp(name)[N])` + +A message or a transaction will initially (when received or created) have an empty list of AVPS attached to it. During the routing script, the script directly or functions called from script may create new AVPS that will automatically attached to the message/transaction. The AVPS will be visible in all routes where any message (reply or request) of the transaction will be processed - `branch_route` , `failure_route`, `onreply_route` (for this last route you need to enable the TM parameter *onreply_avp_mode*). +AVPs are read write and an existing AVP can be even deleted (removed). +An AVP may contain multiple values - a new assignment (or write operation) will add a new value to the AVP; the values are kept in "last added first to be used" order (stack). + +When using the index "N" you can force the AVP to return a certain value (the N-th value). If no index is given, the first value will be returned. +A special index **append** is defined to allow you to add a new value at the end of the list (at the bottom of the stack) - `$(avp(name)[append])` = "last value"; + + +**Hints**: +* to enable AVPs in onreply_route, use "modparam("tm", "onreply_avp_mode", 1)" +* if multiple values are used for a single AVP, the values are index in revert order than added +* AVPs are part of the transaction context, so they will be visible everywhere where the transaction is present. +* the value of an AVP can be deleted + +Example of usage: +* Transaction persistence example +```opensips + +# enable avps in onreply route +modparam("tm", "onreply_avp_mode", 1) +... +route{ +... +$avp(tmp) = $Ts ; # store the current time (at request processing) +... +t_onreply("handle_reply"); +t_relay(); +... +} + +onreply_route[handle_reply] { + if (t_check_status("200")) { + # calculate the setup time + $var(setup_time) = $Ts - $avp(tmp); + } +} + +``` + +* Multiple values example +```opensips + +$avp(demo) = "one"; +# we have a single value + +$avp(demo) = "two"; +# we have two values ("two","one") + +$avp(demo) = "three"; +# we have three values ("three","two","one") + +xlog("accessing values with no index: $avp(demo)\n"); +# this will print the first value, which is the last added value -> "three" + +xlog("accessing values with no index: $(avp(demo)[2])\n"); +# this will print the index 2 value (third one), -> "one" + +# remove the first value of the avp (lastly added one); if there is only one value, the AVP itself will be destroyed +$avp(demo) = NULL; + +# delete all values and destroy the AVP +$avp(demo) := NULL; + +# delete the value located at a certain index +$(avp(demo)[1]) = NULL; + +# overwrite the value at a certain index +$(avp(demo)[0]) = "zero"; + +``` + + + +## Reference Variables + +**Naming**: `$name` + +They provide access to information from the SIP message/transaction/dialog or OpenSIPS internals. +For example, a reference variable may allow access to the processed SIP message (headers, RURI, transport level info, and so on) or from **OpenSIPS** internals (time values, process PID, return code of a function). Depending of what info they provide, the PVs are either bound to the message, either to nothing (global). +Most of the reference variables are read-only and only several allow write operations. The reference variables may return several values or only one, depending of the referred info (if can have multiple values or not). +Standard reference variables are read-only and return a single value (if not otherwise documented). + +**Hints**: +* most of reference variables are made available by **OpenSIPS** core, but there are also module exporting such variables (to make available info specific to that module) - check the modules documentation. +* the reference variables are also known as *pseudo-variables* or *PV*. This is an old terminology. + +Predefined (provided by core) PVs are listed in alphabetical order: + +### URI in SIP Request's P-Asserted-Identity header - $ai + +`$ai` - reference to URI in request's P-Asserted-Identity header (see RFC 3325) + +### Authentication Digest URI - $adu + +`$adu` - URI from Authorization or Proxy-Authorization header. This URI is used when calculating the HTTP Digest Response. + +### Authentication realm - $ar + +`$ar` - realm from Authorization or Proxy-Authorization header + +### Auth username user - $au + +`$au` - user part of username from Authorization or Proxy-Authorization header + +### Auth username domain - $ad + +`$ad` - domain part of username from Authorization or Proxy-Authorization header + +### Auth nonce - $an + +`$an` - the nonce from Authorization or Proxy-Authorization header + +### Auth response - $auth.resp + +`$auth.resp` - the authentication response from Authorization or Proxy-Authorization header + +### Auth nonce - $auth.nonce + +`$auth.nonce` - the nonce string from Authorization or Proxy-Authorization header + +### Auth cnonce - $auth.cnonce + +`$auth.cnonce` - the client nonce string from Authorization or Proxy-Authorization header + +### Auth opaque - $auth.opaque + +`$auth.opaque` - the opaque string from Authorization or Proxy-Authorization header + +### Auth algorithm - $auth.alg + +`$auth.alg` - the algorithm string from Authorization or Proxy-Authorization header + +### Auth QOP - $auth.qop + +`$auth.qop` - the value of qop parameter from Authorization or Proxy-Authorization header + +### Auth nonce count (nc) - $auth.nc + +`$auth.nc` - the value of nonce count parameter from Authorization or Proxy-Authorization header + +### Auth whole username - $aU + +`$aU` - whole username from Authorization or Proxy-Authorization header + +### Acc username - $Au + +`$Au` - username for accounting purposes. It's a selective pseudo variable (inherited from acc module). It returns `$au` if it exists or From username otherwise. + +### Argument options - $argv + +`$argv` - provides access to command line arguments specified with '-o' option. +Examples: +```opensips + + # for option '-o foo=0' + xlog("foo is $argv(foo) \n"); + +``` + +### Authorize Challenge Algorithm - $challenge.algorithm + +`$challenge.algorithm` - the algorithm value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge Realm - $challenge.realm + +`$challenge.realm` - the realm value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge Nonce - $challenge.nonce + +`$challenge.nonce` - the nonce value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge Opaque - $challenge.opaque + +`$challenge.opaque` - the opaque value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge QOP - $challenge.qop + +`$challenge.qop` - the qop value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge IK - $challenge.ik + +`$challenge.ik` - the ik value taken from the WWW-Authorize or Proxy-Authorize header. + +### Authorize Challenge CK - $challenge.ck + +`$challenge.ck` - the ck value taken from the WWW-Authorize or Proxy-Authorize header. + +### Call-Id - $ci + +`$ci` - reference to body of call-id header + +### Content-Length - $cl + +`$cl` - reference to body of content-length header + +### CSeq number - $cs + +`$cs` - reference to cseq number from cseq header + +### Contact instance - $ct + +`$ct` - reference to contact instance/body from the contact header. A contact instance is display_name + URI + contact_params. As a Contact header may contain multiple Contact instances and a message may contain multiple Contact headers, an index was added to the `$ct` variable: +* `$ct` -first contact instance from message +* `$(ct[n])` - the n-th contact instance form the beginning of message, starting with index 0 +* `$(ct[-n])` - the n-th contact instance form the end of the message, starting with index -1 (the last contact instance) + +### Fields of a contact instance - $ct.fields(field) + +`$ct.fields()` - reference to the fields of a contact instance/body (see above). Supported fields are: +* name - display name +* uri - contact uri +* q - q param (value only) +* expires - expires param (value only) +* methods - methods param (value only) +* received - received param (value only) +* params - all params (including names) + +Examples: +* `$ct.fields(uri)` - the URI of the first contact instance +* `$(ct.fields(name)[1])` - the display name of the second contact instance + +### Content-Type - $cT + +`$cT` - reference to body of Content-Type header and also the content-type headers inside a multi-part body +* `$cT` - the main Content-Type of the message; the one inside the headers +* `$(cT[n])` - the **n**-th Content-Type inside a multi-part body from the beginning of message, starting with index 0 +* `$(cT[-n])` - the **n**-th Content-Type inside a multi-part body from the end of the message, starting with index -1 (the last contact instance) +* `$(cT[*])` - all the Content-Type headers including the main one and the ones from the multi-part body + +### Domain of destination URI - $dd + +`$dd` - reference to domain of destination uri + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it from routing logic) + + +### Diversion header URI - $di + +`$di` - reference to Diversion header URI + +### Diversion "privacy" parameter - $dip + +`$dip` - reference to Diversion header "privacy" parameter value + +### Diversion "reason" parameter - $dir + +`$dir` - reference to Diversion header "reason" parameter value + +### Port of destination URI - $dp + +`$dp` - reference to port of destination uri + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it from routing logic) + + +### Transport protocol of destination URI - $dP + +`$dP` - reference to transport protocol of destination uri + +### Destination set - $ds + +`$ds` - reference to destination set + +### Destination URI - $du + +`$du` - reference to destination uri (outbound proxy to be used for sending the request) +If loose_route() returns TRUE a destination uri is set according to the first Route header. + +Alias: `$duri` + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it from routing logic) + + +### Error class - $err.class + +`$err.class` - the class of error (now is '1' for parsing errors) + +### Error level - $err.level + +`$err.level` - severity level for the error + +### Error info - $err.info + +`$err.info` - text describing the error + +### Error reply code - $err.rcode + +`$err.rcode` - recommended reply code + +### Error reply reason - $err.rreason + +`$err.rreason` - recommended reply reason phrase + +### From URI domain - $fd + +`$fd` - reference to domain in URI of 'From' header + +Alias: `$from.domain` + +### From display name - $fn + +`$fn` - reference to display name of 'From' header + +### From tag - $ft + +`$ft` - reference to tag parameter of 'From' header + +### From URI - $fu + +`$fu` - reference to URI of 'From' header + +Alias: `$from` + +### From URI username - $fU + +`$fU` - reference to username in URI of 'From' header + +Alias: `$from.user` + +### OpenSIPS Log level - $log_level + +`$log_level` - changes the log level for the current process ; the log level can be set to a new value (see [possible values](Script-CoreParameters.md#log_level) or it can be reset back to the global log level. +This function is very helpful if you are tracing and debugging only a specific piece of code. + +Example of usage: + +```opensips +log_level= -1 # errors only +..... +{ +...... +$log_level = 4; # set the debug level of the current process to DBG +uac_replace_from(....); +$log_level = NULL; # reset the log level of the current process to its default level +....... +} +``` + +### SIP message buffer - $mb + +`$mb` - reference to SIP message buffer + +### Message Flags - $mf + +`$mf` - displays a list with the message/transaction flags set for the current SIP request + +### SIP message ID - $mi + +`$mi` - reference to SIP message id + +### SIP message length - $ml + +`$ml` - reference to SIP message length + +### Message branch - $msg.branch + +`$msg.branch` - similar to [`$branch`](#branch), this variable is used for creating new message branches by writing into it the value of a SIP URI. By reading this variable, you get the SIP URI of the current/last added branch (or of the RURI branch if no additional branch was added so far). +```opensips + + # creates a new branch + $msg.branch = "sip:new@domain.org"; + # print its URI + xlog("last added branch has URI $msg.branch \n"); + +``` + +### SIP URI of a message branch - $msg.branch.uri + +`$msg.branch.uri` - gives read / write access over the SIP URI (as string) of an existing message branch. The message branches are created via [append_msg_branch()](Script-CoreFunctions.md#append_branch) core function or by various modules (like "registrar" module). The message branches are consumed by the TM "t_relay()" function (they are converted to TM branches). + +The variable supports indexing - it starts from 0, meaning the RURI (or message) branch. The newly added branches will start from 1. So the branch 0 exists all +the time, there is no need to create it. If no index is specified, the current/last added branch (or of the RURI branch if no additional branch was added so far) will be considered. Negative values are also accepted, meaning indexing from the last branch ( -1 is the latest/higher branch) to the RURI branch. An ***** / ALL index will return the comma separated list with the values from all branches. + +The variable can be used in REQUEST and FAILURE routes. +```opensips + + # creates a new branch + $msg.branch = "sip:new@domain.org"; + # change its URI + $msg.branch.uri = "sip:new_new@domain.org" + # change its URI of RURI branch + $(msg.branch.uri[0]) = "sip:new_RURI@domain.org" + +``` + +### Destination URI of a message branch - $msg.branch.duri + +`$msg.branch.duri` - 100% similar to [`$msg.branch.uri`](#msg.branch.uri), but operating with the Destination-URI value of the message branch. + +### PATH of a message branch - $msg.branch.path + +`$msg.branch.path` - 100% similar to [`$msg.branch.uri`](#msg.branch.uri), but operating with the PATH value of the message branch. + +### Q of a message branch - $msg.branch.q + +`$msg.branch.q` - 100% similar to [`$msg.branch.uri`](#msg.branch.uri), but operating with the Q value of the message branch. + +### Flags of a message branch - $msg.branch.flags + +`$msg.branch.flags` - 100% similar to [`$msg.branch.uri`](#msg.branch.uri), but operating with list (comma separated) of per-branch flags (which are set for the branch). + +### SIP socket of a message branch - $msg.branch.socket + +`$msg.branch.socket` - 100% similar to [`$msg.branch.uri`](#msg.branch.uri), but operating with the (forced) socket value of the message branch. + +### A flag of a message branch - $msg.branch.flag() + +`$msg.branch.flag()` - similar to [`$msg.branch.uri`](#msg.branch.uri), but operating over a single branch flag (for the current branch). + +The accepted values are 0 for FALSE, positive non-zero for TRUE. The returned values are 0 for FALSE and 1 for TRUE. + +> [!NOTE] +> the */ALL index cannot be used here. + +```opensips + + # creates a new branch + $msg.branch = "sip:new@domain.org"; + # set the "pstn" named flag for this branch + $msg.branch.flag(pstn) = 1; + $msg.branch.flag(foo) = 1; + # print all the set flags + xlog("Flags are <$msg.branch.flags>\n"); + +``` + +### An attribute of a message branch - $msg.branch.attr() + +`$msg.branch.attr()` - similar to [`$msg.branch.uri`](#msg.branch.uri), but operating over a single branch attribute (attached to the current branch). + +An attribute can have whatever name (no need to be pre-defined) and it can have a single value (at a time), string or integer. + +> [!NOTE] +> the */ALL index cannot be used here. + +```opensips + + # creates a new branch + $msg.branch = "sip:new@domain.org"; + # set the "pstn" named flag for this branch + $msg.branch.attr(name) = "one"; + $msg.branch.attr(num) = 5; + +``` + +### Index of the last message branch - $msg.branch.last_idx + +`$msg.branch.last_idx` - returns the index of the last message branch. IF no additional branches were added, it will return 0, the index of the RURI branch. Then the returned value will get incremented with each append_msg_branch(). + +### Message flag - $msg.flag + +`$msg.flag(flag_name)` - this variable provides read/write access to the value of a single certain message flag (identified by name). The values accepted for writing are 1 (set) and 0 (unset). The returned values are 1/"true" (set) and 0/"false" (unset). +```opensips + + setflag("X"); + xlog("---- flag value is $msg.flag(X) \n"); + $msg.flag(X) = off; + xlog("---- flag value is $msg.flag(X) \n"); + +``` + +### Message is request - $msg.is_request + +`$msg.is_request` - this variable tells if the current SIP message is a request or not. The returned values are 1/"true" (request) and 0/"false" (reply). +```opensips + + xlog("---- this message is a request: $msg.is_request \n"); + if ( $msg.is_request ) + xlog("---- yes, it is a request\n"); + +``` + +### Message type - $msg.type + +`$msg.type` - this variable returns the type of the current message. The returned values are "request" (request) or "reply" (reply). +```opensips + + xlog("---- this message is a SIP $msg.type \n"); + +``` + +### Domain in SIP Request's original URI - $od + +`$od` - reference to domain in request's original R-URI + +### Port of SIP request's original URI - $op + +`$op` - reference to port of original R-URI + +### Transport protocol of SIP request original URI - $oP + +`$oP` - reference to transport protocol of original R-URI + +### SIP Request's original URI - $ou + +`$ou` - reference to request's original URI + +Alias: `$ouri` + +### Username in SIP Request's original URI - $oU + +`$oU` - reference to username in request's original URI + +### Path header - $path + +`$path` - reference to the Path header body. + +### Route parameter - $param +`$param(idx)` - retrieves the parameters of the route. The index can be an integer, or a pseudo-variable (index starts at 1). + +Example: +```opensips + + route { + ... + $var(debug) = "DBUG:" + route(PRINT_VAR, $var(debug), "param value"); + ... + } + + route[PRINT_VAR] { + $var(index) = 2; + xlog("$param(1): The parameter value is <$param($var(index))>\n"); + } + +``` + +### Domain in SIP Request's P-Preferred-Identity header URI - $pd + +`$pd` - reference to domain in request's P-Preferred-Identity header URI (see RFC 3325) + +### Display Name in SIP Request's P-Preferred-Identity header - $pn + +`$pn` - reference to Display Name in request's P-Preferred-Identity header (see RFC 3325) + +### Process id - $pp + +`$pp` - reference to process id (pid) + +### User in SIP Request's P-Preferred-Identity header URI - $pU + +`$pU` - reference to user in request's P-Preferred-Identity header URI (see RFC 3325) + +### URI in SIP Request's P-Preferred-Identity header - $pu + +`$pu` - reference to URI in request's P-Preferred-Identity header (see RFC 3325) + +### Domain in SIP Request's URI - $rd + +`$rd` - reference to domain in request's URI + +Alias: `$ruri.domain` + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it routing script) + + +### Body of request/reply - $rb + +`$rb` - reference to the body or a body part of the SIP message +* `$rb` - the whole body of the message (with all the parts) +* `$(rb[*])` - same as `$rb` +* `$(rb[n])` - the n-th body belonging to a multi-part body from the beginning of message, starting with index 0 +* `$(rb[-n])` - the n-th body belonging to a multi-part body from the end of the message, starting with index -1 (the last contact instance) +* `$rb(application/sdp)` - get the first SDP body part +* `$(rb(application/isup)[-1])` - get the last ISUP body part + +### Returned code - $rc + +`$rc` - reference to returned code by last invoked function + +`$retcode` - same as `$rc` + +### Remote-Party-ID header URI - $re + +`$re` - reference to Remote-Party-ID header URI + +### Return value - $return + +`$return` - Returns the value of the previously executed route. + +The variable receives an index, starting with 0, indicating the return value that needs to be read. + +### SIP request's method - $rm + +`$rm` - reference to request's method + +### SIP request's port - $rp + +`$rp` - reference to port of R-URI + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it routing script) + + +### Transport protocol of SIP request URI - $rP + +`$rP` - reference to transport protocol of R-URI + +### SIP reply's reason - $rr + +`$rr` - reference to reply's reason + +### SIP reply's status - $rs + +`$rs` - reference to reply's status + +### Refer-to URI - $rt + +`$rt` - reference to URI of refer-to header + +### SIP Request's URI - $ru + +`$ru` - reference to request's URI + +Alias: `$ruri` + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it routing script) + + +### Username in SIP Request's URI - $rU + +`$rU` - reference to username in request's URI + +Alias: `$ruri.user` + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it routing script) + + +### Q value of the SIP Request's URI - $ru_q + +`$ru_q` - reference to q value of the R-URI + +> [!IMPORTANT] +> It is R/W variable (you can assign values to it routing script) + + +### SDP body - $sdp + +`$sdp` - Read/Write reference to the SDP body of the current SIP message + +```opensips + +# READ operation on the SIP msg SDP +$sdp + +# WRITE operation (assign a new SDP) +$sdp = $var(rtpengine_sdp); + +# READ operation on the SIP reply SDP +$(sdp) + +# WRITE operation (assign a new SDP to SIP reply) +$(sdp) = $var(rtpengine_sdp); + +``` + +### SDP body line - $sdp.line + +`$sdp.line` - Read/Write reference to SDP body lines, with filtering support + +```opensips + +# Fetch the 1st, 2nd, 3rd, etc. attribute line (starting with "a=") +$sdp.line(a=) # fetch first "a=" line +$sdp.line(a=[0]) # equivalent, "a=" line at index 0 +$sdp.line(a=ptime[1]) # "a=ptime" line at index 1 +$sdp.line(a=[100]) # will likely yield NULL + +# Token-based filtering, inside a line +$sdp.line(m=audio[1]) # m=audio 27292 RTP/AVP 9 8 0 2 102 100 99 101 +$sdp.line(m=audio[1]/[0]) # audio +$sdp.line(m=audio[1]/[1]) # 27292 +$sdp.line(m=audio[1]/[2]) # RTP/AVP +$sdp.line(m=audio[1]/[10]) # 101 +$sdp.line(m=audio[1]/[11]) # NULL +$sdp.line(m=audio[1]/RTP) # RTP/AVP +$sdp.line(m=audio[1]/RTP\/AVP) # RTP/AVP +$sdp.line(m=audio[1]/RTP\/AVP[0]) # RTP/AVP +$sdp.line(m=audio[1]/RTP\/AVP[1]) # NULL +$sdp.line(m=audio[1]/RTQ) # NULL + +``` + +### SDP body line - $sdp.stream + +`$sdp.stream` - Read/Write reference to SDP body streams, with filtering support + +```opensips + +# Within a desired stream, you can first filter by line... +$sdp.stream(/a=ptime); # first “a=ptime” line from Stream #0 ("m=", matching any stream type) +$sdp.stream([1]/a=ptime); # first “a=ptime” line from Stream #1 ("m=", matching any stream type)) +$sdp.stream(audio[1]/a=ptime); # first “a=ptime” line from Audio Stream #1 ("m=audio...") +$sdp.stream(a[1]/a=ptime); # first “a=ptime” line from Audio Stream #1 ("m=a...") +$sdp.stream(video[1]/a=nortpproxy) = NULL; # delete entire line starting with "a=nortpproxy" from Video Stream #1 +$sdp.stream(v[1]/a=nortpproxy:/[0]) = "yes"; # set first "a=nortpproxy" line "yes" value, in Video Stream #1 + +# ... and, additionally, by token +$sdp.stream(video[1]/a=fmtp:115/bitrate=) = 48000; # set "bitrate=" to 48000, under "a=fmtp:115" line #0, as part of Video Stream #1 +$sdp.stream(video[1]/a=fmtp:115[3]) = NULL; # delete the 4th occurrence (if any) of "a=fmtp:115" line, but only within Video Stream #1 +$sdp.stream(video[1]/a=fmtp:115/bitrate=) = 48000; # set "bitrate=" to 48000, under "a=fmtp:115" line #0, as part of Video Stream #1 + +``` + +### SDP body session - $sdp.session + +`$sdp.session` - Read/Write reference to the SDP body session, with filtering support + +```opensips + +# Within the SDP session (i.e. until the 1st "m=" line), you can first filter by line... +$sdp.session(a=ptime); # 1st “a=ptime” line at Session level +$sdp.session(a=ptime[0]); # same as above +$sdp.session(a=ptime[1]); # 2nd “a=ptime” line at Session level +$sdp.session(a=ptime[0]) = NULL; # delete 1st “a=ptime” line at Session level + +# ... but also filter and edit by token: +$sdp.session(a=rtpmap/telephone-event\/) = "8000"; # Match 1st "a=rtpmap" line which describes telephone-event at Session level, and force bitrate to 8000 + +``` + +### SDP stream index - $sdp.stream.idx + +`$sdp.stream.idx` - Read-Only reference to the index of the matched SDP stream. Yields NULL on no-match. + +This variable is especially useful in order to match a line having one specific attribute (e.g. "the rtpmap= line for PCMU codec"), then changing a different attribute within the same stream. Example: + +```opensips + +$var(line_idx) = $sdp.stream.idx(video/a=fmtp/packetization-mode=); # locate index of first "a=fmtp" line, containing a packetization-mode= attribute +$var(data) = $sdp.line([$var(line_idx)]); # grab the full line data +... perform processing on that line ... +$sdp.line([$var(line_idx)]) = $var(data); # re-write the line + +``` + +### IP source address - $si + +`$si` - reference to IP source address of the message + +Alias: `$src_ip` + +### Socket inbound - $socket_in / $socket_in(field) + +`$socket_in` - read-only variable to get the description (proto:ip:port format) of the inbound socket (used for receiving the message). + + +The variable also offers detailed read-only access to various attributes/sub-fields of the socket, as `$socket_in()`. The sub-fields of the socket are: +* ip - the IP part of the socket +* port - the port part of the socket +* proto - the name of the protocol of the socket (as "UDP", "TCP", etc) +* advertised_ip - the advertised IP part of the socket (it may be NULL if no advertising is done on this particular socket) +* advertised_port - the advertised port part of the socket (it may be NULL if no advertising is done on this particular socket) +* tag - the socket internal tag/alias +* anycast - if the socket uses an anycast IP or not (returns 0 if not, 1 if yes) +* af - the address family of the socket's IP. It's value is "INET" if IPv4 or "INET6" if IPv6. +For more details on the meaning of these sub-fields, please also read about the [socket definition](Script-CoreParameters.md#rev_dns). + +### Socket outbound - $socket_out / $socket_out(field) + +`$socket_out` - read-write variable for reading or changing the outbound socket of the message. Originally (before being written/changed) it will return the same socket description as [`$socket_in`](#socket_in) (the inbound socket will be used as outbound socket also). In addition, it also supports the `forced` sub-field, which returns a socket description only if a socket had been explicitly forced; thus, as opposed to the regular [`$socket_out`](#socket_out), if no socket had explicitly been forced, the variable returns NULL. + + + +The variable also offers detailed read-only access to various attributes/sub-fields of the socket, as `$socket_out()`. **It provides the same sub-fields as the [`$socket_in`](#socket_in) variable.** + +```opensips + + $socket_out = "udp:11.11.11.11:5060"; + xlog("The outbound port is $socket_out(port)\n"); + +``` + +### Source port - $sp + +`$sp` - reference to the source port of the message + +### To URI Domain - $td + +`$td` - reference to domain in URI of 'To' header + +Alias: `$to.domain` + +### To display name - $tn + +`$tn` - reference to display name of 'To' header + +### To tag - $tt + +`$tt` - reference to tag parameter of 'To' header + +### To URI - $tu + +`$tu` - reference to URI of 'To' header + +Alias: `$to` + +### To URI Username - $tU + +`$tU` - reference to username in URI of 'To' header + +Alias: `$to.user` + +### Formatted date and time - $time + +`$time(format)` - returns the string formatted time according to UNIX date (see: **man date**). + +### Branch index - $T_branch_idx + +`$T_branch_idx` - the index (starting with 1 for the first branch) of the branch for which is executed the branch_route[]. If used outside of branch_route[] block, the value is '0'. This is exported by TM module. + +### String formatted time - $Tf + +`$Tf` - reference string formatted time + +### Current unix time stamp in seconds - $Ts + +`$Ts` - reference to current unix time stamp in seconds + +### Current microseconds of the current second - $Tsm + +`$Tsm` - reference to current microseconds of the current second + +### Startup unix time stamp - $TS + +`$TS` - reference to startup unix time stamp + +### User agent header - $ua + +`$ua` - reference to user agent header field + +### SIP Headers - $hdr + +`$(hdr(name)[N])` - represents the body of the N-th header identified by 'name'. If [N] is omitted then the body of the first header is printed. The first header is retrieved when N=0, for the second N=1, and so on. To print the last header of that type, use -1, no other negative values are supported now. No white spaces are allowed inside the specifier (before `}`, before or after `{`, [, ] symbols). When N='*', all headers of that type are printed. + +The module should identify most of compact header names (the ones recognized by **OpenSIPS** which should be all at this moment), if not, the compact form has to be specified explicitly. It is recommended to use dedicated specifiers for headers (e.g., %ua for user agent header), if they are available -- they are faster. + +`$(hdr_name[N])` - returns the name of the N-th header. The first header name is obtained for N=0, the second for N=1, and so on. To print the last header name use -1, the second-to-last -2 and so on. No white spaces are allowed inside the specifier (before `}`, before or after `{`, [, ] symbols). When N='*', all header names are printed. + +`$(hdrcnt(name))` -- returns number of headers of type given by 'name'. Uses same rules for specifying header names as `$hdr(name)` above. Many headers (e.g., Via, Path, Record-Route) may appear more than once in the message. This variable returns the number of headers of a given type. + +Note that some headers (e.g., Path) may be joined together with commas and appear as a single header line. This variable counts the number of header lines, not header values. + +For message fragment below, `$hdrcnt(Path)` will have value 2 and `$(hdr(Path)[0])` will have value **``**: +```opensips + + Path: + Path: + +``` + +For message fragment below, `$hdrcnt(Path)` will have value 1 and `$(hdr(Path)[0])` will have value **``,``**: +```opensips + + Path: , + +``` + +Note that both examples above are semantically equivalent but the variables take on different values. + +### Route Name (Full) - $route +`$route` - Access route names of the current route call stack. Usage examples (assuming a route call stack of "route > route[A] > route[B]"): + +* `$route` and `$(route[0])` both return **"route[B]"** (current route) +* `$(route[1])` returns **"route[A]"** (parent route) +* `$(route[2])` returns **"route"** (previous-parent route) +* `$(route[-1])` returns **"route"** (topmost route) +* `$(route[-2])` returns **"route[A]"** (next-topmost route) +* `$(route[-3])` returns **"route[B]"** (next-next-topmost route) +* `$(route[3])` and `$(route[-4])` both return **NULL** (index out of bounds) +* `$(route[*])` returns **"route > route[A] > route[B]"** (entire call stack) + +### Route Type - $route.type +`$route.type` - Access the type of the current route. May be indexed, using positive or negative indexes. + +* `$route.type` and `$(route.type[0])` both return current route type +* `$(route.type[1])` returns parent route type +* `$(route.type[-1])` returns topmost route type +* `$(route.type[-2])` returns next-topmost route type + +### Route Name - $route.name +`$route.name` - Access the name of the current route. May be indexed, using positive or negative indexes. + +* `$route.name` and `$(route.name[0])` both return current route name +* `$(route.name[1])` returns parent route name +* `$(route.name[-1])` returns topmost route name +* `$(route.name[-2])` returns next-topmost route name + +### Current script line and file - $cfg_line +`$cfg_line` - Holds the current line from the script of the action being executed, useful for logging purposes + +`$cfg_file` - Holds the current name of the cfg file being executed, useful when using multiple scripts via the include statement + +### Log level for xlog() - $xlog_level + +`$xlog_level` - allows to set /reset the xlog() logging level on per-process bases. Shortly said, you can read the verbosity level for the xlog() calls or you can temporary change the level per process bases. + +Example: +```opensips + +xlog("current verbosity is $xlog_level \n"); +$xlog_level = L_DBG; # force local xlogging limit to DBG +... +(set of xlogs) +... +$xlog_level = NULL; # reset to initial value + +``` + +## Escape Sequences + +These sequences are exported, and mainly used, by xlog module to print messages in many colors (foreground and background) using escape sequences. + +### Foreground and background colors + +`$C(xy)` - reference to an escape sequence. ¿x¿ represents the foreground color and ¿y¿ represents the background color. + +Colors could be: + +* x : default color of the terminal +* s : Black +* r : Red +* g : Green +* y : Yellow +* b : Blue +* p : Purple +* c : Cyan +* w : White + +### Examples + +A few examples of usage. + +```opensips + +... +route { +... + $avp(uuid)="caller_id"; + $avp(tmp)= $avp(uuid) + ": " + $fu; + xlog("$C(bg)$avp(tmp)$C(xx) [$avp(tmp)] $C(br)$cs$C(xx)=[$hdr(cseq)]\n"); +... +} +... + +``` diff --git a/docs/manual/Script-Flags.md b/docs/manual/Script-Flags.md new file mode 100644 index 00000000000..dbacc7f24aa --- /dev/null +++ b/docs/manual/Script-Flags.md @@ -0,0 +1,126 @@ +--- +title: "Script Flags" +--- + +## What are the flags? + +A flag is a TRUE or FALSE entity. The flags are 32 in number, for each type (see below). A flag is identified by its name - again, you cannot have more than 32 different names/flags. You do not have to declare or define the names of the flags, just use them. +The flags may be used for whatever purpose, there is nothing pre-defined. + +## Types of flags + +* **message flags** (or transaction flags) these flags are attached to the current SIP message or to the current transaction (if a transaction exists). So these flags are transaction persistent. They are visible in all routes and cases where the transaction or SIP message context is visible. +* **branch flags** these flags are also at transaction level, but per SIP branch - yeah SIP branch has its own set of flags. Each time in the context of a specific SIP branch (like in `branch_route` or `reply_route`), you will see the matching branch flags. These flags may be operated from script level or by various module functions (like usrloc saving the branch flags for each registered contact). + +--- + +## Script Flag Functions + +There are a bunch a functions that helps into working with the flags from script level - to set, reset and check. + +### Message/transaction flags + +* [`setflag`](Script-CoreFunctions.md#setflag)`(FLAG)` +* [`resetflag`](Script-CoreFunctions.md#resetflag)`(FLAG)` +* [`isflagset`](Script-CoreFunctions.md#isflagset)`(FLAG)` + +*Examples: setflag(accounting), resetflag(DO_NAT) or setflag(1942)* + +### Branch flags + +* [`setbflag`](Script-CoreFunctions.md#setbflag)`(FLAG, branch_idx)` +* [`resetbflag`](Script-CoreFunctions.md#resetbflag)`(FLAG, branch_idx)` +* [`isbflagset`](Script-CoreFunctions.md#isbflagset)`(FLAG, branch_idx)` + + + +or, the shorter format, working on the default (branch 0) flags: + +* [`setbflag`](Script-CoreFunctions.md#setbflag)`(FLAG)` +* [`resetbflag`](Script-CoreFunctions.md#resetbflag)`(FLAG)` +* [`isbflagset`](Script-CoreFunctions.md#isbflagset)`(FLAG)` + +--- + +## Flags related Variables + +### Message/transaction flags + +* [`$msg.flag(name)`](Script-CoreVar.md#msg.flag) - reads/writes a certain message flag + +* [`$mf`](Script-CoreVar.md#mf) - ReadOnly; outputs a list of all set flags + + +### Branch flags + +* [`$msg.branch.flag(name)`](Script-CoreVar.md#msg.branch.flag) - reads/writes a certain branch flag + +* [`$msg.branch.flags`](Script-CoreVar.md#msg.branch.flags) - ReadOnly; returns a list of all set branch flags + +--- + +## Flags and routes + +### Message/transaction flags + +These flags will show up in all routes where messages related to the initial request are processed. So, they will be visible and changeable in `onbranch`, `failure` and `onreply` routes; the flags will be visible in all `branch` routes; if you change a flag in a `branch` route, the next `branch` routes will inherit the change. + +### Branch flags + +These flags will show up in all routes where messages related to initial branch request are processed. So, in `branch` route you will see different sets of flags (as they are different branches); in `onreply` route you will see the branch flags corresponding to the branch the reply belongs to; in `failure` route, the branch flags corresponding to the branch the winning reply belongs to will be visible. +In `request` route, you may have multiple branches (as a result of a `lookup()` for example), but at least one. All the time there is the default branch, index 0, corresponding to the RURI. Any additional branches will get indexes from 1 and above. + +--- + +## Example + +### NAT flag handling + +```opensips + + .......... + modparam("usrloc", "nat_bflag", "NAT_BFLAG") + .......... + + route { + .......... + if (nat detected) + setbflag(NAT_BFLAG); # set branch flag "NAT_BFLAG" for the branch 0 + + .......... + if (is_method("REGISTER")) { + # the branch flags (including "NAT_BFLAG") will be saved into location + save("location"); + exit; + } else { + # lookup will load the branch flag from location + if (!lookup("location")) { + sl_send_reply(404,"Not Found"); + exit; + } + t_on_branch("handle_branch") + t_relay(); + } + } + + branch_route[handle_branch] { + xlog("-------branch=$T_branch_idx, branch flags=$bf\n"); + if (isbflagset(NAT_BFLAG)) { + #current branch is marked as natted + ......... + } + } + +``` + +if no parallel forking is done, you can get rid of the branch route and add instead of t_on_branch(): +```text + + ........ + if (isbflagset(NAT_BFLAG)) { + #current branch is marked as natted + ......... + } + ......... + +``` diff --git a/docs/manual/Script-Operators.md b/docs/manual/Script-Operators.md new file mode 100644 index 00000000000..a6636cc5cde --- /dev/null +++ b/docs/manual/Script-Operators.md @@ -0,0 +1,72 @@ +--- +title: "Script Operators" +description: "Assignments, string and arithmetic operations can be done directly in the configuration file." +--- + +Assignments, string and arithmetic operations can be done directly in the configuration file. + +## Assignment + +Assignments can be done like in C, via '=' (equal) operator. Not that not all variables (from script) can be written, some are read-only. Check with [listing of variables](Script-CoreVar.md) to see which ones can be written too. + +```opensips + +$var(a) = 123; +$ru = "sip:user@domain"; + +``` + +There is a special assign operator ':=' (colon equal) that can be used with AVPs. If the right value is **null**, all AVPs with that name are deleted. If different, the new value will overwrite any existing values for the AVPs with than name (on other words, delete existing AVPs with same name, add a new one with the right side value). + +```opensips + +$avp(val) := 123; + +``` + +## String operations + +For strings, '+' is available to concatenate. + +```opensips + +$var(a) = "test"; +$var(b) = "sip:" + $var(a) + "@" + $fd; + +``` + +## Arithmetic and bitwise operations + +For numbers, one can use: + +* + : plus +* - : minus +* / : divide +* * : multiply +* % : modulo +* | : bitwise OR +* & : bitwise AND +* ^ : bitwise XOR +* ~ : bitwise NOT +* \<< : bitwise left shift +* \>> : bitwise right shift + +Example: + +```opensips + +$var(a) = 4 + ( 7 & ( ~2 ) ); + +``` + +> [!NOTE] +> to ensure the priority of operands in expression evaluations do use __parenthesis__. + +Arithmetic expressions can be used in condition expressions via test operator ' [ ... ] '. + +```opensips + +if( [ $var(a) & 4 ] ) + log("var a has third bit set\n"); + +``` diff --git a/docs/manual/Script-Routes.md b/docs/manual/Script-Routes.md new file mode 100644 index 00000000000..b374a371690 --- /dev/null +++ b/docs/manual/Script-Routes.md @@ -0,0 +1,321 @@ +--- +title: "Types of routes" +description: "Request routing block. It contains a set of actions to be taken for SIP requests." +--- + +**OpenSIPS** routing logic uses several types of routes. Each type of route is triggered by a certain event and allows you to process a certain type of message (request or reply). + +--- + +## route + +Request routing block. It contains a set of actions to be taken for SIP requests. + +**Triggered by** : receiving an external request from the network. + +**Processing** : the triggering SIP request. + +**Type** : initially stateless, may be forced to stateful by using TM functions. + +**Default action** : if the request is not either forwarded nor replied, the route will simply discard the request at the end. + +The main 'route' block identified by 'route`{...}`' or 'route[0]`{...}`' is executed for each SIP request. + +The implicit action after execution of the main route block is to drop the SIP request. To send a reply or forward the request, explicit actions must be called inside the route block. + +Example of usage: +```opensips + + route { + if(is_method("OPTIONS")) { + # send reply for each options request + sl_send_reply(200, "OK"); + exit(); + } + route(1); + } + route[1] { + # forward according to uri + forward(); + } + +``` + +Note that if a 'route(X)' is called from a 'branch_route[Y]' then in 'route[X]' is just processed each separate branch instead of all branches together as occurs in main route. + +A route can return a set of values, that can later be retrieved from the route's calling context using the [`$return`](https://docs.opensips.org/manual/3-6/script-corevar#return) variable. + +Example of passing values: +```opensips + + route { + route(query); + xlog("Query returned id $return(0) with $return(1) values\n"); + } + route[query] { + # perform a query for information and store the information in $var(id) and $var(values) + return(1, $var(id), $var(values)); + } + +``` +Note that the first parameter of the return is always the return code, and cannot be retrieved using the `$return()` variable. + +--- + +## branch_route + +Request's branch routing block. It contains a set of actions to be taken for each branch of a SIP request. + +**Triggered by** : preparation a new branch (of a request); the branch is well formed, but not yet sent out. + +**Processing** : the SIP request (with the branch particularities, like RURI, branch flags) + +**Type** : stateful + +**Default action** : if the branch is not dropped (via "drop" statement), the branch will be automatically sent out. + +It is executed only by TM module after it was armed via t_on_branch("branch_route_index"). + +Example of usage: +```opensips + + route { + lookup("location"); + t_on_branch("1"); + if(!t_relay()) { + sl_send_reply(500, "Internal Server Error"); + } + } + branch_route[1] { + if($ru=~"10\.10\.10\.10") { + # discard branches that go to 10.10.10.10 + drop(); + } + } + +``` + +--- + +## failure_route + +Failed transaction routing block. It contains a set of actions to be taken each transaction that received only negative replies (>=300) for all branches. + +**Triggered by** : receiving or generation(internal) of a negative reply that completes the transaction (all branches are terminated with negative replies) + +**Processing** : the original SIP request (that was sent out) + +**Type** : stateful + +**Default action** : if no new branch is generated or no reply is forced over, by default, the winning reply will be sent back to UAC. + +The 'failure_route' is executed only by TM module after it was armed via t_on_failure("failure_route_index"). + +Note that inside the 'failure_route', the request that initiated the transaction is being processed, and not its reply. + +Example of usage: +```opensips + + route { + lookup("location"); + t_on_failure("1"); + if(!t_relay()) { + sl_send_reply(500, "Internal Server Error"); + } + } + failure_route[1] { + if(is_method("INVITE")) { + # call failed - relay to voice mail + t_relay("udp:voicemail.server.com:5060"); + } + } + +``` + +--- + +## onreply_route + +Reply routing block. It contains a set of actions to be taken for SIP replies. + +**Triggered by** : receiving of a reply from the network + +**Processing** : the received reply + +**Type** : stateful (if bound to a transaction) or stateless (if global reply route). + +**Default action** : if the reply is not dropped (only provisional replies can be), it will be injected and processed by the transaction engine. + +There are three types of onreply routes: + +* **global** - it catches all replies received by OpenSIPS and does not need any special arming (simple definition is enough) - named 'onreply_route `{...}`' or 'onreply_route[0] `{...}`'. NOTE: this route is not SIP transaction aware (the reply was not matched to the transaction), so no transactional data is available here. + +* **per request/transaction** - it catches all received replies belonging to a certain transaction and need to be armed (via "t_on_reply()" ) at request time, in REQUEST ROUTE - named 'onreply_route[N] `{...}`'. + +* **per branch** - it catches only the replies that belong to a certain branch from a transaction. It needs to be armed (also via "t_on_reply()" ) at request time, but in BRANCH ROUTE, when a certain outgoing branch is processed - named 'onreply_route[N] `{...}`'. + +Certain 'onreply_route' blocks can be executed by TM module for special replies. For this, the 'onreply_route' must be armed for the SIP requests whose replies should be processed within it, via t_on_reply("onreply_route_index"). + +```opensips + +route { + $ru = "sip:bob@opensips.org"; # first branch + $msg.branch = "sip:alice@opensips.org"; # second branch + + t_on_reply("global"); # the "global" reply route + # is set the whole transaction + t_on_branch("1"); + + t_relay(); +} + +branch_route[1] { + if ($rU=="alice") + t_on_reply("alice"); # the "alice" reply route + # is set only for second branch +} + +onreply_route { + xlog("OpenSIPS received a reply from $si\n"); +} + +onreply_route[alice] { + xlog("received reply on the branch from alice\n"); +} + +onreply_route[global] { + if (t_check_status("1[0-9][0-9]")) { + setflag("PROVISIONAL_REPLY"); + log("provisional reply received\n"); + if (t_check_status("183")) + drop; + } +} + +``` + +--- + +## error_route + +The error route is executed automatically when a parsing error occurs during SIP request processing, or when a script [assert](https://docs.opensips.org/manual/3-6/script-corefunctions#assert) fails. It allows the administrator to decide what to do in such error cases. + +> [!IMPORTANT] +> as this is triggered ONLY for SIP request, OpenSIPS has to be able to correctly parse the first line of the SIP message. So any syntax error in the first line will NOT trigger this route (as OpenSIPS will not be able to tell if a reply or request). + +**Triggered by** : parsing error in "route" + +**Processing** : failed request + +**Type** : stateless (recommended) + +**Default action** : discard request. + +In error_route, the following pseudo-variables are available to get access to error details: +* `$(err.class)` - the class of error (now is '1' for parsing errors) +* `$(err.level)` - severity level for the error +* `$(err.info)` - text describing the error +* `$(err.rcode)` - recommended reply code +* `$(err.rreason)` - recommended reply reason phrase + +```opensips + + error_route { + xlog("--- error route class=$(err.class) level=$(err.level) + info=$(err.info) rcode=$(err.rcode) rreason=$(err.rreason) ---\n"); + xlog("--- error from [$si:$sp]\n+++++\n$mb\n++++\n"); + sl_send_reply($err.rcode, $err.rreason); + exit; + } + +``` + +--- + +## local_route + +The local route is executed automatically when a new SIP request is generated by TM, internally (no UAC side). This is a route intended to be used for message inspection, accounting and for applying last changes on the message headers. Routing and signaling functions are not allowed. + +**Triggered by** : TM generating a brand new request + +**Processing** : the new request + +**Type** : stateful + +**Default action** : send the request out + +```opensips + + local_route { + if (is_method("INVITE") && $ru=~"@foreign.com") { + append_hf("P-hint: foreign request\r\n"); + exit; + } + if (is_method("BYE") ) { + acc_log_request("internally generated BYE"); + } + } + +``` + +--- + +## startup_route + +The **startup_route** is executed only once when OpenSIPS is started and before the processing of SIP messages begins. This is useful if some initiation actions are needed, like loading some data in the cache, to ease up the future processing. Notice that this route, compared to the others is not triggered at the receipt of a message, so the functions that can be called here must not do processing on the message. + +**Triggered** : At startup, before the listener processes are started. + +**Processing** : Initializing functions. + +```opensips + + startup_route { + sql_query_one("SELECT gwlist FROM routing_rules WHERE ruleid = 1", "$avp(gateway_list)"); + cache_store("local", "rule1", "$avp(gateway_list)"); + } + +``` + +--- + +## timer_route + +The **timer_route** is a route executed periodically at a configured interval of time specified next to the name (in seconds). Similar to *startup_route*, this route does not process a SIP message. Multiple timer routes (possibly at differing running intervals) are allowed. + +**Triggered by** : The *timer* worker process. + +**Processing** : Functions that do periodic, recurring processing. + +> [!NOTE] +> when OpenSIPS starts, each timer_route is **first executed after ``** seconds! + +```opensips + + timer_route[gw_update, 300] { + sql_query_one("SELECT gwlist FROM routing_rules WHERE ruleid = 1", "$avp(gateway_list)"); + $shv(gateway_list) = $avp(gateway_list); + } + +``` + +--- + +## event_route +The **event_route** is used by the OpenSIPS Event Interface to execute script code when an event is triggered. The name of the route is the event that has to be handled by that route. The route itself is executed asynchronously with regards to the trigger moment. + +**Triggered by** : OpenSIPS core when an event with the same name is raised by the Event Interface + +**Processing** : the event triggered + +**Type** : stateless (recommended) + +**Default action** : no script code is executed when the event is raised. + +```opensips + + event_route[E_PIKE_BLOCKED] { + xlog("The E_PIKE_BLOCKED event was raised\n"); + } + +``` diff --git a/docs/manual/Script-Statements.md b/docs/manual/Script-Statements.md new file mode 100644 index 00000000000..cef28f676b6 --- /dev/null +++ b/docs/manual/Script-Statements.md @@ -0,0 +1,172 @@ +--- +title: "Script Statements" +description: "Statements you can use in the OpenSIPS config file while building the routing logic." +--- + +Statements you can use in the **OpenSIPS** config file while building the routing logic. + +## if + +IF-ELSE statement + +Prototype: + +```opensips + + if (expr) { + actions; + } else { + actions; + } + +``` + +The 'expr' should be a valid logical expression. + +The logical operators that can be used in the logical expressions: + +* == - equal +* != - not equal +* =~ - regular expression matching (e.g. `$rU` =~ '^1800*' is "`$rU` begins with 1800" ) +* !~ - regular expression not-matching +* \> - greater +* \>= - greater or equal +* \< - less +* \<= - less or equal +* && - logical AND +* || - logical OR +* ! - logical NOT +* [ ... ] - test operator - inside can be any arithmetic expression + +Example of usage: + +```opensips + + if ( is_method("INVITE") && $rp==5060 ) + { + log("this sip message is an invite\n"); + } else { + log("this sip message is not an invite\n"); + } + +``` + +## switch + +SWITCH statement - it can be used to test the value of a pseudo-variable. + +IMPORTANT NOTE: 'break' can be used only to mark the end of a 'case' branch (as it is in shell scripts). If you are trying to use 'break' outside a 'case' block the script will return error -- you must use 'return' there. + +Example of usage: +```opensips + + route { + route(my_logic); + switch ($retcode) { + case -1: + log("process INVITE requests here\n"); + break; + case 1: + log("process REGISTER requests here\n"); + break; + case 2: + case 3: + log("process SUBSCRIBE and NOTIFY requests here\n"); + break; + default: + log("process other requests here\n"); + } + + # switch of R-URI username + switch ($rU) { + case "101": + log("destination number is 101\n"); + break; + case "102": + log("destination number is 102\n"); # continue with 103 and 104 + case "103": + case "104": + log("destination number is 103 or 104\n"); + break; + default: + log("unknown destination number\n"); + } + } + + route [my_logic] { + if (is_method("INVITE")) + return(-1); + + if (is_method("REGISTER")) + return(1); + + if (is_method("SUBSCRIBE")) + return(2); + + if (is_method("NOTIFY")) + return(3); + + return(-2); + } + +``` + +> [!WARNING] +> Take care while using 'return' - 'return(0)' stops the execution of the script. + +## while + +while statement + +Example of usage: +```opensips + + $var(i) = 0; + $var(cli) = NULL; + while ($var(i) < 10) { + if ($(avp(valid_clis[$var(i)]) == $fU) { + xlog("matched the From user!\n"); + $var(cli) = $fU; + break; + } + $var(i) = $var(i) + 1; + } + +``` + +## for each + +for each statement - easy iteration over indexed variables or pseudo-variables + +Example of usage: +```opensips + + $avp(arr) = 0; + $avp(arr) = 1; + $avp(arr) = 2; + $avp(arr) = 3; + $avp(arr) = 4; + + for ($var(it) in $(avp(arr)[*])) + xlog("array value: $var(it)\n"); + + # iterate through all Contact URIs from each Contact header + for ($var(ct) in $(ct[*])) + xlog("Contact: $var(ct)\n"); + + # iterate through all Via headers of a SIP request + for ($var(via) in $(hdr(Via)[*])) + xlog("Found \"Via\" header: $var(via)\n"); + + # iterate through all JSON documents returned by a MongoDB query + cache_raw_query("mongodb:location", "{... find ...}", "$avp(res)"); + for ($json(contact) in $(avp(res)[*])) { + xlog("Found: $json(contact/phone) $json(contact/email)\n"); + + if ($json(contact/phone) =~ "^40") { + xlog("found a cheap destination to dial\n"); + break; + } + } + +``` diff --git a/docs/manual/Script-Syntax.md b/docs/manual/Script-Syntax.md new file mode 100644 index 00000000000..9d285b2b4d6 --- /dev/null +++ b/docs/manual/Script-Syntax.md @@ -0,0 +1,163 @@ +--- +title: "Script Syntax" +description: "The OpenSIPs configuration script has three main logical parts:" +--- + +## Script Format + +The OpenSIPs configuration script has three main logical parts: + +* global parameters +* modules section +* routing logic + +--- + +### Global parameters + +Usually, in the first part, you declare the [OpenSIPS global parameters](Script-CoreParameters.md) - these global or core parameters are affecting the OpenSIPS core and possible the modules. + +Configuring the network listeners, available transport protocols, forking (and number of processes), the logging and other global stuff is provided by these global parameters. + +Example: + +```opensips + +disable_tcp = yes +listen = udp:192.168.3.60:5060 +listen = udp:192.168.3.60:5070 +fork = yes +children = 4 +log_stderror = no + +``` + +--- + +#### Modules section + +In regards to the OpenSIPS modules,the modules that are to be loaded (no module is loaded by default) are specified by using the directive **loadmodule**. Modules are to be specified by name and an optional path (to the *.so* file). If no path is provided (and just the name of the module), the default path will be assumed for locating the loading the module (default path is */usr/lib/opensips/modules* if not other one configured at [compile time](Install-CompileAndInstall.md). For configuring a different path, either the path is pushed directly with the module name (to get control per module) or it can be globally (for all modules) configured via the **mpath** global parameter. +\ +Once the modules are loaded, the parameters of the modules may be set using the **modparam** directive - to list of available parameters for each module, the type of parameter value (integer or string) can be found in the [documentation of the modules](Modules.md), the *Parameters* section. + +Examples: +```opensips + +loadmodule "modules/mi_datagram/mi_datagram.so" +modparam("mi_datagram", "socket_name", "udp:127.0.0.1:4343") +modparam("mi_datagram", "children_count", 3) + +``` + +or + +```opensips + +mpath="/usr/local/opensips_proxy/lib/modules" +loadmodule "mi_datagram.so" +modparam("mi_datagram", "socket_name", "udp:127.0.0.1:4343") +modparam("mi_datagram", "children_count", 3) +loadmodule "mi_fifo.so" +modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") + +``` + +--- + +#### Routing logic + +The routing logic is actually a sum of routes (script routes) that contain the OpenSIPS logic for routing SIP traffic. The description of **OpenSIPS behavior in relation to the SIP traffic** is done via this routes. +\ +There are different types of routes : +* **top routes** - routes that are directly triggered by OpenSIPs when some events occurs (like SIP request received, SIP reply received, transaction failed, etc) +* **sub-routes** - routes that are triggered / used from other routes in script. + + +What are the existing **top routes**, when they are triggered, what kind of SIP messages is handled, what SIP operations are allowed and other are documented in the [types of routes section](Script-Routes.md). +\ +The **sub-routes** have names and they are to be called from any other route (top or sub) in the script via their names. The **sub-routes** may take parameters (when called) or return a numerical code (avoid returning 0 value as this will terminate your whole script. The **sub-routes** are similar to functions / procedure in any programing language. +See the [description of the *route*](Script-CoreFunctions.md#setuser) directive. + +## Data Types + +The OpenSIPS scripting language supports the following data types: + +### Basic + +* *integer* (32-bit, signed). + * Max value: +2,147,483,647 == 2 ^ 31 - 1 + * Min value: -2,147,483,648 == - 2 ^ 31 +* *string* (unlimited size) + * note that some functions which use strings may have internal buffers which limit the maximum size of the strings (e.g. the [xlog()](https://docs.opensips.org/manual/3-6/script-corefunctions#sr_check_status) function's output buffer is configurable via [xlog_buf_size](https://docs.opensips.org/manual/3-6/script-coreparameters#tcp_keepinterval)) +* *double* (packed as string), through the **[mathops](../../modules/mathops/README.md)** module + +### Complex + +* *list* via the **[`$avp` variable](https://docs.opensips.org/manual/3-6/script-corevar#avp_variables)** +* *map* via the **[`$json`](../../modules/json/README.md#pv_json)** and **[`$xml`](../../modules/xml/README.md#pv_xml)** variables + +## Function Calling Conventions +All OpenSIPS [core](https://docs.opensips.org/manual/3-6/script-corefunctions) and [module](https://docs.opensips.org/manual/3-6/function-index) functions internally share the same function interface, such that they benefit from the following calling convention: + + + +* **any integer or string function parameter may also be passed using a "holder" variable** + +```opensips + +ds_select_dst(1, 1); + +``` + +... is equivalent to: + +```opensips + +$var(x) = 1; +ds_select_dst($var(x), $var(x)); + +``` + + + +* **any string function parameter can be passed as a format string** + +```opensips + +set_dlg_profile("caller", "$var(country_code)_$var(area)_$fU"); + +``` + + + +Literal **"$"** characters can be included in a format string using the **"$$"** escape sequence + + + +> [!NOTE] +> There still are a few exceptions for the conventions above in the case of string parameters, due to performance optimizations, as some functions still require some parameters to be plain, static strings (e.g. *save("location")*). Such cases will be noted in the function's documentation. + + + +* **input or output variables passed to functions must not be quoted**: + +```opensips + +ds_count(1, "a", $var(out_result)); + +``` + + + +* **integers no longer need to be passed as double-quoted strings**: + +```opensips del={2-2} +# this is deprecated +ds_select_dst("1", "1"); +``` + +```opensips + +ds_select_dst(1, 1); + +``` diff --git a/docs/manual/Script-Tran.md b/docs/manual/Script-Tran.md new file mode 100644 index 00000000000..9fbdb0bfff8 --- /dev/null +++ b/docs/manual/Script-Tran.md @@ -0,0 +1,972 @@ +--- +title: "Script Transformations" +description: "Intuitively, a Transformation is a function that is applied to a variable(script variable, pseudo-variable, AVP, static string) to get a special value from i..." +--- + +Intuitively, a **Transformation** is a function that is applied to a variable(script variable, pseudo-variable, AVP, static string) to get a special value from it. The input value is not altered. + +Examples of using different kinds of variables in **OpenSIPS script**: + +```opensips + +# check if username in From header is equal with username in To header +if ($fU == $tU) { + ... +} + +# Request-URI username based processing +switch ($rU) { + case "1234": + ... + break; + case "5678": + ... + break; + default: + ... +} + +# assign an integer value to an variable +$var(gw_count) = 1; + +# assign a string value to an AVP +$avp(server) = "opensips"; + +# store the Request-URI in a variable +$var(ru_backup) = $ru; + +# concat "sip:" + From username + "@" + To domain in a script variable x +$var(x) = "sip:" + $fU + "@" + $td; + +``` + +The transformations are intended to facilitate access to different attributes of variables (like strlen of value, parts of value, substrings) or complete different value of variables (encoded in hexa, md5 value, escape/unescape value for DB operations...). + +A transformation is represented in between `{` and `}` and follows the name of a variable. When using transformations, the variable name and transformations **must** be enclosed in between `(` and `)`. + +Example: + +```opensips + +# the length of From URI ($fu is pseudo-variable for From URI) + +$(fu{s.len}) + +``` + +Multiple transformations can be applied to a variable at the same time. + +```opensips + +# the length of escaped 'Test' header body + +$(hdr(Test){s.escape.common}{s.len}) + +``` + +All transformations, unless otherwise specified, will return NULL in case of error or unsuccessful operation (e.g looking for an nonexistent parameter in an URI with the "`{uri.param,name}`" transformation). Also, NULL is accepted as input for transformations in order to support chaining with a previous one that would return NULL. + +The transformations can be used anywhere, being considered parts of script variables support -- in xlog, avpops or other modules' functions and parameters, in right side assignment expressions or in comparisons. + +> [!IMPORTANT] +> To learn what variables can be used with transformations see [Scripting variables list](Script-CoreVar.md). + +## String Transformations +The name of these transformation starts with 's.'. They are intended to apply string operations to variables. + +Available transformations in this class: + +### {s.len} + +Return strlen of variable value + +```opensips + +$var(x) = "abc"; +if($(var(x){s.len}) == 3) +{ + ... +} + +``` + +### {s.int} + +Converts the initial part of the given string to an integer value. Returns 0 if there were no digits at all. + +```opensips + +$var(dur) = "2868.12 sec"; +if ($(var(dur){s.int}) < 3600) { + ... +} + +``` + +### {s.md5} + +Returns the MD5 hash of the given input. + +```opensips + +xlog("MD5 over From username: $(fU{s.md5})\n"); + +``` + +### {s.crc32} + +Returns the CRC-32 checksum of the value as a decimal string. + +### {s.reverse} + +Returns the input string in revers order. + +```opensips + +$var(forward) = "onetwothree"; +$var(reverse) = $(var(forward){s.reverse}); //Contains "eerhtowteno"; + +``` + +### {s.substr,offset,length} + +Return the substring starting at *offset* having size of *length*. If *offset* is negative, then it is counted from the end of the value, -1 being the last char. In case of a positive value, *0* is the first char. If *length* is *0* or greater than the string length, the substring to the end of the input string is returned. If *length* is negative, the end of the substring is counted from the end of the value, with -1 excluding the last char. Both offset and length may be specified using variables. + +Example: +```opensips + +$var(x) = "abcd"; +$(var(x){s.substr,1,0}) = "bcd" + +``` + +### {s.select,index,separator} + +Return a field from the value of a variable. The field is selected based on separator and index. The separator must be a character used to identify the fields. Index must be a integer value or a variable. If index is negative, the count of fields starts from end of value, -1 being last field. If index is positive, 0 is the first field. Note that if a field is empty, an empty string will be returned and not NULL. + +Example: +```opensips + +$var(x) = "12,34,56"; +$(var(x){s.select,1,,}) => "34" ; + +$var(x) = "12,34,56"; +$(var(x){s.select,-2,,}) => "34" + +``` + +### {s.encode.hexa} + +Return encoding in hexa of variable's value + +### {s.decode.hexa} + +Return decoding from hexa of variable's value + +### {s.escape.common} + +Return escaped string of variable's value. Characters escaped are ', ", backslash and 0. Useful when doing DB queries (care should be taken for non Latin character set). + +### {s.unescape.common} + +Return unescaped string of variable's value. Reverse of above transformation. + +### {s.escape.user} + +Return escaped string of variable's value, changing to '%hexa' the characters that are not allowed in user part of SIP URI following RFC requirements. + +### {s.unescape.user} + +Return unescaped string of variable's value, changing '%hexa' to character code. Reverse of above transformation. + +### {s.escape.param} + +Return escaped string of variable's value, changing to '%hexa' the characters that are not allowed in the param part of SIP URI following RFC requirements. + +### {s.unescape.param} + +Return unescaped string of variable's value, changing '%hexa' to character code. Reverse of above transformation. + +### {s.tolower} + +Return string with lower case ASCII letters. + +### {s.toupper} + +Return string with upper case ASCII letters. + +### {s.index} + +Searches for one string within another starting at the beginning of the first string. Returns starting index of the string found or NULL if not found. +The optional index specifies the offset to begin the search at in the string. Negative offsets are supported and will wrap. + +```opensips + +$var(strtosearch) = 'onetwothreeone'; +$var(str) = 'one'; + +# Search the string starting at 0 index +$(var(strtosearch){s.index, $var(str)}) # will return 0 +$(var(strtosearch){s.index, $var(str), 0}) # Same as above +$(var(strtosearch){s.index, $var(str), 3}) # returns 11 + +# Negative offset +$(var(strtosearch){s.index, $var(str), -11}) # Same as above + +# Negative wrapping offset +$(var(strtosearch){s.index, $var(str), -25}) # Same as above + +#Test for existence of string in another +if ($(var(strtosearch){s.index, $var(str)}) != NULL) + xlog("found $var(str) in $var(strtosearch)\n"); + +``` + +### {s.rindex} + +Searches for one string within another starting at the end of the first string. Returns starting index of the string found or NULL if not found. +The optional index specifies an offset to start the search before, e.g the start of the found string will be before the supplied offset. Negative offsets are supported and will wrap. + +```opensips + +$(var(strtosearch){s.rindex, $var(str)}) # will return 11 +$(var(strtosearch){s.rindex, $var(str), -3}) # will return 11 +$(var(strtosearch){s.rindex, $var(str), 11}) # will return 11 +$(var(strtosearch){s.rindex, $var(str), -4}) # will return 0 + +``` + +### {s.fill.left, tok, len} + +Fills a string to the left with a char/string until the given final length is reached. The initial string is returned if its length is greater or equal to the given final length. + +```opensips + +$var(in) = "485"; (also works for integer PVs) + +$(var(in){s.fill.left, 0, 3}) => 485 +$(var(in){s.fill.left, 0, 6}) => 000485 +$(var(in){s.fill.left, abc, 8}) => bcabc485 + +``` + +> [!NOTE] +> currently optimized for speed. Does not support pseudo-variable parameters or successive "s.fill" cascading. + +### {s.fill.right, tok, len} + +Fills a string to the right with a char/string until the given final length is reached. The initial string is returned if its length is greater or equal to the given final length. + +```opensips + +$var(in) = 485; (also works for string PVs) + +$(var(in){s.fill.right, 0, 3}) => 485 +$(var(in){s.fill.right, 0, 6}) => 485000 +$(var(in){s.fill.right, abc, 8}) => 485abcab + +``` + +### {s.width, len} + +Truncates or expands the input to the given *len*. Expanding is done to the right with the space character ' '. Truncating is done in a similar manner, from the right. Examples: + +Fills a string to the right with a char/string until the given final length is reached. The initial string is returned if its length is greater or equal to the given final length. If used on pseudo-variables containing integers, it will convert them to strings. + +```opensips + +$var(in) = "transformation"; + +$(var(in){s.width, 14}) => "transformation" +$(var(in){s.width, 16}) => "transformation " +$(var(in){s.width, 9}) => "transform" + +``` + +### {s.trim} + +Strips any leading or trailing whitespace from the input string. Trimmed characters are " " (space), \t (tab), \n (newline) and \r (carriage return). + +```opensips + +$var(in) = "\t \n input string \r "; + +$(var(in){s.trim}) => "input string" + +``` + +### {s.trimr} + +Strips any trailing whitespace from the input string. Trimmed characters are " " (space), \t (tab), \n (newline) and \r (carriage return). + +```opensips + +$var(in) = "\t \n input string \r "; + +$(var(in){s.trimr}) => "\t \n input string" + +``` + +### {s.triml} + +Strips any leading whitespace from the input string. Trimmed characters are " " (space), \t (tab), \n (newline) and \r (carriage return). + +```opensips + +$var(in) = "\t \n input string \r "; + +$(var(in){s.triml}) => "input string \r " + +``` + +### {s.dec2hex} + +Converts a decimal(base 10) number to hexadecimal (in base 16), represented as string. + +### {s.hex2dec} + +Converts a hexadecimal number (base 16) represented as string to decimal (base 10). + +### {s.b64encode} + +Represents binary input data in an ASCII string format. + +```opensips + +$var(in) = "\x2\x3\x4\x5!@#%^&*"; +$(var(in){s.b64encode}) => "AgMEBSFAIyVeJio=" + +``` + +### {s.b64decode} + +Assumes input is a Base64 string and decodes as many characters as possible. + +```opensips + +$var(in) = "AgMEBSFAIyVeJio="; +$(var(in){s.b64decode}) => "\x2\x3\x4\x5!@#%^&*" + +``` + +### {s.xor,secret} + +Performs one or more logical XOR operations with (a part of) the "secret" string parameter and the input string, depending on the lengths of the two strings. + +```opensips + +$var(in) = "aaaaaabbbbbb"; +$(var(in){s.xor,x}) => "!/>^P!/>^P!^U2^Q!^U2^Q" + +``` + +### {s.eval} + +Interprets the string as a variable formatted string, evaluating all the variables declared in it. + +```opensips + +$var(in) = "client"; +$var(format) = "Hello, $var(in)!"; +$(var(format){s.eval}) => "Hello, client!" + +``` + +### {s.date2unix} + +Assumes the input is an RFC-3261 SIP "Date" header value, parses it accordingly and returns the equivalent UNIX timestamp. + +```opensips + +$var(date) = "Thu, 13 Jun 2024 12:48:00 GMT"; +$(var(date){s.date2unix}) => "1718282880"; + +``` + +### {s.sha1} + +Returns the SHA1 hash of the given input. +```opensips + +xlog("SHA1 over From username: $(fU{s.sha1})\n"); + +``` + +### {s.sha224} + +Returns the SHA224 hash of the given input. +```opensips + +xlog("SHA224 over From username: $(fU{s.sha224})\n"); + +``` + +### {s.sha256} + +Returns the SHA256 hash of the given input. +```opensips + +xlog("SHA256 over From username: $(fU{s.sha256})\n"); + +``` + +### {s.sha384} + +Returns the SHA384 hash of the given input. +```opensips + +xlog("SHA384 over From username: $(fU{s.sha384})\n"); + +``` + +### {s.sha512} + +Returns the SHA512 hash of the given input. +```opensips + +xlog("SHA512 over From username: $(fU{s.sha512})\n"); + +``` + +### {s.sha1_hmac,key} + +Returns the SHA1 HMAC hash of the given input using key. +```opensips + +xlog("SHA1 HMAC over From username using key 'secret': $(fU{s.sha1_hmac,secret})\n"); + +``` + +### {s.sha224_hmac,key} + +Returns the SHA224 HMAC hash of the given input using key. +```opensips + +xlog("SHA224 HMAC over From username using key 'secret': $(fU{s.sha224_hmac,secret})\n"); + +``` + +### {s.sha256_hmac,key} + +Returns the SHA256 HMAC hash of the given input using key. +```opensips + +xlog("SHA256 HMAC over From username using key 'secret': $(fU{s.sha256_hmac,secret})\n"); + +``` + +### {s.sha384_hmac,key} + +Returns the SHA384 HMAC hash of the given input using key. +```opensips + +xlog("SHA384 HMAC over From username using key 'secret': $(fU{s.sha384_hmac,secret})\n"); + +``` + +### {s.sha512_hmac,key} + +Returns the SHA512 HMAC hash of the given input using key. +```opensips + +xlog("SHA512 HMAC over From username using key 'secret': $(fU{s.sha512_hmac,secret})\n"); + +``` + +## URI Transformations + +The name of transformation starts with 'uri.'. The value of the variable is considered to be a SIP URI. This transformation returns parts of SIP URI (see struct sip_uri). If that part is missing, the returned value is NULL. + +Available transformations in this class: + +### {uri.user} + +Returns the user part of the URI schema. + +### {uri.host} + +(same as **`{uri.domain}`**) + +Returns the domain part of the URI schema. + +### {uri.passwd} + +Returns the password part of the URI schema. + +### {uri.port} + +Returns the port of the URI schema. + +### {uri.params} + +Returns all the URI parameters into a single string. + +### {uri.param,name} + +Returns the value of URI parameter with name "name" + +### {uri.headers} + +Returns URI headers. + +### {uri.transport} + +Returns the value of transport URI parameter. + +### {uri.ttl} + +Returns the value of ttl URI parameter. + +### {uri.uparam} + +Returns the value of user URI parameter + +### {uri.maddr} + +Returns the value of maddr URI parameter. + +### {uri.method} + +Returns the value of method URI parameter. + +### {uri.lr} + +Returns the value of lr URI parameter. + +### {uri.r2} + +Returns the value of r2 URI parameter. + +### {uri.schema} + +Returns the schema part of the given URI. + +## VIA Transformations + +These transformations parse Via headers and all starts with `via.`. The value of the variable is considered to be a SIP Via header. This transformation returns parts of the via header (see struct via_body). If the requested part is missing, the returned value is NULL. Transformation will fail (with script error) if variable holding the Via header is empty. Unless otherwise specified in descriptions below, the result of transform is a string (not an integer). + +Examples: +```opensips +$var(upstreamtransport) = $(hdr(Via)[1]{via.transport}{s.tolower}); +$var(upstreamip) = $(hdr(Via)[1]{via.param,received}); +$var(clientport) = $(hdr(Via)[-1]{via.param,rport}); +``` + +Available transformations in this class: + +### {via.name} + +Returns the `protocol-name` (of RFC3261 BNF), generally `SIP`. + +### {via.version} + +Returns the `protocol-version` (of RFC3261 BNF), generally `2.0`. + +### {via.transport} + +Returns the `transport` (of RFC3261 BNF), e.g., `UDP`, `TCP`, `TLS`. This is the transport protocol used to send the request message. + +### {via.host} + +(same as `{via.domain}`) + +Returns the `host` portion of the `sent-by` (of RFC3261 BNF). Typically this is the IP address of the sender of the request message, and is the address to which the response will be sent. + +### {via.port} + +Returns the `port` portion of the `sent-by` (of RFC3261 BNF). Typically this is the IP port of the sender of the request message, and is the address to which the response will be sent. Result of transform is valid as both integer and string. + +### {via.comment} + +The comment associated with the via header. The `struct via_body` contains this field, but it isn't clear that RFC3261 allows Via headers to have comments (see text at top of page 221, and the BNF doesn't explicit allow comment within Via). The comment is the text enclosed within parens. + +### {via.params} + +Returns all the Via headers parameters (`via-param` of RFC3261 BNF) as single string. Result can be processed using the `{param.*}` transforms. This is essentially everything after the host and port. + +### {via.param,name} + +Returns the value of Via header parameter with name `name`. Typical parameters include `branch`, `rport` and `received`. + +### {via.branch} + +Returns the value of the branch parameter in the VIA header. + +### {via.received} + +Returns the value of the received parameter in the VIA header, if any. + +### {via.rport} + +Returns the value of the rport parameter in the VIA header, if any. + +## Parameters List Transformations + +The name of the transformation starts with "param.". The value of the variable is considered to be a string like name1=value1;name2=value2;...". The transformations returns the value for a specific parameter, or the name of a parameter at a specific index. + +Available transformations in this class: + +### {param.value,name} + +Returns the value of parameter 'name' + +Example: +```opensips + +"a=1;b=2;c=3"{param.value,c} = "3" + +``` + +'name' can be a variable + +### {param.exist,name} + +Returns 1 if the parameter `name` exists (with or without value), else 0. Returned value is both string and integer. `name` can be variable. This can be used to test existence of parameters that do not have values. + +Example: +```opensips + +"a=0;b=2;ob;c=3"{param.exist,ob}; # returns 1 +"a=0;b=2;ob;c=3"{param.exist,a}; # returns 1 +"a=0;b=2;ob;c=3"{param.exist,foo}; # returns 0 + +``` + +### {param.valueat,index} + +Returns the value of parameter at position give by 'index' (0-based index). Negative indexes are accepted, with -1 being the last parameter. + +Example: +```opensips + +"a=1;b=2;c=3"{param.valueat,1} = "2" + +``` + +'index' can be a variable + +### {param.name,index} + +Returns the name of parameter at position 'index'. Negative indexes are accepted, with -1 being the last parameter. 'index' can be a variable. + +Example: +```opensips + +"a=1;b=2;c=3"{param.name,1} = "b" + +``` + +### {param.count} + +Returns the number of parameters in the list. + +Example: +```opensips + +"a=1;b=2;c=3"{param.count} = 3 + +``` + +## Name-address Transformations + +The name of the transformation starts with 'nameaddr.'. The value of the variable is considered to be a string like '[display_name] uri'. The transformations returns the value for a specific field. + +Each transformation supports an optional 'index'. This can be used when passing a list of nameaddr specs, and represents the spec index that should be considered when extracting the value. Indexes start with 0 (the default value when missing), and can accept negative values (-1 represents the last nameaddr spec). + +Example: +```opensips + +'"first" , "second" ' {nameaddr.0.name} = "first" +'"first" , "second" ' {nameaddr.1.name} = "second" +'"first" , "second" ' {nameaddr.-1.name} = "second" + +``` + +Available transformations in this class: + +### {nameaddr.name} + +Returns the value of display name + +Example: +```opensips + +'"test" ' {nameaddr.name} = "test" + +``` + +### {nameaddr.uri} + +Returns the value of URI + +Example: +```opensips + +'"test" ' {nameaddr.uri} = sip:test@opensips.org + +``` + +### {nameaddr.len} + +Returns the length of the entire name-addr part from the value. + +### {nameaddr.param,param_name} + +Returns the value of the parameter with name param_name. +Example: +```opensips + +'"test" ;tag=dat43h' {nameaddr.param,tag} = dat43h + +``` + +### {nameaddr.params} + +Returns all the parameters and their corresponding values. +Example: +```opensips + +'"test" ;tag=dat43h;private=yes' {nameaddr.params} = "tag=dat43h;private=yes" + +``` + +## IP Transformations + +The name of the transformation starts with 'ip.'. Available transformations in this class: + +### {ip.pton} + +Returns a binary representation of a string represented IP. +Example: +```opensips + +"193.668.3.634" {ip.pton} returns a 4 byte binary representation of the IP provided + +``` + +### {ip.ntop} + +Returns a string representation of the binary IP provided +Example: +```opensips + +"193.668.3.634"{ip.pton}{ip.ntop} = "193.668.3.634" + +``` + +### {ip.isip} + +Returns `1` if the string provided is a valid IPv4 or IPv6 address, otherwise `0`. +Example: +```opensips + +"193.668.3.634" {ip.isip} = 1 +"193.668.3.634.1" {ip.isip} = 0 + +``` + +### {ip.isip4} + +Returns `1` if the string provided is a valid IPv4, otherwise `0`. +Example: +```opensips + +"193.668.3.634" {ip.isip4} = 1 + +``` + +### {ip.isip6} + +Returns `1` if the string provided is a valid IPv6, otherwise `0`. +Example: +```opensips + +"193.668.3.634" {ip.isip6} = 0 +"2001:0db8:85a3:0000:0000:8a2e:0370:7334" {ip.isip6} = 1 + +``` + +### {ip.family} +Returns INET or INET6 if the binary IP representation provided is IPv4 or IPv6. +Example: +```opensips + +"193.668.3.634" {ip.pton}{ip.family} = "INET" + +``` + +### {ip.resolve} +Returns the resolved IP address corresponding to the string domain provided. Transformation has no effect if a string IP is provided. +Example: +```opensips + +"opensips.org" {ip.resolve} = "78.46.64.50" + +``` + +### {ip.matches} +Checks if the input IP address matches a net mask given as IP/masklen (short format). It returns 1 if matches, 0 if not. NULL is returned on error (invalid input, invalid parameter, AF mismatch). Variables are supported for the parameter. +Example: +```opensips + +if ( $(si{ip.matches,10.10.0.1/24})==1 ) + xlog("It DOES match \n"); +else + xlog("It DOES NOT match \n"); + +``` + +### {ip.isprivate} +Checks if the input IP address is an IPv4 private IP, according to RFC 1918 and RFC 6598, or a loopback IP (127.0.0.0/8). It returns 1 if the IP is private, 0 if not. +Example: +```opensips + +if ( $(si{ip.isprivate})==1 ) + xlog("source ip is private\n"); +else + xlog("source ip is not private\n"); + +``` + +## CSV Transformations + +The name of the transformation starts with "csv.". The value of the variable is considered to be a string like "field1,field2,...". The transformations return the number of entries in the provided CSV, or the field at a specified position in the CSV. + +Available transformations in this class: + +### {csv.count} +Returns the number of entries in the provided CSV. +Example: +```opensips + +"a,b,c" {csv.count} = 3 + +``` + +### {csv.value,index} +Returns the entry at the specified position. Indexing starts from 0. Negative indexes are accepted, with -1 being the last entry. 'index' can be a variable. +Example: +```opensips + +"a,b,c" {csv.value,2} = c + +``` + +## SDP Transformations + +The name of the transformation starts with "sdp.". The value of the variable is considered to be a valid SDP body. The transformation returns a specific line in the SDP body. + +Available transformations in this class: + +### {sdp.line} +Returns the specified line in the SDP body. The transformations also accepts a second parameter, that specifies the line number of the first parameter's type to get from the SDP body. Indexing starts from 0. If the second parameter is missing, it is assumed to be 0. +Example: +```opensips + +if (is_method("INVITE")) + { + $var(aline) = $(rb{sdp.line,a,1}); + xlog("The second a line in the SDP body is $var(aline)\n"); + } + +if (is_method("INVITE")) + { + $var(mline) = $(rb{sdp.line,m}); + xlog("The first m line in the SDP body is $var(mline)\n"); + } + +``` + +### {sdp.stream} +Returns a specific stream (starting with the m= line) from an SDP body. The stream to be returned can be specified using its index within the body, or using on its media type. If specified as index, it starts at `0`, but it can also be negative, with `-1` being the last stream. If specified as media type, **only the first** stream of its type will be returned. If the media type or index does not exist, NULL is returned. + +Example: +```opensips + +if (is_method("INVITE")) + { + $var(first_stream) = $(rb{sdp.stream,0}); + xlog("First stream is $var(first_stream)\n"); + } + +if (is_method("INVITE")) + { + $var(audio_stream) = $(rb{sdp.stream,audio}); + xlog("Audio stream is $var(audio_stream)\n"); + } + +``` + +### {sdp.stream-delete} +Returns the specified SDP body with some of its streams deleted. The stream to be deleted can be specified using its index, or using on its media type. If specified as index, it starts at `0`, but it can also be negative, with `-1` being the last stream. If specified as media type, all streams matching will be deleted! If the media type or index does not exist, NULL is returned. + +Example: +```opensips + +if (is_method("INVITE")) + { + $var(new_body) = $(rb{sdp.stream-delete,0}); + xlog("SDP body without first stream is $var(new_body)\n"); + } + +if (is_method("INVITE")) + { + $var(new_body) = $(rb{sdp.stream-delete,video}); + xlog("SDP body without video stream is $var(new_body)\n"); + } + +``` + +## Regular Expression Transformations + +The name of the transformation starts with "re.". The input can be any string. + +### {re.subst,reg_exp} + +The reg_exp parameter can either be a plain string or a variable. +The format of the reg_exp is : +```opensips +/posix_match_expression/replacement_expression/flags +``` + +The flags can be +```opensips +i - match ignore case +s - match within multi-lines strings +g - replace all matches +``` + +Example: +```opensips + +$var(reg_input)="abc"; +$var(reg) = "/a/A/g"; +xlog("Applying reg exp $var(reg) to $var(reg_input) : $(var(reg_input){re.subst,$var(reg)})\n"); + +... +... +xlog("Applying reg /b/B/g to $var(reg_input) : $(var(reg_input){re.subst,/b/B/g})\n"); + +``` + +## Examples + +Within a variable, many transformation can be applied, being executed from left to right. + +* The length of the value of parameter at position 1 (remember 0 is first position, 1 is second position) + +```opensips + +$var(x) = "a=1;b=22;c=333"; +$(var(x){param.value,$(var(x){param.name,1})}{s.len}) = 2 + +``` + +* Test if whether is un-registration or not + +```opensips + +if(is_method("REGISTER") && is_present_hf("Expires") && $(hdr(Expires){s.int})==0) + xlog("This is a de-registration\n"); + +``` diff --git a/docs/manual/Templating-Config-Files.md b/docs/manual/Templating-Config-Files.md new file mode 100644 index 00000000000..0ed5cb76e1e --- /dev/null +++ b/docs/manual/Templating-Config-Files.md @@ -0,0 +1,193 @@ +--- +title: "Templating opensips.cfg Files" +description: "OpenSIPS 3.0+ releases offer script writers full support for piping the opensips.cfg file (including any other files imported by it) to a generic preprocessi..." +--- + +## Generic Preprocessing Support + +OpenSIPS 3.0+ releases offer script writers full support for piping the *opensips.cfg* file (including any other files imported by it) to a generic preprocessing command. This may be useful in scenarios where *opensips.cfg* must be parameterized (e.g. listening interfaces, ports, DB connectors, etc.) and deployed to multiple servers, in an automated fashion. The system administrator may achieve this using the "-p ``" (preprocessor) option. For example: + +```bash + +opensips -f opensips.cfg -p /bin/cat + +``` + +... is a basic use of the "-p" option, by supplying it with an "echo" preprocessor that receives input via **standard input** and mirrors it to **standard output**. From here, it's just a matter of choosing a templating language which fits the deployment requirements. Some basic substitutions can be done using, for example, *sed*: + +```bash + +opensips -f opensips.cfg -p "/bin/sed s/PRIVATE_IP/10.0.0.10/g" + +``` + +## Common Templating Languages + Examples + +Below are some examples of using more advanced templating languages on top of opensips.cfg, for cases where the target environment requires complex decision-making (if statements which enable/disable features, for loops over multiple listening interfaces, etc.). + +### GNU m4 + +[GNU m4](https://www.gnu.org/software/m4/) is a simplistic preprocessor with a mild learning curve, equipped with textual substitution, if statements and file includes among the most notable features. Here is an example integration with *opensips.cfg*: + +```opensips + +listen = udp:PRIVATE_IP:5060 +loadmodule "proto_udp.so" + +``` +**opensips.cfg.m4** + + + +```text + +divert(-1) +define(`PRIVATE_IP', `127.0.0.1') +divert(0)dnl + +``` +**env.m4** + + + +... and we start OpenSIPS using the below command, which will pipe *opensips.cfg.m4* to ''m4**s standard input, and then read the resulting file from its standard output:** + +```bash + +opensips -f opensips.cfg.m4 -p "m4 env.m4 -" + +``` + +### Jinja2 + +[Jinja2](http://jinja.pocoo.org/docs/2.10) is a modern templating language with a rich feature set, including textual replacement, if statements, for loops, a plethora of filters, file includes, and the list goes on! Unlike *m4*, Jinja2 does not currently have a standalone binary, rather it is provided via a Python package. Here is a way of integrating it with *opensips.cfg*: + + + +First, install the **jinja2** Python module with: **"pip install jinja2"**. Next, prepare the files: + + + +```opensips + +listen = udp:{{ private_ip }}:5060 +loadmodule "proto_udp.so" + +``` +**opensips.cfg.j2** + + + +```python + +import sys +import json +from jinja2 import Template + +t = Template("".join(sys.stdin.readlines())) + +with open('env.json') as f: + print(t.render(json.load(f))) + +``` +**opensips-preproc.py** + + + +```json + +{ + "private_ip": "127.0.0.1" +} + +``` +**env.json** + + + +... and we start OpenSIPS using: + +```bash + +opensips -f opensips.cfg.j2 -p "python opensips-preproc.py" + +``` + +### Embedded Ruby + +[Embedded Ruby (ERB)](https://ruby-doc.org/stdlib-2.6.1/libdoc/erb/rdoc/ERB.html) provides an easy to use, powerful templating system for Ruby. Using ERB, actual Ruby code can be added to any plain text document for the purposes of generating document information details and/or flow control. Let's see how it integrates with *opensips.cfg*! + + + +First, install the ERB package (for Debian/Ubuntu: **"apt install ruby-ejs"**). Next, prepare the files: + + + +```opensips + +listen = udp:<%= private_ip %>:5060 +loadmodule "proto_udp.so" + +``` +**opensips.cfg.erb** + + + +```rb + +#!/usr/bin/env ruby +require 'erb' +require './env.rb' + +template = ERB.new($stdin.read, nil, '-') +$stdout.write template.result($erb_context) + +``` +**~/src/opensips-preproc.rb** + + + +```rb + +$erb_context = binding +private_ip = '127.0.0.1' + +``` +**env.rb** + + + +... and OpenSIPS is now started using: + +```bash + +opensips -f opensips.cfg.erb -p "ruby opensips-preproc.rb" + +``` + +## Debugging Preprocessor Output + +Since the output of the preprocessor is never written to any file and is just consumed by OpenSIPS on each run, script developers may still visualize and debug the generated file during development by using a wrapper script over the preprocessing command such as the following: + +```bash + +#!/bin/bash + +m4 env.m4 - | tee >(grep -v __OSSPP_ >/tmp/opensips.cfg) + +``` +**~/src/preprocessor.sh** + + + +... and now we start OpenSIPS using: + +```bash + +opensips -f opensips.cfg.m4 -p ~/src/preprocessor.sh + +``` + + + +The same technique can be used for any other preprocessor. diff --git a/etc/opensips.cfg b/etc/opensips.cfg index f7ed7e613f2..c8a01b6ebf5 100644 --- a/etc/opensips.cfg +++ b/etc/opensips.cfg @@ -2,14 +2,12 @@ # OpenSIPS residential configuration script # by OpenSIPS Solutions # -# This script was generated via "make menuconfig", from -# the "Residential" scenario. -# You can enable / disable more features / functionalities by -# re-generating the scenario with different options.# +# This is a basic residential configuration. Ready-to-use M4 templates are +# available under examples/templates/. # -# Please refer to the Core CookBook at: -# https://opensips.org/Resources/DocsCookbooks -# for a explanation of possible statements, functions and parameters. +# Please refer to the OpenSIPS Manuals at: +# https://opensips.org/Documentation/Manuals +# for an explanation of available statements, functions and parameters. # @@ -262,4 +260,3 @@ failure_route[missed_call] { } - diff --git a/evi/event_interface.c b/evi/event_interface.c index e1c06504c58..cd6c1a7d4ad 100644 --- a/evi/event_interface.c +++ b/evi/event_interface.c @@ -173,7 +173,7 @@ void evi_remove_expired_subs(event_id_t id) { int evi_raise_event_msg(struct sip_msg *msg, event_id_t id, evi_params_t* params) { evi_subs_p subs, prev; - evi_async_ctx_t async_status = {NULL, NULL}; + evi_async_ctx_t evi_async_status = {NULL, NULL}; long now; int flags, pflags = 0; int ret = 0; @@ -240,7 +240,7 @@ int evi_raise_event_msg(struct sip_msg *msg, event_id_t id, evi_params_t* params lock_release(events[id].lock); ret += (subs->trans_mod->raise)(msg, &events[id].name, - subs->reply_sock, params, &async_status); + subs->reply_sock, params, &evi_async_status); lock_get(events[id].lock); subs->reply_sock->flags = flags; diff --git a/examples/templates/README.md b/examples/templates/README.md new file mode 100644 index 00000000000..30e74948245 --- /dev/null +++ b/examples/templates/README.md @@ -0,0 +1,61 @@ +# OpenSIPS configuration templates + +This directory contains ready-to-use GNU M4 templates for common OpenSIPS +deployments: + +- `loadbalancer.m4` +- `residential.m4` +- `trunking.m4` + +Source builds install these examples under +`$PREFIX/share/opensips/examples/templates/`. The default prefix places them +under `/usr/local/share/opensips/examples/templates/`; distribution packages +typically use `/usr/share/opensips/examples/templates/`. + +Each template begins with its available definitions. Set `LISTEN_IP` to the IP +address or interface OpenSIPS should listen on, set `DB_URL` to the database +connection URL, and set each feature switch to `yes` or `no`. Then customize +the remaining endpoint definitions as required by the deployment. + +To check the load-balancer template from the repository root, run: + +```console +opensips -C -f examples/templates/loadbalancer.m4 -p m4 +``` + +Remove `-C` to start OpenSIPS: + +```console +opensips -f examples/templates/loadbalancer.m4 -p m4 +``` + +The `-f` option selects the configuration template. The `-p m4` option pipes +that template through GNU M4 before OpenSIPS parses it. GNU M4 must be installed +and available in `PATH`. + +When using an installed distribution package, run the template from the shared +examples directory instead: + +```console +opensips -f /usr/share/opensips/examples/templates/loadbalancer.m4 -p m4 +``` + +Use the same commands with `residential.m4` or `trunking.m4` for the other +scenarios. + +## Create a standalone configuration file + +You can render any template into a regular OpenSIPS configuration file. For +example: + +```console +m4 examples/templates/loadbalancer.m4 > opensips.cfg +``` + +The resulting `opensips.cfg` no longer requires M4 preprocessing. You can edit +it freely and then check or start it as a normal configuration file: + +```console +opensips -C -f opensips.cfg +opensips -f opensips.cfg +``` diff --git a/examples/templates/loadbalancer.m4 b/examples/templates/loadbalancer.m4 new file mode 100644 index 00000000000..3dd11319a05 --- /dev/null +++ b/examples/templates/loadbalancer.m4 @@ -0,0 +1,297 @@ +# +# OpenSIPS loadbalancer script +# by OpenSIPS Solutions +# +# Edit the feature definitions below to customize this configuration. +# Start OpenSIPS with: +# opensips -f examples/templates/loadbalancer.m4 -p m4 +# +# Please refer to the OpenSIPS Manuals at: +# https://opensips.org/Documentation/Manuals +# for an explanation of available statements, functions and parameters. +# + +divert(-1) +define(`LISTEN_IP', `127.0.0.1') # IP address or interface used by the SIP sockets +define(`DB_URL', `mysql://opensips:opensipsrw@localhost/opensips') # Database URL used by modules +define(`ENABLE_TCP', `no') # OpenSIPS will listen on TCP for SIP requests +define(`ENABLE_TLS', `no') # OpenSIPS will listen on TLS for SIP requests +define(`USE_DBACC', `no') # OpenSIPS will save ACC entries in DB for all calls +define(`USE_DISPATCHER', `no') # OpenSIPS will use DISPATCHER instead of Load-Balancer for distributing the traffic +define(`DISABLE_PINGING', `yes') # OpenSIPS will not ping at all the destinations (otherwise it will ping when detected as failed) +define(`USE_HTTP_MANAGEMENT_INTERFACE', `no') # OpenSIPS will provide a WEB Management Interface on port 8888 +divert(0)dnl + +####### Global Parameters ######### + +/* uncomment the following lines to enable debugging */ +#debug_mode=yes + +log_level=3 +xlog_level=3 +stderror_enabled=no +syslog_enabled=yes +syslog_facility=LOG_LOCAL0 + +udp_workers=4 + +/* uncomment the next line to enable the auto temporary blacklisting of + not available destinations (default disabled) */ +#disable_dns_blacklist=no + +/* uncomment the next line to enable IPv6 lookup after IPv4 dns + lookup failures (default disabled) */ +#dns_try_ipv6=yes + + +socket=udp:LISTEN_IP:5060 +ifelse(ENABLE_TCP, `yes', `socket=tcp:LISTEN_IP:5060',`') +ifelse(ENABLE_TLS,`yes',`socket=tls:LISTEN_IP:5061',`') + +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`define(`HTTPD_NEEDED',`yes')', `') + +####### Modules Section ######## + +#set module path +mpath="/usr/local/lib/opensips/modules/" + +ifdef(`HTTPD_NEEDED',`#### HTTPD module +loadmodule "httpd.so" +modparam("httpd", "port", 8888)') + +#### SIGNALING module +loadmodule "signaling.so" + +#### StateLess module +loadmodule "sl.so" + +#### Transaction Module +loadmodule "tm.so" +modparam("tm", "fr_timeout", 5) +modparam("tm", "fr_inv_timeout", 30) +modparam("tm", "restart_fr_on_each_reply", 0) +modparam("tm", "onreply_avp_mode", 1) + +#### Record Route Module +loadmodule "rr.so" +/* do not append from tag to the RR (no need for this script) */ +modparam("rr", "append_fromtag", 0) + +#### MAX ForWarD module +loadmodule "maxfwd.so" + +#### SIP MSG OPerationS module +loadmodule "sipmsgops.so" + +#### FIFO Management Interface +loadmodule "mi_fifo.so" +modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") +modparam("mi_fifo", "fifo_mode", 0666) + +#### MYSQL module +loadmodule "db_mysql.so" + +#### SQLOPS module +loadmodule "sqlops.so" + +#### ACCounting module +loadmodule "acc.so" +/* what special events should be accounted ? */ +modparam("acc", "early_media", 0) +modparam("acc", "report_cancels", 0) +/* by default we do not adjust the direct of the sequential requests. + if you enable this parameter, be sure to enable "append_fromtag" + in "rr" module */ +modparam("acc", "detect_direction", 0) +ifelse(USE_DBACC,`yes',`modparam("acc", "db_url", "DB_URL") +', `') + +ifelse(USE_DISPATCHER,`no',`#### DIALOG module +loadmodule "dialog.so" +modparam("dialog", "dlg_match_mode", 1) +modparam("dialog", "default_timeout", 21600) # 6 hours timeout +modparam("dialog", "db_mode", 2) +modparam("dialog", "db_url", "DB_URL") +',`') + +ifelse(USE_DISPATCHER,`yes',`#### DISPATCHER module +loadmodule "dispatcher.so" +modparam("dispatcher", "db_url", "DB_URL") +modparam("dispatcher", "ds_ping_method", "OPTIONS") +modparam("dispatcher", "ds_probing_mode", 0) +ifelse(DISABLE_PROBING,`yes',` +modparam("dispatcher", "ds_ping_interval", 0) +', ` +modparam("dispatcher", "ds_ping_interval", 30) +') +', `#### LOAD BALANCER module +loadmodule "load_balancer.so" +modparam("load_balancer", "db_url", "DB_URL") +modparam("load_balancer", "probing_method", "OPTIONS") +ifelse(DISABLE_PROBING,`yes',` +modparam("load_balancer", "probing_interval", 0) +', ` +modparam("load_balancer", "probing_interval", 30) +') +') + +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`#### MI_HTTP module +loadmodule "mi_http.so" +',`') + +loadmodule "proto_udp.so" + +ifelse(ENABLE_TCP, `yes', `loadmodule "proto_tcp.so"' , `') +ifelse(ENABLE_TLS, `yes', `loadmodule "proto_tls.so" +loadmodule "tls_wolfssl.so" +loadmodule "tls_mgm.so" +modparam("tls_mgm","server_domain", "default") +modparam("tls_mgm","match_ip_address", "[default]*") +modparam("tls_mgm","verify_cert", "[default]1") +modparam("tls_mgm","require_cert", "[default]0") +modparam("tls_mgm","tls_method", "[default]TLSv1") +modparam("tls_mgm","certificate", "[default]/etc/opensips/tls/user/user-cert.pem") +modparam("tls_mgm","private_key", "[default]/etc/opensips/tls/user/user-privkey.pem") +modparam("tls_mgm","ca_list", "[default]/etc/opensips/tls/user/user-calist.pem") +' , `') + +####### Routing Logic ######## + + +# main request routing logic + +route{ + + if (!mf_process_maxfwd_header(10)) { + send_reply(483,"Too Many Hops"); + exit; + } + + if (has_totag()) { + + # handle hop-by-hop ACK (no routing required) + if ( is_method("ACK") && t_check_trans() ) { + t_relay(); + exit; + } + + # sequential request withing a dialog should + # take the path determined by record-routing + if ( !loose_route() ) { + # we do record-routing for all our traffic, so we should not + # receive any sequential requests without Route hdr. + send_reply(404,"Not here"); + exit; + } + ifelse(USE_DISPATCHER,`no',` + # validate the sequential request against dialog + if ( $DLG_status!=NULL && !validate_dialog() ) { + xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n"); + ## exit; + } + ',`')dnl + + if (is_method("BYE")) { + # do accounting even if the transaction fails + ifelse(USE_DBACC,`yes',`do_accounting("db","failed"); + ', `do_accounting("log","failed");') + } + + # route it out to whatever destination was set by loose_route() + # in $du (destination URI). + route(RELAY); + exit; + } + + #### INITIAL REQUESTS + + # CANCEL processing + if (is_method("CANCEL")) { + if (t_check_trans()) + t_relay(); + exit; + } else if (!is_method("INVITE")) { + send_reply(405,"Method Not Allowed"); + exit; + } + + if ($rU==NULL) { + # request with no Username in RURI + send_reply(484,"Address Incomplete"); + exit; + } + + t_check_trans(); + + # preloaded route checking + if (loose_route()) { + xlog("L_ERR", + "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]"); + if (!is_method("ACK")) + send_reply(403,"Preload Route denied"); + exit; + } + + # record routing + record_route(); + + ifelse(USE_DBACC,`yes',`do_accounting("db"); + ', `do_accounting("log");') + + ifelse(USE_DISPATCHER,`yes',` + if ( !ds_select_dst(1,4) ) { + ',` + if ( !lb_start(1,"channel")) { + ') + send_reply(500,"No Destination available"); + exit; + } + + + t_on_failure("GW_FAILOVER"); + + route(RELAY); +} + + +route[RELAY] { + if (!t_relay()) { + sl_reply_error(); + } + exit; +} + + +failure_route[GW_FAILOVER] { + if (t_was_cancelled()) { + exit; + } + + # failure detection with redirect to next available trunk + if (t_check_status("(408)|([56][0-9][0-9])")) { + xlog("Failed trunk $rd/$du detected \n"); + + ifelse(USE_DISPATCHER,`yes',` + if ( ds_next_dst() ) { + ',` + if ( lb_next() ) { + ') + t_on_failure("GW_FAILOVER"); + t_relay(); + exit; + } + + send_reply(500,"All GW are down"); + } +} + +ifelse(USE_DISPATCHER,`no',` +local_route { + if (is_method("BYE") && $DLG_dir=="UPSTREAM") { + ifelse(USE_DBACC,`yes',` + acc_db_request("200 Dialog Timeout", "acc"); + ',` + acc_log_request("200 Dialog Timeout"); + ') + } +}',`') diff --git a/examples/templates/residential.m4 b/examples/templates/residential.m4 new file mode 100644 index 00000000000..0285baf50e5 --- /dev/null +++ b/examples/templates/residential.m4 @@ -0,0 +1,561 @@ +# +# OpenSIPS residential configuration script +# by OpenSIPS Solutions +# +# Edit the feature definitions below to customize this configuration. +# Start OpenSIPS with: +# opensips -f examples/templates/residential.m4 -p m4 +# +# Please refer to the OpenSIPS Manuals at: +# https://opensips.org/Documentation/Manuals +# for an explanation of available statements, functions and parameters. +# + +divert(-1) +define(`LISTEN_IP', `127.0.0.1') # IP address or interface used by the SIP sockets +define(`DB_URL', `mysql://opensips:opensipsrw@localhost/opensips') # Database URL used by modules +define(`NATPING_FROM', `sip:pinger@127.0.0.1') # From URI used by NAT keepalive requests +define(`RTPPROXY_SOCKET', `udp:localhost:12221') # RTPProxy control socket +define(`PSTN_IP', `11.22.33.44') # Statically configured PSTN gateway address +define(`PSTN_PORT', `5060') # Statically configured PSTN gateway port +define(`VOICEMAIL_URI', `sip:127.0.0.2:5060') # Voicemail server destination +define(`TLS_DOMAIN_1', `tls_domain1.net') # First domain routed over the forced TLS socket +define(`TLS_DOMAIN_2', `tls_domain2.net') # Second domain routed over the forced TLS socket +define(`TLS_SEND_SOCKET', `tls:LISTEN_IP:5061') # Forced socket for interdomain TLS traffic +define(`ENABLE_TCP', `no') # OpenSIPS will listen on TCP for SIP requests +define(`ENABLE_TLS', `no') # OpenSIPS will listen on TLS for SIP requests +define(`USE_ALIASES', `no') # OpenSIPS will allow the use of Aliases for SIP users +define(`USE_AUTH', `no') # OpenSIPS will authenticate Register & Invite requests +define(`USE_DBACC', `no') # OpenSIPS will save ACC entries in DB for all calls +define(`USE_DBUSRLOC', `no') # OpenSIPS will store UsrLoc entries in the DB +define(`USE_DIALOG', `no') # OpenSIPS will keep track of active dialogs +define(`USE_MULTIDOMAIN', `no') # OpenSIPS will handle multiple domains for subscribers +define(`USE_NAT', `no') # OpenSIPS will try to cope with NAT by fixing SIP msgs and engaging RTPProxy +define(`USE_PRESENCE', `no') # OpenSIPS will act as a Presence server +define(`USE_DIALPLAN', `no') # OpenSIPS will use dialplan for transformation of local numbers +define(`VM_DIVERSION', `no') # OpenSIPS will redirect to VM calls not reaching the subscribers +define(`HAVE_INBOUND_PSTN', `no') # OpenSIPS will accept calls from PSTN gateways (with static IP authentication) +define(`HAVE_OUTBOUND_PSTN', `no') # OpenSIPS will send numerical dials to PSTN gateways (with static IP definition) +define(`USE_DR_PSTN', `no') # OpenSIPS will use Dynamic Routing Support for PSTN interconnection +define(`USE_HTTP_MANAGEMENT_INTERFACE', `no') # OpenSIPS will provide a WEB Management Interface on port 8888 +divert(0)dnl + +####### Global Parameters ######### + +/* uncomment the following lines to enable debugging */ +#debug_mode=yes + +log_level=3 +xlog_level=3 +stderror_enabled=no +syslog_enabled=yes +syslog_facility=LOG_LOCAL0 + +udp_workers=4 + +/* uncomment the next line to enable the auto temporary blacklisting of + not available destinations (default disabled) */ +#disable_dns_blacklist=no + +/* uncomment the next line to enable IPv6 lookup after IPv4 dns + lookup failures (default disabled) */ +#dns_try_ipv6=yes + + +socket=udp:LISTEN_IP:5060 +ifelse(ENABLE_TCP, `yes', `socket=tcp:LISTEN_IP:5060', `') +ifelse(ENABLE_TLS,`yes',`socket=tls:LISTEN_IP:5061', `') + +####### Modules Section ######## + +#set module path +mpath="/usr/local/lib/opensips/modules/" + +#### SIGNALING module +loadmodule "signaling.so" + +#### StateLess module +loadmodule "sl.so" + +#### Transaction Module +loadmodule "tm.so" +modparam("tm", "fr_timeout", 5) +modparam("tm", "fr_inv_timeout", 30) +modparam("tm", "restart_fr_on_each_reply", 0) +modparam("tm", "onreply_avp_mode", 1) + +#### Record Route Module +loadmodule "rr.so" +/* do not append from tag to the RR (no need for this script) */ +modparam("rr", "append_fromtag", 0) + +#### MAX ForWarD module +loadmodule "maxfwd.so" + +#### SIP MSG OPerationS module +loadmodule "sipmsgops.so" + +#### FIFO Management Interface +loadmodule "mi_fifo.so" +modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") +modparam("mi_fifo", "fifo_mode", 0666) + +ifelse(USE_DR_PSTN,`yes',`ifelse(HAVE_INBOUND_PSTN,`yes',`define(`USE_DR_MODULE',`yes')',HAVE_OUTBOUND_PSTN,`yes',`define(`USE_DR_MODULE',`yes')',)',`')dnl +ifelse(USE_AUTH,`yes',`define(`DB_NEEDED',`yes')',USE_MULTIDOMAIN,`yes',`define(`DB_NEEDED',`yes')',USE_PRESENCE,`yes',`define(`DB_NEEDED',`yes')',USE_DBACC,`yes',`define(`DB_NEEDED',`yes')',USE_DBUSRLOC,`yes',`define(`DB_NEEDED',`yes')',USE_DIALOG,`yes',`define(`DB_NEEDED',`yes')',USE_DIALPLAN,`yes',`define(`DB_NEEDED',`yes')',USE_DR_MODULE,`yes',`define(`DB_NEEDED',`yes')',)dnl +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`define(`HTTPD_NEEDED',`yes')',`')dnl +ifdef(`DB_NEEDED',`#### MYSQL module +loadmodule "db_mysql.so" + +')dnl +ifdef(`HTTPD_NEEDED',`#### HTTPD module +loadmodule "httpd.so" +modparam("httpd", "port", 8888) + +')dnl +#### USeR LOCation module +loadmodule "usrloc.so" +modparam("usrloc", "nat_bflag", "NAT") +ifelse(USE_DBUSRLOC,`yes',`modparam("usrloc", "working_mode_preset", "single-instance-sql-write-back") +modparam("usrloc", "db_url", "DB_URL") +', `modparam("usrloc", "working_mode_preset", "single-instance-no-db")') + +#### REGISTRAR module +loadmodule "registrar.so" +modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT") +ifelse(USE_NAT,`yes',`modparam("registrar", "received_avp", "$avp(received_nh)")',`')dnl +/* uncomment the next line not to allow more than 10 contacts per AOR */ +#modparam("registrar", "max_contacts", 10) + +#### ACCounting module +loadmodule "acc.so" +/* what special events should be accounted ? */ +modparam("acc", "early_media", 0) +modparam("acc", "report_cancels", 0) +/* by default we do not adjust the direct of the sequential requests. + if you enable this parameter, be sure to enable "append_fromtag" + in "rr" module */ +modparam("acc", "detect_direction", 0) +ifelse(USE_DBACC,`yes',`modparam("acc", "db_url", "DB_URL") +', `')dnl + +ifelse(USE_AUTH,`yes',`#### AUTHentication modules +loadmodule "auth.so" +loadmodule "auth_db.so" +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "db_url", "DB_URL") +modparam("auth_db", "load_credentials", "") + +', `')dnl +ifelse(USE_ALIASES,`yes',`#### ALIAS module +loadmodule "alias_db.so" +modparam("alias_db", "db_url", "DB_URL") + +', `')dnl +ifelse(USE_MULTIDOMAIN,`yes',`#### DOMAIN module +loadmodule "domain.so" +modparam("domain", "db_url", "DB_URL") +modparam("domain", "db_mode", 1) # Use caching +modparam("auth_db|usrloc", "use_domain", 1) + +', `')dnl +ifelse(USE_PRESENCE,`yes',`#### PRESENCE modules +loadmodule "xcap.so" +loadmodule "presence.so" +loadmodule "presence_xml.so" +modparam("xcap|presence", "db_url", "DB_URL") +modparam("presence_xml", "force_active", 1) +modparam("presence", "fallback2db", 0) + +', `')dnl +ifelse(USE_DIALOG,`yes',`#### DIALOG module +loadmodule "dialog.so" +modparam("dialog", "dlg_match_mode", 1) +modparam("dialog", "default_timeout", 21600) # 6 hours timeout +modparam("dialog", "db_mode", 2) +modparam("dialog", "db_url", "DB_URL") + +',`')dnl +ifelse(USE_NAT,`yes',`#### NAT modules +loadmodule "nathelper.so" +modparam("nathelper", "natping_interval", 10) +modparam("nathelper", "ping_nated_only", 1) +modparam("nathelper", "sipping_bflag", "SIP_PING_FLAG") +modparam("nathelper", "sipping_from", "NATPING_FROM") +modparam("nathelper", "received_avp", "$avp(received_nh)") + +loadmodule "rtpproxy.so" +modparam("rtpproxy", "rtpproxy_sock", "RTPPROXY_SOCKET") + +',`')dnl +ifelse(USE_DIALPLAN,`yes',`#### DIALPLAN module +loadmodule "dialplan.so" +modparam("dialplan", "db_url", "DB_URL") + +',`')dnl +ifelse(USE_DR_MODULE,`yes',`#### DYNAMMIC ROUTING module +loadmodule "drouting.so" +modparam("drouting", "db_url", "DB_URL") + +',`')dnl +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`#### MI_HTTP module +loadmodule "mi_http.so" + +',`')dnl +loadmodule "proto_udp.so" +ifelse(ENABLE_TCP, `yes', `loadmodule "proto_tcp.so"' , `') +ifelse(ENABLE_TLS, `yes', `loadmodule "proto_tls.so" +loadmodule "tls_wolfssl.so" +loadmodule "tls_mgm.so" +modparam("tls_mgm","server_domain", "default") +modparam("tls_mgm","match_ip_address", "[default]*") +modparam("tls_mgm","verify_cert", "[default]1") +modparam("tls_mgm","require_cert", "[default]0") +modparam("tls_mgm","tls_method", "[default]TLSv1") +modparam("tls_mgm","certificate", "[default]/etc/opensips/tls/user/user-cert.pem") +modparam("tls_mgm","private_key", "[default]/etc/opensips/tls/user/user-privkey.pem") +modparam("tls_mgm","ca_list", "[default]/etc/opensips/tls/user/user-calist.pem") +' , `')dnl + +####### Routing Logic ######## + +# main request routing logic + +route{ +ifelse(USE_NAT,`yes',` + # initial NAT handling; detect if the request comes from behind a NAT + # and apply contact fixing + force_rport(); + if (nat_uac_test("diff-port-src-via,private-via,diff-ip-src-via,private-contact")) { + if (is_method("REGISTER")) { + fix_nated_register(); + setbflag("NAT"); + } else { + fix_nated_contact(); + setflag("NAT"); + } + } +',`')dnl + + if (!mf_process_maxfwd_header(10)) { + send_reply(483,"Too Many Hops"); + exit; + } + + if (has_totag()) { + + # handle hop-by-hop ACK (no routing required) + if ( is_method("ACK") && t_check_trans() ) { + t_relay(); + exit; + } + + # sequential request within a dialog should + # take the path determined by record-routing + if ( !loose_route() ) { +ifelse(USE_PRESENCE,`yes', +` if (is_method("SUBSCRIBE") && is_myself("$rd")) { + # in-dialog subscribe requests + route(handle_presence); + exit; + } +',`')dnl + # we do record-routing for all our traffic, so we should not + # receive any sequential requests without Route hdr. + send_reply(404,"Not here"); + exit; + } +ifelse(USE_DIALOG,`yes',` + # validate the sequential request against dialog + if ( $DLG_status!=NULL && !validate_dialog() ) { + xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n"); + ## exit; + } +',`')dnl + + if (is_method("BYE")) { + # do accounting even if the transaction fails + ifelse(USE_DBACC,`yes',`do_accounting("db","failed"); + ', `do_accounting("log","failed");') + } + +ifelse(USE_NAT,`yes',` + if (check_route_param("nat=yes")) + setflag("NAT"); +',`')dnl + # route it out to whatever destination was set by loose_route() + # in $du (destination URI). + route(relay); + exit; + } + + # CANCEL processing + if (is_method("CANCEL")) { + if (t_check_trans()) + t_relay(); + exit; + } + + # absorb retransmissions, but do not create transaction + t_check_trans(); + + if ( !(is_method("REGISTER") ifelse(HAVE_INBOUND_PSTN,`yes',` ifelse(USE_DR_MODULE,`yes',`|| is_from_gw()',`|| ($si==PSTN_IP && $sp=PSTN_PORT)')',`') ) ) { + ifelse(USE_MULTIDOMAIN,`yes',` + if (is_from_local()) {',` + if (is_myself("$fd")) { + ')dnl + ifelse(USE_AUTH,`yes',` + # authenticate if from local subscriber + # authenticate all initial non-REGISTER request that pretend to be + # generated by local subscriber (domain from FROM URI is local) + if (!proxy_authorize("", "subscriber")) { + proxy_challenge("", "auth"); + exit; + } + if ($au!=$fU) { + send_reply(403,"Forbidden auth ID"); + exit; + } + + consume_credentials(); + # caller authenticated + ',`') + } else { + # if caller is not local, then called number must be local + ifelse(USE_MULTIDOMAIN,`yes',` + if (!is_uri_host_local())',` + if (!is_myself("$rd"))') { + send_reply(403,"Relay Forbidden"); + exit; + } + } + + } + + # preloaded route checking + if (loose_route()) { + xlog("L_ERR", + "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]"); + if (!is_method("ACK")) + send_reply(403,"Preload Route denied"); + exit; + } + + # record routing + if (!is_method("REGISTER|MESSAGE")) + record_route(); + + # account only INVITEs + if (is_method("INVITE")) { + ifelse(USE_DIALOG,`yes',` + # create dialog with timeout + if ( !create_dialog("B") ) { + send_reply(500,"Internal Server Error"); + exit; + } + ',`') + ifelse(USE_DBACC,`yes',`do_accounting("db"); + ', `do_accounting("log");') + } + + ifelse(USE_MULTIDOMAIN,`yes',` + if (!is_uri_host_local())',` + if (!is_myself("$rd"))') { + append_hf("P-hint: outbound\r\n"); + ifelse(ENABLE_TLS,`yes',` + # if you have some interdomain connections via TLS + ##if ($rd=="TLS_DOMAIN_1" + ## || $rd=="TLS_DOMAIN_2" + ##) { + ## force_send_socket("TLS_SEND_SOCKET"); + ##} + ',`') + route(relay); + } + + # requests for my domain + ifelse(USE_PRESENCE,`yes',` + if( is_method("PUBLISH|SUBSCRIBE")) + route(handle_presence);',` + if (is_method("PUBLISH|SUBSCRIBE")) { + send_reply(503, "Service Unavailable"); + exit; + }') + + if (is_method("REGISTER")) { + ifelse(USE_AUTH,`yes',`# authenticate the REGISTER requests + if (!www_authorize("", "subscriber")) { + www_challenge("", "auth"); + exit; + } + + if ($au!=$tU) { + send_reply(403,"Forbidden auth ID"); + exit; + }',`')dnl +ifelse(ENABLE_TCP, `yes', ifelse(ENABLE_TLS, `yes', ` + if ($socket_in(proto) == "tcp" || $socket_in(proto) == "tls") + setflag("TCP_PERSISTENT"); +', ` + if ($socket_in(proto) == "tcp") + setflag("TCP_PERSISTENT"); +'), ifelse(ENABLE_TLS, `yes', ` + if ($socket_in(proto) == "tls") + setflag("TCP_PERSISTENT"); +', +`'))dnl + ifelse(USE_NAT,`yes',`if (isflagset("NAT")) { + setbflag("SIP_PING_FLAG"); + }',`')dnl + + # store the registration and generate a SIP reply + if (!save("location")) + xlog("failed to register AoR $tu\n"); + + exit; + } + + if ($rU==NULL) { + # request with no Username in RURI + send_reply(484,"Address Incomplete"); + exit; + } + + ifelse(USE_ALIASES,`yes',` + # apply DB based aliases + alias_db_lookup("dbaliases");',`') + + ifelse(USE_DIALPLAN,`yes',` + # apply transformations from dialplan table + dp_translate( 0, "$rU", $rU);',`') + + ifelse(HAVE_OUTBOUND_PSTN,`yes',` + if ($rU=~"^\+[1-9][0-9]+$") { + ifelse(USE_DR_MODULE,`yes',` + strip(1); + if (!do_routing(0)) { + send_reply(500,"No PSTN Route found"); + exit; + } + ',` + $rd="PSTN_IP"; + $rp=PSTN_PORT; + ') + route(relay); + exit; + } + ',`') + + # do lookup with method filtering + if (!lookup("location", "method-filtering")) { + ifelse(USE_AUTH,`yes',`if (!db_does_uri_exist("$ru","subscriber")) { + send_reply(420,"Bad Extension"); + exit; + }',`') + ifelse(VM_DIVERSION,`yes',` + # redirect to a different VM system + $du = "VOICEMAIL_URI"; + route(relay); + ',` + t_reply(404, "Not Found"); + exit;') + } + + ifelse(USE_NAT,`yes',`if (isbflagset("NAT")) setflag("NAT");',`') + + # when routing via usrloc, log the missed calls also + ifelse(USE_DBACC,`yes',`do_accounting("db","missed"); + ', `do_accounting("log","missed");') + route(relay); +} + + +route[relay] { + # for INVITEs enable some additional helper routes + if (is_method("INVITE")) { + + ifelse(USE_NAT,`yes',`if (isflagset("NAT") && has_body("application/sdp")) { + rtpproxy_offer("ro"); + }',`') + + t_on_branch("per_branch_ops"); + t_on_reply("handle_nat"); + t_on_failure("missed_call"); + } + + ifelse(USE_NAT,`yes',`if (isflagset("NAT")) { + add_rr_param(";nat=yes"); + }',`') + + if (!t_relay()) { + send_reply(500,"Internal Error"); + } + exit; +} + +ifelse(USE_PRESENCE,`yes',` +# Presence route +route[handle_presence] +{ + if (!t_newtran()) { + sl_reply_error(); + exit; + } + + if(is_method("PUBLISH")) { + handle_publish(); + } else + if( is_method("SUBSCRIBE")) { + handle_subscribe(); + } + + exit; +}',`') + + +branch_route[per_branch_ops] { + xlog("new branch at $ru\n"); +} + + +onreply_route[handle_nat] { + ifelse(USE_NAT,`yes',`if (nat_uac_test("private-contact")) + fix_nated_contact(); + if ( isflagset("NAT") && has_body("application/sdp") ) + rtpproxy_answer("ro");',`') + xlog("incoming reply\n"); +} + + +failure_route[missed_call] { + if (t_was_cancelled()) { + exit; + } + + # uncomment the following lines if you want to block client + # redirect based on 3xx replies. + ##if (t_check_status("3[0-9][0-9]")) { + ##t_reply(404,"Not found"); + ## exit; + ##} + + ifelse(VM_DIVERSION,`yes',` + # redirect the failed to a different VM system + if (t_check_status("486|408")) { + $du = "VOICEMAIL_URI"; + # do not set the missed call flag again + route(relay); + }',`') +} + + +ifelse(USE_DIALOG,`yes',` +local_route { + if (is_method("BYE") && $DLG_dir=="UPSTREAM") { + ifelse(USE_DBACC,`yes',` + acc_db_request("200 Dialog Timeout", "acc"); + ',` + acc_log_request("200 Dialog Timeout"); + ') + } +}',`') diff --git a/examples/templates/trunking.m4 b/examples/templates/trunking.m4 new file mode 100644 index 00000000000..f2be38549b7 --- /dev/null +++ b/examples/templates/trunking.m4 @@ -0,0 +1,323 @@ +# +# OpenSIPS trunking script +# by OpenSIPS Solutions +# +# Edit the feature definitions below to customize this configuration. +# Start OpenSIPS with: +# opensips -f examples/templates/trunking.m4 -p m4 +# +# Please refer to the OpenSIPS Manuals at: +# https://opensips.org/Documentation/Manuals +# for an explanation of available statements, functions and parameters. +# + +divert(-1) +define(`LISTEN_IP', `127.0.0.1') # IP address or interface used by the SIP sockets +define(`DB_URL', `mysql://opensips:opensipsrw@localhost/opensips') # Database URL used by modules +define(`ENABLE_TCP', `no') # OpenSIPS will listen on TCP for SIP requests +define(`ENABLE_TLS', `no') # OpenSIPS will listen on TLS for SIP requests +define(`USE_DBACC', `no') # OpenSIPS will save ACC entries in DB for all calls +define(`USE_DIALPLAN', `no') # OpenSIPS will use dialplan for transformation of local numbers +define(`USE_DIALOG', `no') # OpenSIPS will keep track of active dialogs +define(`DO_CALL_LIMITATION', `no') # OpenSIPS will limit the number of parallel calls per trunk +define(`USE_HTTP_MANAGEMENT_INTERFACE', `no') # OpenSIPS will provide a WEB Management Interface on port 8888 +divert(0)dnl + +####### Global Parameters ######### + +/* uncomment the following lines to enable debugging */ +#debug_mode=yes + +log_level=3 +xlog_level=3 +stderror_enabled=no +syslog_enabled=yes +syslog_facility=LOG_LOCAL0 + +udp_workers=4 + +/* uncomment the next line to enable the auto temporary blacklisting of + not available destinations (default disabled) */ +#disable_dns_blacklist=no + +/* uncomment the next line to enable IPv6 lookup after IPv4 dns + lookup failures (default disabled) */ +#dns_try_ipv6=yes + + +socket=udp:LISTEN_IP:5060 +ifelse(ENABLE_TCP, `yes', `socket=tcp:LISTEN_IP:5060',`') +ifelse(ENABLE_TLS,`yes',`socket=tls:LISTEN_IP:5061',`') + +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`define(`HTTPD_NEEDED',`yes')', `') + +####### Modules Section ######## + +#set module path +mpath="/usr/local/lib/opensips/modules/" + +ifdef(`HTTPD_NEEDED',`#### HTTPD module +loadmodule "httpd.so" +modparam("httpd", "port", 8888)') + +#### SIGNALING module +loadmodule "signaling.so" + +#### StateLess module +loadmodule "sl.so" + +#### Transaction Module +loadmodule "tm.so" +modparam("tm", "fr_timeout", 5) +modparam("tm", "fr_inv_timeout", 30) +modparam("tm", "restart_fr_on_each_reply", 0) +modparam("tm", "onreply_avp_mode", 1) + +#### Record Route Module +loadmodule "rr.so" +/* do not append from tag to the RR (no need for this script) */ +modparam("rr", "append_fromtag", 0) + +#### MAX ForWarD module +loadmodule "maxfwd.so" + +#### SIP MSG OPerations module +loadmodule "sipmsgops.so" + +#### FIFO Management Interface +loadmodule "mi_fifo.so" +modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") +modparam("mi_fifo", "fifo_mode", 0666) + +#### MYSQL module +loadmodule "db_mysql.so" + +#### SQLOPS module +loadmodule "sqlops.so" + +#### DYNAMIC ROUTING module +loadmodule "drouting.so" +modparam("drouting", "db_url", "DB_URL") + +#### PERMISSIONS module +loadmodule "permissions.so" +modparam("permissions", "db_url", "DB_URL") + +#### ACCounting module +loadmodule "acc.so" +/* what special events should be accounted ? */ +modparam("acc", "early_media", 0) +modparam("acc", "report_cancels", 0) +/* by default we do not adjust the direct of the sequential requests. + if you enable this parameter, be sure to enable "append_fromtag" + in "rr" module */ +modparam("acc", "detect_direction", 0) +ifelse(USE_DBACC,`yes',`modparam("acc", "db_url", "DB_URL") +', `') + +ifelse(USE_DIALOG,`yes',`#### DIALOG module +loadmodule "dialog.so" +modparam("dialog", "dlg_match_mode", 1) +modparam("dialog", "default_timeout", 21600) # 6 hours timeout +modparam("dialog", "db_mode", 2) +modparam("dialog", "db_url", "DB_URL") +ifelse(DO_CALL_LIMITATION,`yes',` +modparam("dialog", "profiles_with_value", "trunkCalls") +',`') +',`') + +ifelse(USE_DIALPLAN,`yes',`#### DIALPLAN module +loadmodule "dialplan.so" +modparam("dialplan", "db_url", "DB_URL") +',`') + +ifelse(USE_HTTP_MANAGEMENT_INTERFACE,`yes',`#### MI_HTTP module +loadmodule "mi_http.so" +',`') + +loadmodule "proto_udp.so" + +ifelse(ENABLE_TCP, `yes', `loadmodule "proto_tcp.so"' , `') +ifelse(ENABLE_TLS, `yes', `loadmodule "proto_tls.so" +loadmodule "tls_wolfssl.so" +loadmodule "tls_mgm.so" +modparam("tls_mgm","server_domain", "default") +modparam("tls_mgm","match_ip_address", "[default]*") +modparam("tls_mgm","verify_cert", "[default]1") +modparam("tls_mgm","require_cert", "[default]0") +modparam("tls_mgm","tls_method", "[default]TLSv1") +modparam("tls_mgm","certificate", "[default]/etc/opensips/tls/user/user-cert.pem") +modparam("tls_mgm","private_key", "[default]/etc/opensips/tls/user/user-privkey.pem") +modparam("tls_mgm","ca_list", "[default]/etc/opensips/tls/user/user-calist.pem") +' , `') + +####### Routing Logic ######## + +# main request routing logic + +route{ + + if (!mf_process_maxfwd_header(10)) { + send_reply(483,"Too Many Hops"); + exit; + } + + if ( check_source_address( 1, $avp(trunk_attrs)) ) { + # request comes from trunks + setflag("IS_TRUNK"); + } else if ( is_from_gw() ) { + # request comes from GWs + } else { + send_reply(403,"Forbidden"); + exit; + } + + if (has_totag()) { + + # handle hop-by-hop ACK (no routing required) + if ( is_method("ACK") && t_check_trans() ) { + t_relay(); + exit; + } + + # sequential request withing a dialog should + # take the path determined by record-routing + if ( !loose_route() ) { + # we do record-routing for all our traffic, so we should not + # receive any sequential requests without Route hdr. + send_reply(404,"Not here"); + exit; + } + ifelse(USE_DIALOG,`yes',` + # validate the sequential request against dialog + if ( $DLG_status!=NULL && !validate_dialog() ) { + xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n"); + ## exit; + } + ',`') + + if (is_method("BYE")) { + # do accounting even if the transaction fails + ifelse(USE_DBACC,`yes',`do_accounting("db","failed"); + ', `do_accounting("log","failed");') + } + + # route it out to whatever destination was set by loose_route() + # in $du (destination URI). + route(RELAY); + exit; + } + + #### INITIAL REQUESTS + + if ( !isflagset("IS_TRUNK") ) { + ## accept new calls only from trunks + send_reply(403,"Not from trunk"); + exit; + } + + # CANCEL processing + if (is_method("CANCEL")) { + if (t_check_trans()) + t_relay(); + exit; + } else if (!is_method("INVITE")) { + send_reply(405,"Method Not Allowed"); + exit; + } + + if ($rU==NULL) { + # request with no Username in RURI + send_reply(484,"Address Incomplete"); + exit; + } + + t_check_trans(); + + # preloaded route checking + if (loose_route()) { + xlog("L_ERR", + "Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]"); + if (!is_method("ACK")) + send_reply(403,"Preload Route denied"); + exit; + } + + # record routing + record_route(); + + ifelse(USE_DBACC,`yes',`do_accounting("db"); + ', `do_accounting("log");') + + ifelse(USE_DIALOG,`yes',` + # create dialog with timeout + if ( !create_dialog("B") ) { + send_reply(500,"Internal Server Error"); + exit; + } + + ifelse(DO_CALL_LIMITATION,`yes',` + if ($avp(trunk_attrs) != NULL && $avp(trunk_attrs)=~"^[0-9]+$") { + get_profile_size("trunkCalls","$si",$var(size)); + if ( $(var(size){s.int}) >= $(avp(trunk_attrs){s.int}) ) { + send_reply(486,"Busy Here"); + exit; + } + } + set_dlg_profile("trunkCalls","$si"); + ',`') + ',`') + + ifelse(USE_DIALPLAN,`yes',` + # apply transformations from dialplan table + dp_translate( 0, "$rU", $rU);',`') + + # route calls based on prefix + if ( !do_routing(1) ) { + send_reply(404,"No Route found"); + exit; + } + + t_on_failure("GW_FAILOVER"); + + route(RELAY); +} + + +route[RELAY] { + if (!t_relay()) { + sl_reply_error(); + } + exit; +} + + +failure_route[GW_FAILOVER] { + if (t_was_cancelled()) { + exit; + } + + # detect failure and redirect to next available GW + if (t_check_status("(408)|([56][0-9][0-9])")) { + xlog("Failed GW $rd detected \n"); + + if ( use_next_gw() ) { + t_on_failure("GW_FAILOVER"); + t_relay(); + exit; + } + + send_reply(500,"All GW are down"); + } +} + +ifelse(USE_DIALOG,`yes',` +local_route { + if (is_method("BYE") && $DLG_dir=="UPSTREAM") { + ifelse(USE_DBACC,`yes',` + acc_db_request("200 Dialog Timeout", "acc"); + ',` + acc_log_request("200 Dialog Timeout"); + ') + } +}',`') diff --git a/forward.c b/forward.c index 229a4a74dff..a1418b3bc1f 100644 --- a/forward.c +++ b/forward.c @@ -155,11 +155,16 @@ const struct socket_info* get_send_socket(struct sip_msg *msg, msg->force_send_socket=find_si(&(msg->force_send_socket->address), msg->force_send_socket->port_no, proto); - } + } else + if (msg->force_send_socket->address.af!=to->s.sa_family){ + LM_DBG("force_send_socket of different AF (sock=%d, dst=%d)!\n", + msg->force_send_socket->address.af, to->s.sa_family); + msg->force_send_socket=NULL; + } else if (msg->force_send_socket) return msg->force_send_socket; else - LM_WARN("protocol/port mismatch\n"); + LM_WARN("protocol/port/af mismatch\n"); }; if (mhomed && proto==PROTO_UDP) diff --git a/lib/cJSON.c b/lib/cJSON.c index 416fc979c73..ba6636512d2 100644 --- a/lib/cJSON.c +++ b/lib/cJSON.c @@ -133,8 +133,19 @@ static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2) return tolower(*s1) - tolower(*s2); } -static void *(*cJSON_malloc)(size_t sz) = osips_pkg_malloc; -static void (*cJSON_free)(void *ptr) = osips_pkg_free; +#if defined(__GNUC__) || defined(__clang__) +#define CJSON_TLS __thread +#elif defined(_MSC_VER) +#define CJSON_TLS __declspec(thread) +#else +#error "Thread-local storage support required for cJSON allocator hooks" +#endif + +/* allocator hooks are switched at runtime; keep them thread-local to avoid + * cross-thread SHM/PKG allocator mixing when cJSON_InitHooks() is used */ +static CJSON_TLS void *(*cJSON_malloc)(size_t sz) = osips_pkg_malloc; +static CJSON_TLS void (*cJSON_free)(void *ptr) = osips_pkg_free; +#undef CJSON_TLS static unsigned char* cJSON_strdup(const unsigned char* str) { diff --git a/lib/dbg/struct_hist.h b/lib/dbg/struct_hist.h index 87a0befb5e3..c45cb6f5df1 100644 --- a/lib/dbg/struct_hist.h +++ b/lib/dbg/struct_hist.h @@ -56,6 +56,8 @@ VERB_FUN(TCP_SEND2MAIN) \ VERB_FUN(TCP_ADD_READER) \ VERB_FUN(TCP_REF) \ + VERB_FUN(TCP_RELEASED) \ + VERB_FUN(TCP_DEL_DELAY) \ VERB_FUN(TCP_UNREF) \ VERB_FUN(TCP_DESTROY) \ VERB_FUN(DLG_REF) \ diff --git a/lib/reg/common.c b/lib/reg/common.c index fe311d428cf..91a449af18c 100644 --- a/lib/reg/common.c +++ b/lib/reg/common.c @@ -28,6 +28,7 @@ int max_username_len = USERNAME_MAX_SIZE; int max_domain_len = DOMAIN_MAX_SIZE; int max_aor_len = MAX_AOR_LEN; int max_contact_len = CONTACT_MAX_SIZE; +int allow_dup_cseq = 0; int reg_init_globals(void) { @@ -38,6 +39,7 @@ int reg_init_globals(void) realm_prefix.len = strlen(realm_prefix.s); rcv_param.len = strlen(rcv_param.s); + allow_dup_cseq = !!allow_dup_cseq; if (expires_max_deviation < 0) { expires_max_deviation = -expires_max_deviation; diff --git a/lib/reg/common.h b/lib/reg/common.h index 9fe70fc2ddf..53016d68b79 100644 --- a/lib/reg/common.h +++ b/lib/reg/common.h @@ -52,6 +52,7 @@ extern int max_contacts; extern int max_username_len; extern int max_domain_len; extern int max_aor_len; +extern int allow_dup_cseq; extern int max_contact_len; #define reg_modparams \ @@ -60,6 +61,7 @@ extern int max_contact_len; {"max_domain_len", INT_PARAM, &max_domain_len}, \ {"max_aor_len", INT_PARAM, &max_aor_len}, \ {"max_contact_len", INT_PARAM, &max_contact_len}, \ + {"allow_dup_cseq", INT_PARAM, &allow_dup_cseq}, \ {"expires_max_deviation", INT_PARAM, &expires_max_deviation} /* common registrar init code */ @@ -91,4 +93,6 @@ static inline time_t randomize_expires(unsigned int expires_ts) return ret; } +#define REG_CSEQ_ADJUST(_cs) ((_cs) + allow_dup_cseq) + #endif /* __LIB_REG_COMMON_H__ */ diff --git a/lib/reg/doc/lookup_flags.xml b/lib/reg/doc/lookup_flags.xml deleted file mode 100644 index d1d739ba656..00000000000 --- a/lib/reg/doc/lookup_flags.xml +++ /dev/null @@ -1,126 +0,0 @@ -flags (string, optional) - string composed of one or more of - the following flags, comma-separated: - - - - - 'no-branches' - (old b flag) this - flag controls how the ®_lookup_f; function processes multiple contacts. - If there are - multiple contacts for the given username in usrloc and this - flag is not set, Request-URI will be overwritten with the - highest-q rated contact and the rest will be appended to - sip_msg structure and can be later used by tm for forking. If - the flag is set, only Request-URI will be overwritten - with the highest-q rated contact and the rest will be left - unprocessed. - - - - - - 'to-branches-only' - (old B flag) - this flags forces all found contacts to be uploaded only as branches (in the - destination set) and not at all in the R-URI of the - current message. Using this option allows the ®_lookup_f; function to - also be used in the context of a SIP reply. - - - - - - 'branch' - (old r flag) this flag - enables searching through existing branches for aor's and expanding - them to contacts. For example, you have got AOR A in your - ruri but you also want to forward your calls to AOR B. In order - to do this, you must put AOR B in a branch, and if this flag - enabled, the function will also expand AOR B to contacts, - which will be put back into the branches. The AOR's that were - in branches before the function call shall be removed. - - - - WARNING: - if you want this flag activated, - the 'no-branches' flag must not be set, because by setting - that flag you won't allow ®_lookup_f; to write in a branch. - - - - - - 'method-filtering' - (old m flag) - setting this flag will enable contact filtering based on the supported methods - listed in the "Allow" header field during registration. - Contacts which did not present an "Allow" header field during - registration are assumed to support all standard SIP methods. - - - - - 'ua-filtering=[val]' (old u flag) - (User-Agent filtering) - this flag enables regexp filtering by user-agent. - It's useful with enabled append_branches parameter. The value must use the - format '/regexp/'. - - - - - 'case-insensitive' (old i flag) - - this flag enables case insensitive filtering for the 'ua-filtering' flag. - - - - - 'extended-regexp' - (old e flag) - this flag enables using of extended regexp format for the 'ua-filtering' flag. - - - - - 'global' (old g flag) (Global - lookup) - this flag is only relevant with federated user location clustering. - If set, the ®_lookup_f; function will not only perform the classic - in-memory "search-AoR-and-push-branches" operation, but will - also perform a metadata lookup and append an additional branch - for each returned result. The "in-memory branches" correspond - to local contacts (current location), while the "metadata - branches" correspond to contacts available on one or more of - the remaining locations of the platform. - - - The AoR metadata consists of the minimally required information - in order for one of the VoIP platform's locations (data - centers) to advertise the presence of a locally registered AoR - for the global platform. Specifically, this consists of two - pieces of information: - - - - the AoR (e.g. "vladimir@federation-cluster") - - - - - the home IP (e.g. "10.0.0.223") - - - - - - - - 'max-ping-latency=[int]' - (old y - flag) maximally accepted contact pinging latency (microseconds). Contacts of an - AoR with a higher latency will be discarded during ®_lookup_f;. - - - - - 'sort-by-latency' - (old Y flag) - contacts will be picked in ascending order of their last successful - pinging latency (fastest ping -> slowest ping). This flag may - work together with the "max-ping-latency" flag. - - - diff --git a/lib/reg/doc/lookup_retcodes.xml b/lib/reg/doc/lookup_retcodes.xml deleted file mode 100644 index ba23cf0ad21..00000000000 --- a/lib/reg/doc/lookup_retcodes.xml +++ /dev/null @@ -1,33 +0,0 @@ -Return codes: - - - - 1 - contacts found and successfully - pushed as branches. Contacts which required awakening prior to being - reachable are being notified via async Push Notifications. - - - - - 2 - successfully started at least one - async Push Notification for the found contacts, however no extra branches - were populated (i.e. there is no need to call t_relay()). - - - - - -1 - no contact found. - - - - - -2 - contacts found, but neither of them - supports the current SIP method. - - - - - -3 - internal error during processing. - - - diff --git a/lib/reg/doc/pn_async_func.xml b/lib/reg/doc/pn_async_func.xml deleted file mode 100644 index a3bcf8131b7..00000000000 --- a/lib/reg/doc/pn_async_func.xml +++ /dev/null @@ -1,85 +0,0 @@ -
- - <function moreinfo="none">pn_process_purr(domain) - </function> - - - - Perform mid-dialog request processing, according to RFC 8599. For - such requests, search the R-URI and topmost Route header field URI for - a ";pn-purr" parameter value that both matches the - OpenSIPS PURR format and corresponds to an usrloc registration. Once a - usrloc contact is located, trigger an E_UL_CONTACT_REFRESH - event and place the request on async hold for at most - seconds, until a matching - REGISTER request arrives. - - - - If processing ends before triggering the Push Notification, the request - will no longer be put on async hold, with the resume route being - immediately called. - - - Meaning of the parameters is as follows: - - - - domain (static string) - Logical domain within - registrar. If a database is used, then this must be name of the - table which stores the contacts. - - - - - Return Codes - - - 1 - Success, PN was launched. - - - - 2 - Success, - but PN was not launched (due to missing PURR, foreign PURR or - offline contact) - - - - -1 - Internal Error - - - - - - <function moreinfo="none">async pn_process_purr()</function> usage - -route { - ... - if (has_totag()) { - if (is_method("ACK") && t_check_trans()) { - t_relay(); - exit; - } - - if (!loose_route()) { - send_reply(404, "Not Found"); - exit; - } - - if (!is_method("ACK")) - async (pn_process_purr("location"), resume_route); - - route(relay); - exit; - } -} - -route [resume_route] { - $var(rc) = $rc; - xlog("pn_process_purr() finished with $var(rc)\n"); - - ... -} - - -
diff --git a/lib/reg/doc/pn_modparams.xml b/lib/reg/doc/pn_modparams.xml deleted file mode 100644 index 1d3bde6ab39..00000000000 --- a/lib/reg/doc/pn_modparams.xml +++ /dev/null @@ -1,262 +0,0 @@ - - -
- <varname>pn_enable</varname> (boolean) - - Enable SIP Push Notification support (RFC 8599). - If enabled, Contact header field URIs which include all - will be matched against - existing bindings using only these parameters. Otherwise, - the module will attempt to match them as usual, using the current - usrloc - matching_mode. - - - - Default value is false. - - - - - Setting the <varname>pn_enable</varname> parameter - -... -modparam("®_module;", "pn_enable", true) -... - - -
- - -
- <varname>pn_providers</varname> (string) - - A list of supported Push Notification providers. While only three - possible values are defined by RFC 8599 ("apns", "fcm" and "webpush"), - non-standard values may be specified as well. - - - - Default value is NULL - (not set). - - - - - Setting the <varname>pn_providers</varname> parameter - -... -modparam("®_module;", "pn_providers", "apns, fcm, webpush") -... - - -
- - -
- <varname>pn_ct_match_params</varname> (string) - - The minimally required list of RFC 8599 parameters (custom ones are - accepted as well) which must be present in a Contact URI and - identically match an existing binding in order for the binding - to be refreshed during a SIP re-REGISTER. If at least one such - parameter is missing from a Contact header field URI, the module - will fall back to performing regular contact matching. - - - Note that if all above PN Contact URI parameters match an existing - binding, the match is considered to be successful regardless if - other parts of the SIP URI do not match (e.g. hostname, port, - other URI parameters, etc.). - - - After calling ®_lookup_f; or - , the above PN-related - parameters will be automatically stripped from the resulting - Request and Contact URI event parameter, respectively. - - - - Default value is - "pn-provider, pn-prid, pn-param". - - - - - Setting the <varname>pn_ct_match_params</varname> parameter - -... -modparam("®_module;", "pn_ct_match_params", "pn-provider, pn-prid") -... - - -
- - -
- <varname>pn_pnsreg_interval</varname> (integer) - - For devices capable of waking up and refreshing their binding on - their own (signified by the ";+sip.pnsreg" - Contact header field parameter), this setting denotes the - prior-to-expiration interval advertised by the server at which the - device should issue its binding refresh request. - - - - Default value is 130 - (seconds before expiry). - - - - - Setting the <varname>pn_pnsreg_interval</varname> parameter - -... -modparam("®_module;", "pn_pnsreg_interval", 140) -... - - -
- - -
- <varname>pn_trigger_interval</varname> (integer) - - If a binding refresh REGISTER request from a given SIP endpoint does - not arrive within at least - seconds prior to expiration (e.g. because the device does not - support ";+sip.pnsreg" or because of other - error conditions), the E_UL_CONTACT_REFRESH - usrloc event will be triggered. - - - Once E_UL_CONTACT_REFRESH - is triggered, the script writer should use - the RFC 8599 parameters from the Contact URI in order to generate a - Push Notification request to the PN provider of the device, in - order to cause the device to wake up and re-register. - - - - Default value is 120 - (seconds before expiry). - - - - - Setting the <varname>pn_trigger_interval</varname> parameter - -... -modparam("®_module;", "pn_trigger_interval", 130) -... - - -
- - -
- <varname>pn_skip_pn_interval</varname> (integer) - - Following a successful (re)registration of a contact, this setting - denotes a time interval, in seconds, during which the contact is - assumed to be reachable, so any Push Notifications will be skipped. - - - - Default value is 0 seconds - (always generate Push Notifications). - - - - - Setting the <varname>pn_skip_pn_interval</varname> parameter - -... -modparam("®_module;", "pn_skip_pn_interval", 10) -... - - -
- - -
- <varname>pn_refresh_timeout</varname> (integer) - - This timeout starts counting following a ®_lookup_f; or a - which - triggers a Push Notification. The value represents the maximum - allowed sum of the duration required for the Push Notification to - be sent and the duration required for the corresponding - re-registration from the device to arrive. - - - Once this timeout is exceeded for an initial or a mid-dialog - request, any further re-registrations which match the pending Push - Notification will no longer cause the desired effects. For example: - - - pending initial INVITE transactions will complete and will no - longer auto-fork an additional branch for each REGISTER - sent by the callee side - - - pending BYE messages will time out and OpenSIPS will attempt to - route them despite not having received a confirmation that the - target device is actually reachable - - - - - - Default value is 6 seconds. - - - - - Setting the <varname>pn_refresh_timeout</varname> parameter - -... -modparam("®_module;", "pn_refresh_timeout", 10) -... - - -
- - -
- <varname>pn_enable_purr</varname> (boolean) - - Enable the SIP Push Notification mechanism for long-lived dialogs. - If enabled, the ®_module; will include a - "+sip.pnspurr" - Feature-Caps header field tag in 200 OK replies to REGISTER - requests. This tag represents a unique identifier for the - registration (PURR - Proxy Unique Registration Reference). - - - During dialog setup, each UA may include, in its Contact header, - the PURR value returned by OpenSIPS during registration. By - including the PURR (e.g. ";pn-purr=XXX"), an agent indicates that - it expects to be first awoken by a PN before being able to receive - a mid-dialog request sent by the other party. - - - When enabling this parameter, make sure to also add logic for - . - - - - Default value is false. - - - - - Setting the <varname>pn_enable_purr</varname> parameter - -... -modparam("®_module;", "pn_enable_purr", true) -... - - -
diff --git a/lib/reg/doc/reg_modparams.xml b/lib/reg/doc/reg_modparams.xml deleted file mode 100644 index 4ff0dcf4706..00000000000 --- a/lib/reg/doc/reg_modparams.xml +++ /dev/null @@ -1,131 +0,0 @@ - - -
- <varname>expires_max_deviation</varname> (integer) - - Set this parameter in order to add a random +/- deviation up to - and including the given value to the expiration interval of a - newly registered contact. For example, if this parameter is set to - 100 and a phone registers for 1800 sec, the final - expiry will be a random number in the [1700, 1900] interval. - - By randomizing the registration lifetimes of the contacts, the - server is better equipped to deal with a post-restart registration - storm, when all TCP connections are lost and a significant portion of - UAs will re-register at the same time. Thanks to the contact lifetime - randomization, the registration storm will only happen once rather - than, e.g., every 1800 seconds following the restart. - - - - - Default value is 0 (no deviation). - - - - Setting the <varname>expires_max_deviation</varname> parameter - -... -# add a random +/- 0-100 seconds to each registration lifetime -modparam("®_module;", "expires_max_deviation", 100) -... - - -
- - -
- <varname>max_contacts</varname> (integer) - - The parameter can be used to limit the number of contacts per - AOR (Address of Record) in the user location database. Value 0 - disables the check. - - This is the default value and will be used only if no other value - (for max_contacts) is passed as parameter to the save() function. - That's it - the function parameter overwride this global parameter. - - - - - Default value is 0. - - - - Set <varname>max_contacts</varname> parameter - -... -# Allow no more than 10 contacts per AOR -modparam("®_module;", "max_contacts", 10) -... - - -
- - -
- <varname>max_username_len</varname> (integer) - - The maximum length of the "username" part of an Address-of-Record SIP URI. - - - Default value is 64. - - - Setting the <emphasis>max_username_len</emphasis> module parameter - -modparam("®_module;", "max_username_len", 128) - - -
- - -
- <varname>max_domain_len</varname> (integer) - - The maximum length of the "domain" part of an Address-of-Record SIP URI. - - - Default value is 64. - - - Setting the <emphasis>max_domain_len</emphasis> module parameter - -modparam("®_module;", "max_domain_len", 128) - - -
- - -
- <varname>max_aor_len</varname> (integer) - - The maximum length of an Address-of-Record SIP URI. - - - Default value is 256. - - - Setting the <emphasis>max_aor_len</emphasis> module parameter - -modparam("®_module;", "max_aor_len", 512) - - -
- - -
- <varname>max_contact_len</varname> (integer) - - The maximum length of a Contact header field SIP URI. - - - Default value is 255. - - - Setting the <emphasis>max_contact_len</emphasis> module parameter - -modparam("®_module;", "max_contact_len", 512) - - -
diff --git a/lib/reg/doc/save_common_flags.xml b/lib/reg/doc/save_common_flags.xml deleted file mode 100644 index d853e599c87..00000000000 --- a/lib/reg/doc/save_common_flags.xml +++ /dev/null @@ -1,93 +0,0 @@ - - 'memory-only' - (old m flag) - save the contacts only in memory cache without no DB operation; - - - - 'no-reply' - (old r flag) - do not generate a SIP reply to the current REGISTER request. - - - - 'max-contacts=[int]' - (old c - flag) this flag can be used to limit the number of contacts for this - AOR (Address of Record) in the user location database. - Value 0 disables the check. This parameter overrides the - global "max_contacts" module parameter. - - - - 'force-registration' - (old f - flag) this flag can be used to force the registration of NEW contacts - even if the maximum number of contacts is reached. In such - a case, older contacts will be removed to make space to the - new ones, without exceeding the maximum allowed number. - This flag makes sense only if "max-contacts" is used. - - - - 'matching-mode=[val]' - (old M - flag) How the matching should be performed between the uploaded - contacts (by the currently handled REGISTER) and the - already know contacts (in memory or DB). This options will - be used only for the current operation and can be: - - - '0' - contact URI matching - only - - - '1' - contact URI and - SIP Call-ID matching - - - '<param_name>' - only - the value of the given URI param will be used for - matching (for example <rinstance>) - - - - - - 'path-off' - (old p0 flag) - (Path support - 'off' mode) - The Path header is saved into usrloc, - but is never included in the reply. - - - - 'path-lazy' - (old p1 flag) - (Path support - lazy mode) The Path header is saved into usrloc, but is only - included in the reply if path support is indicated in the - registration request by the path option - of the Supported header. - - - - 'path-strict' - (old p2 flag) - (Path support - strict mode) - The path header is only saved into usrloc, - if path support is indicated in the registration request by the - path option of the Supported - header. If no path support is indicated, the request is - rejected with 420 - Bad Extension and the - header Unsupported: path is included in - the reply along with the received Path - header. This mode is the one recommended by RFC-3327. - - - - 'path-received' - (old v flag) - if set, the received parameter of the first Path - URI of a registration is set as received-uri and the NAT - branch flag is set for this contact. This is useful if - the registrar is placed behind a SIP loadbalancer, which - passes the nat'ed UAC address as received - parameter in it's Path uri. - - - - 'only-request-contacts' - (old o - flag) Only include the REGISTER request's Contacts in the 200 OK - reply, in case the registration is successful. While this - is against RFC 3261, it may be useful in certain scenarios. - - \ No newline at end of file diff --git a/lib/reg/doc/supported_rfc.xml b/lib/reg/doc/supported_rfc.xml deleted file mode 100644 index 007a3a76999..00000000000 --- a/lib/reg/doc/supported_rfc.xml +++ /dev/null @@ -1,186 +0,0 @@ -
- Path Support (RFC 3327) - - The ®_module; module includes SIP Path header field support - according to - RFC 3327, - for usage in registrars and home-proxies. - - - A call to ®_save_f; stores, if path support is enabled - in the ®_module; module, the values of the Path - Header(s) along with the Contact information into usrloc. There are - three modes for building the reply to a REGISTER message which - includes one or more Path header fields: - - - - - off - stores the value of the - Path headers into usrloc without passing it back to - the UAC in the reply. - - - - - lazy - stores the Path header and - passes it back to the UAC if Path-support is indicated - by the path param in the Supported HF. - - - - - strict - rejects the registration - with 420 Bad Extension if there's a Path - header but no support for it is indicated by the UAC. - Otherwise it's stored and passed back to the UAC. - - - - - A call to ®_lookup_f; always uses the Path header if - found, and inserts it as Route HF either in front of - the first Route HF, or after the last Via HF if no - Route is present. It also sets the destination URI to - the first Path URI, thus overwriting the received-URI, - because NAT has to be handled at the outbound-proxy of - the UAC (the first hop after client's NAT). - - - The whole process is transparent to the user, so no - config changes are required besides enabling one of the - "p0" / "p1" / "p2" flags when calling ®_save_f;. - -
- - -
- GRUU Support (RFC 5627) - - The ®_module; module includes support for Globally Routable User - Agent URIs according to RFC 5627. - - - A call to ®_save_f; stores, if the phone supports GRUU, - the values of the SIP Instance along with the contact into usrloc. - The module will generate two types of GRUUs: - - - - - public - exposes the underlying AOR, - constructed just by attaching the SIP Instance as the ;gr - parameter value. These are persistent, valid as long as the - contact registration is valid. - - - - - temporary - hides the underlying AOR - Each new Register request leads to the construction of a - new temporary GRUU, while Register requests with a different - Call-ID lead to the invalidation of all the previous generated - temporary GRUUs. - - - - - A call to ®_lookup_f; will try to detect if the R-URI contains a - GRUU. If it does, it will route the request just for the Contact - that the specific AOR belongs to, without appending any other branches. - - - Even if the the GRUU handling during the registration process is - transparent to the user, so no config changes are required, you need - to take care of the GRUU specifics when handling mid-dialog requests. - - - As the GRUU will be present in the contact header of the initial - requests generated byt GRUU enabled devices, you will have to also - do a lookup() when receiving a mid-dialog request with the GRUU - indication in the RURI. - -
- - -
- SIP Push Notification Support (RFC 8599) - - The ®_module; module includes support for standards-based SIP Push - Notifications, per - RFC 8599. - Support for the basic version of the draft can be enabled by switching - to true. The - module also includes optional support for sending Push Notifications - during long-lived dialogs (see RFC section 6), - through the switch. - - - Essential mechanics behind the Push Notification (PN) support: - - - - - the PN support is fully compatible with the existing logic and - enabling it does not impose any limitations, as the - ®_module; can simultaneously handle both SIP PN compliant - and standard SIP User Agents - - - - - OpenSIPS will raise a - E_UL_CONTACT_REFRESH - event any time a Push Notification needs to be sent to a - PN-enabled contact. The event includes the PN coordinates of - the contact -- they may be found in the Contact URI ('uri' - event parameter) and may be extracted using the {uri.param,name} - transformation. From here onwards, it is up to the script - developer to trigger the Push Notification (e.g. possibly by - sending an HTTP POST with the - rest_client module), thus forcing - a re-registration from the device. - - - - - REGISTER processing is unchanged -- PN-enabled UAs are saved - just as regular UAs, with the former ones additionally having - the 4 bitflag set in the "Flags" field of - any MI listing of contacts, for differentiation purposes - - - - - initial INVITE processing is barely changed, with the ®_lookup_f; - function now additionally returning a value of - 2 if the only - found contacts were PN-enabled contacts, all which required a - Push Notification. This means that PNs have been triggered for - each of them and t_relay() is not required, since they are not - reachable until they re-register! - - - Using the event_routing module, OpenSIPS will transparently - fork a new branch from the current INVITE on each - re-registration from these contacts within the accepted - - - - - - mid-dialog requests: In some cases (e.g. long-lived dialogs), - a PN may be required before being able to route a mid-dialog - request to a SIP UA. The - async function will take care of triggering the PN event and - resuming the script as soon as a re-registration from the - concerned contact is received. - - - - - For more information or examples, refer to the documentation of the - "pn_xxx" module parameters or the OpenSIPS blog posts around the - "SIP Push Notification" topic. - -
diff --git a/lib/reg/lookup.c b/lib/reg/lookup.c index e7d248ab85f..df222b9b49f 100644 --- a/lib/reg/lookup.c +++ b/lib/reg/lookup.c @@ -54,12 +54,14 @@ lookup_rc lookup(struct sip_msg *req, udomain_t *d, static char urimem[MAX_BRANCHES-1][MAX_URI_SIZE]; static str branch_uris[MAX_BRANCHES-1]; int idx = 0, nbranches = 0; - urecord_t* r; + urecord_t* r = NULL; str aor; ucontact_t *ct, **ptr, **pn_cts, **cts; int max_latency = 0, ruri_is_pushed = 0; unsigned int flags = 0; int rc, ret = LOOKUP_NO_RESULTS, have_pn_cts = 0, single_branch = 0; + int pn_cts_sz; + unsigned int dst_branches = 0; str sip_instance = STR_NULL, call_id = STR_NULL; regex_t *ua_re = NULL; struct msg_branch *branch; @@ -77,6 +79,13 @@ lookup_rc lookup(struct sip_msg *req, udomain_t *d, max_latency = lookup_flags->max_latency; } + if (!(flags & REG_BRANCH_AOR_LOOKUP_FLAG)) + dst_branches += get_dset_size(); + + if ((flags & REG_LOOKUP_NO_RURI_FLAG) && + req->first_line.type == SIP_REQUEST) + dst_branches++; + single_branch = flags & REG_LOOKUP_NOBRANCH_FLAG; if (flags & REG_BRANCH_AOR_LOOKUP_FLAG) { @@ -147,6 +156,8 @@ lookup_rc lookup(struct sip_msg *req, udomain_t *d, goto done; } else if (rc == 2) { *pn_cts++ = *ptr; + } else if (rc == 0) { + dst_branches++; } if (rc == 0 && single_branch) @@ -157,13 +168,18 @@ lookup_rc lookup(struct sip_msg *req, udomain_t *d, && (flags & REG_LOOKUP_GLOBAL_FLAG)) { for (ct = r->remote_aors; ct; ct = ct->next) { rc = push_branch(req, ct, &ruri_is_pushed); - if (rc == 0 && single_branch) - goto done; + if (rc == 0) { + dst_branches++; + if (single_branch) + goto done; + } } } if (pn_cts > cts) { - rc = pn_awake_pn_contacts(req, cts, single_branch ? 1 : pn_cts - cts); + pn_cts_sz = single_branch ? 1 : pn_cts - cts; + rc = pn_awake_pn_contacts(req, cts, pn_cts_sz, + dst_branches + pn_cts_sz); if (rc <= 0) { ret = (rc == 0 ? LOOKUP_STOP_SCRIPT : LOOKUP_ERROR); goto done; @@ -178,6 +194,7 @@ lookup_rc lookup(struct sip_msg *req, udomain_t *d, /* relsease old aor lock */ ul.release_urecord(r, 0); ul.unlock_udomain(d, &aor); + r = NULL; next_aor: aor_uri = &branch_uris[idx]; diff --git a/lib/reg/pn.c b/lib/reg/pn.c index 754e71d4815..ab30f6d6710 100644 --- a/lib/reg/pn.c +++ b/lib/reg/pn.c @@ -589,14 +589,24 @@ static struct usr_avp *pn_trim_pn_params(evi_params_t *params) } -static void pn_inject_branch(void) +static void pn_notify_branch(void) { + struct usr_avp **avps; + + avps = get_avp_list(); + if (!avps || !*avps) { + if (tmb.t_wait_no_more_branches() != 1) + LM_ERR("failed to stop waiting for PN branches\n"); + return; + } + if (tmb.t_inject_ul_event_branch() != 1) LM_ERR("failed to inject a branch for the "UL_EV_CT_UPDATE" event!\n"); } -int pn_awake_pn_contacts(struct sip_msg *req, ucontact_t **cts, int sz) +int pn_awake_pn_contacts(struct sip_msg *req, ucontact_t **cts, int sz, + unsigned int wait_branches) { ucontact_t **end; struct sip_uri puri; @@ -626,7 +636,7 @@ int pn_awake_pn_contacts(struct sip_msg *req, ucontact_t **cts, int sz) return -1; } - if (tmb.t_wait_for_new_branches(req) != 1) + if (tmb.t_wait_for_new_branches(req, wait_branches) != 1) LM_ERR("failed to enable waiting for new branches\n"); for (end = cts + sz; cts < end; cts++) { @@ -667,7 +677,8 @@ int pn_trigger_pn(struct sip_msg *req, const ucontact_t *ct, } if (ebr.notify_on_event(req, ev_ct_update, pn_ebr_filters, - pn_trim_pn_params, pn_inject_branch, pn_refresh_timeout) != 0) { + pn_trim_pn_params, pn_notify_branch, pn_refresh_timeout, + EBR_SUBS_EXPIRE_NOTIFY) != 0) { LM_ERR("failed to EBR-subscribe to "UL_EV_CT_UPDATE", Contact: %.*s\n", ct->c.len, redact_pii(ct->c.s)); return -1; diff --git a/lib/reg/pn.h b/lib/reg/pn.h index 3f8fec508dc..291d030f21c 100644 --- a/lib/reg/pn.h +++ b/lib/reg/pn.h @@ -182,12 +182,15 @@ int pn_append_rpl_fcaps(struct sip_msg *msg); * @req: the current SIP request * @cts: array of PN-enabled contacts * @sz: array size + * @wait_branches: maximum number of outgoing branches to wait for, including + * already selected destinations and PN-injected branches * * Return: * success: 1 if at least one PN was sent, 2 otherwise * failure: 0 on retransmission, -1 on internal error */ -int pn_awake_pn_contacts(struct sip_msg *req, ucontact_t **cts, int sz); +int pn_awake_pn_contacts(struct sip_msg *req, ucontact_t **cts, int sz, + unsigned int wait_branches); /** diff --git a/mem/q_malloc_dyn.h b/mem/q_malloc_dyn.h index a4070a0f021..443ad7bba68 100644 --- a/mem/q_malloc_dyn.h +++ b/mem/q_malloc_dyn.h @@ -405,7 +405,7 @@ void qm_status(struct qm_block *qm) #endif { struct qm_frag *f; - int i,j; + int i; int h; int unused; @@ -459,10 +459,10 @@ void qm_status(struct qm_block *qm) #endif LM_GEN1(memdump, " dumping free list stats :\n"); - for(h=0,i=0;hfree_hash[h].head.u.nxt_free,j=0; - f!=&(qm->free_hash[h].head); f=f->u.nxt_free, i++, j++){ + for (f=qm->free_hash[h].head.u.nxt_free,i=0; + f!=&(qm->free_hash[h].head); f=f->u.nxt_free, i++){ if (!FRAG_WAS_USED(f)){ unused++; #ifdef DBG_MALLOC @@ -474,15 +474,15 @@ void qm_status(struct qm_block *qm) } } - if (j) LM_GEN1(memdump, "hash= %3d. fragments no.: %5d, unused: %5d\n" + if (i) LM_GEN1(memdump, "hash= %3d. fragments no.: %5d, unused: %5d\n" "\t\t bucket size: %9lu - %9ld (first %9lu)\n", - h, j, unused, UN_HASH(h), + h, i, unused, UN_HASH(h), ((h<=Q_MALLOC_OPTIMIZE/QM_ROUNDTO)?1:2)*UN_HASH(h), qm->free_hash[h].head.u.nxt_free->size ); - if (j!=qm->free_hash[h].no){ + if (i!=qm->free_hash[h].no){ LM_CRIT("different free frag. count: %d!=%lu" - " for hash %3d\n", j, qm->free_hash[h].no, h); + " for hash %3d\n", i, qm->free_hash[h].no, h); } } diff --git a/modules/aaa_diameter/README b/modules/aaa_diameter/README deleted file mode 100644 index f068a90407e..00000000000 --- a/modules/aaa_diameter/README +++ /dev/null @@ -1,509 +0,0 @@ -AAA_DIAMETER MODULE - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Diameter Client - 1.3. Diameter Server - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. fd_log_level (integer) - 1.5.2. realm (string) - 1.5.3. peer_identity (string) - 1.5.4. aaa_url (string) - 1.5.5. answer_timeout (integer) - - 1.6. Exported Functions - - 1.6.1. dm_send_request(app_id, cmd_code, avps_json, - [rpl_avps_pv]) - - 1.6.2. dm_send_answer(avps_json, [is_error]) - - 1.7. Exported Asyncronous Functions - - 1.7.1. dm_send_request(app_id, cmd_code, avps_json, - [rpl_avps_pv]) - - 1.8. Exported Events - - 1.8.1. E_DM_REQUEST - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the fd_log_level parameter - 1.2. Setting the realm parameter - 1.3. Setting the peer_identity parameter - 1.4. Setting the aaa_url parameter - 1.5. Setting the aaa_url parameter - 1.6. Setting the answer_timeout parameter - 1.7. dictionary.opensips extended syntax - 1.8. dm_send_request usage - 1.9. dm_send_answer() usage - 1.10. dm_send_request asynchronous usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides an RFC 6733 Diameter peer implementation, - being able to act as either Diameter client or server, or both. - - Any module that wishes to use it has to do the following: - * include aaa.h - * make a bind call with a proper Diameter-specific URL, e.g. - "diameter:freeDiameter-client.conf" - -1.2. Diameter Client - - The module implements the core AAA OpenSIPS interface, thus - offering an alternative client implementation to the aaa_radius - module which can be useful, for example, when performing - billing and accounting for the live SIP calls. - - In addition to the RADIUS client's auth and accounting - features, the Diameter client includes support for sending - arbitrary Diameter requests, further opening up the scope of - applications which can be achieved through OpenSIPS scripting. - Such Diameter requests can be sent using the dm_send_request() - function. - -1.3. Diameter Server - - Starting with OpenSIPS 3.5, the Diameter module includes - server-side support as well. - - First, the event_route module must be loaded in order to be - able to process E_DM_REQUEST events in the OpenSIPS - configuration file. These events will contain all necessary - information on the incoming Diameter request. - - Finally, once the request information is processed and the - answer AVPs are prepared, script writers should use the - dm_send_answer() function in order to reply with a Diameter - answer message. - - Recommendation: When possible, always load the dict_sip.fdx - freeDiameter extension module inside your freeDiameter.conf - configuration file, as it contains hundreds of well-known AVP - definitions which may be good to have when inter-operating with - other Diameter peer implementations. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - All Diameter message building and parsing, as well as the peer - state machine and Diameter-related network communication are - all powered by the freeDiameter project and C libraries, - dynamically linking with the "aaa_diameter" module. - - The following libraries must be installed before running - OpenSIPS with this module loaded: - * libfdcore v1.2.1 or higher - * libfdproto v1.2.1 or higher - -1.5. Exported Parameters - -1.5.1. fd_log_level (integer) - - This parameter measures the quietness of the logging done by - the freeDiameter library. Possible values: - * 0 (ANNOYING) - * 1 (DEBUG) - * 3 (NOTICE, default) - * 5 (ERROR) - * 6 (FATAL) - - NOTE: since freeDiameter logs to standard output, you must also - enable the new core parameter, log_stdout, before getting any - logs from the library. - - Example 1.1. Setting the fd_log_level parameter - -modparam("aaa_diameter", "fd_log_level", 0) - - -1.5.2. realm (string) - - The unique realm to be used by all participating Diameter - peers. - - Default value is "diameter.test". - - Example 1.2. Setting the realm parameter - -modparam("aaa_diameter", "realm", "opensips.org") - - -1.5.3. peer_identity (string) - - The identity (realm subdomain) of the Diameter server peer, to - which the OpenSIPS Diameter client peer will connect. - - Default value is "server" (i.e. "server.diameter.test"). - - Example 1.3. Setting the peer_identity parameter - -modparam("aaa_diameter", "peer_identity", "server") - - -1.5.4. aaa_url (string) - - URL of the diameter client: the configuration file, with an - optional extra-avps-file, where the Diameter client is - configured. - - By default, the connection is not created. - - Example 1.4. Setting the aaa_url parameter - -modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf") - - - Example 1.5. Setting the aaa_url parameter - with an extra AVPs file. - -modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf;e -xtra-avps-file:dictionary.opensips") - - -1.5.5. answer_timeout (integer) - - Time, in milliseconds, after which a dm_send_request() function - call with no received reply will time out and return a -2 code. - - Default value is 2000 ms. - - Example 1.6. Setting the answer_timeout parameter - -modparam("aaa_diameter", "answer_timeout", 5000) - - -1.6. Exported Functions - -1.6.1. dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv]) - - Perform a blocking Diameter request over to the interconnected - peer and return the Result-Code AVP value from the reply. - - Parameters - * app_id (integer) - ID of the application. A custom - application must be defined in the dictionary.opensips - Diameter configuration file before it can be recognized. - * cmd_code (integer) - ID of the command. A custom command - code, name and AVP requirements must be defined in the - dictionary.opensips Diameter configuration file beforehand. - body of the HTTP response. - * avps_json (string) - A JSON Array containing the AVPs to - include in the message. - * rpl_avps_pv (var, optional) - output variable which will - hold all AVP names from the Diameter Answer along with - their values, packed as a JSON Array string. The "json" - module and its $json variable could be used to iterate this - array. - - Return Codes - * 1 - Success - * -1 - Internal Error - * -2 - Request timeout (the answer_timeout was exceeded - before an Answer could be processed) - - This function can be used from any route. - - Example 1.7. dictionary.opensips extended syntax - -# Example of defining custom Diameter AVPs, Application IDs, -# Requests and Replies in the "dictionary.opensips" file - -ATTRIBUTE out_gw 232 string -ATTRIBUTE trunk_id 233 string - -ATTRIBUTE rated_duration 234 integer -ATTRIBUTE call_cost 235 integer - -ATTRIBUTE Exponent 429 integer32 -ATTRIBUTE Value-Digits 447 integer64 - -ATTRIBUTE Cost-Unit 424 grouped -{ - Value-Digits | REQUIRED | 1 - Exponent | OPTIONAL | 1 -} - -ATTRIBUTE Currency-Code 425 unsigned32 - -ATTRIBUTE Unit-Value 445 grouped -{ - Value-Digits | REQUIRED | 1 - Exponent | OPTIONAL | 1 -} - -ATTRIBUTE Cost-Information 423 grouped -{ - Unit-Value | REQUIRED | 1 - Currency-Code | REQUIRED | 1 - Cost-Unit | OPTIONAL | 1 -} - -APPLICATION 42 My Diameter Application - -REQUEST 92001 My-Custom-Request -{ - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Transaction-Id | REQUIRED | 1 - Sip-From-Tag | REQUIRED | 1 - Sip-To-Tag | REQUIRED | 1 - Acct-Session-Id | REQUIRED | 1 - Sip-Call-Duration | REQUIRED | 1 - Sip-Call-Setuptime | REQUIRED | 1 - Sip-Call-Created | REQUIRED | 1 - Sip-Call-MSDuration | REQUIRED | 1 - out_gw | REQUIRED | 1 - call_cost | REQUIRED | 1 - Cost-Information | OPTIONAL | 1 -} - -ANSWER 92001 My-Custom-Answer -{ - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Transaction-Id | REQUIRED | 1 - Result-Code | REQUIRED | 1 -} - - - Example 1.8. dm_send_request usage - -# Building an sending an My-Custom-Request (92001) for the -# My Diameter Application (42) -$var(payload) = "[ - { \"Origin-Host\": \"client.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" }, - { \"Destination-Realm\": \"diameter.test\" }, - { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, - { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, - { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, - { \"Sip-Call-Duration\": 6 }, - { \"Sip-Call-Setuptime\": 1 }, - { \"Sip-Call-Created\": 1652372541 }, - { \"Sip-Call-MSDuration\": 5850 }, - { \"out_gw\": \"GW-774\" }, - { \"cost\": \"10.84\" }, - { \"Cost-Information\": [ - {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, - {\"Currency-Code\": 35} - ]} -]"; - -$var(rc) = dm_send_request(42, 92001, $var(payload), $var(rpl_avps)); -xlog("rc: $var(rc), AVPs: $var(rpl_avps)\n"); -$json(avps) := $var(rpl_avps); - - -1.6.2. dm_send_answer(avps_json, [is_error]) - - Send back a Diameter answer message to the interconnected peer - in a non-blocking fashion, in response to its request. - - The following fields will be automatically copied over from the - Diameter request when building the answer message: - * Application ID - * Command Code - * Session-Id AVP, if any - * Transaction-Id AVP, if any (only applies when Session-Id is - not present) - - Parameters - * avps_json (string) - A JSON Array containing the AVPs to - include in the answer message (example below). - * is_error (boolean, default: false) - Set to true in order - to set the 'E' (error) bit in the answer message. - - Return Codes - * 1 - Success - * -1 - Internal Error - - This function can only be used from an EVENT_ROUTE. - - Example 1.9. dm_send_answer() usage - -event_route [E_DM_REQUEST] { - xlog("Req: $param(sess_id) / $param(app_id) / $param(cmd_code)\n"); - xlog("AVPs: $param(avps_json)\n"); - - $json(avps) := $param(avps_json); - - /* ... process the data (AVPs) ... */ - - /* ... and reply back with more AVPs! */ - $var(ans_avps) = "[ - { \"Vendor-Specific-Application-Id\": [{ - \"Vendor-Id\": 0 - }] }, - - { \"Result-Code\": 2001 }, - { \"Auth-Session-State\": 0 }, - { \"Origin-Host\": \"opensips.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" } - ]"; - - if (!dm_send_answer($var(ans_avps))) - xlog("ERROR - failed to send Diameter answer\n"); -} - - -1.7. Exported Asyncronous Functions - -1.7.1. dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv]) - - Similar to dm_send_request() but performs an asynchronous - Diameter request. - - Uses the same parameters and return codes as dm_send_request(). - - Example 1.10. dm_send_request asynchronous usage - -# Building an sending an My-Custom-Request (92001) for the -# My Diameter Application (42) -$var(payload) = "[ - { \"Origin-Host\": \"client.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" }, - { \"Destination-Realm\": \"diameter.test\" }, - { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, - { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, - { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, - { \"Sip-Call-Duration\": 6 }, - { \"Sip-Call-Setuptime\": 1 }, - { \"Sip-Call-Created\": 1652372541 }, - { \"Sip-Call-MSDuration\": 5850 }, - { \"out_gw\": \"GW-774\" }, - { \"cost\": \"10.84\" }, - { \"Cost-Information\": [ - {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, - {\"Currency-Code\": 35} - ]} -]"; - -async(dm_send_request(42, 92001, $var(payload), $var(rpl_avps), dm_reply -); - -route[dm_reply] { - xlog("rc: $retcode, AVPs: $var(rpl_avps)\n"); - $json(avps) := $var(rpl_avps); -} - - -1.8. Exported Events - -1.8.1. E_DM_REQUEST - - This event is raised whenever the aaa_diameter module is loaded - and OpenSIPS receives a Diameter request on the configured - Diameter listening interface. - - Parameters: - * app_id (integer) - the Diameter Application Identifier - * cmd_code (integer) - the Diameter Command Code - * sess_id (string) - the value of either the Session-Id AVP, - Transaction-Id AVP or a NULL value if neither of these - transaction-identifying AVPs is present in the Diameter - request. - * avps_json (string) - a JSON Array containing the AVPs of - the request. Use the json module's $json variable to easily - parse and work with it. - - Note that this event is currently designed to be mainly - consumed by an event_route, since that is the only way to gain - access to the dm_send_answer() function in order to build - custom answer messages. On the other hand, if the application - does not mind the answer being always a 3001 - (DIAMETER_COMMAND_UNSUPPORTED) error, this event can be - successfully consumed through any other EVI-compatible delivery - channel ☺️ - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 114 37 6850 1105 - 2. Razvan Crainea (@razvancrainea) 38 21 1423 251 - 3. Alexandra Titoc 6 4 11 2 - 4. Peter Lemenkov (@lemenkov) 4 2 2 2 - 5. Larry Laffer 3 1 6 5 - 6. Maksym Sobolyev (@sobomax) 3 1 5 5 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2023 - Nov 2025 - 2. Peter Lemenkov (@lemenkov) Jul 2024 - Jul 2025 - 3. Larry Laffer Jul 2025 - Jul 2025 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Liviu Chircu (@liviuchircu) May 2021 - Mar 2024 - 6. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2021 www.opensips-solutions.com diff --git a/modules/aaa_diameter/README.md b/modules/aaa_diameter/README.md new file mode 100644 index 00000000000..69c0faa76e3 --- /dev/null +++ b/modules/aaa_diameter/README.md @@ -0,0 +1,450 @@ +--- +title: "AAA_DIAMETER MODULE" +description: "This module provides an RFC 6733 Diameter peer implementation, being able to act as either Diameter client or server, or both." +--- + +## Admin Guide + + +### Overview + + +This module provides an RFC 6733 Diameter peer implementation, being +able to act as either **Diameter client** or **server**, or **both**. + + +Any module that wishes to use it has to do the following: +- *include aaa.h* +- *make a bind call with a proper Diameter-specific URL, e.g. "diameter:freeDiameter-client.conf"* + + +### Diameter Client + + +The module implements the core AAA OpenSIPS interface, thus offering +an alternative client implementation to the +[aaa_radius](../aaa_radius) module which can be useful, +for example, when performing billing and accounting for the live SIP calls. + + +In addition to the RADIUS client's auth and accounting features, the +Diameter client includes support for sending *arbitrary* +Diameter requests, further opening up the scope of applications which +can be achieved through OpenSIPS scripting. Such Diameter requests can +be sent using the [dm send request](#func_dm_send_request) function. + + +### Diameter Server + + +Starting with OpenSIPS **3.5**, the Diameter +module includes *server-side* support as well. + + +First, the [event_route](../event_route) module must be loaded in +order to be able to process [dm request](#event_e_dm_request) events in +the OpenSIPS configuration file. These events will contain all necessary +information on the incoming Diameter request. + + +Finally, once the request information is processed and the answer AVPs +are prepared, script writers should use the [dm send answer](#func_dm_send_answer) +function in order to reply with a Diameter answer message. + + +*Recommendation:* When possible, always load the +**dict_sip.fdx** freeDiameter extension module +inside your *freeDiameter.conf* configuration file, +as it contains hundreds of well-known AVP definitions which may be good +to have when inter-operating with other Diameter peer implementations. + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +All Diameter message building and parsing, as well as the peer state +machine and Diameter-related network communication are all powered by +[the freeDiameter project](http://www.freediameter.net/trac/) +and C libraries, dynamically linking with the "aaa_diameter" module. + + +The following libraries must be installed before running +OpenSIPS with this module loaded: + + +- *libfdcore* v1.2.1 or higher +- *libfdproto* v1.2.1 or higher + + +### Exported Parameters + + +#### fd_log_level (integer) + + +This parameter measures the *quietness* of the logging +done by the freeDiameter library. Possible values: + + +- 0 (ANNOYING) +- 1 (DEBUG) +- 3 (NOTICE, default) +- 5 (ERROR) +- 6 (FATAL) + + +NOTE: since freeDiameter logs to standard output, you must also enable +the new core parameter, **log_stdout**, +before getting any logs from the library. + + +```opensips title="Setting the fd_log_level parameter" +modparam("aaa_diameter", "fd_log_level", 0) +``` + + +#### realm (string) + + +The unique realm to be used by all participating Diameter peers. + + +Default value is *"diameter.test"*. + + +```opensips title="Setting the realm parameter" +modparam("aaa_diameter", "realm", "opensips.org") +``` + + +#### peer_identity (string) + + +The identity (realm subdomain) of the Diameter server peer, to which +the OpenSIPS Diameter client peer will connect. + + +Default value is *"server"* +(i.e. "server.diameter.test"). + + +```opensips title="Setting the peer_identity parameter" +modparam("aaa_diameter", "peer_identity", "server") +``` + + +#### aaa_url (string) + + +URL of the diameter client: the configuration file, with an optional +extra-avps-file, where the Diameter client is configured. + + +By default, the connection is not created. + + +```opensips title="Setting the aaa_url parameter" +modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf") +``` + + +```opensips title="Setting the aaa_url parameter" +modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf;extra-avps-file:dictionary.opensips") +``` + + +#### answer_timeout (integer) + + +Time, in milliseconds, after which a [dm send request](#func_dm_send_request) +function call with no received reply will time out and return a +**-2** code. + + +Default value is *2000* ms. + + +```opensips title="Setting the answer_timeout parameter" +modparam("aaa_diameter", "answer_timeout", 5000) +``` + + +### Exported Functions + + +#### dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv]) + + +Perform a blocking Diameter request over to the interconnected peer +and return the Result-Code AVP value from the reply. + + +*Parameters* + + +- *app_id* (integer) - ID of the application. +A custom application must be defined in the dictionary.opensips +Diameter configuration file before it can be recognized. +- *cmd_code* (integer) - ID of the command. A +custom command code, name and AVP requirements must be defined +in the dictionary.opensips Diameter configuration file beforehand. +body of the HTTP response. +- *avps_json* (string) - A JSON Array containing +the AVPs to include in the message. +- *rpl_avps_pv* (var, optional) - output variable which will +hold all AVP names from the Diameter Answer along with their values, packed +as a JSON Array string. The "json" module and its *$json* +variable could be used to iterate this array. + + +*Return Codes* + + +- **1** - Success +- **-1** - Internal Error +- **-2** - Request timeout +(the [answer timeout](#param_answer_timeout) was exceeded +before an Answer could be processed) + + +This function can be used from any route. + + +``` title="dictionary.opensips extended syntax" +# Example of defining custom Diameter AVPs, Application IDs, +# Requests and Replies in the "dictionary.opensips" file + +ATTRIBUTE out_gw 232 string +ATTRIBUTE trunk_id 233 string + +ATTRIBUTE rated_duration 234 integer +ATTRIBUTE call_cost 235 integer + +ATTRIBUTE Exponent 429 integer32 +ATTRIBUTE Value-Digits 447 integer64 + +ATTRIBUTE Cost-Unit 424 grouped +{ + Value-Digits | REQUIRED | 1 + Exponent | OPTIONAL | 1 +} + +ATTRIBUTE Currency-Code 425 unsigned32 + +ATTRIBUTE Unit-Value 445 grouped +{ + Value-Digits | REQUIRED | 1 + Exponent | OPTIONAL | 1 +} + +ATTRIBUTE Cost-Information 423 grouped +{ + Unit-Value | REQUIRED | 1 + Currency-Code | REQUIRED | 1 + Cost-Unit | OPTIONAL | 1 +} + +APPLICATION 42 My Diameter Application + +REQUEST 92001 My-Custom-Request +{ + Origin-Host | REQUIRED | 1 + Origin-Realm | REQUIRED | 1 + Destination-Realm | REQUIRED | 1 + Transaction-Id | REQUIRED | 1 + Sip-From-Tag | REQUIRED | 1 + Sip-To-Tag | REQUIRED | 1 + Acct-Session-Id | REQUIRED | 1 + Sip-Call-Duration | REQUIRED | 1 + Sip-Call-Setuptime | REQUIRED | 1 + Sip-Call-Created | REQUIRED | 1 + Sip-Call-MSDuration | REQUIRED | 1 + out_gw | REQUIRED | 1 + call_cost | REQUIRED | 1 + Cost-Information | OPTIONAL | 1 +} + +ANSWER 92001 My-Custom-Answer +{ + Origin-Host | REQUIRED | 1 + Origin-Realm | REQUIRED | 1 + Destination-Realm | REQUIRED | 1 + Transaction-Id | REQUIRED | 1 + Result-Code | REQUIRED | 1 +} +``` + + +```opensips title="dm_send_request usage" +# Building an sending an My-Custom-Request (92001) for the +# My Diameter Application (42) +$var(payload) = "[ + { \"Origin-Host\": \"client.diameter.test\" }, + { \"Origin-Realm\": \"diameter.test\" }, + { \"Destination-Realm\": \"diameter.test\" }, + { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, + { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, + { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, + { \"Sip-Call-Duration\": 6 }, + { \"Sip-Call-Setuptime\": 1 }, + { \"Sip-Call-Created\": 1652372541 }, + { \"Sip-Call-MSDuration\": 5850 }, + { \"out_gw\": \"GW-774\" }, + { \"cost\": \"10.84\" }, + { \"Cost-Information\": [ + {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, + {\"Currency-Code\": 35} + ]} +]"; + +$var(rc) = dm_send_request(42, 92001, $var(payload), $var(rpl_avps)); +xlog("rc: $var(rc), AVPs: $var(rpl_avps)\n"); +$json(avps) := $var(rpl_avps); +``` + + +#### dm_send_answer(avps_json, [is_error]) + + +Send back a Diameter answer message to the interconnected peer in a +*non-blocking* fashion, in response to its request. + + +The following fields will be automatically copied over from the Diameter +request when building the answer message: + + +- Application ID +- Command Code +- Session-Id AVP, if any +- Transaction-Id AVP, if any (only applies when +Session-Id is not present) + + +*Parameters* + + +- *avps_json* (string) - A JSON Array containing the AVPs to include in the answer message (example below). +- *is_error* (boolean, default: *false*) - Set to *true* in order to set the 'E' (error) bit in the answer message. + + +*Return Codes* + + +- **1** - Success +- **-1** - Internal Error + + +This function can only be used from an *EVENT_ROUTE*. + + +```opensips title="dm_send_answer() usage" +event_route [E_DM_REQUEST] { + xlog("Req: $param(sess_id) / $param(app_id) / $param(cmd_code)\n"); + xlog("AVPs: $param(avps_json)\n"); + + $json(avps) := $param(avps_json); + + /* ... process the data (AVPs) ... */ + + /* ... and reply back with more AVPs! */ + $var(ans_avps) = "[ + { \"Vendor-Specific-Application-Id\": [{ + \"Vendor-Id\": 0 + }] }, + + { \"Result-Code\": 2001 }, + { \"Auth-Session-State\": 0 }, + { \"Origin-Host\": \"opensips.diameter.test\" }, + { \"Origin-Realm\": \"diameter.test\" } + ]"; + + if (!dm_send_answer($var(ans_avps))) + xlog("ERROR - failed to send Diameter answer\n"); +} +``` + + +### Exported Asynchronous Functions + + +#### dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv]) + + +Similar to [dm send request](#func_dm_send_request) but performs an asynchronous Diameter request. + + +Uses the same parameters and return codes as +[dm send request](#func_dm_send_request). + + +```opensips title="dm_send_request asynchronous usage" +# Building an sending an My-Custom-Request (92001) for the +# My Diameter Application (42) +$var(payload) = "[ + { \"Origin-Host\": \"client.diameter.test\" }, + { \"Origin-Realm\": \"diameter.test\" }, + { \"Destination-Realm\": \"diameter.test\" }, + { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, + { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, + { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, + { \"Sip-Call-Duration\": 6 }, + { \"Sip-Call-Setuptime\": 1 }, + { \"Sip-Call-Created\": 1652372541 }, + { \"Sip-Call-MSDuration\": 5850 }, + { \"out_gw\": \"GW-774\" }, + { \"cost\": \"10.84\" }, + { \"Cost-Information\": [ + {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, + {\"Currency-Code\": 35} + ]} +]"; + +async(dm_send_request(42, 92001, $var(payload), $var(rpl_avps), dm_reply); + +route[dm_reply] { + xlog("rc: $retcode, AVPs: $var(rpl_avps)\n"); + $json(avps) := $var(rpl_avps); +} +``` + + +### Exported Events + + +#### E_DM_REQUEST + + +This event is raised whenever the *aaa_diameter* +module is loaded and OpenSIPS receives a Diameter request on the configured +Diameter listening interface. + + +Parameters: + + +- *app_id (integer)* - the Diameter Application Identifier +- *cmd_code (integer)* - the Diameter Command Code +- *sess_id (string)* - the value of either the *Session-Id* AVP, *Transaction-Id* AVP or a *NULL* value if neither of these transaction-identifying AVPs is present in the Diameter request. +- *avps_json (string)* - a JSON Array containing the AVPs of the request. Use the [json](../json) module's **$json** variable to easily parse and work with it. + + +Note that this event is currently designed to be mainly consumed by an *event_route*, +since that is the only way to gain access to the [dm send answer](#func_dm_send_answer) +function in order to build custom answer messages. On the other hand, +if the application does not mind the answer being always a 3001 (DIAMETER_COMMAND_UNSUPPORTED) error, +this event can be successfully consumed through any other EVI-compatible delivery channel ☺️ + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/aaa_diameter/aaa_diameter.c b/modules/aaa_diameter/aaa_diameter.c index 9752be117f1..de97e6b1e06 100644 --- a/modules/aaa_diameter/aaa_diameter.c +++ b/modules/aaa_diameter/aaa_diameter.c @@ -324,15 +324,15 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code, cJSON_Delete(avps); if (_dm_send_message(NULL, dmsg, &rpl) != 0) - goto error; + goto ret; rc = _dm_get_message_response(rpl, (rpl_avps_pv?&rpl_avps:NULL)); if (rpl_avps_pv) { pv_value_t val = {(str){rpl_avps, strlen(rpl_avps)}, 0, PV_VAL_STR}; if (pv_set_value(msg, rpl_avps_pv, 0, &val) != 0) LM_ERR("failed to set output rpl_avps pv to: %s\n", rpl_avps); - _dm_release_message_response(rpl, rpl_avps); } + _dm_release_message_response(rpl, rpl_avps); if (rc != 0) { LM_ERR("Diameter request failed (rc: %d)\n", rc); @@ -342,13 +342,14 @@ static int dm_send_request(struct sip_msg *msg, int *app_id, int *cmd_code, return 1; error: + cJSON_Delete(avps); +ret: if (rpl_avps_pv) { pv_value_t val = {STR_NULL, 0, PV_VAL_NULL}; if (pv_set_value(msg, rpl_avps_pv, 0, &val) != 0) LM_ERR("failed to set output rpl_avps pv to NULL\n"); } - cJSON_Delete(avps); return -1; } @@ -468,21 +469,22 @@ struct dm_async_msg { struct dm_cond *cond; }; -static struct dm_async_msg *dm_get_async_msg(pv_spec_t *rpl_avps_pv, aaa_message *dmsg) +static struct dm_async_msg *dm_get_async_msg(pv_spec_t *rpl_avps_pv, struct dm_cond *cond) { struct dm_async_msg *msg = pkg_malloc(sizeof *msg); if (!msg) return NULL; memset(msg, 0, sizeof *msg); msg->ret = rpl_avps_pv; - msg->cond = ((struct dm_message *)(dmsg->avpair))->reply_cond; + msg->cond = cond; + dm_cond_ref(cond); return msg; } static void dm_free_sync_msg(struct dm_async_msg *amsg) { if (amsg->cond) - shm_free(amsg->cond); + dm_cond_unref(amsg->cond); pkg_free(amsg); } @@ -516,8 +518,7 @@ static int dm_send_request_async_reply(int fd, error: if (amsg->ret && pv_set_value(msg, amsg->ret, 0, &val) != 0) LM_ERR("failed to set output rpl_avps pv to NULL\n"); - if (rpl_avps) - _dm_release_message_response(amsg->cond, rpl_avps); + _dm_release_message_response(amsg->cond, rpl_avps); dm_free_sync_msg(amsg); return ret; } @@ -525,12 +526,19 @@ static int dm_send_request_async_reply(int fd, static int dm_send_request_async_tout(int fd, struct sip_msg *msg, void *param) { + int removed; struct dm_async_msg *amsg = (struct dm_async_msg *)param; pv_value_t val = {STR_NULL, 0, PV_VAL_NULL}; + async_status = ASYNC_DONE_CLOSE_FD; + if (pv_set_value(msg, amsg->ret, 0, &val) != 0) LM_ERR("failed to set output rpl_avps pv to NULL\n"); + removed = dm_drop_pending_reply_cond(amsg->cond); + if (removed > 0) + dm_cond_unref(amsg->cond); + dm_free_sync_msg(amsg); return -2; } @@ -542,6 +550,7 @@ static int dm_send_request_async(struct sip_msg *msg, async_ctx *ctx, struct dict_object *req; cJSON *avps; struct dm_async_msg *amsg; + struct dm_cond *cond; if (fd_dict_search(fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_CODE_R, cmd_code, &req, ENOENT) == ENOENT) { @@ -584,12 +593,12 @@ static int dm_send_request_async(struct sip_msg *msg, async_ctx *ctx, _dm_destroy_message(dmsg); goto error; } - if (_dm_send_message_async(NULL, dmsg, &async_status) < 0) { + if (_dm_send_message_async(NULL, dmsg, &async_status, &cond) < 0) { LM_ERR("cannot send async message!\n"); goto error; } - amsg = dm_get_async_msg(rpl_avps_pv, dmsg); + amsg = dm_get_async_msg(rpl_avps_pv, cond); if (!amsg) goto error; cJSON_Delete(avps); diff --git a/modules/aaa_diameter/app_opensips/app_opensips.c b/modules/aaa_diameter/app_opensips/app_opensips.c index ad642003772..ce49b7984be 100644 --- a/modules/aaa_diameter/app_opensips/app_opensips.c +++ b/modules/aaa_diameter/app_opensips/app_opensips.c @@ -183,6 +183,8 @@ static FILE *get_acc_log(void) return acc_log[acc_log_idx]; } +#define MAX_ACC_COLS 100 + #define IOV_ADD_NUMBER(number) \ {\ buf[nums] = malloc(20 + 1); \ @@ -206,18 +208,17 @@ static FILE *get_acc_log(void) #define IOV_CLEANUP() \ {\ - for (nums -= 1; nums > 0; nums--) \ - free(buf[nums]); \ + while (nums > 0) \ + free(buf[--nums]); \ } /* Callback for incoming Base Accounting application messages */ static int acc_request( struct msg ** msg, struct avp * avp, struct session * sess, void * data, enum disp_action * act) { - #define MAX_ACC_COLS 100 struct iovec iov[MAX_ACC_COLS * 2]; char *buf[MAX_ACC_COLS]; struct msg_hdr *hdr = NULL; - int rc, n = 0, nums = 0; + int rc, n = 0, nums = 0, drop_record = 0; fd_log_debug("[ACC] request received"); TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act); @@ -295,6 +296,12 @@ static int acc_request( struct msg ** msg, struct avp * avp, struct session * se time_t ts; unsigned char *bytes; + if (n + 2 > MAX_ACC_COLS * 2 || nums >= MAX_ACC_COLS) { + fd_log_error("[ACC] too many AVPs, dropping accounting record"); + drop_record = 1; + break; + } + bytes = h->avp_value->os.data; ts = ((time_t)bytes[0] << 24) | ((time_t)bytes[1] << 16) | @@ -307,10 +314,22 @@ static int acc_request( struct msg ** msg, struct avp * avp, struct session * se } if (h->avp_value->os.len) { + if (n + 2 > MAX_ACC_COLS * 2) { + fd_log_error("[ACC] too many AVPs, dropping accounting record"); + drop_record = 1; + break; + } + IOV_ADD_STRING(h->avp_value->os.data, h->avp_value->os.len); fd_log_debug("[ACC] adding AVP %d (string, '%.*s')", h->avp_code, h->avp_value->os.len, h->avp_value->os.data); } else { + if (n + 2 > MAX_ACC_COLS * 2 || nums >= MAX_ACC_COLS) { + fd_log_error("[ACC] too many AVPs, dropping accounting record"); + drop_record = 1; + break; + } + IOV_ADD_NUMBER(h->avp_value->u32); fd_log_debug("[ACC] adding AVP %d (integer, %d)", h->avp_code, h->avp_value->u32); @@ -320,7 +339,7 @@ static int acc_request( struct msg ** msg, struct avp * avp, struct session * se CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) ); } - if (acc_log_cdrs && n) { + if (!drop_record && acc_log_cdrs && n) { FILE *f = get_acc_log(); iov[n - 1].iov_base = "\n"; @@ -333,9 +352,8 @@ static int acc_request( struct msg ** msg, struct avp * avp, struct session * se } else { fflush(f); } - - IOV_CLEANUP(); } + IOV_CLEANUP(); fd_log_debug("----------------------------------------------------------------------"); diff --git a/modules/aaa_diameter/dm_impl.c b/modules/aaa_diameter/dm_impl.c index 5ba69776799..e1bb6f22eed 100644 --- a/modules/aaa_diameter/dm_impl.c +++ b/modules/aaa_diameter/dm_impl.c @@ -20,6 +20,7 @@ #include #include +#include #include "../../ut.h" #include "../../lib/list.h" @@ -113,6 +114,7 @@ static struct dm_cond *dm_get_cond(int type, diameter_reply_cb *cb, void *param) return NULL; } memset(cond, 0, sizeof *cond); + cond->ref = 1; cond->type = type; switch (type) { case DM_TYPE_EVENT: @@ -274,6 +276,8 @@ static void dm_cond_event_resume(int sender, void *param) } while (ret < 0 && (errno == EINTR || errno == EAGAIN)); if (ret < 0) LM_ERR("could not notify resume: %s\n", strerror(errno)); + + dm_cond_unref(cond); } static void dm_cond_signal(struct dm_cond *cond) @@ -281,9 +285,10 @@ static void dm_cond_signal(struct dm_cond *cond) LM_INFO("singalling %p/%d\n", cond, cond->type); switch (cond->type) { case DM_TYPE_EVENT: + dm_cond_ref(cond); if (ipc_send_rpc(cond->sync.event.pid, dm_cond_event_resume, cond) < 0) { LM_ERR("could not resume async MI command!\n"); - shm_free(cond); + dm_cond_unref(cond); } break; case DM_TYPE_COND: @@ -295,7 +300,6 @@ static void dm_cond_signal(struct dm_cond *cond) case DM_TYPE_CB: if (cond->sync.cb.f) cond->sync.cb.f(NULL, &cond->rpl, cond->sync.cb.p); - shm_free(cond); break; } } @@ -356,6 +360,7 @@ static int dm_auth_reply(struct msg **_msg, struct avp * avp, struct session * s rpl_cond->rpl.is_error = 0; } dm_cond_signal(rpl_cond); + dm_cond_unref(rpl_cond); out: FD_CHECK(fd_msg_free(msg)); @@ -481,7 +486,7 @@ static int dm_avps2json(void *root, cJSON *avps) break; case AVP_TYPE_INTEGER64: - LM_DBG("%2d. got int64 AVP %s (%u), value: %ld\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->i64); + LM_DBG("%2d. got int64 AVP %s (%u), value: %" PRId64 "\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->i64); num_val = (double)h->avp_value->i64; break; @@ -491,7 +496,7 @@ static int dm_avps2json(void *root, cJSON *avps) break; case AVP_TYPE_UNSIGNED64: - LM_DBG("%2d. got uint64 AVP %s (%u), value: %lu\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->u64); + LM_DBG("%2d. got uint64 AVP %s (%u), value: %" PRIu64 "\n", i, dm_avp.avp_name, h->avp_code, h->avp_value->u64); num_val = (double)h->avp_value->u64; break; @@ -519,6 +524,7 @@ static int dm_avps2json(void *root, cJSON *avps) add: cJSON_AddItemToObject(item, dm_avp.avp_name, val); cJSON_AddItemToArray(avps, item); + item = NULL; skip: FD_CHECK_GT(fd_msg_browse(it, MSG_BRW_NEXT, &it, NULL)); @@ -576,7 +582,12 @@ static int dm_receive_req(struct msg **_req, struct avp * avp, struct session * } } - init_str(&avp_arr, cJSON_PrintUnformatted(avps)); + avp_arr.s = cJSON_PrintUnformatted(avps); + if (!avp_arr.s) { + LM_ERR("cJSON_PrintUnformatted failed\n"); + goto error; + } + avp_arr.len = strlen(avp_arr.s); /* keep the request for a while in order to be able to generate the answer */ if (!dm_server_autoreply_error) @@ -688,10 +699,12 @@ static int dm_receive_msg(struct msg **_msg, struct avp * avp, struct session * if (!hash_find_key(pending_replies, tid)) { LM_ERR("Transaction_Id %.*s already processed!\n", tid.len, tid.s); + hash_unlock(pending_replies, hentry); goto out; } rpl_cond->rpl.json = avps; + avps = NULL; hash_remove_key(pending_replies, tid); hash_unlock(pending_replies, hentry); @@ -710,8 +723,11 @@ static int dm_receive_msg(struct msg **_msg, struct avp * avp, struct session * rpl_cond->rpl.is_error = 0; } dm_cond_signal(rpl_cond); + dm_cond_unref(rpl_cond); out: + if (avps) + cJSON_Delete(avps); cJSON_InitHooks(NULL); FD_CHECK(fd_msg_free(msg)); @@ -825,11 +841,57 @@ int dm_add_pending_reply(const str *callid, struct dm_cond *reply_cond) } *cond_holder = reply_cond; + dm_cond_ref(reply_cond); hash_unlock(pending_replies, hentry); return 0; } +struct dm_find_cond_ctx { + struct dm_cond *cond; + str key; + int found; +}; + +static int dm_match_pending_cond(void *param, str key, void *value) +{ + struct dm_find_cond_ctx *ctx = (struct dm_find_cond_ctx *)param; + + if (value != ctx->cond) + return 0; + + ctx->key = key; + ctx->found = 1; + return 1; +} + +int dm_drop_pending_reply_cond(struct dm_cond *reply_cond) +{ + struct dm_find_cond_ctx ctx; + unsigned int hentry; + + if (!reply_cond) + return 0; + + for (hentry = 0; hentry < hash_size(pending_replies); hentry++) { + memset(&ctx, 0, sizeof ctx); + ctx.cond = reply_cond; + + hash_lock(pending_replies, hentry); + map_for_each(pending_replies->entries[hentry], dm_match_pending_cond, &ctx); + if (!ctx.found) { + hash_unlock(pending_replies, hentry); + continue; + } + + hash_remove(pending_replies, hentry, ctx.key); + hash_unlock(pending_replies, hentry); + return 1; + } + + return 0; +} + /* all of these AVPs are part of "RADIUS Extension for Digest Auth" RFC 5090 */ @@ -1933,21 +1995,22 @@ static void dm_push_queue(aaa_message *msg, struct dm_cond *cond) pthread_mutex_unlock(msg_send_lk); } -int _dm_send_message_async(aaa_conn *_, aaa_message *req, int *fd) +int _dm_send_message_async(aaa_conn *_, aaa_message *req, int *fd, struct dm_cond **cond) { - struct dm_cond *cond; + struct dm_cond *_cond; if (!req) return -1; - cond = dm_get_cond(DM_TYPE_EVENT, NULL, NULL); - if (!cond) { + _cond = dm_get_cond(DM_TYPE_EVENT, NULL, NULL); + if (!_cond) { LM_ERR("out of memory for cond\n"); return -1; } - *fd = cond->sync.event.fd; - dm_push_queue(req, cond); + *fd = _cond->sync.event.fd; + *cond = _cond; + dm_push_queue(req, _cond); LM_DBG("message queued for async sending\n"); @@ -1997,13 +2060,14 @@ static int _dm_get_message_reply(struct dm_cond *cond, diameter_reply *rpl) int _dm_get_message_response(struct dm_cond *cond, char **rpl_avps) { - cJSON *obj; - diameter_reply rpl; - int rc = _dm_get_message_reply(cond, &rpl); + int rc; + + LM_DBG("reply received, Result-Code: %d (%s)\n", cond->rpl.rc, + cond->rpl.is_error ? "FAILURE" : "SUCCESS"); + rc = (cond->rpl.is_error ? -1 : 0); if (rpl_avps) { - obj = dm_api_get_reply(&rpl); - *rpl_avps = cJSON_PrintUnformatted(obj); + *rpl_avps = cJSON_PrintUnformatted(cond->rpl.json); LM_DBG("AVPs: %s\n", *rpl_avps); } return rc; @@ -2186,6 +2250,7 @@ void _dm_destroy_message(aaa_message *msg) dm = (struct dm_message *)msg->avpair; dm_free_avps(&dm->avps); + dm_cond_unref(dm->reply_cond); shm_free(dm); shm_free(msg); diff --git a/modules/aaa_diameter/dm_impl.h b/modules/aaa_diameter/dm_impl.h index 2de25d5fae8..b25cd77f19e 100644 --- a/modules/aaa_diameter/dm_impl.h +++ b/modules/aaa_diameter/dm_impl.h @@ -22,6 +22,7 @@ #define AAA_DIAMETER_IMPL #include "../../aaa/aaa.h" +#include "../../mem/shm_mem.h" #include "diameter_api.h" #define __FD_CHECK(__call__, __retok__, __retval__) \ @@ -122,6 +123,7 @@ struct dm_avp { #define DM_TYPE_CB (1<<2) struct dm_cond { + volatile int ref; int type; union { struct { @@ -140,6 +142,23 @@ struct dm_cond { diameter_reply rpl; }; + +static inline void dm_cond_ref(struct dm_cond *cond) +{ + if (!cond || cond->type == DM_TYPE_COND) + return; + + __atomic_add_fetch(&cond->ref, 1, __ATOMIC_SEQ_CST); +} + +static inline void dm_cond_unref(struct dm_cond *cond) +{ + if (!cond || cond->type == DM_TYPE_COND) + return; + + if (__atomic_sub_fetch(&cond->ref, 1, __ATOMIC_SEQ_CST) == 0) + shm_free(cond); +} int init_mutex_cond(pthread_mutex_t *mutex, pthread_cond_t *cond); extern struct list_head dm_unreplied_req; @@ -169,7 +188,8 @@ int dm_avp_add(aaa_conn *_, aaa_message *msg, aaa_map *avp, void *val, int dm_build_avps(struct list_head *subavps, cJSON *array); int dm_send_message(aaa_conn *_, aaa_message *req, aaa_message **__); int _dm_send_message(aaa_conn *_, aaa_message *req, struct dm_cond **reply_cond); -int _dm_send_message_async(aaa_conn *_, aaa_message *req, int *fd); +int _dm_send_message_async(aaa_conn *_, aaa_message *req, int *fd, struct dm_cond **cond); +int dm_drop_pending_reply_cond(struct dm_cond *reply_cond); int _dm_get_message_response(struct dm_cond *cond, char **rpl_avps); void _dm_release_message_response(struct dm_cond *cond, char *rpl_avps); int dm_destroy_message(aaa_conn *con, aaa_message *msg); diff --git a/modules/aaa_diameter/doc/aaa_diameter.xml b/modules/aaa_diameter/doc/aaa_diameter.xml deleted file mode 100644 index 032f874c7c8..00000000000 --- a/modules/aaa_diameter/doc/aaa_diameter.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - AAA_DIAMETER MODULE - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2021 &osipssol; - diff --git a/modules/aaa_diameter/doc/aaa_diameter_admin.xml b/modules/aaa_diameter/doc/aaa_diameter_admin.xml deleted file mode 100644 index c128eb3cdd4..00000000000 --- a/modules/aaa_diameter/doc/aaa_diameter_admin.xml +++ /dev/null @@ -1,559 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides an RFC 6733 Diameter peer implementation, being - able to act as either Diameter client or server, or both. - - - - Any module that wishes to use it has to do the following: - - - - include aaa.h - - - - make a bind call with a proper Diameter-specific URL, e.g. "diameter:freeDiameter-client.conf" - - - - -
- -
- Diameter Client - - The module implements the core AAA OpenSIPS interface, thus offering - an alternative client implementation to the - aaa_radius module which can be useful, - for example, when performing billing and accounting for the live SIP calls. - - - In addition to the RADIUS client's auth and accounting features, the - Diameter client includes support for sending arbitrary - Diameter requests, further opening up the scope of applications which - can be achieved through OpenSIPS scripting. Such Diameter requests can - be sent using the function. - -
- -
- Diameter Server - - Starting with OpenSIPS 3.5, the Diameter - module includes server-side support as well. - - - First, the event_route module must be loaded in - order to be able to process events in - the OpenSIPS configuration file. These events will contain all necessary - information on the incoming Diameter request. - - - Finally, once the request information is processed and the answer AVPs - are prepared, script writers should use the - function in order to reply with a Diameter answer message. - - - Recommendation: When possible, always load the - dict_sip.fdx freeDiameter extension module - inside your freeDiameter.conf configuration file, - as it contains hundreds of well-known AVP definitions which may be good - to have when inter-operating with other Diameter peer implementations. - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - All Diameter message building and parsing, as well as the peer state - machine and Diameter-related network communication are all powered by - the freeDiameter project - and C libraries, dynamically linking with the "aaa_diameter" module. - - - The following libraries must be installed before running - &osips; with this module loaded: - - - - libfdcore v1.2.1 or higher - - - - libfdproto v1.2.1 or higher - - - -
-
- -
- Exported Parameters -
- <varname>fd_log_level (integer)</varname> - - This parameter measures the quietness of the logging - done by the freeDiameter library. Possible values: - - - 0 (ANNOYING) - 1 (DEBUG) - 3 (NOTICE, default) - 5 (ERROR) - 6 (FATAL) - - - NOTE: since freeDiameter logs to standard output, you must also enable - the new core parameter, log_stdout, - before getting any logs from the library. - - - Setting the <varname>fd_log_level</varname> parameter - - -modparam("aaa_diameter", "fd_log_level", 0) - - - -
- -
- <varname>realm (string)</varname> - - The unique realm to be used by all participating Diameter peers. - - - Default value is "diameter.test". - - - Setting the <varname>realm</varname> parameter - - -modparam("aaa_diameter", "realm", "opensips.org") - - - -
- -
- <varname>peer_identity (string)</varname> - - The identity (realm subdomain) of the Diameter server peer, to which - the OpenSIPS Diameter client peer will connect. - - - Default value is "server" - (i.e. "server.diameter.test"). - - - Setting the <varname>peer_identity</varname> parameter - - -modparam("aaa_diameter", "peer_identity", "server") - - - -
- -
- <varname>aaa_url (string)</varname> - - URL of the diameter client: the configuration file, with an optional - extra-avps-file, where the Diameter client is configured. - - - By default, the connection is not created. - - - Setting the <varname>aaa_url</varname> parameter - - -modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf") - - - - - Setting the <varname>aaa_url</varname> parameter with an extra AVPs file. - - -modparam("aaa_diameter", "aaa_url", "diameter:freeDiameter-client.conf;extra-avps-file:dictionary.opensips") - - - -
- -
- <varname>answer_timeout (integer)</varname> - - Time, in milliseconds, after which a - function call with no received reply will time out and return a - -2 code. - - - Default value is 2000 ms. - - - Setting the <varname>answer_timeout</varname> parameter - - -modparam("aaa_diameter", "answer_timeout", 5000) - - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv])</function> - - - Perform a blocking Diameter request over to the interconnected peer - and return the Result-Code AVP value from the reply. - - Parameters - - - app_id (integer) - ID of the application. - A custom application must be defined in the dictionary.opensips - Diameter configuration file before it can be recognized. - - - cmd_code (integer) - ID of the command. A - custom command code, name and AVP requirements must be defined - in the dictionary.opensips Diameter configuration file beforehand. - body of the HTTP response. - - - avps_json (string) - A JSON Array containing - the AVPs to include in the message. - - - rpl_avps_pv (var, optional) - output variable which will - hold all AVP names from the Diameter Answer along with their values, packed - as a JSON Array string. The "json" module and its $json - variable could be used to iterate this array. - - - - Return Codes - - - 1 - Success - - - - -1 - Internal Error - - - - -2 - Request timeout - (the was exceeded - before an Answer could be processed) - - - - - - This function can be used from any route. - - - <function moreinfo="none">dictionary.opensips</function> extended syntax - - -# Example of defining custom Diameter AVPs, Application IDs, -# Requests and Replies in the "dictionary.opensips" file - -ATTRIBUTE out_gw 232 string -ATTRIBUTE trunk_id 233 string - -ATTRIBUTE rated_duration 234 integer -ATTRIBUTE call_cost 235 integer - -ATTRIBUTE Exponent 429 integer32 -ATTRIBUTE Value-Digits 447 integer64 - -ATTRIBUTE Cost-Unit 424 grouped -{ - Value-Digits | REQUIRED | 1 - Exponent | OPTIONAL | 1 -} - -ATTRIBUTE Currency-Code 425 unsigned32 - -ATTRIBUTE Unit-Value 445 grouped -{ - Value-Digits | REQUIRED | 1 - Exponent | OPTIONAL | 1 -} - -ATTRIBUTE Cost-Information 423 grouped -{ - Unit-Value | REQUIRED | 1 - Currency-Code | REQUIRED | 1 - Cost-Unit | OPTIONAL | 1 -} - -APPLICATION 42 My Diameter Application - -REQUEST 92001 My-Custom-Request -{ - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Transaction-Id | REQUIRED | 1 - Sip-From-Tag | REQUIRED | 1 - Sip-To-Tag | REQUIRED | 1 - Acct-Session-Id | REQUIRED | 1 - Sip-Call-Duration | REQUIRED | 1 - Sip-Call-Setuptime | REQUIRED | 1 - Sip-Call-Created | REQUIRED | 1 - Sip-Call-MSDuration | REQUIRED | 1 - out_gw | REQUIRED | 1 - call_cost | REQUIRED | 1 - Cost-Information | OPTIONAL | 1 -} - -ANSWER 92001 My-Custom-Answer -{ - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Transaction-Id | REQUIRED | 1 - Result-Code | REQUIRED | 1 -} - - - - - - <function moreinfo="none">dm_send_request</function> usage - - -# Building an sending an My-Custom-Request (92001) for the -# My Diameter Application (42) -$var(payload) = "[ - { \"Origin-Host\": \"client.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" }, - { \"Destination-Realm\": \"diameter.test\" }, - { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, - { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, - { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, - { \"Sip-Call-Duration\": 6 }, - { \"Sip-Call-Setuptime\": 1 }, - { \"Sip-Call-Created\": 1652372541 }, - { \"Sip-Call-MSDuration\": 5850 }, - { \"out_gw\": \"GW-774\" }, - { \"cost\": \"10.84\" }, - { \"Cost-Information\": [ - {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, - {\"Currency-Code\": 35} - ]} -]"; - -$var(rc) = dm_send_request(42, 92001, $var(payload), $var(rpl_avps)); -xlog("rc: $var(rc), AVPs: $var(rpl_avps)\n"); -$json(avps) := $var(rpl_avps); - - - -
- -
- - <function moreinfo="none">dm_send_answer(avps_json, [is_error])</function> - - - Send back a Diameter answer message to the interconnected peer in a - non-blocking fashion, in response to its request. - - - The following fields will be automatically copied over from the Diameter - request when building the answer message: - - Application ID - Command Code - Session-Id AVP, if any - Transaction-Id AVP, if any (only applies when - Session-Id is not present) - - - Parameters - - - avps_json (string) - A JSON Array containing - the AVPs to include in the answer message (example below). - - - is_error (boolean, default: false) - - Set to true - in order to set the 'E' (error) bit in the answer message. - - - - Return Codes - - - 1 - Success - - - - -1 - Internal Error - - - - - - This function can only be used from an EVENT_ROUTE. - - - <function moreinfo="none">dm_send_answer()</function> usage - - -event_route [E_DM_REQUEST] { - xlog("Req: $param(sess_id) / $param(app_id) / $param(cmd_code)\n"); - xlog("AVPs: $param(avps_json)\n"); - - $json(avps) := $param(avps_json); - - /* ... process the data (AVPs) ... */ - - /* ... and reply back with more AVPs! */ - $var(ans_avps) = "[ - { \"Vendor-Specific-Application-Id\": [{ - \"Vendor-Id\": 0 - }] }, - - { \"Result-Code\": 2001 }, - { \"Auth-Session-State\": 0 }, - { \"Origin-Host\": \"opensips.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" } - ]"; - - if (!dm_send_answer($var(ans_avps))) - xlog("ERROR - failed to send Diameter answer\n"); -} - - - -
- -
- -
- Exported Asyncronous Functions -
- - <function moreinfo="none">dm_send_request(app_id, cmd_code, avps_json, [rpl_avps_pv])</function> - - - Similar to but performs an asynchronous Diameter request. - - - Uses the same parameters and return codes as - . - - - - <function moreinfo="none">dm_send_request</function> asynchronous usage - - -# Building an sending an My-Custom-Request (92001) for the -# My Diameter Application (42) -$var(payload) = "[ - { \"Origin-Host\": \"client.diameter.test\" }, - { \"Origin-Realm\": \"diameter.test\" }, - { \"Destination-Realm\": \"diameter.test\" }, - { \"Sip-From-Tag\": \"dc93-4fba-91db\" }, - { \"Sip-To-Tag\": \"ae12-47d6-816a\" }, - { \"Acct-Session-Id\": \"a59c-dff0d9efd167\" }, - { \"Sip-Call-Duration\": 6 }, - { \"Sip-Call-Setuptime\": 1 }, - { \"Sip-Call-Created\": 1652372541 }, - { \"Sip-Call-MSDuration\": 5850 }, - { \"out_gw\": \"GW-774\" }, - { \"cost\": \"10.84\" }, - { \"Cost-Information\": [ - {\"Unit-Value\": [{\"Value-Digits\": 1000}]}, - {\"Currency-Code\": 35} - ]} -]"; - -async(dm_send_request(42, 92001, $var(payload), $var(rpl_avps), dm_reply); - -route[dm_reply] { - xlog("rc: $retcode, AVPs: $var(rpl_avps)\n"); - $json(avps) := $var(rpl_avps); -} - - - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_DM_REQUEST</function> - - - This event is raised whenever the aaa_diameter - module is loaded and OpenSIPS receives a Diameter request on the configured - Diameter listening interface. - - Parameters: - - - app_id (integer) - the Diameter Application Identifier - - - cmd_code (integer) - the Diameter Command Code - - - sess_id (string) - the value of either the - Session-Id AVP, Transaction-Id AVP - or a NULL value if neither of these - transaction-identifying AVPs is present in the Diameter request. - - - avps_json (string) - a JSON Array containing the - AVPs of the request. Use the json module's - $json variable - to easily parse and work with it. - - - - - Note that this event is currently designed to be mainly consumed by an event_route, - since that is the only way to gain access to the - function in order to build custom answer messages. On the other hand, - if the application does not mind the answer being always a 3001 (DIAMETER_COMMAND_UNSUPPORTED) error, - this event can be successfully consumed through any other EVI-compatible delivery channel ☺️ - -
- -
- -
diff --git a/modules/aaa_diameter/doc/contributors.xml b/modules/aaa_diameter/doc/contributors.xml deleted file mode 100644 index c768d3e16fb..00000000000 --- a/modules/aaa_diameter/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 114 - 37 - 6850 - 1105 - - - 2. - Razvan Crainea (@razvancrainea) - 38 - 21 - 1423 - 251 - - - 3. - Alexandra Titoc - 6 - 4 - 11 - 2 - - - 4. - Peter Lemenkov (@lemenkov) - 4 - 2 - 2 - 2 - - - 5. - Larry Laffer - 3 - 1 - 6 - 5 - - - 6. - Maksym Sobolyev (@sobomax) - 3 - 1 - 5 - 5 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2023 - Nov 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jul 2024 - Jul 2025 - - - 3. - Larry Laffer - Jul 2025 - Jul 2025 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Liviu Chircu (@liviuchircu) - May 2021 - Mar 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/aaa_radius/README b/modules/aaa_radius/README deleted file mode 100644 index c16f9458fc6..00000000000 --- a/modules/aaa_radius/README +++ /dev/null @@ -1,465 +0,0 @@ -AAA RADIUS MODULE - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. sets (string) - 1.3.2. radius_config (string) - 1.3.3. syslog_name (string) - 1.3.4. fetch_all_values (integer) - - 1.4. Exported Functions - - 1.4.1. radius_send_auth(input_set_name, - output_set_name) - - 1.4.2. radius_send_acct(input_set_name) - - 1.5. Exported Async Functions - - 1.5.1. radius_send_auth(input_set_name, - output_set_name) - - 1.5.2. radius_send_acct(input_set_name) - - 2. Using radius async - - 2.1. Downloading radius-client library - 2.2. Applying the patch - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set sets parameter - 1.2. Set radius_config parameter - 1.3. Set syslog_name parameter - 1.4. Set fetch_all_values parameter - 1.5. radius_send_auth usage - 1.6. radius_send_acct usage - 1.7. radius_send_auth usage - 1.8. radius_send_acct usage - 2.1. downloading the library - 2.2. How to apply the patch - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a Radius implementation for the AAA API - from the core. - - It also provides two functions to be used from the script for - generating custom Radius acct and auth requests. Detection and - handling of SIP-AVPs from Radius replies is automatically and - transparently done by the module. - - Since version 2.2, aaa_radius module supports asynchronous - operations. But in order to use them, one must apply the patch - contained by the modules/aaa_radius folder, called - radius_async_support.patch.In order to do this, you must have - freeradius-client sources. In order to do this you can follow - the tutorial in the end of the documentation. - - Any module that wishes to use it has to do the following: - * include aaa.h - * make a bind call with a proper radius specific url - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - None. - -1.2.2. External Libraries or Applications - - One of the following libraries must be installed before running - OpenSIPS with this module loaded: - * radiusclient-ng 0.5.0 or higher See - http://developer.berlios.de/projects/radiusclient-ng/. - * freeradius-client See http://freeradius.org/. - - One can force the radius library that is usedby setting - RADIUSCLIENT env, before compiling the module, to one of the - following values: - * RADCLI *** libradcli-dev library shall be used; - * FREERADIUS *** libfreeradius-client-dev library shall be - used; - * RADIUSCLIENT *** libradiusclient-ng library shall be used; - - IMPORTANT: If the selected library is not installed the module - won't compile. - - NOTE: If RADIUSCLIENT env not set, the module will try to find - one of the three radius libraries in the following order: - radcli, freeradius, radiusclient-ng. That is if radcli library - is installed it shall be used, else freeradius shall be looked - for and so on. - -1.3. Exported Parameters - -1.3.1. sets (string) - - Sets of Radius AVPs to be used when building custom RADIUS - requests (set of input RADIUS AVPs) or when fetching data from - the RADIUS reply (set of output RADIUS AVPs). - - The format for a set definition is the following: - * " set_name = ( attribute_name1 = var1 [, attribute_name2 = - var2 ]* ) " - - The left-hand side of the assignment must be an attribute name - known by the RADIUS dictionary. - - The right-hand side of the assignment must be a script pseudo - variable or a script AVP. For more information about them see - CookBooks - Scripting Variables. - - Example 1.1. Set sets parameter - -... -modparam("aaa_radius","sets","set4 = ( Sip-User-ID = $avp(10) - , Sip-From-Tag=$si,Sip-To-Tag=$tt ) -") -... - -... -modparam("aaa_radius","sets","set1 = (User-Name=$var(usr), Sip-Group = $ -var(grp), - Service-Type = $var(type)) ") -... - -... -modparam("aaa_radius","sets","set2 = (Sip-Group = $var(sipgrup)) ") -... - - -1.3.2. radius_config (string) - - Radiusclient configuration file. - - This parameter is optional. It must be set only if the - radius_send_acct and radius_send_auth functions are used. - - Example 1.2. Set radius_config parameter - -... -modparam("aaa_radius", "radius_config", "/etc/radiusclient-ng/radiusclie -nt.conf") -... - - -1.3.3. syslog_name (string) - - Enable logging of the client library to syslog, using the given - log name. - - This parameter is optional. Radius client libraries will try to - use syslog to report errors (such as problems with - dictionaries) with the given ident string .If this parameter is - set, then these errors are visible in syslog. Otherwise errors - are hidden. - - By default this parameter is not set (no logging). - - Example 1.3. Set syslog_name parameter -... -modparam("aaa_radius", "syslog_name", "aaa-radius") -... - -1.3.4. fetch_all_values (integer) - - For the output sets, this parameter controls if all the values - (for the same RADIUS AVP) should be returned (otherwise only - the first value will be returned). When enabling this options, - be sure that the variable you use to get the RADIUS output can - store multiple values (like the AVP variables). - - By default this parameter is disabled (set to 0) for backward - compatibility reasons. - - Example 1.4. Set fetch_all_values parameter -... -modparam("aaa_radius", "fetch_all_values", 1) -... - -1.4. Exported Functions - -1.4.1. radius_send_auth(input_set_name, output_set_name) - - This function can be used from the script to make custom radius - authentication request. The function takes two parameters. - - Parameters: - * input_set_name (string) - the name of the set that contains - the list of attributes and pvars that will form the - authentication request (see the “sets” module parameter). - * output_set_name (string) - the name of the set that - contains the list of attributes and pvars that will be - extracted form the authentication reply (see the “sets” - module parameter). - - The sets must be defined using the “sets” exported parameter. - - The function return TRUE (retcode 1) if authentication was - successful, FALSE (retcode -1) if an error (any kind of error) - occurred during authentication processes or FALSE (retcode -2) - if authentication was rejected or denied by RADIUS server. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - Example 1.5. radius_send_auth usage - -... -radius_send_auth("set1","set2"); -switch ($rc) { - case 1: - xlog("authentication ok \n"); - break; - case -1: - xlog("error during authentication\n"); - break; - case -2: - xlog("authentication denied \n"); - break; -} -... - - -1.4.2. radius_send_acct(input_set_name) - - This function can be used from the script to make custom radius - authentication request. The function takes only one string - parameter that represents the name of the set that contains the - list of attributes and pvars that will form the accounting - request. - - Only one set is needed as a parameter because no AVPs can be - extracted from the accounting replies. - - The set must be defined using the "sets" exported parameter. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - Example 1.6. radius_send_acct usage - -... -radius_send_acct("set1"); -... - - -1.5. Exported Async Functions - -1.5.1. radius_send_auth(input_set_name, output_set_name) - - This function can be used from the script to make custom radius - authentication request. - - Parameters: - * input_set_name (string) - the name of the set that contains - the list of attributes and pvars that will form the - authentication request (see the “sets” module parameter). - * output_set_name (string) - the name of the set that - contains the list of attributes and pvars that will be - extracted form the authentication reply (see the “sets” - module parameter). - - The sets must be defined using the “sets” exported parameter. - - The function return TRUE (retcode 1) if authentication was - successful, FALSE (retcode -1) if an error (any kind of error) - occurred during authentication processes or FALSE (retcode -2) - if authentication was rejected or denied by RADIUS server. - - Example 1.7. radius_send_auth usage - -... -{ -async( radius_send_auth("set1","set2"), resume); -} - -route[resume] { -switch ($rc) { - case 1: - xlog("authentication ok \n"); - break; - case -1: - xlog("error during authentication\n"); - break; - case -2: - xlog("authentication denied \n"); - break; -} -... - - -1.5.2. radius_send_acct(input_set_name) - - This function can be used from the script to make custom radius - authentication request. The function takes only one string - parameter that represents the name of the set that contains the - list of attributes and pvars that will form the accounting - request. - - Only one set is needed as a parameter because no AVPs can be - extracted from the accounting replies. - - The set must be defined using the "sets" exported parameter. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - Example 1.8. radius_send_acct usage - -... -{ -async( radius_send_acct("set1","set2"), resume); -} - -route[resume] { -xlog(" accounting finished\n"); -} - -... - - -Chapter 2. Using radius async - -2.1. Downloading radius-client library - - You can download the last freeRADIUS Client Library sources - from here . So the first step would be to download these - sources in any folder you want. In this exaple we will consider - this folder generically called freeRADIUS-client. After you - download the sources, extract the contents of the archive. - - Example 2.1. downloading the library -........ -mkdir freeRADIUS-client; cd freeRADIUS-client -wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-client-1.1.7.tar -.gz -tar -xzvf freeradius-client-1.1.7.tar.gz -........ - -2.2. Applying the patch - - After you extracted the contents of the archive, you can apply - the patch called radius_async_support.patch that you can find - in modules/aaa_radius/ inside OpenSIPS sources folder. You must - apply this patch to the freeRADIUS-client library and after - this you can install the radius library as usual using - configure and make commands and free to use the library. - - Example 2.2. How to apply the patch -........ -cd freeRADIUS-client/freeradius-client-1.1.7.tar.gz -patch -p1 < /path/to/opensips/modules/aaa_radius/radius_async_support.pa -tch -./configure --any-options-you-want -make -sudo make install -........ - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Irina-Maria Stanescu 24 10 1432 60 - 2. Ionut Ionita (@ionutrazvanionita) 23 11 1258 30 - 3. Razvan Crainea (@razvancrainea) 15 13 51 42 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 15 12 102 82 - 5. Liviu Chircu (@liviuchircu) 9 7 21 49 - 6. Vlad Patrascu (@rvlad-patrascu) 6 3 49 73 - 7. Boris Ratner 4 2 38 5 - 8. Anca Vamanu 4 2 5 3 - 9. Maksym Sobolyev (@sobomax) 4 2 4 4 - 10. Matt Lehner 3 1 32 3 - - All remaining contributors: Авдиенко Михаил, Alex Massover, - Alexandra Titoc, Ken Rice, Julián Moreno Patiño, Peter Lemenkov - (@lemenkov), Walter Doekes (@wdoekes), Zero King (@l2dy), Dan - Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Zero King (@l2dy) Mar 2020 - Mar 2020 - 5. Razvan Crainea (@razvancrainea) Sep 2010 - Sep 2019 - 6. Dan Pascu (@danpascu) May 2019 - May 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2009 - Apr 2019 - 9. Liviu Chircu (@liviuchircu) Mar 2014 - Nov 2018 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Julián Moreno Patiño, Walter Doekes (@wdoekes), Boris Ratner, - Matt Lehner, Irina-Maria Stanescu, Авдиенко Михаил, Alex - Massover, Anca Vamanu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Zero King (@l2dy), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Razvan Crainea (@razvancrainea), Ionut Ionita - (@ionutrazvanionita), Walter Doekes (@wdoekes), Bogdan-Andrei - Iancu (@bogdan-iancu), Boris Ratner, Irina-Maria Stanescu. - - Documentation Copyrights: - - Copyright © 2009 Irina-Maria Stanescu - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/aaa_radius/README.md b/modules/aaa_radius/README.md new file mode 100644 index 00000000000..b7641b98a10 --- /dev/null +++ b/modules/aaa_radius/README.md @@ -0,0 +1,393 @@ +--- +title: "AAA RADIUS MODULE" +description: "This module provides a Radius implementation for the AAA API from the core." +--- + +## Admin Guide + + +### Overview + + +This module provides a Radius implementation for the AAA API from the core. + + +It also provides two functions to be used from the script for generating custom Radius acct and auth requests. +Detection and handling of SIP-AVPs from Radius replies is automatically and transparently done by the module. + + +Since version 2.2, aaa_radius module supports asynchronous operations. But in order to use them, one must apply +the patch contained by the modules/aaa_radius folder, called *radius_async_support.patch*.In +order to do this, you must have freeradius-client sources. In order to do this you can follow +the tutorial in the end of the documentation. + + +Any module that wishes to use it has to do the following: + + +- *include aaa.h* +- *make a bind call with a proper radius specific url* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +One of the following libraries must be installed before running +OpenSIPS with this module loaded: + + +- *radiusclient-ng* 0.5.0 or higher. See [http://developer.berlios.de/projects/radiusclient-ng/](http://developer.berlios.de/projects/radiusclient-ng/). +- *freeradius-client*. See [http://freeradius.org/](http://freeradius.org/). + + +One can force the radius library that is usedby setting RADIUSCLIENT env, before compiling the module, to one of the following values: + + +- *RADCLI* - libradcli-dev library shall be used; +- *FREERADIUS* - libfreeradius-client-dev library shall be used; +- *RADIUSCLIENT* - libradiusclient-ng library shall be used; + + +> [!IMPORTANT] +> If the selected library is not installed the module won't compile. + +> [!NOTE] +> If RADIUSCLIENT env not set, the module will try to find one of the three radius libraries in +> the following order: radcli, freeradius, radiusclient-ng. That is if radcli library is installed +> it shall be used, else freeradius shall be looked for and so on. + + +### Exported Parameters + + +#### sets (string) + + +Sets of Radius AVPs to be used when building custom RADIUS requests (set of input RADIUS AVPs) +or when fetching data from the RADIUS reply (set of output RADIUS AVPs). + + +The format for a set definition is the following: + + +- " set_name = ( attribute_name1 = var1 [, attribute_name2 = var2 ]* ) " + + +The left-hand side of the assignment must be an attribute name known by the RADIUS dictionary. + + +The right-hand side of the assignment must be a script pseudo variable or +a script AVP. For more information about them see [CookBooks - Scripting Variables](https://docs.opensips.org/manual/3-6/script-corevar/). + + +```opensips title="Set sets parameter" +... +modparam("aaa_radius","sets","set4 = ( Sip-User-ID = $avp(10) + , Sip-From-Tag=$si,Sip-To-Tag=$tt ) ") +... + +... +modparam("aaa_radius","sets","set1 = (User-Name=$var(usr), Sip-Group = $var(grp), + Service-Type = $var(type)) ") +... + +... +modparam("aaa_radius","sets","set2 = (Sip-Group = $var(sipgrup)) ") +... +``` + + +#### radius_config (string) + + +Radiusclient configuration file. + + +This parameter is optional. It must be set only if the radius_send_acct +and radius_send_auth functions are used. + + +```opensips title="Set radius_config parameter" +... +modparam("aaa_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf") +... +``` + + +#### syslog_name (string) + + +Enable logging of the client library to syslog, using the given log name. + + +This parameter is optional. Radius client libraries will try to use syslog +to report errors (such as problems with dictionaries) with the given ident +string .If this parameter is set, then these errors are visible in syslog. +Otherwise errors are hidden. + + +By default this parameter is not set (no logging). + + +```opensips title="Set syslog_name parameter" +... +modparam("aaa_radius", "syslog_name", "aaa-radius") +... +``` + + +#### fetch_all_values (integer) + + +For the output sets, this parameter controls if all the values (for the same +RADIUS AVP) should be returned (otherwise only the first value will be +returned). When enabling this options, be sure that the variable you use +to get the RADIUS output can store multiple values (like the AVP variables). + + +By default this parameter is disabled (set to 0) for backward compatibility +reasons. + + +```opensips title="Set fetch_all_values parameter" +... +modparam("aaa_radius", "fetch_all_values", 1) +... +``` + + +### Exported Functions + + +#### radius_send_auth(input_set_name, output_set_name) + + +This function can be used from the script to make custom +radius authentication request. The function takes two parameters. + + +Parameters: + + +- *input_set_name* (string) - the name of the +set that contains the list of attributes and pvars that will +form the authentication request (see the "sets" +module parameter). +- *output_set_name* (string) - the name of the +set that contains the list of attributes and pvars that will be +extracted form the authentication reply (see the "sets" +module parameter). + + +The sets must be defined using the "sets" exported +parameter. + + +The function return TRUE (retcode 1) if authentication was +successful, FALSE (retcode -1) if an error (any kind of error) +occurred during authentication processes or FALSE (retcode -2) if +authentication was rejected or denied by RADIUS server. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. + + +```opensips title="radius_send_auth usage" +... +radius_send_auth("set1","set2"); +switch ($rc) { + case 1: + xlog("authentication ok \n"); + break; + case -1: + xlog("error during authentication\n"); + break; + case -2: + xlog("authentication denied \n"); + break; +} +... + + +``` + + +#### radius_send_acct(input_set_name) + + +This function can be used from the script to make custom +radius authentication request. The function takes only one string parameter +that represents the name of the set that contains the list of attributes +and pvars that will form the accounting request. + + +Only one set is needed as a parameter because no AVPs can be extracted +from the accounting replies. + + +The set must be defined using the "sets" exported parameter. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. + + +```opensips title="radius_send_acct usage" +... +radius_send_acct("set1"); +... + + +``` + + +### Exported Asynchronous Functions + + +#### radius_send_auth(input_set_name, output_set_name) + + +This function can be used from the script to make custom +radius authentication request. + + +Parameters: + + +- *input_set_name* (string) - the name of the +set that contains the list of attributes and pvars that will +form the authentication request (see the "sets" +module parameter). +- *output_set_name* (string) - the name of the +set that contains the list of attributes and pvars that will be +extracted form the authentication reply (see the "sets" +module parameter). + + +The sets must be defined using the "sets" exported +parameter. + + +The function return TRUE (retcode 1) if authentication was +successful, FALSE (retcode -1) if an error (any kind of error) +occurred during authentication processes or FALSE (retcode -2) if +authentication was rejected or denied by RADIUS server. + + +```opensips title="radius_send_auth usage" +... +{ +async( radius_send_auth("set1","set2"), resume); +} + +route[resume] { +switch ($rc) { + case 1: + xlog("authentication ok \n"); + break; + case -1: + xlog("error during authentication\n"); + break; + case -2: + xlog("authentication denied \n"); + break; +} +... + + +``` + + +#### radius_send_acct(input_set_name) + + +This function can be used from the script to make custom +radius authentication request. The function takes only one string parameter +that represents the name of the set that contains the list of attributes +and pvars that will form the accounting request. + + +Only one set is needed as a parameter because no AVPs can be extracted +from the accounting replies. + + +The set must be defined using the "sets" exported parameter. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. + + +```opensips title="radius_send_acct usage" +... +{ +async( radius_send_acct("set1","set2"), resume); +} + +route[resume] { +xlog(" accounting finished\n"); +} + +... + + +``` + + +## Using radius async + + +### Downloading radius-client library + + +You can download the last freeRADIUS Client Library sources from +[here](ftp://ftp.freeradius.org/pub/freeradius/freeradius-client-1.1.7.tar.gz). +So the first step would be to download these sources in any folder you want. +In this exaple we will consider this folder generically called +*freeRADIUS-client*. After you download the sources, +extract the contents of the archive. + + +```bash title="downloading the library" +........ +mkdir freeRADIUS-client; cd freeRADIUS-client +wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-client-1.1.7.tar.gz +tar -xzvf freeradius-client-1.1.7.tar.gz +........ + +``` + + +### Applying the patch + + +After you extracted the contents of the archive, you can apply the patch +called *radius_async_support.patch* that you can find in +*modules/aaa_radius/* inside OpenSIPS sources folder. +You must apply this patch to the freeRADIUS-client library and after this +you can install the radius library as usual using configure and make +commands and free to use the library. + + +```bash title="How to apply the patch" +........ +cd freeRADIUS-client/freeradius-client-1.1.7.tar.gz +patch -p1 < /path/to/opensips/modules/aaa_radius/radius_async_support.patch +./configure --any-options-you-want +make +sudo make install +........ + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/aaa_radius/doc/aaa_radius.xml b/modules/aaa_radius/doc/aaa_radius.xml deleted file mode 100644 index d4cc50f2937..00000000000 --- a/modules/aaa_radius/doc/aaa_radius.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - AAA RADIUS MODULE - &osipsname; - - - - &admin; - &tutorial; - &contrib; - - &docCopyrights; - ©right; 2009 Irina-Maria Stanescu - ©right; 2009 &voicesystem; - diff --git a/modules/aaa_radius/doc/aaa_radius_admin.xml b/modules/aaa_radius/doc/aaa_radius_admin.xml deleted file mode 100644 index 38c28eed3dd..00000000000 --- a/modules/aaa_radius/doc/aaa_radius_admin.xml +++ /dev/null @@ -1,416 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a Radius implementation for the AAA API from the core. - - - It also provides two functions to be used from the script for generating custom Radius acct and auth requests. - Detection and handling of SIP-AVPs from Radius replies is automatically and transparently done by the module. - - - - Since version 2.2, aaa_radius module supports asynchronous operations. But in order to use them, one must apply - the patch contained by the modules/aaa_radius folder, called radius_async_support.patch.In - order to do this, you must have freeradius-client sources. In order to do this you can follow - the tutorial in the end of the documentation. - - - - Any module that wishes to use it has to do the following: - - - - include aaa.h - - - - make a bind call with a proper radius specific url - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - One of the following libraries must be installed before running - &osips; with this module loaded: - - - - radiusclient-ng 0.5.0 or higher - See - http://developer.berlios.de/projects/radiusclient-ng/. - - - - freeradius-client - See - http://freeradius.org/. - - - - - One can force the radius library that is usedby setting RADIUSCLIENT env, before compiling the module, to one of the following values: - - - RADCLI *** libradcli-dev library shall be used; - - - - FREERADIUS *** libfreeradius-client-dev library shall be used; - - - - RADIUSCLIENT *** libradiusclient-ng library shall be used; - - - - IMPORTANT: If the selected library is not installed the module won't compile. - NOTE: If RADIUSCLIENT env not set, the module will try to find one of the three radius libraries in - the following order: radcli, freeradius, radiusclient-ng. That is if radcli library is installed - it shall be used, else freeradius shall be looked for and so on. - -
-
- -
- Exported Parameters -
- <varname>sets (string)</varname> - - Sets of Radius AVPs to be used when building custom RADIUS requests (set of input RADIUS AVPs) - or when fetching data from the RADIUS reply (set of output RADIUS AVPs). - - - - The format for a set definition is the following: - - - - - " set_name = ( attribute_name1 = var1 [, attribute_name2 = var2 ]* ) " - - - - - The left-hand side of the assignment must be an attribute name known by the RADIUS dictionary. - - - The right-hand side of the assignment must be a script pseudo variable or - a script AVP. For more information about them see - CookBooks - Scripting Variables. - - - Set <varname>sets</varname> parameter - - -... -modparam("aaa_radius","sets","set4 = ( Sip-User-ID = $avp(10) - , Sip-From-Tag=$si,Sip-To-Tag=$tt ) ") -... - -... -modparam("aaa_radius","sets","set1 = (User-Name=$var(usr), Sip-Group = $var(grp), - Service-Type = $var(type)) ") -... - -... -modparam("aaa_radius","sets","set2 = (Sip-Group = $var(sipgrup)) ") -... - - - -
- -
- <varname>radius_config (string)</varname> - - Radiusclient configuration file. - - - This parameter is optional. It must be set only if the radius_send_acct - and radius_send_auth functions are used. - - - Set <varname>radius_config</varname> parameter - - -... -modparam("aaa_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf") -... - - - -
- -
- <varname>syslog_name (string)</varname> - - Enable logging of the client library to syslog, using the given log name. - - - This parameter is optional. Radius client libraries will try to use syslog - to report errors (such as problems with dictionaries) with the given ident - string .If this parameter is set, then these errors are visible in syslog. - Otherwise errors are hidden. - - - By default this parameter is not set (no logging). - - - Set <varname>syslog_name</varname> parameter - -... -modparam("aaa_radius", "syslog_name", "aaa-radius") -... - - -
- -
- <varname>fetch_all_values (integer)</varname> - - For the output sets, this parameter controls if all the values (for the same - RADIUS AVP) should be returned (otherwise only the first value will be - returned). When enabling this options, be sure that the variable you use - to get the RADIUS output can store multiple values (like the AVP variables). - - - By default this parameter is disabled (set to 0) for backward compatibility - reasons. - - - Set <varname>fetch_all_values</varname> parameter - -... -modparam("aaa_radius", "fetch_all_values", 1) -... - - -
- -
- -
- Exported Functions - -
- - - <function moreinfo="none">radius_send_auth(input_set_name, output_set_name)</function> - - - This function can be used from the script to make custom - radius authentication request. The function takes two parameters. - - Parameters: - - - input_set_name (string) - the name of the - set that contains the list of attributes and pvars that will - form the authentication request (see the sets - module parameter). - - - output_set_name (string) - the name of the - set that contains the list of attributes and pvars that will be - extracted form the authentication reply (see the sets - module parameter). - - - - The sets must be defined using the sets exported - parameter. - - - The function return TRUE (retcode 1) if authentication was - successful, FALSE (retcode -1) if an error (any kind of error) - occurred during authentication processes or FALSE (retcode -2) if - authentication was rejected or denied by RADIUS server. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - - <function>radius_send_auth</function> usage - - -... -radius_send_auth("set1","set2"); -switch ($rc) { - case 1: - xlog("authentication ok \n"); - break; - case -1: - xlog("error during authentication\n"); - break; - case -2: - xlog("authentication denied \n"); - break; -} -... - - - -
- -
- - <function moreinfo="none">radius_send_acct(input_set_name)</function> - - - This function can be used from the script to make custom - radius authentication request. The function takes only one string parameter - that represents the name of the set that contains the list of attributes - and pvars that will form the accounting request. - - - Only one set is needed as a parameter because no AVPs can be extracted - from the accounting replies. - - - The set must be defined using the "sets" exported parameter. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - - - <function>radius_send_acct</function> usage - - -... -radius_send_acct("set1"); -... - - - -
-
- -
- Exported Async Functions - -
- - - <function moreinfo="none">radius_send_auth(input_set_name, output_set_name)</function> - - - This function can be used from the script to make custom - radius authentication request. - - Parameters: - - - input_set_name (string) - the name of the - set that contains the list of attributes and pvars that will - form the authentication request (see the sets - module parameter). - - - output_set_name (string) - the name of the - set that contains the list of attributes and pvars that will be - extracted form the authentication reply (see the sets - module parameter). - - - - The sets must be defined using the sets exported - parameter. - - - The function return TRUE (retcode 1) if authentication was - successful, FALSE (retcode -1) if an error (any kind of error) - occurred during authentication processes or FALSE (retcode -2) if - authentication was rejected or denied by RADIUS server. - - - <function>radius_send_auth</function> usage - - -... -{ -async( radius_send_auth("set1","set2"), resume); -} - -route[resume] { -switch ($rc) { - case 1: - xlog("authentication ok \n"); - break; - case -1: - xlog("error during authentication\n"); - break; - case -2: - xlog("authentication denied \n"); - break; -} -... - - - -
- -
- - <function moreinfo="none">radius_send_acct(input_set_name)</function> - - - This function can be used from the script to make custom - radius authentication request. The function takes only one string parameter - that represents the name of the set that contains the list of attributes - and pvars that will form the accounting request. - - - Only one set is needed as a parameter because no AVPs can be extracted - from the accounting replies. - - - The set must be defined using the "sets" exported parameter. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE and LOCAL_ROUTE. - - - - <function>radius_send_acct</function> usage - - -... -{ -async( radius_send_acct("set1","set2"), resume); -} - -route[resume] { -xlog(" accounting finished\n"); -} - -... - - - -
-
-
diff --git a/modules/aaa_radius/doc/aaa_radius_tutorial.xml b/modules/aaa_radius/doc/aaa_radius_tutorial.xml deleted file mode 100644 index d81adc8d70e..00000000000 --- a/modules/aaa_radius/doc/aaa_radius_tutorial.xml +++ /dev/null @@ -1,51 +0,0 @@ - - Using radius async -
- Downloading radius-client library - - You can download the last freeRADIUS Client Library sources from - - here . - So the first step would be to download these sources in any folder you want. - In this exaple we will consider this folder generically called - freeRADIUS-client. After you download the sources, - extract the contents of the archive. - - - downloading the library - -........ -mkdir freeRADIUS-client; cd freeRADIUS-client -wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-client-1.1.7.tar.gz -tar -xzvf freeradius-client-1.1.7.tar.gz -........ - - -
- -
- Applying the patch - - After you extracted the contents of the archive, you can apply the patch - called radius_async_support.patch that you can find in - modules/aaa_radius/ inside &osips; sources folder. - You must apply this patch to the freeRADIUS-client library and after this - you can install the radius library as usual using configure and make - commands and free to use the library. - - - How to apply the patch - -........ -cd freeRADIUS-client/freeradius-client-1.1.7.tar.gz -patch -p1 < /path/to/opensips/modules/aaa_radius/radius_async_support.patch -./configure --any-options-you-want -make -sudo make install -........ - - -
- -
diff --git a/modules/aaa_radius/doc/contributors.xml b/modules/aaa_radius/doc/contributors.xml deleted file mode 100644 index f4f7e0a7ae2..00000000000 --- a/modules/aaa_radius/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Irina-Maria Stanescu - 24 - 10 - 1432 - 60 - - - 2. - Ionut Ionita (@ionutrazvanionita) - 23 - 11 - 1258 - 30 - - - 3. - Razvan Crainea (@razvancrainea) - 15 - 13 - 51 - 42 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 15 - 12 - 102 - 82 - - - 5. - Liviu Chircu (@liviuchircu) - 9 - 7 - 21 - 49 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 3 - 49 - 73 - - - 7. - Boris Ratner - 4 - 2 - 38 - 5 - - - 8. - Anca Vamanu - 4 - 2 - 5 - 3 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 4 - - - 10. - Matt Lehner - 3 - 1 - 32 - 3 - - - -
-All remaining contributors: Авдиенко Михаил, Alex Massover, Alexandra Titoc, Ken Rice, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Zero King (@l2dy), Dan Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Sep 2010 - Sep 2019 - - - 6. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2009 - Apr 2019 - - - 9. - Liviu Chircu (@liviuchircu) - Mar 2014 - Nov 2018 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Walter Doekes (@wdoekes), Boris Ratner, Matt Lehner, Irina-Maria Stanescu, Авдиенко Михаил, Alex Massover, Anca Vamanu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Ionut Ionita (@ionutrazvanionita), Walter Doekes (@wdoekes), Bogdan-Andrei Iancu (@bogdan-iancu), Boris Ratner, Irina-Maria Stanescu. -
- -
diff --git a/modules/acc/README b/modules/acc/README deleted file mode 100644 index e025b10ae5c..00000000000 --- a/modules/acc/README +++ /dev/null @@ -1,1144 +0,0 @@ -Acc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. General Example - - 1.2. Extra accounting - - 1.2.1. Overview - 1.2.2. Definitions and syntax - 1.2.3. How it works - 1.2.4. Radius accounting dependencies - - 1.3. Multi Call-Legs accounting - - 1.3.1. Overview - 1.3.2. Configuration - 1.3.3. Logged data - - 1.4. CDRs accounting - - 1.4.1. Overview - 1.4.2. Configuration - 1.4.3. How it works - - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. External Libraries or Applications - - 1.6. Exported Parameters - - 1.6.1. early_media (integer) - 1.6.2. report_cancels (integer) - 1.6.3. detect_direction (integer) - 1.6.4. extra_fields (string) - 1.6.5. leg_fields (string) - 1.6.6. log_level (integer) - 1.6.7. log_facility (string) - 1.6.8. aaa_url (string) - 1.6.9. service_type (integer) - 1.6.10. db_table_acc (string) - 1.6.11. db_table_missed_calls (string) - 1.6.12. db_url (string) - 1.6.13. acc_method_column (string) - 1.6.14. acc_from_tag_column (string) - 1.6.15. acc_to_tag_column (string) - 1.6.16. acc_callid_column (string) - 1.6.17. acc_sip_code_column (string) - 1.6.18. acc_sip_reason_column (string) - 1.6.19. acc_time_column (string) - - 1.7. Exported Pseudo-Variables - - 1.7.1. $acc_extra(tag_name) - 1.7.2. $(acc_leg(tag_name)[leg_index]) - 1.7.3. $acc_current_leg (read-only) - - 1.8. Exported Functions - - 1.8.1. do_accounting(type, [flags], [table]) - 1.8.2. drop_accounting([type], [flags]) - 1.8.3. acc_log_request(comment) - 1.8.4. acc_db_request(comment, table) - 1.8.5. acc_aaa_request(comment) - 1.8.6. acc_evi_request(comment) - 1.8.7. acc_new_leg() - 1.8.8. acc_load_ctx_from_dlg() - 1.8.9. acc_unload_ctx_from_dlg() - - 1.9. Exported Events - - 1.9.1. E_ACC_CDR - 1.9.2. E_ACC_EVENT - 1.9.3. E_ACC_MISSED_EVENT - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. early_media example - 1.2. report_cancels example - 1.3. detect_direction example - 1.4. Setting extra_fields example: - 1.5. Setting leg_fields example: - 1.6. log_level example - 1.7. log_facility example - 1.8. Set aaa_url parameter - 1.9. service_type example - 1.10. db_table_acc example - 1.11. db_table_missed_calls example - 1.12. db_url example - 1.13. acc_method_column example - 1.14. acc_from_tag_column example - 1.15. acc_to_tag_column example - 1.16. acc_callid_column example - 1.17. acc_sip_code_column example - 1.18. acc_sip_reason_column example - 1.19. acc_time_column example - 1.20. do_accounting usage - 1.21. drop_accounting usage - 1.22. acc_log_request usage - 1.23. acc_db_request usage - 1.24. acc_aaa_request usage - 1.25. acc_evi_request usage - 1.26. acc_new_leg usage - 1.27. acc_load_ctx_from_dlg usage - -Chapter 1. Admin Guide - -1.1. Overview - - The ACC module is used to account transaction information to - different backends such as syslog, SQL, AAA. - - To account a transaction and to choose which set of backends to - be used, the script writer only has to mark the transaction for - accounting by using the do_accounting() script function. Note - that the function is not actually doing the accounting at that - very time, it is just setting a marker - the actual accounting - will be done later when the transaction or dialog will be - completed. - - Even so, the module allows the script writer to force - accounting on the spot in special cases via some other script - functions. - - The accounting module will log by default a fixed set of - attributes for the transaction - if you customize your - accounting by adding more information to be logged, please see - the next chapter about extra accounting - Section 1.2, “Extra - accounting”. - - The fixed minimal accounting information is: - * Request Method name - * From header TAG parameter - * To header TAG parameter - * Call-Id - * 3-digit Status code from final reply - * Reason phrase from final reply - * Timestamp when transaction was completed - - If a value is not present in the request, the empty string is - accounted instead. - - Note that: - * A single INVITE may produce multiple accounting reports -- - that's most likely due to the SIP forking feature. - * Since version 2.2, all flags used for accounting have been - replaced with the do_accounting() function. No need to - worry anymore whether you have set the flags or not, or be - confused by various flag names, now you only have to call - the function and it will do all the work for you. - * OpenSIPS now supports session/dialog accounting. It can - automatically correlate INVITEs with BYEs for generating - proper CDRs, for example for billing purposes. - * If a UA fails in the middle of a conversation, a proxy will - never find out about it. In general, a better practice is - to account from an end-device (such as PSTN gateway), which - best knows about call status (including media status and - PSTN status in case of the gateway). - - The SQL, Event Interface and AAA backend support are compiled - in the module. - - A very comprehensive description of how the accounting module - works in terms accounting scope, accounting events and - accounting backends can be found in this online Advanced - Accounting Tutorial. - -1.1.1. General Example - -loadmodule "modules/acc/acc.so" - -if ($ru=~"sip:+40") /* calls to Romania */ { - if (!proxy_authorize("sip_domain.net" /* realm */, - "subscriber" /* table name */)) { - proxy_challenge("sip_domain.net" /* realm */, "0" /* no qop */ ) -; - exit; - } - - if (is_method("INVITE") && $au!=$fU) { - xlog("FROM URI != digest username\n"); - sl_send_reply(403,"Forbidden"); - } - - do_accounting("log"); /* set for accounting via syslog */ - t_relay(); /* enter stateful mode now */ -}; - -1.2. Extra accounting - -1.2.1. Overview - - Along the static default information, the ACC module allows - dynamic selection of extra information to be logged using the - acc_extra pseudovariable. This allows you to log any - pseudo-variable (AVPs, parts of the request, parts of the - reply, etc). - -1.2.2. Definitions and syntax - - Selection of extra information is done via extra_field - parameter by specifying tags and log_names for the additional - information. This information is defined via acc_extra - pseudovariable, referenced with the define tag. If the tag is - not specified, its value will be considered to be the same as - the log_value. Accounting backend(log, db, aaa, evi) is - specified at the beginning of the definition, separated by ':' - from the rest. The syntax of the parameter is: - * backend : tag -> log_name (';'tag -> log_name)* - * backend : tag (';' tag)* - - Extra values are consistent during the whole call. Setting a - value during a request, will cause it to remain visible during - all replies. Also, concerning CDR logging, setting a value on - the initial INVITE will result in having that value throughout - the dialog. - - Via log_name you define how/where the data will be logged. Its - meaning depends of the accounting support which is used: - * LOG accounting - log_name will be just printed along with - the data in log_name=data format; - * DB accounting - log_name will be the name of the DB column - where the data will be stored.IMPORTANT: add in db acc - table the columns corresponding to each extra data; - * AAA accounting - log_name will be the AVP name used for - packing the data into AAA message. The log_name will be - translated to AVP number via the dictionary. IMPORTANT: add - in AAA dictionary the log_name attribute. - * Events accounting - log_name will be the name of the - parameter in the event raised. - -1.2.3. How it works - - Declaring an extra in the format of -modparam("acc", "extra_fields", "log: a -> test_a") - - will enable you to set the value for test_a field of the log - only by setting $acc_extra(a) variable. Otherwise, the field - shall be logged with no value(null). - -1.2.4. Radius accounting dependencies - - If radius accounting is used, except from a radius client - library which is mandatory, dictionary.rfc2866 must be included - for the module to work properly. - -1.3. Multi Call-Legs accounting - -1.3.1. Overview - - A SIP call can have multiple legs due forwarding actions. For - example user A calls user B which forwards the call to user C. - There is only one SIP call but with 2 legs ( A to B and B to - C). Accounting the legs of a call is required for proper - billing of the calls (if C is a PSTN number and the call is - billed, user B must pay for the call - as last party modifing - the call destination-, and not A - as initiator of the call. - Call forwarding on server is only one example which shows the - necessity of the having an accounting engine with multiple legs - support. - -1.3.2. Configuration - - First how it works: The idea is to have a variable to store a - set of values for each leg. The meaning of the variable content - is strictly decided by the script writer - it can be the origin - and source of the leg, its status or any other related - information. By default there is defined only one leg. Script - writer has to decide when is the time to create a new leg, by - using acc_new_leg() script function. When creating a new leg, - all the values for that leg will be set to NULL by default. - - When the accounting information for the call will be - written/sent, all the call-leg pairs will be added. - - By default, the multiple call-leg support is disabled - it can - be enabled just by setting acc_leg variable leg_fields module - parameter. Note that the last one only makes sense only for - CDRs that are generated automatically by OpenSIPS. - -1.3.3. Logged data - - For each call, all the values from the acc_leg variable will be - logged. How the information will be actually logged, depends of - the data backend: - * syslog -- all leg-sets will be added to one record string - as acc_leg(leg1)=xxx, acc_leg(leg2)=xxxx ,... sets. - * database -- each pair will be separately logged (due DB - data structure constraints); several records will be - written, the difference between them being only the fields - corresponding to the call-leg info. - -Note - You will need to add in your DB (all acc related tables) - the colums for call-leg info (a column for each leg value - of the set). - * AAA -- all sets will be added to the same AAA accounting - message as AAA AVPs - for each call-leg a set of AAA AVPs - will be added (corresponding to the per-leg set) - -Note - You will need to add in your dictionary the AAA AVPs used - in call-leg set definition. - * events -- each pair will appear as a different - parameter-value pair in the event. Similar to the database - behavior, multiple events will be raised, and the only - difference between them is the leg information. - - Important!!! In order to use RADIUS, one must include the AVPs - which are located in - $(opensips_install_dir)/etc/dictionary.opensips, both in - opensips radius config script dictionary and radius server - dictionary. Most important are the last three AVPs (IDs : 227, - 228, 229) which you won't find in any SIP dictionary (at least - at this moment) because they are only used in openSips. - -1.4. CDRs accounting - -1.4.1. Overview - - ACC module can now also maintain session/dialog accounting. - This allows you to log useful information like call duration, - call start time and setup time. - -1.4.2. Configuration - - In order to have CDRs accounting, first you need to set the cdr - flag when calling do_accounting() script function for the - initial INVITE of the dialog. - -1.4.3. How it works - - This type of accounting is based on the dialog module. When an - initial INVITE is received, if the cdr flag is set, then the - dialog creation time is saved. Once the call is answered and - the ACK is received, other information like extra values or leg - values are saved. When the corresponding BYE is received, the - call duration is computed and all information is stored to the - desired backend. - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * tm -- Transaction Manager - * a database module -- If SQL support is used. - * rr -- Record Route, if “detect_direction” module parameter - is enabled. - * an aaa module - * dialog -- Dialog, if “cdr” option is used - -1.5.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none. - -1.6. Exported Parameters - -1.6.1. early_media (integer) - - Should be early media (any provisional reply with body) - accounted too ? - - Default value is 0 (no). - - Example 1.1. early_media example -modparam("acc", "early_media", 1) - -1.6.2. report_cancels (integer) - - By default, CANCEL reporting is disabled -- most accounting - applications wants to see INVITE's cancellation status. Turn on - if you explicitly want to account CANCEL transactions. - - Default value is 0 (no). - - Example 1.2. report_cancels example -modparam("acc", "report_cancels", 1) - -1.6.3. detect_direction (integer) - - Controls the direction detection for sequential requests. If - enabled (non zero value), for sequential requests with upstream - direction (from callee to caller), the FROM and TO will be - swapped (the direction will be preserved as in the original - request). - - It affects all values related to TO and FROM headers (body, - URI, username, domain, TAG). - - Default value is 0 (disabled). - - Example 1.3. detect_direction example -modparam("acc", "detect_direction", 1) - -1.6.4. extra_fields (string) - - Defines the tag-log_value set to be used in extra fields - accounting. See Section 1.2, “Extra accounting” for a detailed - description of the Extra accounting. - - If empty, extra accounting support will be disabled. - - Default value is 0 (disabled). - - Example 1.4. Setting extra_fields example: -# for syslog-based accounting, use any text you want to be printed -# if setting $acc_extra(a) you will see "My_a_Field= in logs -# if setting $acc_extra(b) you will see "b= in logs -modparam("acc", "extra_fields", "log: a->My_a_Field; b") -# for mysql-based accounting, use the names of the columns -# $acc_extra(a) = results in setting col_a with in db -modparam("acc", "extra_fields", "db: a->col_a; col_b") -# for AAA-based accounting, use the names of the AAA AVPs -modparam("acc", "extra_fields","aaa:a->AAA_SRC;b->AAA_DST") -# evi definition example -modparam("acc", "extra_fields","a->2345;b->2346") - -1.6.5. leg_fields (string) - - Defines the tag-log_value set to be used in multi-leg - accounting. See Section 1.3, “Multi Call-Legs accounting” for a - detailed description of the Multi Call-Legs accounting. - - If empty, multi-leg accounting support will be disabled. - - Default value is 0 (disabled). - - Example 1.5. Setting leg_fields example: -# for syslog-based accounting, use any text you want to be printed -# if setting $(acc_leg(a)[0]) you will see "My_a_Field= in logs -# if setting $(acc_leg(b)[0]) you will see "b= in logs -modparam("acc", "leg_fields", "log: a->My_a_Field; b") -# for mysql-based accounting, use the names of the columns -# $acc_leg(a) = results in setting col_a with in db -modparam("acc", "leg_fields", "db: a->col_a; col_b") -# for AAA-based accounting, use the names of the AAA AVPs -modparam("acc", "leg_fields","aaa:a->AAA_LEG_SRC;b->AAA_LEG_DST") -# evi definition example -modparam("acc", "leg_fields","a->2345;b->2346") - -1.6.6. log_level (integer) - - Log level at which accounting messages are issued to syslog. - - Default value is L_NOTICE. - - Example 1.6. log_level example -modparam("acc", "log_level", 2) # Set log_level to 2 - -1.6.7. log_facility (string) - - Log facility to which accounting messages are issued to syslog. - This allows to easily seperate the accounting specific logging - from the other log messages. - - Default value is LOG_DAEMON. - - Example 1.7. log_facility example -modparam("acc", "log_facility", "LOG_DAEMON") - -1.6.8. aaa_url (string) - - This is the url representing the AAA protocol used and the - location of the configuration file of this protocol. - - If the parameter is set to empty string, the AAA accounting - support will be disabled. - - Default value is “NULL”. - - Example 1.8. Set aaa_url parameter -... -modparam("acc", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.con -f") -... - -1.6.9. service_type (integer) - - AAA service type used for accounting. - - Default value is not-set. - - Example 1.9. service_type example -# Default value of service type for SIP is 15 -modparam("acc", "service_type", 15) - -1.6.10. db_table_acc (string) - - Table name of accounting successful calls -- database specific. - - Default value is “acc” - - Example 1.10. db_table_acc example -modparam("acc", "db_table_acc", "myacc_table") - -1.6.11. db_table_missed_calls (string) - - Table name for accounting missed calls -- database specific. - - Default value is “missed_calls” - - Example 1.11. db_table_missed_calls example -modparam("acc", "db_table_missed_calls", "myMC_table") - -1.6.12. db_url (string) - - SQL address -- database specific. If is set to NULL or empty - string, the SQL support is disabled. - - Default value is “NULL” (SQL disabled). - - Example 1.12. db_url example -modparam("acc", "db_url", "mysql://user:password@localhost/opensips") - -1.6.13. acc_method_column (string) - - Column name in accounting table to store the request's method - name as string. - - Default value is “method”. - - Example 1.13. acc_method_column example -modparam("acc", "acc_method_column", "method") - -1.6.14. acc_from_tag_column (string) - - Column name in accounting table to store the From header TAG - parameter. - - Default value is “from_tag”. - - Example 1.14. acc_from_tag_column example -modparam("acc", "acc_from_tag_column", "from_tag") - -1.6.15. acc_to_tag_column (string) - - Column name in accounting table to store the To header TAG - parameter. - - Default value is “to_tag”. - - Example 1.15. acc_to_tag_column example -modparam("acc", "acc_to_tag_column", "to_tag") - -1.6.16. acc_callid_column (string) - - Column name in accounting table to store the request's Callid - value. - - Default value is “callid”. - - Example 1.16. acc_callid_column example -modparam("acc", "acc_callid_column", "callid") - -1.6.17. acc_sip_code_column (string) - - Column name in accounting table to store the final reply's - numeric code value in string format. - - Default value is “sip_code”. - - Example 1.17. acc_sip_code_column example -modparam("acc", "acc_sip_code_column", "sip_code") - -1.6.18. acc_sip_reason_column (string) - - Column name in accounting table to store the final reply's - reason phrase value. - - Default value is “sip_reason”. - - Example 1.18. acc_sip_reason_column example -modparam("acc", "acc_sip_reason_column", "sip_reason") - -1.6.19. acc_time_column (string) - - Column name in accounting table to store the time stamp of the - transaction completion in date-time format. - - Default value is “time”. - - Example 1.19. acc_time_column example -modparam("acc", "acc_time_column", "time") - -1.7. Exported Pseudo-Variables - -1.7.1. $acc_extra(tag_name) - - This variable can addresed with the tag names defined using - extra_fields. If do_accounting() isn't called, this variable is - visible during the whole processing of one message, enabling - calling acc_XXX_request(). If do_accounting() is called, the - variable will be visible from the first call of this function - until the actual accounting is being made. - -1.7.2. $(acc_leg(tag_name)[leg_index]) - - This variable can be addressed with the tag names defined using - leg_fields and a valid leg index (<= $acc_current_leg). This - variable cannot be used unless do_accounting() is used. The - variable also accepts negative indexes, which start from -1 - (the lastly added leg). - -# the "caller" value of the current leg -$acc_leg(caller) - -# the "caller" value of the lastly added leg -$(acc_leg(caller)[-1]) # equivalent to $acc_leg(caller) - # equivalent to $(acc_leg(caller)[$acc_current_le -g]) - -# the "caller" value of the next-to-last leg -$(acc_leg(caller)[-2]) - - -1.7.3. $acc_current_leg (read-only) - - Holds the index of the current leg, starting from 0. Calling - acc_new_leg() will increment this index. - -1.8. Exported Functions - -1.8.1. do_accounting(type, [flags], [table]) - - do_accounting() replaces all the *_flag and, *_missed_flag, - cdr_flag, failed transaction_flag and the db_table_avp - modparams. Just call do_accounting(), select where and how you - want the accounting to take place, and the function will do all - the work for you. - - When called multiple times, the function behaves additively. - - Meaning of the parameters is as follows: - * type (string) - the type of accounting you want to do. All - types have to be separated by '|'. The following parameters - can be used: - + log - syslog accounting; - + db - database accounting; - + aaa - aaa specific accounting; - + evi - Event Interface accounting; - * flags (string, optional) - flags for the accounting type - you have selected. All the types have to be separated by - '|'. The following parameters can be used: - + cdr - enables dialog-level accounting. OpenSIPS will - internally detect dialog termination - (generation/receipt of a BYE request), and store the - CDR as soon as the BYE request is replied to. By - enabling the "cdr" flag, the following additional - fields will be populated: duration, ms_duration, - setuptime, created. (requires dialog module support) - + missed - log missed calls; take care that this flag - will be deactivated after the first missed call; you - will have to reactivate it in the failure_route if you - want to account each destination that did not respond - to the call; - + failed - flag which indicates if the transaction - should also be accounted in case of failure - (status>=300); - * table (string, optional) - table where to do the - accounting; it replaces old table_avp parameter; - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.20. do_accounting usage - ... - if (!has_totag()) { - if (is_method("INVITE")) { - /* enable cdr and missed calls accounting in the - database - * and to syslog; db accounting shall be done in - "my_acc" table */ - do_accounting("db|log", "cdr|missed", "m -y_acc"); - } - } - ... - if (is_method("BYE")) { - /* do normal accounting via aaa */ - do_accounting("aaa"); - } - ... - -1.8.2. drop_accounting([type], [flags]) - - drop_accounting() resets flags and types of accounting set with - do_accounting(). If called with no arguments all accounting - will be stopped. If called with only one argument all - accounting for that type will be stopped. If called with two - arguments normal accounting will still be enabled. - - When called multiple times, the function behaves additively. - - Meaning of the parameters is as follows: - * type (string, optional) - the type of accounting you want - to stop. All the types have to be separated by '|'. The - following parameters can be used: - + log - stop syslog accounting; - + db - stop database accounting; - + aaa - stop aaa specific accounting; - + evi - stop Event Interface accounting; - * flags (string, optional) - flags to be reset for the - accouting type you have selected. All the types have to be - separated by '|'. The following parameters can be used: - + cdr - stop CDR accounting; - + missed - stop logging missed calls; - + failed - stop failed transaction accounting; - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.21. drop_accounting usage - ... - acc_log_request("403 Destination not allowed"); - if (!has_totag()) { - if (is_method("INVITE")) { - /* enable cdr and missed calls accounting in the - database - * and to syslog; db accounting shall be done in - "my_acc" table */ - do_accounting("db|log", "cdr|missed", "m -y_acc"); - } - } - ... - /* later in your script */ - if (...) { /* you don't want accounting anymore */ - /* stop all syslog accounting */ - drop_accounting("log"); - /* or stop missed calls and cdr accounting for s -yslog; - * normal accounting will still be enabled */ - drop_accounting("log", "missed|cdr"); - /* or stop all types of accounting */ - drop_accounting(); - } - ... - -1.8.3. acc_log_request(comment) - - acc_request reports on a request, for example, it can be used - to report on missed calls to off-line users who are replied 404 - - Not Found. To avoid multiple reports on UDP request - retransmission, you would need to embed the action in stateful - processing. - - Meaning of the parameters is as follows: - * comment (string) - Comment describing how the request - completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "480 Nobody Home"). - Variables are accepted in this string. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.22. acc_log_request usage -... -acc_log_request("403 Destination not allowed"); -... - -1.8.4. acc_db_request(comment, table) - - Like acc_log_request, acc_db_request reports on a request. The - report is sent to database at “db_url”, in the table referred - to in the second action parameter. - - Meaning of the parameters is as follows: - * comment (string) - Comment describing how the request - completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "480 Nobody Home"). - Variables are accepted in this string. - * table (string) - Database table to be used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.23. acc_db_request usage -... -acc_db_request("Some comment", "Some table"); -acc_db_request("$T_reply_code $(rr)", "acc"); -... - -1.8.5. acc_aaa_request(comment) - - Like acc_log_request, acc_aaa_request reports on a request. It - reports to aaa server as configured in “aaa_url”. - - Meaning of the parameters is as follows: - * comment (string) - Comment describing how the request - completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "404 Nobody home"). - Variables are accepted in this string. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.24. acc_aaa_request usage -... -acc_aaa_request("403 Destination not allowed"); -... - -1.8.6. acc_evi_request(comment) - - Like acc_log_request, acc_evi_request reports on a request. The - report is packed as an event sent through the OpenSIPS Event - Interface as E_ACC_EVENT if the reply code is a positive one - (lower than 300), or E_ACC_MISSED_EVENT for negative or no - codes. More information on this in Exported Events. - - Meaning of the parameters is as follows: - * comment (string) - Comment describing how the request - completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "404 Nobody home") - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.25. acc_evi_request usage -... -acc_evi_request("403 Destination not allowed"); -... - -1.8.7. acc_new_leg() - - Creates a new leg and increments $acc_current_leg only if - multi-leg accounting is used. All values of the new leg will be - initialized to null. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.26. acc_new_leg usage -... - acc_new_leg(); -... - -1.8.8. acc_load_ctx_from_dlg() - - The function loads and exposes the accounting context of the - currently in-use dialog. By dialog context, it means, from - script level, you will read/write the accounting variables from - the other dialog. The current accounting context is stashed - until an unload operation is done. - - Note that this functions makes sense only when used together - with the load_dialog_ctx() function from the dialog module. - After loading the context of another dialog, by using the - acc_load_ctx_from_dlg() function, you can also access the - accounting context of the loaded dialog. - - NOTE: you cannot perform a new load until doing an unload - no - nested loadings are allowed. - - This function can be used from any type of route. - - Example 1.27. acc_load_ctx_from_dlg usage -... -if ( load_dialog_ctx("$var(callid)") ) { - # we now have the dialog context of the new dialog - acc_load_ctx_from_dlg(); - # we have now also the accouting context of that dialog - xlog("The accounting caller of call '$var(callid)' " - "is '$acc_extra(caller)'\n"); - acc_unload_ctx_from_dlg(); - unload_dialog_ctx(); -} - -... - -1.8.9. acc_unload_ctx_from_dlg() - - The function off-loads a previosuly loaded accounting context, - exposing whatever accounting context was present before doing - the load. - - NOTE: you MUST perform from script an explicit unload for each - load you did! - - This function can be used from any type of route. - - For usage example, see the acc_load_ctx_from_dlg(). - -1.9. Exported Events - -1.9.1. E_ACC_CDR - - The event raised when a CDR is generated. Note that this event - will only be triggered if the auto CDR accounting is used. - - Parameters: - * method - Request method name - * from_tag - From header tag parameter - * to_tag - To header tag parameter - * callid - Message Call-id - * sip_code - The status code from the final reply - * sip_reason - The status reason from the final reply - * time - The timestamp when the call was established - * evi_extra* - Extra parameters added by the evi_extra - parameter. - * evi_extra_bye* - Extra parameters added by the - evi_extra_bye parameter - * multi_leg_info* - Extra parameters added by the - multi_leg_info parameter - * multi_leg_bye_info* - Extra parameters added by the - multi_leg_bye_info parameter - * duration - The call duration in seconds - * ms_duration - The call duration in milliseconds - * setuptime - The call setup time in seconds - * created - The timestamp when the call was created (the - initial Invite was received) - -1.9.2. E_ACC_EVENT - - This event is triggered when old-style accounting is used. It - is generated when the requests (INVITE and BYE) transaction - have positive final replies, or by the acc_evi_request() - function that has a positive reply code in comment. - - Parameters: - * method - Request method name - * from_tag - From header tag parameter - * to_tag - To header tag parameter - * callid - Message Call-id - * sip_code - The status code from the final reply - * sip_reason - The status reason from the final reply - * time - The timestamp when the transaction was created - * evi_extra* - Extra parameters added by the evi_extra - parameter - * multi_leg_info* - Extra parameters added by the - multi_leg_info parameter - -1.9.3. E_ACC_MISSED_EVENT - - This event is triggered when old-style accounting is used. It - is generated when the requests (INVITE and BYE) transaction - have negative final replies, or by the acc_evi_request() - function that has a negative reply code in comment. - - Parameters: - * method - Request method name - * from_tag - From header tag parameter - * to_tag - To header tag parameter - * callid - Message Call-id - * sip_code - The status code from the final reply - * sip_reason - The status reason from the final reply - * time - The timestamp when the transaction was created - * evi_extra* - Extra parameters added by the evi_extra - parameter - * multi_leg_info* - Extra parameters added by the - multi_leg_info parameter - * created - Timestamp when the call was created - * setuptime - The call setup time in seconds - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with old report_ack parameter - - The parameter is considered obsolete. It was removed as acc - module is doing SIP transaction based accouting and according - to SIP RFC, end2end ACKs are a different transaction (still - part of the same dialog). ACKs can be individually accouted as - any other sequential (in-dialog) request. - $ - - 2.2. - - What happened with old log_fmt parameter - - The parameter became obsolete with the restructure of the data - logged by ACC module (refer to the Overview chapter). For - similar behaviour you can use the extra accouting (see the - corresponding chapter). - - 2.3. - - What happened with old multi_leg_enabled parameter - - The parameter became obsolete by the addition of the new - multi_leg_info parameter. The multi-leg accouting is - automatically enabled when multi_leg_info is defined. - - 2.4. - - What happened with old src_leg_avp_id and dst_leg_avp_id - parameters - - The parameter was replaced by the more generic new parameter - multi_leg_info. This allows logging (per-leg) of more - information than just dst and src. - - 2.5. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.6. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.7. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 228 114 4306 4609 - 2. Jan Janak (@janakj) 147 16 5587 5074 - 3. Ionut Ionita (@ionutrazvanionita) 140 39 3730 4180 - 4. Razvan Crainea (@razvancrainea) 102 67 2705 677 - 5. Liviu Chircu (@liviuchircu) 75 55 985 608 - 6. Jiri Kuthan (@jiriatipteldotorg) 57 26 2272 660 - 7. Daniel-Constantin Mierla (@miconda) 26 23 115 88 - 8. Elena-Ramona Modroiu 25 4 2267 5 - 9. Vlad Patrascu (@rvlad-patrascu) 22 11 353 478 - 10. Henning Westerholt (@henningw) 20 15 184 131 - - All remaining contributors: Vlad Paiu (@vladpaiu), Maksym - Sobolyev (@sobomax), Irina-Maria Stanescu, Karel Kozlik, Andrei - Pelinescu-Onciul, Alexandra Titoc, Dan Pascu (@danpascu), Juha - Heinanen (@juha-h), Elena-Ramona Modroiu, Ryan Bullock - (@rrb3942), Ovidiu Sas (@ovidiusas), Walter Doekes (@wdoekes), - Sergio Gutierrez, Peter Nixon, Alex Massover, Nils Ohlmeier, - Konstantin Bokarius, Alexey Vasilyev (@vasilevalex), Jesus - Rodrigues, Julien Blache, Julián Moreno Patiño, Peter Lemenkov - (@lemenkov), Dusan Klinec (@ph4r05), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2010 - Dec 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 4. Maksym Sobolyev (@sobomax) Dec 2003 - Nov 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2003 - May 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 7. Alexey Vasilyev (@vasilevalex) Mar 2022 - Mar 2022 - 8. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 9. Dan Pascu (@danpascu) Jul 2004 - Sep 2018 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Julián Moreno Patiño, Dusan Klinec (@ph4r05), Vlad Paiu - (@vladpaiu), Ryan Bullock (@rrb3942), Irina-Maria Stanescu, - Alex Massover, Sergio Gutierrez, Ovidiu Sas (@ovidiusas), - Henning Westerholt (@henningw), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Jesus Rodrigues, Julien Blache, Peter - Nixon, Juha Heinanen (@juha-h), Jan Janak (@janakj), Jiri - Kuthan (@jiriatipteldotorg), Andrei Pelinescu-Onciul, - Elena-Ramona Modroiu, Nils Ohlmeier, Karel Kozlik. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut - Ionita (@ionutrazvanionita), Ryan Bullock (@rrb3942), - Irina-Maria Stanescu, Sergio Gutierrez, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan - Janak (@janakj), Maksym Sobolyev (@sobomax), Elena-Ramona - Modroiu. - - Documentation Copyrights: - - Copyright © 2009-2013 OpenSIPS Solutions - - Copyright © 2004-2009 Voice Sistem SRL - - Copyright © 2002-2003 FhG FOKUS diff --git a/modules/acc/README.md b/modules/acc/README.md new file mode 100644 index 00000000000..8a056525df5 --- /dev/null +++ b/modules/acc/README.md @@ -0,0 +1,1173 @@ +--- +title: "Acc Module" +description: "The ACC module is used to account transaction information to different backends such as syslog, SQL, AAA." +--- + +## Admin Guide + + +### Overview + + +The ACC module is used to account transaction information to different +backends such as syslog, SQL, AAA. + + +To account a transaction and to choose which set of backends to be +used, the script writer only has to mark the transaction for +accounting by using the [do accounting](#func_do_accounting) script function. +Note that the function is not actually doing the accounting at that +very time, it is just setting a marker - the actual accounting +will be done later when the transaction or dialog will be +completed. + + +Even so, the module allows the script writer to force accounting on the +spot in special cases via some other script functions. + + +The accounting module will log by default a fixed set of attributes +for the transaction - if you customize your accounting by adding more +information to be logged, please see the next chapter about extra +accounting - [ACC extra id](#extra_accounting). + + +The fixed minimal accounting information is: + + +- Request Method name +- From header TAG parameter +- To header TAG parameter +- Call-Id +- 3-digit Status code from final reply +- Reason phrase from final reply +- Timestamp when transaction was completed + + +If a value is not present in the request, the empty string is accounted +instead. + + +Note that: + + +- A single INVITE may produce multiple accounting reports -- that's +most likely due to the SIP forking feature. +- Since version 2.2, all flags used for accounting have been replaced +with the do_accounting() function. No need to worry anymore whether +you have set the flags or not, or be confused by various flag names, +now you only have to call the function and it will do all the work +for you. +- OpenSIPS now supports session/dialog accounting. It can +automatically correlate INVITEs with BYEs for generating proper CDRs, +for example for billing purposes. +- If a UA fails in the middle of a conversation, a proxy will never +find out about it. In general, a better practice is to account from an +end-device (such as PSTN gateway), which best knows about call +status (including media status and PSTN status in case of the +gateway). + + +The SQL, Event Interface and AAA backend support are compiled in the +module. + + +A very comprehensive description of how the accounting module works in +terms accounting scope, accounting events and accounting backends can +be found in this online [Advanced Accounting Tutorial](https://docs.opensips.org/tutorials/advanced-accounting/). + + +#### General Example + + +```opensips +loadmodule "modules/acc/acc.so" + +if ($ru=~"sip:+40") /* calls to Romania */ { + if (!proxy_authorize("sip_domain.net" /* realm */, + "subscriber" /* table name */)) { + proxy_challenge("sip_domain.net" /* realm */, "0" /* no qop */ ); + exit; + } + + if (is_method("INVITE") && $au!=$fU) { + xlog("FROM URI != digest username\n"); + sl_send_reply(403,"Forbidden"); + } + + do_accounting("log"); /* set for accounting via syslog */ + t_relay(); /* enter stateful mode now */ +}; +``` + + +### Extra accounting + + +#### Overview + + +Along the static default information, the ACC module +allows dynamic selection of extra information to be logged using +the acc_extra pseudovariable. This allows you to log any +pseudo-variable (AVPs, parts of the request, parts of the reply, etc). + + +#### Definitions and syntax + + +Selection of extra information is done via +*extra_field* parameter by specifying tags +and log_names for the additional information. This information is +defined via acc_extra pseudovariable, referenced with the define +tag. If the tag is not specified, its value will be considered +to be the same as the log_value. Accounting backend(log, db, aaa, evi) +is specified at the beginning of the definition, separated by ':' from +the rest. The syntax of the parameter is: + + +- *backend : tag -> log_name (';'tag -> log_name)** +- *backend : tag (';' tag)** + + +Extra values are consistent during the whole call. Setting a +value during a request, will cause it to remain visible during all replies. Also, +concerning CDR logging, setting a value on the initial INVITE will +result in having that value throughout the dialog. + + +Via *log_name* you define how/where the +*data* will be logged. Its meaning depends +of the accounting support which is used: + + +- *LOG accounting* - log_name will be just printed along with the data in *log_name=data* format; +- *DB accounting* - log_name will be the name of the DB column where the data will be stored. +> [!IMPORTANT] +> Add in db *acc* table the columns corresponding to each extra data. +- *AAA accounting* - log_name will be the AVP name used for packing the data into AAA message. +The log_name will be translated to AVP number via the dictionary. +> [!IMPORTANT] +> Add in AAA dictionary the *log_name* attribute. +- *Events accounting* - log_name will be the name of the parameter in the event raised. + + +#### How it works + + +Declaring an extra in the format of + + +```opensips +modparam("acc", "extra_fields", "log: a -> test_a") +``` + + +will enable you to set the value for *test_a* field +of the log only by setting *$acc_extra(a)* variable. +Otherwise, the field shall be logged with no value(null). + + +#### Radius accounting dependencies + + +If radius accounting is used, except from a radius client library which is mandatory, +**dictionary.rfc2866** must be included for the module +to work properly. + + +### Multi Call-Legs accounting + + +#### Overview + + +A SIP call can have multiple legs due forwarding actions. For +example user A calls user B which forwards the call to user C. +There is only one SIP call but with 2 legs ( A to B and B to C). +Accounting the legs of a call is required for proper billing of +the calls (if C is a PSTN number and the call is billed, user B +must pay for the call - as last party modifing the call +destination-, and not A - as initiator of the call. Call +forwarding on server is only one example which shows the +necessity of the having an accounting engine with multiple legs +support. + + +#### Configuration + + +First how it works: The idea is to have a variable to store +a set of values for each leg. The meaning of +the variable content is strictly decided by the script writer - it can +be the origin and source of the leg, its status or any other +related information. By default there is defined only one leg. Script +writer has to decide when is the time to create a new leg, by using +*acc_new_leg()* script function. When creating a new +leg, all the values for that leg will be set to NULL by default. + + +When the accounting information for the call will be written/sent, +all the call-leg pairs will be added. + + +By default, the multiple call-leg support is disabled - it can be +enabled just by setting *acc_leg* variable +`leg_fields` module parameter. Note that +the last one only makes sense only for CDRs that are generated +automatically by OpenSIPS. + + +#### Logged data + + +For each call, all the values from the *acc_leg* +variable will be logged. How the information will be actually +logged, depends of the data backend: + + +- *syslog* -- all leg-sets will be added +to one record string as acc_leg(leg1)=xxx, acc_leg(leg2)=xxxx ,... sets. +- *database* -- each pair will be +separately logged (due DB data structure constraints); several +records will be written, the difference between them being +only the fields corresponding to the call-leg info. + +> [!NOTE] +> You will need to add in your DB (all acc related tables) the colums +> for call-leg info (a column for each leg value of the set). + +- *AAA* -- all sets will be added +to the same AAA accounting message as AAA AVPs - for each +call-leg a set of AAA AVPs will be added (corresponding +to the per-leg set) + +> [!NOTE] +> You will need to add in your dictionary the +> AAA AVPs used in call-leg set definition. + +- *events* -- each pair will appear as a +different parameter-value pair in the event. Similar to the +database behavior, multiple events will be raised, and the only +difference between them is the leg information. + + +> [!IMPORTANT] +> In order to use *RADIUS*, one must include the AVPs which are located in +> *$(opensips_install_dir)/etc/dictionary.opensips*, both in opensips radius config +> script dictionary and radius server dictionary. Most important are the last three +> AVPs (IDs : 227, 228, 229) which you won't find in any SIP dictionary +> (at least at this moment) because they are only used in openSips. + + +### CDRs accounting + + +#### Overview + + +ACC module can now also maintain session/dialog accounting. This +allows you to log useful information like call duration, call +start time and setup time. + + +#### Configuration + + +In order to have CDRs accounting, first you need to set the +*cdr* flag when calling +[do accounting](#func_do_accounting) script function for the +initial INVITE of the dialog. + + +#### How it works + + +This type of accounting is based on the dialog module. When +an initial INVITE is received, if the *cdr* +flag is set, then the dialog creation time is saved. Once the call is +answered and the ACK is received, other information like extra values +or leg values are saved. When the corresponding BYE is received, +the call duration is computed and all information is stored to +the desired backend. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *tm* -- Transaction Manager +- *a database module* -- If SQL support is used. +- *rr* -- Record Route, if "detect_direction" module parameter is enabled. +- *an aaa module* +- *dialog* -- Dialog, if "cdr" option is used + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- none. + + +### Exported Parameters + + +#### early_media (integer) + + +Should be early media (any provisional reply with body) accounted too ? + + +Default value is 0 (no). + + +```opensips title="early_media example" +modparam("acc", "early_media", 1) +``` + + +#### report_cancels (integer) + + +By default, CANCEL reporting is disabled -- most accounting +applications wants to see INVITE's cancellation status. +Turn on if you explicitly want to account CANCEL transactions. + + +Default value is 0 (no). + + +```opensips title="report_cancels example" +modparam("acc", "report_cancels", 1) +``` + + +#### detect_direction (integer) + + +Controls the direction detection for sequential requests. If +enabled (non zero value), for sequential requests with upstream +direction (from callee to caller), the FROM and TO will be swapped +(the direction will be preserved as in the original request). + + +It affects all values related to TO and FROM headers (body, URI, +username, domain, TAG). + + +Default value is 0 (disabled). + + +```opensips title="detect_direction example" +modparam("acc", "detect_direction", 1) +``` + + +#### extra_fields (string) + + +Defines the tag-log_value set to be used in extra fields accounting. +See [ACC extra id](#extra_accounting) for a +detailed description of the Extra accounting. + + +If empty, extra accounting support will be disabled. + + +Default value is 0 (disabled). + + +```opensips title="Setting *extra_fields* example:" +# for syslog-based accounting, use any text you want to be printed +# if setting $acc_extra(a) you will see "My_a_Field= in logs +# if setting $acc_extra(b) you will see "b= in logs +modparam("acc", "extra_fields", "log: a->My_a_Field; b") +# for mysql-based accounting, use the names of the columns +# $acc_extra(a) = results in setting col_a with in db +modparam("acc", "extra_fields", "db: a->col_a; col_b") +# for AAA-based accounting, use the names of the AAA AVPs +modparam("acc", "extra_fields","aaa:a->AAA_SRC;b->AAA_DST") +# evi definition example +modparam("acc", "extra_fields","a->2345;b->2346") +``` + + +#### leg_fields (string) + + +Defines the tag-log_value set to be used in multi-leg accounting. +See [multi call legs](#multi_call_legs_accounting) for a +detailed description of the Multi Call-Legs accounting. + + +If empty, multi-leg accounting support will be disabled. + + +Default value is 0 (disabled). + + +```opensips title="Setting *leg_fields* example:" +# for syslog-based accounting, use any text you want to be printed +# if setting $(acc_leg(a)[0]) you will see "My_a_Field= in logs +# if setting $(acc_leg(b)[0]) you will see "b= in logs +modparam("acc", "leg_fields", "log: a->My_a_Field; b") +# for mysql-based accounting, use the names of the columns +# $acc_leg(a) = results in setting col_a with in db +modparam("acc", "leg_fields", "db: a->col_a; col_b") +# for AAA-based accounting, use the names of the AAA AVPs +modparam("acc", "leg_fields","aaa:a->AAA_LEG_SRC;b->AAA_LEG_DST") +# evi definition example +modparam("acc", "leg_fields","a->2345;b->2346") +``` + + +#### log_level (integer) + + +Log level at which accounting messages are issued to syslog. + + +Default value is L_NOTICE. + + +```opensips title="log_level example" +modparam("acc", "log_level", 2) # Set log_level to 2 +``` + + +#### log_facility (string) + + +Log facility to which accounting messages are issued to syslog. +This allows to easily seperate the accounting specific logging +from the other log messages. + + +Default value is LOG_DAEMON. + + +```opensips title="log_facility example" +modparam("acc", "log_facility", "LOG_DAEMON") +``` + + +#### aaa_url (string) + + +This is the url representing the AAA protocol used and the location of the configuration file of this protocol. + + +If the parameter is set to empty string, the AAA accounting support +will be disabled. + + +Default value is "NULL". + + +```opensips title="Set aaa_url parameter" +... +modparam("acc", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") +... +``` + + +#### service_type (integer) + + +AAA service type used for accounting. + + +Default value is not-set. + + +```opensips title="service_type example" +# Default value of service type for SIP is 15 +modparam("acc", "service_type", 15) +``` + + +#### db_table_acc (string) + + +Table name of accounting successful calls -- database specific. + + +Default value is "acc" + + +```opensips title="db_table_acc example" +modparam("acc", "db_table_acc", "myacc_table") +``` + + +#### db_table_missed_calls (string) + + +Table name for accounting missed calls -- database specific. + + +Default value is "missed_calls" + + +```opensips title="db_table_missed_calls example" +modparam("acc", "db_table_missed_calls", "myMC_table") +``` + + +#### db_url (string) + + +SQL address -- database specific. If is set to NULL or empty string, +the SQL support is disabled. + + +Default value is "NULL" (SQL disabled). + + +```opensips title="db_url example" +modparam("acc", "db_url", "mysql://user:password@localhost/opensips") +``` + + +#### acc_method_column (string) + + +Column name in accounting table to store the request's method name as +string. + + +Default value is "method". + + +```opensips title="acc_method_column example" +modparam("acc", "acc_method_column", "method") +``` + + +#### acc_from_tag_column (string) + + +Column name in accounting table to store the From header TAG parameter. + + +Default value is "from_tag". + + +```opensips title="acc_from_tag_column example" +modparam("acc", "acc_from_tag_column", "from_tag") +``` + + +#### acc_to_tag_column (string) + + +Column name in accounting table to store the To header TAG parameter. + + +Default value is "to_tag". + + +```opensips title="acc_to_tag_column example" +modparam("acc", "acc_to_tag_column", "to_tag") +``` + + +#### acc_callid_column (string) + + +Column name in accounting table to store the request's Callid value. + + +Default value is "callid". + + +```opensips title="acc_callid_column example" +modparam("acc", "acc_callid_column", "callid") +``` + + +#### acc_sip_code_column (string) + + +Column name in accounting table to store the final reply's numeric code +value in string format. + + +Default value is "sip_code". + + +```opensips title="acc_sip_code_column example" +modparam("acc", "acc_sip_code_column", "sip_code") +``` + + +#### acc_sip_reason_column (string) + + +Column name in accounting table to store the final reply's reason +phrase value. + + +Default value is "sip_reason". + + +```opensips title="acc_sip_reason_column example" +modparam("acc", "acc_sip_reason_column", "sip_reason") +``` + + +#### acc_time_column (string) + + +Column name in accounting table to store the time stamp of the +transaction completion in date-time format. + + +Default value is "time". + + +```opensips title="acc_time_column example" +modparam("acc", "acc_time_column", "time") +``` + + +### Exported Pseudo-Variables + + +#### $acc_extra(tag_name) + + +This variable can addresed with the tag names defined +using [extra fields](#param_extra_fields). If +[do accounting](#func_do_accounting) isn't called, this +variable is visible during the whole processing of one message, +enabling calling *acc_XXX_request()*. +If [do accounting](#func_do_accounting) is called, the variable +will be visible from the first call of this function until the +actual accounting is being made. + + +#### $(acc_leg(tag_name)[leg_index]) + + +This variable can be addressed with the tag names defined +using [leg fields](#param_leg_fields) and a valid leg index +(<= [acc current leg](#pv_acc_current_leg)). This variable cannot +be used unless [do accounting](#func_do_accounting) is used. The +variable also accepts negative indexes, which start from -1 +(the lastly added leg). + + +```opensips +# the "caller" value of the current leg +$acc_leg(caller) + +# the "caller" value of the lastly added leg +$(acc_leg(caller)[-1]) # equivalent to $acc_leg(caller) + # equivalent to $(acc_leg(caller)[$acc_current_leg]) + +# the "caller" value of the next-to-last leg +$(acc_leg(caller)[-2]) +``` + + +#### $acc_current_leg (read-only) + + +Holds the index of the current leg, starting from 0. Calling +[acc new leg](#func_acc_new_leg) will increment this index. + + +### Exported Functions + + +#### do_accounting(type, [flags], [table]) + + +`do_accounting()` replaces all the +*_flag and, *_missed_flag, cdr_flag, failed transaction_flag and the +db_table_avp modparams. Just call do_accounting(), select where and how you want +the accounting to take place, and the function will do all the work for you. + + +When called multiple times, the function behaves *additively*. + + +Meaning of the parameters is as follows: + + +- *type (string)* - the type of accounting you want to do. +All types have to be separated by '|'. The following parameters can +be used: + - *log* - syslog accounting; + - *db* - database accounting; + - *aaa* - aaa specific accounting; + - *evi* - Event Interface accounting; +- *flags (string, optional)* - flags for the accounting type you have +selected. All the types have to be separated by '|'. The following +parameters can be used: + - *cdr* - enables dialog-level accounting. +OpenSIPS will internally detect dialog termination (generation/receipt +of a BYE request), and store the CDR as soon as the BYE request +is replied to. By enabling the "cdr" flag, the following additional +fields will be populated: duration, ms_duration, setuptime, created. +(requires dialog module support) + - *missed* - log missed calls; take care +that this flag will be deactivated after the first missed call; +you will have to reactivate it in the +*failure_route* if you want to account +each destination that did not respond to the call; + - *failed* - flag which indicates if the +transaction should also be accounted in case +of failure (status>=300); +- *table (string, optional)* - table where to do the accounting; +it replaces old table_avp parameter; + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="do_accounting usage" + ... + if (!has_totag()) { + if (is_method("INVITE")) { + /* enable cdr and missed calls accounting in the database + * and to syslog; db accounting shall be done in "my_acc" table */ + do_accounting("db|log", "cdr|missed", "my_acc"); + } + } + ... + if (is_method("BYE")) { + /* do normal accounting via aaa */ + do_accounting("aaa"); + } + ... + +``` + + +#### drop_accounting([type], [flags]) + + +`drop_accounting()` resets flags +and types of accounting set with do_accounting(). If called with no +arguments all accounting will be stopped. If called with only one argument +all accounting for that type will be stopped. If called with two arguments +normal accounting will still be enabled. + + +When called multiple times, the function behaves *additively*. + + +Meaning of the parameters is as follows: + + +- *type (string, optional)* - the type of accounting you want to stop. +All the types have to be separated by '|'. The following parameters can +be used: + - *log* - stop syslog accounting; + - *db* - stop database accounting; + - *aaa* - stop aaa specific accounting; + - *evi* - stop Event Interface accounting; +- *flags (string, optional)* - flags to be reset for the accouting type you have +selected. All the types have to be separated by '|'. The following +parameters can be used: + - *cdr* - stop CDR accounting; + - *missed* - stop logging missed calls; + - *failed* - stop failed transaction accounting; + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="drop_accounting usage" + ... + acc_log_request("403 Destination not allowed"); + if (!has_totag()) { + if (is_method("INVITE")) { + /* enable cdr and missed calls accounting in the database + * and to syslog; db accounting shall be done in "my_acc" table */ + do_accounting("db|log", "cdr|missed", "my_acc"); + } + } + ... + /* later in your script */ + if (...) { /* you don't want accounting anymore */ + /* stop all syslog accounting */ + drop_accounting("log"); + /* or stop missed calls and cdr accounting for syslog; + * normal accounting will still be enabled */ + drop_accounting("log", "missed|cdr"); + /* or stop all types of accounting */ + drop_accounting(); + } + ... + +``` + + +#### acc_log_request(comment) + + +`acc_request` reports on a request, +for example, it can be used to report on missed calls to off-line users +who are replied 404 - Not Found. To avoid multiple reports on UDP +request retransmission, you would need to embed the +action in stateful processing. + + +Meaning of the parameters is as follows: + + +- *comment (string)* - Comment describing how the +request completed - this string has to contain a reply code +followed by a reply reason phrase (ex: "480 Nobody Home"). Variables +are accepted in this string. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="acc_log_request usage" +... +acc_log_request("403 Destination not allowed"); +... +``` + + +#### acc_db_request(comment, table) + + +Like `acc_log_request`, +`acc_db_request` reports on a +request. The report is sent to database at "db_url", in +the table referred to in the second action parameter. + + +Meaning of the parameters is as follows: + + +- *comment (string)* - Comment describing how the +request completed - this string has to contain a reply code +followed by a reply reason phrase (ex: "480 Nobody Home"). Variables +are accepted in this string. +- *table (string)* - Database table to be used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="acc_db_request usage" +... +acc_db_request("Some comment", "Some table"); +acc_db_request("$T_reply_code $(rr)", "acc"); +... +``` + + +#### acc_aaa_request(comment) + + +Like `acc_log_request`, +`acc_aaa_request` reports on +a request. It reports to aaa server as configured in +"aaa_url". + + +Meaning of the parameters is as follows: + + +- *comment (string)* - Comment describing how the +request completed - this string has to contain a reply code +followed by a reply reason phrase (ex: "404 Nobody home"). Variables +are accepted in this string. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="acc_aaa_request usage" +... +acc_aaa_request("403 Destination not allowed"); +... +``` + + +#### acc_evi_request(comment) + + +Like `acc_log_request`, +`acc_evi_request` reports on a +request. The report is packed as an event sent through the OpenSIPS Event +Interface as *E_ACC_EVENT* if the reply code is a +positive one (lower than 300), or *E_ACC_MISSED_EVENT* +for negative or no codes. More information on this in +[exported events](#exported_events). + + +Meaning of the parameters is as follows: + + +- *comment (string)* - Comment describing how the +request completed - this string has to contain a reply code +followed by a reply reason phrase (ex: "404 Nobody home") + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="acc_evi_request usage" +... +acc_evi_request("403 Destination not allowed"); +... +``` + + +#### acc_new_leg() + + +Creates a new leg and increments [acc current leg](#pv_acc_current_leg) +only if multi-leg accounting is used. All values of the new leg +will be initialized to null. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="acc_new_leg usage" +... + acc_new_leg(); +... +``` + + +#### acc_load_ctx_from_dlg() + + +The function loads and exposes the accounting context of the +currently in-use dialog. By dialog context, it means, from script +level, you will read/write the accounting variables from the +other dialog. The current accounting context is +stashed until an unload operation is done. + + +Note that this functions makes sense only when used together with +the *load_dialog_ctx()* function from the +dialog module. After loading the context of another dialog, by +using the *acc_load_ctx_from_dlg()* function, +you can also access the accounting context of the loaded dialog. + + +NOTE: you cannot perform a new load until doing an unload - no nested +loadings are allowed. + + +This function can be used from any type of route. + + +```opensips title="acc_load_ctx_from_dlg usage" +... +if ( load_dialog_ctx("$var(callid)") ) { + # we now have the dialog context of the new dialog + acc_load_ctx_from_dlg(); + # we have now also the accouting context of that dialog + xlog("The accounting caller of call '$var(callid)' " + "is '$acc_extra(caller)'\n"); + acc_unload_ctx_from_dlg(); + unload_dialog_ctx(); +} + +... +``` + + +#### acc_unload_ctx_from_dlg() + + +The function off-loads a previosuly loaded accounting context, exposing +whatever accounting context was present before doing the load. + + +> [!NOTE] +> You MUST perform from script an explicit unload for each load you did! + + +This function can be used from any type of route. + + +For usage example, see the [acc load ctx from dlg](#func_acc_load_ctx_from_dlg). + + +### Exported Events + + +#### E_ACC_CDR + + +The event raised when a CDR is generated. Note that this event will +only be triggered if the auto CDR accounting is used. + + +Parameters: + + +- *method* - Request method name +- *from_tag* - From header tag parameter +- *to_tag* - To header tag parameter +- *callid* - Message Call-id +- *sip_code* - The status code from the final reply +- *sip_reason* - The status reason from the final reply +- *time* - The timestamp when the call was established +- *evi_extra** - Extra parameters added by +the *evi_extra* parameter. +- *evi_extra_bye** - Extra parameters added by +the *evi_extra_bye* parameter +- *multi_leg_info** - Extra parameters added by +the *multi_leg_info* parameter +- *multi_leg_bye_info** - Extra parameters added by +the *multi_leg_bye_info* parameter +- *duration* - The call duration in seconds +- *ms_duration* - The call duration in milliseconds +- *setuptime* - The call setup time in seconds +- *created* - The timestamp when the call was +created (the initial Invite was received) + + +#### E_ACC_EVENT + + +This event is triggered when old-style accounting is used. It is +generated when the requests (INVITE and BYE) transaction have +positive final replies, or by the `acc_evi_request()` +function that has a positive reply code in comment. + + +Parameters: + + +- *method* - Request method name +- *from_tag* - From header tag parameter +- *to_tag* - To header tag parameter +- *callid* - Message Call-id +- *sip_code* - The status code from the final reply +- *sip_reason* - The status reason from the final reply +- *time* - The timestamp when the transaction was created +- *evi_extra** - Extra parameters added by +the *evi_extra* parameter +- *multi_leg_info** - Extra parameters added by +the *multi_leg_info* parameter + + +#### E_ACC_MISSED_EVENT + + +This event is triggered when old-style accounting is used. It is +generated when the requests (INVITE and BYE) transaction have +negative final replies, or by the `acc_evi_request()` +function that has a negative reply code in comment. + + +Parameters: + + +- *method* - Request method name +- *from_tag* - From header tag parameter +- *to_tag* - To header tag parameter +- *callid* - Message Call-id +- *sip_code* - The status code from the final reply +- *sip_reason* - The status reason from the final reply +- *time* - The timestamp when the transaction was created +- *evi_extra** - Extra parameters added by +the *evi_extra* parameter +- *multi_leg_info** - Extra parameters added by +the *multi_leg_info* parameter +- *created* - Timestamp when the call was created +- *setuptime* - The call setup time in seconds + + +## Frequently Asked Questions + + +**Q: What happened with old report_ack parameter** + + +The parameter is considered obsolete. It was removed as acc +module is doing SIP transaction based accouting and according +to SIP RFC, end2end ACKs are a different transaction (still part +of the same dialog). ACKs can be individually accouted as any +other sequential (in-dialog) request. + + +**Q: What happened with old log_fmt parameter** + + +The parameter became obsolete with the restructure of the data +logged by ACC module (refer to the Overview chapter). For similar +behaviour you can use the extra accouting (see the corresponding +chapter). + + +**Q: What happened with old multi_leg_enabled parameter** + + +The parameter became obsolete by the addition of the new +multi_leg_info parameter. The multi-leg accouting is automatically +enabled when multi_leg_info is defined. + + +**Q: What happened with old src_leg_avp_id and dst_leg_avp_id +parameters** + + +The parameter was replaced by the more generic new parameter +multi_leg_info. This allows logging (per-leg) of more information +than just dst and src. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/acc/doc/acc.xml b/modules/acc/doc/acc.xml deleted file mode 100644 index b79cf43ff44..00000000000 --- a/modules/acc/doc/acc.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Acc Module - &osips; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009-2013 &osipssolname; - ©right; 2004-2009 &voicesystem; - ©right; 2002-2003 &fhg; - diff --git a/modules/acc/doc/acc_admin.xml b/modules/acc/doc/acc_admin.xml deleted file mode 100644 index 69a1ef80465..00000000000 --- a/modules/acc/doc/acc_admin.xml +++ /dev/null @@ -1,1376 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The ACC module is used to account transaction information to different - backends such as syslog, SQL, - AAA. - - - To account a transaction and to choose which set of backends to be - used, the script writer only has to mark the transaction for - accounting by using the script function. - Note that the function is not actually doing the accounting at that - very time, it is just setting a marker - the actual accounting - will be done later when the transaction or dialog will be - completed. - - - Even so, the module allows the script writer to force accounting on the - spot in special cases via some other script functions. - - - The accounting module will log by default a fixed set of attributes - for the transaction - if you customize your accounting by adding more - information to be logged, please see the next chapter about extra - accounting - . - - - The fixed minimal accounting information is: - - - Request Method name - - - From header TAG parameter - - - To header TAG parameter - - - Call-Id - - - 3-digit Status code from final reply - - - Reason phrase from final reply - - - Timestamp when transaction was completed - - - If a value is not present in the request, the empty string is accounted - instead. - - - Note that: - - - - A single INVITE may produce multiple accounting reports -- that's - most likely due to the SIP forking feature. - - - - - Since version 2.2, all flags used for accounting have been replaced - with the do_accounting() function. No need to worry anymore whether - you have set the flags or not, or be confused by various flag names, - now you only have to call the function and it will do all the work - for you. - - - - - &osips; now supports session/dialog accounting. It can - automatically correlate INVITEs with BYEs for generating proper CDRs, - for example for billing purposes. - - - - - If a UA fails in the middle of a conversation, a proxy will never - find out about it. In general, a better practice is to account from an - end-device (such as PSTN gateway), which best knows about call - status (including media status and PSTN status in case of the - gateway). - - - - - - The SQL, Event Interface and AAA backend support are compiled in the - module. - - - A very comprehensive description of how the accounting module works in - terms accounting scope, accounting events and accounting backends can - be found in this online Advanced Accounting Tutorial. - -
- General Example - -loadmodule "modules/acc/acc.so" - -if ($ru=~"sip:+40") /* calls to Romania */ { - if (!proxy_authorize("sip_domain.net" /* realm */, - "subscriber" /* table name */)) { - proxy_challenge("sip_domain.net" /* realm */, "0" /* no qop */ ); - exit; - } - - if (is_method("INVITE") && $au!=$fU) { - xlog("FROM URI != digest username\n"); - sl_send_reply(403,"Forbidden"); - } - - do_accounting("log"); /* set for accounting via syslog */ - t_relay(); /* enter stateful mode now */ -}; - -
-
- -
- Extra accounting -
- Overview - - Along the static default information, the ACC module - allows dynamic selection of extra information to be logged using - the acc_extra pseudovariable. This allows you to log any - pseudo-variable (AVPs, parts of the request, parts of the reply, etc). - -
-
- Definitions and syntax - - Selection of extra information is done via - extra_field parameter by specifying tags - and log_names for the additional information. This information is - defined via acc_extra pseudovariable, referenced with the define - tag. If the tag is not specified, its value will be considered - to be the same as the log_value. Accounting backend(log, db, aaa, evi) - is specified at the beginning of the definition, separated by ':' from - the rest. The syntax of the parameter is: - - - - backend : tag -> log_name (';'tag -> log_name)* - - - backend : tag (';' tag)* - - - - Extra values are consistent during the whole call. Setting a - value during a request, will cause it to remain visible during all replies. Also, - concerning CDR logging, setting a value on the initial INVITE will - result in having that value throughout the dialog. - - - Via log_name you define how/where the - data will be logged. Its meaning depends - of the accounting support which is used: - - LOG accounting - log_name - will be just printed along with the data in - log_name=data format; - - DB accounting - log_name - will be the name of the DB column where the data will be - stored.IMPORTANT: add in db - acc table the columns corresponding to - each extra data; - - AAA accounting - - log_name will be the AVP name used for packing the data into - AAA message. The log_name will be translated to AVP number - via the dictionary. IMPORTANT: add in - AAA dictionary the log_name attribute. - - Events accounting - - log_name will be the name of the parameter in the event raised. - - - -
-
- How it works - - Declaring an extra in the format of - -modparam("acc", "extra_fields", "log: a -> test_a") - - will enable you to set the value for test_a field - of the log only by setting $acc_extra(a) variable. - Otherwise, the field shall be logged with no value(null). - -
-
- Radius accounting dependencies - - If radius accounting is used, except from a radius client library which is mandatory, - dictionary.rfc2866 must be included for the module - to work properly. -
-
- -
- Multi Call-Legs accounting -
- Overview - - A SIP call can have multiple legs due forwarding actions. For - example user A calls user B which forwards the call to user C. - There is only one SIP call but with 2 legs ( A to B and B to C). - Accounting the legs of a call is required for proper billing of - the calls (if C is a PSTN number and the call is billed, user B - must pay for the call - as last party modifing the call - destination-, and not A - as initiator of the call. Call - forwarding on server is only one example which shows the - necessity of the having an accounting engine with multiple legs - support. - -
-
- Configuration - - First how it works: The idea is to have a variable to store - a set of values for each leg. The meaning of - the variable content is strictly decided by the script writer - it can - be the origin and source of the leg, its status or any other - related information. By default there is defined only one leg. Script - writer has to decide when is the time to create a new leg, by using - acc_new_leg() script function. When creating a new - leg, all the values for that leg will be set to NULL by default. - - - When the accounting information for the call will be written/sent, - all the call-leg pairs will be added. - - - By default, the multiple call-leg support is disabled - it can be - enabled just by setting acc_leg variable - leg_fields module parameter. Note that - the last one only makes sense only for CDRs that are generated - automatically by &osips;. - -
-
- Logged data - - For each call, all the values from the acc_leg - variable will be logged. How the information will be actually - logged, depends of the data backend: - - - - syslog -- all leg-sets will be added - to one record string as acc_leg(leg1)=xxx, acc_leg(leg2)=xxxx ,... sets. - - - - database -- each pair will be - separately logged (due DB data structure constraints); several - records will be written, the difference between them being - only the fields corresponding to the call-leg info. - - You will need to add in your DB (all acc related - tables) the colums for call-leg info (a column for each leg value - of the set). - - - - AAA -- all sets will be added - to the same AAA accounting message as AAA AVPs - for each - call-leg a set of AAA AVPs will be added (corresponding - to the per-leg set) - - You will need to add in your dictionary the - AAA AVPs used in call-leg set definition. - - - - events -- each pair will appear as a - different parameter-value pair in the event. Similar to the - database behavior, multiple events will be raised, and the only - difference between them is the leg information. - - - - - - Important!!! In order to use RADIUS, - one must include the AVPs which are located in - $(opensips_install_dir)/etc/dictionary.opensips, both in opensips radius config - script dictionary and radius server dictionary. Most important are the last three - AVPs (IDs : 227, 228, 229) which you won't find in any SIP dictionary - (at least at this moment) because they are only used in openSips. - -
-
- -
- CDRs accounting -
- Overview - - ACC module can now also maintain session/dialog accounting. This - allows you to log useful information like call duration, call - start time and setup time. - -
-
- Configuration - - In order to have CDRs accounting, first you need to set the - cdr flag when calling - script function for the - initial INVITE of the dialog. - -
-
- How it works - - This type of accounting is based on the dialog module. When - an initial INVITE is received, if the cdr - flag is set, then the dialog creation time is saved. Once the call is - answered and the ACK is received, other information like extra values - or leg values are saved. When the corresponding BYE is received, - the call duration is computed and all information is stored to - the desired backend. - -
-
- - - -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - tm -- Transaction Manager - - - a database module -- If SQL - support is used. - - - rr -- Record Route, if - detect_direction module parameter is enabled. - - - - an aaa module - - - dialog -- Dialog, if - cdr option is used - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - - none. - - - -
-
- -
- Exported Parameters - -
- <varname>early_media</varname> (integer) - - Should be early media (any provisional reply with body) accounted too ? - - - Default value is 0 (no). - - - early_media example - -modparam("acc", "early_media", 1) - - -
-
- <varname>report_cancels</varname> (integer) - - By default, CANCEL reporting is disabled -- most accounting - applications wants to see INVITE's cancellation status. - Turn on if you explicitly want to account CANCEL transactions. - - - Default value is 0 (no). - - - report_cancels example - -modparam("acc", "report_cancels", 1) - - -
-
- <varname>detect_direction</varname> (integer) - - Controls the direction detection for sequential requests. If - enabled (non zero value), for sequential requests with upstream - direction (from callee to caller), the FROM and TO will be swapped - (the direction will be preserved as in the original request). - - - It affects all values related to TO and FROM headers (body, URI, - username, domain, TAG). - - - Default value is 0 (disabled). - - - detect_direction example - -modparam("acc", "detect_direction", 1) - - -
- -
- <varname>extra_fields</varname> (string) - - Defines the tag-log_value set to be used in extra fields accounting. - See for a - detailed description of the Extra accounting. - - - If empty, extra accounting support will be disabled. - - - Default value is 0 (disabled). - - - Setting <emphasis>extra_fields</emphasis> example: - -# for syslog-based accounting, use any text you want to be printed -# if setting $acc_extra(a) you will see "My_a_Field=<value> in logs -# if setting $acc_extra(b) you will see "b=<value> in logs -modparam("acc", "extra_fields", "log: a->My_a_Field; b") -# for mysql-based accounting, use the names of the columns -# $acc_extra(a) = <value> results in setting col_a with <value> in db -modparam("acc", "extra_fields", "db: a->col_a; col_b") -# for AAA-based accounting, use the names of the AAA AVPs -modparam("acc", "extra_fields","aaa:a->AAA_SRC;b->AAA_DST") -# evi definition example -modparam("acc", "extra_fields","a->2345;b->2346") - - -
- -
- <varname>leg_fields</varname> (string) - - Defines the tag-log_value set to be used in multi-leg accounting. - See for a - detailed description of the Multi Call-Legs accounting. - - - If empty, multi-leg accounting support will be disabled. - - - Default value is 0 (disabled). - - - Setting <emphasis>leg_fields</emphasis> example: - -# for syslog-based accounting, use any text you want to be printed -# if setting $(acc_leg(a)[0]) you will see "My_a_Field=<value> in logs -# if setting $(acc_leg(b)[0]) you will see "b=<value> in logs -modparam("acc", "leg_fields", "log: a->My_a_Field; b") -# for mysql-based accounting, use the names of the columns -# $acc_leg(a) = <value> results in setting col_a with <value> in db -modparam("acc", "leg_fields", "db: a->col_a; col_b") -# for AAA-based accounting, use the names of the AAA AVPs -modparam("acc", "leg_fields","aaa:a->AAA_LEG_SRC;b->AAA_LEG_DST") -# evi definition example -modparam("acc", "leg_fields","a->2345;b->2346") - - -
- - -
- <varname>log_level</varname> (integer) - - Log level at which accounting messages are issued to syslog. - - - Default value is L_NOTICE. - - - log_level example - -modparam("acc", "log_level", 2) # Set log_level to 2 - - -
-
- <varname>log_facility</varname> (string) - - Log facility to which accounting messages are issued to syslog. - This allows to easily seperate the accounting specific logging - from the other log messages. - - - Default value is LOG_DAEMON. - - - log_facility example - -modparam("acc", "log_facility", "LOG_DAEMON") - - -
- - - -
- <varname>aaa_url</varname> (string) - - This is the url representing the AAA protocol used and the location of the configuration file of this protocol. - - - If the parameter is set to empty string, the AAA accounting support - will be disabled. - - - Default value is NULL. - - - Set <varname>aaa_url</varname> parameter - -... -modparam("acc", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") -... - - -
- -
- <varname>service_type</varname> (integer) - - AAA service type used for accounting. - - - Default value is not-set. - - - service_type example - -# Default value of service type for SIP is 15 -modparam("acc", "service_type", 15) - - -
- -
- <varname>db_table_acc</varname> (string) - - Table name of accounting successful calls -- database specific. - - - Default value is acc - - - db_table_acc example - -modparam("acc", "db_table_acc", "myacc_table") - - -
-
- <varname>db_table_missed_calls</varname> (string) - - Table name for accounting missed calls -- database specific. - - - Default value is missed_calls - - - db_table_missed_calls example - -modparam("acc", "db_table_missed_calls", "myMC_table") - - -
-
- <varname>db_url</varname> (string) - - SQL address -- database specific. If is set to NULL or empty string, - the SQL support is disabled. - - - Default value is NULL (SQL disabled). - - - db_url example - -modparam("acc", "db_url", "mysql://user:password@localhost/opensips") - - -
-
- <varname>acc_method_column</varname> (string) - - Column name in accounting table to store the request's method name as - string. - - - Default value is method. - - - acc_method_column example - -modparam("acc", "acc_method_column", "method") - - -
-
- <varname>acc_from_tag_column</varname> (string) - - Column name in accounting table to store the From header TAG parameter. - - - Default value is from_tag. - - - acc_from_tag_column example - -modparam("acc", "acc_from_tag_column", "from_tag") - - -
-
- <varname>acc_to_tag_column</varname> (string) - - Column name in accounting table to store the To header TAG parameter. - - - Default value is to_tag. - - - acc_to_tag_column example - -modparam("acc", "acc_to_tag_column", "to_tag") - - -
-
- <varname>acc_callid_column</varname> (string) - - Column name in accounting table to store the request's Callid value. - - - Default value is callid. - - - acc_callid_column example - -modparam("acc", "acc_callid_column", "callid") - - -
-
- <varname>acc_sip_code_column</varname> (string) - - Column name in accounting table to store the final reply's numeric code - value in string format. - - - Default value is sip_code. - - - acc_sip_code_column example - -modparam("acc", "acc_sip_code_column", "sip_code") - - -
-
- <varname>acc_sip_reason_column</varname> (string) - - Column name in accounting table to store the final reply's reason - phrase value. - - - Default value is sip_reason. - - - acc_sip_reason_column example - -modparam("acc", "acc_sip_reason_column", "sip_reason") - - -
-
- <varname>acc_time_column</varname> (string) - - Column name in accounting table to store the time stamp of the - transaction completion in date-time format. - - - Default value is time. - - - acc_time_column example - -modparam("acc", "acc_time_column", "time") - - -
- -
- -
- Exported Pseudo-Variables -
- $acc_extra(tag_name) - This variable can addresed with the tag names defined - using . If - isn't called, this - variable is visible during the whole processing of one message, - enabling calling acc_XXX_request(). - If is called, the variable - will be visible from the first call of this function until the - actual accounting is being made. - -
- -
- $(acc_leg(tag_name)[leg_index]) - This variable can be addressed with the tag names defined - using and a valid leg index - (<= ). This variable cannot - be used unless is used. The - variable also accepts negative indexes, which start from -1 - (the lastly added leg). - - - -# the "caller" value of the current leg -$acc_leg(caller) - -# the "caller" value of the lastly added leg -$(acc_leg(caller)[-1]) # equivalent to $acc_leg(caller) - # equivalent to $(acc_leg(caller)[$acc_current_leg]) - -# the "caller" value of the next-to-last leg -$(acc_leg(caller)[-2]) - - - -
- -
- $acc_current_leg (read-only) - Holds the index of the current leg, starting from 0. Calling - will increment this index. - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">do_accounting(type, [flags], [table])</function> - - - do_accounting() replaces all the - *_flag and, *_missed_flag, cdr_flag, failed transaction_flag and the - db_table_avp modparams. Just call do_accounting(), select where and how you want - the accounting to take place, and the function will do all the work for you. - - - - When called multiple times, the function behaves additively. - - - Meaning of the parameters is as follows: - - - type (string) - the type of accounting you want to do. - All types have to be separated by '|'. The following parameters can - be used: - - - log - syslog accounting; - - - db - database accounting; - - - aaa - aaa specific accounting; - - - evi - Event Interface accounting; - - - - - flags (string, optional) - flags for the accounting type you have - selected. All the types have to be separated by '|'. The following - parameters can be used: - - - cdr - enables dialog-level accounting. - OpenSIPS will internally detect dialog termination (generation/receipt - of a BYE request), and store the CDR as soon as the BYE request - is replied to. By enabling the "cdr" flag, the following additional - fields will be populated: duration, ms_duration, setuptime, created. - (requires dialog module support) - - - missed - log missed calls; take care - that this flag will be deactivated after the first missed call; - you will have to reactivate it in the - failure_route if you want to account - each destination that did not respond to the call; - - - failed - flag which indicates if the - transaction should also be accounted in case - of failure (status>=300); - - - - - table (string, optional) - table where to do the accounting; - it replaces old table_avp parameter; - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - do_accounting usage - - ... - if (!has_totag()) { - if (is_method("INVITE")) { - /* enable cdr and missed calls accounting in the database - * and to syslog; db accounting shall be done in "my_acc" table */ - do_accounting("db|log", "cdr|missed", "my_acc"); - } - } - ... - if (is_method("BYE")) { - /* do normal accounting via aaa */ - do_accounting("aaa"); - } - ... - - - -
- -
- - <function moreinfo="none">drop_accounting([type], [flags])</function> - - - drop_accounting() resets flags - and types of accounting set with do_accounting(). If called with no - arguments all accounting will be stopped. If called with only one argument - all accounting for that type will be stopped. If called with two arguments - normal accounting will still be enabled. - - - When called multiple times, the function behaves additively. - - - Meaning of the parameters is as follows: - - - type (string, optional) - the type of accounting you want to stop. - All the types have to be separated by '|'. The following parameters can - be used: - - - log - stop syslog accounting; - - - db - stop database accounting; - - - aaa - stop aaa specific accounting; - - - evi - stop Event Interface accounting; - - - - - flags (string, optional) - flags to be reset for the accouting type you have - selected. All the types have to be separated by '|'. The following - parameters can be used: - - - cdr - stop CDR accounting; - - - missed - stop logging missed calls; - - - failed - stop failed transaction accounting; - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - drop_accounting usage - - ... - acc_log_request("403 Destination not allowed"); - if (!has_totag()) { - if (is_method("INVITE")) { - /* enable cdr and missed calls accounting in the database - * and to syslog; db accounting shall be done in "my_acc" table */ - do_accounting("db|log", "cdr|missed", "my_acc"); - } - } - ... - /* later in your script */ - if (...) { /* you don't want accounting anymore */ - /* stop all syslog accounting */ - drop_accounting("log"); - /* or stop missed calls and cdr accounting for syslog; - * normal accounting will still be enabled */ - drop_accounting("log", "missed|cdr"); - /* or stop all types of accounting */ - drop_accounting(); - } - ... - - - -
- - - -
- - <function moreinfo="none">acc_log_request(comment)</function> - - - acc_request reports on a request, - for example, it can be used to report on missed calls to off-line users - who are replied 404 - Not Found. To avoid multiple reports on UDP - request retransmission, you would need to embed the - action in stateful processing. - - - Meaning of the parameters is as follows: - - - comment (string) - Comment describing how the - request completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "480 Nobody Home"). Variables - are accepted in this string. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - acc_log_request usage - -... -acc_log_request("403 Destination not allowed"); -... - - -
-
- - <function moreinfo="none">acc_db_request(comment, table)</function> - - - Like acc_log_request, - acc_db_request reports on a - request. The report is sent to database at db_url, in - the table referred to in the second action parameter. - - - Meaning of the parameters is as follows: - - - - comment (string) - Comment describing how the - request completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "480 Nobody Home"). Variables - are accepted in this string. - - - table (string) - Database table to be used. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - acc_db_request usage - -... -acc_db_request("Some comment", "Some table"); -acc_db_request("$T_reply_code $(<reply>rr)", "acc"); -... - - -
-
- - <function moreinfo="none">acc_aaa_request(comment)</function> - - - Like acc_log_request, - acc_aaa_request reports on - a request. It reports to aaa server as configured in - aaa_url. - - - Meaning of the parameters is as follows: - - - comment (string) - Comment describing how the - request completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "404 Nobody home"). Variables - are accepted in this string. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - acc_aaa_request usage - -... -acc_aaa_request("403 Destination not allowed"); -... - - -
-
- - <function moreinfo="none">acc_evi_request(comment)</function> - - - Like acc_log_request, - acc_evi_request reports on a - request. The report is packed as an event sent through the &osips; Event - Interface as E_ACC_EVENT if the reply code is a - positive one (lower than 300), or E_ACC_MISSED_EVENT - for negative or no codes. More information on this in - . - - - Meaning of the parameters is as follows: - - - - comment (string) - Comment describing how the - request completed - this string has to contain a reply code - followed by a reply reason phrase (ex: "404 Nobody home") - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - acc_evi_request usage - -... -acc_evi_request("403 Destination not allowed"); -... - - -
- -
- - <function moreinfo="none">acc_new_leg()</function> - - - Creates a new leg and increments - only if multi-leg accounting is used. All values of the new leg - will be initialized to null. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - acc_new_leg usage - -... - acc_new_leg(); -... - - -
- -
- - <function moreinfo="none">acc_load_ctx_from_dlg()</function> - - - The function loads and exposes the accounting context of the - currently in-use dialog. By dialog context, it means, from script - level, you will read/write the accounting variables from the - other dialog. The current accounting context is - stashed until an unload operation is done. - - - Note that this functions makes sense only when used together with - the load_dialog_ctx() function from the - dialog module. After loading the context of another dialog, by - using the acc_load_ctx_from_dlg() function, - you can also access the accounting context of the loaded dialog. - - - NOTE: you cannot perform a new load until doing an unload - no nested - loadings are allowed. - - - This function can be used from any type of route. - - - acc_load_ctx_from_dlg usage - -... -if ( load_dialog_ctx("$var(callid)") ) { - # we now have the dialog context of the new dialog - acc_load_ctx_from_dlg(); - # we have now also the accouting context of that dialog - xlog("The accounting caller of call '$var(callid)' " - "is '$acc_extra(caller)'\n"); - acc_unload_ctx_from_dlg(); - unload_dialog_ctx(); -} - -... - - -
- -
- - <function moreinfo="none">acc_unload_ctx_from_dlg()</function> - - - The function off-loads a previosuly loaded accounting context, exposing - whatever accounting context was present before doing the load. - - - NOTE: you MUST perform from script an explicit unload for each load - you did! - - - This function can be used from any type of route. - - - For usage example, see the . - -
- -
- - -
- Exported Events -
- - <function moreinfo="none">E_ACC_CDR</function> - - - The event raised when a CDR is generated. Note that this event will - only be triggered if the auto CDR accounting is used. - - Parameters: - - - method - Request method name - - - from_tag - From header tag parameter - - - to_tag - To header tag parameter - - - callid - Message Call-id - - - sip_code - The status code from the final reply - - - sip_reason - The status reason from the final reply - - - time - The timestamp when the call was established - - - evi_extra* - Extra parameters added by - the evi_extra parameter. - - - evi_extra_bye* - Extra parameters added by - the evi_extra_bye parameter - - - multi_leg_info* - Extra parameters added by - the multi_leg_info parameter - - - multi_leg_bye_info* - Extra parameters added by - the multi_leg_bye_info parameter - - - duration - The call duration in seconds - - - ms_duration - The call duration in milliseconds - - - setuptime - The call setup time in seconds - - - created - The timestamp when the call was - created (the initial Invite was received) - - - -
-
- - <function moreinfo="none">E_ACC_EVENT</function> - - - This event is triggered when old-style accounting is used. It is - generated when the requests (INVITE and BYE) transaction have - positive final replies, or by the acc_evi_request() - function that has a positive reply code in comment. - - Parameters: - - - method - Request method name - - - from_tag - From header tag parameter - - - to_tag - To header tag parameter - - - callid - Message Call-id - - - sip_code - The status code from the final reply - - - sip_reason - The status reason from the final reply - - - time - The timestamp when the transaction was created - - - evi_extra* - Extra parameters added by - the evi_extra parameter - - - multi_leg_info* - Extra parameters added by - the multi_leg_info parameter - - -
-
- - <function moreinfo="none">E_ACC_MISSED_EVENT</function> - - - This event is triggered when old-style accounting is used. It is - generated when the requests (INVITE and BYE) transaction have - negative final replies, or by the acc_evi_request() - function that has a negative reply code in comment. - - Parameters: - - - method - Request method name - - - from_tag - From header tag parameter - - - to_tag - To header tag parameter - - - callid - Message Call-id - - - sip_code - The status code from the final reply - - - sip_reason - The status reason from the final reply - - - time - The timestamp when the transaction was created - - - evi_extra* - Extra parameters added by - the evi_extra parameter - - - multi_leg_info* - Extra parameters added by - the multi_leg_info parameter - - - created - Timestamp when the call was created - - - setuptime - The call setup time in seconds - - - - -
- -
- -
diff --git a/modules/acc/doc/acc_faq.xml b/modules/acc/doc/acc_faq.xml deleted file mode 100644 index 47957a8b32d..00000000000 --- a/modules/acc/doc/acc_faq.xml +++ /dev/null @@ -1,117 +0,0 @@ - - - - - &faqguide; - - - - - What happened with old report_ack parameter - - - - The parameter is considered obsolete. It was removed as acc - module is doing SIP transaction based accouting and according - to SIP RFC, end2end ACKs are a different transaction (still part - of the same dialog). ACKs can be individually accouted as any - other sequential (in-dialog) request. - $ - $ - $ - - - - What happened with old log_fmt parameter - - - - The parameter became obsolete with the restructure of the data - logged by ACC module (refer to the Overview chapter). For similar - behaviour you can use the extra accouting (see the corresponding - chapter). - - - - - - - What happened with old multi_leg_enabled parameter - - - - The parameter became obsolete by the addition of the new - multi_leg_info parameter. The multi-leg accouting is automatically - enabled when multi_leg_info is defined. - - - - - - - What happened with old src_leg_avp_id and dst_leg_avp_id - parameters - - - - The parameter was replaced by the more generic new parameter - multi_leg_info. This allows logging (per-leg) of more information - than just dst and src. - - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/acc/doc/contributors.xml b/modules/acc/doc/contributors.xml deleted file mode 100644 index d0f43eb8177..00000000000 --- a/modules/acc/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 228 - 114 - 4306 - 4609 - - - 2. - Jan Janak (@janakj) - 147 - 16 - 5587 - 5074 - - - 3. - Ionut Ionita (@ionutrazvanionita) - 140 - 39 - 3730 - 4180 - - - 4. - Razvan Crainea (@razvancrainea) - 102 - 67 - 2705 - 677 - - - 5. - Liviu Chircu (@liviuchircu) - 75 - 55 - 985 - 608 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 57 - 26 - 2272 - 660 - - - 7. - Daniel-Constantin Mierla (@miconda) - 26 - 23 - 115 - 88 - - - 8. - Elena-Ramona Modroiu - 25 - 4 - 2267 - 5 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 22 - 11 - 353 - 478 - - - 10. - Henning Westerholt (@henningw) - 20 - 15 - 184 - 131 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Maksym Sobolyev (@sobomax), Irina-Maria Stanescu, Karel Kozlik, Andrei Pelinescu-Onciul, Alexandra Titoc, Dan Pascu (@danpascu), Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Ryan Bullock (@rrb3942), Ovidiu Sas (@ovidiusas), Walter Doekes (@wdoekes), Sergio Gutierrez, Peter Nixon, Alex Massover, Nils Ohlmeier, Konstantin Bokarius, Alexey Vasilyev (@vasilevalex), Jesus Rodrigues, Julien Blache, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2010 - Dec 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Dec 2003 - Nov 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2003 - May 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 7. - Alexey Vasilyev (@vasilevalex) - Mar 2022 - Mar 2022 - - - 8. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 9. - Dan Pascu (@danpascu) - Jul 2004 - Sep 2018 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Dusan Klinec (@ph4r05), Vlad Paiu (@vladpaiu), Ryan Bullock (@rrb3942), Irina-Maria Stanescu, Alex Massover, Sergio Gutierrez, Ovidiu Sas (@ovidiusas), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jesus Rodrigues, Julien Blache, Peter Nixon, Juha Heinanen (@juha-h), Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Andrei Pelinescu-Onciul, Elena-Ramona Modroiu, Nils Ohlmeier, Karel Kozlik. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Ryan Bullock (@rrb3942), Irina-Maria Stanescu, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), Maksym Sobolyev (@sobomax), Elena-Ramona Modroiu. -
- -
diff --git a/modules/aka_av_diameter/README b/modules/aka_av_diameter/README deleted file mode 100644 index 7c2118a6f1e..00000000000 --- a/modules/aka_av_diameter/README +++ /dev/null @@ -1,249 +0,0 @@ -AKA Authentication Vector Diameter Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Setup - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. aaa_url (string) - 1.4.2. realm (string) - 1.4.3. server_uri (string) - - 1.5. Diameter Commands File - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. aaa_url parameter usage - 1.2. realm parameter usage - 1.3. server_uri parameter usage - 1.4. Diameter Commands File Example - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an extension to the AKA_AUTH module providing a - Diameter AKA AV Manager that implements the - Multimedia-Auth-Request and Multimedia-Auth-Answer Diameter - commands defined in the Cx interface of the ETSI TS 129 229 - specifications in order to fetch a set of authentication - vectors and feed them in the AKA authentication process. - - When the AKA_AUTH module needs a new authentication vector to - do an aka_challenge(), it may require this module to fetch a - set of authentication vectors for the purpose. The module packs - the query in a MAR (Multimedia-Auth-Request) command and sends - it to an HSS Diameter server. When an MAA - (Multimedia-Auth-Answer) command is received in response, the - corresponding authentication vectors are gathered and fed back - to the AUTH_AKA engine. - - It uses the AAA_Diameter module to perform the Diameter - requests. It may run in both a synchronous and asynchronous - mode, depending on how the AUTH_AKA module performs the query. - -1.2. Setup - - The module requires an aaa_diameter connection to an HSS - Diameter server that implements the Cx interfaces and is able - to provide authentication vectors through the - Multimedia-Auth-Request and Multimedia-Auth-Answer commands. - - The format of the command, along with the required fields can - be found in the example/aka_av_diameter.dictionary file located - in the module's source directory, as well as in the Diameter - Commands Example section. - - Note: the module internals uses the AVPs names found in the - provided dictionary - changing the file may break the behavior - of the module. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * auth_aka -- AKA Authentication module that triggers the AKA - authentication process - * aaa_diameter -- AAA Diameter module that implements the - Diameter communication to the HSS Server. - -1.3.2. External Libraries or Applications - - This module does not depend on any external library. - -1.4. Exported Parameters - -1.4.1. aaa_url (string) - - This is the url representing the connection to the AAA server. - - Note: Currently the module only supports connections to a - Diameter server. The path to the AVPs configuration file is - also required, otherwise the module will not start, or not work - properly. - - Example 1.1. aaa_url parameter usage -modparam("auth_aaa", "aaa_url", "diameter:freeDiameter.conf;extra-avps-f -ile:/etc/freeDiameter/aka_av_diameter.dictionary") - -1.4.2. realm (string) - - The Realm used in the Origin Diameter commands. - - Default value is “diameter.test”. - - Example 1.2. realm parameter usage - -modparam("aka_av_diameter", "realm", "scscf.ims.mnc001.mcc001.3gppnetwor -k.org") - -1.4.3. server_uri (string) - - The Server-URI used in the Diameter commands. - - If it is left empty, the Server-Name will be created by adding - "sip:" in front of the realm parameter value (e.g. - “sip:scscf.ims.mnc001.mcc001.3gppnetwork.org”). - - Example 1.3. server_uri parameter usage - -modparam("aka_av_diameter", "server_uri", "sip:scscf.ims.mnc001.mcc001.3 -gppnetwork.org") - -1.5. Diameter Commands File - - File that should be provided to the aaa_diameter connection. - - Example 1.4. Diameter Commands File Example - -VENDOR 10415 TGPP - -ATTRIBUTE Public-Identity 601 string 10415 -ATTRIBUTE Server-Name 602 string 10415 -ATTRIBUTE 3GPP-SIP-Number-Auth-Items 607 unsigned32 10415 -ATTRIBUTE 3GPP-SIP-Authentication-Scheme 608 utf8string 10415 -ATTRIBUTE 3GPP-SIP-Authenticate 609 hexstring 10415 -ATTRIBUTE 3GPP-SIP-Authorization 610 hexstring 10415 -ATTRIBUTE 3GPP-SIP-Authentication-Context 611 string 10415 -ATTRIBUTE 3GPP-SIP-Item-Number 613 unsigned32 10415 -ATTRIBUTE Confidentiality-Key 625 hexstring 10415 -ATTRIBUTE Integrity-Key 626 hexstring 10415 - - -ATTRIBUTE 3GPP-SIP-Auth-Data-Item 612 grouped 10415 -{ - 3GPP-SIP-Item-Number | OPTIONAL | 1 - 3GPP-SIP-Authentication-Scheme | OPTIONAL | 1 - 3GPP-SIP-Authenticate | OPTIONAL | 1 - 3GPP-SIP-Authorization | OPTIONAL | 1 - 3GPP-SIP-Authentication-Context | OPTIONAL | 1 - Confidentiality-Key | OPTIONAL | 1 - Integrity-Key | OPTIONAL | 1 -} - -APPLICATION-AUTH 16777216/10415 3GPP Cx - -REQUEST 303 Multimedia-Auth Request -{ - Session-Id | REQUIRED | 1 - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Vendor-Specific-Application-Id | REQUIRED | 1 - Auth-Session-State | REQUIRED | 1 - User-Name | REQUIRED | 1 - Public-Identity | REQUIRED | 1 - 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 - 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 - Server-Name | REQUIRED | 1 -} - -ANSWER 303 Multimedia-Auth Answer -{ - Session-Id | REQUIRED | 1 - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Host | OPTIONAL | 1 - Destination-Realm | OPTIONAL | 1 - Vendor-Specific-Application-Id | REQUIRED | 1 - Auth-Session-State | REQUIRED | 1 - User-Name | REQUIRED | 1 - Public-Identity | REQUIRED | 1 - 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 - 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 - Result-Code | REQUIRED | 1 -} - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 13 4 941 4 - 2. LarryLaffer-dev 6 4 57 24 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. LarryLaffer-dev Mar 2025 - Mar 2025 - 2. Razvan Crainea (@razvancrainea) Mar 2024 - Mar 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: LarryLaffer-dev, Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Solutions; diff --git a/modules/aka_av_diameter/README.md b/modules/aka_av_diameter/README.md new file mode 100644 index 00000000000..e9138178ed1 --- /dev/null +++ b/modules/aka_av_diameter/README.md @@ -0,0 +1,202 @@ +--- +title: "AKA Authentication Vector Diameter Module" +description: "This module is an extension to the AKA_AUTH module providing a Diameter AKA AV Manager that implements the Multimedia-Auth-Request and Multimedia-Auth-Answer Diameter commands." +--- + +## Admin Guide + + +### Overview + + +This module is an extension to the *AKA_AUTH* module +providing a Diameter AKA AV Manager that implements the Multimedia-Auth-Request +and Multimedia-Auth-Answer Diameter commands defined in the +*Cx* interface of the *ETSI TS 129 229* +specifications in order to fetch a set of authentication vectors and feed +them in the AKA authentication process. + + +When the *AKA_AUTH* module needs a new authentication +vector to do an *aka_challenge()*, it may require this +module to fetch a set of authentication vectors for the purpose. The module +packs the query in a *MAR* (Multimedia-Auth-Request) +command and sends it to an *HSS* Diameter server. When an +*MAA* (Multimedia-Auth-Answer) command is received in +response, the corresponding authentication vectors are gathered and fed back +to the *AUTH_AKA* engine. + + +It uses the *AAA_Diameter* module to perform the Diameter +requests. It may run in both a synchronous and asynchronous mode, +depending on how the *AUTH_AKA* module performs the query. + + +### Setup + + +The module requires an *aaa_diameter* connection to an +*HSS* Diameter server that implements the +*Cx* interfaces and is able to provide authentication vectors +through the Multimedia-Auth-Request and Multimedia-Auth-Answer commands. + + +The format of the command, along with the required fields can be found in the +*example/aka_av_diameter.dictionary* file located in the +module's source directory, as well as in the +[example diameter commands](#diameter_commands_file) section. + + +> [!NOTE] +> The module internals uses the AVPs names +> found in the provided dictionary - changing the file may break the behavior of the module. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *auth_aka* -- AKA Authentication +module that triggers the AKA authentication process +- *aaa_diameter* -- AAA Diameter +module that implements the Diameter communication to the +*HSS* Server. + + +#### External Libraries or Applications + + +This module does not depend on any external library. + + +### Exported Parameters + + +#### aaa_url (string) + + +This is the url representing the connection to the AAA server. + +> [!NOTE] +> Currently the module only supports +> connections to a Diameter server. The path to the AVPs +> configuration file is also required, otherwise the module will +> not start, or not work properly. + + +```opensips title="aaa_url parameter usage" +modparam("auth_aaa", "aaa_url", "diameter:freeDiameter.conf;extra-avps-file:/etc/freeDiameter/aka_av_diameter.dictionary") + +``` + + +#### realm (string) + + +The Realm used in the Origin Diameter commands. + + +Default value is "diameter.test". + + +```opensips title="realm parameter usage" + +modparam("aka_av_diameter", "realm", "scscf.ims.mnc001.mcc001.3gppnetwork.org") + +``` + + +#### server_uri (string) + + +The Server-URI used in the Diameter commands. + + +If it is left empty, the Server-Name will be created by adding "sip:" in front of the realm +parameter value +(e.g. "sip:scscf.ims.mnc001.mcc001.3gppnetwork.org"). + + +```opensips title="server_uri parameter usage" + +modparam("aka_av_diameter", "server_uri", "sip:scscf.ims.mnc001.mcc001.3gppnetwork.org") + +``` + + +### Diameter Commands File + + +File that should be provided to the *aaa_diameter* connection. + + +``` title="Diameter Commands File Example" +VENDOR 10415 TGPP + +ATTRIBUTE Public-Identity 601 string 10415 +ATTRIBUTE Server-Name 602 string 10415 +ATTRIBUTE 3GPP-SIP-Number-Auth-Items 607 unsigned32 10415 +ATTRIBUTE 3GPP-SIP-Authentication-Scheme 608 utf8string 10415 +ATTRIBUTE 3GPP-SIP-Authenticate 609 hexstring 10415 +ATTRIBUTE 3GPP-SIP-Authorization 610 hexstring 10415 +ATTRIBUTE 3GPP-SIP-Authentication-Context 611 string 10415 +ATTRIBUTE 3GPP-SIP-Item-Number 613 unsigned32 10415 +ATTRIBUTE Confidentiality-Key 625 hexstring 10415 +ATTRIBUTE Integrity-Key 626 hexstring 10415 + + +ATTRIBUTE 3GPP-SIP-Auth-Data-Item 612 grouped 10415 +{ + 3GPP-SIP-Item-Number | OPTIONAL | 1 + 3GPP-SIP-Authentication-Scheme | OPTIONAL | 1 + 3GPP-SIP-Authenticate | OPTIONAL | 1 + 3GPP-SIP-Authorization | OPTIONAL | 1 + 3GPP-SIP-Authentication-Context | OPTIONAL | 1 + Confidentiality-Key | OPTIONAL | 1 + Integrity-Key | OPTIONAL | 1 +} + +APPLICATION-AUTH 16777216/10415 3GPP Cx + +REQUEST 303 Multimedia-Auth Request +{ + Session-Id | REQUIRED | 1 + Origin-Host | REQUIRED | 1 + Origin-Realm | REQUIRED | 1 + Destination-Realm | REQUIRED | 1 + Vendor-Specific-Application-Id | REQUIRED | 1 + Auth-Session-State | REQUIRED | 1 + User-Name | REQUIRED | 1 + Public-Identity | REQUIRED | 1 + 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 + 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 + Server-Name | REQUIRED | 1 +} + +ANSWER 303 Multimedia-Auth Answer +{ + Session-Id | REQUIRED | 1 + Origin-Host | REQUIRED | 1 + Origin-Realm | REQUIRED | 1 + Destination-Host | OPTIONAL | 1 + Destination-Realm | OPTIONAL | 1 + Vendor-Specific-Application-Id | REQUIRED | 1 + Auth-Session-State | REQUIRED | 1 + User-Name | REQUIRED | 1 + Public-Identity | REQUIRED | 1 + 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 + 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 + Result-Code | REQUIRED | 1 +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/aka_av_diameter/doc/aka_av_diameter.xml b/modules/aka_av_diameter/doc/aka_av_diameter.xml deleted file mode 100644 index 41d4548ac8f..00000000000 --- a/modules/aka_av_diameter/doc/aka_av_diameter.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - AKA Authentication Vector Diameter Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Solutions; - diff --git a/modules/aka_av_diameter/doc/aka_av_diameter_admin.xml b/modules/aka_av_diameter/doc/aka_av_diameter_admin.xml deleted file mode 100644 index 603c6369711..00000000000 --- a/modules/aka_av_diameter/doc/aka_av_diameter_admin.xml +++ /dev/null @@ -1,212 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an extension to the AKA_AUTH module - providing a Diameter AKA AV Manager that implements the Multimedia-Auth-Request - and Multimedia-Auth-Answer Diameter commands defined in the - Cx interface of the ETSI TS 129 229 - specifications in order to fetch a set of authentication vectors and feed - them in the AKA authentication process. - - - When the AKA_AUTH module needs a new authentication - vector to do an aka_challenge(), it may require this - module to fetch a set of authentication vectors for the purpose. The module - packs the query in a MAR (Multimedia-Auth-Request) - command and sends it to an HSS Diameter server. When an - MAA (Multimedia-Auth-Answer) command is received in - response, the corresponding authentication vectors are gathered and fed back - to the AUTH_AKA engine. - - - It uses the AAA_Diameter module to perform the Diameter - requests. It may run in both a synchronous and asynchronous mode, - depending on how the AUTH_AKA module performs the query. - -
- -
- Setup - - The module requires an aaa_diameter connection to an - HSS Diameter server that implements the - Cx interfaces and is able to provide authentication vectors - through the Multimedia-Auth-Request and Multimedia-Auth-Answer commands. - - - The format of the command, along with the required fields can be found in the - example/aka_av_diameter.dictionary file located in the - module's source directory, as well as in the - section. - - - Note: the module internals uses the AVPs names - found in the provided dictionary - changing the file may break the behavior - of the module. - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - auth_aka -- AKA Authentication - module that triggers the AKA authentication process - - - aaa_diameter -- AAA Diameter - module that implements the Diameter communication to the - HSS Server. - - - -
-
- External Libraries or Applications - - This module does not depend on any external library. - -
-
- -
- Exported Parameters -
- <varname>aaa_url</varname> (string) - - This is the url representing the connection to the AAA server. - - Note: Currently the module only supports - connections to a Diameter server. The path to the AVPs - configuration file is also required, otherwise the module will - not start, or not work properly. - - - - <varname>aaa_url</varname> parameter usage - -modparam("auth_aaa", "aaa_url", "diameter:freeDiameter.conf;extra-avps-file:/etc/freeDiameter/aka_av_diameter.dictionary") - - -
-
- <varname>realm</varname> (string) - - The Realm used in the Origin Diameter commands. - - - Default value is diameter.test. - - - <varname>realm</varname> parameter usage - - -modparam("aka_av_diameter", "realm", "scscf.ims.mnc001.mcc001.3gppnetwork.org") - - -
-
- <varname>server_uri</varname> (string) - - The Server-URI used in the Diameter commands. - - - If it is left empty, the Server-Name will be created by adding "sip:" in front of the realm - parameter value - (e.g. sip:scscf.ims.mnc001.mcc001.3gppnetwork.org). - - - <varname>server_uri</varname> parameter usage - - -modparam("aka_av_diameter", "server_uri", "sip:scscf.ims.mnc001.mcc001.3gppnetwork.org") - - -
- - -
- -
- Diameter Commands File - - File that should be provided to the aaa_diameter connection. - - - Diameter Commands File Example - - -VENDOR 10415 TGPP - -ATTRIBUTE Public-Identity 601 string 10415 -ATTRIBUTE Server-Name 602 string 10415 -ATTRIBUTE 3GPP-SIP-Number-Auth-Items 607 unsigned32 10415 -ATTRIBUTE 3GPP-SIP-Authentication-Scheme 608 utf8string 10415 -ATTRIBUTE 3GPP-SIP-Authenticate 609 hexstring 10415 -ATTRIBUTE 3GPP-SIP-Authorization 610 hexstring 10415 -ATTRIBUTE 3GPP-SIP-Authentication-Context 611 string 10415 -ATTRIBUTE 3GPP-SIP-Item-Number 613 unsigned32 10415 -ATTRIBUTE Confidentiality-Key 625 hexstring 10415 -ATTRIBUTE Integrity-Key 626 hexstring 10415 - - -ATTRIBUTE 3GPP-SIP-Auth-Data-Item 612 grouped 10415 -{ - 3GPP-SIP-Item-Number | OPTIONAL | 1 - 3GPP-SIP-Authentication-Scheme | OPTIONAL | 1 - 3GPP-SIP-Authenticate | OPTIONAL | 1 - 3GPP-SIP-Authorization | OPTIONAL | 1 - 3GPP-SIP-Authentication-Context | OPTIONAL | 1 - Confidentiality-Key | OPTIONAL | 1 - Integrity-Key | OPTIONAL | 1 -} - -APPLICATION-AUTH 16777216/10415 3GPP Cx - -REQUEST 303 Multimedia-Auth Request -{ - Session-Id | REQUIRED | 1 - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Realm | REQUIRED | 1 - Vendor-Specific-Application-Id | REQUIRED | 1 - Auth-Session-State | REQUIRED | 1 - User-Name | REQUIRED | 1 - Public-Identity | REQUIRED | 1 - 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 - 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 - Server-Name | REQUIRED | 1 -} - -ANSWER 303 Multimedia-Auth Answer -{ - Session-Id | REQUIRED | 1 - Origin-Host | REQUIRED | 1 - Origin-Realm | REQUIRED | 1 - Destination-Host | OPTIONAL | 1 - Destination-Realm | OPTIONAL | 1 - Vendor-Specific-Application-Id | REQUIRED | 1 - Auth-Session-State | REQUIRED | 1 - User-Name | REQUIRED | 1 - Public-Identity | REQUIRED | 1 - 3GPP-SIP-Number-Auth-Items | REQUIRED | 1 - 3GPP-SIP-Auth-Data-Item | REQUIRED | 1 - Result-Code | REQUIRED | 1 -} - - -
- -
- diff --git a/modules/aka_av_diameter/doc/contributors.xml b/modules/aka_av_diameter/doc/contributors.xml deleted file mode 100644 index cfc65eb7b8c..00000000000 --- a/modules/aka_av_diameter/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 13 - 4 - 941 - 4 - - - 2. - LarryLaffer-dev - 6 - 4 - 57 - 24 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - LarryLaffer-dev - Mar 2025 - Mar 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Mar 2024 - Mar 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: LarryLaffer-dev, Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/alias_db/README b/modules/alias_db/README deleted file mode 100644 index 14fbf75a366..00000000000 --- a/modules/alias_db/README +++ /dev/null @@ -1,334 +0,0 @@ -ALIAS_DB Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (str) - 1.3.2. user_column (str) - 1.3.3. domain_column (str) - 1.3.4. alias_user_column (str) - 1.3.5. alias_domain_column (str) - 1.3.6. domain_prefix (str) - 1.3.7. append_branches (int) - - 1.4. Exported Functions - - 1.4.1. alias_db_lookup(table_name, [flags]) - 1.4.2. alias_db_find(table_name, input_uri, - output_var, [flags]) - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set user_column parameter - 1.3. Set domain_column parameter - 1.4. Set alias_user_column parameter - 1.5. Set alias_domain_column parameter - 1.6. Set domain_prefix parameter - 1.7. Set append_branches parameter - 1.8. alias_db_lookup() usage - 1.9. alias_db_find() usage - -Chapter 1. Admin Guide - -1.1. Overview - - ALIAS_DB module can be used as an alternative for user aliases - via usrloc. The main feature is that it does not store all - adjacent data as for user location and always uses database for - search (no memory caching). - - Having no memory caching, search speed might decrease but - provisioning is easier. With very fast databases like MySQL, - speed penalty can be lowered. Also, search can be performed on - different tables in the same script. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * database module (mysql, dbtext, ...). - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (str) - - Database URL. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("alias_db", "db_url", "dbdriver://username:password@dbhost/dbna -me") -... - -1.3.2. user_column (str) - - Name of the column storing username. - - Default value is “username”. - - Example 1.2. Set user_column parameter -... -modparam("alias_db", "user_column", "susername") -... - -1.3.3. domain_column (str) - - Name of the column storing user's domain. - - Default value is “domain”. - - Example 1.3. Set domain_column parameter -... -modparam("alias_db", "domain_column", "sdomain") -... - -1.3.4. alias_user_column (str) - - Name of the column storing alias username. - - Default value is “alias_username”. - - Example 1.4. Set alias_user_column parameter -... -modparam("alias_db", "alias_user_column", "auser") -... - -1.3.5. alias_domain_column (str) - - Name of the column storing alias domain. - - Default value is “alias_domain”. - - Example 1.5. Set alias_domain_column parameter -... -modparam("alias_db", "alias_domain_column", "adomain") -... - -1.3.6. domain_prefix (str) - - Specifies the prefix to be stripped from the domain in R-URI - before doing the search. - - Default value is “NULL”. - - Example 1.6. Set domain_prefix parameter -... -modparam("alias_db", "domain_prefix", "sip.") -... - -1.3.7. append_branches (int) - - If the alias resolves to many SIP IDs, the first is replacing - the R-URI, the rest are added as branches. - - Default value is “0” (0 - don't add branches; 1 - add - branches). - - Example 1.7. Set append_branches parameter -... -modparam("alias_db", "append_branches", 1) -... - -1.4. Exported Functions - -1.4.1. alias_db_lookup(table_name, [flags]) - - The function takes the R-URI and search to see whether it is an - alias or not. If it is an alias for a local user, the R-URI is - replaced with user's SIP uri. - - The function returns TRUE if R-URI is alias and it was replaced - by user's SIP uri. - - Meaning of the parameters is as follows: - * table_name (string) - the name of the table to search for - the alias - * flags (string, optional) - set of character flags to - control the alias lookup process: - + d - do not use domain URI part in the alias lookup - query (use only a username-based lookup). By default, - both username and domain are used. - + r - do reverse alias lookup - lookup for the alias - mapped to the current URI (URI 2 alias translation); - normally, the function looks up for the URI mapped to - the alias (alias 2 URI translation). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.8. alias_db_lookup() usage -... -alias_db_lookup("dbaliases", "rd"); -alias_db_lookup("dba_$(rU{s.substr,0,1})"); -... - -1.4.2. alias_db_find(table_name, input_uri, output_var, [flags]) - - The function is very similar to alias_db_lookup(), but instead - of using fixed input (RURI) and output (RURI) is able to get - the input SIP URI from a pseudo-variable and place the result - back also in a pseudo-variable. - - The function is useful as the alias lookup does not affect the - request itself (no RURI changes), can be used in a reply - context (as it does not work with RURI only) and can be used - for others URI than the RURI (To URI, From URI, custom URI). - - The function returns TRUE if any alias mapping was found and - returned. - - Meaning of the parameters is as follows: - * table_name (string) - the name of the table to search for - the alias - * input_uri (string) - a SIP URI to look up - * output_var (var) - a variable to hold the SIP URI result - * flags (string, optional) (optional) - set of flags (char - based flags) to control the alias lookup process: - + d - do not use domain URI part in the alias lookup - query (use only a username-based lookup). By default, - both username and domain are used. - + r - do revers alias lookup - lookup for the alias - mapped to the current URI (URI 2 alias translation); - normally, the function looks up for the URI mapped to - the alias (alias 2 URI translation). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - LOCAL_ROUTE, STARTUP_ROUTE, FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.9. alias_db_find() usage -... -# do revers alias lookup and find the alias for the FROM URI -alias_db_find("dbaliases", $fu, $avp(from_alias), "r"); -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with old use_domain parameter - - The global parameter (affecting the entire module) was replaced - with a per lookup parameter (affecting only current lookup). - See the "d" (do not used domain part) flag in the - db_alias_lookup() and db_alias_find() functions. - - 2.2. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 33 28 222 171 - 2. Daniel-Constantin Mierla (@miconda) 15 12 28 64 - 3. Liviu Chircu (@liviuchircu) 13 10 48 64 - 4. Razvan Crainea (@razvancrainea) 8 6 10 8 - 5. Henning Westerholt (@henningw) 6 4 48 49 - 6. Elena-Ramona Modroiu 5 3 92 39 - 7. Walter Doekes (@wdoekes) 5 3 7 7 - 8. Vlad Patrascu (@rvlad-patrascu) 5 2 38 88 - 9. Maksym Sobolyev (@sobomax) 4 2 3 5 - 10. Vladimir Romanov 4 1 227 51 - - All remaining contributors: Sergey Khripchenko (@shripchenko), - Sergio Gutierrez, Konstantin Bokarius, Anca Vamanu, Dusan - Klinec (@ph4r05), Peter Lemenkov (@lemenkov), Edson Gellert - Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - May 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Walter Doekes (@wdoekes) Apr 2010 - Apr 2021 - 5. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 9. Sergey Khripchenko (@shripchenko) Sep 2015 - Sep 2015 - 10. Anca Vamanu Sep 2009 - Sep 2009 - - All remaining contributors: Vladimir Romanov, Sergio Gutierrez, - Henning Westerholt (@henningw), Elena-Ramona Modroiu, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Sergey Khripchenko (@shripchenko), Razvan Crainea - (@razvancrainea), Walter Doekes (@wdoekes), Bogdan-Andrei Iancu - (@bogdan-iancu), Sergio Gutierrez, Henning Westerholt - (@henningw), Elena-Ramona Modroiu, Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2005-2009 Voice Sistem SRL diff --git a/modules/alias_db/README.md b/modules/alias_db/README.md new file mode 100644 index 00000000000..6cca672b5a7 --- /dev/null +++ b/modules/alias_db/README.md @@ -0,0 +1,277 @@ +--- +title: "ALIAS_DB Module" +description: "ALIAS_DB module can be used as an alternative for user aliases via usrloc. The main feature is that it does not store all adjacent data as for user location and always uses database for search (no memory caching)." +--- + +## Admin Guide + + +### Overview + + +ALIAS_DB module can be used as an alternative for user aliases +via usrloc. The main feature is that it does not store all adjacent +data as for user location and always uses database for search (no +memory caching). + + +Having no memory caching, search speed might decrease but +provisioning is easier. With very fast databases like MySQL, speed +penalty can be lowered. Also, search can be performed on different +tables in the same script. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *database module* (mysql, dbtext, ...). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (str) + + +Database URL. + + +*Default value is "mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("alias_db", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### user_column (str) + + +Name of the column storing username. + + +*Default value is "username".* + + +```opensips title="Set user_column parameter" +... +modparam("alias_db", "user_column", "susername") +... +``` + + +#### domain_column (str) + + +Name of the column storing user's domain. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("alias_db", "domain_column", "sdomain") +... +``` + + +#### alias_user_column (str) + + +Name of the column storing alias username. + + +*Default value is "alias_username".* + + +```opensips title="Set alias_user_column parameter" +... +modparam("alias_db", "alias_user_column", "auser") +... +``` + + +#### alias_domain_column (str) + + +Name of the column storing alias domain. + + +*Default value is "alias_domain".* + + +```opensips title="Set alias_domain_column parameter" +... +modparam("alias_db", "alias_domain_column", "adomain") +... +``` + + +#### domain_prefix (str) + + +Specifies the prefix to be stripped from the domain in R-URI before +doing the search. + + +*Default value is "NULL".* + + +```opensips title="Set domain_prefix parameter" +... +modparam("alias_db", "domain_prefix", "sip.") +... +``` + + +#### append_branches (int) + + +If the alias resolves to many SIP IDs, the first is replacing +the R-URI, the rest are added as branches. + + +*Default value is "0" (0 - don't add branches; +1 - add branches).* + + +```opensips title="Set append_branches parameter" +... +modparam("alias_db", "append_branches", 1) +... +``` + + +### Exported Functions + + +#### alias_db_lookup(table_name, [flags]) + + +The function takes the R-URI and search to see whether it is an alias +or not. If it is an alias for a local user, the R-URI is replaced with +user's SIP uri. + + +The function returns TRUE if R-URI is alias and it was replaced by +user's SIP uri. + + +Meaning of the parameters is as follows: + + +- *table_name (string)* - the name of the +table to search for the alias +- *flags (string, optional)* - set of +character flags to control the alias lookup process: + - **d** - do not use domain URI part in +the alias lookup query (use only a username-based lookup). By +default, both username and domain are used. + - **r** - do reverse alias lookup - lookup +for the alias mapped to the current URI (URI 2 alias +translation); normally, the function looks up for the URI +mapped to the alias (alias 2 URI translation). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="alias_db_lookup() usage" +... +alias_db_lookup("dbaliases", "rd"); +alias_db_lookup("dba_$(rU{s.substr,0,1})"); +... +``` + + +#### alias_db_find(table_name, input_uri, output_var, [flags]) + + +The function is very similar to `alias_db_lookup()`, +but instead of using fixed input (RURI) and output (RURI) is able to +get the input SIP URI from a pseudo-variable and place the result back +also in a pseudo-variable. + + +The function is useful as the alias lookup does not affect the request +itself (no RURI changes), can be used in a reply context (as it does +not work with RURI only) and can be used for others URI than the RURI +(To URI, From URI, custom URI). + + +The function returns TRUE if any alias mapping was found and returned. + + +Meaning of the parameters is as follows: + + +- *table_name (string)* - the name of the table to +search for the alias +- *input_uri (string)* - a SIP URI to look up +- *output_var (var)* - a variable to hold +the SIP URI result +- *flags (string, optional)* (optional) - set of flags +(char based flags) to control the alias lookup process: + + - *d* - do not use domain URI part in +the alias lookup query (use only a username-based lookup). By +default, both username and domain are used. + - *r* - do revers alias lookup - lookup +for the alias mapped to the current URI (URI 2 alias +translation); normally, the function looks up for the URI +mapped to the alias (alias 2 URI translation). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +LOCAL_ROUTE, STARTUP_ROUTE, FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="alias_db_find() usage" +... +# do revers alias lookup and find the alias for the FROM URI +alias_db_find("dbaliases", $fu, $avp(from_alias), "r"); +... +``` + + +## Frequently Asked Questions + + +**Q: What happened with old use_domain parameter** + + +The global parameter (affecting the entire module) was replaced +with a per lookup parameter (affecting only current lookup). +See the "d" (do not used domain part) flag in the db_alias_lookup() +and db_alias_find() functions. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/alias_db/doc/alias_db.xml b/modules/alias_db/doc/alias_db.xml deleted file mode 100644 index 7ab8be787d3..00000000000 --- a/modules/alias_db/doc/alias_db.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - ALIAS_DB Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2009 &voicesystem; - diff --git a/modules/alias_db/doc/alias_db_admin.xml b/modules/alias_db/doc/alias_db_admin.xml deleted file mode 100644 index 58d618cdba3..00000000000 --- a/modules/alias_db/doc/alias_db_admin.xml +++ /dev/null @@ -1,330 +0,0 @@ - - - - - &adminguide; - -
- Overview - - ALIAS_DB module can be used as an alternative for user aliases - via usrloc. The main feature is that it does not store all adjacent - data as for user location and always uses database for search (no - memory caching). - - - Having no memory caching, search speed might decrease but - provisioning is easier. With very fast databases like MySQL, speed - penalty can be lowered. Also, search can be performed on different - tables in the same script. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - database module (mysql, dbtext, ...). - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (str) - - Database URL. - - - - Default value is &defaultrodb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("alias_db", "db_url", "&exampledb;") -... - - -
- -
- <varname>user_column</varname> (str) - - Name of the column storing username. - - - - Default value is username. - - - - Set <varname>user_column</varname> parameter - -... -modparam("alias_db", "user_column", "susername") -... - - -
- -
- <varname>domain_column</varname> (str) - - Name of the column storing user's domain. - - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - -... -modparam("alias_db", "domain_column", "sdomain") -... - - -
- -
- <varname>alias_user_column</varname> (str) - - Name of the column storing alias username. - - - - Default value is alias_username. - - - - Set <varname>alias_user_column</varname> parameter - -... -modparam("alias_db", "alias_user_column", "auser") -... - - -
- -
- <varname>alias_domain_column</varname> (str) - - Name of the column storing alias domain. - - - - Default value is alias_domain. - - - - Set <varname>alias_domain_column</varname> parameter - -... -modparam("alias_db", "alias_domain_column", "adomain") -... - - -
- -
- <varname>domain_prefix</varname> (str) - - Specifies the prefix to be stripped from the domain in R-URI before - doing the search. - - - - Default value is NULL. - - - - Set <varname>domain_prefix</varname> parameter - -... -modparam("alias_db", "domain_prefix", "sip.") -... - - -
- -
- <varname>append_branches</varname> (int) - - If the alias resolves to many SIP IDs, the first is replacing - the R-URI, the rest are added as branches. - - - - Default value is 0 (0 - don't add branches; - 1 - add branches). - - - - Set <varname>append_branches</varname> parameter - -... -modparam("alias_db", "append_branches", 1) -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">alias_db_lookup(table_name, [flags])</function> - - - The function takes the R-URI and search to see whether it is an alias - or not. If it is an alias for a local user, the R-URI is replaced with - user's SIP uri. - - - The function returns TRUE if R-URI is alias and it was replaced by - user's SIP uri. - - Meaning of the parameters is as follows: - - - table_name (string) - the name of the - table to search for the alias - - - - flags (string, optional) - set of - character flags to control the alias lookup process: - - - - d - do not use domain URI part in - the alias lookup query (use only a username-based lookup). By - default, both username and domain are used. - - - - r - do reverse alias lookup - lookup - for the alias mapped to the current URI (URI 2 alias - translation); normally, the function looks up for the URI - mapped to the alias (alias 2 URI translation). - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>alias_db_lookup()</function> usage - -... -alias_db_lookup("dbaliases", "rd"); -alias_db_lookup("dba_$(rU{s.substr,0,1})"); -... - - -
- - -
- - <function moreinfo="none">alias_db_find(table_name, input_uri, output_var, [flags])</function> - - - The function is very similar to alias_db_lookup(), - but instead of using fixed input (RURI) and output (RURI) is able to - get the input SIP URI from a pseudo-variable and place the result back - also in a pseudo-variable. - - - The function is useful as the alias lookup does not affect the request - itself (no RURI changes), can be used in a reply context (as it does - not work with RURI only) and can be used for others URI than the RURI - (To URI, From URI, custom URI). - - - The function returns TRUE if any alias mapping was found and returned. - - Meaning of the parameters is as follows: - - - table_name (string) - the name of the table to - search for the alias - - - - input_uri (string) - a SIP URI to look up - - - - output_var (var) - a variable to hold - the SIP URI result - - - - flags (string, optional) (optional) - set of flags - (char based flags) to control the alias lookup process: - - - - d - do not use domain URI part in - the alias lookup query (use only a username-based lookup). By - default, both username and domain are used. - - - - r - do revers alias lookup - lookup - for the alias mapped to the current URI (URI 2 alias - translation); normally, the function looks up for the URI - mapped to the alias (alias 2 URI translation). - - - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - LOCAL_ROUTE, STARTUP_ROUTE, FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>alias_db_find()</function> usage - -... -# do revers alias lookup and find the alias for the FROM URI -alias_db_find("dbaliases", $fu, $avp(from_alias), "r"); -... - - -
- - -
-
- diff --git a/modules/alias_db/doc/alias_db_faq.xml b/modules/alias_db/doc/alias_db_faq.xml deleted file mode 100644 index d98ce1ae349..00000000000 --- a/modules/alias_db/doc/alias_db_faq.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - &faqguide; - - - - - What happened with old use_domain parameter - - - - The global parameter (affecting the entire module) was replaced - with a per lookup parameter (affecting only current lookup). - See the "d" (do not used domain part) flag in the db_alias_lookup() - and db_alias_find() functions. - - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - - diff --git a/modules/alias_db/doc/contributors.xml b/modules/alias_db/doc/contributors.xml deleted file mode 100644 index c396be3f4e5..00000000000 --- a/modules/alias_db/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 33 - 28 - 222 - 171 - - - 2. - Daniel-Constantin Mierla (@miconda) - 15 - 12 - 28 - 64 - - - 3. - Liviu Chircu (@liviuchircu) - 13 - 10 - 48 - 64 - - - 4. - Razvan Crainea (@razvancrainea) - 8 - 6 - 10 - 8 - - - 5. - Henning Westerholt (@henningw) - 6 - 4 - 48 - 49 - - - 6. - Elena-Ramona Modroiu - 5 - 3 - 92 - 39 - - - 7. - Walter Doekes (@wdoekes) - 5 - 3 - 7 - 7 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 5 - 2 - 38 - 88 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 5 - - - 10. - Vladimir Romanov - 4 - 1 - 227 - 51 - - - -
-All remaining contributors: Sergey Khripchenko (@shripchenko), Sergio Gutierrez, Konstantin Bokarius, Anca Vamanu, Dusan Klinec (@ph4r05), Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - May 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Walter Doekes (@wdoekes) - Apr 2010 - Apr 2021 - - - 5. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 9. - Sergey Khripchenko (@shripchenko) - Sep 2015 - Sep 2015 - - - 10. - Anca Vamanu - Sep 2009 - Sep 2009 - - - -
-All remaining contributors: Vladimir Romanov, Sergio Gutierrez, Henning Westerholt (@henningw), Elena-Ramona Modroiu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Sergey Khripchenko (@shripchenko), Razvan Crainea (@razvancrainea), Walter Doekes (@wdoekes), Bogdan-Andrei Iancu (@bogdan-iancu), Sergio Gutierrez, Henning Westerholt (@henningw), Elena-Ramona Modroiu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/auth/README b/modules/auth/README deleted file mode 100644 index 5583b7a0c99..00000000000 --- a/modules/auth/README +++ /dev/null @@ -1,597 +0,0 @@ -Auth Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. RFC 8760 Support (Strenghtened - Authentication) - - 1.2. Nonce Security - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. secret (string) - 1.4.2. nonce_expire (integer) - 1.4.3. rpid_prefix (string) - 1.4.4. rpid_suffix (string) - 1.4.5. realm_prefix (string) - 1.4.6. rpid_avp (string) - 1.4.7. username_spec (string) - 1.4.8. password_spec (string) - 1.4.9. calculate_ha1 (integer) - 1.4.10. disable_nonce_check (int) - - 1.5. Exported Functions - - 1.5.1. www_challenge(realm[, qop[, algorithms]]) - 1.5.2. proxy_challenge(realm[, qop[, algorithms]]) - 1.5.3. consume_credentials() - 1.5.4. is_rpid_user_e164() - 1.5.5. append_rpid_hf() - 1.5.6. append_rpid_hf(prefix, suffix) - 1.5.7. pv_www_authorize(realm) - 1.5.8. pv_proxy_authorize(realm) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. secret parameter example - 1.2. nonce_expire parameter example - 1.3. rpid_prefix parameter example - 1.4. rpid_suffix parameter example - 1.5. realm_prefix parameter example - 1.6. rpid_avp parameter example - 1.7. username_spec parameter usage - 1.8. password_spec parameter usage - 1.9. calculate_ha1 parameter usage - 1.10. disable_nonce_check parameter usage - 1.11. www_challenge usage - 1.12. proxy_challenge usage - 1.13. consume_credentials example - 1.14. is_rpid_user_e164 usage - 1.15. append_rpid_hf usage - 1.16. append_rpid_hf(prefix, suffix) usage - 1.17. pv_www_authorize usage - 1.18. pv_proxy_authorize usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module that provides common functions that are needed - by other authentication related modules. Also, it can perform - authentication taking username and password from - pseudo-variables. - -1.1.1. RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, auth_db and uac_auth - modules include support for two new digest authentication - algorithms ("SHA-256" and "SHA-512-256"), according to the RFC - 8760 specs. - -1.2. Nonce Security - - The authentication mechanism offers protection against sniffing - intrusion. The module generates and verifies the nonces so that - they can be used only once (in an auth response). This is done - by having a lifetime value and an index associated with every - nonce. Using only an expiration value is not good enough - because,as this value has to be of few tens of seconds, it is - possible for someone to sniff on the network, get the - credentials and then reuse them in another packet with which to - register a different contact or make calls using the others's - account. The index ensures that this will never be possible - since it is generated as unique through the lifetime of the - nonce. - - The default limit for the requests that can be authenticated is - 100000 in 30 seconds. If you wish to adjust this you can - decrease the lifetime of a nonce( how much time to wait for a - reply to a challenge). However, be aware not to set it to a too - smaller value. - - However this mechanism does not work for architectures using a - cluster of servers that share the same dns name for load - balancing. In this case you can disable the nonce reusability - check by setting the module parameter 'disable_nonce_check'. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * signaling -- Signaling module - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. secret (string) - - Secret phrase used to calculate the nonce value. Must be - exactly 32-character long. - - The default is to use a random value generated from the random - source in the core. - - If you use multiple servers in your installation, and would - like to authenticate on the second server against the nonce - generated at the first one its necessary to explicitly set the - secret to the same value on all servers. However, the use of a - shared (and fixed) secret as nonce is insecure, much better is - to stay with the default. Any clients should send the reply to - the server that issued the request. - - Example 1.1. secret parameter example -modparam("auth", "secret", "johndoessecretphrase") - -1.4.2. nonce_expire (integer) - - Nonces have limited lifetime. After a given period of time - nonces will be considered invalid. This is to protect replay - attacks. Credentials containing a stale nonce will be not - authorized, but the user agent will be challenged again. This - time the challenge will contain stale parameter which will - indicate to the client that it doesn't have to disturb user by - asking for username and password, it can recalculate - credentials using existing username and password. - - The value is in seconds and default value is 30 seconds. - - Example 1.2. nonce_expire parameter example -modparam("auth", "nonce_expire", 15) # Set nonce_expire to 15s - -1.4.3. rpid_prefix (string) - - Prefix to be added to Remote-Party-ID header field just before - the URI returned from either radius or database. - - Default value is “”. - - Example 1.3. rpid_prefix parameter example -modparam("auth", "rpid_prefix", "Whatever <") - -1.4.4. rpid_suffix (string) - - Suffix to be added to Remote-Party-ID header field after the - URI returned from either radius or database. - - Default value is - “;party=calling;id-type=subscriber;screen=yes”. - - Example 1.4. rpid_suffix parameter example -modparam("auth", "rpid_suffix", "@1.2.3.4>") - -1.4.5. realm_prefix (string) - - Prefix to be automatically strip from realm. As an alternative - to SRV records (not all SIP clients support SRV lookup), a - subdomain of the master domain can be defined for SIP purposes - (like sip.mydomain.net pointing to same IP address as the SRV - record for mydomain.net). By ignoring the realm_prefix “sip.”, - at authentication, sip.mydomain.net will be equivalent to - mydomain.net . - - Default value is empty string. - - Example 1.5. realm_prefix parameter example -modparam("auth", "realm_prefix", "sip.") - -1.4.6. rpid_avp (string) - - Full AVP specification for the AVP which stores the RPID value. - It used to transport the RPID value from authentication backend - modules (auth_db or auth_radius) or from script to the auth - function append_rpid_hf and is_rpid_user_e164. - - If defined to NULL string, all RPID functions will fail at - runtime. - - Default value is “$avp(rpid)”. - - Example 1.6. rpid_avp parameter example -modparam("auth", "rpid_avp", "$avp(caller_rpid)") - -1.4.7. username_spec (string) - - This name of the pseudo-variable that will hold the username. - - Default value is “NULL”. - - Example 1.7. username_spec parameter usage -modparam("auth", "username_spec", "$var(username)") - -1.4.8. password_spec (string) - - This name of the pseudo-variable that will hold the password. - - Default value is “NULL”. - - Example 1.8. password_spec parameter usage -modparam("auth", "password_spec", "$var(password)") - -1.4.9. calculate_ha1 (integer) - - This parameter tells the server whether it should expect - plaintext passwords in the pseudo-variable or a pre-calculated - HA1 string. - - If the parameter is set to 1 then the server will assume that - the “password_spec” pseudo-variable contains plaintext - passwords and it will calculate HA1 strings on the fly. If the - parameter is set to 0 then the server assumes the - pseudo-variable contains the HA1 strings directly and will not - calculate them. - - Default value of this parameter is 0. - - Example 1.9. calculate_ha1 parameter usage -modparam("auth", "calculate_ha1", 1) - -1.4.10. disable_nonce_check (int) - - By setting this parameter you disable the security mechanism - that protects against intrusion sniffing and does not allow - nonces to be reused. But, because of the current - implementation, having this enabled breaks auth for an - architecture where load is balanced by having more servers with - the same dns name. This parameter has to be set in this case. - - Default value is “0” (enabled). - - Example 1.10. disable_nonce_check parameter usage -modparam("auth", "disable_nonce_check", 1) - -1.5. Exported Functions - -1.5.1. www_challenge(realm[, qop[, algorithms]]) - - The function challenges a user agent. It will generate one or - more WWW-Authorize header fields containing a digest - challenges, it will put the header field(s) into a response - generated from the request the server is processing and will - send the reply. Upon reception of such a reply the user agent - should compute credentials and retry the request. For more - information regarding digest authentication see RFC2617, - RFC3261 and RFC8760. - - Meaning of the parameters is as follows: - * realm (string) - Realm is an opaque string that the user - agent should present to the user so it can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. In case of REGISTER request's To - header field, domain will be used (because this header - field represents a user being registered), for all other - messages From header field domain will be used. - * qop (string, optional) - Value of this parameter can be - either “auth”, “auth-int” or both (separated by ,). When - this parameter is set the server will put a qop parameter - in the challenge. It is recommended to use the qop - parameter, however there are still some user agents that - cannot handle qop properly so we made this optional. On the - other hand there are still some user agents that cannot - handle request without a qop parameter too. - Enabling this parameter does not improve security at the - moment, because the sequence number is not stored and - therefore could not be checked. Actually there is no - information kept by the module during the challenge and - response requests. - * algorithms (string, optional) - Value of this parameter is - a comma-separated list of digest algorithms to be offered - for the UAC to use for authentication. Possible values are: - + “MD5” - + “MD5-sess” - + “SHA-256” - + “SHA-256-sess” - + “SHA-512-256” - + “SHA-512-256-sess” - When the value is empty or not set, the only offered digest - algorithm is MD5, to provide compatibility with pre-RFC8760 - UAC implementations. - Values can be listed in any order. The actual order of - individual challenges in SIP response is defined by the - RFC8760: from stronger algorithm to a weaker one. - - This function can be used from REQUEST_ROUTE. - - Example 1.11. www_challenge usage -... -if (!www_authorize("siphub.net", "subscriber")) { - www_challenge("siphub.net", "auth,auth-int", "MD5,SHA-512-256"); -} -... - -1.5.2. proxy_challenge(realm[, qop[, algorithms]]) - - The function challenges a user agent. It will generate a - Proxy-Authorize header field containing a digest challenge, it - will put the header field into a response generated from the - request the server is processing and will send the reply. Upon - reception of such a reply the user agent should compute - credentials and retry the request. For more information - regarding digest authentication see RFC2617, RFC3261 and - RFC8760. - - See the paragraph on www_challenge() parameters meaning for the - description of the parameters. - - This function can be used from REQUEST_ROUTE. - - Example 1.12. proxy_challenge usage -... -$var(secure_algorithms) = "sha-256,sha-512-256"; -... -if (!proxy_authorize("", "subscriber")) { -... - proxy_challenge("", "auth", $var(secure_algorithms)); # Realm w -ill be autogenerated - # MD5 won -'t be allowed -} -... - -1.5.3. consume_credentials() - - This function removes previously authorized credentials from - the message being processed by the server. That means that the - downstream message will not contain credentials there were used - by this server. This ensures that the proxy will not reveal - information about credentials used to downstream elements and - also the message will be a little bit shorter. The function - must be called after www_authorize or proxy_authorize. - - This function can be used from REQUEST_ROUTE. - - Example 1.13. consume_credentials example -... -if (www_authorize("", "subscriber")) { - consume_credentials(); -} -... - -1.5.4. is_rpid_user_e164() - - The function checks if the SIP URI received from the database - or radius server and will potentially be used in - Remote-Party-ID header field contains an E164 number (+followed - by up to 15 decimal digits) in its user part. Check fails, if - no such SIP URI exists (i.e. radius server or database didn't - provide this information). - - This function can be used from REQUEST_ROUTE. - - Example 1.14. is_rpid_user_e164 usage -... -if (is_rpid_user_e164()) { - # do something here -} -... - -1.5.5. append_rpid_hf() - - Appends to the message a Remote-Party-ID header that contains - header 'Remote-Party-ID: ' followed by the saved value of the - SIP URI received from the database or radius server followed by - the value of module parameter radius_rpid_suffix. The function - does nothing if no saved SIP URI exists. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.15. append_rpid_hf usage -... -append_rpid_hf(); # Append Remote-Party-ID header field -... - -1.5.6. append_rpid_hf(prefix, suffix) - - This function is the same as append_rpid_hf(). The only - difference is that it accepts two parameters--prefix and suffix - to be added to Remote-Party-ID header field. This function - ignores rpid_prefix and rpid_suffix parameters, instead of that - allows to set them in every call. - - Meaning of the parameters is as follows: - * prefix (string) - Prefix of the Remote-Party-ID URI. The - string will be added at the beginning of body of the header - field, just before the URI. - * suffix (string) - Suffix of the Remote-Party-ID header - field. The string will be appended at the end of the header - field. It can be used to set various URI parameters, for - example. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.16. append_rpid_hf(prefix, suffix) usage -... -# Append Remote-Party-ID header field -append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes"); -... - -1.5.7. pv_www_authorize(realm) - - The function verifies credentials according to RFC2617. If the - credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked - credentials can be later used by some other functions). If the - function was unable to verify the credentials for some reason - then it will fail and the script should call www_challenge - which will challenge the user again. - - Negative codes may be interpreted as follows: - * -5 (generic error) - some generic error occurred and no - reply was sent out; - * -4 (no credentials) - credentials were not found in - request; - * -3 (stale nonce) - stale nonce; - * -2 (invalid password) - valid user, but wrong password; - * -1 (invalid user) - authentication user does not exist. - - Meaning of the parameters is as follows: - * realm (string) - Realm is an opaque string that the user - agent should present to the user so he can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. In case of REGISTER requests To header - field domain will be used (because this header field - represents a user being registered), for all other messages - From header field domain will be used. - - This function can be used from REQUEST_ROUTE. - - Example 1.17. pv_www_authorize usage -... -$var(username)="abc"; -$var(password)="xyz"; -if (!pv_www_authorize("opensips.org")) { - www_challenge("opensips.org", "auth"); -} -... - -1.5.8. pv_proxy_authorize(realm) - - The function verifies credentials according to RFC2617. If the - credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked - credentials can be later used by some other functions). If the - function was unable to verify the credentials for some reason - then it will fail and the script should call proxy_challenge - which will challenge the user again. For more about the - negative return codes, see the above function. - - Meaning of the parameters is as follows: - * realm (string) - Realm is an opaque string that the user - agent should present to the user so he can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. From header field domain will be used - as realm. - - This function can be used from REQUEST_ROUTE. - - Example 1.18. pv_proxy_authorize usage -... -$var(username)="abc"; -$var(password)="xyz"; -if (!pv_proxy_authorize("")) { - proxy_challenge("", "auth"); # Realm will be autogenerated -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jan Janak (@janakj) 273 107 7717 6060 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 51 34 704 615 - 3. Daniel-Constantin Mierla (@miconda) 39 21 1136 476 - 4. Maksym Sobolyev (@sobomax) 33 13 587 862 - 5. Liviu Chircu (@liviuchircu) 28 21 206 292 - 6. Jiri Kuthan (@jiriatipteldotorg) 26 19 660 51 - 7. Razvan Crainea (@razvancrainea) 18 13 212 169 - 8. Vlad Patrascu (@rvlad-patrascu) 18 10 420 236 - 9. Anca Vamanu 12 5 497 77 - 10. Henning Westerholt (@henningw) 11 8 107 100 - - All remaining contributors: Edson Gellert Schubert, Andrei - Pelinescu-Onciul, Juha Heinanen (@juha-h), Dan Pascu - (@danpascu), Zero King (@l2dy), Sergio Gutierrez, Anatoly - Pidruchny, Konstantin Bokarius, Vlad Paiu (@vladpaiu), Peter - Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Nils Ohlmeier, - Dusan Klinec (@ph4r05). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Razvan Crainea (@razvancrainea) Jun 2011 - Feb 2024 - 3. Maksym Sobolyev (@sobomax) Jan 2005 - Mar 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jun 2022 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2002 - Jan 2021 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 9. Walter Doekes (@wdoekes) Feb 2014 - Feb 2014 - 10. Vlad Paiu (@vladpaiu) Mar 2012 - Mar 2012 - - All remaining contributors: Sergio Gutierrez, Dan Pascu - (@danpascu), Anca Vamanu, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Juha Heinanen (@juha-h), Anatoly Pidruchny, Jan - Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Andrei - Pelinescu-Onciul, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Maksym Sobolyev (@sobomax), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Sergio Gutierrez, Dan Pascu (@danpascu), - Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2002-2003 FhG FOKUS diff --git a/modules/auth/README.md b/modules/auth/README.md new file mode 100644 index 00000000000..0e4073ffa59 --- /dev/null +++ b/modules/auth/README.md @@ -0,0 +1,571 @@ +--- +title: "Auth Module" +description: "This is a module that provides common functions that are needed by other authentication related modules." +--- + +## Admin Guide + + +### Overview + + +This is a module that provides common functions that are needed by +other authentication related modules. Also, it can perform +authentication taking username and password from pseudo-variables. + + +#### RFC 8760 Support (Strenghtened Authentication) + + +Starting with OpenSIPS 3.2, the [auth](../auth), +[auth_db](../auth_db) and +[uac_auth](../uac_auth) +modules include support for two new digest authentication algorithms +("SHA-256" and "SHA-512-256"), according to the +[RFC 8760](https://datatracker.ietf.org/doc/html/rfc8760) +specs. + + +### Nonce Security + + +The authentication mechanism offers protection against sniffing intrusion. +The module generates and verifies the nonces so that they can be used only +once (in an auth response). This is done +by having a lifetime value and an index associated with every nonce. +Using only an expiration value is not good enough because,as this value +has to be of few tens of seconds, it is possible for someone to sniff +on the network, get the credentials and then reuse them in another packet +with which to register a different contact or make calls using the others's +account. The index ensures that this will never be possible since it +is generated as unique through the lifetime of the nonce. + + +The default limit for the requests that can be authenticated is 100000 +in 30 seconds. +If you wish to adjust this you can decrease the lifetime of a nonce( +how much time to wait for a reply to a challenge). However, be aware not to +set it to a too smaller value. + + +However this mechanism does not work for architectures using a cluster +of servers that share the same dns name for load balancing. In this case +you can disable the nonce reusability check by setting the module parameter +'disable_nonce_check'. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *signaling* -- Signaling module + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### secret (string) + + +Secret phrase used to calculate the nonce value. +Must be exactly 32-character long. + + +The default is to use a random value generated from the random source in the core. + + +If you use multiple servers in your installation, and would like to authenticate +on the second server against the nonce generated at the first one its necessary +to explicitly set the secret to the same value on all servers. +However, the use of a shared (and fixed) secret as nonce is insecure, much better +is to stay with the default. Any clients should send the reply to the server that +issued the request. + + +```opensips title="secret parameter example" +modparam("auth", "secret", "johndoessecretphrase") +``` + + +#### nonce_expire (integer) + + +Nonces have limited lifetime. After a given period of time nonces +will be considered invalid. This is to protect replay attacks. +Credentials containing a stale nonce will be not authorized, but the +user agent will be challenged again. This time the challenge will +contain `stale` parameter which will indicate to the +client that it doesn't have to disturb user by asking for username +and password, it can recalculate credentials using existing username +and password. + + +The value is in seconds and default value is 30 seconds. + + +```opensips title="nonce_expire parameter example" +modparam("auth", "nonce_expire", 15) # Set nonce_expire to 15s +``` + + +#### rpid_prefix (string) + + +Prefix to be added to Remote-Party-ID header field just before +the URI returned from either radius or database. + + +Default value is "". + + +```opensips title="rpid_prefix parameter example" +modparam("auth", "rpid_prefix", "Whatever <") +``` + + +#### rpid_suffix (string) + + +Suffix to be added to Remote-Party-ID header field after the URI +returned from either radius or database. + + +Default value is +";party=calling;id-type=subscriber;screen=yes". + + +```opensips title="rpid_suffix parameter example" +modparam("auth", "rpid_suffix", "@1.2.3.4>") +``` + + +#### realm_prefix (string) + + +Prefix to be automatically strip from realm. As an alternative to +SRV records (not all SIP clients support SRV lookup), a subdomain +of the master domain can be defined for SIP purposes (like +sip.mydomain.net pointing to same IP address as the SRV +record for mydomain.net). By ignoring the realm_prefix +"sip.", at authentication, sip.mydomain.net will be +equivalent to mydomain.net . + + +Default value is empty string. + + +```opensips title="realm_prefix parameter example" +modparam("auth", "realm_prefix", "sip.") +``` + + +#### rpid_avp (string) + + +Full AVP specification for the AVP which +stores the RPID value. It used to transport the RPID value from +authentication backend modules (auth_db or auth_radius) or from +script to the auth function append_rpid_hf and is_rpid_user_e164. + + +If defined to NULL string, all RPID functions will fail at +runtime. + + +Default value is "$avp(rpid)". + + +```opensips title="rpid_avp parameter example" +modparam("auth", "rpid_avp", "$avp(caller_rpid)") + +``` + + +#### username_spec (string) + + +This name of the pseudo-variable that will hold the username. + + +Default value is "NULL". + + +```opensips title="username_spec parameter usage" +modparam("auth", "username_spec", "$var(username)") +``` + + +#### password_spec (string) + + +This name of the pseudo-variable that will hold the password. + + +Default value is "NULL". + + +```opensips title="password_spec parameter usage" +modparam("auth", "password_spec", "$var(password)") +``` + + +#### calculate_ha1 (integer) + + +This parameter tells the server whether it should expect plaintext +passwords in the pseudo-variable or a pre-calculated HA1 string. + + +If the parameter is set to 1 then the server will assume that the +"password_spec" pseudo-variable contains plaintext passwords +and it will calculate HA1 strings on the fly. If the parameter is set to 0 +then the server assumes the pseudo-variable contains the HA1 strings directly +and will not calculate them. + + +Default value of this parameter is 0. + + +```opensips title="calculate_ha1 parameter usage" +modparam("auth", "calculate_ha1", 1) +``` + + +#### disable_nonce_check (int) + + +By setting this parameter you disable the security mechanism +that protects against intrusion sniffing and does not allow +nonces to be reused. But, because of the current implementation, +having this enabled breaks auth for an architecture where load +is balanced by having more servers with the same dns name. +This parameter has to be set in this case. + + +Default value is "0" (enabled). + + +```opensips title="disable_nonce_check parameter usage" +modparam("auth", "disable_nonce_check", 1) +``` + + +### Exported Functions + + +#### www_challenge(realm[, qop[, algorithms]]) + + +The function challenges a user agent. It will generate one or +more WWW-Authorize header fields containing a digest challenges, it will +put the header field(s) into a response generated from the request the +server is processing and will send the reply. Upon reception of such a +reply the user agent should compute credentials and retry the +request. For more information regarding digest authentication +see RFC2617, RFC3261 and RFC8760. + + +Meaning of the parameters is as follows: + + +- *realm* (string) - Realm is an opaque string that +the user agent should present to the user so it can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. In case of REGISTER request's To +header field, domain will be used (because this header field +represents a user being registered), for all other messages From +header field domain will be used. +- *qop* (string, optional) - Value of this +parameter can be either "auth", "auth-int" +or both (separated by *,*). When this parameter is +set the server will put a qop parameter in the challenge. It +is recommended to use the qop parameter, however there are still some +user agents that cannot handle qop properly so we made this optional. +On the other hand there are still some user agents that cannot handle +request without a qop parameter too. +Enabling this parameter does not improve security at the moment, +because the sequence number is not stored and therefore could not be +checked. Actually there is no information kept by the module during +the challenge and response requests. +- *algorithms* (string, optional) - Value of this +parameter is a comma-separated list of digest algorithms to be offered for +the UAC to use for authentication. Possible values are: + + - MD5 + - MD5-sess + - SHA-256 + - SHA-256-sess + - SHA-512-256 + - SHA-512-256-sess +When the value is empty or not set, the only offered digest +algorithm is *MD5*, to provide compatibility +with pre-RFC8760 UAC implementations. +Values can be listed in any order. The actual order of individual +challenges in SIP response is defined by the RFC8760: from stronger +algorithm to a weaker one. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="www_challenge usage" +... +if (!www_authorize("siphub.net", "subscriber")) { + www_challenge("siphub.net", "auth,auth-int", "MD5,SHA-512-256"); +} +... +``` + + +#### proxy_challenge(realm[, qop[, algorithms]]) + + +The function challenges a user agent. It will generate a +Proxy-Authorize header field containing a digest challenge, it will +put the header field into a response generated from the request the +server is processing and will send the reply. Upon reception of such a +reply the user agent should compute credentials and retry the request. +For more information regarding digest authentication see RFC2617, +RFC3261 and RFC8760. + + +See the paragraph on [www challenge params](#www_challenge_params) for +the description of the parameters. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="proxy_challenge usage" +... +$var(secure_algorithms) = "sha-256,sha-512-256"; +... +if (!proxy_authorize("", "subscriber")) { +... + proxy_challenge("", "auth", $var(secure_algorithms)); # Realm will be autogenerated + # MD5 won't be allowed +} +... +``` + + +#### consume_credentials() + + +This function removes previously authorized credentials from the +message being processed by the server. That means that the downstream +message will not contain credentials there were used by this server. +This ensures that the proxy will not reveal information about +credentials used to downstream elements and also the message will be +a little bit shorter. The function must be called after +`www_authorize` or +`proxy_authorize`. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="consume_credentials example" +... +if (www_authorize("", "subscriber")) { + consume_credentials(); +} +... +``` + + +#### is_rpid_user_e164() + + +The function checks if the SIP URI received from the database or +radius server and will potentially be used in Remote-Party-ID header +field contains an E164 number (+followed by up to 15 decimal digits) +in its user part. Check fails, if no such SIP URI exists +(i.e. radius server or database didn't provide this information). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="is_rpid_user_e164 usage" +... +if (is_rpid_user_e164()) { + # do something here +} +... +``` + + +#### append_rpid_hf() + + +Appends to the message a Remote-Party-ID header that contains header +'Remote-Party-ID: ' followed by the saved value of the SIP URI +received from the database or radius server followed by the value of +module parameter radius_rpid_suffix. The function does nothing if +no saved SIP URI exists. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE. + + +```opensips title="append_rpid_hf usage" +... +append_rpid_hf(); # Append Remote-Party-ID header field +... +``` + + +#### append_rpid_hf(prefix, suffix) + + +This function is the same as +[append rpid hf no params](#func_append_rpid_hf). The only difference is +that it accepts two parameters--prefix and suffix to be added to +Remote-Party-ID header field. This function ignores rpid_prefix and +rpid_suffix parameters, instead of that allows to set them in every +call. + + +Meaning of the parameters is as follows: + + +- *prefix* (string) - Prefix of the +Remote-Party-ID URI. The string will be added at the beginning of +body of the header field, just before the URI. +- *suffix* (string) - Suffix of the Remote-Party-ID +header field. The string will be appended at the end of the +header field. It can be used to set various URI parameters, +for example. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE. + + +```opensips title="append_rpid_hf(prefix, suffix) usage" +... +# Append Remote-Party-ID header field +append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes"); +... +``` + + +#### pv_www_authorize(realm) + + +The function verifies credentials according to +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). If the +credentials are verified successfully then the function will succeed +and mark the credentials as authorized (marked credentials can be later +used by some other functions). If the function was unable to verify the +credentials for some reason then it will fail and the script should +call `www_challenge` which will +challenge the user again. + + +Negative codes may be interpreted as follows: + + +- *-5 (generic error)* - some generic error +occurred and no reply was sent out; +- *-4 (no credentials)* - credentials were not +found in request; +- *-3 (stale nonce)* - stale nonce; +- *-2 (invalid password)* - valid user, but +wrong password; +- *-1 (invalid user)* - authentication user does +not exist. + + +Meaning of the parameters is as follows: + + +- *realm* (string) - Realm is an opaque string that +the user agent should present to the user so he can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. In case of REGISTER requests To +header field domain will be used (because this header field +represents a user being registered), for all other messages From +header field domain will be used. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="pv_www_authorize usage" +... +$var(username)="abc"; +$var(password)="xyz"; +if (!pv_www_authorize("opensips.org")) { + www_challenge("opensips.org", "auth"); +} +... +``` + + +#### pv_proxy_authorize(realm) + + +The function verifies credentials according to +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). If +the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials can +be later used by some other functions). If the function was unable to +verify the credentials for some reason then it will fail and +the script should call +`proxy_challenge` which will +challenge the user again. For more about the negative return codes, +see the above function. + + +Meaning of the parameters is as follows: + + +- *realm* (string) - Realm is an opaque string that +the user agent should present to the user so he can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. From header field domain will be +used as realm. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="pv_proxy_authorize usage" +... +$var(username)="abc"; +$var(password)="xyz"; +if (!pv_proxy_authorize("")) { + proxy_challenge("", "auth"); # Realm will be autogenerated +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/auth/doc/auth.xml b/modules/auth/doc/auth.xml deleted file mode 100644 index 7ee842f6366..00000000000 --- a/modules/auth/doc/auth.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Auth Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005 &voicesystem; - ©right; 2002-2003 &fhg; - diff --git a/modules/auth/doc/auth_admin.xml b/modules/auth/doc/auth_admin.xml deleted file mode 100644 index 0f150d9c2a3..00000000000 --- a/modules/auth/doc/auth_admin.xml +++ /dev/null @@ -1,650 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module that provides common functions that are needed by - other authentication related modules. Also, it can perform - authentication taking username and password from pseudo-variables. - - -
- RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, - auth_db and - uac_auth - modules include support for two new digest authentication algorithms - ("SHA-256" and "SHA-512-256"), according to the - RFC 8760 - specs. - -
-
- -
- Nonce Security - - The authentication mechanism offers protection against sniffing intrusion. - The module generates and verifies the nonces so that they can be used only - once (in an auth response). This is done - by having a lifetime value and an index associated with every nonce. - Using only an expiration value is not good enough because,as this value - has to be of few tens of seconds, it is possible for someone to sniff - on the network, get the credentials and then reuse them in another packet - with which to register a different contact or make calls using the others's - account. The index ensures that this will never be possible since it - is generated as unique through the lifetime of the nonce. - - - The default limit for the requests that can be authenticated is 100000 - in 30 seconds. - If you wish to adjust this you can decrease the lifetime of a nonce( - how much time to wait for a reply to a challenge). However, be aware not to - set it to a too smaller value. - - - However this mechanism does not work for architectures using a cluster - of servers that share the same dns name for load balancing. In this case - you can disable the nonce reusability check by setting the module parameter - 'disable_nonce_check'. - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - signaling -- Signaling module - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - none - - -
-
- -
- Exported Parameters -
- <varname>secret</varname> (string) - - Secret phrase used to calculate the nonce value. - Must be exactly 32-character long. - - - The default is to use a random value generated from the random source in the core. - - - If you use multiple servers in your installation, and would like to authenticate - on the second server against the nonce generated at the first one its necessary - to explicitly set the secret to the same value on all servers. - However, the use of a shared (and fixed) secret as nonce is insecure, much better - is to stay with the default. Any clients should send the reply to the server that - issued the request. - - - secret parameter example - -modparam("auth", "secret", "johndoessecretphrase") - - -
- -
- <varname>nonce_expire</varname> (integer) - - Nonces have limited lifetime. After a given period of time nonces - will be considered invalid. This is to protect replay attacks. - Credentials containing a stale nonce will be not authorized, but the - user agent will be challenged again. This time the challenge will - contain stale parameter which will indicate to the - client that it doesn't have to disturb user by asking for username - and password, it can recalculate credentials using existing username - and password. - - - The value is in seconds and default value is 30 seconds. - - - nonce_expire parameter example - -modparam("auth", "nonce_expire", 15) # Set nonce_expire to 15s - - -
- -
- <varname>rpid_prefix</varname> (string) - - Prefix to be added to Remote-Party-ID header field just before - the URI returned from either radius or database. - - - Default value is . - - - rpid_prefix parameter example - -modparam("auth", "rpid_prefix", "Whatever <") - - -
- -
- <varname>rpid_suffix</varname> (string) - - Suffix to be added to Remote-Party-ID header field after the URI - returned from either radius or database. - - - Default value is - ;party=calling;id-type=subscriber;screen=yes. - - - rpid_suffix parameter example - -modparam("auth", "rpid_suffix", "@1.2.3.4>") - - -
- -
- <varname>realm_prefix</varname> (string) - - Prefix to be automatically strip from realm. As an alternative to - SRV records (not all SIP clients support SRV lookup), a subdomain - of the master domain can be defined for SIP purposes (like - sip.mydomain.net pointing to same IP address as the SRV - record for mydomain.net). By ignoring the realm_prefix - sip., at authentication, sip.mydomain.net will be - equivalent to mydomain.net . - - - Default value is empty string. - - - realm_prefix parameter example - -modparam("auth", "realm_prefix", "sip.") - - -
- -
- <varname>rpid_avp</varname> (string) - - Full AVP specification for the AVP which - stores the RPID value. It used to transport the RPID value from - authentication backend modules (auth_db or auth_radius) or from - script to the auth function append_rpid_hf and is_rpid_user_e164. - - - If defined to NULL string, all RPID functions will fail at - runtime. - - - Default value is $avp(rpid). - - - rpid_avp parameter example - -modparam("auth", "rpid_avp", "$avp(caller_rpid)") - - -
- -
- <varname>username_spec</varname> (string) - - This name of the pseudo-variable that will hold the username. - - - Default value is NULL. - - - <varname>username_spec</varname> parameter usage - -modparam("auth", "username_spec", "$var(username)") - - -
- -
- <varname>password_spec</varname> (string) - - This name of the pseudo-variable that will hold the password. - - - Default value is NULL. - - - <varname>password_spec</varname> parameter usage - -modparam("auth", "password_spec", "$var(password)") - - -
- -
- <varname>calculate_ha1</varname> (integer) - - This parameter tells the server whether it should expect plaintext - passwords in the pseudo-variable or a pre-calculated HA1 string. - - - If the parameter is set to 1 then the server will assume that the - password_spec pseudo-variable contains plaintext passwords - and it will calculate HA1 strings on the fly. If the parameter is set to 0 - then the server assumes the pseudo-variable contains the HA1 strings directly - and will not calculate them. - - - Default value of this parameter is 0. - - - <varname>calculate_ha1</varname> parameter usage - -modparam("auth", "calculate_ha1", 1) - - -
- -
- <varname>disable_nonce_check</varname> (int) - - By setting this parameter you disable the security mechanism - that protects against intrusion sniffing and does not allow - nonces to be reused. But, because of the current implementation, - having this enabled breaks auth for an architecture where load - is balanced by having more servers with the same dns name. - This parameter has to be set in this case. - - - Default value is 0 (enabled). - - - <varname>disable_nonce_check</varname> parameter usage - -modparam("auth", "disable_nonce_check", 1) - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">www_challenge(realm[, qop[, algorithms]])</function> - - - The function challenges a user agent. It will generate one or - more WWW-Authorize header fields containing a digest challenges, it will - put the header field(s) into a response generated from the request the - server is processing and will send the reply. Upon reception of such a - reply the user agent should compute credentials and retry the - request. For more information regarding digest authentication - see RFC2617, RFC3261 and RFC8760. - - - Meaning of the parameters is as follows: - - - realm (string) - Realm is an opaque string that - the user agent should present to the user so it can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. In case of REGISTER request's To - header field, domain will be used (because this header field - represents a user being registered), for all other messages From - header field domain will be used. - - - - qop (string, optional) - Value of this - parameter can be either auth, auth-int - or both (separated by ,). When this parameter is - set the server will put a qop parameter in the challenge. It - is recommended to use the qop parameter, however there are still some - user agents that cannot handle qop properly so we made this optional. - On the other hand there are still some user agents that cannot handle - request without a qop parameter too. - - Enabling this parameter does not improve security at the moment, - because the sequence number is not stored and therefore could not be - checked. Actually there is no information kept by the module during - the challenge and response requests. - - - - algorithms (string, optional) - Value of this - parameter is a comma-separated list of digest algorithms to be offered for - the UAC to use for authentication. Possible values are: - - MD5 - MD5-sess - SHA-256 - SHA-256-sess - SHA-512-256 - SHA-512-256-sess - - When the value is empty or not set, the only offered digest - algorithm is MD5, to provide compatibility - with pre-RFC8760 UAC implementations. - Values can be listed in any order. The actual order of individual - challenges in SIP response is defined by the RFC8760: from stronger - algorithm to a weaker one. - - - - This function can be used from REQUEST_ROUTE. - - - - www_challenge usage - -... -if (!www_authorize("siphub.net", "subscriber")) { - www_challenge("siphub.net", "auth,auth-int", "MD5,SHA-512-256"); -} -... - - -
- -
- - <function moreinfo="none">proxy_challenge(realm[, qop[, algorithms]])</function> - - - The function challenges a user agent. It will generate a - Proxy-Authorize header field containing a digest challenge, it will - put the header field into a response generated from the request the - server is processing and will send the reply. Upon reception of such a - reply the user agent should compute credentials and retry the request. - For more information regarding digest authentication see RFC2617, - RFC3261 and RFC8760. - - See the paragraph on for - the description of the parameters. - - This function can be used from REQUEST_ROUTE. - - - proxy_challenge usage - -... -$var(secure_algorithms) = "sha-256,sha-512-256"; -... -if (!proxy_authorize("", "subscriber")) { -... - proxy_challenge("", "auth", $var(secure_algorithms)); # Realm will be autogenerated - # MD5 won't be allowed -} -... - - -
-
- - <function moreinfo="none">consume_credentials()</function> - - - This function removes previously authorized credentials from the - message being processed by the server. That means that the downstream - message will not contain credentials there were used by this server. - This ensures that the proxy will not reveal information about - credentials used to downstream elements and also the message will be - a little bit shorter. The function must be called after - www_authorize or - proxy_authorize. - - - This function can be used from REQUEST_ROUTE. - - - consume_credentials example - -... -if (www_authorize("", "subscriber")) { - consume_credentials(); -} -... - - -
-
- - <function moreinfo="none">is_rpid_user_e164()</function> - - - The function checks if the SIP URI received from the database or - radius server and will potentially be used in Remote-Party-ID header - field contains an E164 number (+followed by up to 15 decimal digits) - in its user part. Check fails, if no such SIP URI exists - (i.e. radius server or database didn't provide this information). - - - This function can be used from REQUEST_ROUTE. - - - is_rpid_user_e164 usage - -... -if (is_rpid_user_e164()) { - # do something here -} -... - - -
-
- - <function moreinfo="none">append_rpid_hf()</function> - - Appends to the message a Remote-Party-ID header that contains header - 'Remote-Party-ID: ' followed by the saved value of the SIP URI - received from the database or radius server followed by the value of - module parameter radius_rpid_suffix. The function does nothing if - no saved SIP URI exists. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - - append_rpid_hf usage - -... -append_rpid_hf(); # Append Remote-Party-ID header field -... - - -
-
- - <function moreinfo="none">append_rpid_hf(prefix, suffix)</function> - - - This function is the same as - . The only difference is - that it accepts two parameters--prefix and suffix to be added to - Remote-Party-ID header field. This function ignores rpid_prefix and - rpid_suffix parameters, instead of that allows to set them in every - call. - - Meaning of the parameters is as follows: - - - prefix (string) - Prefix of the - Remote-Party-ID URI. The string will be added at the beginning of - body of the header field, just before the URI. - - - - suffix (string) - Suffix of the Remote-Party-ID - header field. The string will be appended at the end of the - header field. It can be used to set various URI parameters, - for example. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - - append_rpid_hf(prefix, suffix) usage - -... -# Append Remote-Party-ID header field -append_rpid_hf("", ";party=calling;id-type=subscriber;screen=yes"); -... - - -
-
- - <function moreinfo="none">pv_www_authorize(realm)</function> - - - The function verifies credentials according to - RFC2617. If the - credentials are verified successfully then the function will succeed - and mark the credentials as authorized (marked credentials can be later - used by some other functions). If the function was unable to verify the - credentials for some reason then it will fail and the script should - call www_challenge which will - challenge the user again. - - Negative codes may be interpreted as follows: - - - -5 (generic error) - some generic error - occurred and no reply was sent out; - - - -4 (no credentials) - credentials were not - found in request; - - - -3 (stale nonce) - stale nonce; - - - -2 (invalid password) - valid user, but - wrong password; - - - -1 (invalid user) - authentication user does - not exist. - - - Meaning of the parameters is as follows: - - - realm (string) - Realm is an opaque string that - the user agent should present to the user so he can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. In case of REGISTER requests To - header field domain will be used (because this header field - represents a user being registered), for all other messages From - header field domain will be used. - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">pv_www_authorize</function> - usage - -... -$var(username)="abc"; -$var(password)="xyz"; -if (!pv_www_authorize("opensips.org")) { - www_challenge("opensips.org", "auth"); -} -... - - -
- -
- - <function moreinfo="none">pv_proxy_authorize(realm)</function> - - - The function verifies credentials according to - RFC2617. If - the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials can - be later used by some other functions). If the function was unable to - verify the credentials for some reason then it will fail and - the script should call - proxy_challenge which will - challenge the user again. For more about the negative return codes, - see the above function. - - Meaning of the parameters is as follows: - - - realm (string) - Realm is an opaque string that - the user agent should present to the user so he can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. From header field domain will be - used as realm. - - - - - This function can be used from REQUEST_ROUTE. - - - pv_proxy_authorize usage - -... -$var(username)="abc"; -$var(password)="xyz"; -if (!pv_proxy_authorize("")) { - proxy_challenge("", "auth"); # Realm will be autogenerated -} -... - - -
- -
-
- diff --git a/modules/auth/doc/contributors.xml b/modules/auth/doc/contributors.xml deleted file mode 100644 index f6aa68e3765..00000000000 --- a/modules/auth/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jan Janak (@janakj) - 273 - 107 - 7717 - 6060 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 51 - 34 - 704 - 615 - - - 3. - Daniel-Constantin Mierla (@miconda) - 39 - 21 - 1136 - 476 - - - 4. - Maksym Sobolyev (@sobomax) - 33 - 13 - 587 - 862 - - - 5. - Liviu Chircu (@liviuchircu) - 28 - 21 - 206 - 292 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 26 - 19 - 660 - 51 - - - 7. - Razvan Crainea (@razvancrainea) - 18 - 13 - 212 - 169 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 18 - 10 - 420 - 236 - - - 9. - Anca Vamanu - 12 - 5 - 497 - 77 - - - 10. - Henning Westerholt (@henningw) - 11 - 8 - 107 - 100 - - - -
-All remaining contributors: Edson Gellert Schubert, Andrei Pelinescu-Onciul, Juha Heinanen (@juha-h), Dan Pascu (@danpascu), Zero King (@l2dy), Sergio Gutierrez, Anatoly Pidruchny, Konstantin Bokarius, Vlad Paiu (@vladpaiu), Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Nils Ohlmeier, Dusan Klinec (@ph4r05). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Jun 2011 - Feb 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2005 - Mar 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jun 2022 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2002 - Jan 2021 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 9. - Walter Doekes (@wdoekes) - Feb 2014 - Feb 2014 - - - 10. - Vlad Paiu (@vladpaiu) - Mar 2012 - Mar 2012 - - - -
-All remaining contributors: Sergio Gutierrez, Dan Pascu (@danpascu), Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Juha Heinanen (@juha-h), Anatoly Pidruchny, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Andrei Pelinescu-Onciul, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Maksym Sobolyev (@sobomax), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Sergio Gutierrez, Dan Pascu (@danpascu), Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jan Janak (@janakj). -
- -
diff --git a/modules/auth_aaa/README b/modules/auth_aaa/README deleted file mode 100644 index b650d599005..00000000000 --- a/modules/auth_aaa/README +++ /dev/null @@ -1,387 +0,0 @@ -Auth_aaa Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Additional Credentials - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. aaa_url (string) - 1.4.2. auth_service_type (integer) - 1.4.3. check_service_type (integer) - 1.4.4. use_ruri_flag (string) - - 1.5. Exported Functions - - 1.5.1. aaa_www_authorize(realm, [uri_user]) - 1.5.2. aaa_proxy_authorize(realm, [uri_user]) - 1.5.3. aaa_does_uri_exist([sip_uri]) - 1.5.4. aaa_does_uri_user_exist([sip_uri]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. “SIP-AVP” AAA AVP examples - 1.2. aaa_url parameter usage - 1.3. auth_service_type parameter usage - 1.4. Set check_service_type parameter - 1.5. use_ruri_flag parameter usage - 1.6. aaa_www_authorize usage - 1.7. proxy_authorize usage - 1.8. aaa_does_uri_exist usage - 1.9. aaa_does_uri_user_exist usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module contains functions that are used to perform digest - authentication and some URI checks against an AAA server. In - order to perform the authentication, the proxy will pass along - the credentials to the AAA server which will in turn send a - reply containing result of the authentication. So basically the - whole authentication is done in the AAA server. Before sending - the request to the AAA server we perform some sanity checks - over the credentials to make sure that only well formed - credentials will get to the server. - -1.2. Additional Credentials - - When performing authentication, the AAA server may include in - the response additional credentials. This scheme is very useful - in fetching additional user information from the AAA server - without making extra queries. - - The additional credentials are embedded in the AAA reply as - AVPs “SIP-AVP”. The syntax of the value is: - * value = SIP_AVP_NAME SIP_AVP_VALUE - * SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER - * SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE - - All additional credentials will be stored as OpenSIPS AVPs - (SIP_AVP_NAME = SIP_AVP_VALUE). - - The RPID value may be fetch via this mechanism. - - Example 1.1. “SIP-AVP” AAA AVP examples -.... -"email:joe@yahoo.com" - - STRING NAME AVP (email) with STRING VALUE (joe@yahoo.com) -"#14:joe@yahoo.com" - - ID AVP (14) with STRING VALUE (joe@yahoo.com) -"age#28" - - STRING NAME AVP (age) with INTEGER VALUE (28) -"#14#28" - - ID AVP (14) with INTEGER VALUE (28) -.... - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * auth -- Authentication framework, only if the auth - functions are used from script - * an aaa implementing module -- for example aaa_radius - -1.3.2. External Libraries or Applications - - This module does not depend on any external library. - -1.4. Exported Parameters - -1.4.1. aaa_url (string) - - This is the url representing the AAA protocol used and the - location of the configuration file of this protocol. - - The syntax for the url is the following: - "name_of_the_aaa_protocol_used:path_of_the_configuration_file" - - Example 1.2. aaa_url parameter usage - -modparam("auth_aaa", "aaa_url", "radius:/etc/radiusclient-ng/radiusclien -t.conf") - -1.4.2. auth_service_type (integer) - - This is the value of the Service-Type aaa attribute to be used - when performing an authentication operation. The default should - be fine for most people. See your aaa client include files for - numbers to be put in this parameter if you need to change it. - - Default value is “15”. - - Example 1.3. auth_service_type parameter usage - -modparam("auth_aaa", "auth_service_type", 15) - -1.4.3. check_service_type (integer) - - AAA service type used by aaa_does_uri_exist and - aaa_does_uri_user_exist checks. - - Default value is 10 (Call-Check). - - Example 1.4. Set check_service_type parameter -... -modparam("auth_aaa", "check_service_type", 11) -... - -1.4.4. use_ruri_flag (string) - - When this parameter is set to the value other than "NULL" and - the request being authenticated has flag with matching number - set via setflag() function, use Request URI instead of uri - parameter value from the Authorization / Proxy-Authorization - header field to perform AAA authentication. This is intended to - provide workaround for misbehaving NAT / routers / ALGs that - alter request in the transit, breaking authentication. At the - time of this writing, certain versions of Linksys WRT54GL are - known to do that. - - Default value is “NULL” (not set). - - Example 1.5. use_ruri_flag parameter usage - -modparam("auth_aaa", "use_ruri_flag", "USE_RURI_FLAG") - -1.5. Exported Functions - -1.5.1. aaa_www_authorize(realm, [uri_user]) - - The function verifies credentials according to RFC2617. If the - credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked - credentials can be later used by some other functions). If the - function was unable to verify the credentials for some reason - then it will fail and the script should call www_challenge - which will challenge the user again. - - Negative codes may be interpreted as follows: - * -5 (generic error) - some generic error occurred and no - reply was sent out; - * -4 (no credentials) - credentials were not found in - request; - * -3 (stale nonce) - stale nonce; - - This function will, in fact, perform sanity checks over the - received credentials and then pass them along to the aaa server - which will verify the credentials and return whether they are - valid or not. - - Meaning of the parameter is as follows: - * realm (string) - Realm is a opaque string that the user - agent should present to the user so he can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. In case of REGISTER requests To header - field domain will be used (because this header field - represents a user being registered), for all other messages - From header field domain will be used. - The string may contain pseudo variables. - * uri_user (string, optional) - value passed to the Radius - server as value of the SIP-URI-User check item. If this - parameter is not present, the server will generate the - SIP-URI-User check item value from the username part of the - To header field URI. - - This function can be used from REQUEST_ROUTE. - - Example 1.6. aaa_www_authorize usage - -... -if (!aaa_www_authorize("siphub.net")) - www_challenge("siphub.net", "auth"); -... - - -1.5.2. aaa_proxy_authorize(realm, [uri_user]) - - The function verifies credentials according to RFC2617. If the - credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked - credentials can be later used by some other functions). If the - function was unable to verify the credentials for some reason - then it will fail and the script should call proxy_challenge - which will challenge the user again. For more about the - negative return codes, see the above function. - - This function will, in fact, perform sanity checks over the - received credentials and then pass them along to the aaa server - which will verify the credentials and return whether they are - valid or not. - - Meaning of the parameters is as follows: - * realm (string) - Realm is a opaque string that the user - agent should present to the user so he can decide what - username and password to use. This is usually one of the - domains the proxy is responsible for. If an empty string “” - is used then the server will generate realm from host part - of From header field URI. - The string may contain pseudo variables. - * uri_user (string, optional) - value passed to the Radius - server as value of the SIP-URI-User check item. If this - parameter is not present, the server will generate the - SIP-URI-User check item value from the username part of the - To header field URI. - - This function can be used from REQUEST_ROUTE. - - Example 1.7. proxy_authorize usage - -... -if (!aaa_proxy_authorize("")) # Realm and URI user will be autogenera -ted - proxy_challenge("", "auth"); -... -if (!aaa_proxy_authorize($pd, $pU)) # Realm and URI user are taken - proxy_challenge($pd, "auth"); # from P-Preferred-Identity - # header field -... - - -1.5.3. aaa_does_uri_exist([sip_uri]) - - Checks from Radius if the SIP URI stored in the "sip_uri" - parameter (or user@host part of the Request-URI if "sip_uri" is - not given) belongs to a local user. Can be used to decide if - 404 or 480 should be returned after lookup has failed. If yes, - loads AVP based on SIP-AVP reply items returned from Radius. - Each SIP-AVP reply item must have a string value of form: - - * value = SIP_AVP_NAME SIP_AVP_VALUE - * SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER - * SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE - - Returns 1 if Radius returns Access-Accept, -1 if Radius returns - Access-Reject, and -2 in case of internal error. - - This function can be used from REQUEST_ROUTE. - - Example 1.8. aaa_does_uri_exist usage -... -if (aaa_does_uri_exist()) { - ... -}; -... - -1.5.4. aaa_does_uri_user_exist([sip_uri]) - - Similar to aaa_does_uri_exist, but check is done based only on - Request-URI user part or user stored in "sip_uri". The user - should thus be unique among all users, such as an E.164 number. - - This function can be used from REQUEST_ROUTE. - - Example 1.9. aaa_does_uri_user_exist usage -... -if (aaa_does_uri_user_exist()) { - ... -}; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jan Janak (@janakj) 89 24 3294 2182 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 44 31 892 255 - 3. Liviu Chircu (@liviuchircu) 25 21 101 145 - 4. Daniel-Constantin Mierla (@miconda) 15 13 67 55 - 5. Irina-Maria Stanescu 15 8 185 299 - 6. Maksym Sobolyev (@sobomax) 13 8 171 175 - 7. Razvan Crainea (@razvancrainea) 10 8 13 15 - 8. Juha Heinanen (@juha-h) 8 5 142 53 - 9. Andrei Pelinescu-Onciul 7 5 8 2 - 10. Vlad Patrascu (@rvlad-patrascu) 7 2 55 213 - - All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), - Henning Westerholt (@henningw), Ancuta Onofrei, Anatoly - Pidruchny, Peter Nixon, Konstantin Bokarius, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 2. Razvan Crainea (@razvancrainea) Feb 2012 - Jan 2024 - 3. Maksym Sobolyev (@sobomax) Dec 2003 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2005 - May 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Irina-Maria Stanescu Aug 2009 - Apr 2010 - 8. Daniel-Constantin Mierla (@miconda) Oct 2005 - Mar 2008 - 9. Konstantin Bokarius Mar 2008 - Mar 2008 - 10. Edson Gellert Schubert Feb 2008 - Feb 2008 - - All remaining contributors: Juha Heinanen (@juha-h), Henning - Westerholt (@henningw), Ancuta Onofrei, Anatoly Pidruchny, - Peter Nixon, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri - Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Razvan - Crainea (@razvancrainea), Irina-Maria Stanescu, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Maksym Sobolyev (@sobomax), Henning - Westerholt (@henningw), Anatoly Pidruchny, Juha Heinanen - (@juha-h), Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2005-2009 Voice Sistem SRL - - Copyright © 2002-2003 FhG FOKUS diff --git a/modules/auth_aaa/README.md b/modules/auth_aaa/README.md new file mode 100644 index 00000000000..e6deffd21d8 --- /dev/null +++ b/modules/auth_aaa/README.md @@ -0,0 +1,336 @@ +--- +title: "Auth_aaa Module" +description: "This module contains functions that are used to perform digest authentication and some URI checks against an AAA server." +--- + +## Admin Guide + + +### Overview + + +This module contains functions that are used to perform digest +authentication and some URI checks against an AAA server. +In order to perform the authentication, the proxy will pass along the +credentials to the AAA server which will in turn send a reply +containing result of the authentication. So basically the whole +authentication is done in the AAA server. Before sending the request +to the AAA server we perform some sanity checks over the +credentials to make sure that only well formed credentials will get to +the server. + + +### Additional Credentials + + +When performing authentication, the AAA server may include in the +response additional credentials. This scheme is very useful in fetching +additional user information from the AAA server without making +extra queries. + + +The additional credentials are embedded in the AAA reply as AVPs +"SIP-AVP". The syntax of the value is: + + +- *value = SIP_AVP_NAME SIP_AVP_VALUE* +- *SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER* +- *SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE* + + +All additional credentials will be stored as OpenSIPS AVPs +(SIP_AVP_NAME = SIP_AVP_VALUE). + + +The RPID value may be fetch via this mechanism. + + +```c title="'SIP-AVP' AAA AVP examples" +.... +"email:joe@yahoo.com" + - STRING NAME AVP (email) with STRING VALUE (joe@yahoo.com) +"#14:joe@yahoo.com" + - ID AVP (14) with STRING VALUE (joe@yahoo.com) +"age#28" + - STRING NAME AVP (age) with INTEGER VALUE (28) +"#14#28" + - ID AVP (14) with INTEGER VALUE (28) +.... + +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *auth* -- Authentication framework, +only if the auth functions are used from script +- *an aaa implementing module* -- for +example aaa_radius + + +#### External Libraries or Applications + + +This module does not depend on any external library. + + +### Exported Parameters + + +#### aaa_url (string) + + +This is the url representing the AAA protocol used and the location of the configuration file of this protocol. + + +The syntax for the url is the following: "name_of_the_aaa_protocol_used:path_of_the_configuration_file" + + +```opensips title="aaa_url parameter usage" + +modparam("auth_aaa", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") + +``` + + +#### auth_service_type (integer) + + +This is the value of the Service-Type aaa attribute to be used when +performing an authentication operation. +The default should be fine for most people. See your aaa client +include files for numbers to be put in this parameter if you need +to change it. + + +Default value is "15". + + +```opensips title="auth_service_type parameter usage" + +modparam("auth_aaa", "auth_service_type", 15) + +``` + + +#### check_service_type (integer) + + +AAA service type used by `aaa_does_uri_exist` and +`aaa_does_uri_user_exist` checks. + + +*Default value is 10 (Call-Check).* + + +```opensips title="Set check_service_type parameter" +... +modparam("auth_aaa", "check_service_type", 11) +... +``` + + +#### use_ruri_flag (string) + + +When this parameter is set to the value other than "NULL" and the +request being authenticated has flag with matching number set +via setflag() function, use Request URI instead of uri parameter +value from the Authorization / Proxy-Authorization header field +to perform AAA authentication. This is intended to provide +workaround for misbehaving NAT / routers / ALGs that alter request +in the transit, breaking authentication. At the time of this +writing, certain versions of Linksys WRT54GL are known to do that. + + +Default value is "NULL" (not set). + + +```opensips title="use_ruri_flag parameter usage" + +modparam("auth_aaa", "use_ruri_flag", "USE_RURI_FLAG") + +``` + + +### Exported Functions + + +#### aaa_www_authorize(realm, [uri_user]) + + +The function verifies credentials according to +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). If +the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials can +be later used by some other functions). If the function was unable to +verify the credentials for some reason then it will fail and +the script should call +`www_challenge` +which will challenge the user again. + + +Negative codes may be interpreted as follows: + + +- *-5 (generic error)* - some generic error +occurred and no reply was sent out; +- *-4 (no credentials)* - credentials were not +found in request; +- *-3 (stale nonce)* - stale nonce; + + +This function will, in fact, perform sanity checks over the received +credentials and then pass them along to the aaa server which will +verify the credentials and return whether they are valid or not. + + +Meaning of the parameter is as follows: + + +- *realm (string)* - Realm is a opaque string that +the user agent should present to the user so he can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. In case of REGISTER requests To +header field domain will be used (because this header field +represents a user being registered), for all other messages From +header field domain will be used. +The string may contain pseudo variables. +- *uri_user (string, optional)* - +value passed to the Radius server as value of the SIP-URI-User +check item. If this parameter is not present, the server will +generate the SIP-URI-User check item value from the username part +of the To header field URI. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aaa_www_authorize usage" + +... +if (!aaa_www_authorize("siphub.net")) + www_challenge("siphub.net", "auth"); +... +``` + + +#### aaa_proxy_authorize(realm, [uri_user]) + + +The function verifies credentials according to +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). If +the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials can +be later used by some other functions). If the function was unable to +verify the credentials for some reason then it will fail and the script +should call `proxy_challenge` which +will challenge the user again. For more about the negative return +codes, see the above function. + + +This function will, in fact, perform sanity checks over the received +credentials and then pass them along to the aaa server which will +verify the credentials and return whether they are valid or not. + + +Meaning of the parameters is as follows: + + +- *realm (string)* - Realm is a opaque string that +the user agent should present to the user so he can decide what +username and password to use. This is usually +one of the domains the proxy is responsible for. +If an empty string "" is used then the server will +generate realm from host part of From header field URI. +The string may contain pseudo variables. +- *uri_user (string, optional)* - +value passed to the Radius server as value of the SIP-URI-User +check item. If this parameter is not present, the server will +generate the SIP-URI-User check item value from the username part +of the To header field URI. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="proxy_authorize usage" + +... +if (!aaa_proxy_authorize("")) # Realm and URI user will be autogenerated + proxy_challenge("", "auth"); +... +if (!aaa_proxy_authorize($pd, $pU)) # Realm and URI user are taken + proxy_challenge($pd, "auth"); # from P-Preferred-Identity + # header field +... +``` + + +#### aaa_does_uri_exist([sip_uri]) + + +Checks from Radius if the SIP URI stored in the "sip_uri" parameter +(or user@host part of the Request-URI if "sip_uri" is not given) +belongs to a local user. Can be used to decide if 404 or 480 should +be returned after lookup has failed. If yes, loads AVP +based on SIP-AVP reply items returned from Radius. Each +SIP-AVP reply item must have a string value of form: + + +- *value = SIP_AVP_NAME SIP_AVP_VALUE* +- *SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER* +- *SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE* + + +Returns 1 if Radius returns Access-Accept, -1 if Radius +returns Access-Reject, and -2 in case of internal +error. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aaa_does_uri_exist usage" +... +if (aaa_does_uri_exist()) { + ... +}; +... +``` + + +#### aaa_does_uri_user_exist([sip_uri]) + + +Similar to aaa_does_uri_exist, but check is done +based only on Request-URI user part or user stored in "sip_uri". +The user should thus be unique among all users, such as an +E.164 number. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aaa_does_uri_user_exist usage" +... +if (aaa_does_uri_user_exist()) { + ... +}; +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/auth_aaa/doc/auth_aaa.xml b/modules/auth_aaa/doc/auth_aaa.xml deleted file mode 100644 index 4ddd9667f78..00000000000 --- a/modules/auth_aaa/doc/auth_aaa.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Auth_aaa Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2009 &voicesystem; - ©right; 2002-2003 &fhg; - diff --git a/modules/auth_aaa/doc/auth_aaa_admin.xml b/modules/auth_aaa/doc/auth_aaa_admin.xml deleted file mode 100644 index 8ceb6a73bd2..00000000000 --- a/modules/auth_aaa/doc/auth_aaa_admin.xml +++ /dev/null @@ -1,391 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module contains functions that are used to perform digest - authentication and some URI checks against an AAA server. - In order to perform the authentication, the proxy will pass along the - credentials to the AAA server which will in turn send a reply - containing result of the authentication. So basically the whole - authentication is done in the AAA server. Before sending the request - to the AAA server we perform some sanity checks over the - credentials to make sure that only well formed credentials will get to - the server. - -
-
- Additional Credentials - - When performing authentication, the AAA server may include in the - response additional credentials. This scheme is very useful in fetching - additional user information from the AAA server without making - extra queries. - - - The additional credentials are embedded in the AAA reply as AVPs - SIP-AVP. The syntax of the value is: - - - value = SIP_AVP_NAME SIP_AVP_VALUE - - - SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER - - - SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE - - - - - All additional credentials will be stored as &osips; AVPs - (SIP_AVP_NAME = SIP_AVP_VALUE). - - - The RPID value may be fetch via this mechanism. - - - <quote>SIP-AVP</quote> AAA AVP examples - -.... -"email:joe@yahoo.com" - - STRING NAME AVP (email) with STRING VALUE (joe@yahoo.com) -"#14:joe@yahoo.com" - - ID AVP (14) with STRING VALUE (joe@yahoo.com) -"age#28" - - STRING NAME AVP (age) with INTEGER VALUE (28) -"#14#28" - - ID AVP (14) with INTEGER VALUE (28) -.... - - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - auth -- Authentication framework, - only if the auth functions are used from script - - - an aaa implementing module -- for - example aaa_radius - - - -
-
- External Libraries or Applications - - This module does not depend on any external library. - -
-
- -
- Exported Parameters -
- <varname>aaa_url</varname> (string) - - This is the url representing the AAA protocol used and the location of the configuration file of this protocol. - - - The syntax for the url is the following: "name_of_the_aaa_protocol_used:path_of_the_configuration_file" - - - <varname>aaa_url</varname> parameter usage - - -modparam("auth_aaa", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") - - -
-
- <varname>auth_service_type</varname> (integer) - - This is the value of the Service-Type aaa attribute to be used when - performing an authentication operation. - The default should be fine for most people. See your aaa client - include files for numbers to be put in this parameter if you need - to change it. - - - Default value is 15. - - - <varname>auth_service_type</varname> parameter usage - - -modparam("auth_aaa", "auth_service_type", 15) - - -
- -
- <varname>check_service_type</varname> (integer) - - AAA service type used by aaa_does_uri_exist and - aaa_does_uri_user_exist checks. - - - - Default value is 10 (Call-Check). - - - - Set <varname>check_service_type</varname> parameter - -... -modparam("auth_aaa", "check_service_type", 11) -... - - -
- -
- <varname>use_ruri_flag</varname> (string) - - When this parameter is set to the value other than "NULL" and the - request being authenticated has flag with matching number set - via setflag() function, use Request URI instead of uri parameter - value from the Authorization / Proxy-Authorization header field - to perform AAA authentication. This is intended to provide - workaround for misbehaving NAT / routers / ALGs that alter request - in the transit, breaking authentication. At the time of this - writing, certain versions of Linksys WRT54GL are known to do that. - - - Default value is NULL (not set). - - - <varname>use_ruri_flag</varname> parameter usage - - -modparam("auth_aaa", "use_ruri_flag", "USE_RURI_FLAG") - - -
-
- -
- Exported Functions -
- <function moreinfo="none">aaa_www_authorize(realm, [uri_user])</function> - - The function verifies credentials according to - RFC2617. If - the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials can - be later used by some other functions). If the function was unable to - verify the credentials for some reason then it will fail and - the script should call - www_challenge - which will challenge the user again. - - Negative codes may be interpreted as follows: - - - -5 (generic error) - some generic error - occurred and no reply was sent out; - - - -4 (no credentials) - credentials were not - found in request; - - - -3 (stale nonce) - stale nonce; - - - - This function will, in fact, perform sanity checks over the received - credentials and then pass them along to the aaa server which will - verify the credentials and return whether they are valid or not. - - Meaning of the parameter is as follows: - - - realm (string) - Realm is a opaque string that - the user agent should present to the user so he can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. In case of REGISTER requests To - header field domain will be used (because this header field - represents a user being registered), for all other messages From - header field domain will be used. - - - The string may contain pseudo variables. - - - - uri_user (string, optional) - - value passed to the Radius server as value of the SIP-URI-User - check item. If this parameter is not present, the server will - generate the SIP-URI-User check item value from the username part - of the To header field URI. - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">aaa_www_authorize</function> usage - - -... -if (!aaa_www_authorize("siphub.net")) - www_challenge("siphub.net", "auth"); -... - - - -
- -
- <function moreinfo="none">aaa_proxy_authorize(realm, [uri_user])</function> - - The function verifies credentials according to - RFC2617. If - the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials can - be later used by some other functions). If the function was unable to - verify the credentials for some reason then it will fail and the script - should call proxy_challenge which - will challenge the user again. For more about the negative return - codes, see the above function. - - - This function will, in fact, perform sanity checks over the received - credentials and then pass them along to the aaa server which will - verify the credentials and return whether they are valid or not. - - Meaning of the parameters is as follows: - - - realm (string) - Realm is a opaque string that - the user agent should present to the user so he can decide what - username and password to use. This is usually - one of the domains the proxy is responsible for. - If an empty string is used then the server will - generate realm from host part of From header field URI. - - - The string may contain pseudo variables. - - - - uri_user (string, optional) - - value passed to the Radius server as value of the SIP-URI-User - check item. If this parameter is not present, the server will - generate the SIP-URI-User check item value from the username part - of the To header field URI. - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">proxy_authorize</function> usage - - -... -if (!aaa_proxy_authorize("")) # Realm and URI user will be autogenerated - proxy_challenge("", "auth"); -... -if (!aaa_proxy_authorize($pd, $pU)) # Realm and URI user are taken - proxy_challenge($pd, "auth"); # from P-Preferred-Identity - # header field -... - - - -
- -
- - <function moreinfo="none">aaa_does_uri_exist([sip_uri])</function> - - - Checks from Radius if the SIP URI stored in the "sip_uri" parameter - (or user@host part of the Request-&uri; if "sip_uri" is not given) - belongs to a local user. Can be used to decide if 404 or 480 should - be returned after lookup has failed. If yes, loads AVP - based on SIP-AVP reply items returned from Radius. Each - SIP-AVP reply item must have a string value of form: - - - - - value = SIP_AVP_NAME SIP_AVP_VALUE - - - SIP_AVP_NAME = STRING_NAME | '#'ID_NUMBER - - - SIP_AVP_VALUE = ':'STRING_VALUE | '#'NUMBER_VALUE - - - - - Returns 1 if Radius returns Access-Accept, -1 if Radius - returns Access-Reject, and -2 in case of internal - error. - - - This function can be used from REQUEST_ROUTE. - - - <function>aaa_does_uri_exist</function> usage - -... -if (aaa_does_uri_exist()) { - ... -}; -... - - -
- -
- - <function moreinfo="none">aaa_does_uri_user_exist([sip_uri])</function> - - - Similar to aaa_does_uri_exist, but check is done - based only on Request-URI user part or user stored in "sip_uri". - The user should thus be unique among all users, such as an - E.164 number. - - - This function can be used from REQUEST_ROUTE. - - - <function>aaa_does_uri_user_exist</function> usage - -... -if (aaa_does_uri_user_exist()) { - ... -}; -... - - -
- -
-
- diff --git a/modules/auth_aaa/doc/contributors.xml b/modules/auth_aaa/doc/contributors.xml deleted file mode 100644 index 47bc1d91ad5..00000000000 --- a/modules/auth_aaa/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jan Janak (@janakj) - 89 - 24 - 3294 - 2182 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 44 - 31 - 892 - 255 - - - 3. - Liviu Chircu (@liviuchircu) - 25 - 21 - 101 - 145 - - - 4. - Daniel-Constantin Mierla (@miconda) - 15 - 13 - 67 - 55 - - - 5. - Irina-Maria Stanescu - 15 - 8 - 185 - 299 - - - 6. - Maksym Sobolyev (@sobomax) - 13 - 8 - 171 - 175 - - - 7. - Razvan Crainea (@razvancrainea) - 10 - 8 - 13 - 15 - - - 8. - Juha Heinanen (@juha-h) - 8 - 5 - 142 - 53 - - - 9. - Andrei Pelinescu-Onciul - 7 - 5 - 8 - 2 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - 7 - 2 - 55 - 213 - - - -
-All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), Henning Westerholt (@henningw), Ancuta Onofrei, Anatoly Pidruchny, Peter Nixon, Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jan 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Dec 2003 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2005 - May 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Irina-Maria Stanescu - Aug 2009 - Apr 2010 - - - 8. - Daniel-Constantin Mierla (@miconda) - Oct 2005 - Mar 2008 - - - 9. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 10. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - -
-All remaining contributors: Juha Heinanen (@juha-h), Henning Westerholt (@henningw), Ancuta Onofrei, Anatoly Pidruchny, Peter Nixon, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Irina-Maria Stanescu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Maksym Sobolyev (@sobomax), Henning Westerholt (@henningw), Anatoly Pidruchny, Juha Heinanen (@juha-h), Jan Janak (@janakj). -
- -
diff --git a/modules/auth_aka/README b/modules/auth_aka/README deleted file mode 100644 index 335c535dadf..00000000000 --- a/modules/auth_aka/README +++ /dev/null @@ -1,695 +0,0 @@ -Auth_aka Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Authentication Vectors - 1.3. Supported algorithms - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. default_av_mgm (string) - 1.5.2. default_qop (string) - 1.5.3. default_algorithm (string) - 1.5.4. hash_size (integer) - 1.5.5. sync_timeout (integer) - 1.5.6. async_timeout (integer) - 1.5.7. unused_timeout (integer) - 1.5.8. unused_timeout (integer) - - 1.6. Exported Functions - - 1.6.1. aka_www_authorize([realm]]) - 1.6.2. aka_proxy_authorize([realm]]) - 1.6.3. aka_www_challenge([av_mgm[, realm[ ,qop[, - alg]]]]) - - 1.6.4. aka_proxy_challenge([realm]]) - 1.6.5. aka_av_add(public_identity, private_identity, - authenticate, authorize, - confidentiality_key, integrity_key[, - algorithms]) - - 1.6.6. aka_av_drop(public_identity, - private_identity, authenticate) - - 1.6.7. aka_av_drop_all(public_identity, - private_identity[, count]) - - 1.6.8. aka_av_fail(public_identity, - private_identity[, count]) - - 1.7. Exported MI Functions - - 1.7.1. aka_av_add - 1.7.2. aka_av_drop - 1.7.3. aka_av_drop_all - 1.7.4. aka_av_fail - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. default_av_mgm parameter usage - 1.2. default_qop parameter usage - 1.3. default_algorithm parameter usage - 1.4. hash_size parameter usage - 1.5. sync_timeout parameter usage - 1.6. async_timeout parameter usage - 1.7. unused_timeout parameter usage - 1.8. pending_timeout parameter usage - 1.9. aka_www_authorize usage - 1.10. aka_proxy_authorize usage - 1.11. aka_www_challenge usage - 1.12. aka_proxy_challenge usage - 1.13. aka_av_add usage - 1.14. aka_av_drop usage - 1.15. aka_av_drop_all usage - 1.16. aka_av_fail usage - 1.17. aka_av_add usage - 1.18. aka_av_drop usage - 1.19. aka_av_drop_all usage - 1.20. aka_av_drop usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module contains functions that are used to perform digest - authentication using the AKA (Authentication and Key Agreement) - security protocol. This mechanism is being used in IMS networks - to provide mutual authentication between the UE (device) and - the 3G/4G/5G network. - - The AKA protocol establishes a set of security keys, called - authentication vectors (or AVs), and uses them to generate the - digest challenge, as well as for computing the digest result - and authenticating the UE. AVs are exchanged over a separate - communication channel. - - Although the AKA protocol also requires to use the AVs to - establish a secure channel between the UE and the network (by - means of IPSec tunnels), this module does not handle that part - - it just performs the authentication of the user and passes - along the cyphering and integrity keys in the Authorization - header, according to the ETSI TS 129 229 specifications. These - are later on picked up by other components (such as P-CSCFs) to - establish the secure channel. - -1.2. Authentication Vectors - - Authentication Vectors (or AVs) consist of a set of five - parameter (RAND, AUTN, XRES, CK, IK) that are being used for - mutual authentication. As these need to be exchanged between - the device (UE) and network through a different channel (i.e. - Diameter Cx interface in LTE networks), the module does not - provide any means to fetch the AV information. It does, - however, provide a generic interface (called AV Manage - Interface) to store AVs (that are being fetched by other - modules/channels), manage them and use them in the digest - authentication algorithm. - - Basic AV operations that the module performs: - * Ask for a new AV to be fetched for a specific user identity - * Manage an AV lifetime, including reuses - * Mark an AV as being used in a digest challeng - * Invalidate or discard an AV (due to various reasons) - - A module that implements the AV Manage Interface (called AV - Manager) should be able to fetch all five parameters of an AV, - and push them in the AV Storage. - -1.3. Supported algorithms - - The current implementation only supports the AKAv1 algorithms, - with the associated hashing functions (such as MD5, SHA-256). - In the challenge message, we send, one can advertise other - algorithms as well, but the response cannot be handled by this - module, and an appropriate error will be returned. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * auth -- Authentication framework - * AV manage module -- at least one module that fetches AVs - and pushes them in the AV storage - -1.4.2. External Libraries or Applications - - This module does not depend on any external library. - -1.5. Exported Parameters - -1.5.1. default_av_mgm (string) - - The default AV Manager used in case the functions do not - provide them explicitly. - - Example 1.1. default_av_mgm parameter usage - -modparam("auth_aka", "default_av_mgm", "diameter") # fetch AVs through t -he Cx interface - -1.5.2. default_qop (string) - - The default qop parameter used during challenge, if the - functions do not provide them explicitly. - - Default value is auth. - - Example 1.2. default_qop parameter usage - -modparam("auth_aka", "default_qop", "auth,auth-int") - -1.5.3. default_algorithm (string) - - The default algorithm to be advertise during challenge, if the - functions do not provide them explicitly. Note that at least - one of the algorithms provided should be an AKA one, otherwise - it makes no sense to use this module. - - Default value is AKAv1-MD5. - - WARNING: only AKAv1* algorithms are currently supported. - - Example 1.3. default_algorithm parameter usage - -modparam("auth_aka", "default_algorithm", "AKAv2-MD5") - -1.5.4. hash_size (integer) - - The size of the hash that stores the AVs for each user. Must be - a power of 2 number. - - Default value is 4096. - - Example 1.4. hash_size parameter usage - -modparam("auth_aka", "hash_size", 1024) - -1.5.5. sync_timeout (integer) - - The amount of milliseconds a synchronous call should wait for - getting an authentication vector. - - Must be a positive value. A value of 0 indicates to wait - indefinitely. - - Default value is 100 ms. - - Example 1.5. sync_timeout parameter usage - -modparam("auth_aka", "sync_timeout", 200) - -1.5.6. async_timeout (integer) - - The amount of milliseconds an asynchronous call should wait for - getting an authentication vector. - - Must be a positive value, greater than 0. - - NOTE: the current timeout mechanism only has seconds - granularity, therefore you should configure this parameter as a - multiple of 1000. - - Default value is 1000 ms. - - Example 1.6. async_timeout parameter usage - -modparam("auth_aka", "async_timeout", 2000) - -1.5.7. unused_timeout (integer) - - The amount of seconds an authentication vector that has not - been used can stay in memory. Once this timeout is reached, the - authentication vector is removed. - - Must be a positive value, greater than 0. - - Default value is 60 s. - - Example 1.7. unused_timeout parameter usage - -modparam("auth_aka", "unused_timeout", 120) - -1.5.8. unused_timeout (integer) - - The amount of seconds an authentication vector that is being - used in the authentication process shall stay in memory. Once - this timeout is reached, the authentication vector is removed, - and the authentication using it will fail. - - Must be a positive value, greater than 0. - - Default value is 30 s. - - Example 1.8. pending_timeout parameter usage - -modparam("auth_aka", "pending_timeout", 10) - -1.6. Exported Functions - -1.6.1. aka_www_authorize([realm]]) - - The function verifies credentials according to RFC3310, by - using an authentication vector priorly allocated by an - aka_www_challenge() call, using the av_mgm manager. If the - credentials are verified successfully the function will - succeed, otherwise it will fail with an appropriate error code, - as follows: - * -6 (sync request) - the auts parameter was was present, - thus a sync was requested; - * -5 (generic error) - some generic error occurred and no - reply was sent out; - * -4 (no credentials) - credentials were not found in - request; - * -3 (unknown nonce) - authentication vector with the - corresponding nonce was not found; - * -2 (invalid password) - password does not match the - authentication vector; - * -1 (invalid username) - no username found in the Authorize - header; - - In case the function succeeds, the WWW-Authenticate header is - being added to the reply, containing the challenge information, - as well as the Integrity-Key and the Confidentiality-Key values - associated to the AV being used. - - Meaning of the parameters is as follows: - * realm (string) - Realm is a opaque string that the user - agent should present to the user so he can decide what - username and password to use. This is usually one of the - domains the proxy is responsible for. If an empty string “” - is used then the server will generate realm from host part - of From header field URI. - - If the credentials are verified successfully then the function - will succeed and mark the credentials as authorized (marked - credentials can be later used by some other functions). - - This function can be used from REQUEST_ROUTE. - - Example 1.9. aka_www_authorize usage - -... -if (!aka_www_authorize("diameter", "siphub.com")) - aka_www_challenge("diameter", "siphub.com", "auth"); -... - - -1.6.2. aka_proxy_authorize([realm]]) - - The function behaves the same as aka_www_authorize(), but it - authenticates the user from a proxy perspective. It receives - the same parameters, with the same meaning, and returns the - same values. - - This function can be used from REQUEST_ROUTE. - - Example 1.10. aka_proxy_authorize usage - -... -if (!aka_proxy_authorize("siphub.com")) - aka_proxy_challenge("diameter", "siphub.com", "auth"); -... - - -1.6.3. aka_www_challenge([av_mgm[, realm[ ,qop[, alg]]]]) - - The function challenges a user agent. It fetches an - authentication vector for each algorigthm used through the - av_mgm Manager and generate one or more WWW-Authenticate header - fields containing digest challenges. It will put the header - field(s) into a response generated from the request the server - is processing and will send the reply. Upon reception of such a - reply the user agent should compute credentials using the used - authentication vector annd retry the request. For more - information regarding digest authentication see RFC2617, - RFC3261, RFC3310 and RFC8760. - - Meaning of the parameters is as follows: - * av_mgm (string, optional) - the AV Manager to be used for - this challenge, in case an AV is not already available for - the challenged user identity. In case it is missing the - value of the default_av_mgm is being used. - realm (string) - Realm is an opaque string that the user - agent should present to the user so it can decide what - username and password to use. Usually this is domain of the - host the server is running on. If missing, the value of the - From domain is being used. - * qop (string, optional) - Value of this parameter can be - either “auth”, “auth-int” or both (separated by ,). When - this parameter is set the server will put a qop parameter - in the challenge. It is recommended to use the qop - parameter, however there are still some user agents that - cannot handle qop properly so we made this optional. On the - other hand there are still some user agents that cannot - handle request without a qop parameter too. If missing, the - value of the default_qop is being used. - * algorithms (string, optional) - Value of this parameter is - a comma-separated list of digest algorithms to be offered - for the UAC to use for authentication. Possible values are: - + “AKAv1-MD5” - + “AKAv1-MD5-sess” - + “AKAv1-SHA-256” - + “AKAv1-SHA-256-sess” - + “AKAv1-SHA-512-256” - + “AKAv1-SHA-512-256-sess” - + “AKAv2-MD5” - + “AKAv2-MD5-sess” - + “AKAv2-SHA-256” - + “AKAv2-SHA-256-sess” - + “AKAv2-SHA-512-256” - + “AKAv2-SHA-512-256-sess” - When the value is empty or not set, the only offered digest - the value of the default_algorithm is being used. - - Possible return codes: - * -1 - generic parsing error, generated when there is not - enoough data to build the challange - * -2 - no AV vector could not be fetched - * -3 - authentication headers could not be built - * -5 - a reply could not be sent - * positive - the number of successful chalanges being sent in - the reply; this value can be lower than the number of - algorithms being requested in case there was a timeout - waiting for some AVs. - - This function can be used from REQUEST_ROUTE. - - Example 1.11. aka_www_challenge usage -... -if (!aka_www_authorize("siphub.com")) { - aka_www_challenge(,"siphub.com", "auth-int", "AKAv1-MD5"); -} -... - -1.6.4. aka_proxy_challenge([realm]]) - - The function behaves the same as aka_www_challenge(), but it - challenges the user from a proxy perspective. It receives the - same parameters, with the same meaning, the only difference - being that in case of the realm is missing, then it is taken - from the the To domain, rather than from From domain. The - header added is Proxy-Authenticate, rather than - WWW-Authenticate The rest of the parameters, behavior, as well - as return values are the same. - - This function can be used from REQUEST_ROUTE. - - Example 1.12. aka_proxy_challenge usage - -... -if (!aka_proxy_authorize("siphub.com")) - aka_proxy_challenge(,"siphub.com", "auth"); -... - - -1.6.5. aka_av_add(public_identity, private_identity, authenticate, -authorize, confidentiality_key, integrity_key[, algorithms]) - - Adds an authentication vector for the user identitied by - public_identity and private_identity. - - Meaning of the parameters is as follows: - * public_identity (string) - the public identity (IMPU) of - the user to add authentication vector for. - * private_identity (string) - the private identity (IMPI) of - the user to add authentication vector for. - * authenticate (string) - the concatenation of the - authentication challenge RAND and the token AUTN, encoded - in hexa format. - * authorize (string) - the authorization string (XRES) used - for authorizing the user, encoded in hexa format. - * confidentiality_key (string) - the Confidentiality-Key used - in the AKA IPSec process, encoded in hexa format. - * integrity_key (string) - the Integrity-Key used in the AKA - IPSec process, encoded in hexa format. - * algorithms (string, optional) - AKA algorithms this AV - should be used for. If missing, the AV can be used for any - AKA algorithm. - - This function can be used from any route. - - Example 1.13. aka_av_add usage - -... -aka_av_add("sip:test@siphub.com", "test@siphub.com", - "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4=", -/* authenticate */ - "00000262c0000014000028af2d6398cbe26eea69", /* a -uthorize */ - "db7f8c4a58e17083974bba3b936d34c4", /* ck */ - "6151667b9ef815c1dcb87473685f062a" /* ik */); -... - -1.6.6. aka_av_drop(public_identity, private_identity, authenticate) - - Drops the authentication vector corresponding to the - authenticate/nonce value for an user identitied by - public_identity and private_identity. - - Meaning of the parameters is as follows: - * public_identity (string) - the public identity (IMPU) of - the user to drop authentication vector for. - * private_identity (string) - the private identity (IMPI) of - the user to drop authentication vector for. - * authenticate (string) - the authenticate/nonce that - identifies the authentication vector to be dropped. - - This function can be used from any route. - - Example 1.14. aka_av_drop usage - -... -aka_av_drop("sip:test@siphub.com", "test@siphub.com", - "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4="); -... - -1.6.7. aka_av_drop_all(public_identity, private_identity[, count]) - - Drops all authentication vectors for an user identitied by - public_identity and private_identity. This function is useful - when a synchronization must be done. - - Meaning of the parameters is as follows: - * public_identity (string) - the public identity (IMPU) of - the user to drop authentication vectors for. - * private_identity (string) - the private identity (IMPI) of - the user to drop authentication vectors for. - * count (variable, optional) - a variable to return the - number of authentication vectors dropped. - - This function can be used from any route. - - Example 1.15. aka_av_drop_all usage - -... -aka_av_drop_all("sip:test@siphub.com", "test@siphub.com", $var(count)); -... - -1.6.8. aka_av_fail(public_identity, private_identity[, count]) - - Marks the engine that an authentication vector query for a user - has failed, unlocking the processing of the message. - - Note: this function is useful when you know that fetching a new - authentication vector is not possible (due to various reasons) - - calling it will resume the message procesing, using only the - available AVs fetched so far. - - Meaning of the parameters is as follows: - * public_identity (string) - the public identity (IMPU) of - the user to drop authentication vectors for. - * private_identity (string) - the private identity (IMPI) of - the user to drop authentication vectors for. - * count (integer, optional) - the number of authentication - vectors that failed. If missing, 1 is considered. - - This function can be used from any route. - - Example 1.16. aka_av_fail usage -... -aka_av_fail("sip:test@siphub.com", "test@siphub.com", 3); -... - -1.7. Exported MI Functions - -1.7.1. aka_av_add - - Adds an Authentication Vector through the MI interface. - - Parameters: - * public_identity (string) - the public identity (IMPU) of - the user to add authentication vector for. - * private_identity (string) - the private identity (IMPI) of - the user to add authentication vector for. - * authenticate (string) - the concatenation of the - authentication challenge RAND and the token AUTN, encoded - in hexa format. - * authorize (string) - the authorization string (XRES) used - for authorizing the user, encoded in hexa format. - * confidentiality_key (string) - the Confidentiality-Key used - in the AKA IPSec process, encoded in hexa format. - * integrity_key (string) - the Integrity-Key used in the AKA - IPSec process, encoded in hexa format. - * algorithms (string, optional) - AKA algorithms this AV - should be used for. If missing, the AV can be used for any - AKA algorithm. - - Example 1.17. aka_av_add usage -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_add \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sI -JI4= - 00000262c0000014000028af2d6398cbe26eea69 - db7f8c4a58e17083974bba3b936d34c4 - 6151667b9ef815c1dcb87473685f062a -... - -1.7.2. aka_av_drop - - Invalidates an Authentication Vector of an user identified by - its authenticate value. - - Parameters: - * public_identity (string) - the public identity (IMPU) of - the user to add authentication vector for. - * private_identity (string) - the private identity (IMPI) of - the user to add authentication vector for. - * authenticate (string) - the authenticate/nonce to indentify - the authentication vector. - - Example 1.18. aka_av_drop usage -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sI -JI4= -... - -1.7.3. aka_av_drop_all - - Invalidates all Authentication Vectors of an user through the - MI interface. - - Parameters: - * public_identity (string) - the public identity (IMPU) of - the user to drop authentication vectors for. - * private_identity (string) - the private identity (IMPI) of - the user to drop authentication vectors for. - - Example 1.19. aka_av_drop_all usage -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop_all \ - sip:test@siphub.com - test@siphub.com -... - -1.7.4. aka_av_fail - - Indicates the fact that the fetching of an authentication - vector has failed, unlocking the processing of the message. - - Note: this function is useful when you know that fetching a new - authentication vector is not possible (due to various reasons) - - calling it will resume the message procesing, using only the - available AVs fetched so far. - - Parameters: - * public_identity (string) - the public identity (IMPU) of - the user to add authentication vector for. - * private_identity (string) - the private identity (IMPI) of - the user to add authentication vector for. - * count (integer, optional) - the number of authentication - vectors failures. - - Example 1.20. aka_av_drop usage -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sI -JI4= -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 54 20 3378 295 - 2. Alexandra Titoc 4 2 2 2 - 3. LarryLaffer-dev 3 1 26 1 - 4. Liviu Chircu (@liviuchircu) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Feb 2024 - Jul 2025 - 2. LarryLaffer-dev Mar 2025 - Mar 2025 - 3. Liviu Chircu (@liviuchircu) Sep 2024 - Sep 2024 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Solutions; diff --git a/modules/auth_aka/README.md b/modules/auth_aka/README.md new file mode 100644 index 00000000000..fa342930fed --- /dev/null +++ b/modules/auth_aka/README.md @@ -0,0 +1,730 @@ +--- +title: "AUTH AKA Module" +description: "This module contains functions that are used to perform digest authentication using the AKA (Authentication and Key Agreement) security protocol. This mechanism is being used in IMS networks to provide mutual authentication between the UE (device) and the 3G/4G/5G network." +--- + +## Admin Guide + + +### Overview + + +This module contains functions that are used to perform digest +authentication using the AKA (Authentication and Key Agreement) +security protocol. This mechanism is being used in IMS networks to +provide mutual authentication between the UE (device) and the 3G/4G/5G +network. + + +The AKA protocol establishes a set of security keys, called +authentication vectors (or AVs), and uses them to generate the digest +challenge, as well as for computing the digest result and authenticating +the UE. AVs are exchanged over a separate communication channel. + + +Although the AKA protocol also requires to use the AVs to establish a +secure channel between the UE and the network (by means of IPSec +tunnels), this module does not handle that part - it just performs the +authentication of the user and passes along the cyphering and +integrity keys in the Authorization header, according to +the *ETSI TS 129 229* specifications. These are later +on picked up by other components (such as P-CSCFs) to establish the +secure channel. + + +### Authentication Vectors + + +Authentication Vectors (or AVs) consist of a set of five parameter +(RAND, AUTN, XRES, CK, IK) that are being used for mutual +authentication. As these need to be exchanged between the device (UE) +and network through a different channel (i.e. Diameter Cx interface in +LTE networks), the module does not provide any means to fetch the AV +information. It does, however, provide a generic interface (called AV +Manage Interface) to store AVs (that are being fetched by other +modules/channels), manage them and use them in the digest +authentication algorithm. + + +Basic AV operations that the module performs: + + +- Ask for a new AV to be fetched for a specific user identity +- Manage an AV lifetime, including reuses +- Mark an AV as being used in a digest challeng +- Invalidate or discard an AV (due to various reasons) + + +A module that implements the AV Manage Interface (called AV Manager) +should be able to fetch all five parameters of an AV, and push them in +the AV Storage. + + +### Supported algorithms + + +The current implementation only supports the AKAv1 algorithms, with +the associated hashing functions (such as MD5, SHA-256). In the +challenge message, we send, one can advertise other algorithms as well, +but the response cannot be handled by this module, and an appropriate +error will be returned. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *auth* -- Authentication framework +- *AV manage module* +-- at least one module that fetches AVs and pushes +them in the AV storage + + +#### External Libraries or Applications + + +This module does not depend on any external library. + + +### Exported Parameters + + +#### default_av_mgm (string) + + +The default AV Manager used in case the functions do not provide them explicitly. + + +```opensips title="default_av_mgm parameter usage" + +modparam("auth_aka", "default_av_mgm", "diameter") # fetch AVs through the Cx interface + +``` + + +#### default_qop (string) + + +The default qop parameter used during challenge, if the functions +do not provide them explicitly. + + +Default value is *auth*. + + +```opensips title="default_qop parameter usage" + +modparam("auth_aka", "default_qop", "auth,auth-int") + +``` + + +#### default_algorithm (string) + + +The default algorithm to be advertise during challenge, if the +functions do not provide them explicitly. +> [!NOTE] +> That at least one of the algorithms provided should be an AKA +> one, otherwise it makes no sense to use this module. + + +Default value is *AKAv1-MD5*. + + +> [!WARNING] +> Only AKAv1-* algorithms are currently supported. + + +```opensips title="default_algorithm parameter usage" + +modparam("auth_aka", "default_algorithm", "AKAv2-MD5") + +``` + + +#### hash_size (integer) + + +The size of the hash that stores the AVs for each user. +Must be a power of 2 number. + + +Default value is *4096*. + + +```opensips title="hash_size parameter usage" + +modparam("auth_aka", "hash_size", 1024) + +``` + + +#### sync_timeout (integer) + + +The amount of milliseconds a synchronous call should +wait for getting an authentication vector. + + +Must be a positive value. A value of +*0* indicates to wait indefinitely. + + +Default value is *100* ms. + + +```opensips title="sync_timeout parameter usage" + +modparam("auth_aka", "sync_timeout", 200) + +``` + + +#### async_timeout (integer) + + +The amount of milliseconds an asynchronous call should +wait for getting an authentication vector. + + +Must be a positive value, greater than 0. + + +> [!NOTE] +> The current timeout mechanism only +> has seconds granularity, therefore you should configure this +> parameter as a multiple of 1000. + + +Default value is *1000* ms. + + +```opensips title="async_timeout parameter usage" +modparam("auth_aka", "async_timeout", 2000) + +``` + + +#### unused_timeout (integer) + + +The amount of seconds an authentication vector that has +not been used can stay in memory. Once this timeout is +reached, the authentication vector is removed. + + +Must be a positive value, greater than 0. + + +Default value is *60* s. + + +```opensips title="unused_timeout parameter usage" +modparam("auth_aka", "unused_timeout", 120) + +``` + + +#### unused_timeout (integer) + + +The amount of seconds an authentication vector that is being +used in the authentication process shall stay in memory. +Once this timeout is reached, the authentication vector is +removed, and the authentication using it will fail. + + +Must be a positive value, greater than 0. + + +Default value is *30* s. + + +```opensips title="pending_timeout parameter usage" +modparam("auth_aka", "pending_timeout", 10) + +``` + + +### Exported Functions + + +#### aka_www_authorize([realm]]) + + +The function verifies credentials according to +[RFC3310](http://www.ietf.org/rfc/rfc3310.txt), by using +an authentication vector priorly allocated by an +`aka_www_challenge()` call, using +the *av_mgm* manager. If the credentials are +verified successfully the function will succeed, otherwise it will fail with +an appropriate error code, as follows: + + +- *-6 (sync request)* - the *auts* +parameter was was present, thus a sync was requested; +- *-5 (generic error)* - some generic error +occurred and no reply was sent out; +- *-4 (no credentials)* - credentials were not +found in request; +- *-3 (unknown nonce)* - authentication vector +with the corresponding nonce was not found; +- *-2 (invalid password)* - password does not +match the authentication vector; +- *-1 (invalid username)* - no username found +in the Authorize header; + + +In case the function succeeds, the *WWW-Authenticate* +header is being added to the reply, containing the challenge information, +as well as the *Integrity-Key* and the +*Confidentiality-Key* values associated to the +AV being used. + + +Meaning of the parameters is as follows: + + +- *realm (string)* - Realm is a opaque string that +the user agent should present to the user so he can decide what +username and password to use. This is usually +one of the domains the proxy is responsible for. +If an empty string "" is used then the server will +generate realm from host part of From header field URI. + + +If the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials +can be later used by some other functions). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aka_www_authorize usage" + +... +if (!aka_www_authorize("diameter", "siphub.com")) + aka_www_challenge("diameter", "siphub.com", "auth"); +... +``` + + +#### aka_proxy_authorize([realm]]) + + +The function behaves the same as [aka www authorize](#func_aka_www_authorize), +but it authenticates the user from a proxy perspective. It receives the same +parameters, with the same meaning, and returns the same values. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aka_proxy_authorize usage" + +... +if (!aka_proxy_authorize("siphub.com")) + aka_proxy_challenge("diameter", "siphub.com", "auth"); +... +``` + + +#### aka_www_challenge([av_mgm[, realm[ ,qop[, alg]]]]) + + +The function challenges a user agent. It fetches an authentication +vector for each algorigthm used through the +*av_mgm* Manager and generate one or more +WWW-Authenticate header fields containing digest challenges. It will +put the header field(s) into a response generated from the request the +server is processing and will send the reply. Upon reception of such a +reply the user agent should compute credentials using the used +authentication vector annd retry the request. +For more information regarding digest authentication +see RFC2617, RFC3261, RFC3310 and RFC8760. + + +Meaning of the parameters is as follows: + + +- *av_mgm* (string, optional) - the AV Manager +to be used for this challenge, in case an AV is not already available +for the challenged user identity. In case it is missing the value of the +[default av mgm](#param_default_av_mgm) is being used. +*realm* (string) - Realm is an opaque string that +the user agent should present to the user so it can decide what +username and password to use. Usually this is domain of the host +the server is running on. If missing, the value of the +*From domain* is being used. +- *qop* (string, optional) - Value of this +parameter can be either "auth", "auth-int" +or both (separated by *,*). When this parameter is +set the server will put a qop parameter in the challenge. It +is recommended to use the qop parameter, however there are still some +user agents that cannot handle qop properly so we made this optional. +On the other hand there are still some user agents that cannot handle +request without a qop parameter too. If missing, the value of the +[default qop](#param_default_qop) is being used. +- *algorithms* (string, optional) - Value of this +parameter is a comma-separated list of digest algorithms to be offered for +the UAC to use for authentication. Possible values are: + + - AKAv1-MD5 + - AKAv1-MD5-sess + - AKAv1-SHA-256 + - AKAv1-SHA-256-sess + - AKAv1-SHA-512-256 + - AKAv1-SHA-512-256-sess + - AKAv2-MD5 + - AKAv2-MD5-sess + - AKAv2-SHA-256 + - AKAv2-SHA-256-sess + - AKAv2-SHA-512-256 + - AKAv2-SHA-512-256-sess +When the value is empty or not set, the only offered digest +the value of the [default algorithm](#param_default_algorithm) is being used. + + +Possible return codes: + + +- *-1* - generic parsing error, generated +when there is not enoough data to build the challange +- *-2* - no AV vector could not be fetched +- *-3* - authentication headers could not +be built +- *-5* - a reply could not be sent +- *positive* - the number of successful +chalanges being sent in the reply; this value can be lower than +the number of algorithms being requested in case there was a +timeout waiting for some AVs. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aka_www_challenge usage" +... +if (!aka_www_authorize("siphub.com")) { + aka_www_challenge(,"siphub.com", "auth-int", "AKAv1-MD5"); +} +... +``` + + +#### aka_proxy_challenge([realm]]) + + +The function behaves the same as [aka www challenge](#func_aka_www_challenge), +but it challenges the user from a proxy perspective. It receives the same +parameters, with the same meaning, the only difference being that in case of +the *realm* is missing, then it is taken from the +the *To domain*, rather than from +*From domain*. The header added is +*Proxy-Authenticate*, rather than +*WWW-Authenticate* The rest of the parameters, behavior, +as well as return values are the same. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aka_proxy_challenge usage" + +... +if (!aka_proxy_authorize("siphub.com")) + aka_proxy_challenge(,"siphub.com", "auth"); +... +``` + + +#### aka_av_add(public_identity, private_identity, authenticate, authorize, confidentiality_key, integrity_key[, algorithms]) + + +Adds an authentication vector for the user identitied by +*public_identity* and +*private_identity*. + + +Meaning of the parameters is as follows: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to add authentication vector for. +- *private_identity* (string) - the private identity +(IMPI) of the user to add authentication vector for. +- *authenticate* (string) - the concatenation of the +authentication challenge RAND and the token AUTN, encoded in hexa format. +- *authorize* (string) - the authorization string +(XRES) used for authorizing the user, encoded in hexa format. +- *confidentiality_key* (string) - the Confidentiality-Key +used in the AKA IPSec process, encoded in hexa format. +- *integrity_key* (string) - the Integrity-Key +used in the AKA IPSec process, encoded in hexa format. +- *algorithms* (string, optional) - AKA algorithms +this AV should be used for. If missing, the AV can be used for any AKA +algorithm. + + +This function can be used from any route. + + +```c title="aka_av_add usage" + +... +aka_av_add("sip:test@siphub.com", "test@siphub.com", + "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4=", /* authenticate */ + "00000262c0000014000028af2d6398cbe26eea69", /* authorize */ + "db7f8c4a58e17083974bba3b936d34c4", /* ck */ + "6151667b9ef815c1dcb87473685f062a" /* ik */); +... +``` + + +#### aka_av_drop(public_identity, private_identity, authenticate) + + +Drops the authentication vector corresponding to the +*authenticate/nonce* value +for an user identitied by +*public_identity* and +*private_identity*. + + +Meaning of the parameters is as follows: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to drop authentication vector for. +- *private_identity* (string) - the private identity +(IMPI) of the user to drop authentication vector for. +- *authenticate* (string) - the authenticate/nonce +that identifies the authentication vector to be dropped. + + +This function can be used from any route. + + +```c title="aka_av_drop usage" + +... +aka_av_drop("sip:test@siphub.com", "test@siphub.com", + "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4="); +... +``` + + +#### aka_av_drop_all(public_identity, private_identity[, count]) + + +Drops all authentication vectors for an user identitied by +*public_identity* and +*private_identity*. This function is useful +when a synchronization must be done. + + +Meaning of the parameters is as follows: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to drop authentication vectors for. +- *private_identity* (string) - the private identity +(IMPI) of the user to drop authentication vectors for. +- *count* (variable, optional) - a variable to return the number +of authentication vectors dropped. + + +This function can be used from any route. + + +```opensips title="aka_av_drop_all usage" + +... +aka_av_drop_all("sip:test@siphub.com", "test@siphub.com", $var(count)); +... +``` + + +#### aka_av_fail(public_identity, private_identity[, count]) + + +Marks the engine that an authentication vector query for a user has +failed, unlocking the processing of the message. + + +*Note:* this function is useful when you +know that fetching a new authentication vector is not possible +(due to various reasons) - calling it will resume the message +procesing, using only the available AVs fetched so far. + + +Meaning of the parameters is as follows: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to drop authentication vectors for. +- *private_identity* (string) - the private identity +(IMPI) of the user to drop authentication vectors for. +- *count* (integer, optional) - the number of +authentication vectors that failed. If missing, +*1* is considered. + + +This function can be used from any route. + + +```opensips title="aka_av_fail usage" +... +aka_av_fail("sip:test@siphub.com", "test@siphub.com", 3); +... +``` + + +### Exported MI Functions + + +#### aka_av_add + + +Adds an Authentication Vector through the MI interface. + + +Parameters: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to add authentication vector for. +- *private_identity* (string) - the private identity +(IMPI) of the user to add authentication vector for. +- *authenticate* (string) - the concatenation of the +authentication challenge RAND and the token AUTN, encoded in hexa format. +- *authorize* (string) - the authorization string +(XRES) used for authorizing the user, encoded in hexa format. +- *confidentiality_key* (string) - the Confidentiality-Key +used in the AKA IPSec process, encoded in hexa format. +- *integrity_key* (string) - the Integrity-Key +used in the AKA IPSec process, encoded in hexa format. +- *algorithms* (string, optional) - AKA algorithms +this AV should be used for. If missing, the AV can be used for any AKA +algorithm. + + +```bash title="aka_av_add usage" +... +## adds an AKA AV +$ opensips-cli -x mi aka_av_add \ + sip:test@siphub.com + test@siphub.com + KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= + 00000262c0000014000028af2d6398cbe26eea69 + db7f8c4a58e17083974bba3b936d34c4 + 6151667b9ef815c1dcb87473685f062a +... + +``` + + +#### aka_av_drop + + +Invalidates an Authentication Vector of an user identified +by its authenticate value. + + +Parameters: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to add authentication vector for. +- *private_identity* (string) - the private identity +(IMPI) of the user to add authentication vector for. +- *authenticate* (string) - the authenticate/nonce +to indentify the authentication vector. + + +```bash title="aka_av_drop usage" +... +## adds an AKA AV +$ opensips-cli -x mi aka_av_drop \ + sip:test@siphub.com + test@siphub.com + KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= +... + +``` + + +#### aka_av_drop_all + + +Invalidates all Authentication Vectors of an user through the +MI interface. + + +Parameters: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to drop authentication vectors for. +- *private_identity* (string) - the private identity +(IMPI) of the user to drop authentication vectors for. + + +```bash title="aka_av_drop_all usage" +... +## adds an AKA AV +$ opensips-cli -x mi aka_av_drop_all \ + sip:test@siphub.com + test@siphub.com +... + +``` + + +#### aka_av_fail + + +Indicates the fact that the fetching of an authentication +vector has failed, unlocking the processing of the message. + + +*Note:* this function is useful when you +know that fetching a new authentication vector is not possible +(due to various reasons) - calling it will resume the message +procesing, using only the available AVs fetched so far. + + +Parameters: + + +- *public_identity* (string) - the public identity +(IMPU) of the user to add authentication vector for. +- *private_identity* (string) - the private identity +(IMPI) of the user to add authentication vector for. +- *count* (integer, optional) - the number of +authentication vectors failures. + + +```bash title="aka_av_drop usage" +... +## adds an AKA AV +$ opensips-cli -x mi aka_av_drop \ + sip:test@siphub.com + test@siphub.com + KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/auth_aka/doc/auth_aka.xml b/modules/auth_aka/doc/auth_aka.xml deleted file mode 100644 index 3260f43f58d..00000000000 --- a/modules/auth_aka/doc/auth_aka.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Auth_aka Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Solutions; - diff --git a/modules/auth_aka/doc/auth_aka_admin.xml b/modules/auth_aka/doc/auth_aka_admin.xml deleted file mode 100644 index d17081c4355..00000000000 --- a/modules/auth_aka/doc/auth_aka_admin.xml +++ /dev/null @@ -1,858 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module contains functions that are used to perform digest - authentication using the AKA (Authentication and Key Agreement) - security protocol. This mechanism is being used in IMS networks to - provide mutual authentication between the UE (device) and the 3G/4G/5G - network. - - - The AKA protocol establishes a set of security keys, called - authentication vectors (or AVs), and uses them to generate the digest - challenge, as well as for computing the digest result and authenticating - the UE. AVs are exchanged over a separate communication channel. - - - Although the AKA protocol also requires to use the AVs to establish a - secure channel between the UE and the network (by means of IPSec - tunnels), this module does not handle that part - it just performs the - authentication of the user and passes along the cyphering and - integrity keys in the Authorization header, according to - the ETSI TS 129 229 specifications. These are later - on picked up by other components (such as P-CSCFs) to establish the - secure channel. - -
-
- Authentication Vectors - - Authentication Vectors (or AVs) consist of a set of five parameter - (RAND, AUTN, XRES, CK, IK) that are being used for mutual - authentication. As these need to be exchanged between the device (UE) - and network through a different channel (i.e. Diameter Cx interface in - LTE networks), the module does not provide any means to fetch the AV - information. It does, however, provide a generic interface (called AV - Manage Interface) to store AVs (that are being fetched by other - modules/channels), manage them and use them in the digest - authentication algorithm. - - - Basic AV operations that the module performs: - - - Ask for a new AV to be fetched for a specific user identity - - - Manage an AV lifetime, including reuses - - - Mark an AV as being used in a digest challeng - - - Invalidate or discard an AV (due to various reasons) - - - - - A module that implements the AV Manage Interface (called AV Manager) - should be able to fetch all five parameters of an AV, and push them in - the AV Storage. - -
-
- Supported algorithms - - The current implementation only supports the AKAv1 algorithms, with - the associated hashing functions (such as MD5, SHA-256). In the - challenge message, we send, one can advertise other algorithms as well, - but the response cannot be handled by this module, and an appropriate - error will be returned. - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - auth -- Authentication framework - - - - AV manage module - -- at least one module that fetches AVs and pushes - them in the AV storage - - - - -
-
- External Libraries or Applications - - This module does not depend on any external library. - -
-
- -
- Exported Parameters -
- <varname>default_av_mgm</varname> (string) - - The default AV Manager used in case the functions do not provide them explicitly. - - - <varname>default_av_mgm</varname> parameter usage - - -modparam("auth_aka", "default_av_mgm", "diameter") # fetch AVs through the Cx interface - - -
-
- <varname>default_qop</varname> (string) - - The default qop parameter used during challenge, if the functions - do not provide them explicitly. - - - Default value is auth. - - - <varname>default_qop</varname> parameter usage - - -modparam("auth_aka", "default_qop", "auth,auth-int") - - -
-
- <varname>default_algorithm</varname> (string) - - The default algorithm to be advertise during challenge, if the - functions do not provide them explicitly. - Note - that at least one of the algorithms provided should be an AKA - one, otherwise it makes no sense to use this module. - - - Default value is AKAv1-MD5. - - - WARNING: only AKAv1* algorithms are currently supported. - - - <varname>default_algorithm</varname> parameter usage - - -modparam("auth_aka", "default_algorithm", "AKAv2-MD5") - - -
-
- <varname>hash_size</varname> (integer) - - The size of the hash that stores the AVs for each user. - Must be a power of 2 number. - - - Default value is 4096. - - - <varname>hash_size</varname> parameter usage - - -modparam("auth_aka", "hash_size", 1024) - - -
-
- <varname>sync_timeout</varname> (integer) - - The amount of milliseconds a synchronous call should - wait for getting an authentication vector. - - - Must be a positive value. A value of - 0 indicates to wait indefinitely. - - - Default value is 100 ms. - - - <varname>sync_timeout</varname> parameter usage - - -modparam("auth_aka", "sync_timeout", 200) - - -
-
- <varname>async_timeout</varname> (integer) - - The amount of milliseconds an asynchronous call should - wait for getting an authentication vector. - - - Must be a positive value, greater than 0. - - - NOTE: the current timeout mechanism only - has seconds granularity, therefore you should configure this - parameter as a multiple of 1000. - - - Default value is 1000 ms. - - - <varname>async_timeout</varname> parameter usage - - -modparam("auth_aka", "async_timeout", 2000) - - -
-
- <varname>unused_timeout</varname> (integer) - - The amount of seconds an authentication vector that has - not been used can stay in memory. Once this timeout is - reached, the authentication vector is removed. - - - Must be a positive value, greater than 0. - - - Default value is 60 s. - - - <varname>unused_timeout</varname> parameter usage - - -modparam("auth_aka", "unused_timeout", 120) - - -
-
- <varname>unused_timeout</varname> (integer) - - The amount of seconds an authentication vector that is being - used in the authentication process shall stay in memory. - Once this timeout is reached, the authentication vector is - removed, and the authentication using it will fail. - - - Must be a positive value, greater than 0. - - - Default value is 30 s. - - - <varname>pending_timeout</varname> parameter usage - - -modparam("auth_aka", "pending_timeout", 10) - - -
-
- -
- Exported Functions -
- <function moreinfo="none">aka_www_authorize([realm]])</function> - - The function verifies credentials according to - RFC3310, by using - an authentication vector priorly allocated by an - aka_www_challenge() call, using - the av_mgm manager. If the credentials are - verified successfully the function will succeed, otherwise it will fail with - an appropriate error code, as follows: - - - - -6 (sync request) - the auts - parameter was was present, thus a sync was requested; - - - -5 (generic error) - some generic error - occurred and no reply was sent out; - - - -4 (no credentials) - credentials were not - found in request; - - - -3 (unknown nonce) - authentication vector - with the corresponding nonce was not found; - - - -2 (invalid password) - password does not - match the authentication vector; - - - -1 (invalid username) - no username found - in the Authorize header; - - - - In case the function succeeds, the WWW-Authenticate - header is being added to the reply, containing the challenge information, - as well as the Integrity-Key and the - Confidentiality-Key values associated to the - AV being used. - - Meaning of the parameters is as follows: - - - realm (string) - Realm is a opaque string that - the user agent should present to the user so he can decide what - username and password to use. This is usually - one of the domains the proxy is responsible for. - If an empty string is used then the server will - generate realm from host part of From header field URI. - - - - - If the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials - can be later used by some other functions). - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">aka_www_authorize</function> usage - - -... -if (!aka_www_authorize("diameter", "siphub.com")) - aka_www_challenge("diameter", "siphub.com", "auth"); -... - - - -
- -
- <function moreinfo="none">aka_proxy_authorize([realm]])</function> - - The function behaves the same as , - but it authenticates the user from a proxy perspective. It receives the same - parameters, with the same meaning, and returns the same values. - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">aka_proxy_authorize</function> usage - - -... -if (!aka_proxy_authorize("siphub.com")) - aka_proxy_challenge("diameter", "siphub.com", "auth"); -... - - - -
- -
- <function moreinfo="none">aka_www_challenge([av_mgm[, realm[ ,qop[, alg]]]])</function> - - The function challenges a user agent. It fetches an authentication - vector for each algorigthm used through the - av_mgm Manager and generate one or more - WWW-Authenticate header fields containing digest challenges. It will - put the header field(s) into a response generated from the request the - server is processing and will send the reply. Upon reception of such a - reply the user agent should compute credentials using the used - authentication vector annd retry the request. - For more information regarding digest authentication - see RFC2617, RFC3261, RFC3310 and RFC8760. - - - Meaning of the parameters is as follows: - - - - av_mgm (string, optional) - the AV Manager - to be used for this challenge, in case an AV is not already available - for the challenged user identity. In case it is missing the value of the - is being used. - - realm (string) - Realm is an opaque string that - the user agent should present to the user so it can decide what - username and password to use. Usually this is domain of the host - the server is running on. If missing, the value of the - From domain is being used. - - - - qop (string, optional) - Value of this - parameter can be either auth, auth-int - or both (separated by ,). When this parameter is - set the server will put a qop parameter in the challenge. It - is recommended to use the qop parameter, however there are still some - user agents that cannot handle qop properly so we made this optional. - On the other hand there are still some user agents that cannot handle - request without a qop parameter too. If missing, the value of the - is being used. - - - - algorithms (string, optional) - Value of this - parameter is a comma-separated list of digest algorithms to be offered for - the UAC to use for authentication. Possible values are: - - AKAv1-MD5 - AKAv1-MD5-sess - AKAv1-SHA-256 - AKAv1-SHA-256-sess - AKAv1-SHA-512-256 - AKAv1-SHA-512-256-sess - AKAv2-MD5 - AKAv2-MD5-sess - AKAv2-SHA-256 - AKAv2-SHA-256-sess - AKAv2-SHA-512-256 - AKAv2-SHA-512-256-sess - - When the value is empty or not set, the only offered digest - the value of the is being used. - - - - - Possible return codes: - - - - -1 - generic parsing error, generated - when there is not enoough data to build the challange - - - - -2 - no AV vector could not be fetched - - - - -3 - authentication headers could not - be built - - - - -5 - a reply could not be sent - - - - positive - the number of successful - chalanges being sent in the reply; this value can be lower than - the number of algorithms being requested in case there was a - timeout waiting for some AVs. - - - - - This function can be used from REQUEST_ROUTE. - - - - aka_www_challenge usage - -... -if (!aka_www_authorize("siphub.com")) { - aka_www_challenge(,"siphub.com", "auth-int", "AKAv1-MD5"); -} -... - - -
- -
- <function moreinfo="none">aka_proxy_challenge([realm]])</function> - - The function behaves the same as , - but it challenges the user from a proxy perspective. It receives the same - parameters, with the same meaning, the only difference being that in case of - the realm is missing, then it is taken from the - the To domain, rather than from - From domain. The header added is - Proxy-Authenticate, rather than - WWW-Authenticate The rest of the parameters, behavior, - as well as return values are the same. - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">aka_proxy_challenge</function> usage - - -... -if (!aka_proxy_authorize("siphub.com")) - aka_proxy_challenge(,"siphub.com", "auth"); -... - - - -
- -
- <function moreinfo="none">aka_av_add(public_identity, private_identity, authenticate, authorize, confidentiality_key, integrity_key[, algorithms])</function> - - Adds an authentication vector for the user identitied by - public_identity and - private_identity. - - Meaning of the parameters is as follows: - - - public_identity (string) - the public identity - (IMPU) of the user to add authentication vector for. - - - private_identity (string) - the private identity - (IMPI) of the user to add authentication vector for. - - - authenticate (string) - the concatenation of the - authentication challenge RAND and the token AUTN, encoded in hexa format. - - - authorize (string) - the authorization string - (XRES) used for authorizing the user, encoded in hexa format. - - - confidentiality_key (string) - the Confidentiality-Key - used in the AKA IPSec process, encoded in hexa format. - - - integrity_key (string) - the Integrity-Key - used in the AKA IPSec process, encoded in hexa format. - - - algorithms (string, optional) - AKA algorithms - this AV should be used for. If missing, the AV can be used for any AKA - algorithm. - - - - This function can be used from any route. - - - <function moreinfo="none">aka_av_add</function> usage - - -... -aka_av_add("sip:test@siphub.com", "test@siphub.com", - "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4=", /* authenticate */ - "00000262c0000014000028af2d6398cbe26eea69", /* authorize */ - "db7f8c4a58e17083974bba3b936d34c4", /* ck */ - "6151667b9ef815c1dcb87473685f062a" /* ik */); -... - - - -
- -
- <function moreinfo="none">aka_av_drop(public_identity, private_identity, authenticate)</function> - - Drops the authentication vector corresponding to the - authenticate/nonce value - for an user identitied by - public_identity and - private_identity. - - Meaning of the parameters is as follows: - - - public_identity (string) - the public identity - (IMPU) of the user to drop authentication vector for. - - - private_identity (string) - the private identity - (IMPI) of the user to drop authentication vector for. - - - authenticate (string) - the authenticate/nonce - that identifies the authentication vector to be dropped. - - - - This function can be used from any route. - - - <function moreinfo="none">aka_av_drop</function> usage - - -... -aka_av_drop("sip:test@siphub.com", "test@siphub.com", - "KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4="); -... - - - -
-
- <function moreinfo="none">aka_av_drop_all(public_identity, private_identity[, count])</function> - - Drops all authentication vectors for an user identitied by - public_identity and - private_identity. This function is useful - when a synchronization must be done. - - Meaning of the parameters is as follows: - - - public_identity (string) - the public identity - (IMPU) of the user to drop authentication vectors for. - - - private_identity (string) - the private identity - (IMPI) of the user to drop authentication vectors for. - - - count (variable, optional) - a variable to return the number - of authentication vectors dropped. - - - - This function can be used from any route. - - - <function moreinfo="none">aka_av_drop_all</function> usage - - -... -aka_av_drop_all("sip:test@siphub.com", "test@siphub.com", $var(count)); -... - - - -
-
- <function moreinfo="none">aka_av_fail(public_identity, private_identity[, count])</function> - - Marks the engine that an authentication vector query for a user has - failed, unlocking the processing of the message. - - - Note: this function is useful when you - know that fetching a new authentication vector is not possible - (due to various reasons) - calling it will resume the message - procesing, using only the available AVs fetched so far. - - Meaning of the parameters is as follows: - - - public_identity (string) - the public identity - (IMPU) of the user to drop authentication vectors for. - - - private_identity (string) - the private identity - (IMPI) of the user to drop authentication vectors for. - - - count (integer, optional) - the number of - authentication vectors that failed. If missing, - 1 is considered. - - - - This function can be used from any route. - - - <function moreinfo="none">aka_av_fail</function> usage - -... -aka_av_fail("sip:test@siphub.com", "test@siphub.com", 3); -... - - - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">aka_av_add</function> - - Adds an Authentication Vector through the MI interface. - - Parameters: - - - public_identity (string) - the public identity - (IMPU) of the user to add authentication vector for. - - - private_identity (string) - the private identity - (IMPI) of the user to add authentication vector for. - - - authenticate (string) - the concatenation of the - authentication challenge RAND and the token AUTN, encoded in hexa format. - - - authorize (string) - the authorization string - (XRES) used for authorizing the user, encoded in hexa format. - - - confidentiality_key (string) - the Confidentiality-Key - used in the AKA IPSec process, encoded in hexa format. - - - integrity_key (string) - the Integrity-Key - used in the AKA IPSec process, encoded in hexa format. - - - algorithms (string, optional) - AKA algorithms - this AV should be used for. If missing, the AV can be used for any AKA - algorithm. - - - - - <function moreinfo="none">aka_av_add</function> usage - -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_add \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= - 00000262c0000014000028af2d6398cbe26eea69 - db7f8c4a58e17083974bba3b936d34c4 - 6151667b9ef815c1dcb87473685f062a -... - - -
-
- <function moreinfo="none">aka_av_drop</function> - - Invalidates an Authentication Vector of an user identified - by its authenticate value. - - Parameters: - - - public_identity (string) - the public identity - (IMPU) of the user to add authentication vector for. - - - private_identity (string) - the private identity - (IMPI) of the user to add authentication vector for. - - - authenticate (string) - the authenticate/nonce - to indentify the authentication vector. - - - - - <function moreinfo="none">aka_av_drop</function> usage - -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= -... - - -
-
- <function moreinfo="none">aka_av_drop_all</function> - - Invalidates all Authentication Vectors of an user through the - MI interface. - - Parameters: - - - public_identity (string) - the public identity - (IMPU) of the user to drop authentication vectors for. - - - private_identity (string) - the private identity - (IMPI) of the user to drop authentication vectors for. - - - - - <function moreinfo="none">aka_av_drop_all</function> usage - -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop_all \ - sip:test@siphub.com - test@siphub.com -... - - -
-
- <function moreinfo="none">aka_av_fail</function> - - Indicates the fact that the fetching of an authentication - vector has failed, unlocking the processing of the message. - - - Note: this function is useful when you - know that fetching a new authentication vector is not possible - (due to various reasons) - calling it will resume the message - procesing, using only the available AVs fetched so far. - - Parameters: - - - public_identity (string) - the public identity - (IMPU) of the user to add authentication vector for. - - - private_identity (string) - the private identity - (IMPI) of the user to add authentication vector for. - - - count (integer, optional) - the number of - authentication vectors failures. - - - - - <function moreinfo="none">aka_av_drop</function> usage - -... -## adds an AKA AV -$ opensips-cli -x mi aka_av_drop \ - sip:test@siphub.com - test@siphub.com - KFQ/MpR3cE3V9PxucEQS5KED8uUNYIAALFyk59sIJI4= -... - - -
-
-
- diff --git a/modules/auth_aka/doc/contributors.xml b/modules/auth_aka/doc/contributors.xml deleted file mode 100644 index 1701001e188..00000000000 --- a/modules/auth_aka/doc/contributors.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 54 - 20 - 3378 - 295 - - - 2. - Alexandra Titoc - 4 - 2 - 2 - 2 - - - 3. - LarryLaffer-dev - 3 - 1 - 26 - 1 - - - 4. - Liviu Chircu (@liviuchircu) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Feb 2024 - Jul 2025 - - - 2. - LarryLaffer-dev - Mar 2025 - Mar 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Sep 2024 - Sep 2024 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/auth_db/README b/modules/auth_db/README deleted file mode 100644 index feda4990023..00000000000 --- a/modules/auth_db/README +++ /dev/null @@ -1,545 +0,0 @@ -Auth_db Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. RFC 8760 Support (Strenghtened - Authentication) - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. calculate_ha1 (integer) - 1.3.3. use_domain (integer) - 1.3.4. load_credentials (string) - 1.3.5. skip_version_check (int) - 1.3.6. user_column (string) - 1.3.7. domain_column (string) - 1.3.8. password_column (string) - 1.3.9. hash_column_sha256 (string) - 1.3.10. hash_column_sha512t256 (string) - 1.3.11. uri_user_column (string) - 1.3.12. uri_domain_column (string) - 1.3.13. uri_uriuser_column (string) - - 1.4. Exported Functions - - 1.4.1. www_authorize(realm, table) - 1.4.2. proxy_authorize(realm, table) - 1.4.3. db_is_to_authorized(table) - 1.4.4. db_is_from_authorized(table) - 1.4.5. db_does_uri_exist(uri, table) - 1.4.6. db_get_auth_id(table, uri, auth, realm) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. db_url parameter usage - 1.2. calculate_ha1 parameter usage - 1.3. use_domain parameter usage - 1.4. load_credentials parameter usage - 1.5. skip_version_check parameter usage - 1.6. user_column parameter usage - 1.7. domain_column parameter usage - 1.8. password_column parameter usage - 1.9. password_column parameter usage - 1.10. password_column parameter usage - 1.11. Set uri_user_column parameter - 1.12. Set uri_domain_column parameter - 1.13. Set uriuser_column parameter - 1.14. www_authorize usage - 1.15. proxy_authorize usage - 1.16. db_is_to_authorized usage - 1.17. db_does_uri_exist usage - 1.18. db_get_auth_id usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module contains all authentication related functions that - need the access to the database. This module should be used - together with auth module, it cannot be used independently - because it depends on the module. Select this module if you - want to use database to store authentication information like - subscriber usernames and passwords. If you want to use radius - authentication, then use auth_radius instead. - -1.1.1. RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, auth_db and uac_auth - modules include support for two new digest authentication - algorithms ("SHA-256" and "SHA-512-256"), according to the RFC - 8760 specs. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * auth -- Generic authentication functions - * database -- Any database module (currently mysql, postgres, - dbtext) - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.3. Exported Parameters - -1.3.1. db_url (string) - - This is URL of the database to be used. Value of the parameter - depends on the database module used. For example for mysql and - postgres modules this is something like - mysql://username:password@host:port/database. For dbtext module - (which stores data in plaintext files) it is directory in which - the database resides. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips”. - - Example 1.1. db_url parameter usage -modparam("auth_db", "db_url", "dbdriver://username:password@dbhost/dbnam -e") - -1.3.2. calculate_ha1 (integer) - - This parameter tells the server whether it should considered - the loaded password (for authentification) as plaintext - passwords or a pre-calculated HA1 string. - - Possible meanings of this parameter are: - * 1 (calculate HA1) - the loaded password is a plaintext - password, so OpenSIPS will internally calculate the HA1. As - the passwords will be loaded from the column specified in - the password_column parameter, be sure this parameter - points to a column holding a plaintext password (by - default, this parameter points to the “ha1” column); - * 0 (do not calculate HA1) - the loaded password is a - pre-computed HA1 hash (no calculation needed). The module - will load all hashes stored in the password_column, - hash_column_sha256 and hash_column_sha512t256 columns, then - use the hash corresponding to the hashing algorithm - selected for a given digest authentication challenge. - The content of the hash columns can be generated as - follows: - + password_column: MD5(username:realm:password) - + hash_column_sha256: SHA-256(username:realm:password) - + hash_column_sha512t256: - SHA-512-256(username:realm:password) - - Default value of this parameter is 0 (use hashed passwords). - - Example 1.2. calculate_ha1 parameter usage -modparam("auth_db", "calculate_ha1", 1) - -1.3.3. use_domain (integer) - - If true (not 0), domain will be also used when looking up in - the subscriber table. If you have a multi-domain setup, it is - strongly recommended to turn on this parameter to avoid - username overlapping between domains. - - IMPORTANT: before turning on this parameter, be sure that the - domain column in subscriber table is properly populated. - - Default value is “0 (false)”. - - Example 1.3. use_domain parameter usage -modparam("auth_db", "use_domain", 1) - -1.3.4. load_credentials (string) - - This parameter specifies credentials to be fetched from - database when the authentication is performed. The loaded - credentials will be stored in AVPs. If the AVP name is not - specificaly given, it will be used a NAME AVP with the same - name as the column name. - - Parameter syntax: - * load_credentials = credential (';' credential)* - * credential = (avp_specification '=' column_name) | - (column_name) - * avp_specification = '$avp(' + NAME + ')' - - Default value of this parameter is “rpid”. - - Example 1.4. load_credentials parameter usage -# load rpid column into $avp(13) and email_address column -# into $avp(email_address) -modparam("auth_db", "load_credentials", "$avp(13)=rpid;email_address") - -1.3.5. skip_version_check (int) - - This parameter specifies not to check the auth table version. - This parameter should be set when a custom authentication table - is used. - - Default value is “0 (false)”. - - Example 1.5. skip_version_check parameter usage -modparam("auth_db", "skip_version_check", 1) - -1.3.6. user_column (string) - - This is the name of the column in a 'SUBSCRIBER' like table - holding the usernames. Default value is fine for most people. - Use the parameter if you really need to change it. - - Default value is “username”. - - Example 1.6. user_column parameter usage -modparam("auth_db", "user_column", "user") - -1.3.7. domain_column (string) - - This is the name of the column in a 'SUBSCRIBER' like table - holding the domains of users. Default value is fine for most - people. Use the parameter if you really need to change it. - - Default value is “domain”. - - Example 1.7. domain_column parameter usage -modparam("auth_db", "domain_column", "domain") - -1.3.8. password_column (string) - - This is the name of the column in a "subscriber" like table - holding MD5 HA1 hash strings or plaintext passwords. An MD5 HA1 - hash is an MD5 hash of username, password and realm. Storing - hashes in the DB (as opposed to passwords directly) is much - more secure, because the server does not need to know plaintext - passwords and because it is computationally infeasible for an - attacker to reverse-obtain a password from an HA1 string. - - Default value is “ha1”. - - Example 1.8. password_column parameter usage -modparam("auth_db", "password_column", "password") - -1.3.9. hash_column_sha256 (string) - - The name of the column holding SHA-256 HA1 hashes (RFC 8760 - support). - - Default value is “ha1_sha256”. - - Example 1.9. password_column parameter usage -modparam("auth_db", "hash_column_sha256", "ha1_sha256") - -1.3.10. hash_column_sha512t256 (string) - - The name of the column holding SHA-512/256 HA1 hashes. (RFC - 8760 support). - - Default value is “ha1_sha512t256”. - - Example 1.10. password_column parameter usage -modparam("auth_db", "hash_column_sha512t256", "ha1_sha512t256") - -1.3.11. uri_user_column (string) - - Column holding usernames in an 'URI' like table. - - Default value is “username”. - - Example 1.11. Set uri_user_column parameter -... -modparam("auth_db", "uri_user_column", "username") -... - -1.3.12. uri_domain_column (string) - - Column holding domain in an 'URI' like table. - - Default value is “domain”. - - Example 1.12. Set uri_domain_column parameter -... -modparam("auth_db", "uri_domain_column", "domain") -... - -1.3.13. uri_uriuser_column (string) - - Column holding URI username in an 'URI' like table. - - Default value is “uri_user”. - - Example 1.13. Set uriuser_column parameter -... -modparam("auth_db", "uri_uriuser_column", "uri_user") -... - -1.4. Exported Functions - -1.4.1. www_authorize(realm, table) - - The function verifies the received credentials against a - "SUBSCRIBER"-like table according to digest authentication as - per RFC2617. If the credentials are verified successfully then - the function will succeed and mark the credentials as - authorized (marked credentials can be later used by some other - functions). If the function was unable to verify the - credentials for some reason then it will fail and the script - should call www_challenge which will challenge the user again. - - Negative codes may be interpreted as follows: - * -5 (generic error) - some generic error occurred and no - reply was sent out; - * -4 (no credentials) - credentials were not found in - request; - * -3 (stale nonce) - stale nonce; - * -2 (invalid password) - valid user, but wrong password; - * -1 (invalid user) - authentication user does not exist. - - Meaning of the parameters is as follows: - * realm (string) - Realm is an opaque string that the user - agent should present to the user so it can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. In case of REGISTER requests To header - field domain will be used (because this header field - represents a user being registered), for all other messages - From header field domain will be used. - The string may contain pseudo variables. - * table (string) - Table to be used to lookup usernames and - passwords (usually subscribers table). - - This function can be used from REQUEST_ROUTE. - - Example 1.14. www_authorize usage -... -if (!www_authorize("siphub.net", "subscriber")) - www_challenge("siphub.net", "auth"); -... - -1.4.2. proxy_authorize(realm, table) - - The function verifies the received credentials against a - "SUBSCRIBER"-like table according to digest authentication as - per RFC2617. If the credentials are verified successfully then - the function will succeed and mark the credentials as - authorized (marked credentials can be later used by some other - functions). If the function was unable to verify the - credentials for some reason then it will fail and the script - should call proxy_challenge which will challenge the user - again. - - Negative codes may be interpreted as follows: - * -5 (generic error) - some generic error occurred and no - reply was sent out; - * -4 (no credentials) - credentials were not found in - request; - * -3 (stale nonce) - stale nonce; - * -2 (invalid password) - valid user, but wrong password; - * -1 (invalid user) - authentication user does not exist. - - Meaning of the parameters is as follows: - * realm (string) - Realm is an opaque string that the user - agent should present to the user so it can decide what - username and password to use. Usually this is domain of the - host the server is running on. - If an empty string “” is used then the server will generate - it from the request. From header field domain will be used - as realm. - The string may contain pseudo variables. - * table (string) - Table to be used to lookup usernames and - passwords (usually subscribers table). - - This function can be used from REQUEST_ROUTE. - - Example 1.15. proxy_authorize usage -... -if (!proxy_authorize("", "subscriber")) - proxy_challenge("", "auth"); # Realm will be autogenerated -... - -1.4.3. db_is_to_authorized(table) - - The function checks against a 'URI' like table to see if the - username extracted from the To header URI is allowed/authorized - to use the credentials (authentication username) validated by - www_authorize(). - - The function is part of the mechanism that allows to create - mapping between the SIP users (from the FROM/TO headers) and - the authentication users (from a SUBSCRIBER-like table) that - they use. The mapping is stored into an URI-like table. - - Meaning of the parameters is as follows: - * table (string) - Table to be used to lookup for the - URI/AUTH mappings (usually the URI table). - - This function can be used from REQUEST_ROUTE. - - Example 1.16. db_is_to_authorized usage -... -if (!db_is_to_authorized("uri")) { - xlog("User $tu is not authorized to authenticate with $au creden -tial\n"); -} -... - -1.4.4. db_is_from_authorized(table) - - Similar to db_is_to_authorized() but instead of checking the TO - header URI, the FROM header URI is checked. - -1.4.5. db_does_uri_exist(uri, table) - - Checks if the username@domain from the given URI is an existing - user in a 'SUBSCRIBER' like table. - - Meaning of the parameters is as follows: - * uri (string) - The SIP URI to be tested. It must hold a - username part for a valid check. Variables are allowed. - * table (string) - Table to be used to search for the URI - (usually the SUBSCRIBER table). - - This function can be used from REQUEST_ROUTE. - - Example 1.17. db_does_uri_exist usage -... -if (db_does_uri_exist($ru, "subscriber")) { - ... -} -... - -1.4.6. db_get_auth_id(table, uri, auth, realm) - - Checks given uri-string username against an 'URI' like table. - Returns true if the user exists in the database, and sets the - given variables to the authentication id and realm - corresponding to the given uri. - - Meaning of the parameters is as follows: - * table (string) - Table to be used to search for the URI - (usually the URI table). - * uri (string) - The input SIP URI to be tested. It must hold - a username part for a valid check. Variables are allowed. - * auth (var) - an output variable to store the found - authentication id matching the given SIP URI. - * realm (var) - an output variable to store the found - authentication realm matching the given SIP URI. - - This function can be used from REQUEST_ROUTE ,FAILURE_ROUTE and - LOCAL_ROUTE. - - Example 1.18. db_get_auth_id usage -... -if (db_get_auth_id("uri", $ru, $avp(auth_id), $avp(auth_realm))) { - ... -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 51 37 783 380 - 2. Jan Janak (@janakj) 50 29 1610 424 - 3. Daniel-Constantin Mierla (@miconda) 29 20 130 382 - 4. Liviu Chircu (@liviuchircu) 23 18 161 137 - 5. Henning Westerholt (@henningw) 11 9 83 49 - 6. Razvan Crainea (@razvancrainea) 10 8 30 48 - 7. Maksym Sobolyev (@sobomax) 10 5 307 116 - 8. Vlad Patrascu (@rvlad-patrascu) 8 4 69 163 - 9. Sergio Gutierrez 7 5 13 13 - 10. Andrei Pelinescu-Onciul 6 4 81 33 - - All remaining contributors: Dan Pascu (@danpascu), Jiri Kuthan - (@jiriatipteldotorg), Walter Doekes (@wdoekes), Anatoly - Pidruchny, Kennard White, Konstantin Bokarius, Richard Revels, - Julián Moreno Patiño, Norman Brandinger (@NormB), Peter - Lemenkov (@lemenkov), Edson Gellert Schubert, Ionut Ionita - (@ionutrazvanionita). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Razvan Crainea (@razvancrainea) Jun 2011 - Jan 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2004 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2005 - Jul 2021 - 5. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Ionut Ionita (@ionutrazvanionita) Jan 2015 - Jan 2015 - 10. Richard Revels Sep 2011 - Sep 2011 - - All remaining contributors: Kennard White, Dan Pascu - (@danpascu), Sergio Gutierrez, Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Anatoly Pidruchny, Norman Brandinger - (@NormB), Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri - Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Maksym Sobolyev - (@sobomax), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov - (@lemenkov), Razvan Crainea (@razvancrainea), Kennard White, - Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Anatoly Pidruchny, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2002-2003 FhG FOKUS diff --git a/modules/auth_db/README.md b/modules/auth_db/README.md new file mode 100644 index 00000000000..56b5410695d --- /dev/null +++ b/modules/auth_db/README.md @@ -0,0 +1,574 @@ +--- +title: "Auth_db Module" +description: "This module contains all authentication related functions that need the access to the database. This module should be used together with auth module, it cannot be used independently because it depends on the module." +--- + +## Admin Guide + + +### Overview + + +This module contains all authentication related functions that need +the access to the database. This module should be used together with +auth module, it cannot be used independently because it depends on +the module. Select this module if you want to use database to store +authentication information like subscriber usernames and passwords. If +you want to use radius authentication, then use auth_radius instead. + + +#### RFC 8760 Support (Strenghtened Authentication) + + +Starting with OpenSIPS 3.2, the [auth](../auth), +[auth_db](../auth_db) and +[uac_auth](../uac_auth) +modules include support for two new digest authentication algorithms +("SHA-256" and "SHA-512-256"), according to the +[RFC 8760](https://datatracker.ietf.org/doc/html/rfc8760) +specs. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *auth* -- Generic authentication +functions +- *database* -- Any database module +(currently mysql, postgres, dbtext) + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### db_url (string) + + +This is URL of the database to be used. Value of the parameter depends +on the database module used. For example for mysql and postgres modules +this is something like mysql://username:password@host:port/database. +For dbtext module (which stores data in plaintext files) it is +directory in which the database resides. + + +*Default value is "mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="db_url parameter usage" +modparam("auth_db", "db_url", "dbdriver://username:password@dbhost/dbname") +``` + + +#### calculate_ha1 (integer) + + +This parameter tells the server whether it should considered the +loaded password (for authentification) as plaintext passwords or +a pre-calculated HA1 string. + + +Possible meanings of this parameter are: + + +- *1 (calculate HA1)* - the loaded +password is a plaintext password, so OpenSIPS will internally +calculate the HA1. As the passwords will be loaded from the column +specified in the [password column](#param_password_column) parameter, +be sure this parameter points to a column holding a plaintext password +(by default, this parameter points to the "ha1" column); +- *0 (do **not** +calculate HA1)* - the loaded password is a pre-computed +HA1 hash (no calculation needed). The module will load all hashes +stored in the [password column](#param_password_column), +[hash column sha256](#param_hash_column_sha256) and +[hash column sha512t256](#param_hash_column_sha512t256) columns, then use +the hash corresponding to the hashing algorithm selected for a +given digest authentication challenge. +The content of the hash columns can be generated as follows: + +password_column: MD5(username:realm:password) +hash_column_sha256: SHA-256(username:realm:password) +hash_column_sha512t256: SHA-512-256(username:realm:password) + + +Default value of this parameter is +*0 (use hashed passwords)*. + + +```opensips title="calculate_ha1 parameter usage" +modparam("auth_db", "calculate_ha1", 1) +``` + + +#### use_domain (integer) + + +If true (not 0), domain will be also used when looking up in the +subscriber table. If you have a multi-domain setup, it is strongly +recommended to turn on this parameter to avoid username overlapping +between domains. + + +IMPORTANT: before turning on this parameter, be sure that the +`domain` column in `subscriber` +table is properly populated. + + +Default value is "0 (false)". + + +```opensips title="use_domain parameter usage" +modparam("auth_db", "use_domain", 1) + +``` + + +#### load_credentials (string) + + +This parameter specifies credentials to be fetched from database when +the authentication is performed. The loaded credentials will be stored +in AVPs. If the AVP name is not specificaly given, it will be used a +NAME AVP with the same name as the column name. + + +Parameter syntax: + + +- *load_credentials = credential (';' credential)** +- *credential = (avp_specification '=' column_name) | +(column_name)* +- *avp_specification = '$avp(' + NAME + ')'* + + +Default value of this parameter is "rpid". + + +*Note:* the default schema no longer comes with the +*rpid* column, so if you are using the rpid value, +you should provision it in your table. Otherwise, simply set this +parameter to the empty string value. + + +Default value of this parameter is "rpid". + + +```opensips title="load_credentials parameter usage" +# load rpid column into $avp(13) and email_address column +# into $avp(email_address) +modparam("auth_db", "load_credentials", "$avp(13)=rpid;email_address") +``` + + +#### skip_version_check (int) + + +This parameter specifies not to check the auth table version. This +parameter should be set when a custom authentication table is used. + + +Default value is "0 (false)". + + +```opensips title="skip_version_check parameter usage" +modparam("auth_db", "skip_version_check", 1) + +``` + + +#### user_column (string) + + +This is the name of the column in a 'SUBSCRIBER' like table holding +the usernames. Default value is fine for most people. +Use the parameter if you really need to change it. + + +Default value is "username". + + +```opensips title="user_column parameter usage" +modparam("auth_db", "user_column", "user") +``` + + +#### domain_column (string) + + +This is the name of the column in a 'SUBSCRIBER' like table holding +the domains of users. Default value is fine for most people. +Use the parameter if you really need to +change it. + + +Default value is "domain". + + +```opensips title="domain_column parameter usage" +modparam("auth_db", "domain_column", "domain") +``` + + +#### password_column (string) + + +This is the name of the column in a *"subscriber"* +like table holding MD5 HA1 hash strings or plaintext passwords. An MD5 HA1 +hash is an MD5 hash of username, password and realm. Storing hashes in the +DB (as opposed to passwords directly) is much more secure, because the +server does not need to know plaintext passwords and because it is +computationally infeasible for an attacker to reverse-obtain a password +from an HA1 string. + + +Default value is "ha1". + + +```opensips title="password_column parameter usage" +modparam("auth_db", "password_column", "password") +``` + + +#### hash_column_sha256 (string) + + +The name of the column holding SHA-256 HA1 hashes +([RFC 8760](https://datatracker.ietf.org/doc/html/rfc8760) support). + + +Default value is "ha1_sha256". + + +```opensips title="password_column parameter usage" +modparam("auth_db", "hash_column_sha256", "ha1_sha256") +``` + + +#### hash_column_sha512t256 (string) + + +The name of the column holding SHA-512/256 HA1 hashes. +([RFC 8760](https://datatracker.ietf.org/doc/html/rfc8760) support). + + +Default value is "ha1_sha512t256". + + +```opensips title="password_column parameter usage" +modparam("auth_db", "hash_column_sha512t256", "ha1_sha512t256") +``` + + +#### uri_user_column (string) + + +Column holding usernames in an 'URI' like table. + + +*Default value is "username".* + + +```opensips title="Set uri_user_column parameter" +... +modparam("auth_db", "uri_user_column", "username") +... +``` + + +#### uri_domain_column (string) + + +Column holding domain in an 'URI' like table. + + +*Default value is "domain".* + + +```opensips title="Set uri_domain_column parameter" +... +modparam("auth_db", "uri_domain_column", "domain") +... +``` + + +#### uri_uriuser_column (string) + + +Column holding URI username in an 'URI' like table. + + +*Default value is "uri_user".* + + +```opensips title="Set uriuser_column parameter" +... +modparam("auth_db", "uri_uriuser_column", "uri_user") +... +``` + + +### Exported Functions + + +#### www_authorize(realm, table) + + +The function verifies the received credentials against a +"SUBSCRIBER"-like table according to digest authentication as per +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). +If the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials +can be later used by some other functions). If the function was +unable to verify the +credentials for some reason then it will fail and the script should +call `www_challenge` which will +challenge the user again. + + +Negative codes may be interpreted as follows: + + +- *-5 (generic error)* - some generic error +occurred and no reply was sent out; +- *-4 (no credentials)* - credentials were not +found in request; +- *-3 (stale nonce)* - stale nonce; +- *-2 (invalid password)* - valid user, but +wrong password; +- *-1 (invalid user)* - authentication user does +not exist. + + +Meaning of the parameters is as follows: + + +- *realm (string)* - Realm is an opaque string that +the user agent should present to the user so it can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. In case of REGISTER requests To +header field domain will be used (because this header field +represents a user being registered), for all other messages From +header field domain will be used. +The string may contain pseudo variables. +- *table (string)* - Table to be used to lookup +usernames and passwords (usually subscribers table). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="www_authorize usage" +... +if (!www_authorize("siphub.net", "subscriber")) + www_challenge("siphub.net", "auth"); +... +``` + + +#### proxy_authorize(realm, table) + + +The function verifies the received credentials against a +"SUBSCRIBER"-like table according to digest authentication as per +[RFC2617](http://www.ietf.org/rfc/rfc2617.txt). If +the credentials are verified successfully then the function will +succeed and mark the credentials as authorized (marked credentials can +be later used by some other functions). If the function was unable to +verify the credentials for some reason then it will fail and +the script should call +`proxy_challenge` which will +challenge the user again. + + +Negative codes may be interpreted as follows: + + +- *-5 (generic error)* - some generic +error occurred and no reply was sent out; +- *-4 (no credentials)* - credentials +were not found in request; +- *-3 (stale nonce)* - stale nonce; +- *-2 (invalid password)* - valid user, +but wrong password; +- *-1 (invalid user)* - authentication +user does not exist. + + +Meaning of the parameters is as follows: + + +- *realm (string)* - Realm is an opaque string that +the user agent should present to the user so it can decide what +username and password to use. Usually this is domain of the host +the server is running on. +If an empty string "" is used then the server will +generate it from the request. From header field domain will be +used as realm. +The string may contain pseudo variables. +- *table (string)* - Table to be used to lookup +usernames and passwords (usually subscribers table). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="proxy_authorize usage" +... +if (!proxy_authorize("", "subscriber")) + proxy_challenge("", "auth"); # Realm will be autogenerated +... +``` + + +#### db_is_to_authorized(table) + + +The function checks against a 'URI' like table to see if the +username extracted from the To header URI is allowed/authorized to +use the credentials (authentication username) validated by +[www authorize](#func_www_authorize). + + +The function is part of the mechanism that allows to create +mapping between the SIP users (from the FROM/TO headers) and the +authentication users (from a SUBSCRIBER-like table) that they use. The +mapping is stored into an URI-like table. + + +Meaning of the parameters is as follows: + + +- *table (string)* - Table to be used to lookup +for the URI/AUTH mappings (usually the URI table). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="db_is_to_authorized usage" +... +if (!db_is_to_authorized("uri")) { + xlog("User $tu is not authorized to authenticate with $au credential\n"); +} +... +``` + + +#### db_is_from_authorized(table) + + +Similar to [db is to authorized](#func_db_is_to_authorized) but instead of +checking the TO header URI, the FROM header URI is checked. + + +#### db_does_uri_exist(uri, table) + + +Checks if the username@domain from the given URI is an existing +user in a 'SUBSCRIBER' like table. + + +Meaning of the parameters is as follows: + + +- *uri (string)* - The SIP URI to be tested. It must +hold a username part for a valid check. Variables are allowed. +- *table (string)* - Table to be used to search +for the URI (usually the SUBSCRIBER table). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="db_does_uri_exist usage" +... +if (db_does_uri_exist($ru, "subscriber")) { + ... +} +... +``` + + +#### db_get_auth_id(table, uri, auth, realm) + + +Checks given uri-string username against an 'URI' like table. +Returns true if the user exists in the database, and sets the given +variables to the authentication id and realm corresponding to +the given uri. + + +Meaning of the parameters is as follows: + + +- *table (string)* - Table to be used to search +for the URI (usually the URI table). +- *uri (string)* - The input SIP URI to be tested. +It must hold a username part for a valid check. +Variables are allowed. +- *auth (var)* - an output variable to store the +found authentication id matching the given SIP URI. +- *realm (var)* - an output variable to store the +found authentication realm matching the given SIP URI. + + +This function can be used from REQUEST_ROUTE ,FAILURE_ROUTE and +LOCAL_ROUTE. + + +```opensips title="db_get_auth_id usage" +... +if (db_get_auth_id("uri", $ru, $avp(auth_id), $avp(auth_realm))) { + ... +} +... +``` + +### Tips & FAQ + +#### How to recalculate ha1 and ha1b + +When you change the `domain` column in the subscriber table, you have to recalculate `ha1` and `ha1b` fields. In order to do that you must have the password of each subscriber. + +HA1 is a MD5 hash of "username:domain:password". For example, if you have created a SIP account "1000@mydomain.com" using password "123456", then HA1 is the MD5 hash of "1000:mydomain.com:123456" (without quotes). On the other hand HA1B is the MD5 hash of "username@domain:domain:password"; so using the same example above, HA1B would be the MD5 hash of "1000@mydomain.com:mydomain.com:123456" (without quotes). + +To recalculate and update ha1 and ha1b columns in the subscriber table, just execute the following sql statement in mysql: + +```sql +update subscriber +set ha1 = md5(concat(username, ':', domain, ':', password)), +ha1b = md5(concat(username, '@', domain, ':', domain, ':', password)) +``` + +> [!NOTE] +> The above is only true if you have `use_domain` enabled *and* you do not use a static challenge parameter for `www_authorize()`. + +If you use a static challenge for `www_authorize()` (i.e. the first parameter of `www_authorize()` is not the empty string), then HA1 is MD5("username:challenge:password") and HA1B is MD5("username@challenge:challenge:password"). If the challenge parameter of `www_authorize()` is empty, OpenSIPS automatically selects the domain as the challenge value, which gives the solution presented above. + +If `use_domain` is false, then the HA1B field must be computed based on "username@:domain:password" or "username@:challenge:password", depending on whether challenge is empty or defined, respectively. + + + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/auth_db/doc/auth_db.xml b/modules/auth_db/doc/auth_db.xml deleted file mode 100644 index 8e672788266..00000000000 --- a/modules/auth_db/doc/auth_db.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Auth_db Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005 &voicesystem; - ©right; 2002-2003 &fhg; - diff --git a/modules/auth_db/doc/auth_db_admin.xml b/modules/auth_db/doc/auth_db_admin.xml deleted file mode 100644 index 40e934bbe81..00000000000 --- a/modules/auth_db/doc/auth_db_admin.xml +++ /dev/null @@ -1,673 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module contains all authentication related functions that need - the access to the database. This module should be used together with - auth module, it cannot be used independently because it depends on - the module. Select this module if you want to use database to store - authentication information like subscriber usernames and passwords. If - you want to use radius authentication, then use auth_radius instead. - - -
- RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, - auth_db and - uac_auth - modules include support for two new digest authentication algorithms - ("SHA-256" and "SHA-512-256"), according to the - RFC 8760 - specs. - -
-
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - auth -- Generic authentication - functions - - - - database -- Any database module - (currently mysql, postgres, dbtext) - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - none - - -
-
- - -
- Exported Parameters -
- <varname>db_url</varname> (string) - - This is URL of the database to be used. Value of the parameter depends - on the database module used. For example for mysql and postgres modules - this is something like mysql://username:password@host:port/database. - For dbtext module (which stores data in plaintext files) it is - directory in which the database resides. - - - - Default value is &defaultrodb;. - - - - <varname>db_url</varname> parameter usage - -modparam("auth_db", "db_url", "&exampledb;") - - -
- -
- <varname>calculate_ha1</varname> (integer) - - This parameter tells the server whether it should considered the - loaded password (for authentification) as plaintext passwords or - a pre-calculated HA1 string. - - - Possible meanings of this parameter are: - - - 1 (calculate HA1) - the loaded - password is a plaintext password, so OpenSIPS will internally - calculate the HA1. As the passwords will be loaded from the column - specified in the parameter, - be sure this parameter points to a column holding a plaintext password - (by default, this parameter points to the ha1 column); - - - 0 (do not - calculate HA1) - the loaded password is a pre-computed - HA1 hash (no calculation needed). The module will load all hashes - stored in the , - and - columns, then use - the hash corresponding to the hashing algorithm selected for a - given digest authentication challenge. - - - - The content of the hash columns can be generated as follows: - - password_column: MD5(username:realm:password) - - hash_column_sha256: SHA-256(username:realm:password) - - hash_column_sha512t256: SHA-512-256(username:realm:password) - - - - - - - - Default value of this parameter is - 0 (use hashed passwords). - - - <varname>calculate_ha1</varname> parameter usage - -modparam("auth_db", "calculate_ha1", 1) - - -
- -
- <varname>use_domain</varname> (integer) - - If true (not 0), domain will be also used when looking up in the - subscriber table. If you have a multi-domain setup, it is strongly - recommended to turn on this parameter to avoid username overlapping - between domains. - - - IMPORTANT: before turning on this parameter, be sure that the - domain column in subscriber - table is properly populated. - - - Default value is 0 (false). - - - <varname>use_domain</varname> parameter usage - -modparam("auth_db", "use_domain", 1) - - -
- -
- <varname>load_credentials</varname> (string) - - This parameter specifies credentials to be fetched from database when - the authentication is performed. The loaded credentials will be stored - in AVPs. If the AVP name is not specificaly given, it will be used a - NAME AVP with the same name as the column name. - - - Parameter syntax: - - - load_credentials = credential (';' credential)* - - - credential = (avp_specification '=' column_name) | - (column_name) - - - avp_specification = '$avp(' + NAME + ')' - - - - - Default value of this parameter is rpid. - - - <varname>load_credentials</varname> parameter usage - -# load rpid column into $avp(13) and email_address column -# into $avp(email_address) -modparam("auth_db", "load_credentials", "$avp(13)=rpid;email_address") - - -
- -
- <varname>skip_version_check</varname> (int) - - This parameter specifies not to check the auth table version. This - parameter should be set when a custom authentication table is used. - - - Default value is 0 (false). - - - <varname>skip_version_check</varname> parameter usage - -modparam("auth_db", "skip_version_check", 1) - - -
- -
- <varname>user_column</varname> (string) - - This is the name of the column in a 'SUBSCRIBER' like table holding - the usernames. Default value is fine for most people. - Use the parameter if you really need to change it. - - - Default value is username. - - - <varname>user_column</varname> parameter usage - -modparam("auth_db", "user_column", "user") - - -
- -
- <varname>domain_column</varname> (string) - - This is the name of the column in a 'SUBSCRIBER' like table holding - the domains of users. Default value is fine for most people. - Use the parameter if you really need to - change it. - - - Default value is domain. - - - <varname>domain_column</varname> parameter usage - -modparam("auth_db", "domain_column", "domain") - - -
- -
- <varname>password_column</varname> (string) - - This is the name of the column in a "subscriber" - like table holding MD5 HA1 hash strings or plaintext passwords. An MD5 HA1 - hash is an MD5 hash of username, password and realm. Storing hashes in the - DB (as opposed to passwords directly) is much more secure, because the - server does not need to know plaintext passwords and because it is - computationally infeasible for an attacker to reverse-obtain a password - from an HA1 string. - - - Default value is ha1. - - - <varname>password_column</varname> parameter usage - -modparam("auth_db", "password_column", "password") - - -
- -
- <varname>hash_column_sha256</varname> (string) - - The name of the column holding SHA-256 HA1 hashes - (RFC 8760 support). - - - - Default value is ha1_sha256. - - - <varname>password_column</varname> parameter usage - -modparam("auth_db", "hash_column_sha256", "ha1_sha256") - - -
- -
- <varname>hash_column_sha512t256</varname> (string) - - The name of the column holding SHA-512/256 HA1 hashes. - (RFC 8760 support). - - - Default value is ha1_sha512t256. - - - <varname>password_column</varname> parameter usage - -modparam("auth_db", "hash_column_sha512t256", "ha1_sha512t256") - - -
- -
- <varname>uri_user_column</varname> (string) - - Column holding usernames in an 'URI' like table. - - - - Default value is username. - - - - Set <varname>uri_user_column</varname> parameter - -... -modparam("auth_db", "uri_user_column", "username") -... - - -
- -
- <varname>uri_domain_column</varname> (string) - - Column holding domain in an 'URI' like table. - - - - Default value is domain. - - - - Set <varname>uri_domain_column</varname> parameter - -... -modparam("auth_db", "uri_domain_column", "domain") -... - - -
- -
- <varname>uri_uriuser_column</varname> (string) - - Column holding &uri; username in an 'URI' like table. - - - - Default value is uri_user. - - - - Set <varname>uriuser_column</varname> parameter - -... -modparam("auth_db", "uri_uriuser_column", "uri_user") -... - - -
- - - -
- -
- Exported Functions -
- - <function moreinfo="none">www_authorize(realm, table)</function> - - - The function verifies the received credentials against a - "SUBSCRIBER"-like table according to digest authentication as per - RFC2617. - If the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials - can be later used by some other functions). If the function was - unable to verify the - credentials for some reason then it will fail and the script should - call www_challenge which will - challenge the user again. - - Negative codes may be interpreted as follows: - - - -5 (generic error) - some generic error - occurred and no reply was sent out; - - - -4 (no credentials) - credentials were not - found in request; - - - -3 (stale nonce) - stale nonce; - - - -2 (invalid password) - valid user, but - wrong password; - - - -1 (invalid user) - authentication user does - not exist. - - - Meaning of the parameters is as follows: - - - realm (string) - Realm is an opaque string that - the user agent should present to the user so it can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. In case of REGISTER requests To - header field domain will be used (because this header field - represents a user being registered), for all other messages From - header field domain will be used. - - - The string may contain pseudo variables. - - - - table (string) - Table to be used to lookup - usernames and passwords (usually subscribers table). - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">www_authorize</function> usage - -... -if (!www_authorize("siphub.net", "subscriber")) - www_challenge("siphub.net", "auth"); -... - - -
- -
- - <function moreinfo="none">proxy_authorize(realm, table)</function> - - - The function verifies the received credentials against a - "SUBSCRIBER"-like table according to digest authentication as per - RFC2617. If - the credentials are verified successfully then the function will - succeed and mark the credentials as authorized (marked credentials can - be later used by some other functions). If the function was unable to - verify the credentials for some reason then it will fail and - the script should call - proxy_challenge which will - challenge the user again. - - Negative codes may be interpreted as follows: - - - -5 (generic error) - some generic - error occurred and no reply was sent out; - - - -4 (no credentials) - credentials - were not found in request; - - - -3 (stale nonce) - stale nonce; - - - -2 (invalid password) - valid user, - but wrong password; - - - -1 (invalid user) - authentication - user does not exist. - - - Meaning of the parameters is as follows: - - - realm (string) - Realm is an opaque string that - the user agent should present to the user so it can decide what - username and password to use. Usually this is domain of the host - the server is running on. - - - If an empty string is used then the server will - generate it from the request. From header field domain will be - used as realm. - - - The string may contain pseudo variables. - - - - table (string) - Table to be used to lookup - usernames and passwords (usually subscribers table). - - - - - This function can be used from REQUEST_ROUTE. - - - proxy_authorize usage - -... -if (!proxy_authorize("", "subscriber")) - proxy_challenge("", "auth"); # Realm will be autogenerated -... - - -
- -
- - <function moreinfo="none">db_is_to_authorized(table)</function> - - - The function checks against a 'URI' like table to see if the - username extracted from the To header URI is allowed/authorized to - use the credentials (authentication username) validated by - . - - - The function is part of the mechanism that allows to create - mapping between the SIP users (from the FROM/TO headers) and the - authentication users (from a SUBSCRIBER-like table) that they use. The - mapping is stored into an URI-like table. - - Meaning of the parameters is as follows: - - - table (string) - Table to be used to lookup - for the URI/AUTH mappings (usually the URI table). - - - - - This function can be used from REQUEST_ROUTE. - - - <function>db_is_to_authorized</function> usage - -... -if (!db_is_to_authorized("uri")) { - xlog("User $tu is not authorized to authenticate with $au credential\n"); -} -... - - -
- -
- - <function moreinfo="none">db_is_from_authorized(table)</function> - - - Similar to but instead of - checking the TO header URI, the FROM header URI is checked. - -
- -
- - <function moreinfo="none">db_does_uri_exist(uri, table)</function> - - - Checks if the username@domain from the given &uri; is an existing - user in a 'SUBSCRIBER' like table. - - Meaning of the parameters is as follows: - - - uri (string) - The SIP URI to be tested. It must - hold a username part for a valid check. Variables are allowed. - - - - table (string) - Table to be used to search - for the URI (usually the SUBSCRIBER table). - - - - - This function can be used from REQUEST_ROUTE. - - - <function>db_does_uri_exist</function> usage - -... -if (db_does_uri_exist($ru, "subscriber")) { - ... -} -... - - -
- -
- - <function moreinfo="none">db_get_auth_id(table, uri, auth, realm)</function> - - - Checks given uri-string username against an 'URI' like table. - Returns true if the user exists in the database, and sets the given - variables to the authentication id and realm corresponding to - the given uri. - - Meaning of the parameters is as follows: - - - table (string) - Table to be used to search - for the URI (usually the URI table). - - - - uri (string) - The input SIP URI to be tested. - It must hold a username part for a valid check. - Variables are allowed. - - - - auth (var) - an output variable to store the - found authentication id matching the given SIP URI. - - - - realm (var) - an output variable to store the - found authentication realm matching the given SIP URI. - - - - - This function can be used from REQUEST_ROUTE ,FAILURE_ROUTE and - LOCAL_ROUTE. - - - <function>db_get_auth_id</function> usage - -... -if (db_get_auth_id("uri", $ru, $avp(auth_id), $avp(auth_realm))) { - ... -} -... - - -
- -
-
- diff --git a/modules/auth_db/doc/contributors.xml b/modules/auth_db/doc/contributors.xml deleted file mode 100644 index 4b48d3d6da8..00000000000 --- a/modules/auth_db/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 51 - 37 - 783 - 380 - - - 2. - Jan Janak (@janakj) - 50 - 29 - 1610 - 424 - - - 3. - Daniel-Constantin Mierla (@miconda) - 29 - 20 - 130 - 382 - - - 4. - Liviu Chircu (@liviuchircu) - 23 - 18 - 161 - 137 - - - 5. - Henning Westerholt (@henningw) - 11 - 9 - 83 - 49 - - - 6. - Razvan Crainea (@razvancrainea) - 10 - 8 - 30 - 48 - - - 7. - Maksym Sobolyev (@sobomax) - 10 - 5 - 307 - 116 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 8 - 4 - 69 - 163 - - - 9. - Sergio Gutierrez - 7 - 5 - 13 - 13 - - - 10. - Andrei Pelinescu-Onciul - 6 - 4 - 81 - 33 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Jiri Kuthan (@jiriatipteldotorg), Walter Doekes (@wdoekes), Anatoly Pidruchny, Kennard White, Konstantin Bokarius, Richard Revels, Julián Moreno Patiño, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Ionut Ionita (@ionutrazvanionita). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jan 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2004 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2005 - Jul 2021 - - - 5. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Jan 2015 - Jan 2015 - - - 10. - Richard Revels - Sep 2011 - Sep 2011 - - - -
-All remaining contributors: Kennard White, Dan Pascu (@danpascu), Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Anatoly Pidruchny, Norman Brandinger (@NormB), Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Maksym Sobolyev (@sobomax), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Kennard White, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Anatoly Pidruchny, Jan Janak (@janakj). -
- -
diff --git a/modules/auth_jwt/README b/modules/auth_jwt/README deleted file mode 100644 index a8b9ff58ad9..00000000000 --- a/modules/auth_jwt/README +++ /dev/null @@ -1,405 +0,0 @@ -AUTH_JWT Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_mode (int) - 1.3.2. db_url (string) - 1.3.3. profiles_table (string) - 1.3.4. secrets_table (string) - 1.3.5. tag_column (string) - 1.3.6. username_column (string) - 1.3.7. secret_tag_column (string) - 1.3.8. secret_column (string) - 1.3.9. start_ts_column (string) - 1.3.10. end_ts_column (string) - 1.3.11. tag_claim (string) - 1.3.12. load_credentials (string) - - 1.4. Exported Functions - - 1.4.1. - jwt_db_authorize(jwt_token,out_decoded_token,o - ut_sip_username) - - 1.4.2. jwt_script_authorize(jwt_token,key, - out_decoded_token) - - 1.4.3. - extract_pub_key_from_cert(certificate,out_publ - ic_key) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. db_mode parameter usage - 1.2. db_url parameter usage - 1.3. profiles_table parameter usage - 1.4. secrets_table parameter usage - 1.5. Set tag_column parameter - 1.6. Set username_column parameter - 1.7. Set secret_tag_column parameter - 1.8. set secret_column parameter - 1.9. set start_ts parameter - 1.10. set end_ts parameter - 1.11. set tag_claim parameter - 1.12. load_credentials parameter usage - 1.13. jwt_db_authorize usage - 1.14. jwt_script_authorize usage - 1.15. extract_pub_key_from_cert usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements authentication over JSON Web Tokens. In - some cases ( ie. WebRTC ) the user authenticates on another - layer ( other than SIP ), so it makes no sense to - double-authenticate it on the SIP layer. Thus, the SIP client - will simply present the JWT auth token it received from the - server, and pass it on to OpenSIPS which will use that for - authentication purposes. It relies on two DB tables, one - containing JWT profiles ( a profile name and it's SIP username - associated to it ) and one containing JWT secrets. Each secret - has a corresponding profile, the KEY used for signing the JWT - and two timestamps describing a validation interval. Multiple - JWT secrets can point to the same JWT profile. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * database -- Any database module (currently mysql, postgres, - dbtext) , in case the db_url parameter is set - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libjwt-dev - * openssl-dev or libssl-dev - -1.3. Exported Parameters - -1.3.1. db_mode (int) - - If set to 0, the module won't connect to the Database for - reading the Keys for decoding JWTs - only jwt_script_authorize - will be usable from the script. - - Default value is “0”. - - Example 1.1. db_mode parameter usage -modparam("auth_jwt", "db_mode", 0) - -1.3.2. db_url (string) - - This is URL of the database to be used. Value of the parameter - depends on the database module used. For example for mysql and - postgres modules this is something like - mysql://username:password@host:port/database. For dbtext module - (which stores data in plaintext files) it is directory in which - the database resides. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips”. - - Example 1.2. db_url parameter usage -modparam("auth_jwt", "db_url", "dbdriver://username:password@dbhost/dbna -me") - -1.3.3. profiles_table (string) - - Name of the DB table containing the jwt profiles - - Default value of this parameter is jwt_profiles. - - Example 1.3. profiles_table parameter usage -modparam("auth_jwt", "profiles_table", "my_profiles") - -1.3.4. secrets_table (string) - - Name of the DB table containing the jwt secrets - - Default value of this parameter is jwt_secrets. - - Example 1.4. secrets_table parameter usage -modparam("auth_jwt", "secrets_table", "my_secrets") - -1.3.5. tag_column (string) - - Column holding the JWT profile tag. - - Default value is “tag”. - - Example 1.5. Set tag_column parameter -... -modparam("auth_jwt", "tag_column", "my_tag_column") -... - -1.3.6. username_column (string) - - Column holding the JWT profile associated SIP username. - - Default value is “sip_username”. - - Example 1.6. Set username_column parameter -... -modparam("auth_jwt", "username_column", "my_username_column") -... - -1.3.7. secret_tag_column (string) - - Column holding the JWT secret associated tag. - - Default value is “corresponding_tag”. - - Example 1.7. Set secret_tag_column parameter -... -modparam("auth_jwt", "secret_tag_column", "my_secret_tag_column") -... - -1.3.8. secret_column (string) - - Column holding the actual jwt signing secret. - - default value is “secret”. - - Example 1.8. set secret_column parameter -... -modparam("auth_jwt", "secret_column", "my_secret_column") -... - -1.3.9. start_ts_column (string) - - Column holding the JWT secret start UNIX timestamp. - - default value is “start_ts”. - - Example 1.9. set start_ts parameter -... -modparam("auth_jwt", "start_ts", "my_start_ts_column") -... - -1.3.10. end_ts_column (string) - - column holding the jwt secret end unix timestamp. - - default value is “end_ts”. - - Example 1.10. set end_ts parameter -... -modparam("auth_jwt", "end_ts", "my_end_ts_column") -... - -1.3.11. tag_claim (string) - - The JWT claim which will be used to identify the JWT profile - - default value is “tag”. - - Example 1.11. set tag_claim parameter -... -modparam("auth_jwt", "tag_claim", "my_tag_claim") -... - -1.3.12. load_credentials (string) - - This parameter specifies credentials to be fetched from the JWT - profiles table when the authentication is performed. The loaded - credentials will be stored in AVPs. If the AVP name is not - specificaly given, it will be used a NAME AVP with the same - name as the column name. - - Parameter syntax: - * load_credentials = credential (';' credential)* - * credential = (avp_specification '=' column_name) | - (column_name) - * avp_specification = '$avp(' + NAME + ')' - - Default value of this parameter is “none ( empty )”. - - Example 1.12. load_credentials parameter usage -# load my_extra_column into $avp(extra_jwt_info) -modparam("auth_jwt", "load_credentials", "$avp(extra_jwt_info)=my_extra_ -column") - -1.4. Exported Functions - -1.4.1. -jwt_db_authorize(jwt_token,out_decoded_token,out_sip_username) - - The function will read the first param ( jwt_token ), extract - the tag claim and then try to authenticate it against the DB - secrets for the respective profile tag. In case of success, it - populates the out_decoded_token pvar with the decoded JWT ( in - plaintext format header_json.payload_json ) and the - out_sip_username with the SIP username corresponding to that - JWT profile. - - Negative codes may be interpreted as follows: - * -1 ( error) - JWT authentication failed - - Meaning of the parameters is as follows: - * jwt_token (string) - The JWT token to perform auth on - The string may contain pseudo variables. - * out_decoded_token (pvar) - PVAR used to store the decoded - JWT upon succesful auth - * out_sip_username (pvar) - PVAR used to store the SIP - username corresponding to the JWT profile, upon succesful - auth - - This function can be used from REQUEST_ROUTE. - - Example 1.13. jwt_db_authorize usage -... -if (!jwt_db_authorize("$avp(my_jwt_token)", $avp(decoded_token), $avp(si -p_username) )) { - send_reply(401,"Unauthorized"); - exit; -} else { - xlog("Succesful JWT auth - $avp(decoded_token) \n"); - if ($fU != $avp(sip_username)) { - send_reply(403,"Forbidden AUTH ID"); - exit; - } -} -... - -1.4.2. jwt_script_authorize(jwt_token,key, out_decoded_token) - - The function will read the first param ( jwt_token ), decode it - and then try to validate it against the provided key. If the - JWT decoding is succesful, the out_decoded_token pvar will be - populated. Return codes are : - * -2 : Failure in decoding the JWT ( out_decoded_token will - not be populated ) - * -1 : Failure in validating the JWT ( out_decoded_token will - be populated ) - * 1 : JWT succesfully validated with the key ( - out_decoded_token will be populated ) - - Meaning of the parameters is as follows: - * jwt_token (string) - The JWT token to perform auth on - The string may contain pseudo variables. - * key (string) - The key to be used for validating the JWT. - * out_decoded_token (pvar) - PVAR used to store the decoded - JWT - - This function can be used from REQUEST_ROUTE. - - Example 1.14. jwt_script_authorize usage -... -if (!jwt_script_authorize("$avp(my_jwt_token)",$avp(pub_key), $avp(decod -ed_token))) { - send_reply(401,"Unauthorized"); - exit; -} else { - xlog("Succesful JWT auth - $avp(decoded_token) \n"); -} -... - -1.4.3. extract_pub_key_from_cert(certificate,out_public_key) - - The function will read the first param ( certificate ), decode - it and then try to extract the public key with the certificate. - If the extraction is succesful, the out_public_key will be - populated. Useful to be used in conjuction with the - jwt_script_authorize function, since most providers make their - certificates public, but the JWTs are signed with the actual - public key embeded in the certificate. Return codes are : - * -1 : Failure in extracting the pub key - * 1 : out_public_key succesfully populated - - Meaning of the parameters is as follows: - * certificate (string) - The certificate to read and from - which to extract the public key - The string may contain pseudo variables. - * out_public_key (pvar) - PVAR used to store the extracted - public key - - This function can be used from REQUEST_ROUTE. - - Example 1.15. extract_pub_key_from_cert usage -... -if (extract_pub_key_from_cert("$avp(my_certificate)",$avp(my_pub_key))) -{ - xlog("Succesfully extracted public key - $avp(my_pub_key) \n"); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 20 6 1521 16 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 8 8 - 3. Liviu Chircu (@liviuchircu) 5 3 4 6 - 4. Alexandra Titoc 3 1 5 4 - 5. Maksym Sobolyev (@sobomax) 3 1 3 3 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2020 - Aug 2025 - 2. Liviu Chircu (@liviuchircu) May 2023 - Sep 2024 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Vlad Paiu (@vladpaiu) Mar 2020 - Jul 2023 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu - (@vladpaiu). diff --git a/modules/auth_jwt/README.md b/modules/auth_jwt/README.md new file mode 100644 index 00000000000..72fb756b46a --- /dev/null +++ b/modules/auth_jwt/README.md @@ -0,0 +1,359 @@ +--- +title: "AUTH_JWT Module" +description: "The module implements authentication over JSON Web Tokens." +--- + +## Admin Guide + + +### Overview + + +The module implements authentication over JSON Web Tokens. +In some cases ( ie. WebRTC ) the user authenticates on another layer ( other than SIP ), so it makes no sense to double-authenticate it on the SIP layer. +Thus, the SIP client will simply present the JWT auth token it received from the server, and pass it on to OpenSIPS which will use that for authentication purposes. + +It relies on two DB tables, one containing JWT profiles ( a profile name and it's SIP username associated to it ) and one containing JWT secrets. Each secret has a corresponding profile, the KEY used for signing the JWT and two timestamps describing a validation interval. Multiple JWT secrets can point to the same JWT profile. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *database* -- Any database module +(currently mysql, postgres, dbtext) , in case the db_url parameter is set + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *libjwt-dev* +- *openssl-dev* or +*libssl-dev* + + +### Exported Parameters + + +#### db_mode (int) + + +If set to 0, the module won't connect to the Database for reading the Keys for decoding JWTs - only jwt_script_authorize will be usable from the script. + + +*Default value is "0".* + + +```opensips title="db_mode parameter usage" +modparam("auth_jwt", "db_mode", 0) +``` + + +#### db_url (string) + + +This is URL of the database to be used. Value of the parameter depends +on the database module used. For example for mysql and postgres modules +this is something like mysql://username:password@host:port/database. +For dbtext module (which stores data in plaintext files) it is +directory in which the database resides. + + +*Default value is "mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="db_url parameter usage" +modparam("auth_jwt", "db_url", "dbdriver://username:password@dbhost/dbname") +``` + + +#### profiles_table (string) + + +Name of the DB table containing the jwt profiles + + +Default value of this parameter is jwt_profiles. + + +```opensips title="profiles_table parameter usage" +modparam("auth_jwt", "profiles_table", "my_profiles") +``` + + +#### secrets_table (string) + + +Name of the DB table containing the jwt secrets + + +Default value of this parameter is jwt_secrets. + + +```opensips title="secrets_table parameter usage" +modparam("auth_jwt", "secrets_table", "my_secrets") +``` + + +#### tag_column (string) + + +Column holding the JWT profile tag. + + +*Default value is "tag".* + + +```opensips title="Set tag_column parameter" +... +modparam("auth_jwt", "tag_column", "my_tag_column") +... +``` + + +#### username_column (string) + + +Column holding the JWT profile associated SIP username. + + +*Default value is "sip_username".* + + +```opensips title="Set username_column parameter" +... +modparam("auth_jwt", "username_column", "my_username_column") +... +``` + + +#### secret_tag_column (string) + + +Column holding the JWT secret associated tag. + + +*Default value is "corresponding_tag".* + + +```opensips title="Set secret_tag_column parameter" +... +modparam("auth_jwt", "secret_tag_column", "my_secret_tag_column") +... +``` + + +#### secret_column (string) + + +Column holding the actual jwt signing secret. + + +*default value is "secret".* + + +```opensips title="set secret_column parameter" +... +modparam("auth_jwt", "secret_column", "my_secret_column") +... +``` + + +#### start_ts_column (string) + + +Column holding the JWT secret start UNIX timestamp. + + +*default value is "start_ts".* + + +```opensips title="set start_ts parameter" +... +modparam("auth_jwt", "start_ts", "my_start_ts_column") +... +``` + + +#### end_ts_column (string) + + +column holding the jwt secret end unix timestamp. + + +*default value is "end_ts".* + + +```opensips title="set end_ts parameter" +... +modparam("auth_jwt", "end_ts", "my_end_ts_column") +... +``` + + +#### tag_claim (string) + + +The JWT claim which will be used to identify the JWT profile + + +*default value is "tag".* + + +```opensips title="set tag_claim parameter" +... +modparam("auth_jwt", "tag_claim", "my_tag_claim") +... +``` + + +#### load_credentials (string) + + +This parameter specifies credentials to be fetched from the JWT profiles table when +the authentication is performed. The loaded credentials will be stored +in AVPs. If the AVP name is not specificaly given, it will be used a +NAME AVP with the same name as the column name. + + +Parameter syntax: + + +- *load_credentials = credential (';' credential)** +- *credential = (avp_specification '=' column_name) | +(column_name)* +- *avp_specification = '$avp(' + NAME + ')'* + + +Default value of this parameter is "none ( empty )". + + +```opensips title="load_credentials parameter usage" +# load my_extra_column into $avp(extra_jwt_info) +modparam("auth_jwt", "load_credentials", "$avp(extra_jwt_info)=my_extra_column") +``` + + +### Exported Functions + + +#### jwt_db_authorize(jwt_token,out_decoded_token,out_sip_username) + + +The function will read the first param ( jwt_token ), extract the tag claim and then try to authenticate it against the DB secrets for the respective profile tag. In case of success, it populates the out_decoded_token pvar with the decoded JWT ( in plaintext format header_json.payload_json ) and the out_sip_username with the SIP username corresponding to that JWT profile. + + +Negative codes may be interpreted as follows: + + +- *-1 ( error)* - JWT authentication failed + + +Meaning of the parameters is as follows: + + +- *jwt_token (string)* - The JWT token to perform auth on +The string may contain pseudo variables. +- *out_decoded_token (pvar)* - PVAR used to store the decoded JWT upon succesful auth +- *out_sip_username (pvar)* - PVAR used to store the SIP username corresponding to the JWT profile, upon succesful auth + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jwt_db_authorize usage" +... +if (!jwt_db_authorize("$avp(my_jwt_token)", $avp(decoded_token), $avp(sip_username) )) { + send_reply(401,"Unauthorized"); + exit; +} else { + xlog("Succesful JWT auth - $avp(decoded_token) \n"); + if ($fU != $avp(sip_username)) { + send_reply(403,"Forbidden AUTH ID"); + exit; + } +} +... +``` + + +#### jwt_script_authorize(jwt_token,key, out_decoded_token) + + +The function will read the first param ( jwt_token ), decode it and then try to validate it against the provided key. If the JWT decoding is succesful, the out_decoded_token pvar will be populated. +Return codes are : + + +- -2 : Failure in decoding the JWT ( out_decoded_token will not be populated ) +- -1 : Failure in validating the JWT ( out_decoded_token will be populated ) +- 1 : JWT succesfully validated with the key ( out_decoded_token will be populated ) + + +Meaning of the parameters is as follows: + + +- *jwt_token (string)* - The JWT token to perform auth on +The string may contain pseudo variables. +- *key (string)* - The key to be used for validating the JWT. +- *out_decoded_token (pvar)* - PVAR used to store the decoded JWT + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jwt_script_authorize usage" +... +if (!jwt_script_authorize("$avp(my_jwt_token)",$avp(pub_key), $avp(decoded_token))) { + send_reply(401,"Unauthorized"); + exit; +} else { + xlog("Succesful JWT auth - $avp(decoded_token) \n"); +} +... +``` + + +#### extract_pub_key_from_cert(certificate,out_public_key) + + +The function will read the first param ( certificate ), decode it and then try to extract the public key with the certificate. If the extraction is succesful, the out_public_key will be populated. Useful to be used in conjuction with the jwt_script_authorize function, since most providers make their certificates public, but the JWTs are signed with the actual public key embeded in the certificate. +Return codes are : + + +- -1 : Failure in extracting the pub key +- 1 : out_public_key succesfully populated + + +Meaning of the parameters is as follows: + + +- *certificate (string)* - The certificate to read and from which to extract the public key +The string may contain pseudo variables. +- *out_public_key (pvar)* - PVAR used to store the extracted public key + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="extract_pub_key_from_cert usage" +... +if (extract_pub_key_from_cert("$avp(my_certificate)",$avp(my_pub_key))) { + xlog("Succesfully extracted public key - $avp(my_pub_key) \n"); +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/auth_jwt/authorize.c b/modules/auth_jwt/authorize.c index b844ac12da0..2042400aff2 100644 --- a/modules/auth_jwt/authorize.c +++ b/modules/auth_jwt/authorize.c @@ -34,6 +34,7 @@ #include "../../usr_avp.h" #include "../../mod_fix.h" #include "../../mem/mem.h" +#include "../../strcommon.h" #include "jwt_avps.h" #include "authjwt_mod.h" @@ -57,12 +58,13 @@ int jwt_db_authorize(struct sip_msg* _msg, str* jwt_token, pv_spec_t* decoded_jwt, pv_spec_t* auth_user) { char raw_query_s[RAW_QUERY_BUF_LEN], *p; + char *escaped_tag_buf = NULL; int n,len, i,j; str raw_query,secret; struct jwt_avp *cred; char *jwt_token_buf = NULL,*tag_s; jwt_t *jwt = NULL,*jwt_dec=NULL; - str tag; + str tag, escaped_tag; db_res_t *res = NULL; db_row_t *row; pv_value_t pv_val; @@ -98,6 +100,22 @@ int jwt_db_authorize(struct sip_msg* _msg, str* jwt_token, tag.s = tag_s; tag.len = strlen(tag_s); + /* Escape the tag value to prevent SQL injection + * escape_common() escapes single quotes, double quotes, backslashes, and null bytes + * Allocate buffer for worst case: each char escaped = 2x original length + 1 for null + */ + escaped_tag_buf = pkg_malloc(tag.len * 2 + 1); + if (!escaped_tag_buf) { + LM_ERR("No more pkg mem for escaped tag\n"); + goto err_out; + } + + escaped_tag.len = escape_common(escaped_tag_buf, tag.s, tag.len); + escaped_tag.s = escaped_tag_buf; + + LM_DBG("Escaped JWT tag claim from [%.*s] to [%.*s]\n", + tag.len, tag.s, escaped_tag.len, escaped_tag.s); + raw_query.s = raw_query_s; p = raw_query_s; len = RAW_QUERY_BUF_LEN; @@ -121,7 +139,7 @@ int jwt_db_authorize(struct sip_msg* _msg, str* jwt_token, tag_column.len,tag_column.s, secret_tag_column.len,secret_tag_column.s, tag_column.len,tag_column.s, - tag.len,tag.s, + escaped_tag.len,escaped_tag.s, unix_ts, start_ts_column.len,start_ts_column.s, unix_ts, end_ts_column.len,end_ts_column.s); @@ -227,6 +245,8 @@ int jwt_db_authorize(struct sip_msg* _msg, str* jwt_token, LM_INFO("Validated jwt %s with key %.*s\n",jwt_dump_str(jwt_dec,0),secret.len,secret.s); auth_dbf.free_result(auth_db_handle, res); + if (escaped_tag_buf) + pkg_free(escaped_tag_buf); if (jwt_token_buf) pkg_free(jwt_token_buf); if (jwt) @@ -239,6 +259,8 @@ int jwt_db_authorize(struct sip_msg* _msg, str* jwt_token, auth_dbf.free_result(auth_db_handle, res); err_out: + if (escaped_tag_buf) + pkg_free(escaped_tag_buf); if (jwt_token_buf) pkg_free(jwt_token_buf); if (jwt) diff --git a/modules/auth_jwt/doc/auth_jwt.xml b/modules/auth_jwt/doc/auth_jwt.xml deleted file mode 100644 index ab12f587743..00000000000 --- a/modules/auth_jwt/doc/auth_jwt.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - AUTH_JWT Module - - - - &admin; - &faq; - &contrib; - diff --git a/modules/auth_jwt/doc/auth_jwt_admin.xml b/modules/auth_jwt/doc/auth_jwt_admin.xml deleted file mode 100644 index f2bf2b34146..00000000000 --- a/modules/auth_jwt/doc/auth_jwt_admin.xml +++ /dev/null @@ -1,477 +0,0 @@ - - - &adminguide; - -
- Overview - - The module implements authentication over JSON Web Tokens. - In some cases ( ie. WebRTC ) the user authenticates on another layer ( other than SIP ), so it makes no sense to double-authenticate it on the SIP layer. - Thus, the SIP client will simply present the JWT auth token it received from the server, and pass it on to OpenSIPS which will use that for authentication purposes. - - It relies on two DB tables, one containing JWT profiles ( a profile name and it's SIP username associated to it ) and one containing JWT secrets. Each secret has a corresponding profile, the KEY used for signing the JWT and two timestamps describing a validation interval. Multiple JWT secrets can point to the same JWT profile. - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - database -- Any database module - (currently mysql, postgres, dbtext) , in case the db_url parameter is set - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - libjwt-dev - - - openssl-dev or - libssl-dev - - - -
-
- - -
- Exported Parameters -
- <varname>db_mode</varname> (int) - - If set to 0, the module won't connect to the Database for reading the Keys for decoding JWTs - only jwt_script_authorize will be usable from the script. - - - - Default value is 0. - - - - <varname>db_mode</varname> parameter usage - -modparam("auth_jwt", "db_mode", 0) - - -
-
- <varname>db_url</varname> (string) - - This is URL of the database to be used. Value of the parameter depends - on the database module used. For example for mysql and postgres modules - this is something like mysql://username:password@host:port/database. - For dbtext module (which stores data in plaintext files) it is - directory in which the database resides. - - - - Default value is &defaultrodb;. - - - - <varname>db_url</varname> parameter usage - -modparam("auth_jwt", "db_url", "&exampledb;") - - -
- -
- <varname>profiles_table</varname> (string) - - Name of the DB table containing the jwt profiles - - - Default value of this parameter is jwt_profiles. - - - <varname>profiles_table</varname> parameter usage - -modparam("auth_jwt", "profiles_table", "my_profiles") - - -
- -
- <varname>secrets_table</varname> (string) - - Name of the DB table containing the jwt secrets - - - Default value of this parameter is jwt_secrets. - - - <varname>secrets_table</varname> parameter usage - -modparam("auth_jwt", "secrets_table", "my_secrets") - - -
- -
- <varname>tag_column</varname> (string) - - Column holding the JWT profile tag. - - - - Default value is tag. - - - - Set <varname>tag_column</varname> parameter - -... -modparam("auth_jwt", "tag_column", "my_tag_column") -... - - -
- -
- <varname>username_column</varname> (string) - - Column holding the JWT profile associated SIP username. - - - - Default value is sip_username. - - - - Set <varname>username_column</varname> parameter - -... -modparam("auth_jwt", "username_column", "my_username_column") -... - - -
- -
- <varname>secret_tag_column</varname> (string) - - Column holding the JWT secret associated tag. - - - - Default value is corresponding_tag. - - - - Set <varname>secret_tag_column</varname> parameter - -... -modparam("auth_jwt", "secret_tag_column", "my_secret_tag_column") -... - - -
- -
- <varname>secret_column</varname> (string) - - Column holding the actual jwt signing secret. - - - - default value is secret. - - - - set <varname>secret_column</varname> parameter - -... -modparam("auth_jwt", "secret_column", "my_secret_column") -... - - -
- -
- <varname>start_ts_column</varname> (string) - - Column holding the JWT secret start UNIX timestamp. - - - - default value is start_ts. - - - - set <varname>start_ts</varname> parameter - -... -modparam("auth_jwt", "start_ts", "my_start_ts_column") -... - - -
- -
- <varname>end_ts_column</varname> (string) - - column holding the jwt secret end unix timestamp. - - - - default value is end_ts. - - - - set <varname>end_ts</varname> parameter - -... -modparam("auth_jwt", "end_ts", "my_end_ts_column") -... - - -
- -
- <varname>tag_claim</varname> (string) - - The JWT claim which will be used to identify the JWT profile - - - - default value is tag. - - - - set <varname>tag_claim</varname> parameter - -... -modparam("auth_jwt", "tag_claim", "my_tag_claim") -... - - -
- - -
- <varname>load_credentials</varname> (string) - - This parameter specifies credentials to be fetched from the JWT profiles table when - the authentication is performed. The loaded credentials will be stored - in AVPs. If the AVP name is not specificaly given, it will be used a - NAME AVP with the same name as the column name. - - - Parameter syntax: - - - load_credentials = credential (';' credential)* - - - credential = (avp_specification '=' column_name) | - (column_name) - - - avp_specification = '$avp(' + NAME + ')' - - - - - Default value of this parameter is none ( empty ). - - - <varname>load_credentials</varname> parameter usage - -# load my_extra_column into $avp(extra_jwt_info) -modparam("auth_jwt", "load_credentials", "$avp(extra_jwt_info)=my_extra_column") - - -
- - - -
- -
- Exported Functions -
- - <function moreinfo="none">jwt_db_authorize(jwt_token,out_decoded_token,out_sip_username)</function> - - - The function will read the first param ( jwt_token ), extract the tag claim and then try to authenticate it against the DB secrets for the respective profile tag. In case of success, it populates the out_decoded_token pvar with the decoded JWT ( in plaintext format header_json.payload_json ) and the out_sip_username with the SIP username corresponding to that JWT profile. - - Negative codes may be interpreted as follows: - - - -1 ( error) - JWT authentication failed - - - Meaning of the parameters is as follows: - - - jwt_token (string) - The JWT token to perform auth on - - - The string may contain pseudo variables. - - - - out_decoded_token (pvar) - PVAR used to store the decoded JWT upon succesful auth - - - - out_sip_username (pvar) - PVAR used to store the SIP username corresponding to the JWT profile, upon succesful auth - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">jwt_db_authorize</function> usage - -... -if (!jwt_db_authorize("$avp(my_jwt_token)", $avp(decoded_token), $avp(sip_username) )) { - send_reply(401,"Unauthorized"); - exit; -} else { - xlog("Succesful JWT auth - $avp(decoded_token) \n"); - if ($fU != $avp(sip_username)) { - send_reply(403,"Forbidden AUTH ID"); - exit; - } -} -... - - -
- -
- - <function moreinfo="none">jwt_script_authorize(jwt_token,key, out_decoded_token)</function> - - - The function will read the first param ( jwt_token ), decode it and then try to validate it against the provided key. If the JWT decoding is succesful, the out_decoded_token pvar will be populated. - Return codes are : - - - - -2 : Failure in decoding the JWT ( out_decoded_token will not be populated ) - - - - - - -1 : Failure in validating the JWT ( out_decoded_token will be populated ) - - - - - - 1 : JWT succesfully validated with the key ( out_decoded_token will be populated ) - - - - - - Meaning of the parameters is as follows: - - - jwt_token (string) - The JWT token to perform auth on - - - The string may contain pseudo variables. - - - - key (string) - The key to be used for validating the JWT. - - - - out_decoded_token (pvar) - PVAR used to store the decoded JWT - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">jwt_script_authorize</function> usage - -... -if (!jwt_script_authorize("$avp(my_jwt_token)",$avp(pub_key), $avp(decoded_token))) { - send_reply(401,"Unauthorized"); - exit; -} else { - xlog("Succesful JWT auth - $avp(decoded_token) \n"); -} -... - - -
- -
- - <function moreinfo="none">extract_pub_key_from_cert(certificate,out_public_key)</function> - - - The function will read the first param ( certificate ), decode it and then try to extract the public key with the certificate. If the extraction is succesful, the out_public_key will be populated. Useful to be used in conjuction with the jwt_script_authorize function, since most providers make their certificates public, but the JWTs are signed with the actual public key embeded in the certificate. - Return codes are : - - - - -1 : Failure in extracting the pub key - - - - - - 1 : out_public_key succesfully populated - - - - - - Meaning of the parameters is as follows: - - - certificate (string) - The certificate to read and from which to extract the public key - - - The string may contain pseudo variables. - - - - out_public_key (pvar) - PVAR used to store the extracted public key - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">extract_pub_key_from_cert</function> usage - -... -if (extract_pub_key_from_cert("$avp(my_certificate)",$avp(my_pub_key))) { - xlog("Succesfully extracted public key - $avp(my_pub_key) \n"); -} -... - - -
- -
-
- diff --git a/modules/auth_jwt/doc/contributors.xml b/modules/auth_jwt/doc/contributors.xml deleted file mode 100644 index 63ee4714fee..00000000000 --- a/modules/auth_jwt/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 20 - 6 - 1521 - 16 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 8 - 8 - - - 3. - Liviu Chircu (@liviuchircu) - 5 - 3 - 4 - 6 - - - 4. - Alexandra Titoc - 3 - 1 - 5 - 4 - - - 5. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2020 - Aug 2025 - - - 2. - Liviu Chircu (@liviuchircu) - May 2023 - Sep 2024 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Vlad Paiu (@vladpaiu) - Mar 2020 - Jul 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/b2b_entities/README b/modules/b2b_entities/README deleted file mode 100644 index 9b3e409423e..00000000000 --- a/modules/b2b_entities/README +++ /dev/null @@ -1,886 +0,0 @@ -B2B_ENTITIES - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. server_hsize (int) - 1.3.2. client_hsize (int) - 1.3.3. script_req_route (str) - 1.3.4. script_reply_route (str) - 1.3.5. db_url (str) - 1.3.6. cachedb_url (str) - 1.3.7. cachedb_key_prefix (string) - 1.3.8. update_period (int) - 1.3.9. b2b_key_prefix (string) - 1.3.10. db_mode (int) - 1.3.11. db_table (str) - 1.3.12. cluster_id (int) - 1.3.13. passthru_prack (int) - 1.3.14. advertised_contact (str) - 1.3.15. ua_default_timeout (str) - - 1.4. Exported Functions - - 1.4.1. ua_session_server_init([key], [flags], - [extra_params]) - - 1.4.2. ua_session_update(key, method, [body], - [extra_headers], [content_type]) - - 1.4.3. ua_session_reply(key, method, code, [reason], - [body], [extra_headers], [content_type]) - - 1.4.4. ua_session_terminate(key, [extra_headers]) - - 1.5. Exported MI Functions - - 1.5.1. b2be_list - 1.5.2. ua_session_client_start - 1.5.3. ua_session_update - 1.5.4. ua_session_reply - 1.5.5. ua_session_terminate - 1.5.6. ua_session_list - - 1.6. Exported Events - - 1.6.1. E_UA_SESSION - - 2. Developer Guide - - 2.1. b2b_load_api(b2b_api_t* api) - 2.2. server_new - 2.3. client_new - 2.4. send_request - 2.5. send_reply - 2.6. entity_delete - 2.7. restore_logic_info - 2.8. update_b2bl_param - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set server_hsize parameter - 1.2. Set client_hsize parameter - 1.3. Set script_req_route parameter - 1.4. Set script_repl_route parameter - 1.5. Set db_url parameter - 1.6. Set cachedb_url parameter - 1.7. Set cachedb_key_prefix parameter - 1.8. Set update_period parameter - 1.9. Set b2b_key_prefix parameter - 1.10. Set db_mode parameter - 1.11. Set db_table parameter - 1.12. Set cluster_id parameter - 1.13. Set passthru_prack parameter - 1.14. Set advertised_contact parameter - 1.15. Set ua_default_timeout parameter - 1.16. ua_session_server_init usage - 1.17. ua_session_update usage - 1.18. ua_session_reply usage - 1.19. ua_session_terminate usage - 2.1. b2b_api_t structure - -Chapter 1. Admin Guide - -1.1. Overview - - The B2BUA implementation in OpenSIPS is separated in two - layers: - * a lower one(coded in this module)- which implements the - basic functions of a UAS and UAC - * a upper one - which represents the logic engine of B2BUA, - responsible of actually implementing the B2BUA services - using the functions offered by the low level. - - This module stores records corresponding to the dialogs in - which the B2BUA is involved. It exports an API to be called - from other modules which offers functions for creating a new - dialog record, for sending requests or replies in one dialog - and will also notify the upper level module when a request or - reply is received inside one stored dialog. The records are - separated in two types: b2b server entities and b2b client - entities depending on the mode they are created. An entity - created for a received initial message will be a server entity, - while a entity that will send an initial request(create a new - dialog) will be a b2b client entity. The name corresponds to - the behavior in the first transaction - if UAS - server entity - and if UAC - client entity. This module does not implement a - B2BUA alone, but needs a B2B logic implementing module. - - The module is able to respond to authentication challanges if - the uac_auth module is loaded first. The list of credentials - for b2b authentication is also provided by the uac_auth module. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - * tm - * a db module - * uac_auth (mandatory if authentication is required) - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.3. Exported Parameters - -1.3.1. server_hsize (int) - - The size of the hash table that stores the b2b server entities. - It is the 2 logarithmic value of the real size. - - Default value is “9” (512 records). - - Example 1.1. Set server_hsize parameter -... -modparam("b2b_entities", "server_hsize", 10) -... - -1.3.2. client_hsize (int) - - The size of the hash table that stores the b2b client entities. - It is the 2 logarithmic value of the real size. - - Default value is “9” (512 records). - - Example 1.2. Set client_hsize parameter -... -modparam("b2b_entities", "client_hsize", 10) -... - -1.3.3. script_req_route (str) - - The name of the b2b script route that will be called when B2B - requests are received. - - Example 1.3. Set script_req_route parameter -... -modparam("b2b_entities", "script_req_route", "b2b_request") -... - -1.3.4. script_reply_route (str) - - The name of the b2b script route that will be called when B2B - replies are received. - - Example 1.4. Set script_repl_route parameter -... -modparam("b2b_entities", "script_reply_route", "b2b_reply") -... - -1.3.5. db_url (str) - - Database URL. It is not compulsory, if not set data is not - stored in database. - - Example 1.5. Set db_url parameter -... -modparam("b2b_entities", "db_url", "mysql://opensips:opensipsrw@127.0.0. -1/opensips") -... - -1.3.6. cachedb_url (str) - - URL of a NoSQL database to be used. Only Redis is supported at - the moment. - - Example 1.6. Set cachedb_url parameter -... -modparam("b2b_entities", "cachedb_url", "redis://localhost:6379/") -... - -1.3.7. cachedb_key_prefix (string) - - Prefix to use for every key set in the NoSQL database. - - Default value is “b2be$”. - - Example 1.7. Set cachedb_key_prefix parameter -... -modparam("b2b_entities", "cachedb_key_prefix", "b2b") -... - -1.3.8. update_period (int) - - The time interval at which to update the info in database. - - Default value is “100”. - - Example 1.8. Set update_period parameter -... -modparam("b2b_entities", "update_period", 60) -... - -1.3.9. b2b_key_prefix (string) - - The string to use when generating the key ( it is inserted in - the SIP messages as callid or to tag. It is useful to set this - prefix if you use more instances of opensips B2BUA cascaded in - the same architecture. Sometimes opensips B2BUA looks at the - callid or totag to see if it has the format it uses to - determine if the request was sent by it. - - Default value is “B2B”. - - Example 1.9. Set b2b_key_prefix parameter -... -modparam("b2b_entities", "b2b_key_prefix", "B2B1") -... - -1.3.10. db_mode (int) - - The B2B modules have support for the 3 type of database storage - - * NO DB STORAGE - set this parameter to 0 - * WRITE THROUGH (synchronous write in database) - set this - parameter to 1 - * WRITE BACK (update in db from time to time) - set this - parameter to 2 - - Default value is “2” (WRITE BACK). - - Example 1.10. Set db_mode parameter -... -modparam("b2b_entities", "db_mode", 1) -... - -1.3.11. db_table (str) - - The name of the table that will be used for storing B2B - entities - - Default value is “b2b_entities” - - Example 1.11. Set db_table parameter -... -modparam("b2b_entities", "db_table", "some table name") -... - -1.3.12. cluster_id (int) - - The ID of the cluster this instance belongs to. Setting this - parameter enables clustering support for the OpenSIPS B2BUA by - replicating the B2B entities (B2B dialogs) between instances. - This also ensures restart persistency through the clusterer - module's data "sync" mechanism. - - This OpenSIPS cluster exposes the "b2be-entities-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - Default value is “0” (clustering disabled) - - Example 1.12. Set cluster_id parameter -... -modparam("b2b_entities", "cluster_id", 10) -... - -1.3.13. passthru_prack (int) - - This parameter allows to control, whether a PRACK should be - generated locally (=0) or if we request it to be end-to-end - (=1). - - Default value is “0” (generate PRACK locally) - - Example 1.13. Set passthru_prack parameter -... -modparam("b2b_entities", "passthru_prack", 1) -... - -1.3.14. advertised_contact (str) - - Contact to use in generated messages for UA session started - with the ua_session_client_start MI function. - - Example 1.14. Set advertised_contact parameter -... -modparam("b2b_entities", "advertised_contact", "opensips@10.10.10.10:506 -0") -... - -1.3.15. ua_default_timeout (str) - - Default timeout, in seconds, for UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. After this interval a BYE - will be sent and the session will be deleted. - - If not set the default is 43200 (12 hours). - - Example 1.15. Set ua_default_timeout parameter -... -modparam("b2b_entities", "ua_default_timeout", 7200) -... - -1.4. Exported Functions - -1.4.1. ua_session_server_init([key], [flags], [extra_params]) - - This function initializes a new UA session by processing an - initial INVITE. Further requests/replies received belonging to - this session will only be handled via the E_UA_SESSION event. - - Parameters: - * key (var, optional) - Variable to return the b2b entity key - of the new UA session. - * flags (string, optional) - configures options for this UA - session via the following flags: - + t[nn] - maximum duration of this session in seconds. - After this timeout a BYE will be sent and the session - will be deleted. If this is not set, the default - timeout, configured with ua_default_timeout will be - used. Example: t3600 - + a - report the receving of ACK requests via the - E_UA_SESSION event. - + r - report the receving of replies via the - E_UA_SESSION event. - + d - disable the automatic sending of ACK upon receving - a 200 OK reply for INVITE (in case of UAC session) or - re-INVITE. - + h - provide the headers of the SIP request/reply in - the E_UA_SESSION event. - + b - provide the body of the SIP request/reply in the - E_UA_SESSION event. - + n - do not trigger the E_UA_SESSION event (with - event_type NEW) for initial INVITES handled with this - function. - * extra_params (string, optional) - An arbitrary value to be - passed to the extra_params parameter in the E_UA_SESSION - event. - - This function can be used from REQUEST_ROUTE. - - Example 1.16. ua_session_server_init usage -... -if(is_method("INVITE") && !has_totag()) { - ua_session_server_init($var(b2b_key), "arhb"); - - ua_session_reply($var(b2b_key), "INVITE", 200, "OK", $var(my_sdp)); - - exit; -} -... - -1.4.2. ua_session_update(key, method, [body], [extra_headers], -[content_type]) - - Sends a sequential request for a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Parameters: - * key (string) - b2b entity key of the UA session. - * method (string) - name of the SIP method for this request. - * body (string, optional) - body to include in the SIP - message. - * extra_headers (string, optional) - extra headers to include - in the SIP message. - * content_type (string, optional) - Content-Type header. If - the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - Example 1.17. ua_session_update usage -... -ua_session_update($var(b2b_key), "OPTIONS"); -... - -1.4.3. ua_session_reply(key, method, code, [reason], [body], -[extra_headers], [content_type]) - - Sends a reply for a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Parameters: - * key (string) - b2b entity key of the UA session. - * method (string) - name of the SIP method that is replied - to. - * code (int) - reply code. - * reason (string, optional) - reply reason string. - * body (string, optional) - body to include in the SIP - message. - * extra_headers (string, optional) - extra headers to include - in the SIP message. - * content_type (string, optional) - Content-Type header. If - the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - Example 1.18. ua_session_reply usage -... -ua_session_reply($var(b2b_key), "INVITE", 180, "Ringing"); -... - -1.4.4. ua_session_terminate(key, [extra_headers]) - - Terminate a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Parameters: - * key (string) - b2b entity key of the UA session. - * extra_headers (string, optional) - extra headers to include - in the SIP message - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - Example 1.19. ua_session_terminate usage -... -ua_session_terminate($var(b2b_key)); -... - -1.5. Exported MI Functions - -1.5.1. b2be_list - - This command can be used to list the internals of the b2b - entities. - - Name: b2be_list - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi b2be_list - -1.5.2. ua_session_client_start - - This command starts a new UAC session by sending an initial - INVITE. Further requests/replies received belonging to this - session will only be handled via the E_UA_SESSION event. - - Name: ua_session_client_start - - Parameters: - * ruri - Request URI - * to - To URI; can also be specified as: display_name,uri in - order to set a Display Name, eg. - Alice,sip:alice@opensips.org. - * from - From URI; can also be specified as: display_name,uri - in order to set a Display Name, eg. - Alice,sip:alice@opensips.org - * proxy (optional) - URI of the outbound proxy to send the - INVITE to - * body (optional) - message body - * content_type (optional) - Content Type header to use. If - missing and a body is provided, "Content-Type: - application/sdp" will be used. - * extra_headers (optional) - extra headers - * flags (optional) - flags with the same meaning as for the - flags paramater of ua_session_server_init(). - * socket (optional) - OpenSIPS sending socket - - opensips-cli Command Format: -opensips-cli -x mi ua_session_client_start ruri=sip:bob@opensips.org \ -to=sip:bob@opensips.org from=sip:alice@opensips.org flags=arhb - -1.5.3. ua_session_update - - Sends a sequential request for a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Name: ua_session_update - - Parameters: - * key - b2b entity key of the UA session. - * method - name of the SIP method for this request. - * body (optional) - body to include in the SIP message. - * extra_headers (optional) - extra headers to include in the - SIP message. - * content_type (string) - Content-Type header. If the - parameter is missing and a body is provided, "Content-Type: - application/sdp" will be used. - - opensips-cli Command Format: -opensips-cli -x mi ua_session_update key=B2B.436.1925389.1649338095 meth -od=OPTIONS - -1.5.4. ua_session_reply - - Sends a reply for a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Name: ua_session_reply - - Parameters: - * key - b2b entity key of the UA session. - * method - name of the SIP method that is replied to. - * code - reply code - * reason - reply reason string - * body (optional) - body to include in the SIP message - * extra_headers (optional) - extra headers to include in the - SIP message - * content_type (optional) - Content-Type header. If the - parameter is missing and a body is provided, "Content-Type: - application/sdp" will be used. - - opensips-cli Command Format: -opensips-cli -x mi ua_session_reply key=B2B.436.1925389.1649338095 metho -d=OPTIONS code=200 reason=OK - -1.5.5. ua_session_terminate - - Terminate a UA session started with the - ua_session_server_init() function or the - ua_session_client_start MI function. - - Name: ua_session_terminate - - Parameters: - * key - b2b entity key of the UA session. - * extra_headers (optional) - extra headers to include in the - SIP message - - opensips-cli Command Format: -opensips-cli -x mi ua_session_terminate key=B2B.436.1925389.1649338095 - -1.5.6. ua_session_list - - List information about UA sessions started with - ua_session_server_init() function or the - ua_session_client_start MI function. - - Name: ua_session_list - - Parameters: - * key (optional) - b2b entity key of the UA session to list. - If missing, all sessions will be listed. - - MI FIFO Command Format: - opensips-cli -x mi ua_session_list - -1.6. Exported Events - -1.6.1. E_UA_SESSION - - This event is triggered for requests/replies belonging to an - ongoing UA session started with the ua_session_server_init() - function or the ua_session_client_start MI function. - - Note that replies will not be reported at all unless the r flag - was set when initiating the UA session. Also ACK requests are - only reported if the a flag was set. - - Parameters: - * key - b2b entity key of the UA session. - * entity_type - indicates whether this is a UAS or UAc - entity. - * event_type - the type of event: - + NEW - for initial INVITE requests, handled with the - ua_session_server_init() function. - + EARLY - for 1xx provisional responses - + ANSWERED - for 2xx successful responses - + REJECTED - for 3xx-6xx failure responses - + UPDATED - for any sequential requests, including ACK - but excluding BYE/CANCEL - + TERMINATED - for BYE or CANCEL requests - * status - the reply status code if the message is a SIP - reply - * reason - the reply reason if the message is a SIP reply - * method - the SIP method name - * body - SIP message body - * headers - full list of all SIP headers in the message. - * extra_params - an arbitrary value. Currently only the - ua_session_server_init() function passes this if the - extra_params argument is used, and it only appears in the - NEW event_type. - -Chapter 2. Developer Guide - - The module provides an API that can be used from other OpenSIPS - modules. The API offers the functions for creating and handing - dialogs. A dialog can be created on a receipt initial message, - and this will correspond to a b2b server entity, or initiated - by the server and in this case a client entity will be created - in b2b_entities module. - -2.1. b2b_load_api(b2b_api_t* api) - - This function binds the b2b_entities modules and fills the - structure the exported functions that will be described in - detail. - - Example 2.1. b2b_api_t structure -... -typedef struct b2b_api { - b2b_server_new_t server_new; - b2b_client_new_t client_new; - - b2b_send_request_t send_request; - b2b_send_reply_t send_reply; - - b2b_entity_delete_t entity_delete; - - b2b_restore_linfo_t restore_logic_info; - b2b_update_b2bl_param_t update_b2bl_param; -}b2b_api_t; -... - -2.2. server_new - - Field type: -... -typedef str* (*b2b_server_new_t) (struct sip_msg* , str* local_contact, - b2b_notify_t , str *mod_name, str* logic_key, struct b2b -_tracer *tracer, - void *param, b2b_param_free_cb free_param); -... - - This function asks the b2b_entities modules to create a new - server entity record. The internal processing actually extracts - the dialog information from the message and constructs a record - that will be stored in a hash table. The second parameters is a - pointer to a function that the b2b_entities module will call - when a event will come for that dialog (a request or reply). - The third parameter is a pointer to a value that will be stored - and given as a parameter when the notify function will be - called(it has to be allocated in shared memory). - - The return value is an identifier for the record that will be - mentioned when calling other functions that represent actions - in the dialog(send request, send reply). - - The notify function has the following prototype: -... -typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void -* param); -... - - This function is called when a request or reply is received for - a dialog handled by b2b_entities. The first parameter is the - message, the second is the identifier for the dialog, the third - is a flag that says which is the type of the message(it has two - possible values - B2B_REQUEST and B2B_REPLY). The last - parameter is the parameter by the upper module when the entity - was created. - -2.3. client_new - - Field type: -... -typedef str* (*b2b_client_new_t) (client_info_t* , b2b_notify_t b2b_cbac -k, - b2b_add_dlginfo_t add_dlginfo_f, str *mo -d_name, str *logic_key, - struct b2b_tracer *tracer, void *param, -b2b_param_free_cb free_param); -... - - This function asks the b2b_entities modules to create a new - client entity record and also create a new dialog by sending an - initial message. The parameters are all the values needed for - the initial request to which the notify function and parameter - are added. The b2b_cback parameter is a pointer to the callback - that must be called when an event happens(receiving a reply or - request) in the dialog created with this function. The - add_dlginfo_f parameter is also a function pointer to a - callback that will be called when a final success response will - be received for the created dialog. The callback will receive - as parameter the complete dialog information for the record. It - should be stored and used when calling send_request or - send_reply functions. - - The return value is an identifier for the record that will be - mentioned when calling other functions that represent actions - in the dialog(send request, send reply). - -2.4. send_request - - Field type: -... -typedef int (*b2b_send_request_t)(enum b2b_entity_type ,str* b2b_key, st -r* method, - str* extra_headers, str* body, b2b_dlginfo_t*); -... - - This function asks the b2b_entities modules to send a request - inside a b2b dialog identified by b2b_key. The first parameter - is the entity type and can have two values: B2B_SERVER and - B2B_CLIENT. The second is the identifier returned by the create - function(server_new or client_new) and the next are the - informations needed for the new request: method, extra_headers, - body. The last parameter contains the dialog information - - callid, to tag, from tag. These are needed to make a perfect - match to of b2b_entities record for which a new request must be - sent. - - The return value is 0 for success and a negative value for - error. - -2.5. send_reply - - Field type: -... -typedef int (*b2b_send_reply_t)(enum b2b_entity_type et, str* b2b_key, i -nt code, str* text, - str* body, str* extra_headers, b2b_dlginfo_t* dlginfo); -... - - This function asks the b2b_entities modules to send a reply - inside a b2b dialog identified by b2b_key. The first parameter - is the entity type and can have two values: B2B_SERVER and - B2B_CLIENT. The second is the identifier returned by the create - function(server_new or client_new) and the next are the - informations needed for the new reply: code, text, body, - extra_headers. The last parameter contains the dialog - information used for matching the right record. - - The return value is 0 for success and a negative value for - error. - -2.6. entity_delete - - Field type: -... -typedef void (*b2b_entity_delete_t)(enum b2b_entity_type et, str* b2b_ke -y, - b2b_dlginfo_t* dlginfo); -... - - This function must be called by the upper level function to - delete the records in b2b_entities. The records are not cleaned - up by the b2b_entities module and the upper level module must - take care to delete them. - -2.7. restore_logic_info - - Field type: -... -typedef int (*b2b_restore_linfo_t)(enum b2b_entity_type type, str* key, - b2b_notify_t cback, void *param, b2b_param_free_cb free_ -param); -... - - This function is used at startup when loading the data from the - database to restore the pointer to the callback function. - -2.8. update_b2bl_param - - Field type: -... -typedef int (*b2b_update_b2bl_param_t)(enum b2b_entity_type type, str* k -ey, - str* param, int replicate); -... - - This function can be used to change the logic param stored for - an entity ( useful in case an entity is moved between logic - records). - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 183 94 6839 1860 - 2. Vlad Patrascu (@rvlad-patrascu) 127 62 5443 1147 - 3. Razvan Crainea (@razvancrainea) 89 73 830 534 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 60 51 515 202 - 5. Ovidiu Sas (@ovidiusas) 57 42 987 348 - 6. Liviu Chircu (@liviuchircu) 21 17 97 128 - 7. Maksym Sobolyev (@sobomax) 7 5 30 23 - 8. Vlad Paiu (@vladpaiu) 6 4 74 47 - 9. Carsten Bock 6 4 66 40 - 10. Nick Altmann (@nikbyte) 6 3 166 29 - - All remaining contributors: Alexandra Titoc, Giedrius, - Stanislaw Pitucha, Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), @DMOsipov, Stéphane Alnet (@shimaore), - Henk Hesselink, Ryan Bullock (@rrb3942), Walter Doekes - (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2009 - Dec 2025 - 2. Ovidiu Sas (@ovidiusas) Nov 2010 - Nov 2025 - 3. Razvan Crainea (@razvancrainea) Dec 2010 - Oct 2025 - 4. Maksym Sobolyev (@sobomax) Jan 2021 - Apr 2025 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2024 - 6. Alexandra Titoc Sep 2024 - Sep 2024 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jun 2023 - 8. Giedrius Apr 2023 - May 2023 - 9. Carsten Bock Mar 2022 - Apr 2022 - 10. Nick Altmann (@nikbyte) Jan 2013 - Feb 2022 - - All remaining contributors: Peter Lemenkov (@lemenkov), - @DMOsipov, Ionut Ionita (@ionutrazvanionita), Walter Doekes - (@wdoekes), Vlad Paiu (@vladpaiu), Ryan Bullock (@rrb3942), - Stéphane Alnet (@shimaore), Anca Vamanu, Henk Hesselink, - Stanislaw Pitucha. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Carsten Bock, - Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu - (@bogdan-iancu), Vlad Paiu (@vladpaiu), Ovidiu Sas - (@ovidiusas), Anca Vamanu. - - Documentation Copyrights: - - Copyright © 2009 Anca-Maria Vamanu - - Copyright © 2022 ng-voice GmbH diff --git a/modules/b2b_entities/README.md b/modules/b2b_entities/README.md new file mode 100644 index 00000000000..f7b7f632c39 --- /dev/null +++ b/modules/b2b_entities/README.md @@ -0,0 +1,954 @@ +--- +title: "B2B_ENTITIES" +description: "This module implements the basic functions of a UAS and UAC needed by the B2BUA implementation of OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +The B2BUA implementation in OpenSIPS is separated in two layers: + + +- a lower one(coded in this module)- which implements the basic functions of a UAS and UAC +- a upper one - which represents the logic engine of B2BUA, responsible of actually +implementing the B2BUA services using the functions offered by the low level. + + +This module stores records corresponding to the dialogs in which the B2BUA +is involved. It exports an API to be called from other modules which offers functions for +creating a new dialog record, for sending requests or replies in one dialog and will also +notify the upper level module when a request or reply is received inside one stored dialog. + +The records are separated in two types: b2b server entities and b2b client entities depending +on the mode they are created. An entity created for a received initial message will be a server entity, +while a entity that will send an initial request(create a new dialog) will be a b2b client entity. +The name corresponds to the behavior in the first transaction - if UAS - server entity and if UAC - client entity. + +This module does not implement a B2BUA alone, but needs a B2B logic implementing module. + + +The module is able to respond to authentication challanges if the +uac_auth module is loaded first. The list of credentials for +b2b authentication is also provided by the uac_auth module. + + +### Dependencies + + +#### OpenSIPS Modules + + +- *tm* +- *a db module* +- *uac_auth* +(mandatory if authentication is required) + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### server_hsize (int) + + +The size of the hash table that stores the b2b server entities. +It is the 2 logarithmic value of the real size. + + +*Default value is "9"* +(512 records). + + +```opensips title="Set server_hsize parameter" +... +modparam("b2b_entities", "server_hsize", 10) +... + +``` + + +#### client_hsize (int) + + +The size of the hash table that stores the b2b client entities. +It is the 2 logarithmic value of the real size. + + +*Default value is "9"* +(512 records). + + +```opensips title="Set client_hsize parameter" +... +modparam("b2b_entities", "client_hsize", 10) +... + +``` + + +#### script_req_route (str) + + +The name of the b2b script route that will be called when +B2B requests are received. + + +```opensips title="Set script_req_route parameter" +... +modparam("b2b_entities", "script_req_route", "b2b_request") +... + +``` + + +#### script_reply_route (str) + + +The name of the b2b script route that will be called when +B2B replies are received. + + +```opensips title="Set script_repl_route parameter" +... +modparam("b2b_entities", "script_reply_route", "b2b_reply") +... + +``` + + +#### db_url (str) + + +Database URL. It is not compulsory, if not set +data is not stored in database. + + +```opensips title="Set db_url parameter" +... +modparam("b2b_entities", "db_url", "mysql://opensips:opensipsrw@127.0.0.1/opensips") +... + +``` + + +#### cachedb_url (str) + + +URL of a NoSQL database to be used. Only Redis is supported +at the moment. + + +```opensips title="Set cachedb_url parameter" +... +modparam("b2b_entities", "cachedb_url", "redis://localhost:6379/") +... + +``` + + +#### cachedb_key_prefix (string) + + +Prefix to use for every key set in the NoSQL database. + + +*Default value is "b2be$".* + + +```opensips title="Set cachedb_key_prefix parameter" +... +modparam("b2b_entities", "cachedb_key_prefix", "b2b") +... +``` + + +#### update_period (int) + + +The time interval at which to update the info in database. + + +*Default value is "100".* + + +```opensips title="Set update_period parameter" +... +modparam("b2b_entities", "update_period", 60) +... + +``` + + +#### b2b_key_prefix (string) + + +The string to use when generating the key ( it is inserted +in the SIP messages as callid or to tag. It is useful to set +this prefix if you use more instances of opensips B2BUA cascaded +in the same architecture. Sometimes opensips B2BUA looks at the +callid or totag to see if it has the format it uses to determine +if the request was sent by it. + + +*Default value is "B2B".* + + +```opensips title="Set b2b_key_prefix parameter" +... +modparam("b2b_entities", "b2b_key_prefix", "B2B1") +... + +``` + + +#### db_mode (int) + + +The B2B modules have support for the 3 type of database storage + + +- NO DB STORAGE - set this parameter to 0 +- WRITE THROUGH (synchronous write in database) - set this parameter to 1 +- WRITE BACK (update in db from time to time) - set this parameter to 2 + + +*Default value is "2" (WRITE BACK).* + + +```opensips title="Set db_mode parameter" +... +modparam("b2b_entities", "db_mode", 1) +... + +``` + + +#### db_table (str) + + +The name of the table that will be used for storing B2B entities + + +*Default value is "b2b_entities"* + + +```opensips title="Set db_table parameter" +... +modparam("b2b_entities", "db_table", "some table name") +... + +``` + + +#### cluster_id (int) + + +The ID of the cluster this instance belongs to. Setting this parameter +enables clustering support for the OpenSIPS B2BUA by replicating the +B2B entities (B2B dialogs) between instances. This also ensures restart +persistency through the *clusterer* module's +data "sync" mechanism. + + +This OpenSIPS cluster exposes the **"b2be-entities-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +*Default value is "0" (clustering disabled)* + + +```opensips title="Set cluster_id parameter" +... +modparam("b2b_entities", "cluster_id", 10) +... + +``` + + +#### passthru_prack (int) + + +This parameter allows to control, whether a PRACK should be generated locally (=0) +or if we request it to be end-to-end (=1). + + +*Default value is "0" (generate PRACK locally)* + + +```opensips title="Set passthru_prack parameter" +... +modparam("b2b_entities", "passthru_prack", 1) +... + +``` + + +#### advertised_contact (str) + + +Contact to use in generated messages for UA session started with the +[mi ua session client start](#mi_ua_session_client_start) MI function. + + +```opensips title="Set advertised_contact parameter" +... +modparam("b2b_entities", "advertised_contact", "opensips@10.10.10.10:5060") +... + +``` + + +#### ua_default_timeout (str) + + +Default timeout, in seconds, for UA session started with the +[ua session server init](#func_ua_session_server_init) function or the +[mi ua session client start](#mi_ua_session_client_start) MI function. After this +interval a BYE will be sent and the session will be deleted. + + +If not set the default is 43200 (12 hours). + + +```opensips title="Set ua_default_timeout parameter" +... +modparam("b2b_entities", "ua_default_timeout", 7200) +... + +``` + + +### Exported Functions + + +#### ua_session_server_init([key], [flags], [extra_params]) + + +This function initializes a new UA session by processing an initial INVITE. +Further requests/replies received belonging to this session will only +be handled via the [E UA SESSION](#event_e_ua_session) event. + + +Parameters: + + +- *key (var, optional)* - Variable to return the +b2b entity key of the new UA session. +- *flags (string, optional)* - configures options +for this UA session via the following flags: + - *t[nn]* - maximum duration of +this session in seconds. After this timeout a BYE +will be sent and the session will be deleted. If this +is not set, the default timeout, configured with +[ua default timeout](#param_ua_default_timeout) will be used. +Example: *t3600* + - *a* - report the receving of ACK requests +via the [E UA SESSION](#event_e_ua_session) event. + - *r* - report the receving of replies via +the [E UA SESSION](#event_e_ua_session) event. + - *d* - disable the automatic sending of ACK +upon receving a 200 OK reply for INVITE (in case of UAC session) +or re-INVITE. + - *h* - provide the headers of the SIP request/reply +in the [E UA SESSION](#event_e_ua_session) event. + - *b* - provide the body of the SIP request/reply +in the [E UA SESSION](#event_e_ua_session) event. + - *n* - do not trigger the +[E UA SESSION](#event_e_ua_session) event (with event_type +*NEW*) for initial INVITES +handled with this function. +- *extra_params (string, optional)* - An arbitrary +value to be passed to the *extra_params* parameter +in the [E UA SESSION](#event_e_ua_session) event. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="ua_session_server_init usage" +... +if(is_method("INVITE") && !has_totag()) { + ua_session_server_init($var(b2b_key), "arhb"); + + ua_session_reply($var(b2b_key), "INVITE", 200, "OK", $var(my_sdp)); + + exit; +} +... + +``` + + +#### ua_session_update(key, method, [body], [extra_headers], [content_type]) + + +Sends a sequential request for a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Parameters: + + +- *key (string)* - b2b entity key of the UA session. +- *method (string)* - name of the SIP method for this +request. +- *body (string, optional)* - body to include in the +SIP message. +- *extra_headers (string, optional)* - extra headers +to include in the SIP message. +- *content_type (string, optional)* - Content-Type +header. If the parameter is missing and a body is provided, +"Content-Type: application/sdp" will be used. + + +This function can be used from REQUEST_ROUTE, EVENT_ROUTE. + + +```opensips title="ua_session_update usage" +... +ua_session_update($var(b2b_key), "OPTIONS"); +... + +``` + + +#### ua_session_reply(key, method, code, [reason], [body], [extra_headers], [content_type]) + + +Sends a reply for a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Parameters: + + +- *key (string)* - b2b entity key of the UA session. +- *method (string)* - name of the SIP method that is +replied to. +- *code (int)* - reply code. +- *reason (string, optional)* - reply reason string. +- *body (string, optional)* - body to include in the +SIP message. +- *extra_headers (string, optional)* - extra headers +to include in the SIP message. +- *content_type (string, optional)* - Content-Type header. +If the parameter is missing and a body is provided, +"Content-Type: application/sdp" will be used. + + +This function can be used from REQUEST_ROUTE, EVENT_ROUTE. + + +```opensips title="ua_session_reply usage" +... +ua_session_reply($var(b2b_key), "INVITE", 180, "Ringing"); +... + +``` + + +#### ua_session_terminate(key, [extra_headers]) + + +Terminate a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Parameters: + + +- *key (string)* - b2b entity key of the UA session. +- *extra_headers (string, optional)* - extra headers +to include in the SIP message + + +This function can be used from REQUEST_ROUTE, EVENT_ROUTE. + + +```opensips title="ua_session_terminate usage" +... +ua_session_terminate($var(b2b_key)); +... + +``` + + +### Exported MI Functions + + +#### b2be_list + + +This command can be used to list the internals of the b2b entities. + + +Name: *b2be_list* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi b2be_list + +``` + + +#### ua_session_client_start + + +This command starts a new UAC session by sending an initial INVITE. +Further requests/replies received belonging to this session will only +be handled via the [E UA SESSION](#event_e_ua_session) event. + + +Name: *ua_session_client_start* + + +Parameters: + + +- *ruri* - Request URI +- *to* - To URI; can also be specified as: +*display_name,uri* in order to set a Display Name, +eg. *Alice,sip:alice@opensips.org*. +- *from* - From URI; can also be specified as: +*display_name,uri* in order to set a Display Name, +eg. *Alice,sip:alice@opensips.org* +- *proxy (optional)* - URI of the +outbound proxy to send the INVITE to +- *body (optional)* - message body +- *content_type (optional)* - Content Type +header to use. If missing and a body is provided, +"Content-Type: application/sdp" will be used. +- *extra_headers (optional)* - extra headers +- *flags (optional)* - flags with the same meaning +as for the *flags* paramater of +[ua session server init](#func_ua_session_server_init). +- *socket (optional)* - OpenSIPS sending socket + + +opensips-cli Command Format: + + +```bash +opensips-cli -x mi ua_session_client_start ruri=sip:bob@opensips.org \ +to=sip:bob@opensips.org from=sip:alice@opensips.org flags=arhb +``` + + +#### ua_session_update + + +Sends a sequential request for a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Name: *ua_session_update* + + +Parameters: + + +- *key* - b2b entity key of the UA session. +- *method* - name of the SIP method for this +request. +- *body (optional)* - body to include in the +SIP message. +- *extra_headers (optional)* - extra headers +to include in the SIP message. +- *content_type (string)* - Content-Type header. +If the parameter is missing and a body is provided, +"Content-Type: application/sdp" will be used. + + +opensips-cli Command Format: + + +```bash +opensips-cli -x mi ua_session_update key=B2B.436.1925389.1649338095 method=OPTIONS +``` + + +#### ua_session_reply + + +Sends a reply for a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Name: *ua_session_reply* + + +Parameters: + + +- *key* - b2b entity key of the UA session. +- *method* - name of the SIP method that is +replied to. +- *code* - reply code +- *reason* - reply reason string +- *body (optional)* - body to include in the +SIP message +- *extra_headers (optional)* - extra headers +to include in the SIP message +- *content_type (optional)* - Content-Type header. +If the parameter is missing and a body is provided, +"Content-Type: application/sdp" will be used. + + +opensips-cli Command Format: + + +```bash +opensips-cli -x mi ua_session_reply key=B2B.436.1925389.1649338095 method=OPTIONS code=200 reason=OK +``` + + +#### ua_session_terminate + + +Terminate a UA session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Name: *ua_session_terminate* + + +Parameters: + + +- *key* - b2b entity key of the UA session. +- *extra_headers (optional)* - extra headers +to include in the SIP message + + +opensips-cli Command Format: + + +```bash +opensips-cli -x mi ua_session_terminate key=B2B.436.1925389.1649338095 +``` + + +#### ua_session_list + + +List information about UA sessions started with +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Name: *ua_session_list* + + +Parameters: + + +- *key (optional)* - b2b entity key of the UA session +to list. If missing, all sessions will be listed. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi ua_session_list + +``` + + +### Exported Events + + +#### E_UA_SESSION + + +This event is triggered for requests/replies belonging to an ongoing UA +session started with the +[ua session server init](#func_ua_session_server_init) function or +the [mi ua session client start](#mi_ua_session_client_start) MI function. + + +Note that replies will not be reported at all unless the +*r* flag was set when initiating the UA session. Also +ACK requests are only reported if the *a* flag was set. + + +Parameters: + + +- *key* - b2b entity key of the UA session. +- *entity_type* - indicates whether this is a +*UAS* or *UAc* entity. +- *event_type* - the type of event: + - *NEW* - for initial INVITE requests, handled with the [ua session server init](#func_ua_session_server_init) function. + - *EARLY* - for 1xx provisional responses + - *ANSWERED* - for 2xx successful responses + - *REJECTED* - for 3xx-6xx failure responses + - *UPDATED* - for any sequential requests, including ACK but excluding BYE/CANCEL + - *TERMINATED* - for BYE or CANCEL requests +- *status* - the reply status code if the message is +a SIP reply +- *reason* - the reply reason if the message is +a SIP reply +- *method* - the SIP method name +- *body* - SIP message body +- *headers* - full list of all SIP headers in the +message. +- *extra_params* - an arbitrary value. Currently only +the [ua session server init](#func_ua_session_server_init) function passes this +if the *extra_params* argument is used, and it only +appears in the *NEW* event_type. + + +## Developer Guide + + +The module provides an API that can be used from other +OpenSIPS modules. The API offers the functions for creating and handing dialogs. +A dialog can be created on a receipt initial message, and this will correspond to +a b2b server entity, or initiated by the server and in this case a client entity +will be created in b2b_entities module. + + +### b2b_load_api(b2b_api_t* api) + + +This function binds the b2b_entities modules and fills the structure +the exported functions that will be described in detail. + + +```c title="b2b_api_t structure" +... +typedef struct b2b_api { + b2b_server_new_t server_new; + b2b_client_new_t client_new; + + b2b_send_request_t send_request; + b2b_send_reply_t send_reply; + + b2b_entity_delete_t entity_delete; + + b2b_restore_linfo_t restore_logic_info; + b2b_update_b2bl_param_t update_b2bl_param; +}b2b_api_t; +... +``` + + +### server_new + + +Field type: + + +```c +... +typedef str* (*b2b_server_new_t) (struct sip_msg* , str* local_contact, + b2b_notify_t , str *mod_name, str* logic_key, struct b2b_tracer *tracer, + void *param, b2b_param_free_cb free_param); +... +``` + + +This function asks the b2b_entities modules to create a new server +entity record. The internal processing actually extracts the dialog information +from the message and constructs a record that will be stored in a hash table. +The second parameters is a pointer to a function that the b2b_entities module +will call when a event will come for that dialog (a request or reply). The third +parameter is a pointer to a value that will be stored and given as a parameter +when the notify function will be called(it has to be allocated in shared memory). + + +The return value is an identifier for the record that will be mentioned when +calling other functions that represent actions in the dialog(send request, +send reply). + + +The notify function has the following prototype: + + +```c +... +typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void* param); +... +``` + + +This function is called when a request or reply is received for a dialog +handled by b2b_entities. The first parameter is the message, the second is the +identifier for the dialog, the third is a flag that says which is the type of +the message(it has two possible values - B2B_REQUEST and B2B_REPLY). The last +parameter is the parameter by the upper module when the entity was created. + + +### client_new + + +Field type: + + +```c +... +typedef str* (*b2b_client_new_t) (client_info_t* , b2b_notify_t b2b_cback, + b2b_add_dlginfo_t add_dlginfo_f, str *mod_name, str *logic_key, + struct b2b_tracer *tracer, void *param, b2b_param_free_cb free_param); +... +``` + + +This function asks the b2b_entities modules to create a new client +entity record and also create a new dialog by sending an initial message. +The parameters are all the values needed for the initial request to which +the notify function and parameter are added. +The b2b_cback parameter is a pointer to the callback that must be called when +an event happens(receiving a reply or request) in the dialog created with +this function. +The add_dlginfo_f parameter is also a function pointer to a callback that will +be called when a final success response will be received for the created dialog. +The callback will receive as parameter the complete dialog information for the +record. It should be stored and used when calling send_request or send_reply functions. + + +The return value is an identifier for the record that will be mentioned when +calling other functions that represent actions in the dialog(send request, +send reply). + + +### send_request + + +Field type: + + +```c +... +typedef int (*b2b_send_request_t)(enum b2b_entity_type ,str* b2b_key, str* method, + str* extra_headers, str* body, b2b_dlginfo_t*); +... +``` + + +This function asks the b2b_entities modules to send a request inside a b2b dialog +identified by b2b_key. The first parameter is the entity type and can have two values: +B2B_SERVER and B2B_CLIENT. The second is the identifier returned by the create +function(server_new or client_new) and the next are the informations needed for +the new request: method, extra_headers, body. +The last parameter contains the dialog information - callid, to tag, from tag. These +are needed to make a perfect match to of b2b_entities record for which a new request +must be sent. + + +The return value is 0 for success and a negative value for error. + + +### send_reply + + +Field type: + + +```c +... +typedef int (*b2b_send_reply_t)(enum b2b_entity_type et, str* b2b_key, int code, str* text, + str* body, str* extra_headers, b2b_dlginfo_t* dlginfo); +... +``` + + +This function asks the b2b_entities modules to send a reply inside a b2b dialog +identified by b2b_key. The first parameter is the entity type and can have two values: +B2B_SERVER and B2B_CLIENT. The second is the identifier returned by the create +function(server_new or client_new) and the next are the informations needed for +the new reply: code, text, body, extra_headers. The last parameter contains the +dialog information used for matching the right record. + + +The return value is 0 for success and a negative value for error. + + +### entity_delete + + +Field type: + + +```c +... +typedef void (*b2b_entity_delete_t)(enum b2b_entity_type et, str* b2b_key, + b2b_dlginfo_t* dlginfo); +... +``` + + +This function must be called by the upper level function to delete the +records in b2b_entities. The records are not cleaned up by the b2b_entities +module and the upper level module must take care to delete them. + + +### restore_logic_info + + +Field type: + + +```c +... +typedef int (*b2b_restore_linfo_t)(enum b2b_entity_type type, str* key, + b2b_notify_t cback, void *param, b2b_param_free_cb free_param); +... +``` + + +This function is used at startup when loading the data from the database to +restore the pointer to the callback function. + + +### update_b2bl_param + + +Field type: + + +```c +... +typedef int (*b2b_update_b2bl_param_t)(enum b2b_entity_type type, str* key, + str* param, int replicate); +... +``` + + +This function can be used to change the logic param stored for an +entity ( useful in case an entity is moved between logic records). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/b2b_entities/b2b_entities.c b/modules/b2b_entities/b2b_entities.c index 155e550288d..a2d76f38225 100644 --- a/modules/b2b_entities/b2b_entities.c +++ b/modules/b2b_entities/b2b_entities.c @@ -629,6 +629,7 @@ static void mod_destroy(void) } else { b2b_entities_dump(1); b2be_dbf.close(b2be_db); + b2be_db = NULL; } } else if (b2be_cdbf.init) { b2be_cdb = b2be_cdbf.init(&b2be_cdb_url); @@ -637,6 +638,7 @@ static void mod_destroy(void) } else { b2b_entities_dump(1); b2be_cdbf.destroy(b2be_cdb); + b2be_cdb = NULL; } } } diff --git a/modules/b2b_entities/dlg.c b/modules/b2b_entities/dlg.c index c343687b8eb..a5b082df745 100644 --- a/modules/b2b_entities/dlg.c +++ b/modules/b2b_entities/dlg.c @@ -51,6 +51,8 @@ #include "ua_api.h" #define BUF_LEN 65535 +#define RACK_HDR_PREFIX "RAck: " +#define RACK_HDR_PREFIX_LEN (sizeof(RACK_HDR_PREFIX) - 1) str ack = str_init(ACK); str bye = str_init(BYE); @@ -62,6 +64,17 @@ struct b2b_callback *b2b_trig_cbs, *b2b_recv_cbs; static str storage_cap = str_init("b2b-storage-bin"); +static void b2b_free_record(b2b_dlg_t *dlg, b2b_table htable); + +/* called with the entity hash lock held */ +static void b2b_dlg_unref(b2b_dlg_t *dlg, b2b_table htable, + unsigned int hash_index) +{ + if (--dlg->ref || !dlg->deleted) + return; + + b2b_delete_record(dlg, htable, hash_index); +} /* This is the "transaction created" callback for the UAC transactions, @@ -661,6 +674,7 @@ static void run_create_cb_all(struct b2b_callback *cb, int etype) if (bin_append_buffer(&storage, &dlg->storage) < 0) { LM_ERR("Failed to build entity storage buffer\n"); + bin_free_packet(&storage); return; } @@ -742,6 +756,9 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) int b2b_cb_flags = 0; unsigned int ua_flags = 0; int ua_ev_type = -1; + int dlg_ref = 0; + + storage.buffer.s = NULL; /* check if a b2b request */ if (parse_headers(msg, HDR_EOH_F, 0) < 0) @@ -1350,6 +1367,10 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) dlg_state = dlg->state; ua_flags = dlg->ua_flags; + if (!(ua_flags & UA_FL_IS_UA_ENTITY) && b2b_cback) { + dlg->ref++; + dlg_ref = 1; + } B2BE_LOCK_RELEASE(table, hash_index); @@ -1385,6 +1406,12 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) } B2BE_LOCK_GET(table, hash_index); + if (dlg_ref && dlg->deleted) { + current_dlg = 0; + b2b_dlg_unref(dlg, table, hash_index); + B2BE_LOCK_RELEASE(table, hash_index); + return SCB_DROP_MSG; + } if(dlg_state>B2B_CONFIRMED) { @@ -1397,6 +1424,9 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) if(!aux_dlg) { LM_DBG("Record not found anymore\n"); + current_dlg = 0; + if (dlg_ref) + b2b_dlg_unref(dlg, table, hash_index); B2BE_LOCK_RELEASE(table, hash_index); return SCB_DROP_MSG; } @@ -1407,14 +1437,22 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) b2b_ev = B2B_EVENT_ACK; if (b2b_run_cb(dlg, hash_index, etype, B2BCB_TRIGGER_EVENT, b2b_ev, - &storage, serialize_backend) != 0) + &storage, serialize_backend) != 0) { + current_dlg = 0; + if (dlg_ref) + b2b_dlg_unref(dlg, table, hash_index); goto done; + } } else if (dlg_state == B2B_TERMINATED) { b2b_ev = B2B_EVENT_DELETE; if (b2b_run_cb(dlg, hash_index, etype, B2BCB_TRIGGER_EVENT, b2b_ev, - &storage, serialize_backend) != 0) + &storage, serialize_backend) != 0) { + current_dlg = 0; + if (dlg_ref) + b2b_dlg_unref(dlg, table, hash_index); goto done; + } } } @@ -1424,6 +1462,8 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) if(b2be_db_update(dlg, etype) < 0) LM_ERR("Failed to update in database\n"); } + if (dlg_ref) + b2b_dlg_unref(dlg, table, hash_index); B2BE_LOCK_RELEASE(table, hash_index); @@ -1435,14 +1475,11 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) replicate_entity_delete(dlg, etype, hash_index, &storage); } - if (b2b_ev != -1 && storage.buffer.s) - bin_free_packet(&storage); - if ((ua_flags&UA_FL_IS_UA_ENTITY) && dlg_state == B2B_TERMINATED) { if (ua_send_reply(etype, &b2b_key, METHOD_BYE, 200, &str_init("OK"), NULL, NULL, NULL) < 0) { LM_ERR("Failed to send 200 OK reply\n"); - return SCB_DROP_MSG; + goto end; } if (ua_entity_delete(etype, &b2b_key, b2be_db_mode == WRITE_BACK, 1) < 0) @@ -1451,6 +1488,9 @@ int b2b_prescript_f(struct sip_msg *msg, void *uparam) done: lock_release(&table[hash_index].lock); +end: + if (b2b_ev != -1 && storage.buffer.s) + bin_free_packet(&storage); return SCB_DROP_MSG; } @@ -2006,8 +2046,10 @@ int b2b_send_reply(b2b_rpl_data_t* rpl_data) void b2b_delete_record(b2b_dlg_t* dlg, b2b_table htable, unsigned int hash_index) { - str reply_text = str_init("Request Timeout"); - struct to_body *pto; + if (dlg->ref) { + dlg->deleted = 1; + return; + } if(dlg->prev == NULL) { @@ -2021,6 +2063,14 @@ void b2b_delete_record(b2b_dlg_t* dlg, b2b_table htable, unsigned int hash_index if(dlg->next) dlg->next->prev = dlg->prev; + b2b_free_record(dlg, htable); +} + +static void b2b_free_record(b2b_dlg_t *dlg, b2b_table htable) +{ + str reply_text = str_init("Request Timeout"); + struct to_body *pto; + if(htable == server_htable && dlg->tag[CALLEE_LEG].s) shm_free(dlg->tag[CALLEE_LEG].s); @@ -2039,29 +2089,39 @@ void b2b_delete_record(b2b_dlg_t* dlg, b2b_table htable, unsigned int hash_index shm_free(dlg->logic_key.s); if(dlg->uas_tran) { - tmb.unref_cell(dlg->uas_tran); - pto = get_to(dlg->uas_tran->uas.request); - if (pto == NULL || pto->error != PARSE_OK) { - LM_ERR("'To' header COULD NOT be parsed\n"); - } else { - if (tmb.t_reply_with_body(dlg->uas_tran, 408, &reply_text, 0, 0, + /* if we come across an already finally replied trans, + * just release it; otherwise send 408 */ + if ( dlg->uas_tran->uas.status<200) { + pto = get_to(dlg->uas_tran->uas.request); + if (pto == NULL || pto->error != PARSE_OK) { + LM_ERR("'To' header COULD NOT be parsed\n"); + } else { + if (tmb.t_reply_with_body(dlg->uas_tran, 408, &reply_text, 0, 0, &pto->tag_value) < 0) - LM_ERR("Failed to send 408 reply\n"); + LM_ERR("Failed to send 408 reply\n"); + } } + + tmb.unref_cell(dlg->uas_tran); } if (dlg->update_tran) { - tmb.unref_cell(dlg->update_tran); - pto = get_to(dlg->update_tran->uas.request); - if (pto == NULL || pto->error != PARSE_OK) { - LM_ERR("'To' header COULD NOT be parsed\n"); - } else { - if (tmb.t_reply_with_body(dlg->update_tran, 408, &reply_text, 0, 0, + /* if we come across an already finally replied trans, + * just release it; otherwise send 408 */ + if ( dlg->update_tran->uas.status<200) { + pto = get_to(dlg->update_tran->uas.request); + if (pto == NULL || pto->error != PARSE_OK) { + LM_ERR("'To' header COULD NOT be parsed\n"); + } else { + if (tmb.t_reply_with_body(dlg->update_tran, 408, &reply_text, 0, 0, &pto->tag_value) < 0) - LM_ERR("Failed to send 408 reply\n"); + LM_ERR("Failed to send 408 reply\n"); + } } + + tmb.unref_cell(dlg->update_tran); } if(dlg->ack_sdp.s) @@ -2110,6 +2170,10 @@ void b2b_entity_delete(enum b2b_entity_type et, str* b2b_key, B2BE_LOCK_RELEASE(table, hash_index); return; } + if (dlg->deleted) { + B2BE_LOCK_RELEASE(table, hash_index); + return; + } LM_DBG("Deleted dlg [%p]->[%.*s] with dlginfo [%p]\n", dlg, b2b_key->len, b2b_key->s, dlginfo); @@ -2491,7 +2555,7 @@ int _b2b_send_request(b2b_dlg_t* dlg, b2b_req_data_t* req_data) memcpy(ehdr.s, dlg->prack_headers.s, dlg->prack_headers.len); ehdr.len = ehdr.len + dlg->prack_headers.len; - LM_ERR("METHOD_PRACK ehdr %d[%.*s]\n", ehdr.len ,ehdr.len, ehdr.s); + LM_DBG("PRACK ehdr %d[%.*s]\n", ehdr.len ,ehdr.len, ehdr.s); } if(dlg->state < B2B_CONFIRMED) @@ -2515,6 +2579,7 @@ int _b2b_send_request(b2b_dlg_t* dlg, b2b_req_data_t* req_data) dlg->last_method == METHOD_INVITE) { /* send it ACK so that you can send the new request */ + dlg->last_method = METHOD_ACK; b2b_send_indlg_req(dlg, et, b2b_key, &ack, &ehdr, 0, req_data->body, req_data->no_cb); dlg->state= B2B_ESTABLISHED; @@ -2554,7 +2619,9 @@ int _b2b_send_request(b2b_dlg_t* dlg, b2b_req_data_t* req_data) } else { + dlg->last_method = METHOD_ACK; b2b_send_indlg_req(dlg, et, b2b_key, &ack, &ehdr, 0, 0, req_data->no_cb); + dlg->last_method = METHOD_BYE; ret = b2b_send_indlg_req(dlg, et, b2b_key, &bye, &ehdr, 0, req_data->body, req_data->no_cb); method_value = METHOD_BYE; @@ -3500,6 +3567,9 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) } if(dlg->callid.s==0 || dlg->callid.len==0) dlg->callid = msg->callid->body; + /* seed the CALLER cseq with what was received in 200 OK */ + dlg->cseq[CALLER_LEG] = leg->cseq; + dlg->last_invite_cseq = leg->cseq; if(b2b_send_req(dlg, etype, leg, &ack, 0, 0) < 0) { LM_ERR("Failed to send ACK request\n"); @@ -3600,8 +3670,9 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) { str method={"PRACK", 5}; str extra_headers; - char buf[128]; str rseq, cseq; + char *p; + int rack_overhead; hdr = get_header_by_static_name( msg, "RSeq"); if(!hdr) { @@ -3612,20 +3683,46 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) cseq = msg->cseq->body; trim_trailing(&rseq); trim_trailing(&cseq); - sprintf(buf, "RAck: %.*s %.*s\r\n", - rseq.len, rseq.s, cseq.len, cseq.s); - extra_headers.s = buf; - extra_headers.len = strlen(buf); + rack_overhead = RACK_HDR_PREFIX_LEN + 1 /* space */ + CRLF_LEN; + if (rseq.len < 0 || cseq.len < 0 || + rseq.len > BUF_LEN - rack_overhead || + cseq.len > BUF_LEN - rack_overhead - rseq.len) { + LM_ERR("RAck header too large\n"); + goto error; + } + extra_headers.len = rack_overhead + rseq.len + cseq.len; + extra_headers.s = pkg_malloc(extra_headers.len); + if (!extra_headers.s) { + LM_ERR("no more private memory\n"); + goto error; + } + + p = extra_headers.s; + memcpy(p, RACK_HDR_PREFIX, RACK_HDR_PREFIX_LEN); + p += RACK_HDR_PREFIX_LEN; + memcpy(p, rseq.s, rseq.len); + p += rseq.len; + *p++ = ' '; + memcpy(p, cseq.s, cseq.len); + p += cseq.len; + memcpy(p, CRLF, CRLF_LEN); if (passthru_prack) { /* Store the RAck header for when a response PRACK comes */ if (dlg->prack_headers.s) { shm_free(dlg->prack_headers.s); + dlg->prack_headers.s = NULL; + dlg->prack_headers.len = 0; } dlg->prack_headers.s = shm_malloc(extra_headers.len); + if (!dlg->prack_headers.s) { + LM_ERR("no more shared memory\n"); + pkg_free(extra_headers.s); + goto error; + } memcpy(dlg->prack_headers.s, extra_headers.s, extra_headers.len); dlg->prack_headers.len = extra_headers.len; - LM_ERR("dlg->prack_headers %d[%.*s]\n", dlg->prack_headers.len ,dlg->prack_headers.len, dlg->prack_headers.s); + LM_DBG("dlg->prack_headers %d[%.*s]\n", dlg->prack_headers.len ,dlg->prack_headers.len, dlg->prack_headers.s); } else { @@ -3637,6 +3734,7 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) LM_ERR("Failed to send PRACK\n"); } } + pkg_free(extra_headers.s); } goto done; } @@ -3673,7 +3771,7 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) } else { - b2b_dlginfo_t dlginfo; + b2b_dlginfo_t *dlginfo; b2b_add_dlginfo_t add_infof= dlg->add_dlginfo; /* delete all and add the confirmed leg */ @@ -3685,9 +3783,22 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) goto error; } dlg->tag[CALLEE_LEG] = leg->tag; - dlginfo.fromtag = to_tag; - dlginfo.callid = dlg->callid; - dlginfo.totag = dlg->tag[CALLER_LEG]; + + /* Deep-copy dialog info while holding the hash lock. + * The previous code did shallow copies of dlg->callid + * and dlg->tag[CALLER_LEG] (pointers into shm) and + * used them after releasing the lock — a TOCTOU race + * where another thread could modify the shm strings + * between size calculation and memcpy, causing a + * heap buffer overflow. */ + dlginfo = b2b_new_dlginfo(&dlg->callid, + &to_tag, &dlg->tag[CALLER_LEG]); + if(dlginfo == NULL) + { + LM_ERR("Failed to create dlginfo\n"); + goto error; + } + dlg->state = B2B_CONFIRMED; current_dlg = dlg; @@ -3703,11 +3814,13 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps) B2BE_LOCK_RELEASE(htable, hash_index); if(add_infof && add_infof(logic_key.s?&logic_key:0, b2b_key, - etype,&dlginfo, b2b_param)< 0) + etype, dlginfo, b2b_param)< 0) { LM_ERR("Failed to add dialoginfo\n"); + shm_free(dlginfo); goto error1; } + shm_free(dlginfo); goto done1; } @@ -3978,6 +4091,9 @@ int b2b_apply_lumps(struct sip_msg* msg) if(!msg->body_lumps && !msg->add_rm) return 0; + if (msg->msg_flags & FL_TM_FAKE_REQ) + return 0; + if (msg->first_line.type==SIP_REQUEST) obuf.s = build_req_buf_from_sip_req(msg, (unsigned int*)&obuf.len, msg->rcv.bind_address, msg->rcv.proto, NULL, MSG_TRANS_NOVIA_FLAG ); diff --git a/modules/b2b_entities/dlg.h b/modules/b2b_entities/dlg.h index b8d5488ad44..ee49ccd70c7 100644 --- a/modules/b2b_entities/dlg.h +++ b/modules/b2b_entities/dlg.h @@ -119,6 +119,8 @@ typedef struct b2b_dlg struct b2b_tracer *tracer; void *param; b2b_param_free_cb free_param; + unsigned int ref; + int deleted; str prack_headers; }b2b_dlg_t; diff --git a/modules/b2b_entities/doc/b2b_entities.xml b/modules/b2b_entities/doc/b2b_entities.xml deleted file mode 100644 index 15e51b28947..00000000000 --- a/modules/b2b_entities/doc/b2b_entities.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - B2B_ENTITIES - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 Anca-Maria Vamanu - ©right; 2022 ng-voice GmbH - - - diff --git a/modules/b2b_entities/doc/b2b_entities_admin.xml b/modules/b2b_entities/doc/b2b_entities_admin.xml deleted file mode 100644 index 85b62297e9a..00000000000 --- a/modules/b2b_entities/doc/b2b_entities_admin.xml +++ /dev/null @@ -1,895 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The B2BUA implementation in OpenSIPS is separated in two layers: - - - a lower one(coded in this module)- which implements the basic functions of a UAS and UAC - - - a upper one - which represents the logic engine of B2BUA, responsible of actually - implementing the B2BUA services using the functions offered by the low level. - - - - This module stores records corresponding to the dialogs in which the B2BUA - is involved. It exports an API to be called from other modules which offers functions for - creating a new dialog record, for sending requests or replies in one dialog and will also - notify the upper level module when a request or reply is received inside one stored dialog. - - The records are separated in two types: b2b server entities and b2b client entities depending - on the mode they are created. An entity created for a received initial message will be a server entity, - while a entity that will send an initial request(create a new dialog) will be a b2b client entity. - The name corresponds to the behavior in the first transaction - if UAS - server entity and if UAC - client entity. - - This module does not implement a B2BUA alone, but needs a B2B logic implementing module. - - - The module is able to respond to authentication challanges if the - uac_auth module is loaded first. The list of credentials for - b2b authentication is also provided by the uac_auth module. - -
- -
- Dependencies -
- &osips; Modules - - - - tm - - - - - a db module - - - - - uac_auth - (mandatory if authentication is required) - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - none - - - -
-
- -
- Exported Parameters -
- <varname>server_hsize</varname> (int) - - The size of the hash table that stores the b2b server entities. - It is the 2 logarithmic value of the real size. - - - Default value is 9 - - (512 records). - - - Set <varname>server_hsize</varname> parameter - -... -modparam("b2b_entities", "server_hsize", 10) -... - - -
- -
- <varname>client_hsize</varname> (int) - - The size of the hash table that stores the b2b client entities. - It is the 2 logarithmic value of the real size. - - - Default value is 9 - - (512 records). - - - Set <varname>client_hsize</varname> parameter - -... -modparam("b2b_entities", "client_hsize", 10) -... - - -
- -
- <varname>script_req_route</varname> (str) - - The name of the b2b script route that will be called when - B2B requests are received. - - - Set <varname>script_req_route</varname> parameter - -... -modparam("b2b_entities", "script_req_route", "b2b_request") -... - - -
- -
- <varname>script_reply_route</varname> (str) - - The name of the b2b script route that will be called when - B2B replies are received. - - - Set <varname>script_repl_route</varname> parameter - -... -modparam("b2b_entities", "script_reply_route", "b2b_reply") -... - - -
- -
- <varname>db_url</varname> (str) - - Database URL. It is not compulsory, if not set - data is not stored in database. - - - Set <varname>db_url</varname> parameter - -... -modparam("b2b_entities", "db_url", "mysql://opensips:opensipsrw@127.0.0.1/opensips") -... - - -
- -
- <varname>cachedb_url</varname> (str) - - URL of a NoSQL database to be used. Only Redis is supported - at the moment. - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("b2b_entities", "cachedb_url", "redis://localhost:6379/") -... - - -
- -
- <varname>cachedb_key_prefix</varname> (string) - - Prefix to use for every key set in the NoSQL database. - - - - Default value is b2be$. - - - - Set <varname>cachedb_key_prefix</varname> parameter - -... -modparam("b2b_entities", "cachedb_key_prefix", "b2b") -... - - -
- -
- <varname>update_period</varname> (int) - - The time interval at which to update the info in database. - - - Default value is 100. - - - Set <varname>update_period</varname> parameter - -... -modparam("b2b_entities", "update_period", 60) -... - - -
- -
- <varname>b2b_key_prefix</varname> (string) - - The string to use when generating the key ( it is inserted - in the SIP messages as callid or to tag. It is useful to set - this prefix if you use more instances of opensips B2BUA cascaded - in the same architecture. Sometimes opensips B2BUA looks at the - callid or totag to see if it has the format it uses to determine - if the request was sent by it. - - - Default value is B2B. - - - Set <varname>b2b_key_prefix</varname> parameter - -... -modparam("b2b_entities", "b2b_key_prefix", "B2B1") -... - - -
-
- <varname>db_mode</varname> (int) - - The B2B modules have support for the 3 type of database storage - - - - NO DB STORAGE - set this parameter to 0 - WRITE THROUGH (synchronous write in database) - set this parameter to 1 - WRITE BACK (update in db from time to time) - set this parameter to 2 - - - - Default value is 2 (WRITE BACK). - - - Set <varname>db_mode</varname> parameter - -... -modparam("b2b_entities", "db_mode", 1) -... - - -
- -
- <varname>db_table</varname> (str) - - The name of the table that will be used for storing B2B entities - - - Default value is b2b_entities - - - Set <varname>db_table</varname> parameter - -... -modparam("b2b_entities", "db_table", "some table name") -... - - -
- -
- <varname>cluster_id</varname> (int) - - The ID of the cluster this instance belongs to. Setting this parameter - enables clustering support for the OpenSIPS B2BUA by replicating the - B2B entities (B2B dialogs) between instances. This also ensures restart - persistency through the clusterer module's - data "sync" mechanism. - - - &clusterer_sync_cap_para; - - - Default value is 0 (clustering disabled) - - - Set <varname>cluster_id</varname> parameter - -... -modparam("b2b_entities", "cluster_id", 10) -... - - -
- -
- <varname>passthru_prack</varname> (int) - - This parameter allows to control, whether a PRACK should be generated locally (=0) - or if we request it to be end-to-end (=1). - - - Default value is 0 (generate PRACK locally) - - - Set <varname>passthru_prack</varname> parameter - -... -modparam("b2b_entities", "passthru_prack", 1) -... - - -
- -
- <varname>advertised_contact</varname> (str) - - Contact to use in generated messages for UA session started with the - MI function. - - - Set <varname>advertised_contact</varname> parameter - -... -modparam("b2b_entities", "advertised_contact", "opensips@10.10.10.10:5060") -... - - -
- -
- <varname>ua_default_timeout</varname> (str) - - Default timeout, in seconds, for UA session started with the - function or the - MI function. After this - interval a BYE will be sent and the session will be deleted. - - - If not set the default is 43200 (12 hours). - - - Set <varname>ua_default_timeout</varname> parameter - -... -modparam("b2b_entities", "ua_default_timeout", 7200) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">ua_session_server_init([key], [flags], [extra_params])</function> - - - This function initializes a new UA session by processing an initial INVITE. - Further requests/replies received belonging to this session will only - be handled via the event. - - Parameters: - - - key (var, optional) - Variable to return the - b2b entity key of the new UA session. - - - flags (string, optional) - configures options - for this UA session via the following flags: - - - t[nn] - maximum duration of - this session in seconds. After this timeout a BYE - will be sent and the session will be deleted. If this - is not set, the default timeout, configured with - will be used. - Example: t3600 - - - a - report the receving of ACK requests - via the event. - - - r - report the receving of replies via - the event. - - - d - disable the automatic sending of ACK - upon receving a 200 OK reply for INVITE (in case of UAC session) - or re-INVITE. - - - h - provide the headers of the SIP request/reply - in the event. - - - b - provide the body of the SIP request/reply - in the event. - - - n - do not trigger the - event (with event_type - NEW) for initial INVITES - handled with this function. - - - - - extra_params (string, optional) - An arbitrary - value to be passed to the extra_params parameter - in the event. - - - - This function can be used from REQUEST_ROUTE. - - - <function>ua_session_server_init</function> usage - -... -if(is_method("INVITE") && !has_totag()) { - ua_session_server_init($var(b2b_key), "arhb"); - - ua_session_reply($var(b2b_key), "INVITE", 200, "OK", $var(my_sdp)); - - exit; -} -... - - -
- -
- - <function moreinfo="none">ua_session_update(key, method, [body], [extra_headers], [content_type])</function> - - - Sends a sequential request for a UA session started with the - function or - the MI function. - - Parameters: - - - key (string) - b2b entity key of the UA session. - - - method (string) - name of the SIP method for this - request. - - - body (string, optional) - body to include in the - SIP message. - - - extra_headers (string, optional) - extra headers - to include in the SIP message. - - - content_type (string, optional) - Content-Type - header. If the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - - <function>ua_session_update</function> usage - -... -ua_session_update($var(b2b_key), "OPTIONS"); -... - - -
- -
- - <function moreinfo="none">ua_session_reply(key, method, code, [reason], [body], [extra_headers], [content_type])</function> - - - Sends a reply for a UA session started with the - function or - the MI function. - - Parameters: - - - key (string) - b2b entity key of the UA session. - - - method (string) - name of the SIP method that is - replied to. - - - code (int) - reply code. - - - reason (string, optional) - reply reason string. - - - body (string, optional) - body to include in the - SIP message. - - - extra_headers (string, optional) - extra headers - to include in the SIP message. - - - content_type (string, optional) - Content-Type header. - If the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - - <function>ua_session_reply</function> usage - -... -ua_session_reply($var(b2b_key), "INVITE", 180, "Ringing"); -... - - -
- -
- - <function moreinfo="none">ua_session_terminate(key, [extra_headers])</function> - - - Terminate a UA session started with the - function or - the MI function. - - Parameters: - - - key (string) - b2b entity key of the UA session. - - - extra_headers (string, optional) - extra headers - to include in the SIP message - - - - This function can be used from REQUEST_ROUTE, EVENT_ROUTE. - - - <function>ua_session_terminate</function> usage - -... -ua_session_terminate($var(b2b_key)); -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">b2be_list</function> - - - This command can be used to list the internals of the b2b entities. - - - Name: b2be_list - - Parameters: none - - - MI FIFO Command Format: - - opensips-cli -x mi b2be_list - -
- -
- - <function moreinfo="none">ua_session_client_start</function> - - - This command starts a new UAC session by sending an initial INVITE. - Further requests/replies received belonging to this session will only - be handled via the event. - - - Name: ua_session_client_start - - Parameters: - - - ruri - Request URI - - - to - To URI; can also be specified as: - display_name,uri in order to set a Display Name, - eg. Alice,sip:alice@opensips.org. - - - from - From URI; can also be specified as: - display_name,uri in order to set a Display Name, - eg. Alice,sip:alice@opensips.org - - - proxy (optional) - URI of the - outbound proxy to send the INVITE to - - - body (optional) - message body - - - content_type (optional) - Content Type - header to use. If missing and a body is provided, - "Content-Type: application/sdp" will be used. - - - extra_headers (optional) - extra headers - - - flags (optional) - flags with the same meaning - as for the flags paramater of - . - - - socket (optional) - OpenSIPS sending socket - - - opensips-cli Command Format: - -opensips-cli -x mi ua_session_client_start ruri=sip:bob@opensips.org \ -to=sip:bob@opensips.org from=sip:alice@opensips.org flags=arhb - -
- -
- - <function moreinfo="none">ua_session_update</function> - - - Sends a sequential request for a UA session started with the - function or - the MI function. - - - Name: ua_session_update - - Parameters: - - - key - b2b entity key of the UA session. - - - method - name of the SIP method for this - request. - - - body (optional) - body to include in the - SIP message. - - - extra_headers (optional) - extra headers - to include in the SIP message. - - - content_type (string) - Content-Type header. - If the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - - opensips-cli Command Format: - -opensips-cli -x mi ua_session_update key=B2B.436.1925389.1649338095 method=OPTIONS - -
- -
- - <function moreinfo="none">ua_session_reply</function> - - - Sends a reply for a UA session started with the - function or - the MI function. - - - Name: ua_session_reply - - Parameters: - - - key - b2b entity key of the UA session. - - - method - name of the SIP method that is - replied to. - - - code - reply code - - - reason - reply reason string - - - body (optional) - body to include in the - SIP message - - - extra_headers (optional) - extra headers - to include in the SIP message - - - content_type (optional) - Content-Type header. - If the parameter is missing and a body is provided, - "Content-Type: application/sdp" will be used. - - - opensips-cli Command Format: - -opensips-cli -x mi ua_session_reply key=B2B.436.1925389.1649338095 method=OPTIONS code=200 reason=OK - -
- -
- - <function moreinfo="none">ua_session_terminate</function> - - - Terminate a UA session started with the - function or - the MI function. - - - Name: ua_session_terminate - - Parameters: - - - key - b2b entity key of the UA session. - - - extra_headers (optional) - extra headers - to include in the SIP message - - - opensips-cli Command Format: - -opensips-cli -x mi ua_session_terminate key=B2B.436.1925389.1649338095 - -
- -
- - <function moreinfo="none">ua_session_list</function> - - - List information about UA sessions started with - function or - the MI function. - - - Name: ua_session_list - - Parameters: - - - key (optional) - b2b entity key of the UA session - to list. If missing, all sessions will be listed. - - - MI FIFO Command Format: - - opensips-cli -x mi ua_session_list - -
- -
- -
-Exported Events - -
- - <function moreinfo="none">E_UA_SESSION</function> - - - This event is triggered for requests/replies belonging to an ongoing UA - session started with the - function or - the MI function. - - - Note that replies will not be reported at all unless the - r flag was set when initiating the UA session. Also - ACK requests are only reported if the a flag was set. - - Parameters: - - - key - b2b entity key of the UA session. - - - entity_type - indicates whether this is a - UAS or UAc entity. - - - event_type - the type of event: - - - NEW - for initial INVITE requests, - handled with the - function. - - - EARLY - for 1xx provisional - responses - - - ANSWERED - for 2xx successful - responses - - - REJECTED - for 3xx-6xx failure - responses - - - UPDATED - for any sequential requests, - including ACK but excluding BYE/CANCEL - - - TERMINATED - for BYE or CANCEL - requests - - - - - status - the reply status code if the message is - a SIP reply - - - reason - the reply reason if the message is - a SIP reply - - - method - the SIP method name - - - body - SIP message body - - - headers - full list of all SIP headers in the - message. - - - extra_params - an arbitrary value. Currently only - the function passes this - if the extra_params argument is used, and it only - appears in the NEW event_type. - - -
- -
- -
- diff --git a/modules/b2b_entities/doc/b2b_entities_devel.xml b/modules/b2b_entities/doc/b2b_entities_devel.xml deleted file mode 100644 index f2cd71ffe73..00000000000 --- a/modules/b2b_entities/doc/b2b_entities_devel.xml +++ /dev/null @@ -1,234 +0,0 @@ - - - - &develguide; - - The module provides an API that can be used from other - &osips; modules. The API offers the functions for creating and handing dialogs. - A dialog can be created on a receipt initial message, and this will correspond to - a b2b server entity, or initiated by the server and in this case a client entity - will be created in b2b_entities module. - -
- - <function moreinfo="none">b2b_load_api(b2b_api_t* api)</function> - - - This function binds the b2b_entities modules and fills the structure - the exported functions that will be described in detail. - - - <function>b2b_api_t</function> structure - -... -typedef struct b2b_api { - b2b_server_new_t server_new; - b2b_client_new_t client_new; - - b2b_send_request_t send_request; - b2b_send_reply_t send_reply; - - b2b_entity_delete_t entity_delete; - - b2b_restore_linfo_t restore_logic_info; - b2b_update_b2bl_param_t update_b2bl_param; -}b2b_api_t; -... - - - -
- -
- - <function moreinfo="none">server_new</function> - - - Field type: - - -... -typedef str* (*b2b_server_new_t) (struct sip_msg* , str* local_contact, - b2b_notify_t , str *mod_name, str* logic_key, struct b2b_tracer *tracer, - void *param, b2b_param_free_cb free_param); -... - - - This function asks the b2b_entities modules to create a new server - entity record. The internal processing actually extracts the dialog information - from the message and constructs a record that will be stored in a hash table. - The second parameters is a pointer to a function that the b2b_entities module - will call when a event will come for that dialog (a request or reply). The third - parameter is a pointer to a value that will be stored and given as a parameter - when the notify function will be called(it has to be allocated in shared memory). - - - The return value is an identifier for the record that will be mentioned when - calling other functions that represent actions in the dialog(send request, - send reply). - - - The notify function has the following prototype: - - -... -typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void* param); -... - - - This function is called when a request or reply is received for a dialog - handled by b2b_entities. The first parameter is the message, the second is the - identifier for the dialog, the third is a flag that says which is the type of - the message(it has two possible values - B2B_REQUEST and B2B_REPLY). The last - parameter is the parameter by the upper module when the entity was created. - -
- -
- - <function moreinfo="none">client_new</function> - - - Field type: - - -... -typedef str* (*b2b_client_new_t) (client_info_t* , b2b_notify_t b2b_cback, - b2b_add_dlginfo_t add_dlginfo_f, str *mod_name, str *logic_key, - struct b2b_tracer *tracer, void *param, b2b_param_free_cb free_param); -... - - - This function asks the b2b_entities modules to create a new client - entity record and also create a new dialog by sending an initial message. - The parameters are all the values needed for the initial request to which - the notify function and parameter are added. - The b2b_cback parameter is a pointer to the callback that must be called when - an event happens(receiving a reply or request) in the dialog created with - this function. - The add_dlginfo_f parameter is also a function pointer to a callback that will - be called when a final success response will be received for the created dialog. - The callback will receive as parameter the complete dialog information for the - record. It should be stored and used when calling send_request or send_reply functions. - - - The return value is an identifier for the record that will be mentioned when - calling other functions that represent actions in the dialog(send request, - send reply). - -
- -
- - <function moreinfo="none">send_request</function> - - - Field type: - - -... -typedef int (*b2b_send_request_t)(enum b2b_entity_type ,str* b2b_key, str* method, - str* extra_headers, str* body, b2b_dlginfo_t*); -... - - - This function asks the b2b_entities modules to send a request inside a b2b dialog - identified by b2b_key. The first parameter is the entity type and can have two values: - B2B_SERVER and B2B_CLIENT. The second is the identifier returned by the create - function(server_new or client_new) and the next are the informations needed for - the new request: method, extra_headers, body. - The last parameter contains the dialog information - callid, to tag, from tag. These - are needed to make a perfect match to of b2b_entities record for which a new request - must be sent. - - - The return value is 0 for success and a negative value for error. - -
- -
- - <function moreinfo="none">send_reply</function> - - - Field type: - - -... -typedef int (*b2b_send_reply_t)(enum b2b_entity_type et, str* b2b_key, int code, str* text, - str* body, str* extra_headers, b2b_dlginfo_t* dlginfo); -... - - - This function asks the b2b_entities modules to send a reply inside a b2b dialog - identified by b2b_key. The first parameter is the entity type and can have two values: - B2B_SERVER and B2B_CLIENT. The second is the identifier returned by the create - function(server_new or client_new) and the next are the informations needed for - the new reply: code, text, body, extra_headers. The last parameter contains the - dialog information used for matching the right record. - - - The return value is 0 for success and a negative value for error. - -
- -
- - <function moreinfo="none">entity_delete</function> - - - Field type: - - -... -typedef void (*b2b_entity_delete_t)(enum b2b_entity_type et, str* b2b_key, - b2b_dlginfo_t* dlginfo); -... - - - This function must be called by the upper level function to delete the - records in b2b_entities. The records are not cleaned up by the b2b_entities - module and the upper level module must take care to delete them. - -
- -
- - <function moreinfo="none">restore_logic_info</function> - - - Field type: - - -... -typedef int (*b2b_restore_linfo_t)(enum b2b_entity_type type, str* key, - b2b_notify_t cback, void *param, b2b_param_free_cb free_param); -... - - - This function is used at startup when loading the data from the database to - restore the pointer to the callback function. - -
- -
- - <function moreinfo="none">update_b2bl_param</function> - - - Field type: - - -... -typedef int (*b2b_update_b2bl_param_t)(enum b2b_entity_type type, str* key, - str* param, int replicate); -... - - - This function can be used to change the logic param stored for an - entity ( useful in case an entity is moved between logic records). - -
- -
- diff --git a/modules/b2b_entities/doc/contributors.xml b/modules/b2b_entities/doc/contributors.xml deleted file mode 100644 index 2ef3f6b61c6..00000000000 --- a/modules/b2b_entities/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 183 - 94 - 6839 - 1860 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 127 - 62 - 5443 - 1147 - - - 3. - Razvan Crainea (@razvancrainea) - 89 - 73 - 830 - 534 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 60 - 51 - 515 - 202 - - - 5. - Ovidiu Sas (@ovidiusas) - 57 - 42 - 987 - 348 - - - 6. - Liviu Chircu (@liviuchircu) - 21 - 17 - 97 - 128 - - - 7. - Maksym Sobolyev (@sobomax) - 7 - 5 - 30 - 23 - - - 8. - Vlad Paiu (@vladpaiu) - 6 - 4 - 74 - 47 - - - 9. - Carsten Bock - 6 - 4 - 66 - 40 - - - 10. - Nick Altmann (@nikbyte) - 6 - 3 - 166 - 29 - - - -
-All remaining contributors: Alexandra Titoc, Giedrius, Stanislaw Pitucha, Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), @DMOsipov, Stéphane Alnet (@shimaore), Henk Hesselink, Ryan Bullock (@rrb3942), Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2009 - Dec 2025 - - - 2. - Ovidiu Sas (@ovidiusas) - Nov 2010 - Nov 2025 - - - 3. - Razvan Crainea (@razvancrainea) - Dec 2010 - Oct 2025 - - - 4. - Maksym Sobolyev (@sobomax) - Jan 2021 - Apr 2025 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2024 - - - 6. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jun 2023 - - - 8. - Giedrius - Apr 2023 - May 2023 - - - 9. - Carsten Bock - Mar 2022 - Apr 2022 - - - 10. - Nick Altmann (@nikbyte) - Jan 2013 - Feb 2022 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), @DMOsipov, Ionut Ionita (@ionutrazvanionita), Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu), Ryan Bullock (@rrb3942), Stéphane Alnet (@shimaore), Anca Vamanu, Henk Hesselink, Stanislaw Pitucha. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Carsten Bock, Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Anca Vamanu. -
- -
diff --git a/modules/b2b_logic/README b/modules/b2b_logic/README deleted file mode 100644 index 39969848128..00000000000 --- a/modules/b2b_logic/README +++ /dev/null @@ -1,1343 +0,0 @@ -B2B_LOGIC - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Scenario Logic - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. hash_size (int) - 1.4.2. script_req_route (str) - 1.4.3. script_reply_route (str) - 1.4.4. cleanup_period (int) - 1.4.5. custom_headers_regexp (str) - 1.4.6. custom_headers (str) - 1.4.7. db_url (str) - 1.4.8. cachedb_url (str) - 1.4.9. cachedb_key_prefix (string) - 1.4.10. update_period (int) - 1.4.11. max_duration (int) - 1.4.12. contact_user (int) - 1.4.13. b2bl_from_spec_param (string) - 1.4.14. server_address (str) - 1.4.15. init_callid_hdr (str) - 1.4.16. db_mode (int) - 1.4.17. db_table (str) - 1.4.18. b2bl_th_init_timeout (int) - 1.4.19. b2bl_early_update (int) - 1.4.20. old_entity_term_delay (int) - - 1.5. Exported Functions - - 1.5.1. b2b_init_request(id, [flags], [req_route], - [reply_route]) - - 1.5.2. b2b_server_new(id, [adv_contact], - [extra_hdrs], [extra_hdr_bodies]) - - 1.5.3. b2b_client_new(id, dest_uri, [proxy], - [from_dname], [adv_contact], [extra_hdrs], - [extra_hdr_bodies]) - - 1.5.4. b2b_bridge(entity1, entity2, [provmedia_uri], - [flags]) - - 1.5.5. b2b_bridge_retry(new_entity) - 1.5.6. b2b_pass_request() - 1.5.7. b2b_handle_reply([flags]) - 1.5.8. b2b_send_reply(code, reason[, headers[, - body]]) - - 1.5.9. b2b_delete_entity() - 1.5.10. b2b_end_dlg_leg() - 1.5.11. b2b_bridge_request(b2bl_key,entity_no, - [adv_contact], [flags]) - - 1.5.12. b2b_trigger_scenario(scenario, [params], - peer1, [extra_headers_peer1], - [extra_headers_contents_peer1], peer2 - [extra_headers_peer2], - [extra_headers_contents_peer2]) - - 1.6. Exported MI Functions - - 1.6.1. b2b_trigger_scenario - 1.6.2. b2b_bridge - 1.6.3. b2b_list - 1.6.4. b2b_terminate_call - - 1.7. Exported Pseudo-Variables - - 1.7.1. $b2b_logic.key - 1.7.2. $b2b_logic.entity(field)[idx] - 1.7.3. $b2b_logic.ctx(key) - 1.7.4. $b2b_logic.scenario(key) - - 2. Developer Guide - - 2.1. b2b_logic_bind(b2bl_api_t* api) - 2.2. init - 2.3. bridge - 2.4. bridge_extern - 2.5. bridge_2calls - 2.6. terminate_call - 2.7. set_state - 2.8. bridge_msg - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set server_hsize parameter - 1.2. Set script_req_route parameter - 1.3. Set script_repl_route parameter - 1.4. Set cleanup_period parameter - 1.5. Set parameter - 1.6. Set parameter - 1.7. Set db_url parameter - 1.8. Set cachedb_url parameter - 1.9. Set cachedb_key_prefix parameter - 1.10. Set update_period parameter - 1.11. Set max_duration parameter - 1.12. Set contact_user parameter - 1.13. Set b2bl_from_spec_param parameter - 1.14. Set server_address parameter - 1.15. Set server_address parameter using Pseudo-Variables - 1.16. Set init_callid_hdr parameter - 1.17. Set db_mode parameter - 1.18. Set db_table parameter - 1.19. Set b2bl_th_init_timeout parameter - 1.20. Set b2bl_early_update parameter - 1.21. Set old_entity_term_delay parameter - 1.22. b2b_init_request usage - 1.23. b2b_server_new usage - 1.24. b2b_client_new usage - 1.25. b2b_bridge usage - 1.26. b2b_bridge usage - 1.27. b2b_pass_request usage - 1.28. b2b_handle_reply usage - 1.29. b2b_send_reply usage - 1.30. b2b_delete_entity usage - 1.31. b2b_end_dlg_leg usage - 1.32. b2b_bridge_request usage - 1.33. b2b_trigger_scenario usage - 1.34. $b2b_logic.key usage - 1.35. $b2b_logic.entity usage - 1.36. $b2b_logic.ctx usage - 1.37. $b2b_logic.scenario usage - 2.1. b2bl_api_t structure - -Chapter 1. Admin Guide - -1.1. Overview - - The B2BUA implementation in OpenSIPS is separated in two - layers: - * a lower one (implemented in the b2b_entities module) - the - basic functions of a UAS and UAC - * an upper one (implemented in b2b_logic module) - which - represents the logic engine of B2BUA, responsible of - actually implementing the B2BUA services using the - functions offered by the low level. - - This module is a B2BUA upper level implementation that can be - used along with the b2b_entities module in order to provide - various B2BUA services (eg. PBX features). The actual logic of - the B2BUA scenarios can be implemented in dedicated script - routes. - - A B2B session can be triggered in two ways: - * from the script - at the receipt of an initial INVITE - message - * with an extern command (MI) command - the server will - connect two end points in a session(Third Party Call - Control). - - High Availability for B2B sessions can be achieved by enabling - the clustering support offered by the the lower b2b_entities - module (by setting the cluster_id modparam from b2b_entities). - -1.2. Scenario Logic - - After initializing a B2B session, the call legs will be handled - by the b2b_logic module and the first step will be to put the - two initial entities in contact. Requests and replies belonging - to these dialogs will not enter the script through the standard - OpenSIPS routes but instead will be handled in b2b_logic - dedicated routes (defined through the script_req_route and - script_reply_route modparams or, the custom routes given as - parameters to b2b_init_request()). The further steps of the - scenario can be implemented in these routes, by calling - dedicated b2b_logic script functions in order to perform - various actions. Normal "proxy-like" OpenSIPS functions should - not be executed in the b2b_logic routes. - - Some messages will be handled automatically by the module and - will not enter the b2b_logic routes at all (BYE requests - received while in the process of bridging two entities, - ACKs/BYEs/replies for disconnected entities). Also, if no - dedicated b2b_logic reply route is defined, replies will be - handled internally by the module, with the same effects as - calling b2b_handle_reply() from such a route if it were - defined. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - * b2b_entities, a db module - -1.3.2. External Libraries or Applications - - No libraries or applications required before running OpenSIPS - with this module. - -1.4. Exported Parameters - -1.4.1. hash_size (int) - - The size of the hash table that stores the session entities. - - Default value is “9” (512 records). - - Example 1.1. Set server_hsize parameter -... -modparam("b2b_logic", "hash_size", 10) -... - -1.4.2. script_req_route (str) - - The name of the script route to be called when requests - belonging to an ongoing B2B session are received. - - Example 1.2. Set script_req_route parameter -... -modparam("b2b_logic", "script_req_route", "b2b_request") -... - -1.4.3. script_reply_route (str) - - The name of the script route to be called when replies - belonging to an ongoing B2B session are received. - - Example 1.3. Set script_repl_route parameter -... -modparam("b2b_logic", "script_reply_route", "b2b_reply") -... - -1.4.4. cleanup_period (int) - - The time interval at which to search for an hanged b2b context. - A session is considered expired if the duration of a session - exceeds its defined lifetime. At that moment, BYE is sent in - all the dialogs from that context and the context is deleted. - - Default value is “100”. - - Example 1.4. Set cleanup_period parameter -... -modparam("b2b_logic", "cleanup_period", 60) -... - -1.4.5. custom_headers_regexp (str) - - Regexp to search SIP header by names that should be passed from - the dialog of one side to the other side. There are a number of - headers that are passed by default. They are: - * Max-Forwards (it is decreased by 1) - * Content-Type - * Supported - * Allow - * Proxy-Require - * Session-Expires - * Min-SE - * Require - * RSeq - - If you wish some other headers to be passed also you should - define them by setting this parameter. - - It can be in forms like "regexp", "/regexp/" and - "/regexp/flags". - - Meaning of the flags is as follows: - * i - Case insensitive search. - * e - Use extended regexp. - - Default value is “NULL”. - - Example 1.5. Set parameter -... -modparam("b2b_logic", "custom_headers_regexp", "/^x-/i") -... - -1.4.6. custom_headers (str) - - A list of SIP header names delimited by ';' that should be - passed from the dialog of one side to the other side. There are - a number of headers that are passed by default. They are: - * Max-Forwards (it is decreased by 1) - * Content-Type - * Supported - * Allow - * Proxy-Require - * Session-Expires - * Min-SE - * Require - * RSeq - - If you wish some other headers to be passed also you should - define them by setting this parameter. - - Default value is “NULL”. - - Example 1.6. Set parameter -... -modparam("b2b_logic", "custom_headers", "User-Agent;Date") -... - -1.4.7. db_url (str) - - Database URL. - - Example 1.7. Set db_url parameter -... -modparam("b2b_logic", "db_url", "mysql://opensips:opensipsrw@127.0.0.1/o -pensips") -... - -1.4.8. cachedb_url (str) - - URL of a NoSQL database to be used. Only Redis is supported at - the moment. - - Example 1.8. Set cachedb_url parameter -... -modparam("b2b_logic", "cachedb_url", "redis://localhost:6379/") -... - -1.4.9. cachedb_key_prefix (string) - - Prefix to use for every key set in the NoSQL database. - - Default value is “b2bl$”. - - Example 1.9. Set cachedb_key_prefix parameter -... -modparam("b2b_logic", "cachedb_key_prefix", "b2b") -... - -1.4.10. update_period (int) - - The time interval at which to update the info in database. - - Default value is “100”. - - Example 1.10. Set update_period parameter -... -modparam("b2b_logic", "update_period", 60) -... - -1.4.11. max_duration (int) - - The maximum duration of a call. - - Default value is “12 * 3600 (12 hours)”. - - If you set it to 0, there will be no limitation. - - Example 1.11. Set max_duration parameter -... -modparam("b2b_logic", "max_duration", 7200) -... - -1.4.12. contact_user (int) - - If set to 1, adds user from From: header to generated Contact: - - Default value is “0”. - - Example 1.12. Set contact_user parameter -... -modparam("b2b_logic", "contact_user", 1) -... - -1.4.13. b2bl_from_spec_param (string) - - The name of the pseudo variable for storing the new “From” - header. The PV must be set before calling “b2b_init_request”. - - Default value is “NULL” (disabled). - - Example 1.13. Set b2bl_from_spec_param parameter -... -modparam("b2b_logic", "b2bl_from_spec_param", "$var(b2bl_from)") -... -route{ - ... - # setting the From header - $var(b2bl_from) = "\"Call ID\" "; - ... - b2b_init_request("top hiding"); - ... -} - -1.4.14. server_address (str) - - The IP address of the machine that will be used as Contact in - the generated messages. This is compulsory only when OpenSIPS - starts a call from the middle. For scenarios triggered by - received calls, if it is not set, it is constructed dynamically - from the socket where the initiating request was received. This - socket will be used to send all the requests, replies for that - session. This parameter support Pseudo-Variables. - - Example 1.14. Set server_address parameter -... -modparam("b2b_logic", "server_address", "sip:sa@10.10.10.10:5060") -... - - Example 1.15. Set server_address parameter using - Pseudo-Variables -... -modparam("b2b_logic", "server_address", "sip:$socket_in(advertised_ip):$ -socket_in(advertised_port)") -... - -1.4.15. init_callid_hdr (str) - - The module offers the possibility to insert the original callid - in a header in the generated Invites. If you want this, set - this parameter to the name of the header in which to insert the - original callid. - - Example 1.16. Set init_callid_hdr parameter -... -modparam("b2b_logic", "init_callid_hdr", "Init-CallID") -... - -1.4.16. db_mode (int) - - The B2B modules have support for the 3 type of database storage - - * NO DB STORAGE - set this parameter to 0 - * WRITE THROUGH (synchronous write in database) - set this - parameter to 1 - * WRITE BACK (update in db from time to time) - set this - parameter to 2 - - Default value is “2” (WRITE BACK). - - Example 1.17. Set db_mode parameter -... -modparam("b2b_logic", "db_mode", 1) -... - -1.4.17. db_table (str) - - Name of the database table to be used - - Default value is “b2b_logic” - - Example 1.18. Set db_table parameter -... -modparam("b2b_logic", "db_table", "some_table_name") -... - -1.4.18. b2bl_th_init_timeout (int) - - Call setup timeout for topology hiding scenario. - - Default value is “60” - - Example 1.19. Set b2bl_th_init_timeout parameter -... -modparam("b2b_logic", "b2bl_th_init_timeout", 60) -... - -1.4.19. b2bl_early_update (int) - - Allow bridging of calls in early stage by issuing a "UPDATE" - request - - * 0 - Do not bridge dialogs in early stage - * 1 - Try to update an session in early stage by sending an - UPDATE - - Default value is “0” Do not bridge dialogs in early stage - - Example 1.20. Set b2bl_early_update parameter -... -modparam("b2b_logic", "b2bl_early_update", 1) -... - -1.4.20. old_entity_term_delay (int) - - When the b2b_bridge_request is being used with the late_bye - flag, this parameter can delay the moment when the BYE is being - sent to the terminating entity. Thus, instead of terminating it - when the new entity is established, the BYE is delayed with the - value of this param, expressed in seconds. - - Default value is “0” - send BYE on the spot - - Example 1.21. Set old_entity_term_delay parameter -... -modparam("b2b_logic", "old_entity_term_delay", 2) # delay the BYE with 2 - seconds -... - -1.5. Exported Functions - -1.5.1. b2b_init_request(id, [flags], [req_route], [reply_route]) - - This function initializes a new B2B session based on an initial - INVITE. A new server entity and a new client entity must be - created before running this function, with b2b_server_new() and - b2b_client_new(), respectively. These are the initial entities - to be connected and further scenario logic can be implemented - in the b2b_logic dedicated routes. - - Parameters: - * scenario_id (string) - identifier for the scenario of this - B2B session. The special value top hiding initializes an - internal topology hiding scenario. This scenario will do a - simple pass-through of messages from one side to another, - and no additional scripting or dedicated routes are - required. - * flags (string, optional) - CSV list of the following flags: - + setup-timeout=[nn] - Call setup timeout. 0 sets - timeout to max_duration value. Example: - "setup-timeout=300". - + transparent-auth - Transparent authentication. In this - mode b2b passes your 401 or 407 authentication request - to destination server. - + preserve-to - Preserve To: header. - * req_route (string, optional) - name of the script route to - be called when requests belonging to this B2B session are - received. This parameter will override the global - script_req_route modparam for this particular B2B session. - * reply_route (string, optional) - name of the script route - to be called when replies belonging to this B2B session are - received. This parameter will override the global - script_reply_route modparam for this particular B2B - session. - - This function can be used from REQUEST_ROUTE. - -Note - - If you have a multi interface setup and want to change the - outbound interface, it is mandatory to use the - "force_send_socket()" core function before passing control to - b2b function. If you do not do it, the requests may be - correctly routed, but the SIP pacakge may be invalid (as - Contact, Via, etc). - - Example 1.22. b2b_init_request usage -... -if(is_method("INVITE") && !has_totag() && prepaid_user()) { - ... - # create initial entities - b2b_server_new("server1"); - b2b_client_new("client1", $var(media_uri)); - - # initialize B2B session - b2b_init_request("prepaid"); - exit; -} -... - -1.5.2. b2b_server_new(id, [adv_contact], [extra_hdrs], -[extra_hdr_bodies]) - - This function creates a new server entity (dialog where - OpenSIPS acts as a UAS) to be used for initializing a new B2B - session. It should only be used for initial INVITES, before - calling b2b_init_request(). - - Parameters: - * id (string) - ID used to reference this entity in further - B2B actions. - * adv_contact (string, optional) - Contact header to - advertise in generated messages. - * extra_hdrs (var, optional) - AVP variable holding a list of - extra headers (the header names) to be added for any - request sent to this entity. - * extra_hdr_bodies (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers - given in the extra_hdrs parameter) to be added for any - request sent to this entity. - - This function can be used from REQUEST_ROUTE. - - Example 1.23. b2b_server_new usage -... -if(is_method("INVITE") && !has_totag()) { - b2b_server_new("server1", $avp(b2b_hdrs), $avp(b2b_hdr_bodies)); - ... -} -... - -1.5.3. b2b_client_new(id, dest_uri, [proxy], [from_dname], -[adv_contact], [extra_hdrs], [extra_hdr_bodies]) - - This function creates a new client entity (dialog where - OpenSIPS acts as a UAC) to be used for initializing a new B2B - session or for a bridge action. The function can be used before - calling b2b_init_request() or b2b_bridge(). - - Parameters: - * id (string) - ID used to reference this entity in further - B2B actions. - * dest_uri (string) - URI of the new destination. - * proxy (string, optional) - URI of the outbound proxy to - send the INVITE to. - * from_dname (string, optional) - Display name to use in the - From header. - * adv_contact (string, optional) - Contact header to - advertise in generated messages. - * extra_hdrs (var, optional) - AVP variable holding a list of - extra headers (the header names) to be added for any - request sent to this entity. - * extra_hdr_bodies (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers - given in the extra_hdrs parameter) to be added for any - request sent to this entity. - - This function can be used from REQUEST_ROUTE and the b2b_logic - request routes. - - Example 1.24. b2b_client_new usage -... -b2b_client_new("client1", "sip:alice@opensips.org"); -... - -1.5.4. b2b_bridge(entity1, entity2, [provmedia_uri], [flags]) - - This function bridges two entities, in the context of an - existing B2B session (the initial entities are already - connected). At least one of the two entities has to be a new - client entity. - - Parameters: - * entity1 (string) - ID of the first entity to bridge; the - special values: peer and this can also be used to refer to - existing entities. - * entity2 (string) - ID of the second entity to bridge; the - special values: peer and this can also be used to refer to - existing entities. - * provmedia_uri (string, optional) - URI of the provisional - media server to be connected with the caller while the - callee answers. - * flags (string, optional) - CSV list of the following flags: - + max_duration=[nn] - Maximum duration of the B2B - session. If the lifetime expires, the B2BUA will send - BYE messages to both ends and delete the record. - Example: "max_duration=300". - + notify - Enable rfc3515 NOTIFY to inform the agent - sending the REFER of the status of the reference. - + rollback-failed - Rollback call to state before - bridging in case of transfer failed, don't hangup the - call (default behaviour). - + hold - Put the old entity on hold before bridging it - to the new entity. - + no-late-sdp - Do not attempt late SDP negotiation with - the new entity. Start the bridging by first contacting - the new entity using the initial SDP received from the - old entity. After the new entity answers, send a - reINVITE without body to the old entity. Use the - current SDP received in this new answer from the old - entity to trigger a renegotiation with the new entity. - - This function can be used from the b2b_logic request routes. - - Example 1.25. b2b_bridge usage -... -route[b2b_logic_request] { - ... - b2b_client_new("client2", $hdr(Refer-To)); - - b2b_bridge("peer", "client2"); -} -... - -1.5.5. b2b_bridge_retry(new_entity) - - This function can be used to retry a failed bridging action by - contacting a new destination. A new client entity must be - created before running this function with b2b_client_new(). - - Parameters: - * entity1 (string) - ID of the new entity to bridge. - - This function can be used from the b2b_logic reply route. - - Example 1.26. b2b_bridge usage -... -route[b2b_logic_reply] { - ... - if ($b2b_logic.entity(id) == "client1" && $rm == "INVITE" && $rs >= 3 -00) { - b2b_client_new("client_retry", "sip:alice@opensips.org"); - - b2b_bridge_retry("client_retry"); - } else { - b2b_handle_reply(); - } - ... -} -... - -1.5.6. b2b_pass_request() - - This function passes a request belonging to an existing B2B - session to the peer entity. The function should be called for - all requests unless a different action is required to implement - the scenario logic (eg. a bridge action). - - This function can be used from the b2b_logic request routes. - - Example 1.27. b2b_pass_request usage -... -route[b2b_logic_request] { - if ($rm != "BYE") { - b2b_pass_request(); - exit; - } else { - # delete the current entity and bridge the peer to a new one - } -... - -1.5.7. b2b_handle_reply([flags]) - - This function processes the received reply by taking the - appropriate actions for the current state of the ongoing B2B - session (pass reply to peer, send INVITE or ACK to comeplete an - ongoing bridge action etc.). The function should be called for - all replies, if a b2b_logic reply route is defined. - - This function can be used from the b2b_logic reply routes. - - Parameters: - * flags (string, optional) - a list of comma separated flags - that changes the behavior of the reply processing. - Supported values are: - + pass-3xx-contact - When a redirect reply (3xx) message - is received, pass the contact to the other peer just - as it is, without modifying it. - - Example 1.28. b2b_handle_reply usage -... -route[b2b_logic_reply] { - xlog("B2B REPLY: [$rs $rm] from entity: $b2b_logic.entity(id)\n"); - b2b_handle_reply(); -} -... - -1.5.8. b2b_send_reply(code, reason[, headers[, body]]) - - This function sends a reply to the entity that sent the current - request. - - Parameters: - * code (int) - reply code - * reason (string) - reply reason string - * headers (string, optional) - additional headers - * body (string, optional) - message body - - This function can be used from the b2b_logic request routes. - - Example 1.29. b2b_send_reply usage -... -route[b2b_logic_request] { - if ($rm == "REFER") { - b2b_send_reply(202, "Accepted"); - ... - } -} -... - -1.5.9. b2b_delete_entity() - - This function deletes the entity that sent the current request. - - This function can be used from the b2b_logic request routes. - - Example 1.30. b2b_delete_entity usage -... -route[b2b_logic_request] { - if ($rm == "BYE") { - b2b_send_reply(200, "OK"); - b2b_delete_entity(); - ... - } -} -... - -1.5.10. b2b_end_dlg_leg() - - This function sends a BYE request to the entity that sent the - current request. It is not required to also call - b2b_delete_entity() in order to delete the current entity. - - This function can be used from the b2b_logic request or reply - routes. - - Example 1.31. b2b_end_dlg_leg usage -... -route[b2b_logic_request] { - if ($rm == "REFER") { - b2b_send_reply(202, "Accepted"); - b2b_end_dlg_leg(); - } -} -... - -1.5.11. b2b_bridge_request(b2bl_key,entity_no, [adv_contact], -[flags]) - - This function will bridge an initial INVITE with one of the - particapnts from an existing b2b session. - - Parameters: - * b2bl_key (string) - a string that contains the b2b_logic - key. The key can also be in the form of - callid;from-tag;to-tag. - * entity_no (int) - an integer that holds the entity of the - entity/participant to bridge. - * adv_contact (string, optional) - Contact header to - advertise in generated messages. - * flags (string, optional) - Flags that can modify the - behavior of the function. Available flags are: - + late_bye - instead of terminating the replaced entity - on the stop, leave it pending until the new enity - fully establishes. - - Example 1.32. b2b_bridge_request usage -... -if ($rU == "pickup") { - # get the b2b logic key of the parked call for this user - cache_fetch("local", "$fU", $var(b2bl_key)); - cache_remove("local", "$fU"); - - if ($var(b2bl_key) != NULL) - b2b_bridge_request($var(b2bl_key), 0); - else - send_reply(481, "Call/Transaction Does Not Exist"); - - exit; -} -... - -1.5.12. b2b_trigger_scenario(scenario, [params], peer1, -[extra_headers_peer1], [extra_headers_contents_peer1], peer2 -[extra_headers_peer2], [extra_headers_contents_peer2]) - - This function triggers a certain scenario from routing script, - e.g. out-of-dialog REFERs. - - Parameters: - * scenario (string) - Name of the scenario to be triggered. - * params (string, optional) - Parameters to be used in this - scenario (optionally as CSV) - + n - Enable rfc3515 NOTIFY to inform the agent sending - the REFER of the status of the reference. - + session key (string, optional) - Internal session key, - if the NOTIFY should be sent in a different session on - this B2B-UA (e.g. useful for receiving out-of-dialog - REFERs) - + party of remote session (int, optional) - If the - NOTIFY should be sent to a different session, which - side should receive the NOTIFY of the session (0 = - A-Party of the session, 1 = B-Party of the session) - * peer1 (string) - Parameters to define the A-Party of the - triggered scenario - + entitiy_name (string) - Name of the entity - + RURI (string) - R-URI of the entity to contact - + Proxy (string, optional) - Outbound Proxy to be used - for this entity - + Display-Name (string, optional) - Display Name to be - used for this entity - * extra_headers_peer1 (var, optional) - AVP variable holding - a list of extra headers (the header names) to be added for - any request sent for the first entity. - * extra_headers_contents_peer1 (var, optional) - AVP variable - holding a list of extra header bodies (corresponding to the - headers given in the extra_headers_peer1 parameter) to be - added for any request sent for the first entity. - * peer2 (string) - Parameters to define the B-Party of the - triggered scenario. The format is identitical to the - definition of peer1. - * extra_headers_peer2 (var, optional) - AVP variable holding - a list of extra headers (the header names) to be added for - any request sent for the second entity. - * extra_headers_contents_peer2 (var, optional) - AVP variable - holding a list of extra header bodies (corresponding to the - headers given in the extra_headers_peer2 parameter) to be - added for any request sent for the second entity. - - This function can be used from REQUEST_ROUTE. - - Example 1.33. b2b_trigger_scenario usage -... -if(is_method("REFER") && !has_totag()) { - $avp(header) = "Replaces"; - $avp(header_content) = "call-id=xyz"; - b2b_trigger_scenario("refer", "n", "conf,sip:conference@10.0.0.1", $a -vp(header), $avp(header_content), "callee,sip:user@10.0.0.1,sip:10.0.0.1 -"); - ... -} -... - -1.6. Exported MI Functions - -1.6.1. b2b_trigger_scenario - - This command initializes a new B2B session where OpenSIPS will - start a call from the middle. The initial entities to be - connected are specified through the command's parameters and - further scenario logic can be implemented in the b2b_logic - dedicated routes. - - Name: b2b_trigger_scenario - - Parameters: - * senario_id : ID for the scenario of this B2B session. - * entity1 - first entity to be connected; specified in the - following format: id,dest_uri[,from_dname] where: - + id - ID used to reference this entity in further B2B - actions - + dest_uri - URI of the new destination - + from_dname (optional) - Display name to use in the - From header. - * entity2 - second entity to be connected; specified in the - same format as entity1 - * context (array, optional) - array of B2B context values, in - the format: key=value - - MI FIFO Command Format: - opensips-cli -x mi b2b_trigger_scenario marketing client1,sip:bo -b@opensips.org client2,sip:322@opensips.org:5070 agent_uri=sip:alice@ope -nsips.org - -1.6.2. b2b_bridge - - This command can be used by an external application to tell - B2BUA to bridge a call party from an on going dialog to another - destination. By default the caller is bridged to the new uri - and BYE is set to the callee. You can instead bridge the callee - if you send 1 as the third parameter. - - Name: b2b_bridge - - Parameters: - * dialog_id : the b2b_logic key, or the - callid;from-tag;to-tag of the ongoing dialog. - * new_uri - the uri of the new destination - * flag (optional) - used to specify that the callee must be - bridged to the new destination. If not present the caller - will be bridged. Possible values are '0' or '1'. - * prov_media_uri (optional) - the uri of a media server able - to play provisional media starting from the beginning of - the bridging scenario to the end of it. It is optional. If - not present, no other entity will be envolved in the - bridging scenario - - MI FIFO Command Format: - opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org - - opensips-cli Command Format: - opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org - -1.6.3. b2b_list - - This command can be used to list the internals of b2b_logic - entities. - - Name: b2b_list - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi b2b_list - -1.6.4. b2b_terminate_call - - Terminates an ongoing B2B session. - - Name: b2b_terminate_call - - Parameters: - * key : the b2b_logic key or the callid;from-tag;to-tag of - one of call legs of the ongoing session. - - MI FIFO Command Format: - opensips-cli -x mi b2b_terminate_call 159.0 - -1.7. Exported Pseudo-Variables - -1.7.1. $b2b_logic.key - - This is a read-only variable that returns the b2b_logic key of - the ongoing B2B session. - - The variable can be used in request route, local_route and the - dedicated routes defined through the b2b_entities and b2b_logic - modules. - - Example 1.34. $b2b_logic.key usage -... -local_route { - ... - if ($b2b_logic.key) { - xlog("request belongs to B2B session: $b2b_logic.key\n"); - ... - } - ... -} -... - -1.7.2. $b2b_logic.entity(field)[idx] - - This is a read-only variable that returns information about the - entities(dialogs) involved in the ongoing B2B session. - - The available entity information is: - * the Call-ID of the dialog, accessible by using the callid - subname; - * the entity key, accessible by using the key subname or no - subname at all. - * the entity ID, accessible by using the id subname. - * the From-Tag of the dialog, accessible by using the fromtag - subname. - * the To-Tag of the dialog, accessible by using the totag - subname. - - The index is used to select which entity from the B2B session - to refer to. The only possible values are 0 or 1 and correspond - to the positions of the entities in the scenario. Initially, - this depends on the order in which the entities are created. In - the case of the internal topology hiding scenario, 0 is the - caller and 1 is the callee. When a further bridge action - happens, the bridged entity is always placed on the 0 index and - the new entity on 1. - - If no index is provided, the variable will refer to the - entity(dialog) which the current SIP message belongs to. - - The variable can be used in request route, local_route and the - dedicated routes defined through the b2b_entities and b2b_logic - modules. - - Example 1.35. $b2b_logic.entity usage -... -modparam("b2b_entities", "script_request_route", "b2b_request") -... -route[b2b_request] { - ... - xlog("received request for entity: $b2b_logic.entity\n"); - ... - if ($rm == "BYE" && $b2b_logic.entity == $(b2b_logic.entity[1])) - xlog("Disconnecting callee\n") - ... -} -... - -1.7.3. $b2b_logic.ctx(key) - - This is a read-write variable that provides access to a custom - Key-Value storage(of string values) in the context of the - ongoing B2B session. - - The variable can be used in request route, local_route and the - dedicated routes defined through the b2b_entities and b2b_logic - modules. In the main request route the variable can be used for - storing a new context value even before instantiating the - scenario with b2b_init_request(). - - Setting the variable to NULL will delete the value at the given - key. - - Example 1.36. $b2b_logic.ctx usage -... -modparam("b2b_entities", "script_reply_route", "b2b_reply") -... -route { - ... - b2b_init_request("prepaid", "sip:alice@127.0.0.1"); - - $b2b_logic.ctx(my_extra_info) = "my_value"; - ... -} -... -route[b2b_reply] { - ... - xlog("my info: $b2b_logic.ctx(my_extra_info)\n"); - ... -} -... - -1.7.4. $b2b_logic.scenario(key) - - This is a read-only variable that returns the scenario ID of - the ongoing B2B session - - The variable can be used in request route, local_route and the - dedicated routes defined through the b2b_entities and b2b_logic - modules. - - Example 1.37. $b2b_logic.scenario usage -... -route[b2b_logic_request] { - if ($b2b_logic.scenario == "prepaid") { - route(prepaid); - } else { - route(marketing); - } -} -... - -Chapter 2. Developer Guide - - The module provides an API that can be used from other OpenSIPS - modules. The API offers the functions for instantiating b2b - scenarios from other modules (this comes as an addition to the - other two means of instantiating b2b scenarios - from script - and with an MI command). Also the instantiations can be - dynamically controlled, by commanding the bridging of an entity - involved in a call to another entity or the termination of the - call or even bridging two existing calls. - -2.1. b2b_logic_bind(b2bl_api_t* api) - - This function binds the b2b_entities modules and fills the - structure the exported functions that will be described in - detail. - - Example 2.1. b2bl_api_t structure -... -typedef struct b2bl_api -{ - b2bl_init_f init; - b2bl_bridge_f bridge; - b2bl_bridge_extern_f bridge_extern; - b2bl_bridge_2calls_t bridge_2calls; - b2bl_terminate_call_t terminate_call; - b2bl_set_state_f set_state; - b2bl_bridge_msg_t bridge_msg; -}b2bl_api_t; -... - -2.2. init - - Field type: -... -typedef str* (*b2bl_init_f)(struct sip_msg* msg, str* name, str* args[5] -, - b2bl_cback_f, void* param); -... - - Initializing a b2b scenario. The last two parameters are the - callback function and the parameter to be called in 3 - situations that will be listed below. The callback function has - the following definition: -... -typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void -* param); -... - - The first argument is the callback given in the init function. - - The second argument is a structure with some statistics about - the call -start time, setup time, call time. - - The third argument is the current state of the scenario - instantiation. - - The last argument is the event that triggered the callback. - There are 3 events when the callback is called: - * when a BYE is received from either side- event parameter - will also show from which side the BYE is received, so it - can be B2B_BYE_E1 or B2B_BYE_E2 - * If while bridging, a negative reply is received from the - second entity - the event is B2B_REJECT_E2. - * When the b2b logic entity is deleted- the evnet is - B2B_DESTROY - - The return code controls what will happen with the - request/reply that caused the event (except for the last event, - when the return code does not matter) - * -1 - error - * 0 - drop the BYE or reply - * 1 - send the BYE or reply on the other side - * 2 - do what the scenario tells, if no rule defined send the - BYE or reply on the other side - -2.3. bridge - - Field type: -... -typedef int (*b2bl_bridge_f)(str* key, str* new_uri, str* new_from_dname -,int entity_type); -... - - This function allows bridging an entity that is in a call - handled by b2b_logic to another entity. - -2.4. bridge_extern - - Field type: -... -typedef str* (*b2bl_bridge_extern_f)(str* scenario_name, str* args[5], - b2bl_cback_f cbf, void* cb_param); -... - - This function allows initiating an extern scenario, when the - B2BUA starts a call from the middle. - -2.5. bridge_2calls - - Field type: -... -typedef int (*b2bl_bridge_2calls_t)(str* key1, str* key2); -... - - With this function it is possible to bridge two existing calls. - The first entity from the two calls will be connected and BYE - will be sent to their peers. - -2.6. terminate_call - - Field type: -... -typedef int (*b2bl_terminate_call_t)(str* key); -... - - Terminate a call. - -2.7. set_state - - Field type: -... -typedef int (*b2bl_set_state_f)(str* key, int state); -... - - Set the scenario state. - -2.8. bridge_msg - - Field type: -... -typedef int (*b2bl_bridge_msg_t)(struct sip_msg* msg, str* key, int enti -ty_no); -... - - This function allows bridging an incoming call to an entity - from an existing call. - - The first argument is the INVITE message of the current - incoming call. - - The second argument is the b2bl_key of an existing call. - - The third argument is the entity identifier. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 239 57 8167 6793 - 2. Razvan Crainea (@razvancrainea) 45 28 1210 315 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 15 11 152 76 - 4. Nick Altmann (@nikbyte) 14 10 346 36 - 5. Carsten Bock 12 5 679 23 - 6. Alexandra Titoc 11 9 14 14 - 7. Maksym Sobolyev (@sobomax) 7 5 31 31 - 8. Norman Brandinger (@NormB) 6 4 5 5 - 9. Liviu Chircu (@liviuchircu) 5 3 4 3 - 10. truong.hua 4 2 8 7 - - All remaining contributors: andingv, Aron Podrigal (@ar45), - Rick Barenthin, Shanee Vanstone, Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. andingv Nov 2025 - Nov 2025 - 2. Razvan Crainea (@razvancrainea) Jan 2021 - Sep 2025 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2021 - May 2025 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Norman Brandinger (@NormB) May 2024 - Jun 2024 - 6. Liviu Chircu (@liviuchircu) Nov 2020 - Feb 2024 - 7. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 8. Rick Barenthin Nov 2023 - Nov 2023 - 9. Vlad Patrascu (@rvlad-patrascu) Nov 2020 - Jul 2023 - 10. Shanee Vanstone Apr 2023 - Apr 2023 - - All remaining contributors: truong.hua, Nick Altmann - (@nikbyte), Carsten Bock, Aron Podrigal (@ar45), Zero King - (@l2dy). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Norman - Brandinger (@NormB), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Carsten Bock, Nick Altmann - (@nikbyte). - - Documentation Copyrights: - - Copyright © 2022 ng-voice GmbH - - Copyright © 2010 VoIP Embedded, Inc. - - Copyright © 2009 Anca-Maria Vamanu diff --git a/modules/b2b_logic/README.md b/modules/b2b_logic/README.md new file mode 100644 index 00000000000..0527d427052 --- /dev/null +++ b/modules/b2b_logic/README.md @@ -0,0 +1,1467 @@ +--- +title: "B2B_LOGIC" +description: "This module represents the logic engine of B2BUA, responsible of actually implementing the B2BUA services using the functions offered by the low level." +--- + +## Admin Guide + + +### Overview + + +The B2BUA implementation in OpenSIPS is separated in two layers: + + +- a lower one (implemented in the b2b_entities module) - the basic functions +of a UAS and UAC +- an upper one (implemented in b2b_logic module) - which represents the logic +engine of B2BUA, responsible of actually implementing the B2BUA services +using the functions offered by the low level. + + +This module is a B2BUA upper level implementation that can be used along with the +b2b_entities module in order to provide various B2BUA services (eg. PBX features). +The actual logic of the B2BUA scenarios can be implemented in dedicated script routes. + + +A B2B session can be triggered in two ways: + + +- from the script - at the receipt of an initial INVITE message +- with an extern command (MI) command - the server will connect two +end points in a session(Third Party Call Control). + + +High Availability for B2B sessions can be achieved by enabling the clustering support +offered by the the lower *b2b_entities* module (by setting the +[cluster_id](../b2b_entities#param_cluster_id) modparam from *b2b_entities*). + + +### Scenario Logic + + +After initializing a B2B session, the call legs will be handled by the b2b_logic +module and the first step will be to put the two initial entities in contact. +Requests and replies belonging to these dialogs will not enter the script through +the standard OpenSIPS routes but instead will be handled in b2b_logic dedicated routes +(defined through the [script req route](#param_script_req_route) and +[script reply route](#param_script_reply_route) modparams or, the custom routes given as +parameters to [b2b init request](#func_b2b_init_request)). +The further steps of the scenario can be implemented in these routes, by calling +dedicated b2b_logic script functions in order to perform various actions. Normal +"proxy-like" OpenSIPS functions should not be executed in the b2b_logic routes. + + +Some messages will be handled automatically by the module and will not enter the +b2b_logic routes at all (BYE requests received while in the process of bridging two +entities, ACKs/BYEs/replies for disconnected entities). Also, if no dedicated b2b_logic +reply route is defined, replies will be handled internally by the module, with the +same effects as calling [b2b handle reply](#func_b2b_handle_reply) from such a route if it were defined. + + +### Dependencies + + +#### OpenSIPS Modules + + +- *b2b_entities, a db module* + + +#### External Libraries or Applications + + +No libraries or applications required before running OpenSIPS with this module. + + +### Exported Parameters + + +#### hash_size (int) + + +The size of the hash table that stores the session entities. + + +*Default value is "9"* +(512 records). + + +```opensips title="Set server_hsize parameter" +... +modparam("b2b_logic", "hash_size", 10) +... + +``` + + +#### script_req_route (str) + + +The name of the script route to be called when requests belonging to +an ongoing B2B session are received. + + +```opensips title="Set script_req_route parameter" +... +modparam("b2b_logic", "script_req_route", "b2b_request") +... + +``` + + +#### script_reply_route (str) + + +The name of the script route to be called when replies belonging to +an ongoing B2B session are received. + + +```opensips title="Set script_repl_route parameter" +... +modparam("b2b_logic", "script_reply_route", "b2b_reply") +... + +``` + + +#### cleanup_period (int) + + +The time interval at which to search for an hanged b2b context. +A session is considered expired if the duration of a session exceeds its +defined lifetime. At that moment, BYE is sent in all the dialogs from that +context and the context is deleted. + + +*Default value is "100".* + + +```opensips title="Set cleanup_period parameter" +... +modparam("b2b_logic", "cleanup_period", 60) +... + +``` + + +#### custom_headers_regexp (str) + + +Regexp to search SIP header by names that should be passed +from the dialog of one side to the other side. There are a number +of headers that are passed by default. They are: + + +- Max-Forwards (it is decreased by 1) +- Content-Type +- Supported +- Allow +- Proxy-Require +- Session-Expires +- Min-SE +- Require +- RSeq + + +If you wish some other headers to be passed also you should define them +by setting this parameter. + + +It can be in forms like "regexp", "/regexp/" and "/regexp/flags". + + +Meaning of the flags is as follows: + + +- *i* - Case insensitive search. +- *e* - Use extended regexp. + + +*Default value is "NULL".* + + +```opensips title="Set parameter" +... +modparam("b2b_logic", "custom_headers_regexp", "/^x-/i") +... + +``` + + +#### custom_headers (str) + + +A list of SIP header names delimited by ';' that should be passed +from the dialog of one side to the other side. There are a number +of headers that are passed by default. They are: + + +- Max-Forwards (it is decreased by 1) +- Content-Type +- Supported +- Allow +- Proxy-Require +- Session-Expires +- Min-SE +- Require +- RSeq + + +If you wish some other headers to be passed also you should define them +by setting this parameter. + + +*Default value is "NULL".* + + +```opensips title="Set parameter" +... +modparam("b2b_logic", "custom_headers", "User-Agent;Date") +... + +``` + + +#### db_url (str) + + +Database URL. + + +```opensips title="Set db_url parameter" +... +modparam("b2b_logic", "db_url", "mysql://opensips:opensipsrw@127.0.0.1/opensips") +... + +``` + + +#### cachedb_url (str) + + +URL of a NoSQL database to be used. Only Redis is supported +at the moment. + + +```opensips title="Set cachedb_url parameter" +... +modparam("b2b_logic", "cachedb_url", "redis://localhost:6379/") +... + +``` + + +#### cachedb_key_prefix (string) + + +Prefix to use for every key set in the NoSQL database. + + +*Default value is "b2bl$".* + + +```opensips title="Set cachedb_key_prefix parameter" +... +modparam("b2b_logic", "cachedb_key_prefix", "b2b") +... + +``` + + +#### update_period (int) + + +The time interval at which to update the info in database. + + +*Default value is "100".* + + +```opensips title="Set update_period parameter" +... +modparam("b2b_logic", "update_period", 60) +... + +``` + + +#### max_duration (int) + + +The maximum duration of a call. + + +*Default value is "12 * 3600 (12 hours)".* + + +If you set it to 0, there will be no limitation. + + +```opensips title="Set max_duration parameter" +... +modparam("b2b_logic", "max_duration", 7200) +... + +``` + + +#### contact_user (int) + + +If set to 1, adds user from From: header to generated Contact: + + +*Default value is "0".* + + +```opensips title="Set contact_user parameter" +... +modparam("b2b_logic", "contact_user", 1) +... + +``` + + +#### b2bl_from_spec_param (string) + + +The name of the pseudo variable for storing the new +"From" header. +The PV must be set before calling "b2b_init_request". + + +*Default value is "NULL" (disabled).* + + +```opensips title="Set b2bl_from_spec_param parameter" +... +modparam("b2b_logic", "b2bl_from_spec_param", "$var(b2bl_from)") +... +route{ + ... + # setting the From header + $var(b2bl_from) = "\"Call ID\" "; + ... + b2b_init_request("top hiding"); + ... +} + +``` + + +#### server_address (str) + + +The IP address of the machine that will be used as Contact in +the generated messages. This is compulsory only when OpenSIPS +starts a call from the middle. For scenarios triggered by received +calls, if it is not set, it is constructed dynamically from the +socket where the initiating request was received. +This socket will be used to send all the requests, replies for that +session. +This parameter support Pseudo-Variables. + + +```opensips title="Set server_address parameter" +... +modparam("b2b_logic", "server_address", "sip:sa@10.10.10.10:5060") +... + +``` + + +```opensips title="Set server_address parameter using Pseudo-Variables" +... +modparam("b2b_logic", "server_address", "sip:$socket_in(advertised_ip):$socket_in(advertised_port)") +... + +``` + + +#### init_callid_hdr (str) + + +The module offers the possibility to insert the original callid in a header +in the generated Invites. If you want this, set this parameter to the name +of the header in which to insert the original callid. + + +```opensips title="Set init_callid_hdr parameter" +... +modparam("b2b_logic", "init_callid_hdr", "Init-CallID") +... + +``` + + +#### db_mode (int) + + +The B2B modules have support for the 3 type of database storage + + +- NO DB STORAGE - set this parameter to 0 +- WRITE THROUGH (synchronous write in database) - set this parameter to 1 +- WRITE BACK (update in db from time to time) - set this parameter to 2 + + +*Default value is "2" (WRITE BACK).* + + +```opensips title="Set db_mode parameter" +... +modparam("b2b_logic", "db_mode", 1) +... + +``` + + +#### db_table (str) + + +Name of the database table to be used + + +*Default value is "b2b_logic"* + + +```opensips title="Set db_table parameter" +... +modparam("b2b_logic", "db_table", "some_table_name") +... + +``` + + +#### b2bl_th_init_timeout (int) + + +Call setup timeout for topology hiding scenario. + + +*Default value is "60"* + + +```opensips title="Set b2bl_th_init_timeout parameter" +... +modparam("b2b_logic", "b2bl_th_init_timeout", 60) +... + +``` + + +#### b2bl_early_update (int) + + +Allow bridging of calls in early stage by issuing a "UPDATE" request + + +- 0 - Do not bridge dialogs in early stage +- 1 - Try to update an session in early stage by sending an UPDATE + + +*Default value is "0" Do not bridge dialogs in early stage* + + +```opensips title="Set b2bl_early_update parameter" +... +modparam("b2b_logic", "b2bl_early_update", 1) +... + +``` + + +#### old_entity_term_delay (int) + + +When the *b2b_bridge_request* is being used with the +*late_bye* flag, this parameter can delay the moment +when the BYE is being sent to the terminating entity. Thus, instead of +terminating it when the new entity is established, the BYE is delayed +with the value of this param, expressed in seconds. + + +*Default value is "0" - send BYE on the spot* + + +```opensips title="Set old_entity_term_delay parameter" +... +modparam("b2b_logic", "old_entity_term_delay", 2) # delay the BYE with 2 seconds +... + +``` + + +### Exported Functions + + +#### b2b_init_request(id, [flags], [req_route], [reply_route]) + + +This function initializes a new B2B session based on an initial INVITE. +A new server entity and a new client entity must be created before running +this function, with [b2b server new](#func_b2b_server_new) and +[b2b client new](#func_b2b_client_new), respectively. These are the initial +entities to be connected and further scenario logic can be implemented in +the b2b_logic dedicated routes. + + +Parameters: + + +- *scenario_id (string)* - identifier for +the scenario of this B2B session. The special value *top hiding* +initializes an internal topology hiding scenario. This scenario will do +a simple pass-through of messages from one side to another, and no additional +scripting or dedicated routes are required. +- *flags (string, optional)* - CSV list of the following flags: + - *setup-timeout=[nn]* - Call setup timeout. 0 sets timeout to max_duration value. Example: "setup-timeout=300". + - *transparent-auth* - Transparent authentication. In this mode b2b passes your 401 or 407 authentication request to destination server. + - *preserve-to* - Preserve To: header. +- *req_route (string, optional)* - name of the script route +to be called when requests belonging to this B2B session are received. This +parameter will override the global [script req route](#param_script_req_route) +modparam for this particular B2B session. +- *reply_route (string, optional)* - name of the script route +to be called when replies belonging to this B2B session are received. This +parameter will override the global [script reply route](#param_script_reply_route) +modparam for this particular B2B session. + + +This function can be used from REQUEST_ROUTE. + + +> [!NOTE] +> If you have a multi interface setup and want to change the outbound interface, +it is mandatory to use the "force_send_socket()" core function before passing +control to b2b function. If you do not do it, the requests may be correctly routed, +but the SIP pacakge may be invalid (as Contact, Via, etc). + + +```opensips title="b2b_init_request usage" +... +if(is_method("INVITE") && !has_totag() && prepaid_user()) { + ... + # create initial entities + b2b_server_new("server1"); + b2b_client_new("client1", $var(media_uri)); + + # initialize B2B session + b2b_init_request("prepaid"); + exit; +} +... + +``` + + +#### b2b_server_new(id, [adv_contact], [extra_hdrs], [extra_hdr_bodies]) + + +This function creates a new server entity (dialog where OpenSIPS acts as a UAS) +to be used for initializing a new B2B session. It should only be +used for initial INVITES, before calling [b2b init request](#func_b2b_init_request). + + +Parameters: + + +- *id (string)* - ID used to reference this entity +in further B2B actions. +- *adv_contact (string, optional)* - Contact header to +advertise in generated messages. +- *extra_hdrs (var, optional)* - AVP variable holding a list +of extra headers (the header names) to be added for any request sent +to this entity. +- *extra_hdr_bodies (var, optional)* - AVP variable holding a +list of extra header bodies (corresponding to the headers given in the +*extra_hdrs* parameter) to be added for any request +sent to this entity. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="b2b_server_new usage" +... +if(is_method("INVITE") && !has_totag()) { + b2b_server_new("server1", $avp(b2b_hdrs), $avp(b2b_hdr_bodies)); + ... +} +... + +``` + + +#### b2b_client_new(id, dest_uri, [proxy], [from_dname], [adv_contact], [extra_hdrs], [extra_hdr_bodies]) + + +This function creates a new client entity (dialog where OpenSIPS acts as a UAC) +to be used for initializing a new B2B session or for a bridge action. The function +can be used before calling [b2b init request](#func_b2b_init_request) or +[b2b bridge](#func_b2b_bridge). + + +Parameters: + + +- *id (string)* - ID used to reference this entity +in further B2B actions. +- *dest_uri (string)* - URI of the new destination. +- *proxy (string, optional)* - URI of the outbound proxy +to send the INVITE to. +- *from_dname (string, optional)* - Display name to +use in the From header. +- *adv_contact (string, optional)* - Contact header to +advertise in generated messages. +- *extra_hdrs (var, optional)* - AVP variable holding a list +of extra headers (the header names) to be added for any request sent +to this entity. +- *extra_hdr_bodies (var, optional)* - AVP variable holding a +list of extra header bodies (corresponding to the headers given in the +*extra_hdrs* parameter) to be added for any request +sent to this entity. + + +This function can be used from REQUEST_ROUTE and the b2b_logic request routes. + + +```opensips title="b2b_client_new usage" +... +b2b_client_new("client1", "sip:alice@opensips.org"); +... + +``` + + +#### b2b_bridge(entity1, entity2, [provmedia_uri], [flags]) + + +This function bridges two entities, in the context of an existing B2B session +(the initial entities are already connected). At least one of the two entities +has to be a new client entity. + + +Parameters: + + +- *entity1 (string)* - ID of the first entity to bridge; +the special values: *peer* and *this* +can also be used to refer to existing entities. +- *entity2 (string)* - ID of the second entity to bridge; +the special values: *peer* and *this* +can also be used to refer to existing entities. +- *provmedia_uri (string, optional)* - URI of the provisional +media server to be connected with the caller while the callee answers. +- *flags (string, optional)* - CSV list of the following flags: + - *max_duration=[nn]* - Maximum duration of the B2B + session. If the lifetime expires, the B2BUA will send BYE messages to both + ends and delete the record. This per-bridge value takes precedence over the + global [max duration](#param_max_duration) module parameter. + Example: "max_duration=300". + - *notify* - Enable rfc3515 NOTIFY to inform the agent + sending the REFER of the status of the reference. + - *rollback-failed* - Rollback call to state before + bridging in case of transfer failed, don't hangup the call + (default behaviour). + - *hold* - Put the old entity on hold before bridging + it to the new entity. + - *no-late-sdp* - Do not attempt late SDP negotiation + with the new entity. Start the bridging by first contacting the new entity + using the initial SDP received from the old entity. After the new entity + answers, send a reINVITE without body to the old entity. Use the current + SDP received in this new answer from the old entity to trigger a + renegotiation with the new entity. + + +This function can be used from the b2b_logic request routes. + + +```opensips title="b2b_bridge usage" +... +route[b2b_logic_request] { + ... + b2b_client_new("client2", $hdr(Refer-To)); + + b2b_bridge("peer", "client2"); +} +... + +``` + + +#### b2b_bridge_retry(new_entity) + + +This function can be used to retry a failed bridging action by contacting +a new destination. A new client entity must be created before running this +function with [b2b client new](#func_b2b_client_new). + + +Parameters: + + +- *entity1 (string)* - ID of the new entity to bridge. + + +This function can be used from the b2b_logic reply route. + + +```opensips title="b2b_bridge usage" +... +route[b2b_logic_reply] { + ... + if ($b2b_logic.entity(id) == "client1" && $rm == "INVITE" && $rs >= 300) { + b2b_client_new("client_retry", "sip:alice@opensips.org"); + + b2b_bridge_retry("client_retry"); + } else { + b2b_handle_reply(); + } + ... +} +... + +``` + + +#### b2b_pass_request() + + +This function passes a request belonging to an existing B2B session +to the peer entity. The function should be called for all requests unless +a different action is required to implement the scenario logic (eg. a +bridge action). + + +This function can be used from the b2b_logic request routes. + + +```opensips title="b2b_pass_request usage" +... +route[b2b_logic_request] { + if ($rm != "BYE") { + b2b_pass_request(); + exit; + } else { + # delete the current entity and bridge the peer to a new one + } +... + +``` + + +#### b2b_handle_reply([flags]) + + +This function processes the received reply by taking the appropriate actions +for the current state of the ongoing B2B session (pass reply to peer, +send INVITE or ACK to comeplete an ongoing bridge action etc.). +The function should be called for all replies, if a b2b_logic reply +route is defined. + + +This function can be used from the b2b_logic reply routes. + + +Parameters: + + +- *flags (string, optional)* - a list of comma +separated flags that changes the behavior of the reply processing. +Supported values are: + * *pass-3xx-contact* - When a redirect reply (3xx) message is received, pass the contact to the other peer just as it is, without modifying it. + + +```opensips title="b2b_handle_reply usage" +... +route[b2b_logic_reply] { + xlog("B2B REPLY: [$rs $rm] from entity: $b2b_logic.entity(id)\n"); + b2b_handle_reply(); +} +... + +``` + + +#### b2b_send_reply(code, reason[, headers[, body]]) + + +This function sends a reply to the entity that sent the current +request. + + +Parameters: + + +- *code (int)* - reply code +- *reason (string)* - reply reason string +- *headers (string, optional)* - additional headers +- *body (string, optional)* - message body + + +This function can be used from the b2b_logic request routes. + + +```opensips title="b2b_send_reply usage" +... +route[b2b_logic_request] { + if ($rm == "REFER") { + b2b_send_reply(202, "Accepted"); + ... + } +} +... + +``` + + +#### b2b_delete_entity() + + +This function deletes the entity that sent the current request. + + +This function can be used from the b2b_logic request routes. + + +```opensips title="b2b_delete_entity usage" +... +route[b2b_logic_request] { + if ($rm == "BYE") { + b2b_send_reply(200, "OK"); + b2b_delete_entity(); + ... + } +} +... + +``` + + +#### b2b_end_dlg_leg() + + +This function sends a BYE request to the entity that sent +the current request. It is not required to also call +[b2b delete entity](#func_b2b_delete_entity) in order to delete +the current entity. + + +This function can be used from the b2b_logic request or reply routes. + + +```opensips title="b2b_end_dlg_leg usage" +... +route[b2b_logic_request] { + if ($rm == "REFER") { + b2b_send_reply(202, "Accepted"); + b2b_end_dlg_leg(); + } +} +... + +``` + + +#### b2b_bridge_request(b2bl_key,entity_no, [adv_contact], [flags]) + + +This function will bridge an initial INVITE with one of the +particapnts from an existing b2b session. + + +Parameters: + + +- *b2bl_key (string)* - a string that +contains the b2b_logic key. The key can also be in the form +of *callid;from-tag;to-tag*. +- *entity_no (int)* - an integer that +holds the entity of the entity/participant to bridge. +- *adv_contact (string, optional)* - Contact header to +advertise in generated messages. +- *flags (string, optional)* - Flags that can modify the +behavior of the function. Available flags are: + * *late_bye* - instead of terminating the replaced entity + on the stop, leave it pending until the new enity fully establishes. + + +```opensips title="b2b_bridge_request usage" +... +if ($rU == "pickup") { + # get the b2b logic key of the parked call for this user + cache_fetch("local", "$fU", $var(b2bl_key)); + cache_remove("local", "$fU"); + + if ($var(b2bl_key) != NULL) + b2b_bridge_request($var(b2bl_key), 0); + else + send_reply(481, "Call/Transaction Does Not Exist"); + + exit; +} +... + +``` + + +#### b2b_trigger_scenario(scenario, [params], peer1, [extra_headers_peer1], [extra_headers_contents_peer1], peer2 [extra_headers_peer2], [extra_headers_contents_peer2]) + + +This function triggers a certain scenario from routing script, e.g. +out-of-dialog REFERs. + + +Parameters: + + +- *scenario (string)* - Name of the scenario to be triggered. +- *params (string, optional)* - Parameters to be used in this scenario (optionally as CSV) + + - *n* - Enable rfc3515 NOTIFY to inform the agent sending the +REFER of the status of the reference. + - *session key (string, optional)* - Internal session key, if the NOTIFY should be sent +in a different session on this B2B-UA (e.g. useful for receiving out-of-dialog REFERs) + - *party of remote session (int, optional)* - If the NOTIFY should be sent to a different session, which +side should receive the NOTIFY of the session (0 = A-Party of the session, 1 = B-Party of the session) +- *peer1 (string)* - Parameters to define the A-Party of the triggered scenario + + - *entitiy_name (string)* - Name of the entity + - *RURI (string)* - R-URI of the entity to contact + - *Proxy (string, optional)* - Outbound Proxy to be used for this entity + - *Display-Name (string, optional)* - Display Name to be used for this entity +- *extra_headers_peer1 (var, optional)* - AVP variable holding a list +of extra headers (the header names) to be added for any request sent for the first entity. +- *extra_headers_contents_peer1 (var, optional)* - AVP variable holding a +list of extra header bodies (corresponding to the headers given in the +*extra_headers_peer1* parameter) to be added for any request +sent for the first entity. +- *peer2 (string)* - Parameters to define the B-Party of the +triggered scenario. The format is identitical to the definition of *peer1*. +- *extra_headers_peer2 (var, optional)* - AVP variable holding a list +of extra headers (the header names) to be added for any request sent for the second entity. +- *extra_headers_contents_peer2 (var, optional)* - AVP variable holding a +list of extra header bodies (corresponding to the headers given in the +*extra_headers_peer2* parameter) to be added for any request +sent for the second entity. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="b2b_trigger_scenario usage" +... +if(is_method("REFER") && !has_totag()) { + $avp(header) = "Replaces"; + $avp(header_content) = "call-id=xyz"; + b2b_trigger_scenario("refer", "n", "conf,sip:conference@10.0.0.1", $avp(header), $avp(header_content), "callee,sip:user@10.0.0.1,sip:10.0.0.1"); + ... +} +... + +``` + + +### Exported MI Functions + + +#### b2b_trigger_scenario + + +This command initializes a new B2B session where OpenSIPS will start +a call from the middle. The initial entities to be connected are +specified through the command's parameters and further scenario logic +can be implemented in the b2b_logic dedicated routes. + + +Name: *b2b_trigger_scenario* + + +Parameters: + + +- *senario_id* : ID for the scenario of this B2B session. +- *entity1* - first entity to be connected; specified +in the following format: *id,dest_uri[,from_dname]* where: + + - *id* - ID used to reference this entity +in further B2B actions + - *dest_uri* - URI of the new destination + - *from_dname (optional)* - Display name to +use in the From header. +- *entity2* - second entity to be connected; +specified in the same format as *entity1* +- *context (array, optional)* - array of B2B +context values, in the format: *key=value* + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi b2b_trigger_scenario marketing client1,sip:bob@opensips.org client2,sip:322@opensips.org:5070 agent_uri=sip:alice@opensips.org + +``` + + +#### b2b_bridge + + +This command can be used by an external application to tell B2BUA to bridge a +call party from an on going dialog to another destination. By default the caller +is bridged to the new uri and BYE is set to the callee. You can instead bridge +the callee if you send 1 as the third parameter. + + +Name: *b2b_bridge* + + +Parameters: + + +- *dialog_id* : the *b2b_logic key*, or the +*callid;from-tag;to-tag* of the ongoing dialog. +- *new_uri* - the uri of the new destination +- *flag* (optional) - used to specify that the callee must be bridged to the new destination. If not present the caller will be bridged. Possible values are +'0' or '1'. +- *prov_media_uri* (optional) - the uri of a media server able to play +provisional media starting from the beginning of the bridging scenario +to the end of it. It is optional. If not present, no other entity will be +envolved in the bridging scenario + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org + +``` + + +opensips-cli Command Format: + + +```bash + opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org + +``` + + +#### b2b_list + + +This command can be used to list the internals of b2b_logic entities. + + +Name: *b2b_list* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi b2b_list + +``` + + +#### b2b_terminate_call + + +Terminates an ongoing B2B session. + + +Name: *b2b_terminate_call* + + +Parameters: + + +- *key* : the *b2b_logic key* +or the *callid;from-tag;to-tag* of +one of call legs of the ongoing session. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi b2b_terminate_call 159.0 + +``` + + +### Exported Pseudo-Variables + + +#### $b2b_logic.key + + +This is a read-only variable that returns the b2b_logic key of the +ongoing B2B session. + + +The variable can be used in request route, local_route and the dedicated +routes defined through the *b2b_entities* and +*b2b_logic* modules. + + +```opensips title="$b2b_logic.key usage" +... +local_route { + ... + if ($b2b_logic.key) { + xlog("request belongs to B2B session: $b2b_logic.key\n"); + ... + } + ... +} +... + +``` + + +#### $b2b_logic.entity(field)[idx] + + +This is a read-only variable that returns information about the +entities(dialogs) involved in the ongoing B2B session. + + +The available entity information is: + + +- the Call-ID of the dialog, accessible by using the +*callid* subname; +- the entity key, accessible by using the +*key* subname or no subname at all. +- the entity ID, accessible by using the +*id* subname. +- the From-Tag of the dialog, accessible by using the +*fromtag* subname. +- the To-Tag of the dialog, accessible by using the +*totag* subname. + + +The index is used to select which entity from the B2B session to refer +to. The only possible values are *0* or *1* and correspond to the positions of the entities +in the scenario. Initially, this depends on the order in which the entities +are created. In the case of the internal topology hiding scenario, +*0* is the caller and *1* is the callee. +When a further bridge action happens, the bridged entity is always placed on the +*0* index and the new entity on *1*. + + +If no index is provided, the variable will refer to the entity(dialog) +which the current SIP message belongs to. + + +The variable can be used in request route, local_route and the dedicated +routes defined through the *b2b_entities* and +*b2b_logic* modules. + + +```opensips title="$b2b_logic.entity usage" +... +modparam("b2b_entities", "script_request_route", "b2b_request") +... +route[b2b_request] { + ... + xlog("received request for entity: $b2b_logic.entity\n"); + ... + if ($rm == "BYE" && $b2b_logic.entity == $(b2b_logic.entity[1])) + xlog("Disconnecting callee\n") + ... +} +... + +``` + + +#### $b2b_logic.ctx(key) + + +This is a read-write variable that provides access to a custom +Key-Value storage(of string values) in the context of the ongoing +B2B session. + + +The variable can be used in request route, local_route and the dedicated +routes defined through the *b2b_entities* and +*b2b_logic* modules. In the main request route +the variable can be used for storing a new context value even before +instantiating the scenario with *b2b_init_request()*. + + +Setting the variable to *NULL* will delete the value +at the given key. + + +```opensips title="$b2b_logic.ctx usage" +... +modparam("b2b_entities", "script_reply_route", "b2b_reply") +... +route { + ... + b2b_init_request("prepaid", "sip:alice@127.0.0.1"); + + $b2b_logic.ctx(my_extra_info) = "my_value"; + ... +} +... +route[b2b_reply] { + ... + xlog("my info: $b2b_logic.ctx(my_extra_info)\n"); + ... +} +... + +``` + + +#### $b2b_logic.scenario(key) + + +This is a read-only variable that returns the scenario ID of the ongoing +B2B session + + +The variable can be used in request route, local_route and the dedicated +routes defined through the *b2b_entities* and +*b2b_logic* modules. + + +```opensips title="$b2b_logic.scenario usage" +... +route[b2b_logic_request] { + if ($b2b_logic.scenario == "prepaid") { + route(prepaid); + } else { + route(marketing); + } +} +... + +``` + + +## Developer Guide + + +The module provides an API that can be used from other OpenSIPS +modules. The API offers the functions for instantiating b2b +scenarios from other modules (this comes as an addition to the +other two means of instantiating b2b scenarios - from script +and with an MI command). Also the instantiations can be +dynamically controlled, by commanding the bridging of an entity +involved in a call to another entity or the termination of the +call or even bridging two existing calls. + + +### b2b_logic_bind(b2bl_api_t* api) + + +This function binds the b2b_entities modules and fills the +structure the exported functions that will be described in +detail. + + +```c title="b2bl_api_t structure" +... +typedef struct b2bl_api +{ + b2bl_init_f init; + b2bl_bridge_f bridge; + b2bl_bridge_extern_f bridge_extern; + b2bl_bridge_2calls_t bridge_2calls; + b2bl_terminate_call_t terminate_call; + b2bl_set_state_f set_state; + b2bl_bridge_msg_t bridge_msg; +}b2bl_api_t; +... +``` + + +### init + + +Field type: + + +```opensips +... +typedef str* (*b2bl_init_f)(struct sip_msg* msg, str* name, str* args[5], + b2bl_cback_f, void* param); +... +``` + + +Initializing a b2b scenario. The last two parameters are the +callback function and the parameter to be called in 3 +situations that will be listed below. The callback function has +the following definition: + + +```c +... +typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void* param); +... +``` + + +The first argument is the callback given in the init function. + + +The second argument is a structure with some statistics about +the call -start time, setup time, call time. + + +The third argument is the current state of the scenario +instantiation. + + +The last argument is the event that triggered the callback. +There are 3 events when the callback is called: + + +- *when a BYE is received from either side- event parameter +will also show from which side the BYE is received, so it +can be B2B_BYE_E1 or B2B_BYE_E2* +- *If while bridging, a negative reply is received from the +second entity - the event is B2B_REJECT_E2.* +- *When the b2b logic entity is deleted- the evnet is +B2B_DESTROY* + + +The return code controls what will happen with the +request/reply that caused the event (except for the last event, +when the return code does not matter) + + +- *-1 - error* +- *0 - drop the BYE or reply* +- *1 - send the BYE or reply on the other side* +- *2 - do what the scenario tells, if no rule defined send the +BYE or reply on the other side* + + +### bridge + + +Field type: + + +```c +... +typedef int (*b2bl_bridge_f)(str* key, str* new_uri, str* new_from_dname,int entity_type); +... +``` + + +This function allows bridging an entity that is in a call +handled by b2b_logic to another entity. + + +### bridge_extern + + +Field type: + + +```c +... +typedef str* (*b2bl_bridge_extern_f)(str* scenario_name, str* args[5], + b2bl_cback_f cbf, void* cb_param); +... +``` + + +This function allows initiating an extern scenario, when the +B2BUA starts a call from the middle. + + +### bridge_2calls + + +Field type: + + +```c +... +typedef int (*b2bl_bridge_2calls_t)(str* key1, str* key2); +... +``` + + +With this function it is possible to bridge two existing calls. +The first entity from the two calls will be connected and BYE +will be sent to their peers. + + +### terminate_call + + +Field type: + + +```c +... +typedef int (*b2bl_terminate_call_t)(str* key); +... +``` + + +Terminate a call. + + +### set_state + + +Field type: + + +```c +... +typedef int (*b2bl_set_state_f)(str* key, int state); +... +``` + + +Set the scenario state. + + +### bridge_msg + + +Field type: + + +```c +... +typedef int (*b2bl_bridge_msg_t)(struct sip_msg* msg, str* key, int entity_no); +... +``` + + +This function allows bridging an incoming call to an entity from an +existing call. + + +The first argument is the INVITE message of the current incoming call. + + +The second argument is the b2bl_key of an existing call. + + +The third argument is the entity identifier. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/b2b_logic/bridging.c b/modules/b2b_logic/bridging.c index 394a8824406..2913d606429 100644 --- a/modules/b2b_logic/bridging.c +++ b/modules/b2b_logic/bridging.c @@ -270,6 +270,7 @@ int process_bridge_dialog_end(b2bl_tuple_t* tuple, unsigned int hash_index, /* send cancel or bye to the peers */ b2b_end_dialog(tuple->bridge_entities[1], tuple, hash_index); b2b_end_dialog(tuple->bridge_entities[2], tuple, hash_index); + b2b_end_dialog(tuple->bridge_initiator, tuple, hash_index); b2b_mark_todel(tuple); } else @@ -386,17 +387,13 @@ int process_bridge_bye(struct sip_msg* msg, b2bl_tuple_t* tuple, entity && tuple->bridge_initiator == entity) { entity_no = 3; // Bridge initiator + } else if (!entity) { + LM_ERR("No match found\n"); + return -1; } else { entity_no = bridge_get_entityno(tuple, entity); - if(entity_no < 0) - { - if (!entity) { - LM_ERR("No match found\n"); - return -1; - } - /* we've got a known entity, but no longer part of the - * bridge - we gracefully reply and drop */ - } + /* we've got a known entity, but no longer part of the + * bridge - we gracefully reply and drop */ } memset(&rpl_data, 0, sizeof(b2b_rpl_data_t)); diff --git a/modules/b2b_logic/doc/b2b_logic.xml b/modules/b2b_logic/doc/b2b_logic.xml deleted file mode 100644 index 30a9cda12bd..00000000000 --- a/modules/b2b_logic/doc/b2b_logic.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - B2B_LOGIC - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2022 ng-voice GmbH - ©right; 2010 VoIP Embedded, Inc. - ©right; 2009 Anca-Maria Vamanu - - - diff --git a/modules/b2b_logic/doc/b2b_logic_admin.xml b/modules/b2b_logic/doc/b2b_logic_admin.xml deleted file mode 100644 index 6607f552b09..00000000000 --- a/modules/b2b_logic/doc/b2b_logic_admin.xml +++ /dev/null @@ -1,1474 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The B2BUA implementation in OpenSIPS is separated in two layers: - - - a lower one (implemented in the b2b_entities module) - the basic functions - of a UAS and UAC - - - an upper one (implemented in b2b_logic module) - which represents the logic - engine of B2BUA, responsible of actually implementing the B2BUA services - using the functions offered by the low level. - - - - - This module is a B2BUA upper level implementation that can be used along with the - b2b_entities module in order to provide various B2BUA services (eg. PBX features). - The actual logic of the B2BUA scenarios can be implemented in dedicated script routes. - - - A B2B session can be triggered in two ways: - - - from the script - at the receipt of an initial INVITE message - - - with an extern command (MI) command - the server will connect two - end points in a session(Third Party Call Control). - - - - - High Availability for B2B sessions can be achieved by enabling the clustering support - offered by the the lower b2b_entities module (by setting the - - cluster_id modparam from b2b_entities). - -
- -
- Scenario Logic - - After initializing a B2B session, the call legs will be handled by the b2b_logic - module and the first step will be to put the two initial entities in contact. - Requests and replies belonging to these dialogs will not enter the script through - the standard OpenSIPS routes but instead will be handled in b2b_logic dedicated routes - (defined through the and - modparams or, the custom routes given as - parameters to ). - The further steps of the scenario can be implemented in these routes, by calling - dedicated b2b_logic script functions in order to perform various actions. Normal - "proxy-like" OpenSIPS functions should not be executed in the b2b_logic routes. - - - Some messages will be handled automatically by the module and will not enter the - b2b_logic routes at all (BYE requests received while in the process of bridging two - entities, ACKs/BYEs/replies for disconnected entities). Also, if no dedicated b2b_logic - reply route is defined, replies will be handled internally by the module, with the - same effects as calling from such a route if it were defined. - -
- -
- Dependencies -
- &osips; Modules - - - - b2b_entities, a db module - - - -
- -
- External Libraries or Applications - - No libraries or applications required before running &osips; with this module. - -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (int) - - The size of the hash table that stores the session entities. - - - Default value is 9 - - (512 records). - - - Set <varname>server_hsize</varname> parameter - -... -modparam("b2b_logic", "hash_size", 10) -... - - -
- -
- <varname>script_req_route</varname> (str) - - The name of the script route to be called when requests belonging to - an ongoing B2B session are received. - - - Set <varname>script_req_route</varname> parameter - -... -modparam("b2b_logic", "script_req_route", "b2b_request") -... - - -
- -
- <varname>script_reply_route</varname> (str) - - The name of the script route to be called when replies belonging to - an ongoing B2B session are received. - - - Set <varname>script_repl_route</varname> parameter - -... -modparam("b2b_logic", "script_reply_route", "b2b_reply") -... - - -
- -
- <varname>cleanup_period</varname> (int) - - The time interval at which to search for an hanged b2b context. - A session is considered expired if the duration of a session exceeds its - defined lifetime. At that moment, BYE is sent in all the dialogs from that - context and the context is deleted. - - - Default value is 100. - - - Set <varname>cleanup_period</varname> parameter - -... -modparam("b2b_logic", "cleanup_period", 60) -... - - -
- -
- <varname>custom_headers_regexp</varname> (str) - - Regexp to search SIP header by names that should be passed - from the dialog of one side to the other side. There are a number - of headers that are passed by default. They are: - - Max-Forwards (it is decreased by 1) - Content-Type - Supported - Allow - Proxy-Require - Session-Expires - Min-SE - Require - RSeq - - If you wish some other headers to be passed also you should define them - by setting this parameter. - - - It can be in forms like "regexp", "/regexp/" and "/regexp/flags". - - Meaning of the flags is as follows: - - - i - Case insensitive search. - - - e - Use extended regexp. - - - - Default value is NULL. - - - Set <varname></varname> parameter - -... -modparam("b2b_logic", "custom_headers_regexp", "/^x-/i") -... - - -
- -
- <varname>custom_headers</varname> (str) - - A list of SIP header names delimited by ';' that should be passed - from the dialog of one side to the other side. There are a number - of headers that are passed by default. They are: - - Max-Forwards (it is decreased by 1) - Content-Type - Supported - Allow - Proxy-Require - Session-Expires - Min-SE - Require - RSeq - - If you wish some other headers to be passed also you should define them - by setting this parameter. - - - Default value is NULL. - - - Set <varname></varname> parameter - -... -modparam("b2b_logic", "custom_headers", "User-Agent;Date") -... - - -
-
- <varname>db_url</varname> (str) - - Database URL. - - - Set <varname>db_url</varname> parameter - -... -modparam("b2b_logic", "db_url", "mysql://opensips:opensipsrw@127.0.0.1/opensips") -... - - -
-
- <varname>cachedb_url</varname> (str) - - URL of a NoSQL database to be used. Only Redis is supported - at the moment. - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("b2b_logic", "cachedb_url", "redis://localhost:6379/") -... - - -
-
- <varname>cachedb_key_prefix</varname> (string) - - Prefix to use for every key set in the NoSQL database. - - - - Default value is b2bl$. - - - - Set <varname>cachedb_key_prefix</varname> parameter - -... -modparam("b2b_logic", "cachedb_key_prefix", "b2b") -... - - -
-
- <varname>update_period</varname> (int) - - The time interval at which to update the info in database. - - - Default value is 100. - - - Set <varname>update_period</varname> parameter - -... -modparam("b2b_logic", "update_period", 60) -... - - -
-
- <varname>max_duration</varname> (int) - - The maximum duration of a call. - - - Default value is 12 * 3600 (12 hours). - - If you set it to 0, there will be no limitation. - - Set <varname>max_duration</varname> parameter - -... -modparam("b2b_logic", "max_duration", 7200) -... - - -
- -
- <varname>contact_user</varname> (int) - - If set to 1, adds user from From: header to generated Contact: - - - Default value is 0. - - - Set <varname>contact_user</varname> parameter - -... -modparam("b2b_logic", "contact_user", 1) -... - - -
- -
- <varname>b2bl_from_spec_param</varname> (string) - - The name of the pseudo variable for storing the new - From header. - The PV must be set before calling b2b_init_request. - - - Default value is NULL (disabled). - - - Set <varname>b2bl_from_spec_param</varname> parameter - -... -modparam("b2b_logic", "b2bl_from_spec_param", "$var(b2bl_from)") -... -route{ - ... - # setting the From header - $var(b2bl_from) = "\"Call ID\" <sip:user@opensips.org>"; - ... - b2b_init_request("top hiding"); - ... -} - - -
- -
- <varname>server_address</varname> (str) - - The IP address of the machine that will be used as Contact in - the generated messages. This is compulsory only when OpenSIPS - starts a call from the middle. For scenarios triggered by received - calls, if it is not set, it is constructed dynamically from the - socket where the initiating request was received. - This socket will be used to send all the requests, replies for that - session. - This parameter support Pseudo-Variables. - - - Set <varname>server_address</varname> parameter - -... -modparam("b2b_logic", "server_address", "sip:sa@10.10.10.10:5060") -... - - - - Set <varname>server_address</varname> parameter using Pseudo-Variables - -... -modparam("b2b_logic", "server_address", "sip:$socket_in(advertised_ip):$socket_in(advertised_port)") -... - - -
- -
- <varname>init_callid_hdr</varname> (str) - - The module offers the possibility to insert the original callid in a header - in the generated Invites. If you want this, set this parameter to the name - of the header in which to insert the original callid. - - - Set <varname>init_callid_hdr</varname> parameter - -... -modparam("b2b_logic", "init_callid_hdr", "Init-CallID") -... - - -
-
- <varname>db_mode</varname> (int) - - The B2B modules have support for the 3 type of database storage - - - - NO DB STORAGE - set this parameter to 0 - WRITE THROUGH (synchronous write in database) - set this parameter to 1 - WRITE BACK (update in db from time to time) - set this parameter to 2 - - - - Default value is 2 (WRITE BACK). - - - Set <varname>db_mode</varname> parameter - -... -modparam("b2b_logic", "db_mode", 1) -... - - -
- -
- <varname>db_table</varname> (str) - - Name of the database table to be used - - - Default value is b2b_logic - - - Set <varname>db_table</varname> parameter - -... -modparam("b2b_logic", "db_table", "some_table_name") -... - - -
- -
- <varname>b2bl_th_init_timeout</varname> (int) - - Call setup timeout for topology hiding scenario. - - - Default value is 60 - - - Set <varname>b2bl_th_init_timeout</varname> parameter - -... -modparam("b2b_logic", "b2bl_th_init_timeout", 60) -... - - -
- - -
- <varname>b2bl_early_update</varname> (int) - - Allow bridging of calls in early stage by issuing a "UPDATE" request - - - - 0 - Do not bridge dialogs in early stage - 1 - Try to update an session in early stage by sending an UPDATE - - - - Default value is 0 Do not bridge dialogs in early stage - - - Set <varname>b2bl_early_update</varname> parameter - -... -modparam("b2b_logic", "b2bl_early_update", 1) -... - - -
-
- <varname>old_entity_term_delay</varname> (int) - - When the b2b_bridge_request is being used with the - late_bye flag, this parameter can delay the moment - when the BYE is being sent to the terminating entity. Thus, instead of - terminating it when the new entity is established, the BYE is delayed - with the value of this param, expressed in seconds. - - - Default value is 0 - send BYE on the spot - - - Set <varname>old_entity_term_delay</varname> parameter - -... -modparam("b2b_logic", "old_entity_term_delay", 2) # delay the BYE with 2 seconds -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">b2b_init_request(id, [flags], [req_route], - [reply_route])</function> - - - This function initializes a new B2B session based on an initial INVITE. - A new server entity and a new client entity must be created before running - this function, with and - , respectively. These are the initial - entities to be connected and further scenario logic can be implemented in - the b2b_logic dedicated routes. - - Parameters: - - - scenario_id (string) - identifier for - the scenario of this B2B session. The special value top hiding - initializes an internal topology hiding scenario. This scenario will do - a simple pass-through of messages from one side to another, and no additional - scripting or dedicated routes are required. - - - flags (string, optional) - CSV list of the following flags: - - - setup-timeout=[nn] - Call setup timeout. 0 sets - timeout to max_duration value. Example: "setup-timeout=300". - - - transparent-auth - Transparent authentication. - In this mode b2b passes your 401 or 407 authentication request to - destination server. - - - preserve-to - Preserve To: header. - - - - - req_route (string, optional) - name of the script route - to be called when requests belonging to this B2B session are received. This - parameter will override the global - modparam for this particular B2B session. - - - reply_route (string, optional) - name of the script route - to be called when replies belonging to this B2B session are received. This - parameter will override the global - modparam for this particular B2B session. - - - - This function can be used from REQUEST_ROUTE. - - - If you have a multi interface setup and want to change the outbound interface, - it is mandatory to use the "force_send_socket()" core function before passing - control to b2b function. If you do not do it, the requests may be correctly routed, - but the SIP pacakge may be invalid (as Contact, Via, etc). - - - <function>b2b_init_request</function> usage - -... -if(is_method("INVITE") && !has_totag() && prepaid_user()) { - ... - # create initial entities - b2b_server_new("server1"); - b2b_client_new("client1", $var(media_uri)); - - # initialize B2B session - b2b_init_request("prepaid"); - exit; -} -... - - -
- -
- - <function moreinfo="none">b2b_server_new(id, [adv_contact], [extra_hdrs], - [extra_hdr_bodies])</function> - - - This function creates a new server entity (dialog where OpenSIPS acts as a UAS) - to be used for initializing a new B2B session. It should only be - used for initial INVITES, before calling . - - Parameters: - - - id (string) - ID used to reference this entity - in further B2B actions. - - - adv_contact (string, optional) - Contact header to - advertise in generated messages. - - - extra_hdrs (var, optional) - AVP variable holding a list - of extra headers (the header names) to be added for any request sent - to this entity. - - - extra_hdr_bodies (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers given in the - extra_hdrs parameter) to be added for any request - sent to this entity. - - - - This function can be used from REQUEST_ROUTE. - - - <function>b2b_server_new</function> usage - -... -if(is_method("INVITE") && !has_totag()) { - b2b_server_new("server1", $avp(b2b_hdrs), $avp(b2b_hdr_bodies)); - ... -} -... - - -
- -
- - <function moreinfo="none">b2b_client_new(id, dest_uri, [proxy], [from_dname], - [adv_contact], [extra_hdrs], [extra_hdr_bodies])</function> - - - This function creates a new client entity (dialog where OpenSIPS acts as a UAC) - to be used for initializing a new B2B session or for a bridge action. The function - can be used before calling or - . - - Parameters: - - - id (string) - ID used to reference this entity - in further B2B actions. - - - dest_uri (string) - URI of the new destination. - - - proxy (string, optional) - URI of the outbound proxy - to send the INVITE to. - - - from_dname (string, optional) - Display name to - use in the From header. - - - adv_contact (string, optional) - Contact header to - advertise in generated messages. - - - extra_hdrs (var, optional) - AVP variable holding a list - of extra headers (the header names) to be added for any request sent - to this entity. - - - extra_hdr_bodies (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers given in the - extra_hdrs parameter) to be added for any request - sent to this entity. - - - - This function can be used from REQUEST_ROUTE and the b2b_logic request routes. - - - <function>b2b_client_new</function> usage - -... -b2b_client_new("client1", "sip:alice@opensips.org"); -... - - -
- -
- - <function moreinfo="none">b2b_bridge(entity1, entity2, [provmedia_uri], [flags])</function> - - - This function bridges two entities, in the context of an existing B2B session - (the initial entities are already connected). At least one of the two entities - has to be a new client entity. - - Parameters: - - - entity1 (string) - ID of the first entity to bridge; - the special values: peer and this - can also be used to refer to existing entities. - - - entity2 (string) - ID of the second entity to bridge; - the special values: peer and this - can also be used to refer to existing entities. - - - provmedia_uri (string, optional) - URI of the provisional - media server to be connected with the caller while the callee answers. - - - flags (string, optional) - CSV list of the following flags: - - - max_duration=[nn] - Maximum duration of the B2B - session. If the lifetime expires, the B2BUA will send BYE messages to both - ends and delete the record. Example: "max_duration=300". - - - notify - Enable rfc3515 NOTIFY to inform the agent - sending the REFER of the status of the reference. - - - rollback-failed - Rollback call to state before - bridging in case of transfer failed, don't hangup the call - (default behaviour). - - - hold - Put the old entity on hold before bridging - it to the new entity. - - - no-late-sdp - Do not attempt late SDP negotiation - with the new entity. Start the bridging by first contacting the new entity - using the initial SDP received from the old entity. After the new entity - answers, send a reINVITE without body to the old entity. Use the current - SDP received in this new answer from the old entity to trigger a - renegotiation with the new entity. - - - - - - This function can be used from the b2b_logic request routes. - - - <function>b2b_bridge</function> usage - -... -route[b2b_logic_request] { - ... - b2b_client_new("client2", $hdr(Refer-To)); - - b2b_bridge("peer", "client2"); -} -... - - -
- -
- - <function moreinfo="none">b2b_bridge_retry(new_entity)</function> - - - This function can be used to retry a failed bridging action by contacting - a new destination. A new client entity must be created before running this - function with . - - Parameters: - - - entity1 (string) - ID of the new entity to bridge. - - - - This function can be used from the b2b_logic reply route. - - - <function>b2b_bridge</function> usage - -... -route[b2b_logic_reply] { - ... - if ($b2b_logic.entity(id) == "client1" && $rm == "INVITE" && $rs >= 300) { - b2b_client_new("client_retry", "sip:alice@opensips.org"); - - b2b_bridge_retry("client_retry"); - } else { - b2b_handle_reply(); - } - ... -} -... - - -
- -
- - <function moreinfo="none">b2b_pass_request()</function> - - - This function passes a request belonging to an existing B2B session - to the peer entity. The function should be called for all requests unless - a different action is required to implement the scenario logic (eg. a - bridge action). - - - This function can be used from the b2b_logic request routes. - - - <function>b2b_pass_request</function> usage - -... -route[b2b_logic_request] { - if ($rm != "BYE") { - b2b_pass_request(); - exit; - } else { - # delete the current entity and bridge the peer to a new one - } -... - - -
- -
- - <function moreinfo="none">b2b_handle_reply([flags])</function> - - - This function processes the received reply by taking the appropriate actions - for the current state of the ongoing B2B session (pass reply to peer, - send INVITE or ACK to comeplete an ongoing bridge action etc.). - The function should be called for all replies, if a b2b_logic reply - route is defined. - - - This function can be used from the b2b_logic reply routes. - - Parameters: - - - flags (string, optional) - a list of comma - separated flags that changes the behavior of the reply processing. - Supported values are: - - - pass-3xx-contact - When a redirect reply - (3xx) message is received, pass the contact to the other peer - just as it is, without modifying it. - - - - - - <function>b2b_handle_reply</function> usage - -... -route[b2b_logic_reply] { - xlog("B2B REPLY: [$rs $rm] from entity: $b2b_logic.entity(id)\n"); - b2b_handle_reply(); -} -... - - -
- -
- - <function moreinfo="none">b2b_send_reply(code, reason[, headers[, body]])</function> - - - This function sends a reply to the entity that sent the current - request. - - Parameters: - - - code (int) - reply code - - - reason (string) - reply reason string - - - headers (string, optional) - additional headers - - - body (string, optional) - message body - - - - This function can be used from the b2b_logic request routes. - - - <function>b2b_send_reply</function> usage - -... -route[b2b_logic_request] { - if ($rm == "REFER") { - b2b_send_reply(202, "Accepted"); - ... - } -} -... - - -
- -
- - <function moreinfo="none">b2b_delete_entity()</function> - - - This function deletes the entity that sent the current request. - - - This function can be used from the b2b_logic request routes. - - - <function>b2b_delete_entity</function> usage - -... -route[b2b_logic_request] { - if ($rm == "BYE") { - b2b_send_reply(200, "OK"); - b2b_delete_entity(); - ... - } -} -... - - -
- -
- - <function moreinfo="none">b2b_end_dlg_leg()</function> - - - This function sends a BYE request to the entity that sent - the current request. It is not required to also call - in order to delete - the current entity. - - - This function can be used from the b2b_logic request or reply routes. - - - <function>b2b_end_dlg_leg</function> usage - -... -route[b2b_logic_request] { - if ($rm == "REFER") { - b2b_send_reply(202, "Accepted"); - b2b_end_dlg_leg(); - } -} -... - - -
- -
- - <function moreinfo="none">b2b_bridge_request(b2bl_key,entity_no, [adv_contact], [flags])</function> - - - This function will bridge an initial INVITE with one of the - particapnts from an existing b2b session. - - Parameters: - - - b2bl_key (string) - a string that - contains the b2b_logic key. The key can also be in the form - of callid;from-tag;to-tag. - - - entity_no (int) - an integer that - holds the entity of the entity/participant to bridge. - - - adv_contact (string, optional) - Contact header to - advertise in generated messages. - - - flags (string, optional) - Flags that can modify the - behavior of the function. Available flags are: - - - late_bye - instead of terminating the replaced entity - on the stop, leave it pending until the new enity fully establishes. - - - - - - <function>b2b_bridge_request</function> usage - -... -if ($rU == "pickup") { - # get the b2b logic key of the parked call for this user - cache_fetch("local", "$fU", $var(b2bl_key)); - cache_remove("local", "$fU"); - - if ($var(b2bl_key) != NULL) - b2b_bridge_request($var(b2bl_key), 0); - else - send_reply(481, "Call/Transaction Does Not Exist"); - - exit; -} -... - - -
- -
- - <function moreinfo="none">b2b_trigger_scenario(scenario, [params], peer1, - [extra_headers_peer1], [extra_headers_contents_peer1], - peer2 - [extra_headers_peer2], [extra_headers_contents_peer2])</function> - - - This function triggers a certain scenario from routing script, e.g. - out-of-dialog REFERs. - - Parameters: - - - scenario (string) - Name of the scenario to be triggered. - - - - params (string, optional) - Parameters to be used in this scenario (optionally as CSV) - - - - n - Enable rfc3515 NOTIFY to inform the agent sending the - REFER of the status of the reference. - - - session key (string, optional) - Internal session key, if the NOTIFY should be sent - in a different session on this B2B-UA (e.g. useful for receiving out-of-dialog REFERs) - - - party of remote session (int, optional) - If the NOTIFY should be sent to a different session, which - side should receive the NOTIFY of the session (0 = A-Party of the session, 1 = B-Party of the session) - - - - - - peer1 (string) - Parameters to define the A-Party of the triggered scenario - - - - entitiy_name (string) - Name of the entity - - - RURI (string) - R-URI of the entity to contact - - - Proxy (string, optional) - Outbound Proxy to be used for this entity - - - Display-Name (string, optional) - Display Name to be used for this entity - - - - - extra_headers_peer1 (var, optional) - AVP variable holding a list - of extra headers (the header names) to be added for any request sent for the first entity. - - - extra_headers_contents_peer1 (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers given in the - extra_headers_peer1 parameter) to be added for any request - sent for the first entity. - - - peer2 (string) - Parameters to define the B-Party of the - triggered scenario. The format is identitical to the definition of peer1. - - - extra_headers_peer2 (var, optional) - AVP variable holding a list - of extra headers (the header names) to be added for any request sent for the second entity. - - - extra_headers_contents_peer2 (var, optional) - AVP variable holding a - list of extra header bodies (corresponding to the headers given in the - extra_headers_peer2 parameter) to be added for any request - sent for the second entity. - - - - This function can be used from REQUEST_ROUTE. - - - <function>b2b_trigger_scenario</function> usage - -... -if(is_method("REFER") && !has_totag()) { - $avp(header) = "Replaces"; - $avp(header_content) = "call-id=xyz"; - b2b_trigger_scenario("refer", "n", "conf,sip:conference@10.0.0.1", $avp(header), $avp(header_content), "callee,sip:user@10.0.0.1,sip:10.0.0.1"); - ... -} -... - - -
- -
- -
- Exported MI Functions -
- - <function moreinfo="none">b2b_trigger_scenario</function> - - - This command initializes a new B2B session where OpenSIPS will start - a call from the middle. The initial entities to be connected are - specified through the command's parameters and further scenario logic - can be implemented in the b2b_logic dedicated routes. - - - Name: b2b_trigger_scenario - - Parameters: - - - senario_id : ID for the scenario of this B2B session. - - - - entity1 - first entity to be connected; specified - in the following format: id,dest_uri[,from_dname] where: - - - id - ID used to reference this entity - in further B2B actions - - - dest_uri - URI of the new destination - - - from_dname (optional) - Display name to - use in the From header. - - - - - entity2 - second entity to be connected; - specified in the same format as entity1 - - - context (array, optional) - array of B2B - context values, in the format: key=value - - - - MI FIFO Command Format: - - - opensips-cli -x mi b2b_trigger_scenario marketing client1,sip:bob@opensips.org client2,sip:322@opensips.org:5070 agent_uri=sip:alice@opensips.org - -
- -
- - <function moreinfo="none">b2b_bridge</function> - - - This command can be used by an external application to tell B2BUA to bridge a - call party from an on going dialog to another destination. By default the caller - is bridged to the new uri and BYE is set to the callee. You can instead bridge - the callee if you send 1 as the third parameter. - - - Name: b2b_bridge - - Parameters: - - - dialog_id : the b2b_logic key, or the - callid;from-tag;to-tag of the ongoing dialog. - - - - new_uri - the uri of the new destination - - - flag (optional) - used to specify that the callee must be bridged to the new destination. If not present the caller will be bridged. Possible values are - '0' or '1'. - - - prov_media_uri (optional) - the uri of a media server able to play - provisional media starting from the beginning of the bridging scenario - to the end of it. It is optional. If not present, no other entity will be - envolved in the bridging scenario - - - MI FIFO Command Format: - - opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org - - opensips-cli Command Format: - - opensips-cli -x mi b2b_bridge 1020.30 sip:alice@opensips.org - -
- -
- - <function moreinfo="none">b2b_list</function> - - - This command can be used to list the internals of b2b_logic entities. - - - Name: b2b_list - - Parameters: none - - - MI FIFO Command Format: - - opensips-cli -x mi b2b_list - -
- -
- - <function moreinfo="none">b2b_terminate_call</function> - - - Terminates an ongoing B2B session. - - - Name: b2b_terminate_call - - Parameters: - - - key : the b2b_logic key - or the callid;from-tag;to-tag of - one of call legs of the ongoing session. - - - - MI FIFO Command Format: - - opensips-cli -x mi b2b_terminate_call 159.0 - -
- -
- -
- Exported Pseudo-Variables - -
- - <varname>$b2b_logic.key</varname> - - - This is a read-only variable that returns the b2b_logic key of the - ongoing B2B session. - - - The variable can be used in request route, local_route and the dedicated - routes defined through the b2b_entities and - b2b_logic modules. - - - <varname>$b2b_logic.key</varname> usage - -... -local_route { - ... - if ($b2b_logic.key) { - xlog("request belongs to B2B session: $b2b_logic.key\n"); - ... - } - ... -} -... - - -
- -
- - <varname>$b2b_logic.entity(field)[idx]</varname> - - - This is a read-only variable that returns information about the - entities(dialogs) involved in the ongoing B2B session. - - - The available entity information is: - - - the Call-ID of the dialog, accessible by using the - callid subname; - - - the entity key, accessible by using the - key subname or no subname at all. - - - the entity ID, accessible by using the - id subname. - - - the From-Tag of the dialog, accessible by using the - fromtag subname. - - - the To-Tag of the dialog, accessible by using the - totag subname. - - - - - The index is used to select which entity from the B2B session to refer - to. The only possible values are 0 or 1 - and correspond to the positions of the entities - in the scenario. Initially, this depends on the order in which the entities - are created. In the case of the internal topology hiding scenario, - 0 is the caller and 1 is the callee. - When a further bridge action happens, the bridged entity is always placed on the - 0 index and the new entity on 1. - - - If no index is provided, the variable will refer to the entity(dialog) - which the current SIP message belongs to. - - - The variable can be used in request route, local_route and the dedicated - routes defined through the b2b_entities and - b2b_logic modules. - - - <varname>$b2b_logic.entity</varname> usage - -... -modparam("b2b_entities", "script_request_route", "b2b_request") -... -route[b2b_request] { - ... - xlog("received request for entity: $b2b_logic.entity\n"); - ... - if ($rm == "BYE" && $b2b_logic.entity == $(b2b_logic.entity[1])) - xlog("Disconnecting callee\n") - ... -} -... - - -
- -
- - <varname>$b2b_logic.ctx(key)</varname> - - - This is a read-write variable that provides access to a custom - Key-Value storage(of string values) in the context of the ongoing - B2B session. - - - The variable can be used in request route, local_route and the dedicated - routes defined through the b2b_entities and - b2b_logic modules. In the main request route - the variable can be used for storing a new context value even before - instantiating the scenario with b2b_init_request(). - - - Setting the variable to NULL will delete the value - at the given key. - - - <varname>$b2b_logic.ctx</varname> usage - -... -modparam("b2b_entities", "script_reply_route", "b2b_reply") -... -route { - ... - b2b_init_request("prepaid", "sip:alice@127.0.0.1"); - - $b2b_logic.ctx(my_extra_info) = "my_value"; - ... -} -... -route[b2b_reply] { - ... - xlog("my info: $b2b_logic.ctx(my_extra_info)\n"); - ... -} -... - - -
- -
- - <varname>$b2b_logic.scenario(key)</varname> - - - This is a read-only variable that returns the scenario ID of the ongoing - B2B session - - - The variable can be used in request route, local_route and the dedicated - routes defined through the b2b_entities and - b2b_logic modules. - - - <varname>$b2b_logic.scenario</varname> usage - -... -route[b2b_logic_request] { - if ($b2b_logic.scenario == "prepaid") { - route(prepaid); - } else { - route(marketing); - } -} -... - - -
- -
- -
- diff --git a/modules/b2b_logic/doc/b2b_logic_devel.xml b/modules/b2b_logic/doc/b2b_logic_devel.xml deleted file mode 100644 index 063fc5897c8..00000000000 --- a/modules/b2b_logic/doc/b2b_logic_devel.xml +++ /dev/null @@ -1,252 +0,0 @@ - - - - &develguide; - - The module provides an API that can be used from other &osips; - modules. The API offers the functions for instantiating b2b - scenarios from other modules (this comes as an addition to the - other two means of instantiating b2b scenarios - from script - and with an MI command). Also the instantiations can be - dynamically controlled, by commanding the bridging of an entity - involved in a call to another entity or the termination of the - call or even bridging two existing calls. - -
- - <function moreinfo="none">b2b_logic_bind(b2bl_api_t* api)</function> - - - This function binds the b2b_entities modules and fills the - structure the exported functions that will be described in - detail. - - - <function>b2bl_api_t</function> structure - -... -typedef struct b2bl_api -{ - b2bl_init_f init; - b2bl_bridge_f bridge; - b2bl_bridge_extern_f bridge_extern; - b2bl_bridge_2calls_t bridge_2calls; - b2bl_terminate_call_t terminate_call; - b2bl_set_state_f set_state; - b2bl_bridge_msg_t bridge_msg; -}b2bl_api_t; -... - - - -
- -
- - <function moreinfo="none">init</function> - - - Field type: - - -... -typedef str* (*b2bl_init_f)(struct sip_msg* msg, str* name, str* args[5], - b2bl_cback_f, void* param); -... - - - Initializing a b2b scenario. The last two parameters are the - callback function and the parameter to be called in 3 - situations that will be listed below. The callback function has - the following definition: - - -... -typedef int (*b2b_notify_t)(struct sip_msg* msg, str* id, int type, void* param); -... - - - The first argument is the callback given in the init function. - - - The second argument is a structure with some statistics about - the call -start time, setup time, call time. - - - The third argument is the current state of the scenario - instantiation. - - - The last argument is the event that triggered the callback. - There are 3 events when the callback is called: - - - - - when a BYE is received from either side- event parameter - will also show from which side the BYE is received, so it - can be B2B_BYE_E1 or B2B_BYE_E2 - - - - - If while bridging, a negative reply is received from the - second entity - the event is B2B_REJECT_E2. - - - - - When the b2b logic entity is deleted- the evnet is - B2B_DESTROY - - - - - The return code controls what will happen with the - request/reply that caused the event (except for the last event, - when the return code does not matter) - - - - - -1 - error - - - - - 0 - drop the BYE or reply - - - - - 1 - send the BYE or reply on the other side - - - - - 2 - do what the scenario tells, if no rule defined send the - BYE or reply on the other side - - - -
- -
- - <function moreinfo="none">bridge</function> - - - Field type: - - -... -typedef int (*b2bl_bridge_f)(str* key, str* new_uri, str* new_from_dname,int entity_type); -... - - - This function allows bridging an entity that is in a call - handled by b2b_logic to another entity. - -
- -
- - <function moreinfo="none">bridge_extern</function> - - - Field type: - - -... -typedef str* (*b2bl_bridge_extern_f)(str* scenario_name, str* args[5], - b2bl_cback_f cbf, void* cb_param); -... - - - This function allows initiating an extern scenario, when the - B2BUA starts a call from the middle. - -
- -
- - <function moreinfo="none">bridge_2calls</function> - - - Field type: - - -... -typedef int (*b2bl_bridge_2calls_t)(str* key1, str* key2); -... - - - With this function it is possible to bridge two existing calls. - The first entity from the two calls will be connected and BYE - will be sent to their peers. - -
- -
- - <function moreinfo="none">terminate_call</function> - - - Field type: - - -... -typedef int (*b2bl_terminate_call_t)(str* key); -... - - - Terminate a call. - -
- -
- - <function moreinfo="none">set_state</function> - - - Field type: - - -... -typedef int (*b2bl_set_state_f)(str* key, int state); -... - - - Set the scenario state. - -
- -
- - <function moreinfo="none">bridge_msg</function> - - - Field type: - - -... -typedef int (*b2bl_bridge_msg_t)(struct sip_msg* msg, str* key, int entity_no); -... - - - This function allows bridging an incoming call to an entity from an - existing call. - - - The first argument is the INVITE message of the current incoming call. - - - The second argument is the b2bl_key of an existing call. - - - The third argument is the entity identifier. - -
- -
- diff --git a/modules/b2b_logic/doc/contributors.xml b/modules/b2b_logic/doc/contributors.xml deleted file mode 100644 index 5eb0e6bdbe3..00000000000 --- a/modules/b2b_logic/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 239 - 57 - 8167 - 6793 - - - 2. - Razvan Crainea (@razvancrainea) - 45 - 28 - 1210 - 315 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 15 - 11 - 152 - 76 - - - 4. - Nick Altmann (@nikbyte) - 14 - 10 - 346 - 36 - - - 5. - Carsten Bock - 12 - 5 - 679 - 23 - - - 6. - Alexandra Titoc - 11 - 9 - 14 - 14 - - - 7. - Maksym Sobolyev (@sobomax) - 7 - 5 - 31 - 31 - - - 8. - Norman Brandinger (@NormB) - 6 - 4 - 5 - 5 - - - 9. - Liviu Chircu (@liviuchircu) - 5 - 3 - 4 - 3 - - - 10. - truong.hua - 4 - 2 - 8 - 7 - - - -
-All remaining contributors: andingv, Aron Podrigal (@ar45), Rick Barenthin, Shanee Vanstone, Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - andingv - Nov 2025 - Nov 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jan 2021 - Sep 2025 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2021 - May 2025 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Norman Brandinger (@NormB) - May 2024 - Jun 2024 - - - 6. - Liviu Chircu (@liviuchircu) - Nov 2020 - Feb 2024 - - - 7. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 8. - Rick Barenthin - Nov 2023 - Nov 2023 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - Nov 2020 - Jul 2023 - - - 10. - Shanee Vanstone - Apr 2023 - Apr 2023 - - - -
-All remaining contributors: truong.hua, Nick Altmann (@nikbyte), Carsten Bock, Aron Podrigal (@ar45), Zero King (@l2dy). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Norman Brandinger (@NormB), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Carsten Bock, Nick Altmann (@nikbyte). -
- -
diff --git a/modules/b2b_logic/entity_storage.c b/modules/b2b_logic/entity_storage.c index 59a19bdb4b0..20e56c90f33 100644 --- a/modules/b2b_logic/entity_storage.c +++ b/modules/b2b_logic/entity_storage.c @@ -138,7 +138,7 @@ static void pack_entity(b2bl_tuple_t* tuple, enum b2b_entity_type entity_type, bin_push_str(storage, &entity->from_uri); bin_push_str(storage, &entity->from_dname); bin_push_str(storage, &entity->hdrs); - bin_push_str(storage, &entity->out_sdp); + bin_push_str(storage, &entity->in_sdp); bin_push_str(storage, &entity->dlginfo->callid); bin_push_str(storage, &entity->dlginfo->fromtag); @@ -351,6 +351,9 @@ static void receive_entity_create(enum b2b_entity_type entity_type, goto error; } + if (shm_str_sync(&entity->in_sdp, &sdp) < 0) + goto error; + memset(&dlginfo, 0, sizeof dlginfo); bin_pop_str(storage, &dlginfo.callid); bin_pop_str(storage, &dlginfo.fromtag); @@ -360,6 +363,7 @@ static void receive_entity_create(enum b2b_entity_type entity_type, LM_ERR("Failed to add entity dialoginfo\n"); goto error; } + bin_pop_str(storage, &sdp); bin_pop_int(storage, &entity->stats.start_time); bin_pop_int(storage, &entity->stats.setup_time); diff --git a/modules/b2b_logic/logic.c b/modules/b2b_logic/logic.c index 6b2ac317a1d..008d6ec9364 100644 --- a/modules/b2b_logic/logic.c +++ b/modules/b2b_logic/logic.c @@ -2323,6 +2323,7 @@ int b2b_logic_notify(int src, struct sip_msg* msg, str* key, int type, str* b2bl { LM_ERR("not enough space in the buffer: " "U_REPLACES_BUF_LEN < %d\n", i); + goto done; } memcpy(u_replaces.s, r_peer->dlginfo->callid.s, r_peer->dlginfo->callid.len); diff --git a/modules/b2b_sca/README b/modules/b2b_sca/README deleted file mode 100644 index ef68db835ce..00000000000 --- a/modules/b2b_sca/README +++ /dev/null @@ -1,518 +0,0 @@ -b2b_sca Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. To-do - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - - 1.4. Exported Parameters - - 1.4.1. hash_size(integer) - 1.4.2. presence_server(string) - 1.4.3. watchers_avp_spec(string) - 1.4.4. shared_line_spec_param(string) - 1.4.5. appearance_name_addr_spec_param(string) - 1.4.6. db_url(string) - 1.4.7. db_mode(integer) - 1.4.8. table_name(string) - 1.4.9. shared_line_column(string) - 1.4.10. watchers_column(string) - 1.4.11. app[index]_shared_entity_column(string) - 1.4.12. app[index]_call_state_column(string) - 1.4.13. app[index]_call_info_uri_column(string) - 1.4.14. - app[index]_call_info_appearance_uri_column(st - ring) - - 1.4.15. appindex_b2bl_key_column(string) - - 1.5. Exported Functions - - 1.5.1. sca_init_request(shared_line) - 1.5.2. sca_bridge_request(shared_line_to bridge) - - 1.6. Exported MI Functions - - 1.6.1. sca_list - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hash_size parameter - 1.2. Set presence_server parameter - 1.3. Set watchers_avp_spec parameter - 1.4. Set shared_line_spec_param parameter - 1.5. Set appearance_name_addr_spec_param parameter - 1.6. Set db_url parameter - 1.7. Set db_mode parameter - 1.8. Set table_name parameter - 1.9. Set shared_line_column parameter - 1.10. Set watchers_column parameter - 1.11. Set app[index]_shared_entity_column parameter - 1.12. Set app[index]_call_state_column parameter - 1.13. Set app[index]_call_info_uri_column parameter - 1.14. Set app[index]_call_info_appearance_uri_column parameter - 1.15. Set app[index]_b2bl_key_column parameter - 1.16. sca_init_request() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides core SCA (Shared Call Appearance) - functionality for OpenSIPS. It is designed to work in tandem - with the presence_callinfo module. - - The module handles the basic SIP signalling for call controll - while publishing callinfo events to a presence server. It is - built on top of the b2b_logic module and it is using the 'top - hiding' scenario to control SIP signalling. - - A typical usage example is provided below, where Alice makes a - call to Bob. The call leg between Alice and the b2b_sca server - is an "appearance" call of the "shared" call between the - b2b_sca server and Bob. - - caller caller b2b_sca callee presence server -alice1@example alice2@example server bob@example watcher@example - | | | | | - |--INV bob------------------>| | | - | | |--INV bob->| | - | | |--PUBLISH(alerting)--->| - | | |<-----200 OK-----------| - | | | | | - | | |<-180 ring-| | - |<-180 ring------------------| | | - | | | | | - | | | | | - | | |<-200 OK---| | - |<-200 OK--------------------|--ACK----->| | - |--ACK---------------------->|--PUBLISH(active)----->| - | | |<-----200 OK-----------| - | | | | | - |--INV bob (hold)----------->| | | - | | |--INV bob->| | - | | |--PUBLISH(held)------->| - | | |<-----200 OK-----------| - | | |<-200 OK---| | - |<--200 OK-------------------| | | - | | | | | - | |--INV------->| | | - | | |--INV bob->| | - |<-BYE-----------------------|--PUBLISH(active)----->| - |--200 OK------------------->|<-----200 OK-----------| - | | |<-200 OK---| | - | |<-200 OK-----| | - - - * Alice calls Bob from her desk IP phone (alice1). - * Bob answers the call. - * Alice decide to carry the conversation from a meeting room - and she put's BOB on hold. - * Alice arrives to the meeting room and retrieves the call on - the conference room IP phone (alice2). - -1.2. To-do - - Features to be added in the future: - * possibility to handle unlimited number of appearances. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tm module. pua module. b2b_logic module. - -1.4. Exported Parameters - -1.4.1. hash_size(integer) - - The size of the hash table internally used to keep the shared - calls. A larger table means faster acces at the expense of - memory. The hash size is a power of number two. - - The default value is "10". - - Example 1.1. Set hash_size parameter -... -modparam("b2b_sca", "hash_size", "5") -... - -1.4.2. presence_server(string) - - The address of the presence server, where the PUBLISH messages - should be sent (not compulsory). If not set, the PUBLISH - requests will be routed based on watcher's URI. - - The default value is "NULL". - - Example 1.2. Set presence_server parameter -... -modparam("b2b_sca", "presence_server", "sip:opensips.org") -... - -1.4.3. watchers_avp_spec(string) - - AVP that will hold one or more watcher URI(s). If not set, no - PUBLISH requests will be sent out. The watchers_avp_spec MUST - be set before calling sca_init_request(); - - The default value is "NULL". - - Example 1.3. Set watchers_avp_spec parameter -... -modparam("b2b_sca", "watchers_avp_spec", "$avp(watchers_avp_spec)") -... -route { - ... - $avp(watchers_avp_spec) = "sip:first_watcher@opensip.org"; - $avp(watchers_avp_spec) = "sip:second_watcher@opensip.org"; - ... -} - -1.4.4. shared_line_spec_param(string) - - Mandatory parameter. Opaque string identifing the shared - line/call. The shared_line_spec_param MUST be set before - calling sca_init_request(); - - The default value is "NULL". - - Example 1.4. Set shared_line_spec_param parameter -... -modparam("b2b_sca", "shared_line_spec_param", "$var(shared_line)") -... - -1.4.5. appearance_name_addr_spec_param(string) - - Mandatory parameter. It must be a valid SIP URI. It will - populate the appearance-uri SIP parameter inside the Call-Info - SIP header. The appearance_name_addr_spec_param MUST be set - before calling sca_init_request(); - - The default value is "NULL". - - Example 1.5. Set appearance_name_addr_spec_param parameter -... -modparam("b2b_sca", "appearance_name_addr_spec_param", "") -... - -1.4.6. db_url(string) - - This is URL of the database to be used. - - The default value is "NULL". - - Example 1.6. Set db_url parameter -... -modparam("b2b_sca", "db_url", "[dbdriver]://[[username]:[password]]@[dbh -ost]/[dbname]") -... - -1.4.7. db_mode(integer) - - The b2b_sca module can utilize database for persistent call - appearance storage. Using a database ensure that active call - appearances will survive machine restarts or SW crashes. The - following databse accessing modes are available for b2b_sca - module: - - * NO DB STORAGE - set this parameter to 0 - * WRITE THROUGH (synchronous write in database) - set this - parameter to 1 - - The default value is 0 (NO DB STORAGE). - - Example 1.7. Set db_mode parameter -... -modparam("b2b_sca", "db_mode", 1) -... - -1.4.8. table_name(string) - - Identifies the table name from the defined database. - - The default value is "b2b_sca". - - Example 1.8. Set table_name parameter -... -modparam("b2b_sca", "table_name", "sla") -... - -1.4.9. shared_line_column(string) - - The column's name in the database storing the shared call/line - id. See "shared_line_spec_param" parameter. - - The default value is "shared_line". - - Example 1.9. Set shared_line_column parameter -... -modparam("b2b_sca", "shared_line_column", "") -... - -1.4.10. watchers_column(string) - - The column's name in the database storing the list of watchers. - See "watchers_avp_spec" parameter. - - The default value is "watchers". - - Example 1.10. Set watchers_column parameter -... -modparam("b2b_sca", "watchers_column", "") -... - -1.4.11. app[index]_shared_entity_column(string) - - The column's name in the database storing the shared entity of - a particular appearance. See "sca_init_request" for more info. - - The default value is "app[index]_shared_entity". Index is an - integer between 1 and 10. - - Example 1.11. Set app[index]_shared_entity_column parameter -... -modparam("b2b_sca", "app1_shared_entity_column", "first_shared_entity") -modparam("b2b_sca", "app2_shared_entity_column", "second_shared_entity") -... - -1.4.12. app[index]_call_state_column(string) - - The column's name in the database storing the call state of a - particular appearance. The following states are stored: - - * 1 - alerting, - * 2 - active, - * 3 - held, - * 4 - held-private. - - The default value is "app[index]_call_state". Index is an - integer between 1 and 10. - - Example 1.12. Set app[index]_call_state_column parameter -... -modparam("b2b_sca", "app1_call_state_column", "first_call_state") -modparam("b2b_sca", "app2_call_state_column", "second_call_state") -... - -1.4.13. app[index]_call_info_uri_column(string) - - The column's name in the database storing the call info URI of - a particular appearance. - - The default value is "app[index]_call_info_uri". Index is an - integer between 1 and 10. - - Example 1.13. Set app[index]_call_info_uri_column parameter -... -modparam("b2b_sca", "app1_call_info_uri_column", "first_call_info_uri") -modparam("b2b_sca", "app2_call_info_uri_column", "second_call_info_uri") -... - -1.4.14. app[index]_call_info_appearance_uri_column(string) - - The column's name in the database storing the call info - appearance URI of a particular appearance. For each appearance, - the value is extracted from the - "appearance_name_addr_spec_param" parameter. - - The default value is "app[index]_call_info_appearance_uri". - Index is an integer between 1 and 10. - - Example 1.14. Set app[index]_call_info_appearance_uri_column - parameter -... -modparam("b2b_sca", "app1_call_info_appearance_uri_column", "first_call_ -info_appearance_uri") -modparam("b2b_sca", "app2_call_info_appearance_uri_column", "second_call -_info_appearance_uri") -... - -1.4.15. appindex_b2bl_key_column(string) - - The column's name in the database storing the b2b_logic key of - a particular appearance. - - The default value is "app[index]_b2bl_key". Index is an integer - between 1 and 10. - - Example 1.15. Set app[index]_b2bl_key_column parameter -... -modparam("b2b_sca", "app1_b2bl_key_column", "first_b2bl_key") -modparam("b2b_sca", "app2_b2bl_key_column", "second_b2bl_key") -... - -1.5. Exported Functions - -1.5.1. sca_init_request(shared_line) - - This is the function that must be called by the script writer - on an initial INVITE for which an SCA call must be instantiated - (see the call from alice1 in the above diagram). - - Meaning of the parameters: - * shared_line (int) - an integer identifying the call leg as - being an "appearnace" call or a "shared" call: - + 0: "shared" call - + 1: "appearance" call - - Example 1.16. sca_init_request() usage -... -modparam("b2b_sca", - "shared_line_spec_param","$var(shared_line)") -modparam("b2b_sca", - "appearance_name_addr_spec_param","$var(appearance_name_addr)") -modparam("b2b_sca", - "watchers_avp_spec","$avp(watchers_avp_spec)") - -... - - # Setting the shared call identifier - $var(shared_line) = "alice"; - - # Setting the watchers - $avp(watchers_avp_spec) = "sip:alice1@example.com"; - $avp(watchers_avp_spec) = "sip:alice2@example.com"; - - if (INCOMING_SHARED_CALL) { - # The incoming call is a 'shared' call - $var(shared_line_entity) = 0; - # Setting the appearance name address - $var(appearance_name_addr) = $fu; - } - else { - # The incoming call is an 'appearance' call - # - see Alice's initial call leg in the given example - $var(shared_line_entity) = 1; - # Setting the appearance name address - $var(appearance_name_addr) = $tu; - } - - # Initiate the call - if (!sca_init_request($var(shared_line_entity))) { - send_reply(403, "Internal Server Error (SLA)"); - exit; - } -... - -1.5.2. sca_bridge_request(shared_line_to bridge) - - This is the function that must be called by the script writer - on an initial "appearance" INVITE for an existing shared call. - It will bridge the current "appearance" call with the existing - "shared" call and the old "appearance" call will be - disconnected (see the call from alice2 in the above diagram). - - Meaning of the parameters: - * shared_line_to_bridge (string) - a string identifying the - shared line/call that was previously set by - sca_init_request(). - -... - if ($rU==NULL && is_method("INVITE") && - $fU==$tU && is_present_hf("Call-Info")) { - # The incoming call is an 'appearance' call - # - see Alice's call from alice2 in the given example - $var(shared_line_to_bridge) = "alice"; - if (!sca_bridge_request($var(shared_line_to_bridge))) - send_reply(403, "Internal SLA Error"); - exit; - } - } -... - -1.6. Exported MI Functions - -1.6.1. sca_list - - It lists the appearances belonging to a shared line/call. - - Name: sca_list - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi sca_list - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 33 2 3536 2 - 2. Liviu Chircu (@liviuchircu) 13 10 63 67 - 3. Razvan Crainea (@razvancrainea) 12 10 32 28 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 9 7 13 13 - 5. Vlad Patrascu (@rvlad-patrascu) 8 5 82 90 - 6. Maksym Sobolyev (@sobomax) 5 3 5 7 - 7. Ezequiel Lovelle (@lovelle) 3 1 1 1 - 8. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - Nov 2022 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Feb 2022 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) May 2014 - Mar 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Ovidiu Sas (@ovidiusas) Dec 2013 - Feb 2016 - 8. Ezequiel Lovelle (@lovelle) Oct 2014 - Oct 2014 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Ovidiu Sas (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2011-2013 VoIP Embedded, Inc. diff --git a/modules/b2b_sca/README.md b/modules/b2b_sca/README.md new file mode 100644 index 00000000000..59ccfe29d22 --- /dev/null +++ b/modules/b2b_sca/README.md @@ -0,0 +1,509 @@ +--- +title: "b2b_sca Module" +description: "This module provides core SCA (Shared Call Appearance) functionality for OpenSIPS. It is designed to work in tandem with the presence_callinfo module." +--- + +## Admin Guide + + +### Overview + + +This module provides core SCA (Shared Call Appearance) functionality +for OpenSIPS. +It is designed to work in tandem with the presence_callinfo module. + + +The module handles the basic SIP signalling for call controll while +publishing callinfo events to a presence server. +It is built on top of the b2b_logic module and it is using the +'top hiding' scenario to control SIP signalling. + + +A typical usage example is provided below, where Alice makes a +call to Bob. The call leg between Alice and the b2b_sca server +is an "appearance" call of the "shared" call between the b2b_sca server +and Bob. + + +```c + caller caller b2b_sca callee presence server +alice1@example alice2@example server bob@example watcher@example + | | | | | + |--INV bob------------------>| | | + | | |--INV bob->| | + | | |--PUBLISH(alerting)--->| + | | |<-----200 OK-----------| + | | | | | + | | |<-180 ring-| | + |<-180 ring------------------| | | + | | | | | + | | | | | + | | |<-200 OK---| | + |<-200 OK--------------------|--ACK----->| | + |--ACK---------------------->|--PUBLISH(active)----->| + | | |<-----200 OK-----------| + | | | | | + |--INV bob (hold)----------->| | | + | | |--INV bob->| | + | | |--PUBLISH(held)------->| + | | |<-----200 OK-----------| + | | |<-200 OK---| | + |<--200 OK-------------------| | | + | | | | | + | |--INV------->| | | + | | |--INV bob->| | + |<-BYE-----------------------|--PUBLISH(active)----->| + |--200 OK------------------->|<-----200 OK-----------| + | | |<-200 OK---| | + | |<-200 OK-----| | + + +``` + + +- Alice calls Bob from her desk IP phone (alice1). +- Bob answers the call. +- Alice decide to carry the conversation from a meeting room +and she put's BOB on hold. +- Alice arrives to the meeting room and retrieves the call on the +conference room IP phone (alice2). + + +### To-do + + +Features to be added in the future: + + +- possibility to handle unlimited number of appearances. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tm* module. +*pua* module. +*b2b_logic* module. + + +### Exported Parameters + + +#### hash_size(integer) + + +The size of the hash table internally used to keep the shared calls. +A larger table means faster acces at the expense of memory. +The hash size is a power of number two. + + +*The default value is "10".* + + +```opensips title="Set hash_size parameter" +... +modparam("b2b_sca", "hash_size", "5") +... +``` + + +#### presence_server(string) + + +The address of the presence server, where the PUBLISH +messages should be sent (not compulsory). +If not set, the PUBLISH requests will be routed based +on watcher's URI. + + +*The default value is "NULL".* + + +```opensips title="Set presence_server parameter" +... +modparam("b2b_sca", "presence_server", "sip:opensips.org") +... +``` + + +#### watchers_avp_spec(string) + + +AVP that will hold one or more watcher URI(s). +If not set, no PUBLISH requests will be sent out. +The watchers_avp_spec MUST be set before calling sca_init_request(); + + +*The default value is "NULL".* + + +```opensips title="Set watchers_avp_spec parameter" +... +modparam("b2b_sca", "watchers_avp_spec", "$avp(watchers_avp_spec)") +... +route { + ... + $avp(watchers_avp_spec) = "sip:first_watcher@opensip.org"; + $avp(watchers_avp_spec) = "sip:second_watcher@opensip.org"; + ... +} +``` + + +#### shared_line_spec_param(string) + + +Mandatory parameter. +Opaque string identifing the shared line/call. +The shared_line_spec_param MUST be set before calling sca_init_request(); + + +*The default value is "NULL".* + + +```opensips title="Set shared_line_spec_param parameter" +... +modparam("b2b_sca", "shared_line_spec_param", "$var(shared_line)") +... +``` + + +#### appearance_name_addr_spec_param(string) + + +Mandatory parameter. +It must be a valid SIP URI. +It will populate the *appearance-uri* SIP parameter +inside the *Call-Info* SIP header. +The appearance_name_addr_spec_param MUST be set before calling sca_init_request(); + + +*The default value is "NULL".* + + +```opensips title="Set appearance_name_addr_spec_param parameter" +... +modparam("b2b_sca", "appearance_name_addr_spec_param", "") +... +``` + + +#### db_url(string) + + +This is URL of the database to be used. + + +*The default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("b2b_sca", "db_url", "[dbdriver]://[[username]:[password]]@[dbhost]/[dbname]") +... +``` + + +#### db_mode(integer) + + +The b2b_sca module can utilize database for persistent call appearance storage. +Using a database ensure that active call appearances will survive +machine restarts or SW crashes. +The following databse accessing modes are available for b2b_sca module: + + +- NO DB STORAGE - set this parameter to 0 +- WRITE THROUGH (synchronous write in database) - set this parameter to 1 + + +*The default value is 0 (NO DB STORAGE).* + + +```opensips title="Set db_mode parameter" +... +modparam("b2b_sca", "db_mode", 1) +... +``` + + +#### table_name(string) + + +Identifies the table name from the defined database. + + +*The default value is "b2b_sca".* + + +```opensips title="Set table_name parameter" +... +modparam("b2b_sca", "table_name", "sla") +... +``` + + +#### shared_line_column(string) + + +The column's name in the database storing the shared call/line id. +See "shared_line_spec_param" parameter. + + +*The default value is "shared_line".* + + +```opensips title="Set shared_line_column parameter" +... +modparam("b2b_sca", "shared_line_column", "") +... +``` + + +#### watchers_column(string) + + +The column's name in the database storing the list of watchers. +See "watchers_avp_spec" parameter. + + +*The default value is "watchers".* + + +```opensips title="Set watchers_column parameter" +... +modparam("b2b_sca", "watchers_column", "") +... +``` + + +#### app[index]_shared_entity_column(string) + + +The column's name in the database storing the shared entity of a +particular appearance. +See "sca_init_request" for more info. + + +*The default value is "app[index]_shared_entity".* +Index is an integer between 1 and 10. + + +```opensips title="Set app[index]_shared_entity_column parameter" +... +modparam("b2b_sca", "app1_shared_entity_column", "first_shared_entity") +modparam("b2b_sca", "app2_shared_entity_column", "second_shared_entity") +... +``` + + +#### app[index]_call_state_column(string) + + +The column's name in the database storing the call state of a +particular appearance. The following states are stored: + + +- 1 - alerting, +- 2 - active, +- 3 - held, +- 4 - held-private. + + +*The default value is "app[index]_call_state".* +Index is an integer between 1 and 10. + + +```opensips title="Set app[index]_call_state_column parameter" +... +modparam("b2b_sca", "app1_call_state_column", "first_call_state") +modparam("b2b_sca", "app2_call_state_column", "second_call_state") +... +``` + + +#### app[index]_call_info_uri_column(string) + + +The column's name in the database storing the call info URI of a +particular appearance. + + +*The default value is "app[index]_call_info_uri".* +Index is an integer between 1 and 10. + + +```opensips title="Set app[index]_call_info_uri_column parameter" +... +modparam("b2b_sca", "app1_call_info_uri_column", "first_call_info_uri") +modparam("b2b_sca", "app2_call_info_uri_column", "second_call_info_uri") +... +``` + + +#### app[index]_call_info_appearance_uri_column(string) + + +The column's name in the database storing the call info appearance URI +of a particular appearance. +For each appearance, the value is extracted from the +"appearance_name_addr_spec_param" parameter. + + +*The default value is "app[index]_call_info_appearance_uri".* +Index is an integer between 1 and 10. + + +```opensips title="Set app[index]_call_info_appearance_uri_column parameter" +... +modparam("b2b_sca", "app1_call_info_appearance_uri_column", "first_call_info_appearance_uri") +modparam("b2b_sca", "app2_call_info_appearance_uri_column", "second_call_info_appearance_uri") +... +``` + + +#### appindex_b2bl_key_column(string) + + +The column's name in the database storing the b2b_logic key of a +particular appearance. + + +*The default value is "app[index]_b2bl_key".* +Index is an integer between 1 and 10. + + +```opensips title="Set app[index]_b2bl_key_column parameter" +... +modparam("b2b_sca", "app1_b2bl_key_column", "first_b2bl_key") +modparam("b2b_sca", "app2_b2bl_key_column", "second_b2bl_key") +... +``` + + +### Exported Functions + + +#### sca_init_request(shared_line) + + +This is the function that must be called by the script writer +on an initial INVITE for which an SCA call must be instantiated +(see the call from alice1 in the above diagram). + + +Meaning of the parameters: + + +- *shared_line* (int) - an integer +identifying the call leg as being an "appearnace" call or a "shared" call: + * 0: "shared" call + * 1: "appearance" call + + +```opensips title="sca_init_request() usage" +... +modparam("b2b_sca", + "shared_line_spec_param","$var(shared_line)") +modparam("b2b_sca", + "appearance_name_addr_spec_param","$var(appearance_name_addr)") +modparam("b2b_sca", + "watchers_avp_spec","$avp(watchers_avp_spec)") + +... + + # Setting the shared call identifier + $var(shared_line) = "alice"; + + # Setting the watchers + $avp(watchers_avp_spec) = "sip:alice1@example.com"; + $avp(watchers_avp_spec) = "sip:alice2@example.com"; + + if (INCOMING_SHARED_CALL) { + # The incoming call is a 'shared' call + $var(shared_line_entity) = 0; + # Setting the appearance name address + $var(appearance_name_addr) = $fu; + } + else { + # The incoming call is an 'appearance' call + # - see Alice's initial call leg in the given example + $var(shared_line_entity) = 1; + # Setting the appearance name address + $var(appearance_name_addr) = $tu; + } + + # Initiate the call + if (!sca_init_request($var(shared_line_entity))) { + send_reply(403, "Internal Server Error (SLA)"); + exit; + } +... +``` + + +#### sca_bridge_request(shared_line_to bridge) + + +This is the function that must be called by the script writer on an initial +"appearance" INVITE for an existing shared call. It will bridge the current +"appearance" call with the existing "shared" call and the old "appearance" +call will be disconnected (see the call from alice2 in the above diagram). + + +Meaning of the parameters: + + +- *shared_line_to_bridge* (string) - a string identifying +the shared line/call that was previously set by sca_init_request(). + + +```opensips +... + if ($rU==NULL && is_method("INVITE") && + $fU==$tU && is_present_hf("Call-Info")) { + # The incoming call is an 'appearance' call + # - see Alice's call from alice2 in the given example + $var(shared_line_to_bridge) = "alice"; + if (!sca_bridge_request($var(shared_line_to_bridge))) + send_reply(403, "Internal SLA Error"); + exit; + } + } +... +``` + + +### Exported MI Functions + + +#### sca_list + + +It lists the appearances belonging to a shared line/call. + + +Name: *sca_list* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi sca_list +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/b2b_sca/doc/b2b_sca.xml b/modules/b2b_sca/doc/b2b_sca.xml deleted file mode 100644 index f570a32cd15..00000000000 --- a/modules/b2b_sca/doc/b2b_sca.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - b2b_sca Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011-2013 VoIP Embedded, Inc. - - - diff --git a/modules/b2b_sca/doc/b2b_sca_admin.xml b/modules/b2b_sca/doc/b2b_sca_admin.xml deleted file mode 100644 index d507ca74779..00000000000 --- a/modules/b2b_sca/doc/b2b_sca_admin.xml +++ /dev/null @@ -1,533 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides core SCA (Shared Call Appearance) functionality - for &osips;. - It is designed to work in tandem with the presence_callinfo module. - - - The module handles the basic SIP signalling for call controll while - publishing callinfo events to a presence server. - It is built on top of the b2b_logic module and it is using the - 'top hiding' scenario to control SIP signalling. - - - A typical usage example is provided below, where Alice makes a - call to Bob. The call leg between Alice and the b2b_sca server - is an "appearance" call of the "shared" call between the b2b_sca server - and Bob. - - -| | | - | | |--INV bob->| | - | | |--PUBLISH(alerting)--->| - | | |<-----200 OK-----------| - | | | | | - | | |<-180 ring-| | - |<-180 ring------------------| | | - | | | | | - | | | | | - | | |<-200 OK---| | - |<-200 OK--------------------|--ACK----->| | - |--ACK---------------------->|--PUBLISH(active)----->| - | | |<-----200 OK-----------| - | | | | | - |--INV bob (hold)----------->| | | - | | |--INV bob->| | - | | |--PUBLISH(held)------->| - | | |<-----200 OK-----------| - | | |<-200 OK---| | - |<--200 OK-------------------| | | - | | | | | - | |--INV------->| | | - | | |--INV bob->| | - |<-BYE-----------------------|--PUBLISH(active)----->| - |--200 OK------------------->|<-----200 OK-----------| - | | |<-200 OK---| | - | |<-200 OK-----| | -]]> - - - - Alice calls Bob from her desk IP phone (alice1). - - - Bob answers the call. - - - Alice decide to carry the conversation from a meeting room - and she put's BOB on hold. - - - Alice arrives to the meeting room and retrieves the call on the - conference room IP phone (alice2). - - -
- -
- To-do - - Features to be added in the future: - - - - possibility to handle unlimited number of appearances. - - -
- -
Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tm module. - pua module. - b2b_logic module. - - - - -
-
- -
Exported Parameters -
- <varname>hash_size</varname>(integer) - - The size of the hash table internally used to keep the shared calls. - A larger table means faster acces at the expense of memory. - The hash size is a power of number two. - - - The default value is "10". - - - Set <varname>hash_size</varname> parameter - -... -modparam("b2b_sca", "hash_size", "5") -... - - -
-
- <varname>presence_server</varname>(string) - - The address of the presence server, where the PUBLISH - messages should be sent (not compulsory). - If not set, the PUBLISH requests will be routed based - on watcher's URI. - - - The default value is "NULL". - - - Set <varname>presence_server</varname> parameter - -... -modparam("b2b_sca", "presence_server", "sip:opensips.org") -... - - -
-
- <varname>watchers_avp_spec</varname>(string) - - AVP that will hold one or more watcher URI(s). - If not set, no PUBLISH requests will be sent out. - The watchers_avp_spec MUST be set before calling sca_init_request(); - - - The default value is "NULL". - - - Set <varname>watchers_avp_spec</varname> parameter - -... -modparam("b2b_sca", "watchers_avp_spec", "$avp(watchers_avp_spec)") -... -route { - ... - $avp(watchers_avp_spec) = "sip:first_watcher@opensip.org"; - $avp(watchers_avp_spec) = "sip:second_watcher@opensip.org"; - ... -} - - -
-
- <varname>shared_line_spec_param</varname>(string) - - Mandatory parameter. - Opaque string identifing the shared line/call. - The shared_line_spec_param MUST be set before calling sca_init_request(); - - - The default value is "NULL". - - - Set <varname>shared_line_spec_param</varname> parameter - -... -modparam("b2b_sca", "shared_line_spec_param", "$var(shared_line)") -... - - -
-
- <varname>appearance_name_addr_spec_param</varname>(string) - - Mandatory parameter. - It must be a valid SIP URI. - It will populate the appearance-uri SIP parameter - inside the Call-Info SIP header. - The appearance_name_addr_spec_param MUST be set before calling sca_init_request(); - - - The default value is "NULL". - - - Set <varname>appearance_name_addr_spec_param</varname> parameter - -... -modparam("b2b_sca", "appearance_name_addr_spec_param", "") -... - - -
-
- <varname>db_url</varname>(string) - - This is URL of the database to be used. - - - The default value is "NULL". - - - Set <varname>db_url</varname> parameter - -... -modparam("b2b_sca", "db_url", "[dbdriver]://[[username]:[password]]@[dbhost]/[dbname]") -... - - -
-
- <varname>db_mode</varname>(integer) - - The b2b_sca module can utilize database for persistent call appearance storage. - Using a database ensure that active call appearances will survive - machine restarts or SW crashes. - The following databse accessing modes are available for b2b_sca module: - - - - NO DB STORAGE - set this parameter to 0 - WRITE THROUGH (synchronous write in database) - set this parameter to 1 - - - - The default value is 0 (NO DB STORAGE). - - - Set <varname>db_mode</varname> parameter - -... -modparam("b2b_sca", "db_mode", 1) -... - - -
-
- <varname>table_name</varname>(string) - - Identifies the table name from the defined database. - - - The default value is "b2b_sca". - - - Set <varname>table_name</varname> parameter - -... -modparam("b2b_sca", "table_name", "sla") -... - - -
-
- <varname>shared_line_column</varname>(string) - - The column's name in the database storing the shared call/line id. - See "shared_line_spec_param" parameter. - - - The default value is "shared_line". - - - Set <varname>shared_line_column</varname> parameter - -... -modparam("b2b_sca", "shared_line_column", "") -... - - -
-
- <varname>watchers_column</varname>(string) - - The column's name in the database storing the list of watchers. - See "watchers_avp_spec" parameter. - - - The default value is "watchers". - - - Set <varname>watchers_column</varname> parameter - -... -modparam("b2b_sca", "watchers_column", "") -... - - -
-
- <varname>app[index]_shared_entity_column</varname>(string) - - The column's name in the database storing the shared entity of a - particular appearance. - See "sca_init_request" for more info. - - - The default value is "app[index]_shared_entity". - Index is an integer between 1 and 10. - - - Set <varname>app[index]_shared_entity_column</varname> parameter - -... -modparam("b2b_sca", "app1_shared_entity_column", "first_shared_entity") -modparam("b2b_sca", "app2_shared_entity_column", "second_shared_entity") -... - - -
-
- <varname>app[index]_call_state_column</varname>(string) - - The column's name in the database storing the call state of a - particular appearance. The following states are stored: - - - - 1 - alerting, - 2 - active, - 3 - held, - 4 - held-private. - - - - The default value is "app[index]_call_state". - Index is an integer between 1 and 10. - - - Set <varname>app[index]_call_state_column</varname> parameter - -... -modparam("b2b_sca", "app1_call_state_column", "first_call_state") -modparam("b2b_sca", "app2_call_state_column", "second_call_state") -... - - -
-
- <varname>app[index]_call_info_uri_column</varname>(string) - - The column's name in the database storing the call info URI of a - particular appearance. - - - The default value is "app[index]_call_info_uri". - Index is an integer between 1 and 10. - - - Set <varname>app[index]_call_info_uri_column</varname> parameter - -... -modparam("b2b_sca", "app1_call_info_uri_column", "first_call_info_uri") -modparam("b2b_sca", "app2_call_info_uri_column", "second_call_info_uri") -... - - -
-
- <varname>app[index]_call_info_appearance_uri_column</varname>(string) - - The column's name in the database storing the call info appearance URI - of a particular appearance. - For each appearance, the value is extracted from the - "appearance_name_addr_spec_param" parameter. - - - The default value is "app[index]_call_info_appearance_uri". - Index is an integer between 1 and 10. - - - Set <varname>app[index]_call_info_appearance_uri_column</varname> parameter - -... -modparam("b2b_sca", "app1_call_info_appearance_uri_column", "first_call_info_appearance_uri") -modparam("b2b_sca", "app2_call_info_appearance_uri_column", "second_call_info_appearance_uri") -... - - -
-
- <varname>appindex_b2bl_key_column</varname>(string) - - The column's name in the database storing the b2b_logic key of a - particular appearance. - - - The default value is "app[index]_b2bl_key". - Index is an integer between 1 and 10. - - - Set <varname>app[index]_b2bl_key_column</varname> parameter - -... -modparam("b2b_sca", "app1_b2bl_key_column", "first_b2bl_key") -modparam("b2b_sca", "app2_b2bl_key_column", "second_b2bl_key") -... - - -
-
- -
Exported Functions -
- - <function moreinfo="none">sca_init_request(shared_line)</function> - - - This is the function that must be called by the script writer - on an initial INVITE for which an SCA call must be instantiated - (see the call from alice1 in the above diagram). - - Meaning of the parameters: - - shared_line (int) - an integer - identifying the call leg as being an "appearnace" call or a "shared" call: - - 0: "shared" call - 1: "appearance" call - - - - - <function>sca_init_request()</function> usage - -... -modparam("b2b_sca", - "shared_line_spec_param","$var(shared_line)") -modparam("b2b_sca", - "appearance_name_addr_spec_param","$var(appearance_name_addr)") -modparam("b2b_sca", - "watchers_avp_spec","$avp(watchers_avp_spec)") - -... - - # Setting the shared call identifier - $var(shared_line) = "alice"; - - # Setting the watchers - $avp(watchers_avp_spec) = "sip:alice1@example.com"; - $avp(watchers_avp_spec) = "sip:alice2@example.com"; - - if (INCOMING_SHARED_CALL) { - # The incoming call is a 'shared' call - $var(shared_line_entity) = 0; - # Setting the appearance name address - $var(appearance_name_addr) = $fu; - } - else { - # The incoming call is an 'appearance' call - # - see Alice's initial call leg in the given example - $var(shared_line_entity) = 1; - # Setting the appearance name address - $var(appearance_name_addr) = $tu; - } - - # Initiate the call - if (!sca_init_request($var(shared_line_entity))) { - send_reply(403, "Internal Server Error (SLA)"); - exit; - } -... - - -
-
- <function moreinfo="none">sca_bridge_request(shared_line_to bridge)</function> - - This is the function that must be called by the script writer on an initial - "appearance" INVITE for an existing shared call. It will bridge the current - "appearance" call with the existing "shared" call and the old "appearance" - call will be disconnected (see the call from alice2 in the above diagram). - - Meaning of the parameters: - - shared_line_to_bridge (string) - a string identifying - the shared line/call that was previously set by sca_init_request(). - - - - -... - if ($rU==NULL && is_method("INVITE") && - $fU==$tU && is_present_hf("Call-Info")) { - # The incoming call is an 'appearance' call - # - see Alice's call from alice2 in the given example - $var(shared_line_to_bridge) = "alice"; - if (!sca_bridge_request($var(shared_line_to_bridge))) - send_reply(403, "Internal SLA Error"); - exit; - } - } -... - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">sca_list</function> - - It lists the appearances belonging to a shared line/call. - - Name: sca_list - Parameters: none - MI FIFO Command Format: - - opensips-cli -x mi sca_list - -
-
-
- diff --git a/modules/b2b_sca/doc/contributors.xml b/modules/b2b_sca/doc/contributors.xml deleted file mode 100644 index 821a80d91ed..00000000000 --- a/modules/b2b_sca/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 33 - 2 - 3536 - 2 - - - 2. - Liviu Chircu (@liviuchircu) - 13 - 10 - 63 - 67 - - - 3. - Razvan Crainea (@razvancrainea) - 12 - 10 - 32 - 28 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 7 - 13 - 13 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 8 - 5 - 82 - 90 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 5 - 7 - - - 7. - Ezequiel Lovelle (@lovelle) - 3 - 1 - 1 - 1 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - Nov 2022 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Feb 2022 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2014 - Mar 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Ovidiu Sas (@ovidiusas) - Dec 2013 - Feb 2016 - - - 8. - Ezequiel Lovelle (@lovelle) - Oct 2014 - Oct 2014 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/b2b_sca/sca_logic.c b/modules/b2b_sca/sca_logic.c index 2261e6835e8..18cb7b0ec52 100644 --- a/modules/b2b_sca/sca_logic.c +++ b/modules/b2b_sca/sca_logic.c @@ -315,7 +315,7 @@ int build_appearanceURI(str *display, str *uri, str *call_info_apperance_uri) char *p; char escaped_display[256]; - size = display->len + 5 + uri->len + 2; + size = 2 * display->len + 1 + uri->len + 2; if (size > CALL_INFO_APPEARANCE_URI_LEN) { LM_WARN("buffer overflow on appearance URI param: size [%d]\n", size); p = (char *)pkg_malloc(size); diff --git a/modules/b2b_sdp_demux/README b/modules/b2b_sdp_demux/README deleted file mode 100644 index 772904a4707..00000000000 --- a/modules/b2b_sdp_demux/README +++ /dev/null @@ -1,209 +0,0 @@ -B2B SDP De-Multiplexer Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Use Cases - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. client_bye_mode (string) - - 1.5. Exported Functions - - 1.5.1. b2b_sdp_demux(URI[, [headers][, streams]]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set client_bye_mode parameter - 1.2. Use b2b_sdp_demux() to handle an audio SIPREC call - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides the logic to convert a multi-stream SDP - call, to multiple calls, each containing a subset of streams - from the initial call. The module only handles the SIP - signalling part of the call, without interfering with the media - of the call, which will flow end-to-end. The only manipulation - it does is at the SDP level to disable the media-streams that - are not being used downstream. - - The logic is implemented on top of the B2B module, and - de-multiplexes a B2B server (the initial call with multiple - streams) to multiple B2B clients (with their own streams - subset). In-dialog requests that come from the initial caller - will be forked towards each client, and their replies - aggregated back to the caller. The other side in-dialog - requests are forwarded to the caller as if only their stream - had changed. When a call is terminated from the client side, - the module can have different behaviors, according to the - client_bye_mode parameter. - -1.2. Use Cases - - A common scenario where this module can become useful is when - configuring OpenSIPS as a SIPREC SRS proxy. Using this module - you can receive on one side SIPREC INVITEs, which usually have - two or more SDP streams (one for each call/conference - participants), and split/de-multiplex each stream in a new call - downstream, usually towards a media server that is able to do - call recording. This way the media server will have to handle - calls that contain a single media stream. - - Another use case is balancing multiple streams to different - media servers. For example, if you are offering both audio and - video services, you can split a two-stream call (with an audio - and video stream) to two different calls, and send them to be - processed by different servers. This way you may have separated - audio-dedicated processing media servers, as well as - video-dedicated one. Of course, this can be achieved if you can - process the streams separately, for example for recording. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * B2B_ENTITIES - Back-2-Back module used for handing server - and client side calls. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. client_bye_mode (string) - - This parameter indicates how a BYE coming from the client side - should be treated in the context of the upstream call. - - Possible values are: - * disable - when a client terminates its call, the module - will simply disable the media streams associated with its - call, resulting in a re-INVITE upstream. - * terminate - when one client terminates its call, the module - will terminate all other calls, including the upstream one. - * disable-terminate - same as disable, except that when the - final stream is disabled, instead of a re-INVITE with all - streams disabled, the module sends a BYE upstream. - - Default value is “disable”. - - Example 1.1. Set client_bye_mode parameter -... -modparam("b2b_sdp_demux", "client_bye_mode", "terminate") -... - -1.5. Exported Functions - -1.5.1. b2b_sdp_demux(URI[, [headers][, streams]]) - - Engages the B2B SDP De-Multiplexing scenario for the calls it - has been triggered on. - - Parameters: - * URI (string) - the URI where to send the newly generated - calls - * headers (AVP, optional) - an AVP containing multiple - values, each index corresponding to one of the new calls - generated by the function. The number of values in the AVP - should be equal to the number of calls resulted, otherwise - it may lead to an unexpected behavior. If missing, no extra - headers will be added. - * streams (AVP, optional) - an AVP containing multiple - values, each value indicating the media stream index that - should be used for the current client. If multiple streams - should be used for a single call, they should be specified - comma-separated (i.e. 0,2). The number of AVP values - represent the number of calls generated downstream. If the - parameter is missing, a call will be generated for each - stream present in the initial call. - - This function can be used only from request route. - - Example 1.2. Use b2b_sdp_demux() to handle an audio SIPREC call -... -if (!has_totag() && is_method("INVITE")) { - $avp(headers) = "X-Leg: caller\r\n"); - $avp(headers) = "X-Leg: callee\r\n"); - b2b_sdp_demux("sip:media@localhost", $avp(headers)); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 93 59 2949 500 - 2. Maksym Sobolyev (@sobomax) 4 2 5 5 - 3. Alexandra Titoc 4 2 3 2 - 4. Norman Brandinger (@NormB) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2021 - Aug 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Norman Brandinger (@NormB) Jun 2024 - Jun 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2021-2022 Five9 Inc. diff --git a/modules/b2b_sdp_demux/README.md b/modules/b2b_sdp_demux/README.md new file mode 100644 index 00000000000..98e53ab2183 --- /dev/null +++ b/modules/b2b_sdp_demux/README.md @@ -0,0 +1,174 @@ +--- +title: "B2B SDP De-Multiplexer Module" +description: "This module provides the logic to convert a multi-stream SDP call, to multiple calls, each containing a subset of streams from the initial call." +--- + +## Admin Guide + + +### Overview + + +This module provides the logic to convert a multi-stream +SDP call, to multiple calls, each containing a subset of +streams from the initial call. The module only handles the +SIP signalling part of the call, without interfering with +the media of the call, which will flow end-to-end. The only +manipulation it does is at the SDP level to disable the +media-streams that are not being used downstream. + + +The logic is implemented on top of the B2B module, and +de-multiplexes a B2B server (the initial call with +multiple streams) to multiple B2B clients (with their own +streams subset). In-dialog requests that come from the +initial caller will be forked towards each client, and their +replies aggregated back to the caller. The other side +in-dialog requests are forwarded to the caller as if only +their stream had changed. When a call is terminated from +the client side, the module can have different behaviors, +according to the [client bye mode](#param_client_bye_mode) +parameter. + + +### Use Cases + + +A common scenario where this module can become useful is +when configuring OpenSIPS as a SIPREC SRS proxy. Using this +module you can receive on one side SIPREC INVITEs, which +usually have two or more SDP streams (one for each +call/conference participants), and split/de-multiplex each +stream in a new call downstream, usually towards a media +server that is able to do call recording. This way the +media server will have to handle calls that contain a +single media stream. + + +Another use case is balancing multiple streams to different +media servers. For example, if you are offering both audio +and video services, you can split a two-stream call (with +an audio and video stream) to two different calls, and send +them to be processed by different servers. This way you may +have separated audio-dedicated processing media servers, as +well as video-dedicated one. Of course, this can be achieved +if you can process the streams separately, for example for +recording. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *B2B_ENTITIES* - Back-2-Back module +used for handing server and client side calls. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### client_bye_mode (string) + + +This parameter indicates how a BYE coming from the +client side should be treated in the context of the +upstream call. + + +Possible values are: + +- *disable* - when a client +terminates its call, the module will simply disable +the media streams associated with its call, resulting +in a re-INVITE upstream. + + +- *terminate* - when one client +terminates its call, the module will terminate +all other calls, including the upstream one. + + +- *disable-terminate* - same as +disable, except that when the final stream is disabled, +instead of a re-INVITE with all streams disabled, +the module sends a BYE upstream. + +*Default value is "disable".* + + +```opensips title="Set client_bye_mode parameter" +... +modparam("b2b_sdp_demux", "client_bye_mode", "terminate") +... +``` + + +### Exported Functions + + +#### b2b_sdp_demux(URI[, [headers][, streams]]) + + +Engages the B2B SDP De-Multiplexing scenario for the +calls it has been triggered on. + + +Parameters: + + +- *URI* (string) - the URI where +to send the newly generated calls +- *headers* (AVP, optional) - an +AVP containing multiple values, each index +corresponding to one of the new calls generated +by the function. The number of values in the +AVP should be equal to the number of calls +resulted, otherwise it may lead to an unexpected +behavior. If missing, no extra headers will be +added. +- *streams* (AVP, optional) - an +AVP containing multiple values, each value +indicating the media stream index that should be +used for the current client. If multiple streams +should be used for a single call, they should +be specified comma-separated (i.e. +*0,2*). The number of AVP +values represent the number of calls generated +downstream. If the parameter is missing, +a call will be generated for each stream present in +the initial call. + + +This function can be used only from request route. + + +```opensips title="Use b2b_sdp_demux() to handle an audio SIPREC call" +... +if (!has_totag() && is_method("INVITE")) { + $avp(headers) = "X-Leg: caller\r\n"); + $avp(headers) = "X-Leg: callee\r\n"); + b2b_sdp_demux("sip:media@localhost", $avp(headers)); +} +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/b2b_sdp_demux/b2b_sdp_demux.c b/modules/b2b_sdp_demux/b2b_sdp_demux.c index 1aa4c7f5c9c..d5a994da5b2 100644 --- a/modules/b2b_sdp_demux/b2b_sdp_demux.c +++ b/modules/b2b_sdp_demux/b2b_sdp_demux.c @@ -234,12 +234,38 @@ struct b2b_sdp_ctx { time_t sess_id; str sess_ip; gen_lock_t lock; + unsigned int ref; b2b_dlginfo_t *dlginfo; struct list_head clients; struct list_head streams; struct list_head contexts; }; +static void b2b_sdp_ctx_ref(struct b2b_sdp_ctx *ctx) +{ + lock_get(&ctx->lock); + ctx->ref++; + lock_release(&ctx->lock); +} + +static void b2b_sdp_ctx_unref(struct b2b_sdp_ctx *ctx) +{ + int free_ctx; + + lock_get(&ctx->lock); + free_ctx = (--ctx->ref == 0); + lock_release(&ctx->lock); + if (!free_ctx) + return; + + if (ctx->b2b_key.s) + shm_free(ctx->b2b_key.s); + if (ctx->dlginfo) + shm_free(ctx->dlginfo); + shm_free(ctx->sess_ip.s); + shm_free(ctx); +} + static str *b2b_sdp_label_from_sdp(sdp_stream_cell_t *stream) @@ -389,6 +415,7 @@ static struct b2b_sdp_client *b2b_sdp_client_new(struct b2b_sdp_ctx *ctx) memset(client, 0, sizeof *client); INIT_LIST_HEAD(&client->streams); client->ctx = ctx; + b2b_sdp_ctx_ref(ctx); list_add_tail(&client->list, &ctx->clients); ctx->clients_no++; return client; @@ -441,6 +468,7 @@ static void b2b_sdp_client_terminate(struct b2b_sdp_client *client, str *key, in static void b2b_sdp_client_free(void *param) { struct list_head *it, *safe; + struct b2b_sdp_ctx *ctx; struct b2b_sdp_client *client = param; @@ -460,7 +488,9 @@ static void b2b_sdp_client_free(void *param) b2b_sdp_stream_free(list_entry(it, struct b2b_sdp_stream, list)); if (client->dlginfo) shm_free(client->dlginfo); + ctx = client->ctx; shm_free(client); + b2b_sdp_ctx_unref(ctx); } static int b2b_sdp_client_release(struct b2b_sdp_client *client, int lock) @@ -495,6 +525,7 @@ static struct b2b_sdp_ctx *b2b_sdp_ctx_new(str *callid) INIT_LIST_HEAD(&ctx->clients); INIT_LIST_HEAD(&ctx->streams); lock_init(&ctx->lock); + ctx->ref = 1; /* server entity ownership */ time(&ctx->sess_id); ctx->callid.len = callid->len; ctx->callid.s = (char *)(ctx + 1); @@ -546,15 +577,38 @@ static struct b2b_sdp_client *b2b_sdp_client_get(struct b2b_sdp_ctx *ctx, str *k static void b2b_sdp_ctx_release(struct b2b_sdp_ctx *ctx, int replicate) { struct list_head *it, *safe; + struct b2b_sdp_client *client; - list_for_each_safe(it, safe, &ctx->clients) - b2b_sdp_client_delete(list_entry(it, struct b2b_sdp_client, list)); - /* free remaining streams */ - list_for_each_safe(it, safe, &ctx->streams) - b2b_sdp_stream_free(list_entry(it, struct b2b_sdp_stream, ordered)); + /* Make the release idempotent: only the caller that removes the context + * from the global list proceeds, the rest bail out. This prevents a + * concurrent/double release (e.g. a BYE arriving from both the upstream + * server and a downstream client) from corrupting the contexts list and + * deleting the server entity twice. */ lock_start_write(b2b_sdp_contexts_lock); + if (!list_is_valid(&ctx->contexts)) { + lock_stop_write(b2b_sdp_contexts_lock); + return; + } list_del(&ctx->contexts); lock_stop_write(b2b_sdp_contexts_lock); + + /* Drain the clients while holding the lock: list_del() poisons each entry + * before we drop the lock, so a concurrent b2b_sdp_client_bye() sees its + * client already removed (release returns 0) and bails out instead of + * deleting the same client entity twice. */ + lock_get(&ctx->lock); + while (!list_empty(&ctx->clients)) { + client = list_entry(ctx->clients.next, struct b2b_sdp_client, list); + list_del(&client->list); + ctx->clients_no--; + lock_release(&ctx->lock); + b2b_sdp_client_terminate(client, &client->b2b_key, 1); + lock_get(&ctx->lock); + } + lock_release(&ctx->lock); + /* free remaining streams */ + list_for_each_safe(it, safe, &ctx->streams) + b2b_sdp_stream_free(list_entry(it, struct b2b_sdp_stream, ordered)); if (ctx->b2b_key.s) b2b_api.entity_delete(B2B_SERVER, &ctx->b2b_key, ctx->dlginfo, 1, replicate); } @@ -564,12 +618,7 @@ static void b2b_sdp_ctx_free(void *param) struct b2b_sdp_ctx *ctx = param; if (!ctx) return; - if (ctx->b2b_key.s) - shm_free(ctx->b2b_key.s); - if (ctx->dlginfo) - shm_free(ctx->dlginfo); - shm_free(ctx->sess_ip.s); - shm_free(ctx); + b2b_sdp_ctx_unref(ctx); } static int b2b_sdp_streams_from_sdp(struct b2b_sdp_ctx *ctx, @@ -953,7 +1002,6 @@ static void b2b_sdp_client_destroy(struct b2b_sdp_client *client) { b2b_sdp_client_release_streams(client); b2b_sdp_client_release(client, 0); - b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, client->dlginfo, 1, 1); } @@ -972,6 +1020,25 @@ static void b2b_sdp_client_remove(struct b2b_sdp_client *client) lock_release(&ctx->lock); } +static int b2b_sdp_client_remove_release(struct b2b_sdp_client *client) +{ + struct b2b_sdp_ctx *ctx = client->ctx; + + lock_get(&ctx->lock); + if (!list_is_valid(&client->list)) { + lock_release(&ctx->lock); + return 0; + } + if (client->flags & B2B_SDP_CLIENT_STARTED) { + client->flags &= ~(B2B_SDP_CLIENT_EARLY|B2B_SDP_CLIENT_STARTED); + b2b_sdp_client_release_streams(client); + } + list_del(&client->list); + ctx->clients_no--; + lock_release(&ctx->lock); + return 1; +} + static void b2b_sdp_server_send_bye(struct b2b_sdp_ctx *ctx) { str method; @@ -996,10 +1063,12 @@ static int b2b_sdp_client_bye(struct sip_msg *msg, struct b2b_sdp_client *client str method; b2b_req_data_t req_data; struct b2b_sdp_ctx *ctx = client->ctx; + int del; - b2b_sdp_client_remove(client); b2b_sdp_reply(&client->b2b_key, client->dlginfo, B2B_CLIENT, METHOD_BYE, 200, NULL); - b2b_sdp_client_release(client, 1); + del = b2b_sdp_client_remove_release(client); + if (!del) + return 0; b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, client->dlginfo, 1, 1); lock_get(&ctx->lock); @@ -1221,6 +1290,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien { str *body = NULL; int ret = -1; + int destroy_client = 0; struct b2b_sdp_ctx *ctx; /* only ACK if not fake reply, or not a dummy message as @@ -1249,6 +1319,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien if (!(client->flags & B2B_SDP_CLIENT_CANCEL)) b2b_sdp_client_end(client, &client->b2b_key, 0); b2b_sdp_client_destroy(client); + destroy_client = 1; goto release; } body = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP); @@ -1262,6 +1333,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien if (!(client->flags & B2B_SDP_CLIENT_STARTED)) { /* client was not started, thus this is a final negative reply */ b2b_sdp_client_destroy(client); + destroy_client = 1; } } body = NULL; @@ -1293,6 +1365,8 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien } else if (ret == -2) { b2b_sdp_reply(&ctx->b2b_key, ctx->dlginfo, B2B_SERVER, METHOD_INVITE, 503, NULL); } + if (destroy_client) + b2b_api.entity_delete(B2B_CLIENT, &client->b2b_key, client->dlginfo, 1, 1); if (ret < 0 && ctx->clients_no == 0) { /* no more remaining clients - terminate the entity as well */ b2b_sdp_ctx_release(ctx, 1); diff --git a/modules/b2b_sdp_demux/doc/b2b_sdp_demux.xml b/modules/b2b_sdp_demux/doc/b2b_sdp_demux.xml deleted file mode 100644 index 31cb851384c..00000000000 --- a/modules/b2b_sdp_demux/doc/b2b_sdp_demux.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - B2B SDP De-Multiplexer Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2021-2022 Five9 Inc. - diff --git a/modules/b2b_sdp_demux/doc/b2b_sdp_demux_admin.xml b/modules/b2b_sdp_demux/doc/b2b_sdp_demux_admin.xml deleted file mode 100644 index 434ab043f8e..00000000000 --- a/modules/b2b_sdp_demux/doc/b2b_sdp_demux_admin.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides the logic to convert a multi-stream - SDP call, to multiple calls, each containing a subset of - streams from the initial call. The module only handles the - SIP signalling part of the call, without interfering with - the media of the call, which will flow end-to-end. The only - manipulation it does is at the SDP level to disable the - media-streams that are not being used downstream. - - - The logic is implemented on top of the B2B module, and - de-multiplexes a B2B server (the initial call with - multiple streams) to multiple B2B clients (with their own - streams subset). In-dialog requests that come from the - initial caller will be forked towards each client, and their - replies aggregated back to the caller. The other side - in-dialog requests are forwarded to the caller as if only - their stream had changed. When a call is terminated from - the client side, the module can have different behaviors, - according to the - parameter. - -
-
- Use Cases - - A common scenario where this module can become useful is - when configuring &osips; as a SIPREC SRS proxy. Using this - module you can receive on one side SIPREC INVITEs, which - usually have two or more SDP streams (one for each - call/conference participants), and split/de-multiplex each - stream in a new call downstream, usually towards a media - server that is able to do call recording. This way the - media server will have to handle calls that contain a - single media stream. - - - Another use case is balancing multiple streams to different - media servers. For example, if you are offering both audio - and video services, you can split a two-stream call (with - an audio and video stream) to two different calls, and send - them to be processed by different servers. This way you may - have separated audio-dedicated processing media servers, as - well as video-dedicated one. Of course, this can be achieved - if you can process the streams separately, for example for - recording. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - B2B_ENTITIES - Back-2-Back module - used for handing server and client side calls. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>client_bye_mode</varname> (string) - - This parameter indicates how a BYE coming from the - client side should be treated in the context of the - upstream call. - - - - Possible values are: - - - - disable - when a client - terminates its call, the module will simply disable - the media streams associated with its call, resulting - in a re-INVITE upstream. - - - - - terminate - when one client - terminates its call, the module will terminate - all other calls, including the upstream one. - - - - - disable-terminate - same as - disable, except that when the final stream is disabled, - instead of a re-INVITE with all streams disabled, - the module sends a BYE upstream. - - - - - - Default value is disable. - - - - Set <varname>client_bye_mode</varname> parameter - -... -modparam("b2b_sdp_demux", "client_bye_mode", "terminate") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">b2b_sdp_demux(URI[, [headers][, streams]])</function> - - - Engages the B2B SDP De-Multiplexing scenario for the - calls it has been triggered on. - - - Parameters: - - - URI (string) - the URI where - to send the newly generated calls - - - headers (AVP, optional) - an - AVP containing multiple values, each index - corresponding to one of the new calls generated - by the function. The number of values in the - AVP should be equal to the number of calls - resulted, otherwise it may lead to an unexpected - behavior. If missing, no extra headers will be - added. - - - streams (AVP, optional) - an - AVP containing multiple values, each value - indicating the media stream index that should be - used for the current client. If multiple streams - should be used for a single call, they should - be specified comma-separated (i.e. - 0,2). The number of AVP - values represent the number of calls generated - downstream. If the parameter is missing, - a call will be generated for each stream present in - the initial call. - - - - - This function can be used only from request route. - - - Use <function>b2b_sdp_demux()</function> to - handle an audio SIPREC call - -... -if (!has_totag() && is_method("INVITE")) { - $avp(headers) = "X-Leg: caller\r\n"); - $avp(headers) = "X-Leg: callee\r\n"); - b2b_sdp_demux("sip:media@localhost", $avp(headers)); -} -... - - -
-
- -
diff --git a/modules/b2b_sdp_demux/doc/contributors.xml b/modules/b2b_sdp_demux/doc/contributors.xml deleted file mode 100644 index 235712756ec..00000000000 --- a/modules/b2b_sdp_demux/doc/contributors.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 93 - 59 - 2949 - 500 - - - 2. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - 3. - Alexandra Titoc - 4 - 2 - 3 - 2 - - - 4. - Norman Brandinger (@NormB) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2021 - Aug 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Norman Brandinger (@NormB) - Jun 2024 - Jun 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/benchmark/README b/modules/benchmark/README deleted file mode 100644 index b4cd7c880cb..00000000000 --- a/modules/benchmark/README +++ /dev/null @@ -1,436 +0,0 @@ -Benchmark Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. enable (int) - 1.3.2. granularity (int) - 1.3.3. loglevel (int) - - 1.4. Exported Functions - - 1.4.1. bm_start_timer(name) - 1.4.2. bm_log_timer(name) - - 1.5. Exported Pseudo-Variables - - 1.5.1. $BM_time_diff - - 1.6. Exported MI Functions - - 1.6.1. bm_enable_global - 1.6.2. bm_enable_timer - 1.6.3. bm_granularity - 1.6.4. bm_loglevel - 1.6.5. bm_poll_results - - 1.7. Example of usage - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. bm_register(name, mode, id) - 2.1.2. bm_start(id) - 2.1.3. bm_log(id) - - 2.2. Benchmark API Example - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set enable parameter - 1.2. Set granularity parameter - 1.3. Set loglevel parameter - 1.4. bm_start_timer usage - 1.5. bm_log_timer usage - 1.6. Enabling a timer - 1.7. Getting the results via FIFO interface - 1.8. benchmark usage - 2.1. Using the benchmark module's API from another module - -Chapter 1. Admin Guide - -1.1. Overview - - This module helps developers to benchmark their module - functions. By adding this module's functions via the - configuration file or through its API, OpenSIPS can log - profiling information for every function. - - The duration between calls to start_timer and log_timer is - stored and logged via OpenSIPS's logging facility. Please note - that all durations are given as microseconds (don't confuse - with milliseconds!). - - Important note: as this benchmarking is intended to measure the - time spent in executing different parts/blocks of the script - (and not for measuring the time induced by the SIP signaling), - the benchmark module is to be used within the SAME top route - (request route, failure route, branch route, onreply rout, - etc). It is not design to be used across different types of top - routes (like started in request route and ended in failure - route)!! - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. enable (int) - - Even when the module is loaded, benchmarking is not enabled per - default. This variable may have three different values: - * -1 - Globally disable benchmarking - * 0 - Enable per-timer enabling. Single timers are inactive - by default and can be activated through the MI interface as - soon as that feature is implemented. - * 1 - Globally enable benchmarking - - Default value is “0”. - - Example 1.1. Set enable parameter -... -modparam("benchmark", "enable", 1) -... - -1.3.2. granularity (int) - - Logging normally is not done for every reference to the - log_timer() function, but only every n'th call. n is defined - through this variable. A sensible granularity seems to be 100. - - If granularity is set to 0, then nothing will be logged - automatically. Instead bm_poll_results MI command can be used - to retrieve the results and clean the local values. - - Default value is “100”. - - Example 1.2. Set granularity parameter -... -modparam("benchmark", "granularity", 500) -... - -1.3.3. loglevel (int) - - Set the log level for the benchmark logs. These levels should - be used: - * -3 - L_ALERT - * -2 - L_CRIT - * -1 - L_ERR - * 1 - L_WARN - * 2 - L_NOTICE - * 3 - L_INFO - * 4 - L_DBG - - Default value is “3” (L_INFO). - - Example 1.3. Set loglevel parameter -... -modparam("benchmark", "loglevel", 4) -... - - This will set the logging level to L_DBG. - -1.4. Exported Functions - -1.4.1. bm_start_timer(name) - - Start timer “name”. A later call to “bm_log_timer()” logs this - timer.. - - Example 1.4. bm_start_timer usage -... -bm_start_timer("test"); -... - -1.4.2. bm_log_timer(name) - - This function logs the timer with the given ID. The following - data are logged: - * Last msgs is the number of calls in the last logging - interval. This equals the granularity variable. - - * Last sum is the accumulated duration in the current logging - interval (i.e. for the last “granularity” calls). - - * Last min is the minimum duration between start/log_timer - calls during the last interval. - - * Last max - maximum duration. - - * Last average is the average duration between - bm_start_timer() and bm_log_timer() since the last logging. - - * Global msgs number of calls to log_timer. - - * Global sum total duration in microseconds. - - * Global min... You get the point. :) - - * Global max also obvious. - - * Global avg possibly the most interesting value. - - Example 1.5. bm_log_timer usage -... -bm_log_timer("test"); -... - -1.5. Exported Pseudo-Variables - - Exported pseudo-variables are listed in the next sections. - -1.5.1. $BM_time_diff - - $BM_time_diff - the time difference elapsed between calls of - bm_start_timer(name) and bm_log_timer(name). The value is 0 if - no bm_log_timer() was called. - -1.6. Exported MI Functions - -1.6.1. bm_enable_global - - Enables/disables the module. - - Parameters: - * enable - value may be -1, 0 or 1. See discription of - "enable" parameter. - - MI FIFO Command Format: - opensips-cli -x mi bm_enable_global 1 - -1.6.2. bm_enable_timer - - Enable or disable a single timer. - - Parameters: - * timer - timer name - * enable - enable (1) or disable (0) timer - - MI FIFO Command Format: - - Example 1.6. Enabling a timer -... -opensips-cli -x mi bm_enable_timer test 1 -... - -1.6.3. bm_granularity - - Modifies the benchmarking granularity. - - Parameters: - * granularity - See discription of "granularity" parameter. - - MI FIFO Command Format: - opensips-cli -x mi bm_granularity 300 - -1.6.4. bm_loglevel - - Modifies the module log level. - - Parameters: - * log_level - See discription of "loglevel" parameter. - - MI FIFO Command Format: - opensips-cli -x mi bm_loglevel 4 - -1.6.5. bm_poll_results - - Returns the current and global results for each timer. This - command is only available if the "granularity" variable is set - to 0. It can be used to get results in stable time intervals - instead of every N messages. Each timer will have 2 nodes - the - local and the global values. Format of the values is the same - as the one normally used in logfile. This way of getting the - results allows to interface with external graphing applications - like Munin. - - If there were no new calls to bm_log_timer since last check, - then all current values of a timer will be equal 0. Each call - to bm_poll_results will reset current values (but not global - ones). - - Example 1.7. Getting the results via FIFO interface -... -opensips-cli -x mi bm_poll_results -register_timer - 3/40/12/14/13.333333 - 9/204/12/97/22.666667 -security_check_timer - 3/21/7/7/7.000000 - 9/98/7/41/10.888889 -... - -1.7. Example of usage - - Measure the duration of user location lookup. - - Example 1.8. benchmark usage -... -bm_start_timer("usrloc-lookup"); -lookup("location"); -bm_log_timer("usrloc-lookup"); -... - -Chapter 2. Developer Guide - - The benchmark module provides an internal API to be used by - other OpenSIPS modules. The available functions are identical - to the user exported functions. - - Please note that this module is intended mainly for developers. - It should be used with caution in production environments. - -2.1. Available Functions - -2.1.1. bm_register(name, mode, id) - - This function register a new timer and/or returns the internal - ID associated with the timer. mode controls the creation of new - timer if not found. id is to be used by start and log timer - functions. - -2.1.2. bm_start(id) - - This function equals the user-exported function bm_start_timer. - The id is passed as an integer, though. - -2.1.3. bm_log(id) - - This function equals the user-exported function bm_log_timer. - The id is passed as an integer, though. - -2.2. Benchmark API Example - - Example 2.1. Using the benchmark module's API from another - module -... -#include "../benchmark/benchmark.h" -... -struct bm_binds bmb; -... -... -/* load the benchmarking API */ -if (load_bm_api( &bmb )!=0) { - LM_ERR("can't load benchmark API\n"); - goto error; -} -... -... -/* Start/log timers during a (usually user-exported) module function */ -bmb.bm_register("test", 1, &id) -bmb.bm_start(id); -do_something(); -bmb.bm_log(id); -... - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 23 10 1391 50 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 21 19 88 53 - 3. Liviu Chircu (@liviuchircu) 14 11 28 61 - 4. Razvan Crainea (@razvancrainea) 11 9 23 21 - 5. Vlad Patrascu (@rvlad-patrascu) 9 4 185 143 - 6. Stanislaw Pitucha 7 3 170 65 - 7. Henning Westerholt (@henningw) 6 4 11 10 - 8. Maksym Sobolyev (@sobomax) 5 3 5 6 - 9. David Sanders 4 2 8 1 - 10. Anca Vamanu 3 1 5 2 - - All remaining contributors: Konstantin Bokarius, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Apr 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. David Sanders Aug 2012 - Jan 2013 - 8. Anca Vamanu Sep 2009 - Sep 2009 - 9. Stanislaw Pitucha Aug 2009 - Sep 2009 - 10. Daniel-Constantin Mierla (@miconda) Jul 2007 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), - Stanislaw Pitucha, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw). - - Documentation Copyrights: - - Copyright © 2007 Collax GmbH - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/benchmark/README.md b/modules/benchmark/README.md new file mode 100644 index 00000000000..ed2651368a0 --- /dev/null +++ b/modules/benchmark/README.md @@ -0,0 +1,400 @@ +--- +title: "Benchmark Module" +description: "This module helps developers to benchmark their module functions. By adding this module's functions via the configuration file or through its API, OpenSIPS can log profiling information for every function." +--- + +## Admin Guide + + +### Overview + + +This module helps developers to benchmark their module functions. By adding +this module's functions via the configuration file or through its API, OpenSIPS +can log profiling information for every function. + + +The duration between calls to start_timer and log_timer is stored and logged +via OpenSIPS's logging facility. Please note that all durations are given as +microseconds (don't confuse with milliseconds!). + + +Important note: as this benchmarking is intended to measure the time +spent in executing different parts/blocks of the script (and not for +measuring the time induced by the SIP signaling), the benchmark module +is to be used within the SAME top route (request route, failure route, +branch route, onreply rout, etc). It is not design to be used across +different types of top routes (like started in request route and ended in +failure route)! + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### enable (int) + + +Even when the module is loaded, benchmarking is not enabled +per default. This variable may have three different values: + + +- -1 - Globally disable benchmarking +- 0 - Enable per-timer enabling. Single timers are inactive by default +and can be activated through the MI interface as soon as that feature is +implemented. +- 1 - Globally enable benchmarking + + +*Default value is "0".* + + +```opensips title="Set enable parameter" +... +modparam("benchmark", "enable", 1) +... +``` + + +#### granularity (int) + + +Logging normally is not done for every reference to the log_timer() +function, but only every n'th call. n is defined through this variable. +A sensible granularity seems to be 100. + + +If granularity is set to 0, then nothing will be logged automatically. Instead bm_poll_results MI command can be used to retrieve the results and clean the local values. + + +*Default value is "100".* + + +```opensips title="Set granularity parameter" +... +modparam("benchmark", "granularity", 500) +... +``` + + +#### loglevel (int) + + +Set the log level for the benchmark logs. These levels should be used: + + +- -3 - *L_ALERT* +- -2 - *L_CRIT* +- -1 - *L_ERR* +- 1 - *L_WARN* +- 2 - *L_NOTICE* +- 3 - *L_INFO* +- 4 - *L_DBG* + + +*Default value is "3" (L_INFO).* + + +```opensips title="Set loglevel parameter" +... +modparam("benchmark", "loglevel", 4) +... +``` + + +This will set the logging level to L_DBG. + + +### Exported Functions + + +#### bm_start_timer(name) + + +Start timer "name". A later call to +"bm_log_timer()" logs this timer.. + + +```opensips title="bm_start_timer usage" +... +bm_start_timer("test"); +... +``` + + +#### bm_log_timer(name) + + +This function logs the timer with the given ID. The following data are +logged: + + +- *Last msgs* is the number of calls in the last logging interval. This equals the granularity variable. + + +- *Last sum* is the accumulated duration in the current logging interval (i.e. for the last "granularity" calls). + + +- *Last min* is the minimum duration between start/log_timer calls during the last interval. + + +- *Last max* - maximum duration. + + +- *Last average* is the average duration between +bm_start_timer() and bm_log_timer() since the last logging. + + +- *Global msgs* number of calls to log_timer. + + +- *Global sum* total duration in microseconds. + + +- *Global min*... You get the point. :) + + +- *Global max* also obvious. + + +- *Global avg* possibly the most interesting value. + + +```opensips title="bm_log_timer usage" +... +bm_log_timer("test"); +... +``` + + +### Exported Pseudo-Variables + + +Exported pseudo-variables are listed in the next sections. + + +#### $BM_time_diff + + +*$BM_time_diff* - the time difference +elapsed between calls of bm_start_timer(name) and +bm_log_timer(name). The value is 0 if no bm_log_timer() +was called. + + +### Exported MI Functions + + +#### bm_enable_global + + +Enables/disables the module. + + +Parameters: + + +- *enable* - value may be -1, 0 or 1. See +discription of "enable" parameter. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi bm_enable_global 1 + +``` + + +#### bm_enable_timer + + +Enable or disable a single timer. + + +Parameters: + + +- *timer* - timer name +- *enable* - enable (1) or disable (0) timer + + +MI FIFO Command Format: + + +```bash title="Enabling a timer" +... +opensips-cli -x mi bm_enable_timer test 1 +... +``` + + +#### bm_granularity + + +Modifies the benchmarking granularity. + + +Parameters: + + +- *granularity* - See +discription of "granularity" parameter. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi bm_granularity 300 + +``` + + +#### bm_loglevel + + +Modifies the module log level. + + +Parameters: + + +- *log_level* - See +discription of "loglevel" parameter. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi bm_loglevel 4 + +``` + + +#### bm_poll_results + + +Returns the current and global results for each timer. This command is only available if the "granularity" variable is set to 0. It can be used to get results in stable time intervals instead of every N messages. Each timer will have 2 nodes - the local and the global values. Format of the values is the same as the one normally used in logfile. This way of getting the results allows to interface with external graphing applications like Munin. + + +If there were no new calls to *bm_log_timer* since last check, then all current values of a timer will be equal 0. Each call to *bm_poll_results* will reset current values (but not global ones). + + +```bash title="Getting the results via FIFO interface" +... +opensips-cli -x mi bm_poll_results +register_timer + 3/40/12/14/13.333333 + 9/204/12/97/22.666667 +security_check_timer + 3/21/7/7/7.000000 + 9/98/7/41/10.888889 +... +``` + + +### Example of usage + + +Measure the duration of user location lookup. + + +```opensips title="benchmark usage" +... +bm_start_timer("usrloc-lookup"); +lookup("location"); +bm_log_timer("usrloc-lookup"); +... +``` + + +## Developer Guide + + +The benchmark module provides an internal API to be used by +other OpenSIPS modules. The available functions are identical to the user exported +functions. + + +Please note that this module is intended mainly for developers. It should +be used with caution in production environments. + + +### Available Functions + + +#### bm_register(name, mode, id) + + +This function register a new timer and/or returns the internal ID +associated with the timer. mode controls the creation of new timer +if not found. id is to be used by start and log timer functions. + + +#### bm_start(id) + + +This function equals the user-exported function bm_start_timer. The +id is passed as an integer, though. + + +#### bm_log(id) + + +This function equals the user-exported function bm_log_timer. The id +is passed as an integer, though. + + +### Benchmark API Example + + +```c title="Using the benchmark module's API from another module" +... +#include "../benchmark/benchmark.h" +... +struct bm_binds bmb; +... +... +/* load the benchmarking API */ +if (load_bm_api( &bmb )!=0) { + LM_ERR("can't load benchmark API\n"); + goto error; +} +... +... +/* Start/log timers during a (usually user-exported) module function */ +bmb.bm_register("test", 1, &id) +bmb.bm_start(id); +do_something(); +bmb.bm_log(id); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/benchmark/doc/benchmark.xml b/modules/benchmark/doc/benchmark.xml deleted file mode 100644 index 18f5a9fc266..00000000000 --- a/modules/benchmark/doc/benchmark.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Benchmark Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Collax GmbH - ©right; 2007 &voicesystem; - diff --git a/modules/benchmark/doc/benchmark_admin.xml b/modules/benchmark/doc/benchmark_admin.xml deleted file mode 100644 index d837dca6e35..00000000000 --- a/modules/benchmark/doc/benchmark_admin.xml +++ /dev/null @@ -1,402 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module helps developers to benchmark their module functions. By adding - this module's functions via the configuration file or through its API, OpenSIPS - can log profiling information for every function. - - - The duration between calls to start_timer and log_timer is stored and logged - via &osips;'s logging facility. Please note that all durations are given as - microseconds (don't confuse with milliseconds!). - - Important note: as this benchmarking is intended to measure the time - spent in executing different parts/blocks of the script (and not for - measuring the time induced by the SIP signaling), the benchmark module - is to be used within the SAME top route (request route, failure route, - branch route, onreply rout, etc). It is not design to be used across - different types of top routes (like started in request route and ended in - failure route)!! - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters - -
- <varname>enable</varname> (int) - - Even when the module is loaded, benchmarking is not enabled - per default. This variable may have three different values: - - - - -1 - Globally disable benchmarking - - - - - 0 - Enable per-timer enabling. Single timers are inactive by default - and can be activated through the MI interface as soon as that feature is - implemented. - - - - - 1 - Globally enable benchmarking - - - - - - - Default value is 0. - - - - Set <varname>enable</varname> parameter - -... -modparam("benchmark", "enable", 1) -... - - -
- -
- <varname>granularity</varname> (int) - - Logging normally is not done for every reference to the log_timer() - function, but only every n'th call. n is defined through this variable. - A sensible granularity seems to be 100. - - - If granularity is set to 0, then nothing will be logged automatically. Instead bm_poll_results MI command can be used to retrieve the results and clean the local values. - - - - Default value is 100. - - - - Set <varname>granularity</varname> parameter - -... -modparam("benchmark", "granularity", 500) -... - - -
- -
- <varname>loglevel</varname> (int) - - Set the log level for the benchmark logs. These levels should be used: - - -3 - L_ALERT - -2 - L_CRIT - -1 - L_ERR - 1 - L_WARN - 2 - L_NOTICE - 3 - L_INFO - 4 - L_DBG - - - - - Default value is 3 (L_INFO). - - - - Set <varname>loglevel</varname> parameter - -... -modparam("benchmark", "loglevel", 4) -... - - - - This will set the logging level to L_DBG. - -
- -
-
- Exported Functions -
- - <function moreinfo="none">bm_start_timer(name)</function> - - - Start timer name. A later call to - bm_log_timer() logs this timer.. - - - <function>bm_start_timer</function> usage - -... -bm_start_timer("test"); -... - - -
- -
- - <function moreinfo="none">bm_log_timer(name)</function> - - - This function logs the timer with the given ID. The following data are - logged: - - - Last msgs is the number of calls in the last logging interval. This equals the granularity variable. - - - - - - Last sum is the accumulated duration in the current logging interval (i.e. for the last granularity calls). - - - - - - Last min is the minimum duration between start/log_timer calls during the last interval. - - - - - - Last max - maximum duration. - - - - - - Last average is the average duration between - bm_start_timer() and bm_log_timer() since the last logging. - - - - - - Global msgs number of calls to log_timer. - - - - - - Global sum total duration in microseconds. - - - - - - Global min... You get the point. :) - - - - - - Global max also obvious. - - - - - - Global avg possibly the most interesting value. - - - - - - <function>bm_log_timer</function> usage - -... -bm_log_timer("test"); -... - - -
-
- -
- Exported Pseudo-Variables - - Exported pseudo-variables are listed in the next sections. - -
- $BM_time_diff - - $BM_time_diff - the time difference - elapsed between calls of bm_start_timer(name) and - bm_log_timer(name). The value is 0 if no bm_log_timer() - was called. - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">bm_enable_global</function> - - Enables/disables the module. - - Parameters: - - - enable - value may be -1, 0 or 1. See - discription of "enable" parameter. - - - - MI FIFO Command Format: - - - opensips-cli -x mi bm_enable_global 1 - -
-
- <function moreinfo="none">bm_enable_timer</function> - - Enable or disable a single timer. - - Parameters: - - - timer - timer name - - - enable - enable (1) or disable (0) timer - - - - MI FIFO Command Format: - - - Enabling a timer - -... -opensips-cli -x mi bm_enable_timer test 1 -... - - -
-
- <function moreinfo="none">bm_granularity</function> - - Modifies the benchmarking granularity. - - Parameters: - - - granularity - See - discription of "granularity" parameter. - - - - MI FIFO Command Format: - - - opensips-cli -x mi bm_granularity 300 - -
-
- <function moreinfo="none">bm_loglevel</function> - - Modifies the module log level. - - Parameters: - - - log_level - See - discription of "loglevel" parameter. - - - - MI FIFO Command Format: - - - opensips-cli -x mi bm_loglevel 4 - -
-
- <function moreinfo="none">bm_poll_results</function> - - Returns the current and global results for each timer. This command is only available if the "granularity" variable is set to 0. It can be used to get results in stable time intervals instead of every N messages. Each timer will have 2 nodes - the local and the global values. Format of the values is the same as the one normally used in logfile. This way of getting the results allows to interface with external graphing applications like Munin. - - - If there were no new calls to bm_log_timer since last check, then all current values of a timer will be equal 0. Each call to bm_poll_results will reset current values (but not global ones). - - - Getting the results via FIFO interface - -... -opensips-cli -x mi bm_poll_results -register_timer - 3/40/12/14/13.333333 - 9/204/12/97/22.666667 -security_check_timer - 3/21/7/7/7.000000 - 9/98/7/41/10.888889 -... - - -
-
- -
- Example of usage - - Measure the duration of user location lookup. - - - benchmark usage - -... -bm_start_timer("usrloc-lookup"); -lookup("location"); -bm_log_timer("usrloc-lookup"); -... - - -
-
- diff --git a/modules/benchmark/doc/benchmark_devel.xml b/modules/benchmark/doc/benchmark_devel.xml deleted file mode 100644 index fbaf4d9719c..00000000000 --- a/modules/benchmark/doc/benchmark_devel.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - &develguide; - - - The benchmark module provides an internal API to be used by - other &osips; modules. The available functions are identical to the user exported - functions. - - - Please note that this module is intended mainly for developers. It should - be used with caution in production environments. - - -
- Available Functions - -
- - <function moreinfo="none">bm_register(name, mode, id)</function> - - - This function register a new timer and/or returns the internal ID - associated with the timer. mode controls the creation of new timer - if not found. id is to be used by start and log timer functions. - -
- -
- - <function moreinfo="none">bm_start(id)</function> - - - This function equals the user-exported function bm_start_timer. The - id is passed as an integer, though. - -
- -
- - <function moreinfo="none">bm_log(id)</function> - - - This function equals the user-exported function bm_log_timer. The id - is passed as an integer, though. - -
-
- - -
- Benchmark API Example - - Using the benchmark module's API from another module - -... -#include "../benchmark/benchmark.h" -... -struct bm_binds bmb; -... -... -/* load the benchmarking API */ -if (load_bm_api( &bmb )!=0) { - LM_ERR("can't load benchmark API\n"); - goto error; -} -... -... -/* Start/log timers during a (usually user-exported) module function */ -bmb.bm_register("test", 1, &id) -bmb.bm_start(id); -do_something(); -bmb.bm_log(id); -... - - -
- -
- diff --git a/modules/benchmark/doc/contributors.xml b/modules/benchmark/doc/contributors.xml deleted file mode 100644 index d085df1db19..00000000000 --- a/modules/benchmark/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 23 - 10 - 1391 - 50 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 21 - 19 - 88 - 53 - - - 3. - Liviu Chircu (@liviuchircu) - 14 - 11 - 28 - 61 - - - 4. - Razvan Crainea (@razvancrainea) - 11 - 9 - 23 - 21 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 9 - 4 - 185 - 143 - - - 6. - Stanislaw Pitucha - 7 - 3 - 170 - 65 - - - 7. - Henning Westerholt (@henningw) - 6 - 4 - 11 - 10 - - - 8. - Maksym Sobolyev (@sobomax) - 5 - 3 - 5 - 6 - - - 9. - David Sanders - 4 - 2 - 8 - 1 - - - 10. - Anca Vamanu - 3 - 1 - 5 - 2 - - - -
-All remaining contributors: Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Apr 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - David Sanders - Aug 2012 - Jan 2013 - - - 8. - Anca Vamanu - Sep 2009 - Sep 2009 - - - 9. - Stanislaw Pitucha - Aug 2009 - Sep 2009 - - - 10. - Daniel-Constantin Mierla (@miconda) - Jul 2007 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Stanislaw Pitucha, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw). -
- -
diff --git a/modules/cachedb_cassandra/README b/modules/cachedb_cassandra/README deleted file mode 100644 index 1ac7a06b889..00000000000 --- a/modules/cachedb_cassandra/README +++ /dev/null @@ -1,341 +0,0 @@ -cachedb_cassandra Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - 1.5.2. connect_timeout (int) - 1.5.3. query_timeout (int) - 1.5.4. wr_consistency_level (int) - 1.5.5. rd_consistency_level (int) - 1.5.6. exec_threshold (int) - - 1.6. Exported Functions - 1.7. Table Schema - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Use Cassandra servers - 1.3. Set connect_timeout parameter - 1.4. Set query_timeout parameter - 1.5. Set wr_consistency_level parameter - 1.6. Set rd_consistency_level parameter - 1.7. Set exec_threshold parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with Cassandra servers. It uses the Key-Value interface - exported from the core. - - The underlying client library is compatible with Cassandra - versions 2.1+. - -1.2. Advantages - - * memory costs are no longer on the server - * many servers can be used inside a cluster, so the memory is - virtually unlimited - * the cache is 100% persistent. A restart of OpenSIPS server - will not affect the DB. The Cassandra DB is also persistent - so it can also be restarted without loss of information. - * Cassandra is an open-source project so it can be used to - exchange data with various other applications - * By creating a Cassandra Cluster, multiple OpenSIPS - instances can easily share key-value information - -1.3. Limitations - - * keys (in key:value pairs) may not contain spaces or control - characters - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libuv - * cassandra-cpp-driver - - The DataStax C/C++ driver for Cassandra and the libuv - dependency can be downloaded from: - http://downloads.datastax.com/cpp-driver/. - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The urls of the server groups that OpenSIPS will connect to in - order to use the from script cache_store,cache_fetch, etc - operations. It can be set more than one time. The prefix part - of the URL will be the identifier that will be used from the - script. - - Cassandra does not support regular columns in a table that - contains any counter columns so in order to use the - add()/sub()/get_counter() methods in the Key-Value Interface - you can specify an extra table reserved only for counters. - - The database part of the URL needs to be in the format - Keyspace.Table[.CountersTable]. - - Example 1.1. Set cachedb_url parameter -... -modparam("cachedb_cassandra", "cachedb_url", - "cassandra:group1://localhost:9042/keyspace1.users.counters") - -# Defining multiple contact points for a Cassandra cluster -modparam("cachedb_cassandra", "cachedb_url", - "cassandra:cluster1://10.0.0.10,10.0.0.15/keyspace2.keys.counter -s") -... - - Example 1.2. Use Cassandra servers -... -cache_store("cassandra:group1","key","$ru value"); -cache_fetch("cassandra:cluster1","key",$avp(10)); -cache_remove("cassandra:cluster1","key"); -... - -1.5.2. connect_timeout (int) - - The timeout in ms that will be triggered in case a connection - attempt fails. - - Default value is “5000”. - - Example 1.3. Set connect_timeout parameter -... -modparam("cachedb_cassandra", "connect_timeout",1000); -... - -1.5.3. query_timeout (int) - - The timeout in ms that will be triggered in case a Cassandra - query takes too long. - - Default value is “5000”. - - Example 1.4. Set query_timeout parameter -... -modparam("cachedb_cassandra", "query_timeout",1000); -... - -1.5.4. wr_consistency_level (int) - - The consistency level desired for write operations. Options are - : - * all - A write must be written to the commit log and - memtable on all replica nodes in the cluster for that - partition. - * each_quorum - Strong consistency. A write must be written - to the commit log and memtable on a quorum of replica nodes - in each datacenter. - * quorum - A write must be written to the commit log and - memtable on a quorum of replica nodes across all - datacenters. - * local_quorum - Strong consistency. A write must be written - to the commit log and memtable on a quorum of replica nodes - in the same datacenter as the coordinator. Avoids latency - of inter-datacenter communication. - * one - A write must be written to the commit log and - memtable of at least one replica node. - * two - A write must be written to the commit log and - memtable of at least two replica node. - * three - A write must be written to the commit log and - memtable of at least three replica node. - * local_one - A write must be sent to, and successfully - acknowledged by, at least one replica node in the local - datacenter. - * any - A write must be written to at least one node. If all - replica nodes for the given partition key are down, the - write can still succeed after a hinted handoff has been - written. If all replica nodes are down at write time, an - ANY write is not readable until the replica nodes for that - partition have recovered. - - Default value is one. - - Example 1.5. Set wr_consistency_level parameter -... -modparam("cachedb_cassandra", "wr_consistency_level", "each_quorum"); -... - -1.5.5. rd_consistency_level (int) - - The consistency level desired for write operations. Options are - : - * all - Returns the record after all replicas have responded. - The read operation will fail if a replica does not respond. - * quorum - Returns the record after a quorum of replicas from - all datacenters has responded. - * local_quorum - Returns the record after a quorum of - replicas in the current datacenter as the coordinator has - reported. Avoids latency of inter-datacenter communication. - * one - Returns a response from the closest replica, as - determined by the snitch. By default, a read repair runs in - the background to make the other replicas consistent. - * two - Returns the most recent data from two of the closest - replicas. - * three - Returns the most recent data from three of the - closest replicas. - * local_one - Returns a response from the closest replica in - the local datacenter. - * serial - Allows reading the current (and possibly - uncommitted) state of data without proposing a new addition - or update. If a SERIAL read finds an uncommitted - transaction in progress, it will commit the transaction as - part of the read. Similar to QUORUM. - * local_serial - Same as SERIAL, but confined to the - datacenter. Similar to LOCAL_QUORUM. - - Default value is one. - - Example 1.6. Set rd_consistency_level parameter -... -modparam("cachedb_cassandra", "rd_consistency_level", "quorum"); -... - -1.5.6. exec_threshold (int) - - A cassandra cache query that lasts more than this threshold - will trigger a warning message to the log. - - This value, if set, only makes sense to be lower than the - query_timeout since any query taking longer than that value - will be dropped anyway. - - Default value is “0 ( unlimited - no warnings )”. - - Example 1.7. Set exec_threshold parameter -... -modparam("cachedb_cassandra", "exec_threshold", 100000) -... - -1.6. Exported Functions - - The module does not export functions to be used in - configuration script. - -1.7. Table Schema - - The table required for supporting the - cache_store()/cache_fetch()/cache_remove() functions of the - Key-Value interface needs to have at least the following - columns: - * opensipskey - as the primary key with type "text" - * opensipsval - with type "text" - - The table required for supporting the - cache_add()/cache_sub()/cache_counter_fetch() functions of the - Key-Value interface needs to have at least the following - columns: - * opensipskey - as the primary key with type "text" - * opensipsval - with type "counter" - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 378 13 1998 21057 - 2. Vlad Paiu (@vladpaiu) 189 7 21444 38 - 3. Liviu Chircu (@liviuchircu) 11 9 39 50 - 4. Razvan Crainea (@razvancrainea) 8 6 16 14 - 5. fabriziopicconi 4 2 5 5 - 6. Maksym Sobolyev (@sobomax) 4 2 3 3 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 3 1 - 8. Zoop 3 1 5 2 - 9. Norman Brandinger (@NormB) 3 1 2 2 - 10. Julián Moreno Patiño 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov), Jarrod - Baumann (@jarrodb). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Norman Brandinger (@NormB) Jan 2025 - Jan 2025 - 2. Zoop Oct 2024 - Oct 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Jan 2021 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jun 2020 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Jarrod Baumann (@jarrodb) May 2015 - May 2015 - - All remaining contributors: fabriziopicconi, Vlad Paiu - (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Norman Brandinger (@NormB), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), - Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2011 www.opensips-solutions.com diff --git a/modules/cachedb_cassandra/README.md b/modules/cachedb_cassandra/README.md new file mode 100644 index 00000000000..ef2b0b8dd62 --- /dev/null +++ b/modules/cachedb_cassandra/README.md @@ -0,0 +1,254 @@ +--- +title: "cachedb_cassandra Module" +description: "This module is an implementation of a cache system designed to work with Cassandra servers. It uses the Key-Value interface exported from the core." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with +Cassandra servers. +It uses the Key-Value interface exported from the core. + + +The underlying client library is compatible with Cassandra versions 2.1+. + + +### Advantages + + +- *memory costs are no longer on the server* +- *many servers can be used inside a cluster, so the memory +is virtually unlimited* +- *the cache is 100% persistent. A restart +of OpenSIPS server will not affect the DB. The Cassandra DB is also +persistent so it can also be restarted without loss of information.* +- *Cassandra is an open-source project so +it can be used to exchange data +with various other applications* +- *By creating a Cassandra Cluster, multiple OpenSIPS +instances can easily share key-value information* + + +### Limitations + + +- *keys (in key:value pairs) may not contain spaces or control characters* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libuv* +- *cassandra-cpp-driver* + + +The DataStax C/C++ driver for Cassandra and the libuv dependency +can be downloaded from: [http://downloads.datastax.com/cpp-driver/](http://downloads.datastax.com/cpp-driver/). + + +### Exported Parameters + + +#### cachedb_url (string) + + +The urls of the server groups that OpenSIPS will connect to in order +to use the from script cache_store,cache_fetch, etc operations. +It can be set more than one time. +The prefix part of the URL will be the identifier that will be used +from the script. + + +Cassandra does not support regular columns in a table that contains any +counter columns so in order to use the add()/sub()/get_counter() methods +in the Key-Value Interface you can specify an extra table reserved +only for counters. + + +The database part of the URL needs to be in the format *Keyspace.Table[.CountersTable]*. + + +```opensips title="Set cachedb_url parameter" +... +modparam("cachedb_cassandra", "cachedb_url", + "cassandra:group1://localhost:9042/keyspace1.users.counters") + +# Defining multiple contact points for a Cassandra cluster +modparam("cachedb_cassandra", "cachedb_url", + "cassandra:cluster1://10.0.0.10,10.0.0.15/keyspace2.keys.counters") +... + +``` + + +```opensips title="Use Cassandra servers" +... +cache_store("cassandra:group1","key","$ru value"); +cache_fetch("cassandra:cluster1","key",$avp(10)); +cache_remove("cassandra:cluster1","key"); +... + +``` + + +#### connect_timeout (int) + + +The timeout in ms that will be triggered in case a connection attempt fails. + + +*Default value is "5000".* + + +```opensips title="Set connect_timeout parameter" +... +modparam("cachedb_cassandra", "connect_timeout",1000); +... + +``` + + +#### query_timeout (int) + + +The timeout in ms that will be triggered in case a Cassandra query takes too long. + + +*Default value is "5000".* + + +```opensips title="Set query_timeout parameter" +... +modparam("cachedb_cassandra", "query_timeout",1000); +... + +``` + + +#### wr_consistency_level (int) + + +The consistency level desired for write operations. +Options are: + + +- *all* - A write must be written to the commit log and memtable on all replica nodes in the cluster for that partition. +- *each_quorum* - Strong consistency. A write must be written to the commit log and memtable on a quorum of replica nodes in each datacenter. +- *quorum* - A write must be written to the commit log and memtable on a quorum of replica nodes across all datacenters. +- *local_quorum* - Strong consistency. A write must be written to the commit log and memtable on a quorum of replica nodes in the same datacenter as the coordinator. Avoids latency of inter-datacenter communication. +- *one* - A write must be written to the commit log and memtable of at least one replica node. +- *two* - A write must be written to the commit log and memtable of at least two replica node. +- *three* - A write must be written to the commit log and memtable of at least three replica node. +- *local_one* - A write must be sent to, and successfully acknowledged by, at least one replica node in the local datacenter. +- *any* - A write must be written to at least one node. If all replica nodes for the given partition key are down, the write can still succeed after a hinted handoff has been written. If all replica nodes are down at write time, an ANY write is not readable until the replica nodes for that partition have recovered. + + +Default value is *one*. + + +```opensips title="Set wr_consistency_level parameter" +... +modparam("cachedb_cassandra", "wr_consistency_level", "each_quorum"); +... + +``` + + +#### rd_consistency_level (int) + + +The consistency level desired for write operations. +Options are: + + +- *all* - Returns the record after all replicas have responded. The read operation will fail if a replica does not respond. +- *quorum* - Returns the record after a quorum of replicas from all datacenters has responded. +- *local_quorum* - Returns the record after a quorum of replicas in the current datacenter as the coordinator has reported. Avoids latency of inter-datacenter communication. +- *one* - Returns a response from the closest replica, as determined by the snitch. By default, a read repair runs in the background to make the other replicas consistent. +- *two* - Returns the most recent data from two of the closest replicas. +- *three* - Returns the most recent data from three of the closest replicas. +- *local_one* - Returns a response from the closest replica in the local datacenter. +- *serial* - Allows reading the current (and possibly uncommitted) state of data without proposing a new addition or update. If a SERIAL read finds an uncommitted transaction in progress, it will commit the transaction as part of the read. Similar to QUORUM. +- *local_serial* - Same as SERIAL, but confined to the datacenter. Similar to LOCAL_QUORUM. + + +Default value is *one*. + + +```opensips title="Set rd_consistency_level parameter" +... +modparam("cachedb_cassandra", "rd_consistency_level", "quorum"); +... + +``` + + +#### exec_threshold (int) + + +A cassandra cache query that lasts more than this threshold will +trigger a warning message to the log. + + +This value, if set, only makes sense to be lower than the +[query timeout](#param_query_timeout) since any query taking longer +than that value will be dropped anyway. + + +*Default value is "0 ( unlimited - no warnings )".* + + +```opensips title="Set exec_threshold parameter" +... +modparam("cachedb_cassandra", "exec_threshold", 100000) +... + +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### Table Schema + + +The table required for supporting the cache_store()/cache_fetch()/cache_remove() +functions of the Key-Value interface needs to have at least the following columns: + + +- *opensipskey* - as the primary key with type "text" +- *opensipsval* - with type "text" + + +The table required for supporting the cache_add()/cache_sub()/cache_counter_fetch() +functions of the Key-Value interface needs to have at least the following columns: + + +- *opensipskey* - as the primary key with type "text" +- *opensipsval* - with type "counter" + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_cassandra/cachedb_cassandra_dbase.c b/modules/cachedb_cassandra/cachedb_cassandra_dbase.c index 580fb470405..f50cd5b0627 100644 --- a/modules/cachedb_cassandra/cachedb_cassandra_dbase.c +++ b/modules/cachedb_cassandra/cachedb_cassandra_dbase.c @@ -141,13 +141,13 @@ int cassandra_reopen(cassandra_con *cass_con) int cassandra_new_connection(cassandra_con *con, char *host, int port, char *username, char *password) { con->cluster = cass_cluster_new(); - if (username && password) { - cass_cluster_set_credentials(con->cluster, username, password); - } if (!con->cluster) { LM_ERR("Failed to create Cassandra Cluster object\n"); return -1; } + if (username && password) { + cass_cluster_set_credentials(con->cluster, username, password); + } #if CASS_VERSION_MAJOR >= 2 && CASS_VERSION_MINOR >= 15 /* since version 2.15, DSE support is available in the standard driver diff --git a/modules/cachedb_cassandra/doc/cachedb_cassandra.xml b/modules/cachedb_cassandra/doc/cachedb_cassandra.xml deleted file mode 100644 index 7beedd91553..00000000000 --- a/modules/cachedb_cassandra/doc/cachedb_cassandra.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - cachedb_cassandra Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2011 &osipssol; - - diff --git a/modules/cachedb_cassandra/doc/cachedb_cassandra_admin.xml b/modules/cachedb_cassandra/doc/cachedb_cassandra_admin.xml deleted file mode 100644 index 190c7fa7539..00000000000 --- a/modules/cachedb_cassandra/doc/cachedb_cassandra_admin.xml +++ /dev/null @@ -1,379 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with - Cassandra servers. - It uses the Key-Value interface exported from the core. - - - The underlying client library is compatible with Cassandra versions 2.1+. - -
- - -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - many servers can be used inside a cluster, so the memory - is virtually unlimited - - - - - - the cache is 100% persistent. A restart - of OpenSIPS server will not affect the DB. The Cassandra DB is also - persistent so it can also be restarted without loss of information. - - - - - - Cassandra is an open-source project so - it can be used to exchange data - with various other applications - - - - - - By creating a Cassandra Cluster, multiple OpenSIPS - instances can easily share key-value information - - - - - - - -
- -
- Limitations - - - - - - - - keys (in key:value pairs) may not contain spaces or control characters - - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libuv - - - cassandra-cpp-driver - - - - The DataStax C/C++ driver for Cassandra and the libuv dependency - can be downloaded from: . - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The urls of the server groups that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - It can be set more than one time. - The prefix part of the URL will be the identifier that will be used - from the script. - - - Cassandra does not support regular columns in a table that contains any - counter columns so in order to use the add()/sub()/get_counter() methods - in the Key-Value Interface you can specify an extra table reserved - only for counters. - - - The database part of the URL needs to be in the format - Keyspace.Table[.CountersTable]. - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("cachedb_cassandra", "cachedb_url", - "cassandra:group1://localhost:9042/keyspace1.users.counters") - -# Defining multiple contact points for a Cassandra cluster -modparam("cachedb_cassandra", "cachedb_url", - "cassandra:cluster1://10.0.0.10,10.0.0.15/keyspace2.keys.counters") -... - - - - - Use Cassandra servers - -... -cache_store("cassandra:group1","key","$ru value"); -cache_fetch("cassandra:cluster1","key",$avp(10)); -cache_remove("cassandra:cluster1","key"); -... - - -
- -
- <varname>connect_timeout</varname> (int) - - The timeout in ms that will be triggered in case a connection attempt fails. - - - Default value is 5000. - - - - Set <varname>connect_timeout</varname> parameter - -... -modparam("cachedb_cassandra", "connect_timeout",1000); -... - - - -
- -
- <varname>query_timeout</varname> (int) - - The timeout in ms that will be triggered in case a Cassandra query takes too long. - - - Default value is 5000. - - - Set <varname>query_timeout</varname> parameter - -... -modparam("cachedb_cassandra", "query_timeout",1000); -... - - - -
- -
- <varname>wr_consistency_level</varname> (int) - - The consistency level desired for write operations. - Options are : - - - all - A write must be written to the commit log and memtable on all replica nodes in the cluster for that partition. - - - - each_quorum - Strong consistency. A write must be written to the commit log and memtable on a quorum of replica nodes in each datacenter. - - - - quorum - A write must be written to the commit log and memtable on a quorum of replica nodes across all datacenters. - - - - local_quorum - Strong consistency. A write must be written to the commit log and memtable on a quorum of replica nodes in the same datacenter as the coordinator. Avoids latency of inter-datacenter communication. - - - - one - A write must be written to the commit log and memtable of at least one replica node. - - - - two - A write must be written to the commit log and memtable of at least two replica node. - - - - three - A write must be written to the commit log and memtable of at least three replica node. - - - - local_one - A write must be sent to, and successfully acknowledged by, at least one replica node in the local datacenter. - - - - any - A write must be written to at least one node. If all replica nodes for the given partition key are down, the write can still succeed after a hinted handoff has been written. If all replica nodes are down at write time, an ANY write is not readable until the replica nodes for that partition have recovered. - - - - - Default value is one. - - - - Set <varname>wr_consistency_level</varname> parameter - -... -modparam("cachedb_cassandra", "wr_consistency_level", "each_quorum"); -... - - - -
- -
- <varname>rd_consistency_level</varname> (int) - - The consistency level desired for write operations. - Options are : - - - all - Returns the record after all replicas have responded. The read operation will fail if a replica does not respond. - - - - quorum - Returns the record after a quorum of replicas from all datacenters has responded. - - - - local_quorum - Returns the record after a quorum of replicas in the current datacenter as the coordinator has reported. Avoids latency of inter-datacenter communication. - - - - one - Returns a response from the closest replica, as determined by the snitch. By default, a read repair runs in the background to make the other replicas consistent. - - - - two - Returns the most recent data from two of the closest replicas. - - - - three - Returns the most recent data from three of the closest replicas. - - - - local_one - Returns a response from the closest replica in the local datacenter. - - - - serial - Allows reading the current (and possibly uncommitted) state of data without proposing a new addition or update. If a SERIAL read finds an uncommitted transaction in progress, it will commit the transaction as part of the read. Similar to QUORUM. - - - - local_serial - Same as SERIAL, but confined to the datacenter. Similar to LOCAL_QUORUM. - - - - - Default value is one. - - - - Set <varname>rd_consistency_level</varname> parameter - -... -modparam("cachedb_cassandra", "rd_consistency_level", "quorum"); -... - - - -
- -
- <varname>exec_threshold</varname> (int) - - A cassandra cache query that lasts more than this threshold will - trigger a warning message to the log. - - - This value, if set, only makes sense to be lower than the - since any query taking longer - than that value will be dropped anyway. - - - Default value is 0 ( unlimited - no warnings ). - - - - Set <varname>exec_threshold</varname> parameter - -... -modparam("cachedb_cassandra", "exec_threshold", 100000) -... - - -
-
- -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- -
- Table Schema - - The table required for supporting the cache_store()/cache_fetch()/cache_remove() - functions of the Key-Value interface needs to have at least the following columns: - - - opensipskey - as the primary key with type "text" - - - opensipsval - with type "text" - - - - - The table required for supporting the cache_add()/cache_sub()/cache_counter_fetch() - functions of the Key-Value interface needs to have at least the following columns: - - - opensipskey - as the primary key with type "text" - - - opensipsval - with type "counter" - - - -
- -
- diff --git a/modules/cachedb_cassandra/doc/contributors.xml b/modules/cachedb_cassandra/doc/contributors.xml deleted file mode 100644 index e664e65cb31..00000000000 --- a/modules/cachedb_cassandra/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 378 - 13 - 1998 - 21057 - - - 2. - Vlad Paiu (@vladpaiu) - 189 - 7 - 21444 - 38 - - - 3. - Liviu Chircu (@liviuchircu) - 11 - 9 - 39 - 50 - - - 4. - Razvan Crainea (@razvancrainea) - 8 - 6 - 16 - 14 - - - 5. - fabriziopicconi - 4 - 2 - 5 - 5 - - - 6. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 3 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 3 - 1 - - - 8. - Zoop - 3 - 1 - 5 - 2 - - - 9. - Norman Brandinger (@NormB) - 3 - 1 - 2 - 2 - - - 10. - Julián Moreno Patiño - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Jarrod Baumann (@jarrodb). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Norman Brandinger (@NormB) - Jan 2025 - Jan 2025 - - - 2. - Zoop - Oct 2024 - Oct 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jan 2021 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jun 2020 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Jarrod Baumann (@jarrodb) - May 2015 - May 2015 - - - -
-All remaining contributors: fabriziopicconi, Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Norman Brandinger (@NormB), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/cachedb_couchbase/README b/modules/cachedb_couchbase/README deleted file mode 100644 index 8475b093682..00000000000 --- a/modules/cachedb_couchbase/README +++ /dev/null @@ -1,223 +0,0 @@ -cachedb_couchbase Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - 1.5.2. timeout (int) - 1.5.3. exec_threshold (int) - 1.5.4. lazy_connect (int) - 1.5.5. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Set timeout parameter - 1.3. Set exec_threshold parameter - 1.4. Set lazy_connect parameter - 1.5. Use CouchBase servers - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with a Couchbase server. It uses the libcouchbase client - library to connect to the server instance, It uses the - Key-Value interface exported from the core. - -1.2. Advantages - - * memory costs are no longer on the server - * many servers can be used inside a cluster, so the memory is - virtually unlimited - * the cache is 100% persistent. A restart of OpenSIPS server - will not affect the DB. The CouchBase DB is also persistent - so it can also be restarted without loss of information. - * CouchBase is an open-source project so it can be used to - exchange data with various other applications - * By creating a CouchBase Cluster, multiple OpenSIPS - instances can easily share key-value information - -1.3. Limitations - - * keys (in key:value pairs) may not contain spaces or control - characters - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libcouchbase >= 3.0: - libcoucbase can be downloaded from - http://www.couchbase.com/develop/c/current - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The urls of the server groups that OpenSIPS will connect to in - order to use the from script cache_store,cache_fetch, etc - operations. It can be set more than one time. The prefix part - of the URL will be the identifier that will be used from the - script. The format of the URL is - couchbase[:identifier]://[username:password@]IP:Port/bucket_nam - e - - Example 1.1. Set cachedb_url parameter -... -modparam("cachedb_couchbase", "cachedb_url","couchbase:group1://localhos -t:6379/default") -modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random -_url:8888/my_bucket") -# Multiple hosts -modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random -_url1:8888,random_url2:8888,random_url3:8888/my_bucket") -... - -1.5.2. timeout (int) - - The max duration in microseconds that a couchbase op is - expected to last. Default is 3000000 ( 3 seconds ) - - Example 1.2. Set timeout parameter -... -modparam("cachedb_couchbase", "timeout",5000000); -... - -1.5.3. exec_threshold (int) - - The maximum number of microseconds that a couchbase query can - last. Anything above the threshold will trigger a warning - message to the log - - Default value is “0 ( unlimited - no warnings )”. - - Example 1.3. Set exec_threshold parameter -... -modparam("cachedb_couchbase", "exec_threshold", 100000) -... - -1.5.4. lazy_connect (int) - - Delay connecting to a bucket until the first time it is used. - Connecting to many buckets at startup can be time consuming. - This option allows for faster startup by delaying connections - until they are needed. This option can be dangerous for - untested bucket configurations/settings. Always test first - without lazy_connect. This option will show errors in the log - during the first access made to a bucket. Default is 0 ( - Connect to all buckets on startup ) - - Example 1.4. Set lazy_connect parameter -... -modparam("cachedb_couchbase", "lazy_connect", 1); -... - - Example 1.5. Use CouchBase servers -... -cache_store("couchbase:group1","key","$ru value"); -cache_fetch("couchbase:cluster1","key",$avp(10)); -cache_remove("couchbase:cluster1","key"); -... - -1.5.5. Exported Functions - - The module does not export functions to be used in - configuration script. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 21 8 1146 151 - 2. Peter Lemenkov (@lemenkov) 17 11 206 238 - 3. Razvan Crainea (@razvancrainea) 11 9 101 20 - 4. Liviu Chircu (@liviuchircu) 10 7 96 89 - 5. Ryan Bullock (@rrb3942) 6 2 230 87 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 3 5 - 7. Maksym Sobolyev (@sobomax) 4 2 3 3 - 8. Julián Moreno Patiño 3 1 1 1 - 9. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2015 - Mar 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Peter Lemenkov (@lemenkov) Jun 2018 - Jan 2021 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Mar 2020 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 7. Julián Moreno Patiño Feb 2016 - Feb 2016 - 8. Ryan Bullock (@rrb3942) Oct 2013 - Jun 2015 - 9. Vlad Paiu (@vladpaiu) Jan 2013 - May 2014 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, - Vlad Paiu (@vladpaiu), Ryan Bullock (@rrb3942). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/cachedb_couchbase/README.md b/modules/cachedb_couchbase/README.md new file mode 100644 index 00000000000..9d3df383001 --- /dev/null +++ b/modules/cachedb_couchbase/README.md @@ -0,0 +1,160 @@ +--- +title: "cachedb_couchbase Module" +description: "This module is an implementation of a cache system designed to work with a Couchbase server." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with a +Couchbase server. It uses the libcouchbase client library to connect to the +server instance. +It uses the Key-Value interface exported from the core. + + +### Advantages + + +- *memory costs are no longer on the server* +- *many servers can be used inside a cluster, so the memory +is virtually unlimited* +- *the cache is 100% persistent. A restart +of OpenSIPS server will not affect the DB. The CouchBase DB is also +persistent so it can also be restarted without loss of information.* +- *CouchBase is an open-source project so +it can be used to exchange data +with various other applications* +- *By creating a CouchBase Cluster, multiple OpenSIPS +instances can easily share key-value information* + + +### Limitations + + +- *keys (in key:value pairs) may not contain spaces or control characters* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libcouchbase >= 3.0:* +libcoucbase can be downloaded from http://www.couchbase.com/develop/c/current + + +### Exported Parameters + + +#### cachedb_url (string) + + +The urls of the server groups that OpenSIPS will connect to in order +to use the from script cache_store,cache_fetch, etc operations. +It can be set more than one time. +The prefix part of the URL will be the identifier that will be used +from the script. +The format of the URL is +*couchbase[:identifier]://[username:password@]IP:Port/bucket_name* + + +```opensips title="Set cachedb_url parameter" +... +modparam("cachedb_couchbase", "cachedb_url","couchbase:group1://localhost:6379/default") +modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random_url:8888/my_bucket") +# Multiple hosts +modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random_url1:8888,random_url2:8888,random_url3:8888/my_bucket") +... + +``` + + +#### timeout (int) + + +The max duration in microseconds that a couchbase op is expected to last. + +*Default value is 3000000 (3 seconds).* + + +```opensips title="Set timeout parameter" +... +modparam("cachedb_couchbase", "timeout",5000000); +... + +``` + + +#### exec_threshold (int) + + +The maximum number of microseconds that a couchbase query can last. +Anything above the threshold will trigger a warning message to the log + + +*Default value is "0 ( unlimited - no warnings )".* + + +```opensips title="Set exec_threshold parameter" +... +modparam("cachedb_couchbase", "exec_threshold", 100000) +... + +``` + + +#### lazy_connect (int) + + +Delay connecting to a bucket until the first time it is used. +Connecting to many buckets at startup can be time consuming. This option allows for +faster startup by delaying connections until they are needed. +This option can be dangerous for untested bucket configurations/settings. Always test +first without lazy_connect. +This option will show errors in the log during the first access made to a bucket. + +*Default value is 0 (Connect to all buckets on startup).* + + +```opensips title="Set lazy_connect parameter" +... +modparam("cachedb_couchbase", "lazy_connect", 1); +... + +``` + + +```opensips title="Use CouchBase servers" +... +cache_store("couchbase:group1","key","$ru value"); +cache_fetch("couchbase:cluster1","key",$avp(10)); +cache_remove("couchbase:cluster1","key"); +... + +``` + + +#### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_couchbase/doc/cachedb_couchbase.xml b/modules/cachedb_couchbase/doc/cachedb_couchbase.xml deleted file mode 100644 index 9db78e85a6d..00000000000 --- a/modules/cachedb_couchbase/doc/cachedb_couchbase.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - cachedb_couchbase Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - diff --git a/modules/cachedb_couchbase/doc/cachedb_couchbase_admin.xml b/modules/cachedb_couchbase/doc/cachedb_couchbase_admin.xml deleted file mode 100644 index be4d44814e2..00000000000 --- a/modules/cachedb_couchbase/doc/cachedb_couchbase_admin.xml +++ /dev/null @@ -1,220 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with a - Couchbase server. It uses the libcouchbase client library to connect to the - server instance, - It uses the Key-Value interface exported from the core. - - - -
- - -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - many servers can be used inside a cluster, so the memory - is virtually unlimited - - - - - - the cache is 100% persistent. A restart - of OpenSIPS server will not affect the DB. The CouchBase DB is also - persistent so it can also be restarted without loss of information. - - - - - - CouchBase is an open-source project so - it can be used to exchange data - with various other applications - - - - - - By creating a CouchBase Cluster, multiple OpenSIPS - instances can easily share key-value information - - - - - - - -
- -
- Limitations - - - - - - - - keys (in key:value pairs) may not contain spaces or control characters - - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - libcouchbase >= 3.0: - - - - libcoucbase can be downloaded from http://www.couchbase.com/develop/c/current - - - - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The urls of the server groups that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - It can be set more than one time. - The prefix part of the URL will be the identifier that will be used - from the script. - The format of the URL is - couchbase[:identifier]://[username:password@]IP:Port/bucket_name - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("cachedb_couchbase", "cachedb_url","couchbase:group1://localhost:6379/default") -modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random_url:8888/my_bucket") -# Multiple hosts -modparam("cachedb_couchbase", "cachedb_url","couchbase:cluster1://random_url1:8888,random_url2:8888,random_url3:8888/my_bucket") -... - - -
- -
- <varname>timeout</varname> (int) - - The max duration in microseconds that a couchbase op is expected to last. - Default is 3000000 ( 3 seconds ) - - - - Set <varname>timeout</varname> parameter - -... -modparam("cachedb_couchbase", "timeout",5000000); -... - - -
-
- <varname>exec_threshold</varname> (int) - - The maximum number of microseconds that a couchbase query can last. - Anything above the threshold will trigger a warning message to the log - - - Default value is 0 ( unlimited - no warnings ). - - - - Set <varname>exec_threshold</varname> parameter - -... -modparam("cachedb_couchbase", "exec_threshold", 100000) -... - - -
- -
- <varname>lazy_connect</varname> (int) - - Delay connecting to a bucket until the first time it is used. - Connecting to many buckets at startup can be time consuming. This option allows for - faster startup by delaying connections until they are needed. - This option can be dangerous for untested bucket configurations/settings. Always test - first without lazy_connect. - This option will show errors in the log during the first access made to a bucket. - Default is 0 ( Connect to all buckets on startup ) - - - - Set <varname>lazy_connect</varname> parameter - -... -modparam("cachedb_couchbase", "lazy_connect", 1); -... - - -
- - - Use CouchBase servers - -... -cache_store("couchbase:group1","key","$ru value"); -cache_fetch("couchbase:cluster1","key",$avp(10)); -cache_remove("couchbase:cluster1","key"); -... - - - - -
- Exported Functions - The module does not export functions to be used - in configuration script. -
-
- -
- diff --git a/modules/cachedb_couchbase/doc/contributors.xml b/modules/cachedb_couchbase/doc/contributors.xml deleted file mode 100644 index b52a3c3e153..00000000000 --- a/modules/cachedb_couchbase/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 21 - 8 - 1146 - 151 - - - 2. - Peter Lemenkov (@lemenkov) - 17 - 11 - 206 - 238 - - - 3. - Razvan Crainea (@razvancrainea) - 11 - 9 - 101 - 20 - - - 4. - Liviu Chircu (@liviuchircu) - 10 - 7 - 96 - 89 - - - 5. - Ryan Bullock (@rrb3942) - 6 - 2 - 230 - 87 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 3 - 5 - - - 7. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 3 - - - 8. - Julián Moreno Patiño - 3 - 1 - 1 - 1 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2015 - Mar 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jan 2021 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Mar 2020 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 7. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 8. - Ryan Bullock (@rrb3942) - Oct 2013 - Jun 2015 - - - 9. - Vlad Paiu (@vladpaiu) - Jan 2013 - May 2014 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), Ryan Bullock (@rrb3942). -
- -
diff --git a/modules/cachedb_dynamodb/README b/modules/cachedb_dynamodb/README deleted file mode 100644 index b6b8ac21123..00000000000 --- a/modules/cachedb_dynamodb/README +++ /dev/null @@ -1,288 +0,0 @@ -cachedb_dynamodb Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Functionalities - 1.1.2. Table Format and TTL Option - - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - 1.4.3. Deploying DynamoDB locally on your computer - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - - 1.6. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Use Dynamodb servers - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cachedb system designed - to work with Amazon DynamoDB. It uses the AWS SDK library for - C++ to connect to a DynamoDB instance. It leverages the - Key-Value interface exported from the core. - - https://aws.amazon.com/pm/dynamodb/ - -1.1.1. Functionalities - - * set - sets a key in DynamoDB using the cachedb_store - function - * get - queries a key from DynamoDB using the cachedb_fetch - function - * remove - removes a key from DynamoDB using the - cachedb_remove function - * get_counter - queries a key with a numerical value from - DynamoDB using the cachedb_counter_fetch function - * add - increments the value of a specific item with a given - value using the cachedb_add function - * sub - decrements the value of a specific item with a given - value using the cachedb_sub function - - The following are internally used by OpenSIPS: - * map_get - * map_set - * map_remove - -1.1.2. Table Format and TTL Option - - The tables used with DynamoDB must adhere to a specific format. - Below is an example of creating a table: - -aws dynamodb create-table \ ---table-name TableName \ ---attribute-definitions \ - AttributeName=KeyName,AttributeType=S \ ---key-schema \ - AttributeName=KeyName,KeyType=HASH \ ---provisioned-throughput \ - ReadCapacityUnits=5,WriteCapacityUnits=5 \ ---table-class STANDARD - - If you create the table using the above command, then you have - to specify the key in the cachedb_url: - modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb://localhost:8000/TableName?key=KeyName;val=ValName")" - - For additional examples of how cachedb_url should be formatted, - refer to the cachedb_url (string) section. - - To enable TTL (Time to Live) for the table, which can be used - with operations like set, add, and subtract, you can update the - table with the TTL option: - -aws dynamodb update-time-to-live --table-name TableName --time-to-live-s -pecification -"Enabled=true, AttributeName=ttl" - - For additional information about the table format and TTL - options, follow these links: - - Creating a Table - - Time to Live (TTL) - -1.2. Advantages - - * scalable and fully managed NoSQL database service provided - by AWS - * integrated with other AWS services, providing robust - security and scalability features - * high availability and durability due to data replication - across multiple AWS Availability Zones - * serverless architecture, reducing operational overhead - * offers single-digit response times, with DynamoDB - Accelerator (DAX) for even lower latencies - -1.3. Limitations - - * relies heavily on indexes; without them, querying involves - costly full table scans - * does not support table joins, limiting complex queries - involving multiple tables - * item size limit:each item has a size limit of 400KB, which - cannot be increased. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - There is no need to load any module before this module. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * AWS SDK for C++: - By following these steps, you'll have the AWS SDK for C++ - installed and configured on your Linux system, allowing you - to integrate with DynamoDB: AWS SDK for C++ Installation - Guide - Additional instructions for installation can be found at: - AWS SDK for C++ GitHub Repository - -1.4.3. Deploying DynamoDB locally on your computer - - For testing purposes, you can run a DynamoDB locally. To - achieve this, you should follow these steps in order to deploy - dynamodb locally. - - Don't forget to always run the server using this command: java - -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar - -sharedDb in the directory where you extracted - DynamoDBLocal.jar. - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The URLs of the server groups that OpenSIPS will connect to in - order to use, from script, the cache_store(), cache_fetch(), - etc. operations. It may be set more than once. The prefix part - of the URL will be the identifier that will be used from the - script. - - There are some default parameters that can appear in the URL: - * region - specifies the AWS region where the DynamoDB table - is located - * key - specifies the table's Key column; default value is - "opensipskey" - * val - specifies the table's Value column on which cache - operations such as cache_store, cache_fetch, etc., will be - performed; default value is "opensipsval" - - Syntax for cachedb_url - * when using a previously created table (you have to specify - the key and value): - + host and port - "dynamodb://id_host:id_port/tableName?key=key1;val=val - 1" - + region - "dynamodb:///tableName?region=regionName;key=key2;val= - val2" - * when using the default key and value: - + host and port - "dynamodb://id_host:id_port/tableName" - + region - "dynamodb:///tableName?region=regionName" - - Example 1.1. Set cachedb_url parameter -... - -# single-instance URLs -modparam("cachedb_dynamodb", "cachedb_url", "dynamodb://localhost:8000/t -able1") -modparam("cachedb_dynamodb", "cachedb_url", "dynamodb:///table2?region=c -entral-1") - - -# multi-instance URL (will perform circular failover on each query) -modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb://localhost:8000/table1?key=Key;val=Val") -modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb:///table2?region=central-1;key=Key;val=Val") - - -... - - Example 1.2. Use Dynamodb servers -... - -cache_store("dynamodb", "call1", "10"); -cache_store("dynamodb", "call2", "25", 150) // expires = 150s -optional -cache_fetch("dynamodb", "call1", $var(total)); -cache_remove("dynamodb", "call1"); - - -cache_store("dynamodb", "counter1", "200"); -cache_sub("dynamodb", "counter1", 4, 1000); // expires = 1000s -mandator -y parameter -cache_add("dynamodb", "call2", 5, 0) // -this update will not expire -m -andatory parameter -cache_remove("dynamodb", "counter1"); - -... - -1.6. Exported Functions - - The module does not export functions to be used in - configuration script. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Alexandra Titoc 68 17 3573 1192 - 2. Razvan Crainea (@razvancrainea) 6 2 0 213 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Jul 2024 - Sep 2024 - 2. Razvan Crainea (@razvancrainea) Aug 2024 - Aug 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Alexandra - Titoc. - - Documentation Copyrights: - - Copyright © 2024 www.opensips-solutions.com diff --git a/modules/cachedb_dynamodb/README.md b/modules/cachedb_dynamodb/README.md new file mode 100644 index 00000000000..33d42c625ac --- /dev/null +++ b/modules/cachedb_dynamodb/README.md @@ -0,0 +1,227 @@ +--- +title: "cachedb_dynamodb Module" +description: "This module is an implementation of a cachedb system designed to work with Amazon DynamoDB." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cachedb system designed to work with +Amazon DynamoDB. It uses the AWS SDK library for C++ to connect to a DynamoDB instance. +It leverages the Key-Value interface exported from the core. +[https://aws.amazon.com/pm/dynamodb/](https://aws.amazon.com/pm/dynamodb/) + + +#### Functionalities + + +- *set* - sets a key in DynamoDB using the *cachedb_store* function +- *get* - queries a key from DynamoDB using the *cachedb_fetch* function +- *remove* - removes a key from DynamoDB using the +*cachedb_remove* function +- *get_counter* - queries a key with a numerical value +from DynamoDB using the *cachedb_counter_fetch* function +- *add* - increments the value of a specific item with a given value +using the *cachedb_add* function +- *sub* - decrements the value of a specific item with a given value +using the *cachedb_sub* function + + +The following are internally used by OpenSIPS: + + +- *map_get* +- *map_set* +- *map_remove* + + +#### Table Format and TTL Option + + +The tables used with DynamoDB must adhere to a specific format. +Below is an example of creating a table: + + +```bash +aws dynamodb create-table \ +--table-name TableName \ +--attribute-definitions \ + AttributeName=KeyName,AttributeType=S \ +--key-schema \ + AttributeName=KeyName,KeyType=HASH \ +--provisioned-throughput \ + ReadCapacityUnits=5,WriteCapacityUnits=5 \ +--table-class STANDARD + +``` + + +If you create the table using the above command, then you have to specify the key in the +cachedb_url: *modparam("cachedb_dynamodb", "cachedb_url", +"dynamodb://localhost:8000/TableName?key=KeyName;val=ValName")"* + + +For additional examples of how cachedb_url should be formatted, refer to the +[cachedb_url (string)](#param_cachedb_url) section. + + +To enable TTL (Time to Live) for the table, which can be used with operations like set, +add, and subtract, you can update the table with the TTL option: + + +```c +aws dynamodb update-time-to-live --table-name TableName --time-to-live-specification +"Enabled=true, AttributeName=ttl" + +``` + + +For additional information about the table format and TTL options, follow these links: + + +[Creating a Table](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html) + + +[Time to Live (TTL)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/time-to-live-ttl-how-to.html) + + +### Advantages + + +- *scalable and fully managed NoSQL database service provided by AWS* +- *integrated with other AWS services, providing robust security +and scalability features* +- *high availability and durability due to data replication across +multiple AWS Availability Zones* +- *serverless architecture, reducing operational overhead* +- *offers single-digit response times, with DynamoDB Accelerator (DAX) +for even lower latencies* + + +### Limitations + + +- *relies heavily on indexes; without them, querying involves costly full table scans* +- *does not support table joins, limiting complex queries involving multiple tables* +- *item size limit:each item has a size limit of 400KB, which cannot be increased.* + + +### Dependencies + + +#### OpenSIPS Modules + + +There is no need to load any module before this module. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *AWS SDK for C++:* +By following these steps, you'll have the AWS SDK for C++ installed and +configured on your Linux system, allowing you to integrate with DynamoDB: +[AWS SDK for C++ Installation Guide](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/setup-linux.html) +Additional instructions for installation can be found at: +[AWS SDK for C++ GitHub Repository](https://github.com/aws/aws-sdk-cpp) + + +#### Deploying DynamoDB locally on your computer + + +For testing purposes, you can run a DynamoDB locally. To achieve this, you should follow +[these](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html) steps in order to deploy dynamodb locally. + + +Don't forget to always run the server using this command: + +`java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb` +in the directory where you extracted *DynamoDBLocal.jar*. + + +### Exported Parameters + + +#### cachedb_url (string) + + +The URLs of the server groups that OpenSIPS will connect to in order +to use, from script, the cache_store(), cache_fetch(), etc. operations. +It may be set more than once. The prefix part of the URL will be +the identifier that will be used from the script. + + +There are some default parameters that can appear in the URL: + + +- *region* - specifies the AWS region where the DynamoDB table is located +- *key* - specifies the table's Key column; default value is *"opensipskey"* +- *val* - specifies the table's Value column on which cache operations such as cache_store, cache_fetch, etc., will be performed; +default value is *"opensipsval"* + + +Syntax for *cachedb_url* + + +- when using a previously created table (you have to specify the key and value): + + - host and port +*"dynamodb://id_host:id_port/tableName?key=key1;val=val1"* + - region +*"dynamodb:///tableName?region=regionName;key=key2;val=val2"* +- when using the default key and value: + + - host and port +*"dynamodb://id_host:id_port/tableName"* + - region +*"dynamodb:///tableName?region=regionName"* + + +```opensips title="Set cachedb_url parameter" +... + +# single-instance URLs +modparam("cachedb_dynamodb", "cachedb_url", "dynamodb://localhost:8000/table1") +modparam("cachedb_dynamodb", "cachedb_url", "dynamodb:///table2?region=central-1") + + +# multi-instance URL (will perform circular +``` + + +```opensips title="Use Dynamodb servers" +... + +cache_store("dynamodb", "call1", "10"); +cache_store("dynamodb", "call2", "25", 150) // expires = 150s -optional +cache_fetch("dynamodb", "call1", $var(total)); +cache_remove("dynamodb", "call1"); + + +cache_store("dynamodb", "counter1", "200"); +cache_sub("dynamodb", "counter1", 4, 1000); // expires = 1000s -mandatory parameter +cache_add("dynamodb", "call2", 5, 0) // -this update will not expire -mandatory parameter +cache_remove("dynamodb", "counter1"); + +... + +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_dynamodb/cachedb_dynamodb_dbase.c b/modules/cachedb_dynamodb/cachedb_dynamodb_dbase.c index 5479a79d598..c1b9df2dbb8 100644 --- a/modules/cachedb_dynamodb/cachedb_dynamodb_dbase.c +++ b/modules/cachedb_dynamodb/cachedb_dynamodb_dbase.c @@ -19,6 +19,8 @@ * */ +#include + #include "cachedb_dynamodb_dbase.h" @@ -304,7 +306,7 @@ int dynamodb_map_set(cachedb_con *connection, const str *key, const str *keyset, LM_ERR("No more pkg mem\n"); return -1; } - sprintf(attribute_value_int, "%ld", pair->val.val.i64); + sprintf(attribute_value_int, "%" PRId64, pair->val.val.i64); init_str(&attribute_value, attribute_value_int); break; diff --git a/modules/cachedb_dynamodb/doc/cachedb_dynamodb.xml b/modules/cachedb_dynamodb/doc/cachedb_dynamodb.xml deleted file mode 100644 index 61ba2ccd26d..00000000000 --- a/modules/cachedb_dynamodb/doc/cachedb_dynamodb.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - cachedb_dynamodb Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 &osipssol; - diff --git a/modules/cachedb_dynamodb/doc/cachedb_dynamodb_admin.xml b/modules/cachedb_dynamodb/doc/cachedb_dynamodb_admin.xml deleted file mode 100644 index 9a1b959f21c..00000000000 --- a/modules/cachedb_dynamodb/doc/cachedb_dynamodb_admin.xml +++ /dev/null @@ -1,387 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cachedb system designed to work with - Amazon DynamoDB. It uses the AWS SDK library for C++ to connect to a DynamoDB instance. - It leverages the Key-Value interface exported from the core. - - - - - - - -
- Functionalities - - - - set - sets a key in DynamoDB using the cachedb_store function - - - - - get - queries a key from DynamoDB using the cachedb_fetch function - - - - - remove - removes a key from DynamoDB using the - cachedb_remove function - - - - - get_counter - queries a key with a numerical value - from DynamoDB using the cachedb_counter_fetch function - - - - - add - increments the value of a specific item with a given value - using the cachedb_add function - - - - - sub - decrements the value of a specific item with a given value - using the cachedb_sub function - - - - - - The following are internally used by OpenSIPS: - - - - - map_get - - - - - map_set - - - - - map_remove - - - -
- -
- Table Format and TTL Option - - The tables used with DynamoDB must adhere to a specific format. - Below is an example of creating a table: - - - -aws dynamodb create-table \ ---table-name TableName \ ---attribute-definitions \ - AttributeName=KeyName,AttributeType=S \ ---key-schema \ - AttributeName=KeyName,KeyType=HASH \ ---provisioned-throughput \ - ReadCapacityUnits=5,WriteCapacityUnits=5 \ ---table-class STANDARD - - - - - If you create the table using the above command, then you have to specify the key in the - cachedb_url: modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb://localhost:8000/TableName?key=KeyName;val=ValName")" - - - For additional examples of how cachedb_url should be formatted, refer to the - cachedb_url (string) section. - - - - To enable TTL (Time to Live) for the table, which can be used with operations like set, - add, and subtract, you can update the table with the TTL option: - - - -aws dynamodb update-time-to-live --table-name TableName --time-to-live-specification -"Enabled=true, AttributeName=ttl" - - - - For additional information about the table format and TTL options, follow these links: - - - Creating a Table - - - Time to Live (TTL) - -
- - -
- - -
- Advantages - - - - - scalable and fully managed NoSQL database service provided by AWS - - - - - - integrated with other AWS services, providing robust security - and scalability features - - - - - - high availability and durability due to data replication across - multiple AWS Availability Zones - - - - - - serverless architecture, reducing operational overhead - - - - - - offers single-digit response times, with DynamoDB Accelerator (DAX) - for even lower latencies - - - - - - - -
- -
- Limitations - - - - - - - relies heavily on indexes; without them, querying involves costly full table scans - - - - - - does not support table joins, limiting complex queries involving multiple tables - - - - - - item size limit:each item has a size limit of 400KB, which cannot be increased. - - - - - - -
- -
- Dependencies -
- &osips; Modules - - There is no need to load any module before this module. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - AWS SDK for C++: - - By following these steps, you'll have the AWS SDK for C++ installed and - configured on your Linux system, allowing you to integrate with DynamoDB: - AWS SDK for C++ Installation Guide - - - Additional instructions for installation can be found at: - AWS SDK for C++ GitHub Repository - - - - -
- -
- Deploying DynamoDB locally on your computer - - For testing purposes, you can run a DynamoDB locally. To achieve this, you should follow - - these steps in order to deploy dynamodb locally. - - - Don't forget to always run the server using this command: - - java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb - in the directory where you extracted DynamoDBLocal.jar. - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The URLs of the server groups that OpenSIPS will connect to in order - to use, from script, the cache_store(), cache_fetch(), etc. operations. - It may be set more than once. The prefix part of the URL will be - the identifier that will be used from the script. - - - - There are some default parameters that can appear in the URL: - - - - - - region - specifies the AWS region where the DynamoDB table is located - - - - - key - specifies the table's Key column; default value is "opensipskey" - - - - - val - specifies the table's Value column on which cache operations such as cache_store, cache_fetch, etc., will be performed; - default value is "opensipsval" - - - - - - - Syntax for cachedb_url - - - - - when using a previously created table (you have to specify the key and value): - - - - - host and port - "dynamodb://id_host:id_port/tableName?key=key1;val=val1" - - - - region - "dynamodb:///tableName?region=regionName;key=key2;val=val2" - - - - - - - when using the default key and value: - - - - host and port - "dynamodb://id_host:id_port/tableName" - - - - region - "dynamodb:///tableName?region=regionName" - - - - - - - - Set <varname>cachedb_url</varname> parameter - -... - -# single-instance URLs -modparam("cachedb_dynamodb", "cachedb_url", "dynamodb://localhost:8000/table1") -modparam("cachedb_dynamodb", "cachedb_url", "dynamodb:///table2?region=central-1") - - -# multi-instance URL (will perform circular failover on each query) -modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb://localhost:8000/table1?key=Key;val=Val") -modparam("cachedb_dynamodb", "cachedb_url", - "dynamodb:///table2?region=central-1;key=Key;val=Val") - - -... - - - - - Use Dynamodb servers - -... - -cache_store("dynamodb", "call1", "10"); -cache_store("dynamodb", "call2", "25", 150) // expires = 150s -optional -cache_fetch("dynamodb", "call1", $var(total)); -cache_remove("dynamodb", "call1"); - - -cache_store("dynamodb", "counter1", "200"); -cache_sub("dynamodb", "counter1", 4, 1000); // expires = 1000s -mandatory parameter -cache_add("dynamodb", "call2", 5, 0) // -this update will not expire -mandatory parameter -cache_remove("dynamodb", "counter1"); - -... - - -
- - -
- - -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- - -
- diff --git a/modules/cachedb_dynamodb/doc/contributors.xml b/modules/cachedb_dynamodb/doc/contributors.xml deleted file mode 100644 index 5260bf6957e..00000000000 --- a/modules/cachedb_dynamodb/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Alexandra Titoc - 68 - 17 - 3573 - 1192 - - - 2. - Razvan Crainea (@razvancrainea) - 6 - 2 - 0 - 213 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Jul 2024 - Sep 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2024 - Aug 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Alexandra Titoc. -
- -
diff --git a/modules/cachedb_local/README b/modules/cachedb_local/README deleted file mode 100644 index ee57e2924ec..00000000000 --- a/modules/cachedb_local/README +++ /dev/null @@ -1,410 +0,0 @@ -cachedb_local Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Clustering - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. cachedb_url (string) - 1.4.2. cache_collections (string) - 1.4.3. cache_clean_period (int) - 1.4.4. cluster_id (int) - 1.4.5. cluster_persistency (string) - 1.4.6. enable_restart_persistency (int) - - 1.5. Exported Functions - - 1.5.1. cache_remove_chunk([collection,] glob) - - 1.6. Exported MI Functions - - 1.6.1. cache_remove_chunk - 1.6.2. cache_fetch_chunk - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Set cache_collections parameter - 1.3. Set cache_clean_period parameter - 1.4. Setting the cluster_id parameter - 1.5. Set cluster_persistency parameter - 1.6. Set enable_restart_persistency parameter - 1.7. cache_remove_chunk usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a local cache system - designed as a hash table. It uses the Key-Value interface - exported by OpenSIPS core. Starting with version 2.3, the - module can have multiple hash tables, called collections. Each - url for cachedb_local module points to one collection. One - collection can be shared between multiple urls. - -1.2. Clustering - - Cachedb_local clustering is a mechanism used to mirror local - cache changes taking place in one OpenSIPS instance to one or - multiple other instances without the need of third party - dependencies. The process is simplified by using the clusterer - module which facilitates the management of a cluster of - OpenSIPS noeds and the sending of replication-related BIN - packets (binary-encoded, using proto_bin). This might be - usefull for implementing a hot stand-by system, where the - stand-by instance can take over without the need of filling the - cache by its own. - - The following cache operations will be distributet within the - cluster: - * cache_store - * cache_remove - * cache_add - * cache_sub - - In addition to the event-driven replication, an OpenSIPS - instance will first try to learn all the local cache - information from antoher node in the cluster at startup. The - data synchronization mechanism requires defining one of the - nodes in the cluster as a "seed" node. See the clusterer module - for details on how to do this and why is it needed. - - Note: You have to explicitly specify which collections you want - to replicate when you set cache_collections. - - Limitations: The clustering operations are not atomic and - constistency over the cluster nodes is not guaranteed. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * clusterer, if cluster_id is set. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. cachedb_url (string) - - URLs of local cache groups to be used used for the script and - MI cacheDB operations. The parameter can be set multiple times. - - One collection can belong to multiple URLs, but one URL can - have only one collection. Redefining an URL with the same - schema and group name will result in overwriting that URL. Each - collection used in URL definition must be defined using - cachedb_collection parameter. The collection shall be defined - as a normal database, at the end of the URL as in the examples. - In the script the collection shall be identified using the - schema and, if exists, the group name. - - “If no URL defined, the url with no group name and collection - "default" will be used.”. - - Example 1.1. Set cachedb_url parameter -... -### for this example, if no collection is defined, the default collectio -n named -### "default" shall be used -modparam("cachedb_local", "cachedb_url", "local://") -### this URL will use the collection named collection1; it will overwrit -e the -### previous url definition which was using the "default" collection -modparam("cachedb_local", "cachedb_url", "local:///collection1") -### this URL will use collection2; it will be referenced from the script -### with "local:group2" -modparam("cachedb_local", "cachedb_url", "local:group2:///collection2") - -## how to use the URLs from the script -## as defined above, this call will use collection1 -cache_store("local", ...) -## as defined above, this call will use collection2 -cache_store("local:group2", ...) -... - -1.4.2. cache_collections (string) - - Using this parameter, collections(hash tables) and their sizes - can be defined. Each collection definition must be separated - one from another using ';'. Default size for a hash is 512. The - size must be separated from the name of the collection using - '='. - - If clustering is enabled you have to specify which collections - you want to replicate with the /r suffix to the collection - name. - - The "default" collection always gets created, even when not - included in this list of collections. - - Example 1.2. Set cache_collections parameter -... -## creating collection1 with default size (512) and collection2 with cus -tom size -## 2^5 (32); we also changed the size of the default collection, which w -ould have been -## created anyway from 2^9 - 512 (default value) to 2^4 - 16 -## also, collection1 and collection2 will be replicated in the cluster, -while the -## default collection will be local to this node -modparam("cachedb_local", "cache_collections", "collection1/r; collectio -n2/r = 5; default = 4") -... - -1.4.3. cache_clean_period (int) - - The time interval in seconds at which to go through all the - records and delete the expired ones. - - Default value is “600 (10 minutes)”. - - Example 1.3. Set cache_clean_period parameter -... -modparam("cachedb_local", "cache_clean_period", 1200) -... - -1.4.4. cluster_id (int) - - Specifies the cluster ID which this instance will send to and - receive cache data. - - This OpenSIPS cluster exposes the "cachedb-local-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - Default value is 0 (replication disabled). - - Example 1.4. Setting the cluster_id parameter -... -modparam("cachedb_local", "cluster_id", 1) -... - -1.4.5. cluster_persistency (string) - - Controls the behavior of the OpenSIPS local cachedb clustering - following a restart. - - This parameter may take the following values: - * "none" - no explicit data synchronization following a - restart. The node starts empty. - * "sync-from-cluster" - enable cluster-based restart - persistency. Following a restart, an OpenSIPS cluster node - will search for a healthy "donor" node from which to mirror - the entire user location dataset via direct cluster sync - (TCP-based, binary-encoded data transfer). This will - require the configuration of one or multiple "seed" nodes - in the cluster. - - Default value is "sync-from-cluster". - - Example 1.5. Set cluster_persistency parameter -... -modparam("cachedb_local", "cluster_persistency", "sync-from-cluster") -... - -1.4.6. enable_restart_persistency (int) - - Enable restart persistency using the persistent memory - mechanism. Data is stored in a cache file that is mapped - against OpenSIPS memory. - - Note that you have to keep the same collection definitions from - a previous run in order to use the cached data for the - respective collections. - - If cluster persistency is enabled as well, keys loaded from the - persistent cache will be discarded if they are not received in - the cluster sync data. - - Default value is “0 (disabled)”. - - Example 1.6. Set enable_restart_persistency parameter -... -modparam("cachedb_local", "enable_restart_persistency", yes) -... - -1.5. Exported Functions - -1.5.1. cache_remove_chunk([collection,] glob) - - Remove all keys from local cache that match the glob pattern - corresponding to a certain collection or the 'default' - collection if none defined. Keep in mind that collection name - is different than group name, which identifies the engine in - cachedb operations. - - Parameters: - * collection (string, optional) - * glob (string) - - This function can be used from all routes - - Example 1.7. cache_remove_chunk usage - ... - cache_remove_chunk("myinfo_*"); - cache_remove_chunk("collection1", "myinfo_*"); - ... - -1.6. Exported MI Functions - -1.6.1. cache_remove_chunk - - Removes all local cache entries that match the provided glob - param. - - Parameters : - * glob - keys that match glob will be removed - * collection(optional) - collection from which the keys shall - be removed; if no collection set, the default collection - will be used; - - MI FIFO Command Format: -opensips-cli -x mi cache_remove_chunk "keyprefix*" collection - -1.6.2. cache_fetch_chunk - - Fetches all local cache entries that match the provided glob - param. - - Parameters : - * glob - keys that match glob will be returned - * collection(optional) - collection from which the keys shall - be retrieved; if no collection set, the default collection - will be used; - - MI FIFO Command Format: -opensips-cli -x mi cache_fetch_chunk "keyprefix*" collection -{ - "keys": [ - { - "name": "keyprefix_1", - "value": "key 1 data here" - }, - { - "name": "keyprefix_2", - "value": "key 2 data here" - } - ] -} - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with old cache_table_size parameter? - - The parameter was removed because it was redundant. Since the - addition of collections, the old hash now belongs to the - default collection. This collection is created every time and - it has a default size of 512. The size can be changed by - setting the default collection size using cache_collections - paramter. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 35 11 1335 693 - 2. Vlad Patrascu (@rvlad-patrascu) 25 16 509 226 - 3. Liviu Chircu (@liviuchircu) 24 18 165 191 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 16 14 46 50 - 5. Anca Vamanu 13 5 739 54 - 6. Andrei Dragus 9 4 182 181 - 7. Fabian Gast (@fgast) 9 3 517 48 - 8. Ionut Ionita (@ionutrazvanionita) 9 3 513 55 - 9. Razvan Crainea (@razvancrainea) 7 5 8 6 - 10. Maksym Sobolyev (@sobomax) 5 3 9 10 - - All remaining contributors: Peter Lemenkov (@lemenkov), Dusan - Klinec (@ph4r05), Ryan Bullock (@rrb3942), Julián Moreno - Patiño, Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Vlad Paiu (@vladpaiu) Oct 2011 - Feb 2024 - 2. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 3. Vlad Patrascu (@rvlad-patrascu) Jan 2017 - Oct 2022 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 5. Zero King (@l2dy) Mar 2020 - Mar 2020 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 7. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 8. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2009 - Apr 2019 - 9. Fabian Gast (@fgast) Dec 2018 - Dec 2018 - 10. Ionut Ionita (@ionutrazvanionita) Jan 2017 - Jan 2017 - - All remaining contributors: Julián Moreno Patiño, Dusan Klinec - (@ph4r05), Ryan Bullock (@rrb3942), Andrei Dragus, Anca Vamanu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu - (@vladpaiu), Vlad Patrascu (@rvlad-patrascu), Zero King - (@l2dy), Bogdan-Andrei Iancu (@bogdan-iancu), Fabian Gast - (@fgast), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), Andrei Dragus, Anca Vamanu. - - Documentation Copyrights: - - Copyright © 2009 Anca-Maria Vamanu diff --git a/modules/cachedb_local/README.md b/modules/cachedb_local/README.md new file mode 100644 index 00000000000..6d2ad73f38f --- /dev/null +++ b/modules/cachedb_local/README.md @@ -0,0 +1,362 @@ +--- +title: "cachedb_local Module" +description: "This module is an implementation of a local cache system designed as a hash table." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a local cache system designed as +a hash table. It uses the Key-Value interface exported by OpenSIPS core. +Starting with version 2.3, the module can have multiple hash tables, +called collections. Each url for cachedb_local module points to one +collection. One collection can be shared between multiple urls. + + +### Clustering + + +Cachedb_local clustering is a mechanism used to mirror local cache changes +taking place in one OpenSIPS instance to one or multiple other instances without +the need of third party dependencies. +The process is simplified by using the clusterer module which facilitates the +management of a cluster of OpenSIPS noeds and the sending of replication-related +BIN packets (binary-encoded, using proto_bin). This might be usefull for implementing +a hot stand-by system, where the stand-by instance can take over without the need +of filling the cache by its own. + + +The following cache operations will be distributet within the cluster: + + +- cache_store +- cache_remove +- cache_add +- cache_sub + + +In addition to the event-driven replication, an OpenSIPS instance will first +try to learn all the local cache information from antoher node in the cluster at startup. +The data synchronization mechanism requires defining one of the nodes in the cluster +as a "**seed**" node. +See the [clusterer](../clusterer#capabilities) +module for details on how to do this and why is it needed. + + +*Note:* You have to explicitly specify which collections +you want to replicate when you set [cache collections](#param_cache_collections). + + +**Limitations:** The clustering operations are not atomic +and constistency over the cluster nodes is not guaranteed. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *clusterer, if [cluster id](#param_cluster_id) +is set.* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### cachedb_url (string) + + +URLs of local cache groups to be used used for the script and MI cacheDB +operations. The parameter can be set multiple times. + + +One collection can belong to multiple URLs, but one URL can have only one collection. +Redefining an URL with the same schema and group name will result in overwriting +that URL. Each collection used in URL definition must be defined using +*cachedb_collection* parameter. The collection shall be defined +as a normal database, at the end of the URL as in the examples. In the script the +collection shall be identified using the schema and, if exists, the group name. + + +*"If no URL defined, the url with no group name and collection "default" +will be used.".* + + +```opensips title="Set cachedb_url parameter" +... +### for this example, if no collection is defined, the default collection named +### "default" shall be used +modparam("cachedb_local", "cachedb_url", "local://") +### this URL will use the collection named collection1; it will overwrite the +### previous url definition which was using the "default" collection +modparam("cachedb_local", "cachedb_url", "local:///collection1") +### this URL will use collection2; it will be referenced from the script +### with "local:group2" +modparam("cachedb_local", "cachedb_url", "local:group2:///collection2") + +## how to use the URLs from the script +## as defined above, this call will use collection1 +cache_store("local", ...) +## as defined above, this call will use collection2 +cache_store("local:group2", ...) +... + +``` + + +#### cache_collections (string) + + +Using this parameter, collections(hash tables) and their sizes can be defined. Each +collection definition must be separated one from another using ';'. Default size +for a hash is 512. The size must be separated from the name of the collection using +'='. + + +If clustering is enabled you have to specify which collections you want to replicate +with the */r* suffix to the collection name. + + +The *"default"* collection always gets created, even when +not included in this list of collections. + + +```opensips title="Set cache_collections parameter" +... +## creating collection1 with default size (512) and collection2 with custom size +## 2^5 (32); we also changed the size of the default collection, which would have been +## created anyway from 2^9 - 512 (default value) to 2^4 - 16 +## also, collection1 and collection2 will be replicated in the cluster, while the +## default collection will be local to this node +modparam("cachedb_local", "cache_collections", "collection1/r; collection2/r = 5; default = 4") +... + +``` + + +#### cache_clean_period (int) + + +The time interval in seconds at which to go through all the +records and delete the expired ones. + + +*Default value is "600 (10 minutes)".* + + +```opensips title="Set cache_clean_period parameter" +... +modparam("cachedb_local", "cache_clean_period", 1200) +... + +``` + + +#### cluster_id (int) + + +Specifies the cluster ID which this instance will send to and receive +cache data. + + +This OpenSIPS cluster exposes the **"cachedb-local-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +*Default value is 0 (replication disabled).* + + +```opensips title="Setting the cluster_id parameter" +... +modparam("cachedb_local", "cluster_id", 1) +... + +``` + + +#### cluster_persistency (string) + + +Controls the behavior of the OpenSIPS local cachedb clustering following a restart. + + +This parameter may take the following values: + + +- *"none"* - no explicit data +synchronization following a restart. The node starts empty. +- *"sync-from-cluster"* - enable +cluster-based restart persistency. Following a restart, +an OpenSIPS cluster node will search for a healthy "donor" node +from which to mirror the entire user location dataset via +direct cluster sync (TCP-based, binary-encoded data transfer). +This will require the configuration of one or multiple "seed" +nodes in the cluster. + + +*Default value is "sync-from-cluster".* + + +```opensips title="Set cluster_persistency parameter" +... +modparam("cachedb_local", "cluster_persistency", "sync-from-cluster") +... + +``` + + +#### enable_restart_persistency (int) + + +Enable restart persistency using the persistent memory mechanism. Data is +stored in a cache file that is mapped against OpenSIPS memory. + + +Note that you have to keep the same collection definitions from a previous +run in order to use the cached data for the respective collections. + + +If cluster persistency is enabled as well, keys loaded from the persistent +cache will be discarded if they are not received in the cluster sync data. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set enable_restart_persistency parameter" +... +modparam("cachedb_local", "enable_restart_persistency", yes) +... +``` + + +### Exported Functions + + +#### cache_remove_chunk([collection,] glob) + + +Remove all keys from local cache that match the *glob* pattern +corresponding to a certain *collection* or the 'default' collection +if none defined. Keep in mind that collection name is different than group name, +which identifies the engine in cachedb operations. + + +Parameters: + + +- *collection* (string, optional) +- *glob* (string) + + +This function can be used from all routes + + +```opensips title="cache_remove_chunk usage" + ... + cache_remove_chunk("myinfo_*"); + cache_remove_chunk("collection1", "myinfo_*"); + ... + +``` + + +### Exported MI Functions + + +#### cache_remove_chunk + + +Removes all local cache entries that match the provided glob param. + + +Parameters : + + +- *glob* - keys that match glob will be removed +- *collection(optional)* - collection from which the keys shall +be removed; if no collection set, the default collection will be used; + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi cache_remove_chunk "keyprefix*" collection + +``` + + +#### cache_fetch_chunk + + +Fetches all local cache entries that match the provided glob param. + + +Parameters : + + +- *glob* - keys that match glob will be returned +- *collection(optional)* - collection from which the keys shall +be retrieved; if no collection set, the default collection will be used; + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi cache_fetch_chunk "keyprefix*" collection +{ + "keys": [ + { + "name": "keyprefix_1", + "value": "key 1 data here" + }, + { + "name": "keyprefix_2", + "value": "key 2 data here" + } + ] +} + +``` + + +## Frequently Asked Questions + + +**Q: What happened with old cache_table_size parameter?** + + +The parameter was removed because it was redundant. Since the +addition of collections, the old hash now belongs to the +default collection. This collection is created every time and +it has a default size of 512. The size can be changed by +setting the default collection size using cache_collections paramter. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_local/doc/cachedb_local.xml b/modules/cachedb_local/doc/cachedb_local.xml deleted file mode 100644 index 9f9b15e6c77..00000000000 --- a/modules/cachedb_local/doc/cachedb_local.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - cachedb_local Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 Anca-Maria Vamanu - - - diff --git a/modules/cachedb_local/doc/cachedb_local_admin.xml b/modules/cachedb_local/doc/cachedb_local_admin.xml deleted file mode 100644 index b235a03df2c..00000000000 --- a/modules/cachedb_local/doc/cachedb_local_admin.xml +++ /dev/null @@ -1,385 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a local cache system designed as - a hash table. It uses the Key-Value interface exported by OpenSIPS core. - Starting with version 2.3, the module can have multiple hash tables, - called collections. Each url for cachedb_local module points to one - collection. One collection can be shared between multiple urls. - - - -
-
- Clustering - - Cachedb_local clustering is a mechanism used to mirror local cache changes - taking place in one OpenSIPS instance to one or multiple other instances without - the need of third party dependencies. - The process is simplified by using the clusterer module which facilitates the - management of a cluster of OpenSIPS noeds and the sending of replication-related - BIN packets (binary-encoded, using proto_bin). This might be usefull for implementing - a hot stand-by system, where the stand-by instance can take over without the need - of filling the cache by its own. - - - The following cache operations will be distributet within the cluster: - - cache_store - cache_remove - cache_add - cache_sub - - - - In addition to the event-driven replication, an OpenSIPS instance will first - try to learn all the local cache information from antoher node in the cluster at startup. - The data synchronization mechanism requires defining one of the nodes in the cluster - as a "seed" node. - See the clusterer - module for details on how to do this and why is it needed. - - - Note: You have to explicitly specify which collections - you want to replicate when you set . - - - Limitations: The clustering operations are not atomic - and constistency over the cluster nodes is not guaranteed. - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - clusterer, if - is set. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - none - - - -
-
- -
- Exported Parameters - -
- <varname>cachedb_url</varname> (string) - - URLs of local cache groups to be used used for the script and MI cacheDB - operations. The parameter can be set multiple times. - - - One collection can belong to multiple URLs, but one URL can have only one collection. - Redefining an URL with the same schema and group name will result in overwriting - that URL. Each collection used in URL definition must be defined using - cachedb_collection parameter. The collection shall be defined - as a normal database, at the end of the URL as in the examples. In the script the - collection shall be identified using the schema and, if exists, the group name. - - - If no URL defined, the url with no group name and collection "default" - will be used.. - - - - Set <varname>cachedb_url</varname> parameter - -... -### for this example, if no collection is defined, the default collection named -### "default" shall be used -modparam("cachedb_local", "cachedb_url", "local://") -### this URL will use the collection named collection1; it will overwrite the -### previous url definition which was using the "default" collection -modparam("cachedb_local", "cachedb_url", "local:///collection1") -### this URL will use collection2; it will be referenced from the script -### with "local:group2" -modparam("cachedb_local", "cachedb_url", "local:group2:///collection2") - -## how to use the URLs from the script -## as defined above, this call will use collection1 -cache_store("local", ...) -## as defined above, this call will use collection2 -cache_store("local:group2", ...) -... - - -
- -
- <varname>cache_collections</varname> (string) - - Using this parameter, collections(hash tables) and their sizes can be defined. Each - collection definition must be separated one from another using ';'. Default size - for a hash is 512. The size must be separated from the name of the collection using - '='. - - - If clustering is enabled you have to specify which collections you want to replicate - with the /r suffix to the collection name. - - - The "default" collection always gets created, even when - not included in this list of collections. - - - Set <varname>cache_collections</varname> parameter - -... -## creating collection1 with default size (512) and collection2 with custom size -## 2^5 (32); we also changed the size of the default collection, which would have been -## created anyway from 2^9 - 512 (default value) to 2^4 - 16 -## also, collection1 and collection2 will be replicated in the cluster, while the -## default collection will be local to this node -modparam("cachedb_local", "cache_collections", "collection1/r; collection2/r = 5; default = 4") -... - - -
- -
- <varname>cache_clean_period</varname> (int) - - The time interval in seconds at which to go through all the - records and delete the expired ones. - - - Default value is 600 (10 minutes). - - - - Set <varname>cache_clean_period</varname> parameter - -... -modparam("cachedb_local", "cache_clean_period", 1200) -... - - -
- -
- <varname>cluster_id</varname> (int) - - Specifies the cluster ID which this instance will send to and receive - cache data. - - - &clusterer_sync_cap_para; - - - Default value is 0 (replication disabled). - - - Setting the <varname>cluster_id</varname> parameter - -... -modparam("cachedb_local", "cluster_id", 1) -... - - -
-
- <varname>cluster_persistency</varname> (string) - - Controls the behavior of the OpenSIPS local cachedb clustering following a restart. - - - This parameter may take the following values: - - - - "none" - no explicit data - synchronization following a restart. The node starts empty. - - - - "sync-from-cluster" - enable - cluster-based restart persistency. Following a restart, - an OpenSIPS cluster node will search for a healthy "donor" node - from which to mirror the entire user location dataset via - direct cluster sync (TCP-based, binary-encoded data transfer). - This will require the configuration of one or multiple "seed" - nodes in the cluster. - - - - - - Default value is - "sync-from-cluster". - - - - Set <varname>cluster_persistency</varname> parameter - -... -modparam("cachedb_local", "cluster_persistency", "sync-from-cluster") -... - - -
-
- <varname>enable_restart_persistency</varname> (int) - - Enable restart persistency using the persistent memory mechanism. Data is - stored in a cache file that is mapped against OpenSIPS memory. - - - Note that you have to keep the same collection definitions from a previous - run in order to use the cached data for the respective collections. - - - If cluster persistency is enabled as well, keys loaded from the persistent - cache will be discarded if they are not received in the cluster sync data. - - - Default value is 0 (disabled). - - - - Set <varname>enable_restart_persistency</varname> parameter - -... -modparam("cachedb_local", "enable_restart_persistency", yes) -... - - -
-
- -
- Exported Functions - -
- - <function moreinfo="none">cache_remove_chunk([collection,] glob)</function> - - - Remove all keys from local cache that match the glob pattern - corresponding to a certain collection or the 'default' collection - if none defined. Keep in mind that collection name is different than group name, - which identifies the engine in cachedb operations. - - Parameters: - - - collection (string, optional) - - - glob (string) - - - - This function can be used from all routes - - - <function>cache_remove_chunk</function> usage - - ... - cache_remove_chunk("myinfo_*"); - cache_remove_chunk("collection1", "myinfo_*"); - ... - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">cache_remove_chunk</function> - - - Removes all local cache entries that match the provided glob param. - - - Parameters : - - - glob - keys that match glob will be removed - - - collection(optional) - collection from which the keys shall - be removed; if no collection set, the default collection will be used; - - - - MI FIFO Command Format: - - -opensips-cli -x mi cache_remove_chunk "keyprefix*" collection - -
- -
- - <function moreinfo="none">cache_fetch_chunk</function> - - - Fetches all local cache entries that match the provided glob param. - - - Parameters : - - - glob - keys that match glob will be returned - - - collection(optional) - collection from which the keys shall - be retrieved; if no collection set, the default collection will be used; - - - - MI FIFO Command Format: - - -opensips-cli -x mi cache_fetch_chunk "keyprefix*" collection -{ - "keys": [ - { - "name": "keyprefix_1", - "value": "key 1 data here" - }, - { - "name": "keyprefix_2", - "value": "key 2 data here" - } - ] -} - -
-
- -
diff --git a/modules/cachedb_local/doc/cachedb_local_faq.xml b/modules/cachedb_local/doc/cachedb_local_faq.xml deleted file mode 100644 index 03e1cea7529..00000000000 --- a/modules/cachedb_local/doc/cachedb_local_faq.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - &faqguide; - - - - - What happened with old cache_table_size parameter? - - - - The parameter was removed because it was redundant. Since the - addition of collections, the old hash now belongs to the - default collection. This collection is created every time and - it has a default size of 512. The size can be changed by - setting the default collection size using cache_collections paramter. - - - - - - - - diff --git a/modules/cachedb_local/doc/contributors.xml b/modules/cachedb_local/doc/contributors.xml deleted file mode 100644 index abe6e5d96df..00000000000 --- a/modules/cachedb_local/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 35 - 11 - 1335 - 693 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 25 - 16 - 509 - 226 - - - 3. - Liviu Chircu (@liviuchircu) - 24 - 18 - 165 - 191 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 16 - 14 - 46 - 50 - - - 5. - Anca Vamanu - 13 - 5 - 739 - 54 - - - 6. - Andrei Dragus - 9 - 4 - 182 - 181 - - - 7. - Fabian Gast (@fgast) - 9 - 3 - 517 - 48 - - - 8. - Ionut Ionita (@ionutrazvanionita) - 9 - 3 - 513 - 55 - - - 9. - Razvan Crainea (@razvancrainea) - 7 - 5 - 8 - 6 - - - 10. - Maksym Sobolyev (@sobomax) - 5 - 3 - 9 - 10 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), Ryan Bullock (@rrb3942), Julián Moreno Patiño, Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Vlad Paiu (@vladpaiu) - Oct 2011 - Feb 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - Jan 2017 - Oct 2022 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 5. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 7. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 8. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2009 - Apr 2019 - - - 9. - Fabian Gast (@fgast) - Dec 2018 - Dec 2018 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Jan 2017 - Jan 2017 - - - -
-All remaining contributors: Julián Moreno Patiño, Dusan Klinec (@ph4r05), Ryan Bullock (@rrb3942), Andrei Dragus, Anca Vamanu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu (@vladpaiu), Vlad Patrascu (@rvlad-patrascu), Zero King (@l2dy), Bogdan-Andrei Iancu (@bogdan-iancu), Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Andrei Dragus, Anca Vamanu. -
- -
diff --git a/modules/cachedb_memcached/README b/modules/cachedb_memcached/README deleted file mode 100644 index 5ebb98224c5..00000000000 --- a/modules/cachedb_memcached/README +++ /dev/null @@ -1,198 +0,0 @@ -cachedb_memcached Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - 1.5.2. exec_threshold (int) - 1.5.3. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Use memcached servers - 1.3. Set exec_threshold parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with a memcached server. It uses libmemcached client - library to connect to several memcached servers that store - data. It uses the Key-Value interface exported from the core. - -1.2. Advantages - - * memory costs are no longer on the server - * many servers may be used so the memory is virtually - unlimited - * the cache is persistent so a restart of the server will not - affect the cache - * memcached is an open-source project so it can be used to - exchange data with various other applications - * servers may be grouped together (e.g. for security purposes - : some can be inside a private network, some can be in a - public one) - -1.3. Limitations - - * keys (in key:value pairs) may not contain spaces or control - characters - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libmemcached: - libmemcached can be downloaded from: - http://tangent.org/552/libmemcached.html. Download the - archive, extract sources, run ./configure, make,sudo make - install. - ... - wget http://download.tangent.org/libmemcached-0.31.tar.gz - tar -xzvf libmemcached-0.31.tar.gz - cd libmemcached-0.31 - ./configure - make - sudo make install - ... - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The urls of the server groups that OpenSIPS will connect to in - order to use the from script cache_store,cache_fetch, etc - operations. It can be set more than one time. The prefix part - of the URL will be the identifier that will be used from the - script. - - Example 1.1. Set cachedb_url parameter -... -modparam("cachedb_memcached", "cachedb_url","memcached:group1://localhos -t:9999,127.0.0.1/"); -modparam("cachedb_memcached", "cachedb_url","memcached:y://random_url:88 -88/"); -... - - Example 1.2. Use memcached servers -... -cache_store("memcached:group1","key","$ru value"); -cache_fetch("memcached:y","key",$avp(10)); -cache_remove("memcached:group1","key"); -... - -1.5.2. exec_threshold (int) - - The maximum number of microseconds that a local cache query can - last. Anything above the threshold will trigger a warning - message to the log - - Default value is “0 ( unlimited - no warnings )”. - - Example 1.3. Set exec_threshold parameter -... -modparam("cachedb_memcached", "exec_threshold", 100000) -... - -1.5.3. Exported Functions - - The module does not export functions to be used in - configuration script. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 23 13 859 63 - 2. Razvan Crainea (@razvancrainea) 12 10 28 16 - 3. Liviu Chircu (@liviuchircu) 12 9 71 91 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 7 5 5 7 - 5. Maksym Sobolyev (@sobomax) 4 2 3 3 - 6. Julián Moreno Patiño 3 1 1 1 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - 8. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2013 - Mar 2020 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2019 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 7. Julián Moreno Patiño Feb 2016 - Feb 2016 - 8. Vlad Paiu (@vladpaiu) Oct 2011 - May 2014 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), - Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2009 Andrei Dragus - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/cachedb_memcached/README.md b/modules/cachedb_memcached/README.md new file mode 100644 index 00000000000..01811ac9c6f --- /dev/null +++ b/modules/cachedb_memcached/README.md @@ -0,0 +1,131 @@ +--- +title: "cachedb_memcached Module" +description: "This module is an implementation of a cache system designed to work with a memcached server." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with a +memcached server. It uses libmemcached client library to connect to several memcached +servers that store data. It uses the Key-Value interface exported from the core. + + +### Advantages + + +- *memory costs are no longer on the server* +- *many servers may be used so the memory +is virtually unlimited* +- *the cache is persistent so a restart +of the server will not affect the cache* +- *memcached is an open-source project so +it can be used to exchange data +with various other applications* +- *servers may be grouped together +(e.g. for security purposes : some can be +inside a private network, some can be in +a public one)* + + +### Limitations + + +- *keys (in key:value pairs) may not contain spaces or control characters* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libmemcached:* +libmemcached can be downloaded from: http://tangent.org/552/libmemcached.html. +Download the archive, extract sources, run ./configure, make, sudo make install. + +```bash +... +$ wget http://download.tangent.org/libmemcached-0.31.tar.gz +$ tar -xzvf libmemcached-0.31.tar.gz +$ cd libmemcached-0.31 +$ ./configure +$ make +$ sudo make install +... +``` + + +### Exported Parameters + + +#### cachedb_url (string) + + +The urls of the server groups that OpenSIPS will connect to in order +to use the from script cache_store,cache_fetch, etc operations. +It can be set more than one time. +The prefix part of the URL will be the identifier that will be used +from the script. + + +```opensips title="Set cachedb_url parameter" +... +modparam("cachedb_memcached", "cachedb_url","memcached:group1://localhost:9999,127.0.0.1/"); +modparam("cachedb_memcached", "cachedb_url","memcached:y://random_url:8888/"); +... + +``` + + +```opensips title="Use memcached servers" +... +cache_store("memcached:group1","key","$ru value"); +cache_fetch("memcached:y","key",$avp(10)); +cache_remove("memcached:group1","key"); +... + +``` + + +#### exec_threshold (int) + + +The maximum number of microseconds that a local cache query can last. +Anything above the threshold will trigger a warning message to the log + + +*Default value is "0 ( unlimited - no warnings )".* + + +```opensips title="Set exec_threshold parameter" +... +modparam("cachedb_memcached", "exec_threshold", 100000) +... + +``` + + +#### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_memcached/cachedb_memcached.c b/modules/cachedb_memcached/cachedb_memcached.c index 9efdfc29616..f2fd4e8eab5 100644 --- a/modules/cachedb_memcached/cachedb_memcached.c +++ b/modules/cachedb_memcached/cachedb_memcached.c @@ -400,6 +400,11 @@ memcached_con* memcached_new_connection(struct cachedb_id *id) con->ref = 1; con->memc = memcached_create(NULL); + if (!con->memc) { + LM_ERR("failed to create memcached handle\n"); + pkg_free(con); + return 0; + } memset(host_buff,0,MAX_HOSTPORT_SIZE); diff --git a/modules/cachedb_memcached/doc/cachedb_memcached.xml b/modules/cachedb_memcached/doc/cachedb_memcached.xml deleted file mode 100644 index 5499fd297d8..00000000000 --- a/modules/cachedb_memcached/doc/cachedb_memcached.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - cachedb_memcached Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 Andrei Dragus - ©right; 2009 &voicesystem; - - - - diff --git a/modules/cachedb_memcached/doc/cachedb_memcached_admin.xml b/modules/cachedb_memcached/doc/cachedb_memcached_admin.xml deleted file mode 100644 index cf52ce5fe6c..00000000000 --- a/modules/cachedb_memcached/doc/cachedb_memcached_admin.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with a - memcached server. It uses libmemcached client library to connect to several memcached - servers that store data. It uses the Key-Value interface exported from the core. - - - -
- - -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - many servers may be used so the memory - is virtually unlimited - - - - - - the cache is persistent so a restart - of the server will not affect the cache - - - - - - memcached is an open-source project so - it can be used to exchange data - with various other applications - - - - - - servers may be grouped together - (e.g. for security purposes : some can be - inside a private network, some can be in - a public one) - - - - - - - -
- -
- Limitations - - - - - - - - keys (in key:value pairs) may not contain spaces or control characters - - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - libmemcached: - - - - libmemcached can be downloaded from: http://tangent.org/552/libmemcached.html. - Download the archive, extract sources, run ./configure, make,sudo make install. - - - - - ... - wget http://download.tangent.org/libmemcached-0.31.tar.gz - tar -xzvf libmemcached-0.31.tar.gz - cd libmemcached-0.31 - ./configure - make - sudo make install - ... - - - - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The urls of the server groups that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - It can be set more than one time. - The prefix part of the URL will be the identifier that will be used - from the script. - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("cachedb_memcached", "cachedb_url","memcached:group1://localhost:9999,127.0.0.1/"); -modparam("cachedb_memcached", "cachedb_url","memcached:y://random_url:8888/"); -... - - - - - Use memcached servers - -... -cache_store("memcached:group1","key","$ru value"); -cache_fetch("memcached:y","key",$avp(10)); -cache_remove("memcached:group1","key"); -... - - -
- -
- <varname>exec_threshold</varname> (int) - - The maximum number of microseconds that a local cache query can last. - Anything above the threshold will trigger a warning message to the log - - - Default value is 0 ( unlimited - no warnings ). - - - - Set <varname>exec_threshold</varname> parameter - -... -modparam("cachedb_memcached", "exec_threshold", 100000) -... - - -
- -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- - -
- -
- diff --git a/modules/cachedb_memcached/doc/contributors.xml b/modules/cachedb_memcached/doc/contributors.xml deleted file mode 100644 index 0d4aba97c53..00000000000 --- a/modules/cachedb_memcached/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 23 - 13 - 859 - 63 - - - 2. - Razvan Crainea (@razvancrainea) - 12 - 10 - 28 - 16 - - - 3. - Liviu Chircu (@liviuchircu) - 12 - 9 - 71 - 91 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 5 - 5 - 7 - - - 5. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 3 - - - 6. - Julián Moreno Patiño - 3 - 1 - 1 - 1 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2013 - Mar 2020 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2019 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 7. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 8. - Vlad Paiu (@vladpaiu) - Oct 2011 - May 2014 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/cachedb_mongodb/Makefile b/modules/cachedb_mongodb/Makefile index cd1aafc0b0d..e361505a3cb 100644 --- a/modules/cachedb_mongodb/Makefile +++ b/modules/cachedb_mongodb/Makefile @@ -10,7 +10,9 @@ NAME=cachedb_mongodb.so include ../../lib/json/Makefile.json ifeq ($(CROSS_COMPILE),) MONGOC_BUILDER := $(shell \ - if pkg-config --exists libmongoc-1.0; then \ + if pkg-config --exists mongoc2; then \ + echo 'pkg-config mongoc2'; \ + elif pkg-config --exists libmongoc-1.0; then \ echo 'pkg-config libmongoc-1.0'; \ fi) endif diff --git a/modules/cachedb_mongodb/README b/modules/cachedb_mongodb/README deleted file mode 100644 index a52c31d3435..00000000000 --- a/modules/cachedb_mongodb/README +++ /dev/null @@ -1,328 +0,0 @@ -cachedb_mongodb Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - 1.5.2. exec_threshold (int) - 1.5.3. compat_mode_2.4 (int) - 1.5.4. compat_mode_3.0 (int) - - 1.6. Exported Functions - 1.7. Raw Query Syntax - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Runtime requirements for "cachedb_mongodb" - 1.2. Compilation requirements for "cachedb_mongodb" - 1.3. Set cachedb_url parameter - 1.4. Reference MongoDB connections - 1.5. Set exec_threshold parameter - 1.6. Setting the compat_mode_2.4 parameter - 1.7. Setting the compat_mode_3.0 parameter - 1.8. MongoDB Raw Insert - 1.9. MongoDB Raw Update - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with MongoDB servers. It implements the Key-Value - interface exposed by the OpenSIPS core. - - The underlying client library is compatible with any of the - following MongoDB server versions: 2.4, 2.6, 3.0, 3.2 and 3.4, - as stated in the MongoDB documentation. - -1.2. Advantages - - * memory costs are no longer on the server - * many servers can be used inside a cluster, so the memory is - virtually unlimited - * the cache is 100% persistent. A restart of OpenSIPS server - will not affect the DB. The MongoDB is also persistent so - it can also be restarted without loss of information. - * MongoDB is an open-source project so it can be used to - exchange data with various other applications - * By creating a MongoDB Cluster, multiple OpenSIPS instances - can easily share key-value information - * This module also implements the CacheDB Raw query - capability, thus you can run whatever query that the - MongoDB back-end supports, taking full advatange of it. - -1.3. Limitations - - * keys (in key:value pairs) may not contain spaces or control - characters - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - The following packages must be installed before running - OpenSIPS with this module loaded: - - Example 1.1. Runtime requirements for "cachedb_mongodb" -# Debian / Ubuntu -sudo apt-get install libjson-c2 libmongoc-1.0 - -# Red Hat / CentOS -sudo yum install json-c mongo-c-driver - - The following packages are required in order to compile this - module: - - Example 1.2. Compilation requirements for "cachedb_mongodb" -# Debian / Ubuntu -sudo apt-get install libjson-c-dev libmongoc-dev libbson-dev - -# Red Hat / CentOS -sudo yum install json-c-devel mongo-c-driver-devel - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The URLs of the server groups that OpenSIPS will connect to in - order to allow the cache_store(), cache_fetch(), etc. functions - to be used from the OpenSIPS script. It can be set more than - one time. The prefix part of the URL will be the identifier - that will be used from the script. - - The URL syntax is identical to the one used by MongoDB, - including connect string options. For more info, please refer - to the official MongoDB connect string documentation. - - Example 1.3. Set cachedb_url parameter -... -# Connect to a single mongod instance -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost:27017/opensipsDB.dialog") - -# Connect to a mongod replica set -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://10.0.0.10,10.0.0.11:27017/opensipsDB.dialog?replicaS -et=my-set") - -# Connect to a mongos instance (routes to a sharded cluster) -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost/opensipsDB.dialog") - -# Example of multiple connections: -# * to a main mongos, with failover to a backup mongos -# * to a single mongod -modparam("cachedb_mongodb", "cachedb_url", - "mongodb:cluster://localhost,10.0.0.10:27017/opensipsDB.dialog" -) -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost:27017/opensipsDB.userlocation") -... - - Example 1.4. Reference MongoDB connections -... -cache_store("mongodb", "key", "$ru value"); -cache_remove("mongodb:cluster", "key"); -cache_fetch("mongodb:instance1", "key", $avp(10)); -... - -1.5.2. exec_threshold (int) - - The maximum number of microseconds that a mongodb query can - last. Anything above the threshold will trigger a warning - message to the log - - Default value is “0 ( unlimited - no warnings )”. - - Example 1.5. Set exec_threshold parameter -... -modparam("cachedb_mongodb", "exec_threshold", 100000) -... - -1.5.3. compat_mode_2.4 (int) - - Switch the module into compatibility mode for MongoDB 2.4 - servers. Specifically, this allows "insert/update/delete" raw - queries to not fail, since they were introduced in MongoDB 2.6. - The module will interpret the raw query JSON, convert it to its - corresponding command and run it. - - Caveat: only the minimally required raw query options are - supported in this mode. - - Default value is “0 (disabled)”. - - Example 1.6. Setting the compat_mode_2.4 parameter -... -modparam("cachedb_mongodb", "compat_mode_2.4", 1) -... - -1.5.4. compat_mode_3.0 (int) - - Switch the module into compatibility mode for MongoDB 2.6/3.0 - servers. Specifically, this allows "find" raw queries to not - fail, since they were introduced in MongoDB 3.2. The module - will interpret the "find" raw query JSON, convert it to its - corresponding command and run it. - - Caveat: only the minimally required options for "find" raw - queries are supported in this mode. - - Default value is “0 (disabled)”. - - Example 1.7. Setting the compat_mode_3.0 parameter -... -modparam("cachedb_mongodb", "compat_mode_3.0", 1) -... - -1.6. Exported Functions - - The module does not export functions to be used in - configuration script. - -1.7. Raw Query Syntax - - The cachedb_mongodb module supports raw queries, thus taking - full advantage of the capabilities of the back-end, including - query-specific options such as read/write preference, timeouts, - filtering options, etc. - - The query syntax is identical to the mongo cli. Documentation - for it can be found on the MongoDB website. Query results are - returned as JSON documents, that one can further process in the - OpenSIPS script by using the JSON module. - - Some example raw queries: - - Example 1.8. MongoDB Raw Insert -... -cache_raw_query("mongodb:cluster", "{ \ - \"insert\": \"ip_blacklist\", \ - \"documents\": [{ \ - \"username\": \"$fU\", \ - \"ip\": \"$si\", \ - \"attempts\": 1 \ - }]}", - "$avp(out)"); -xlog("INSERT RAW QUERY returned $rc, output: '$avp(out)'\n"); -... - - Example 1.9. MongoDB Raw Update -... -cache_raw_query("mongodb:cluster", "{ \ - \"update\": \"ip_blacklist\", \ - \"updates\": [{ \ - \"q\": { \ - \"username\": \"$fU\", \ - \"ip\": \"$si\" \ - }, \ - \"u\": { \ - \"$$inc\": {\"attempts\": 1} \ - } \ - }]}", - "$avp(out)"); -xlog("UPDATE RAW QUERY returned $rc, output: '$avp(out)'\n"); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 154 83 2921 2759 - 2. Vlad Paiu (@vladpaiu) 37 10 3018 50 - 3. Razvan Crainea (@razvancrainea) 13 11 31 27 - 4. Ovidiu Sas (@ovidiusas) 10 8 92 16 - 5. Vlad Patrascu (@rvlad-patrascu) 6 4 96 11 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 5 7 - 7. Alexandra Titoc 4 2 10 3 - 8. Dan Pascu (@danpascu) 4 2 4 4 - 9. Alessio Garzi (@Ozzyboshi) 4 2 2 2 - 10. @jalung 3 1 97 56 - - All remaining contributors: tcresson, Maksym Sobolyev - (@sobomax), Julián Moreno Patiño, Ken Rice, Peter Lemenkov - (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Nov 2025 - 2. Ken Rice Sep 2025 - Sep 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2024 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2024 - 5. Alexandra Titoc Sep 2024 - Sep 2024 - 6. Vlad Paiu (@vladpaiu) Jan 2013 - Aug 2024 - 7. tcresson Oct 2023 - Oct 2023 - 8. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2021 - 10. Alessio Garzi (@Ozzyboshi) Nov 2019 - Dec 2019 - - All remaining contributors: Dan Pascu (@danpascu), Peter - Lemenkov (@lemenkov), @jalung, Julián Moreno Patiño, Ovidiu Sas - (@ovidiusas). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Julián Moreno Patiño, Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2013-2017 www.opensips-solutions.com diff --git a/modules/cachedb_mongodb/README.md b/modules/cachedb_mongodb/README.md new file mode 100644 index 00000000000..953f8edae88 --- /dev/null +++ b/modules/cachedb_mongodb/README.md @@ -0,0 +1,268 @@ +--- +title: "cachedb_mongodb Module" +description: "This module is an implementation of a cache system designed to work with MongoDB servers." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with +MongoDB servers. +It implements the Key-Value interface exposed by the OpenSIPS core. + + +The underlying client library is compatible with any of the following +MongoDB server versions: 2.4, 2.6, 3.0, 3.2 and 3.4, as stated in +[the MongoDB documentation](https://docs.mongodb.com/ecosystem/drivers/driver-compatibility-reference/). + + +### Advantages + + +- *memory costs are no longer on the server* +- *many servers can be used inside a cluster, so the memory +is virtually unlimited* +- *the cache is 100% persistent. A restart +of OpenSIPS server will not affect the DB. The MongoDB is also +persistent so it can also be restarted without loss of information.* +- *MongoDB is an open-source project so +it can be used to exchange data +with various other applications* +- *By creating a MongoDB Cluster, multiple OpenSIPS +instances can easily share key-value information* +- *This module also implements the CacheDB Raw query +capability, thus you can run whatever query that the MongoDB +back-end supports, taking full advatange of it.* + + +### Limitations + + +- *keys (in key:value pairs) may not contain spaces or control characters* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following packages must be installed before running OpenSIPS with this module loaded: + + +```bash title="Runtime requirements for 'cachedb_mongodb'" +# Debian / Ubuntu +sudo apt-get install libjson-c2 libmongoc-1.0 + +# Red Hat / CentOS +sudo yum install json-c mongo-c-driver + +``` + + +The following packages are required in order to compile this module: + + +```bash title="Compilation requirements for 'cachedb_mongodb'" +# Debian / Ubuntu +sudo apt-get install libjson-c-dev libmongoc-dev libbson-dev + +# Red Hat / CentOS +sudo yum install json-c-devel mongo-c-driver-devel + +``` + + +### Exported Parameters + + +#### cachedb_url (string) + + +The URLs of the server groups that OpenSIPS will connect to in order +to allow the cache_store(), cache_fetch(), etc. functions to be used +from the OpenSIPS script. It can be set more than one time. +The prefix part of the URL will be the identifier that will be used +from the script. + + +The URL syntax is identical to the one used by MongoDB, including +connect string options. For more info, +please refer to [the official MongoDB connect string documentation](https://docs.mongodb.com/manual/reference/connection-string/). + + +```opensips title="Set cachedb_url parameter" +... +# Connect to a single mongod instance +modparam("cachedb_mongodb", "cachedb_url", + "mongodb://localhost:27017/opensipsDB.dialog") + +# Connect to a mongod replica set +modparam("cachedb_mongodb", "cachedb_url", + "mongodb://10.0.0.10,10.0.0.11:27017/opensipsDB.dialog?replicaSet=my-set") + +# Connect to a mongos instance (routes to a sharded cluster) +modparam("cachedb_mongodb", "cachedb_url", + "mongodb://localhost/opensipsDB.dialog") + +# Example of multiple connections: +# * to a main mongos, with failover to a backup mongos +# * to a single mongod +modparam("cachedb_mongodb", "cachedb_url", + "mongodb:cluster://localhost,10.0.0.10:27017/opensipsDB.dialog") +modparam("cachedb_mongodb", "cachedb_url", + "mongodb://localhost:27017/opensipsDB.userlocation") +... +``` + + +```opensips title="Reference MongoDB connections" +... +cache_store("mongodb", "key", "$ru value"); +cache_remove("mongodb:cluster", "key"); +cache_fetch("mongodb:instance1", "key", $avp(10)); +... + +``` + + +#### exec_threshold (int) + + +The maximum number of microseconds that a mongodb query can last. +Anything above the threshold will trigger a warning message to the log + + +*Default value is "0 ( unlimited - no warnings )".* + + +```opensips title="Set exec_threshold parameter" +... +modparam("cachedb_mongodb", "exec_threshold", 100000) +... + +``` + + +#### compat_mode_2.4 (int) + + +Switch the module into compatibility mode for MongoDB 2.4 servers. +Specifically, this allows "insert/update/delete" raw queries to not fail, +since they were introduced in MongoDB 2.6. The module will interpret +the raw query JSON, convert it to its corresponding command and run it. + + +Caveat: only the minimally required raw query options are +supported in this mode. + + +*Default value is "0 (disabled)".* + + +```opensips title="Setting the compat_mode_2.4 parameter" +... +modparam("cachedb_mongodb", "compat_mode_2.4", 1) +... + +``` + + +#### compat_mode_3.0 (int) + + +Switch the module into compatibility mode for MongoDB 2.6/3.0 servers. +Specifically, this allows "find" raw queries to not fail, +since they were introduced in MongoDB 3.2. The module will interpret +the "find" raw query JSON, convert it to its corresponding command and run it. + + +Caveat: only the minimally required options for "find" raw queries are +supported in this mode. + + +*Default value is "0 (disabled)".* + + +```opensips title="Setting the compat_mode_3.0 parameter" +... +modparam("cachedb_mongodb", "compat_mode_3.0", 1) +... + +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### Raw Query Syntax + + +The cachedb_mongodb module supports raw queries, thus taking +full advantage of the capabilities of the back-end, including +query-specific options such as read/write preference, timeouts, +filtering options, etc. + + +The query syntax is identical to the mongo cli. Documentation for it +can be found on the +[MongoDB website](https://docs.mongodb.com/manual/reference/command/nav-crud/). Query results +are returned as JSON documents, that one can further process +in the OpenSIPS script by using the JSON module. + + +Some example raw queries: + + +```opensips title="MongoDB Raw Insert" +... +cache_raw_query("mongodb:cluster", "{ \ + \"insert\": \"ip_blacklist\", \ + \"documents\": [{ \ + \"username\": \"$fU\", \ + \"ip\": \"$si\", \ + \"attempts\": 1 \ + }]}", + "$avp(out)"); +xlog("INSERT RAW QUERY returned $rc, output: '$avp(out)'\n"); +... + +``` + + +```opensips title="MongoDB Raw Update" +... +cache_raw_query("mongodb:cluster", "{ \ + \"update\": \"ip_blacklist\", \ + \"updates\": [{ \ + \"q\": { \ + \"username\": \"$fU\", \ + \"ip\": \"$si\" \ + }, \ + \"u\": { \ + \"$$inc\": {\"attempts\": 1} \ + } \ + }]}", + "$avp(out)"); +xlog("UPDATE RAW QUERY returned $rc, output: '$avp(out)'\n"); +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_mongodb/cachedb_mongodb_dbase.c b/modules/cachedb_mongodb/cachedb_mongodb_dbase.c index 73e4db3b68a..5b5ab550a84 100644 --- a/modules/cachedb_mongodb/cachedb_mongodb_dbase.c +++ b/modules/cachedb_mongodb/cachedb_mongodb_dbase.c @@ -40,11 +40,15 @@ extern int compat_mode_24; #define HEX_OID_SIZE 25 char *hex_oid_id; +#if !MONGOC_CHECK_VERSION(1, 29, 0) +#define bson_as_legacy_extended_json bson_as_json +#endif + #define dbg_bson(_prepend_txt, __bson_ptr__) \ do { \ char *__bson_str__; \ if (is_printable(L_DBG)) { \ - __bson_str__ = bson_as_json(__bson_ptr__, NULL); \ + __bson_str__ = bson_as_legacy_extended_json(__bson_ptr__, NULL); \ LM_DBG("%s%s\n", _prepend_txt, __bson_str__); \ bson_free(__bson_str__); \ } \ @@ -1309,11 +1313,11 @@ int mongo_db_query_trans(cachedb_con *con, const str *table, const db_key_t *_k, namespace); if (is_printable(L_DBG)) { - strf = bson_as_json(filter, NULL); + strf = bson_as_legacy_extended_json(filter, NULL); #if MONGOC_CHECK_VERSION(1, 5, 0) - stro = bson_as_json(opts, NULL); + stro = bson_as_legacy_extended_json(opts, NULL); #else - stro = bson_as_json(fields, NULL); + stro = bson_as_legacy_extended_json(fields, NULL); #endif LM_DBG("query doc:\n%s\n%s\n", strf, stro); bson_free(strf); diff --git a/modules/cachedb_mongodb/cachedb_mongodb_dbase.h b/modules/cachedb_mongodb/cachedb_mongodb_dbase.h index cbe4855561a..0eaf766670e 100644 --- a/modules/cachedb_mongodb/cachedb_mongodb_dbase.h +++ b/modules/cachedb_mongodb/cachedb_mongodb_dbase.h @@ -27,8 +27,8 @@ #define MONGO_HAVE_STDINT 1 -#include -#include +#include +#include #include diff --git a/modules/cachedb_mongodb/cachedb_mongodb_json.h b/modules/cachedb_mongodb/cachedb_mongodb_json.h index f3bcbd9bbc0..85bbbab8dc9 100644 --- a/modules/cachedb_mongodb/cachedb_mongodb_json.h +++ b/modules/cachedb_mongodb/cachedb_mongodb_json.h @@ -23,7 +23,7 @@ #include "cachedb_mongodb_dbase.h" -#include +#include #include int json_to_bson(char *json,bson_t *bb); diff --git a/modules/cachedb_mongodb/doc/cachedb_mongodb.xml b/modules/cachedb_mongodb/doc/cachedb_mongodb.xml deleted file mode 100644 index 65d14c74da9..00000000000 --- a/modules/cachedb_mongodb/doc/cachedb_mongodb.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - cachedb_mongodb Module - &osipsname; - - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2013-2017 &osipssol; - diff --git a/modules/cachedb_mongodb/doc/cachedb_mongodb_admin.xml b/modules/cachedb_mongodb/doc/cachedb_mongodb_admin.xml deleted file mode 100644 index f7eef014912..00000000000 --- a/modules/cachedb_mongodb/doc/cachedb_mongodb_admin.xml +++ /dev/null @@ -1,344 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with - MongoDB servers. - It implements the Key-Value interface exposed by the OpenSIPS core. - - - The underlying client library is compatible with any of the following - MongoDB server versions: 2.4, 2.6, 3.0, 3.2 and 3.4, as stated in - - the MongoDB documentation. - - - -
- -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - many servers can be used inside a cluster, so the memory - is virtually unlimited - - - - - - the cache is 100% persistent. A restart - of OpenSIPS server will not affect the DB. The MongoDB is also - persistent so it can also be restarted without loss of information. - - - - - - MongoDB is an open-source project so - it can be used to exchange data - with various other applications - - - - - - By creating a MongoDB Cluster, multiple OpenSIPS - instances can easily share key-value information - - - - - - This module also implements the CacheDB Raw query - capability, thus you can run whatever query that the MongoDB - back-end supports, taking full advatange of it. - - - - - - - - -
- -
- Limitations - - - - - - - - keys (in key:value pairs) may not contain spaces or control characters - - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The following packages must be installed before running &osips; with this module loaded: - - - - Runtime requirements for "cachedb_mongodb" - -# Debian / Ubuntu -sudo apt-get install libjson-c2 libmongoc-1.0 - -# Red Hat / CentOS -sudo yum install json-c mongo-c-driver - - - - - - The following packages are required in order to compile this module: - - - - Compilation requirements for "cachedb_mongodb" - -# Debian / Ubuntu -sudo apt-get install libjson-c-dev libmongoc-dev libbson-dev - -# Red Hat / CentOS -sudo yum install json-c-devel mongo-c-driver-devel - - - - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The URLs of the server groups that OpenSIPS will connect to in order - to allow the cache_store(), cache_fetch(), etc. functions to be used - from the OpenSIPS script. It can be set more than one time. - The prefix part of the URL will be the identifier that will be used - from the script. - - - - The URL syntax is identical to the one used by MongoDB, including - connect string options. For more info, - please refer to - the official MongoDB connect string documentation. - - - - Set <varname>cachedb_url</varname> parameter - -... -# Connect to a single mongod instance -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost:27017/opensipsDB.dialog") - -# Connect to a mongod replica set -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://10.0.0.10,10.0.0.11:27017/opensipsDB.dialog?replicaSet=my-set") - -# Connect to a mongos instance (routes to a sharded cluster) -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost/opensipsDB.dialog") - -# Example of multiple connections: -# * to a main mongos, with failover to a backup mongos -# * to a single mongod -modparam("cachedb_mongodb", "cachedb_url", - "mongodb:cluster://localhost,10.0.0.10:27017/opensipsDB.dialog") -modparam("cachedb_mongodb", "cachedb_url", - "mongodb://localhost:27017/opensipsDB.userlocation") -... - - - - - Reference MongoDB connections - -... -cache_store("mongodb", "key", "$ru value"); -cache_remove("mongodb:cluster", "key"); -cache_fetch("mongodb:instance1", "key", $avp(10)); -... - - -
- -
- <varname>exec_threshold</varname> (int) - - The maximum number of microseconds that a mongodb query can last. - Anything above the threshold will trigger a warning message to the log - - - Default value is 0 ( unlimited - no warnings ). - - - - Set <varname>exec_threshold</varname> parameter - -... -modparam("cachedb_mongodb", "exec_threshold", 100000) -... - - -
- -
- <varname>compat_mode_2.4</varname> (int) - - Switch the module into compatibility mode for MongoDB 2.4 servers. - Specifically, this allows "insert/update/delete" raw queries to not fail, - since they were introduced in MongoDB 2.6. The module will interpret - the raw query JSON, convert it to its corresponding command and run it. - - - Caveat: only the minimally required raw query options are - supported in this mode. - - - Default value is 0 (disabled). - - - - Setting the <varname>compat_mode_2.4</varname> parameter - -... -modparam("cachedb_mongodb", "compat_mode_2.4", 1) -... - - -
- -
- <varname>compat_mode_3.0</varname> (int) - - Switch the module into compatibility mode for MongoDB 2.6/3.0 servers. - Specifically, this allows "find" raw queries to not fail, - since they were introduced in MongoDB 3.2. The module will interpret - the "find" raw query JSON, convert it to its corresponding command and run it. - - - Caveat: only the minimally required options for "find" raw queries are - supported in this mode. - - - Default value is 0 (disabled). - - - - Setting the <varname>compat_mode_3.0</varname> parameter - -... -modparam("cachedb_mongodb", "compat_mode_3.0", 1) -... - - -
- -
- -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- - -
- Raw Query Syntax - - The cachedb_mongodb module supports raw queries, thus taking - full advantage of the capabilities of the back-end, including - query-specific options such as read/write preference, timeouts, - filtering options, etc. - - - The query syntax is identical to the mongo cli. Documentation for it - can be found on the - - MongoDB website. Query results - are returned as JSON documents, that one can further process - in the OpenSIPS script by using the JSON module. - - - - Some example raw queries: - - MongoDB Raw Insert - -... -cache_raw_query("mongodb:cluster", "{ \ - \"insert\": \"ip_blacklist\", \ - \"documents\": [{ \ - \"username\": \"$fU\", \ - \"ip\": \"$si\", \ - \"attempts\": 1 \ - }]}", - "$avp(out)"); -xlog("INSERT RAW QUERY returned $rc, output: '$avp(out)'\n"); -... - - - - - MongoDB Raw Update - -... -cache_raw_query("mongodb:cluster", "{ \ - \"update\": \"ip_blacklist\", \ - \"updates\": [{ \ - \"q\": { \ - \"username\": \"$fU\", \ - \"ip\": \"$si\" \ - }, \ - \"u\": { \ - \"$$inc\": {\"attempts\": 1} \ - } \ - }]}", - "$avp(out)"); -xlog("UPDATE RAW QUERY returned $rc, output: '$avp(out)'\n"); -... - - - - -
- -
- diff --git a/modules/cachedb_mongodb/doc/contributors.xml b/modules/cachedb_mongodb/doc/contributors.xml deleted file mode 100644 index f701b2426ba..00000000000 --- a/modules/cachedb_mongodb/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 154 - 83 - 2921 - 2759 - - - 2. - Vlad Paiu (@vladpaiu) - 37 - 10 - 3018 - 50 - - - 3. - Razvan Crainea (@razvancrainea) - 13 - 11 - 31 - 27 - - - 4. - Ovidiu Sas (@ovidiusas) - 10 - 8 - 92 - 16 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 96 - 11 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 5 - 7 - - - 7. - Alexandra Titoc - 4 - 2 - 10 - 3 - - - 8. - Dan Pascu (@danpascu) - 4 - 2 - 4 - 4 - - - 9. - Alessio Garzi (@Ozzyboshi) - 4 - 2 - 2 - 2 - - - 10. - @jalung - 3 - 1 - 97 - 56 - - - -
-All remaining contributors: tcresson, Maksym Sobolyev (@sobomax), Julián Moreno Patiño, Ken Rice, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Nov 2025 - - - 2. - Ken Rice - Sep 2025 - Sep 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2024 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2024 - - - 5. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 6. - Vlad Paiu (@vladpaiu) - Jan 2013 - Aug 2024 - - - 7. - tcresson - Oct 2023 - Oct 2023 - - - 8. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2021 - - - 10. - Alessio Garzi (@Ozzyboshi) - Nov 2019 - Dec 2019 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), @jalung, Julián Moreno Patiño, Ovidiu Sas (@ovidiusas). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/cachedb_redis/README b/modules/cachedb_redis/README deleted file mode 100644 index 23a2a11c224..00000000000 --- a/modules/cachedb_redis/README +++ /dev/null @@ -1,424 +0,0 @@ -cachedb_redis Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Redis Stack Support - 1.4. Limitations - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. External Libraries or Applications - - 1.6. Exported Parameters - - 1.6.1. cachedb_url (string) - 1.6.2. connect_timeout (integer) - 1.6.3. query_timeout (integer) - 1.6.4. shutdown_on_error (integer) - 1.6.5. use_tls (integer) - 1.6.6. ftsearch_index_name (string) - 1.6.7. ftsearch_json_prefix (string) - 1.6.8. ftsearch_max_results (integer) - 1.6.9. ftsearch_json_mset_expire (integer) - - 1.7. Exported Functions - 1.8. Raw Query Syntax - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - 4. Frequently Asked Questions - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Use Redis servers - 1.3. Set connect_timeout parameter - 1.4. Set connect_timeout parameter - 1.5. Set the shutdown_on_error parameter - 1.6. Set the use_tls parameter - 1.7. Set the ftsearch_index_name parameter - 1.8. Set the ftsearch_json_prefix parameter - 1.9. Set the ftsearch_max_results parameter - 1.10. Set the ftsearch_json_mset_expire parameter - 1.11. Redis Raw Query Examples - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with a Redis server. It uses hiredis client library to - connect to either a single Redis server instance, or to a Redis - Server inside a Redis Cluster. It uses the Key-Value interface - exported from the core. - -1.2. Advantages - - * memory costs are no longer on the server - * many servers can be used inside a cluster, so the memory is - virtually unlimited - * the cache is 100% persistent. A restart of OpenSIPS server - will not affect the DB. The Redis DB is also persistent so - it can also be restarted without loss of information. - * redis is an open-source project so it can be used to - exchange data with various other applications - * By creating a Redis Cluster, multiple OpenSIPS instances - can easily share key-value information - -1.3. Redis Stack Support - - Starting with OpenSIPS 3.6, the cachedb_redis module implements - the column-oriented cacheDB API functions. This makes it a - suitable cacheDB storage in scenarios such as user location - federation and full-sharing, which require this API to be - available. - - The implementation makes use of RedisJSON and RediSearch -- - these relatively new features are available in Redis Stack - Server, instead of the usual Redis Server (Redis OSS project). - More documentation is available on the Redis website. - - OpenSIPS will auto-detect availability of the RedisJSON support - when necessary and log the appropriate messages. - -1.4. Limitations - - * keys (in key:value pairs) may not contain spaces or control - characters - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * If a use_tls is defined, the tls_mgm module will need to be - loaded as well. - -1.5.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * hiredis: - On the latest Debian based distributions, hiredis can be - installed by running 'apt-get install libhiredis-dev' - Alternatively, if hiredis is not available on your OS - repos, hiredis can be downloaded from: - https://github.com/antirez/hiredis . Download the archive, - extract sources, run make,sudo make install. - If TLS connections are enabled via the use_tls modparam, - hiredis needs to be compiled with TLS support. - -1.6. Exported Parameters - -1.6.1. cachedb_url (string) - - The URLs of the server groups that OpenSIPS will connect to in - order to use, from script, the cache_store(), cache_fetch(), - etc. operations. It may be set more than once. The prefix part - of the URL will be the identifier that will be used from the - script. - - Example 1.1. Set cachedb_url parameter -... -# single-instance URLs (Redis Server or Redis Cluster) -modparam("cachedb_redis", "cachedb_url", "redis:group1://localhost:6379/ -") -modparam("cachedb_redis", "cachedb_url", "redis:cluster1://random_url:88 -88/") - -# multi-instance URL (will perform circular failover on each query) -modparam("cachedb_redis", "cachedb_url", - "redis:ha://localhost,host_a:6380,host_b:6381,host_c/") -... - - Example 1.2. Use Redis servers -... -cache_store("redis:group1", "key", "$ru value"); -cache_fetch("redis:cluster1", "key", $avp(10)); -cache_remove("redis:cluster1", "key"); -... - -1.6.2. connect_timeout (integer) - - This parameter specifies how many milliseconds OpenSIPS should - wait for connecting to a Redis node. - - Default value is “5000 ms”. - - Example 1.3. Set connect_timeout parameter -... -# wait 1 seconds for Redis to connect -modparam("cachedb_redis", "connect_timeout",1000) -... - -1.6.3. query_timeout (integer) - - This parameter specifies how many milliseconds OpenSIPS should - wait for a query response from a Redis node. - - Default value is “5000 ms”. - - Example 1.4. Set connect_timeout parameter -... -# wait 1 seconds for Redis queries -modparam("cachedb_redis", "query_timeout",1000) -... - -1.6.4. shutdown_on_error (integer) - - By setting this parameter to 1, OpenSIPS will abort startup if - the initial connection to Redis is not possible. Runtime - reconnect behavior is unaffected by this parameter, and is - always enabled. - - Default value is “0” (disabled). - - Example 1.5. Set the shutdown_on_error parameter -... -# abort OpenSIPS startup if Redis is down -modparam("cachedb_redis", "shutdown_on_error", 1) -... - -1.6.5. use_tls (integer) - - Setting this parameter will allow you to use TLS for Redis - connections. In order to enable TLS for a specific connection, - you can use the "tls_domain=dom_name" URL parameter in the - cachedb_url of this module (or other modules that use the - CacheDB interface). This should be placed at the end of the URL - after the '?' character. - - When using this parameter, you must also ensure that tls_mgm is - loaded and properly configured. Refer to the the module for - additional info regarding TLS client domains. - - Note that TLS is supported by Redis starting with version 6.0. - Also, it is an optional feature enabled at compile time and - might not be included in the standard Redis packages available - for your OS. - - Default value is 0 (not enabled) - - Example 1.6. Set the use_tls parameter -... -modparam("tls_mgm", "client_domain", "redis") -modparam("tls_mgm", "certificate", "[redis]/etc/pki/tls/certs/redis.pem" -) -modparam("tls_mgm", "private_key", "[redis]/etc/pki/tls/private/redis.ke -y") -modparam("tls_mgm", "ca_list", "[redis]/etc/pki/tls/certs/ca.pem") -... -modparam("cachedb_redis", "use_tls", 1) -modparam("cachedb_redis", "cachedb_url","redis://localhost:6379/?tls_dom -ain=redis") -... - -1.6.6. ftsearch_index_name (string) - - Only relevant with RedisJSON and RediSearch server-side - support. - - A global index name to be used for all internal JSON full-text - search operations. Future extensions may add, e.g., a - connection-level index name setting. - - Default value is "idx:usrloc". - - Example 1.7. Set the ftsearch_index_name parameter - -modparam("cachedb_redis", "ftsearch_index_name", "ix::usrloc") - - -1.6.7. ftsearch_json_prefix (string) - - Only relevant with RedisJSON and RediSearch server-side - support. - - A key naming prefix for all internally-created Redis JSON - objects (e.g. created with JSON.SET or JSON.MSET). - - Default value is "usrloc:". - - Example 1.8. Set the ftsearch_json_prefix parameter - -modparam("cachedb_redis", "ftsearch_json_prefix", "userlocation:") - - -1.6.8. ftsearch_max_results (integer) - - Only relevant with RedisJSON and RediSearch server-side - support. - - The maximum number of results returned by each - internally-triggered FT.SEARCH JSON lookup query. - - Default value is 10000 max results. - - Example 1.9. Set the ftsearch_max_results parameter - -modparam("cachedb_redis", "ftsearch_max_results", 100) - - -1.6.9. ftsearch_json_mset_expire (integer) - - Only relevant with RedisJSON and RediSearch server-side - support. - - A Redis EXPIRE timer to set/refresh on the JSON key after each - JSON.MSET operation (create the JSON or add/remove subkeys), in - seconds. A value of 0 disables the EXPIRE queries completely. - - Default value is 3600 seconds. - - Example 1.10. Set the ftsearch_json_mset_expire parameter - -modparam("cachedb_redis", "ftsearch_json_mset_expire", 7200) - - -1.7. Exported Functions - - The module does not export functions to be used in - configuration script. - -1.8. Raw Query Syntax - - The cachedb_redis module allows to run RAW queries, thus taking - full advantage of the capabilities of the back-end. The query - syntax is the typical REDIS one. - - Here are a couple examples of running some Redis queries : - - Example 1.11. Redis Raw Query Examples -... - $var(my_hash) = "my_hash_name"; - $var(my_key) = "my_key_name"; - $var(my_value) = "my_key_value"; - cache_raw_query("redis","HSET $var(my_hash) $var(my_key) $var(my -_value)"); - cache_raw_query("redis","HGET $var(my_hash) $var(my_key)","$avp( -result)"); - xlog("We have fetched $avp(result) \n"); -... - $var(my_hash) = "my_hash_name"; - $var(my_key1) = "my_key1_name"; - $var(my_key2) = "my_key2_name"; - $var(my_value1) = "my_key1_value"; - $var(my_value2) = "my_key2_value"; - cache_raw_query("redis","HSET $var(my_hash) $var(my_key1) $var(m -y_value1)"); - cache_raw_query("redis","HSET $var(my_hash) $var(my_key2) $var(m -y_value2)"); - cache_raw_query("redis","HGETALL $var(my_hash)","$avp(result)"); - - $var(it) = 0; - while ($(avp(result_final)[$var(it)]) != NULL) { - xlog("Multiple key reply: - we have fetched $(avp(result -_final)[$var(it)]) \n"); - $var(it) = $var(it) + 1; - } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 43 23 1720 288 - 2. Vlad Paiu (@vladpaiu) 33 19 1446 50 - 3. Razvan Crainea (@razvancrainea) 17 14 150 48 - 4. Vlad Patrascu (@rvlad-patrascu) 13 6 595 38 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 7 5 7 5 - 6. Maksym Sobolyev (@sobomax) 6 4 7 7 - 7. jalung 5 1 144 61 - 8. Norm Brandinger 4 1 207 5 - 9. Dan Pascu (@danpascu) 3 1 15 15 - 10. Ezequiel Lovelle 3 1 11 4 - - All remaining contributors: John Burke (@john08burke), - tcresson, Eddie Fiorentine, Julián Moreno Patiño, Ken Rice, - Peter Lemenkov (@lemenkov), zhengsh, Jarrod Baumann (@jarrodb), - Kristian Høgh. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Razvan Crainea (@razvancrainea) Feb 2012 - May 2025 - 3. Norm Brandinger May 2025 - May 2025 - 4. Eddie Fiorentine Mar 2025 - Mar 2025 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Jan 2025 - 6. Vlad Paiu (@vladpaiu) Oct 2011 - Nov 2024 - 7. tcresson Oct 2023 - Oct 2023 - 8. zhengsh Aug 2023 - Aug 2023 - 9. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 10. John Burke (@john08burke) Apr 2022 - Apr 2022 - - All remaining contributors: Vlad Patrascu (@rvlad-patrascu), - Bogdan-Andrei Iancu (@bogdan-iancu), Dan Pascu (@danpascu), - Peter Lemenkov (@lemenkov), Kristian Høgh, Julián Moreno - Patiño, Jarrod Baumann (@jarrodb), jalung, Ezequiel Lovelle. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Julián Moreno - Patiño, Razvan Crainea (@razvancrainea), Vlad Paiu (@vladpaiu). - -Chapter 4. Frequently Asked Questions - - 4.1. - - My OpenSIPS is occasionally crashing in libhiredis, what to do? - - Make sure you've upgraded the Redis "libhiredis" client library - to at least version 0.14.1. There was at least one significant - vulnerability reported in library versions prior to that one - (CVE-2020-7105), so upgrading to latest stable may very well - fix the crash! - - Documentation Copyrights: - - Copyright © 2011 www.opensips-solutions.com diff --git a/modules/cachedb_redis/README.md b/modules/cachedb_redis/README.md new file mode 100644 index 00000000000..3bc4b0584eb --- /dev/null +++ b/modules/cachedb_redis/README.md @@ -0,0 +1,351 @@ +--- +title: "cachedb_redis Module" +description: "This module is an implementation of a cache system designed to work with a Redis server." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with a +Redis server. It uses hiredis client library to connect to either a single Redis +server instance, or to a Redis Server inside a Redis Cluster. +It uses the Key-Value interface exported from the core. + + +### Advantages + + +- *memory costs are no longer on the server* +- *many servers can be used inside a cluster, so the memory +is virtually unlimited* +- *the cache is 100% persistent. A restart +of OpenSIPS server will not affect the DB. The Redis DB is also +persistent so it can also be restarted without loss of information.* +- *redis is an open-source project so +it can be used to exchange data +with various other applications* +- *By creating a Redis Cluster, multiple OpenSIPS +instances can easily share key-value information* + + +### Redis Stack Support + + +Starting with OpenSIPS **3.6**, the *cachedb_redis* +module implements the column-oriented cacheDB API functions. This makes it a suitable +cacheDB storage in scenarios such as user location *federation* +and *full-sharing*, which require this API to be available. + + +The implementation makes use of *RedisJSON* and *RediSearch* -- +these relatively new features are available in Redis Stack Server, instead of the usual Redis Server +(Redis OSS project). More documentation is available on the Redis website. + + +OpenSIPS will auto-detect availability of the RedisJSON support when necessary and log +the appropriate messages. + + +### Limitations + + +- *keys (in key:value pairs) may not contain spaces or control characters* + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *If a [use tls](#param_use_tls) is defined, the **tls_mgm** module will need to be loaded as well*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *hiredis:* +On the latest Debian based distributions, hiredis can be installed +by running 'apt-get install libhiredis-dev' + +Alternatively, if hiredis is not available on your OS repos, +hiredis can be downloaded from: https://github.com/antirez/hiredis . +Download the archive, extract sources, run make,sudo make install. +If TLS connections are enabled via the [use tls](#param_use_tls) modparam, +*hiredis* needs to be compiled with TLS support. + + +### Exported Parameters + + +#### cachedb_url (string) + + +The URLs of the server groups that OpenSIPS will connect to in order +to use, from script, the cache_store(), cache_fetch(), etc. operations. +It may be set more than once. The prefix part of the URL will be +the identifier that will be used from the script. + + +```opensips title="Set cachedb_url parameter" +... +# single-instance URLs (Redis Server or Redis Cluster) +modparam("cachedb_redis", "cachedb_url", "redis:group1://localhost:6379/") +modparam("cachedb_redis", "cachedb_url", "redis:cluster1://random_url:8888/") + +# multi-instance URL (will perform circular +``` + + +```opensips title="Use Redis servers" +... +cache_store("redis:group1", "key", "$ru value"); +cache_fetch("redis:cluster1", "key", $avp(10)); +cache_remove("redis:cluster1", "key"); +... + +``` + + +#### connect_timeout (integer) + + +This parameter specifies how many milliseconds OpenSIPS should wait +for connecting to a Redis node. + + +*Default value is "5000 ms".* + + +```opensips title="Set connect_timeout parameter" +... +# wait 1 seconds for Redis to connect +modparam("cachedb_redis", "connect_timeout",1000) +... + +``` + + +#### query_timeout (integer) + + +This parameter specifies how many milliseconds OpenSIPS should wait +for a query response from a Redis node. + + +*Default value is "5000 ms".* + + +```opensips title="Set connect_timeout parameter" +... +# wait 1 seconds for Redis queries +modparam("cachedb_redis", "query_timeout",1000) +... + +``` + + +#### shutdown_on_error (integer) + + +By setting this parameter to 1, OpenSIPS will abort startup if +the initial connection to Redis is not possible. Runtime reconnect +behavior is unaffected by this parameter, and is always enabled. + + +*Default value is "0" (disabled).* + + +```opensips title="Set the shutdown_on_error parameter" +... +# abort OpenSIPS startup if Redis is down +modparam("cachedb_redis", "shutdown_on_error", 1) +... + +``` + + +#### use_tls (integer) + + +Setting this parameter will allow you to use TLS for Redis connections. +In order to enable TLS for a specific connection, you can use the +"tls_domain=*dom_name*" URL parameter in the cachedb_url +of this module (or other modules that use the CacheDB interface). This should +be placed at the end of the URL after the '?' character. + + +When using this parameter, you must also ensure that +*tls_mgm* is loaded and properly configured. Refer to +the the module for additional info regarding TLS client domains. + + +Note that TLS is supported by Redis starting with version 6.0. Also, it is +an optional feature enabled at compile time and might not be included in the +standard Redis packages available for your OS. + + +*Default value is **0** (not enabled)* + + +```opensips title="Set the use_tls parameter" +... +modparam("tls_mgm", "client_domain", "redis") +modparam("tls_mgm", "certificate", "[redis]/etc/pki/tls/certs/redis.pem") +modparam("tls_mgm", "private_key", "[redis]/etc/pki/tls/private/redis.key") +modparam("tls_mgm", "ca_list", "[redis]/etc/pki/tls/certs/ca.pem") +... +modparam("cachedb_redis", "use_tls", 1) +modparam("cachedb_redis", "cachedb_url","redis://localhost:6379/?tls_domain=redis") +... +``` + + +#### ftsearch_index_name (string) + + +Only relevant with *RedisJSON* and +*RediSearch* server-side support. + + +A global index name to be used for all internal JSON full-text search operations. +Future extensions may add, e.g., a connection-level index name setting. + + +Default value is **"idx:usrloc"**. + + +```opensips title="Set the ftsearch_index_name parameter" +modparam("cachedb_redis", "ftsearch_index_name", "ix::usrloc") +``` + + +#### ftsearch_json_prefix (string) + + +Only relevant with *RedisJSON* and +*RediSearch* server-side support. + + +A key naming prefix for all internally-created Redis JSON objects (e.g. +created with JSON.SET or JSON.MSET). + + +Default value is **"usrloc:"**. + + +```opensips title="Set the ftsearch_json_prefix parameter" +modparam("cachedb_redis", "ftsearch_json_prefix", "userlocation:") +``` + + +#### ftsearch_max_results (integer) + + +Only relevant with *RedisJSON* and +*RediSearch* server-side support. + + +The maximum number of results returned by each internally-triggered +FT.SEARCH JSON lookup query. + + +Default value is **10000** max results. + + +```opensips title="Set the ftsearch_max_results parameter" +modparam("cachedb_redis", "ftsearch_max_results", 100) +``` + + +#### ftsearch_json_mset_expire (integer) + + +Only relevant with *RedisJSON* and +*RediSearch* server-side support. + + +A Redis EXPIRE timer to set/refresh on the JSON key after each JSON.MSET operation +(create the JSON or add/remove subkeys), in seconds. A value of **0** +disables the EXPIRE queries completely. + + +Default value is **3600** seconds. + + +```opensips title="Set the ftsearch_json_mset_expire parameter" +modparam("cachedb_redis", "ftsearch_json_mset_expire", 7200) +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### Raw Query Syntax + + +The cachedb_redis module allows to run RAW queries, thus taking full advantage of the capabilities of the back-end. + +The query syntax is the typical REDIS one. + + +Here are a couple examples of running some Redis queries : + + +```opensips title="Redis Raw Query Examples" +... + $var(my_hash) = "my_hash_name"; + $var(my_key) = "my_key_name"; + $var(my_value) = "my_key_value"; + cache_raw_query("redis","HSET $var(my_hash) $var(my_key) $var(my_value)"); + cache_raw_query("redis","HGET $var(my_hash) $var(my_key)","$avp(result)"); + xlog("We have fetched $avp(result) \n"); +... + $var(my_hash) = "my_hash_name"; + $var(my_key1) = "my_key1_name"; + $var(my_key2) = "my_key2_name"; + $var(my_value1) = "my_key1_value"; + $var(my_value2) = "my_key2_value"; + cache_raw_query("redis","HSET $var(my_hash) $var(my_key1) $var(my_value1)"); + cache_raw_query("redis","HSET $var(my_hash) $var(my_key2) $var(my_value2)"); + cache_raw_query("redis","HGETALL $var(my_hash)","$avp(result)"); + + $var(it) = 0; + while ($(avp(result_final)[$var(it)]) != NULL) { + xlog("Multiple key reply: - we have fetched $(avp(result_final)[$var(it)]) \n"); + $var(it) = $var(it) + 1; + } +... + +``` + + +## Frequently Asked Questions + + +**Q: My OpenSIPS is occasionally crashing in libhiredis, what to do?** + + +Make sure you've upgraded the Redis "libhiredis" client library to at +least version 0.14.1. There was at least one significant vulnerability +reported in library versions prior to that one ([CVE-2020-7105](https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2020-7105)), +so upgrading to latest stable may very well fix the crash! + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_redis/cachedb_redis_dbase.c b/modules/cachedb_redis/cachedb_redis_dbase.c index 38957e4a9cc..5ef92c6a5a4 100644 --- a/modules/cachedb_redis/cachedb_redis_dbase.c +++ b/modules/cachedb_redis/cachedb_redis_dbase.c @@ -58,7 +58,7 @@ static unsigned int redis_calc_escaped_len_json(str *s); redisContext *redis_get_ctx(char *ip, int port) { struct timeval tv; - static char warned = 0; + static int warned = 0; redisContext *ctx; if (!port) @@ -79,6 +79,12 @@ redisContext *redis_get_ctx(char *ip, int port) return NULL; } + if (!ctx) { + LM_ERR("failed to connect to redis %s:%hu - out of memory\n", + ip, (unsigned short)port); + return NULL; + } + if (redis_query_tout) { tv.tv_sec = redis_query_tout / 1000; tv.tv_usec = (redis_query_tout * 1000) % 1000000; diff --git a/modules/cachedb_redis/doc/cachedb_redis.xml b/modules/cachedb_redis/doc/cachedb_redis.xml deleted file mode 100644 index 4b56af074e3..00000000000 --- a/modules/cachedb_redis/doc/cachedb_redis.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - cachedb_redis Module - &osipsname; - - - - &admin; - &contrib; - &faq; - - &docCopyrights; - ©right; 2011 &osipssol; - diff --git a/modules/cachedb_redis/doc/cachedb_redis_admin.xml b/modules/cachedb_redis/doc/cachedb_redis_admin.xml deleted file mode 100644 index dd7edb2e631..00000000000 --- a/modules/cachedb_redis/doc/cachedb_redis_admin.xml +++ /dev/null @@ -1,448 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with a - Redis server. It uses hiredis client library to connect to either a single Redis - server instance, or to a Redis Server inside a Redis Cluster. - It uses the Key-Value interface exported from the core. - - - -
- - -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - many servers can be used inside a cluster, so the memory - is virtually unlimited - - - - - - the cache is 100% persistent. A restart - of OpenSIPS server will not affect the DB. The Redis DB is also - persistent so it can also be restarted without loss of information. - - - - - - redis is an open-source project so - it can be used to exchange data - with various other applications - - - - - - By creating a Redis Cluster, multiple OpenSIPS - instances can easily share key-value information - - - - - - - -
- -
- Redis Stack Support - - Starting with OpenSIPS 3.6, the cachedb_redis - module implements the column-oriented cacheDB API functions. This makes it a suitable - cacheDB storage in scenarios such as user location federation - and full-sharing, which require this API to be available. - - - The implementation makes use of RedisJSON and RediSearch -- - these relatively new features are available in Redis Stack Server, instead of the usual Redis Server - (Redis OSS project). More documentation is available on the Redis website. - - - OpenSIPS will auto-detect availability of the RedisJSON support when necessary and log - the appropriate messages. - - - -
- -
- Limitations - - - - - - - - keys (in key:value pairs) may not contain spaces or control characters - - - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - If a is defined, the tls_mgm module will need to be loaded as well. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - hiredis: - - - - On the latest Debian based distributions, hiredis can be installed - by running 'apt-get install libhiredis-dev' - - Alternatively, if hiredis is not available on your OS repos, - hiredis can be downloaded from: https://github.com/antirez/hiredis . - Download the archive, extract sources, run make,sudo make install. - - - If TLS connections are enabled via the modparam, - hiredis needs to be compiled with TLS support. - - - - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The URLs of the server groups that OpenSIPS will connect to in order - to use, from script, the cache_store(), cache_fetch(), etc. operations. - It may be set more than once. The prefix part of the URL will be - the identifier that will be used from the script. - - - - Set <varname>cachedb_url</varname> parameter - -... -# single-instance URLs (Redis Server or Redis Cluster) -modparam("cachedb_redis", "cachedb_url", "redis:group1://localhost:6379/") -modparam("cachedb_redis", "cachedb_url", "redis:cluster1://random_url:8888/") - -# multi-instance URL (will perform circular failover on each query) -modparam("cachedb_redis", "cachedb_url", - "redis:ha://localhost,host_a:6380,host_b:6381,host_c/") -... - - - - - Use Redis servers - -... -cache_store("redis:group1", "key", "$ru value"); -cache_fetch("redis:cluster1", "key", $avp(10)); -cache_remove("redis:cluster1", "key"); -... - - -
- -
- <varname>connect_timeout</varname> (integer) - - This parameter specifies how many milliseconds &osips; should wait - for connecting to a Redis node. - - - - Default value is 5000 ms. - - - - - Set <varname>connect_timeout</varname> parameter - -... -# wait 1 seconds for Redis to connect -modparam("cachedb_redis", "connect_timeout",1000) -... - - - -
- -
- <varname>query_timeout</varname> (integer) - - This parameter specifies how many milliseconds &osips; should wait - for a query response from a Redis node. - - - - Default value is 5000 ms. - - - - - Set <varname>connect_timeout</varname> parameter - -... -# wait 1 seconds for Redis queries -modparam("cachedb_redis", "query_timeout",1000) -... - - -
- -
- <varname>shutdown_on_error</varname> (integer) - - By setting this parameter to 1, &osips; will abort startup if - the initial connection to Redis is not possible. Runtime reconnect - behavior is unaffected by this parameter, and is always enabled. - - - - Default value is 0 (disabled). - - - - - Set the <varname>shutdown_on_error</varname> parameter - -... -# abort OpenSIPS startup if Redis is down -modparam("cachedb_redis", "shutdown_on_error", 1) -... - - - -
- -
- <varname>use_tls</varname> (integer) - - Setting this parameter will allow you to use TLS for Redis connections. - In order to enable TLS for a specific connection, you can use the - "tls_domain=dom_name" URL parameter in the cachedb_url - of this module (or other modules that use the CacheDB interface). This should - be placed at the end of the URL after the '?' character. - - - When using this parameter, you must also ensure that - tls_mgm is loaded and properly configured. Refer to - the the module for additional info regarding TLS client domains. - - - Note that TLS is supported by Redis starting with version 6.0. Also, it is - an optional feature enabled at compile time and might not be included in the - standard Redis packages available for your OS. - - - - Default value is 0 (not enabled) - - - - Set the <varname>use_tls</varname> parameter - -... -modparam("tls_mgm", "client_domain", "redis") -modparam("tls_mgm", "certificate", "[redis]/etc/pki/tls/certs/redis.pem") -modparam("tls_mgm", "private_key", "[redis]/etc/pki/tls/private/redis.key") -modparam("tls_mgm", "ca_list", "[redis]/etc/pki/tls/certs/ca.pem") -... -modparam("cachedb_redis", "use_tls", 1) -modparam("cachedb_redis", "cachedb_url","redis://localhost:6379/?tls_domain=redis") -... - - -
- -
- <varname>ftsearch_index_name</varname> (string) - - Only relevant with RedisJSON and - RediSearch server-side support. - - - A global index name to be used for all internal JSON full-text search operations. - Future extensions may add, e.g., a connection-level index name setting. - - - Default value is "idx:usrloc". - - - Set the <varname>ftsearch_index_name</varname> parameter - - -modparam("cachedb_redis", "ftsearch_index_name", "ix::usrloc") - - - -
- -
- <varname>ftsearch_json_prefix</varname> (string) - - Only relevant with RedisJSON and - RediSearch server-side support. - - - A key naming prefix for all internally-created Redis JSON objects (e.g. - created with JSON.SET or JSON.MSET). - - - Default value is "usrloc:". - - - Set the <varname>ftsearch_json_prefix</varname> parameter - - -modparam("cachedb_redis", "ftsearch_json_prefix", "userlocation:") - - - -
- -
- <varname>ftsearch_max_results</varname> (integer) - - Only relevant with RedisJSON and - RediSearch server-side support. - - - The maximum number of results returned by each internally-triggered - FT.SEARCH JSON lookup query. - - - Default value is 10000 max results. - - - Set the <varname>ftsearch_max_results</varname> parameter - - -modparam("cachedb_redis", "ftsearch_max_results", 100) - - - -
- -
- <varname>ftsearch_json_mset_expire</varname> (integer) - - Only relevant with RedisJSON and - RediSearch server-side support. - - - A Redis EXPIRE timer to set/refresh on the JSON key after each JSON.MSET operation - (create the JSON or add/remove subkeys), in seconds. A value of 0 - disables the EXPIRE queries completely. - - - Default value is 3600 seconds. - - - Set the <varname>ftsearch_json_mset_expire</varname> parameter - - -modparam("cachedb_redis", "ftsearch_json_mset_expire", 7200) - - - -
- -
- - -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- -
- Raw Query Syntax - - The cachedb_redis module allows to run RAW queries, thus taking full advantage of the capabilities of the back-end. - - The query syntax is the typical REDIS one. - - - - Here are a couple examples of running some Redis queries : - - Redis Raw Query Examples - -... - $var(my_hash) = "my_hash_name"; - $var(my_key) = "my_key_name"; - $var(my_value) = "my_key_value"; - cache_raw_query("redis","HSET $var(my_hash) $var(my_key) $var(my_value)"); - cache_raw_query("redis","HGET $var(my_hash) $var(my_key)","$avp(result)"); - xlog("We have fetched $avp(result) \n"); -... - $var(my_hash) = "my_hash_name"; - $var(my_key1) = "my_key1_name"; - $var(my_key2) = "my_key2_name"; - $var(my_value1) = "my_key1_value"; - $var(my_value2) = "my_key2_value"; - cache_raw_query("redis","HSET $var(my_hash) $var(my_key1) $var(my_value1)"); - cache_raw_query("redis","HSET $var(my_hash) $var(my_key2) $var(my_value2)"); - cache_raw_query("redis","HGETALL $var(my_hash)","$avp(result)"); - - $var(it) = 0; - while ($(avp(result_final)[$var(it)]) != NULL) { - xlog("Multiple key reply: - we have fetched $(avp(result_final)[$var(it)]) \n"); - $var(it) = $var(it) + 1; - } -... - - - - -
- - -
- diff --git a/modules/cachedb_redis/doc/cachedb_redis_faq.xml b/modules/cachedb_redis/doc/cachedb_redis_faq.xml deleted file mode 100644 index ff4d027a892..00000000000 --- a/modules/cachedb_redis/doc/cachedb_redis_faq.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - &faqguide; - - - - My OpenSIPS is occasionally crashing in libhiredis, what to do? - - - - Make sure you've upgraded the Redis "libhiredis" client library to at - least version 0.14.1. There was at least one significant vulnerability - reported in library versions prior to that one (CVE-2020-7105), - so upgrading to latest stable may very well fix the crash! - - - - - - diff --git a/modules/cachedb_redis/doc/contributors.xml b/modules/cachedb_redis/doc/contributors.xml deleted file mode 100644 index 7ab5ff42b4c..00000000000 --- a/modules/cachedb_redis/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 43 - 23 - 1720 - 288 - - - 2. - Vlad Paiu (@vladpaiu) - 33 - 19 - 1446 - 50 - - - 3. - Razvan Crainea (@razvancrainea) - 17 - 14 - 150 - 48 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 13 - 6 - 595 - 38 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 5 - 7 - 5 - - - 6. - Maksym Sobolyev (@sobomax) - 6 - 4 - 7 - 7 - - - 7. - jalung - 5 - 1 - 144 - 61 - - - 8. - Norm Brandinger - 4 - 1 - 207 - 5 - - - 9. - Dan Pascu (@danpascu) - 3 - 1 - 15 - 15 - - - 10. - Ezequiel Lovelle - 3 - 1 - 11 - 4 - - - -
-All remaining contributors: John Burke (@john08burke), tcresson, Eddie Fiorentine, Julián Moreno Patiño, Ken Rice, Peter Lemenkov (@lemenkov), zhengsh, Jarrod Baumann (@jarrodb), Kristian Høgh. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Feb 2012 - May 2025 - - - 3. - Norm Brandinger - May 2025 - May 2025 - - - 4. - Eddie Fiorentine - Mar 2025 - Mar 2025 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jan 2025 - - - 6. - Vlad Paiu (@vladpaiu) - Oct 2011 - Nov 2024 - - - 7. - tcresson - Oct 2023 - Oct 2023 - - - 8. - zhengsh - Aug 2023 - Aug 2023 - - - 9. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 10. - John Burke (@john08burke) - Apr 2022 - Apr 2022 - - - -
-All remaining contributors: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Kristian Høgh, Julián Moreno Patiño, Jarrod Baumann (@jarrodb), jalung, Ezequiel Lovelle. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Razvan Crainea (@razvancrainea), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/cachedb_sql/README b/modules/cachedb_sql/README deleted file mode 100644 index 08f95f759ef..00000000000 --- a/modules/cachedb_sql/README +++ /dev/null @@ -1,256 +0,0 @@ -cachedb_sql Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Advantages - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. cachedb_url (string) - 1.5.2. db_table (string) - 1.5.3. key_column (string) - 1.5.4. value_column (string) - 1.5.5. counter_column (string) - 1.5.6. expires_column (string) - 1.5.7. cache_clean_period (int) - 1.5.8. Exported Functions - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Usage example - 1.3. Set db_url parameter - 1.4. Set key_column parameter - 1.5. Set value_column parameter - 1.6. Set counter_column parameter - 1.7. Set expires_column parameter - 1.8. Set cache_clean_period parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed to - work with a regular SQL-based server. It uses the internal DB - interface to connect to the back-end, and also implements the - Key-Value interface exported from the core. - -1.2. Advantages - - * memory costs are no longer on the server - * the cache is 100% persistent. A restart of OpenSIPS server - will not affect the DB. The DB is also persistent so it can - also be restarted without loss of information. - * Multiple OpenSIPS instances can easily share key-value - information via a regular SQL-based database - -1.3. Limitations - - * The module's counter operations ( ADD and SUB ) are - currently only supported by MySQL - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none: - -1.5. Exported Parameters - -1.5.1. cachedb_url (string) - - The url of the Database that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - - The format to follow is : sql:[conn_id]-dburl - - The parameter can be set multiple times to create multiple - connections accessible from the OpenSIPS script. - - Example 1.1. Set db_url parameter -... -modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localh -ost/opensips_sql") -... - - Example 1.2. Usage example -... -modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localh -ost/opensips_sql") -modparam("cachedb_sql", "cachedb_url", "sql:2nd-postgres://root:vlad@loc -alhost/opensips_pg") -... -... -cache_store("sql:1st-mysql","key","$ru value"); -cache_store("sql:2nd-postgres","counter","10"); -... - -1.5.2. db_table (string) - - The table of the Database that OpenSIPS will connect to in - order to use the from script cache_store,cache_fetch, etc - operations. - - Example 1.3. Set db_url parameter -... -modparam("cachedb_sql", "db_table","my_table"); -... - -1.5.3. key_column (string) - - The column where the key will be stored - - Example 1.4. Set key_column parameter -... -modparam("cachedb_sql", "key_column","some_name"); -... - -1.5.4. value_column (string) - - The column where the value will be stored - - Example 1.5. Set value_column parameter -... -modparam("cachedb_sql", "value_column","some_name"); -... - -1.5.5. counter_column (string) - - The column where the counter value will be stored - - Example 1.6. Set counter_column parameter -... -modparam("cachedb_sql", "counter_column","some_name"); -... - -1.5.6. expires_column (string) - - The column where the expires will be stored - - Example 1.7. Set expires_column parameter -... -modparam("cachedb_sql", "expires_column","some_name"); -... - -1.5.7. cache_clean_period (int) - - The interval in seconds at which the expired keys will be - removed from the database. Default value is 60 ( seconds ) - - Example 1.8. Set cache_clean_period parameter -... -modparam("cachedb_sql", "cache_clean_period",10); -... - -1.5.8. Exported Functions - - The module does not export functions to be used in - configuration script. - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with the old “db_url” module parameter? - - It was replaced with the “cachedb_url” parameter. See the - documentation for the usage of the “cachedb_url” parameter. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 16 5 1001 87 - 2. Liviu Chircu (@liviuchircu) 11 9 42 59 - 3. Razvan Crainea (@razvancrainea) 7 5 4 2 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 5 2 - 5. Alexandra Titoc 4 2 4 3 - 6. Maksym Sobolyev (@sobomax) 4 2 1 2 - 7. Dusan Klinec (@ph4r05) 3 1 2 2 - 8. Julián Moreno Patiño 3 1 2 2 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - 10. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - All remaining contributors: Ovidiu Sas (@ovidiusas). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Ovidiu Sas (@ovidiusas) Apr 2022 - Apr 2022 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 5. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - - All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/cachedb_sql/README.md b/modules/cachedb_sql/README.md new file mode 100644 index 00000000000..0908dbcea7d --- /dev/null +++ b/modules/cachedb_sql/README.md @@ -0,0 +1,196 @@ +--- +title: "cachedb_sql Module" +description: "This module is an implementation of a cache system designed to work with a regular SQL-based server." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed to work with a +regular SQL-based server. It uses the internal DB interface to connect +to the back-end, and also implements the Key-Value interface exported from the core. + + +### Advantages + + +- *memory costs are no longer on the server* +- *the cache is 100% persistent. A restart +of OpenSIPS server will not affect the DB. The DB is also +persistent so it can also be restarted without loss of information.* +- *Multiple OpenSIPS instances can easily share key-value information +via a regular SQL-based database* + + +### Limitations + + +- *The module's counter operations (ADD and SUB) are currently only +supported by MySQL* + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *none:* + + +### Exported Parameters + + +#### cachedb_url (string) + + +The url of the Database that OpenSIPS will connect to in order +to use the from script cache_store,cache_fetch, etc operations. + + +The format to follow is : sql:[conn_id]-dburl + + +The parameter can be set multiple times to create multiple connections accessible from the OpenSIPS script. + + +```opensips title="Set db_url parameter" +... +modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localhost/opensips_sql") +... + +``` + + +```opensips title="Usage example" +... +modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localhost/opensips_sql") +modparam("cachedb_sql", "cachedb_url", "sql:2nd-postgres://root:vlad@localhost/opensips_pg") +... +... +cache_store("sql:1st-mysql","key","$ru value"); +cache_store("sql:2nd-postgres","counter","10"); +... + +``` + + +#### db_table (string) + + +The table of the Database that OpenSIPS will connect to in order +to use the from script cache_store,cache_fetch, etc operations. + + +```opensips title="Set db_url parameter" +... +modparam("cachedb_sql", "db_table","my_table"); +... + +``` + + +#### key_column (string) + + +The column where the key will be stored + + +```opensips title="Set key_column parameter" +... +modparam("cachedb_sql", "key_column","some_name"); +... + +``` + + +#### value_column (string) + + +The column where the value will be stored + + +```opensips title="Set value_column parameter" +... +modparam("cachedb_sql", "value_column","some_name"); +... + +``` + + +#### counter_column (string) + + +The column where the counter value will be stored + + +```opensips title="Set counter_column parameter" +... +modparam("cachedb_sql", "counter_column","some_name"); +... + +``` + + +#### expires_column (string) + + +The column where the expires will be stored + + +```opensips title="Set expires_column parameter" +... +modparam("cachedb_sql", "expires_column","some_name"); +... + +``` + + +#### cache_clean_period (int) + + +The interval in seconds at which the expired keys will be removed from +the database. Default value is 60 ( seconds ) + + +```opensips title="Set cache_clean_period parameter" +... +modparam("cachedb_sql", "cache_clean_period",10); +... + +``` + + +#### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +## Frequently Asked Questions + + +**Q: What happened with the old "db_url" module parameter?** + + +It was replaced with the "cachedb_url" parameter. +See the documentation for the usage of the "cachedb_url" parameter. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cachedb_sql/doc/cachedb_sql.xml b/modules/cachedb_sql/doc/cachedb_sql.xml deleted file mode 100644 index 872df8eac89..00000000000 --- a/modules/cachedb_sql/doc/cachedb_sql.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - cachedb_sql Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - diff --git a/modules/cachedb_sql/doc/cachedb_sql_admin.xml b/modules/cachedb_sql/doc/cachedb_sql_admin.xml deleted file mode 100644 index ee4ade8555a..00000000000 --- a/modules/cachedb_sql/doc/cachedb_sql_admin.xml +++ /dev/null @@ -1,245 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed to work with a - regular SQL-based server. It uses the internal DB interface to connect - to the back-end, and also implements the Key-Value interface exported from the core. - - - -
- - -
- Advantages - - - - - memory costs are no longer on the server - - - - - - - the cache is 100% persistent. A restart - of OpenSIPS server will not affect the DB. The DB is also - persistent so it can also be restarted without loss of information. - - - - - - Multiple OpenSIPS instances can easily share key-value information - via a regular SQL-based database - - - - - - - -
- -
- Limitations - - - - - - - - The module's counter operations ( ADD and SUB ) are currently only - supported by MySQL - - - - - - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - none: - - - - -
-
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The url of the Database that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - - - - The format to follow is : sql:[conn_id]-dburl - - - - The parameter can be set multiple times to create multiple connections accessible from the OpenSIPS script. - - - - Set <varname>db_url</varname> parameter - -... -modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localhost/opensips_sql") -... - - - - - Usage example - -... -modparam("cachedb_sql", "cachedb_url", "sql:1st-mysql://root:vlad@localhost/opensips_sql") -modparam("cachedb_sql", "cachedb_url", "sql:2nd-postgres://root:vlad@localhost/opensips_pg") -... -... -cache_store("sql:1st-mysql","key","$ru value"); -cache_store("sql:2nd-postgres","counter","10"); -... - - -
- -
- <varname>db_table</varname> (string) - - The table of the Database that OpenSIPS will connect to in order - to use the from script cache_store,cache_fetch, etc operations. - - - - Set <varname>db_url</varname> parameter - -... -modparam("cachedb_sql", "db_table","my_table"); -... - - -
- -
- <varname>key_column</varname> (string) - - The column where the key will be stored - - - - Set <varname>key_column</varname> parameter - -... -modparam("cachedb_sql", "key_column","some_name"); -... - - -
- -
- <varname>value_column</varname> (string) - - The column where the value will be stored - - - - Set <varname>value_column</varname> parameter - -... -modparam("cachedb_sql", "value_column","some_name"); -... - - -
- -
- <varname>counter_column</varname> (string) - - The column where the counter value will be stored - - - - Set <varname>counter_column</varname> parameter - -... -modparam("cachedb_sql", "counter_column","some_name"); -... - - -
- -
- <varname>expires_column</varname> (string) - - The column where the expires will be stored - - - - Set <varname>expires_column</varname> parameter - -... -modparam("cachedb_sql", "expires_column","some_name"); -... - - -
- -
- <varname>cache_clean_period</varname> (int) - - The interval in seconds at which the expired keys will be removed from - the database. Default value is 60 ( seconds ) - - - - Set <varname>cache_clean_period</varname> parameter - -... -modparam("cachedb_sql", "cache_clean_period",10); -... - - -
- -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- - -
- -
- diff --git a/modules/cachedb_sql/doc/cachedb_sql_faq.xml b/modules/cachedb_sql/doc/cachedb_sql_faq.xml deleted file mode 100644 index f2494104bd7..00000000000 --- a/modules/cachedb_sql/doc/cachedb_sql_faq.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - &faqguide; - - - - - - What happened with the old db_url module parameter? - - - - It was replaced with the cachedb_url parameter. - See the documentation for the usage of the cachedb_url parameter. - - - - - - - - diff --git a/modules/cachedb_sql/doc/contributors.xml b/modules/cachedb_sql/doc/contributors.xml deleted file mode 100644 index 3a74e6e37c7..00000000000 --- a/modules/cachedb_sql/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 16 - 5 - 1001 - 87 - - - 2. - Liviu Chircu (@liviuchircu) - 11 - 9 - 42 - 59 - - - 3. - Razvan Crainea (@razvancrainea) - 7 - 5 - 4 - 2 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 5 - 2 - - - 5. - Alexandra Titoc - 4 - 2 - 4 - 3 - - - 6. - Maksym Sobolyev (@sobomax) - 4 - 2 - 1 - 2 - - - 7. - Dusan Klinec (@ph4r05) - 3 - 1 - 2 - 2 - - - 8. - Julián Moreno Patiño - 3 - 1 - 2 - 2 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Ovidiu Sas (@ovidiusas) - Apr 2022 - Apr 2022 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 5. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/call_center/README b/modules/call_center/README deleted file mode 100644 index ed8f0050a52..00000000000 --- a/modules/call_center/README +++ /dev/null @@ -1,1182 +0,0 @@ -Call-Center Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - - 1.2.1. DB tables - 1.2.2. Call Flows - 1.2.3. Agents - - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. db_url (string) - 1.4.2. acc_db_url (string) - 1.4.3. rt_db_url (string) - 1.4.4. wrapup_time (integer) - 1.4.5. queue_pos_param (string) - 1.4.6. reject_on_no_agents (int) - 1.4.7. chat_dispatch_policy (int) - 1.4.8. internal_call_dispatching (int) - 1.4.9. cc_agents_table (string) - 1.4.10. cca_agentid_column (string) - 1.4.11. cca_location_column (string) - 1.4.12. cca_msrp_location_column (string) - 1.4.13. cca_msrp_max_sessions_column (string) - 1.4.14. cca_skills_column (string) - 1.4.15. cca_logstate_column (string) - 1.4.16. cca_wrapuptime_column (string) - 1.4.17. cca_wrapupend_column (string) - 1.4.18. cc_flows_table (string) - 1.4.19. ccf_flowid_column (string) - 1.4.20. ccf_priority_column (string) - 1.4.21. ccf_skill_column (string) - 1.4.22. ccf_cid_column (string) - 1.4.23. ccf_max_wrapup_column (string) - 1.4.24. ccf_dissuading_hangup_column (string) - 1.4.25. ccf_dissuading_onhold_th_column (string) - 1.4.26. ccf_dissuading_ewt_th_column (string) - 1.4.27. ccf_dissuading_qsize_th_column (string) - 1.4.28. ccf_m_welcome_column (string) - 1.4.29. ccf_m_queue_column (string) - 1.4.30. ccf_m_dissuading_column (string) - 1.4.31. ccf_m_flow_id_column (string) - 1.4.32. b2b_logic_ctx_param (string) - - 1.5. Exported Functions - - 1.5.1. cc_handle_call( flowID [,param]) - 1.5.2. cc_agent_login(agentID, state) - - 1.6. Exported Statistics - - 1.6.1. Global statistics - 1.6.2. Per-flow statistics (one set for each flow) - 1.6.3. Per-agent statistics (one set for each agent) - - 1.7. Exported MI Functions - - 1.7.1. cc_reload - 1.7.2. cc_agent_login - 1.7.3. cc_list_queue - 1.7.4. cc_list_flows - 1.7.5. cc_list_agents - 1.7.6. cc_list_calls - 1.7.7. cc_dispatch_call_to_agent - 1.7.8. cc_internal_call_dispatching - 1.7.9. cc_reset_stats - - 1.8. Exported Events - - 1.8.1. E_CALLCENTER_AGENT_REPORT - - 1.9. Exported Pseudo-Variables - - 2. Developer Guide - - 2.1. Available Functions - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set acc_db_url parameter - 1.3. Set rt_db_url parameter - 1.4. Set wrapup_time parameter - 1.5. Set queue_pos_param parameter - 1.6. Set reject_on_no_agents parameter - 1.7. Set chat_dispatch_policy parameter - 1.8. Set internal_call_dispatching parameter - 1.9. Set cc_agents_table parameter - 1.10. Set cca_agentid_column parameter - 1.11. Set cca_location_column parameter - 1.12. Set cca_msrp_location_column parameter - 1.13. Set cca_msrp_max_sessions_column parameter - 1.14. Set cca_skills_column parameter - 1.15. Set cca_logstate_column parameter - 1.16. Set cca_wrapuptime_column parameter - 1.17. Set cca_wrapupend_column parameter - 1.18. Set cc_flows_table parameter - 1.19. Set ccf_flowid_column parameter - 1.20. Set ccf_priority_column parameter - 1.21. Set ccf_skill_column parameter - 1.22. Set ccf_cid_column parameter - 1.23. Set ccf_max_wrapup_column parameter - 1.24. Set ccf_dissuading_hangup_column parameter - 1.25. Set ccf_dissuading_onhold_th_column parameter - 1.26. Set ccf_dissuading_ewt_th_column parameter - 1.27. Set ccf_dissuading_qsize_th_column parameter - 1.28. Set ccf_m_welcome_column parameter - 1.29. Set ccf_m_queue_column parameter - 1.30. Set ccf_m_dissuading_column parameter - 1.31. Set ccf_m_flow_id_column parameter - 1.32. Set b2b_logic_ctx_param parameter - 1.33. cc_handle_call usage - 1.34. cc_agent_login usage - 1.35. $rtpquery Usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Call Center module implements an inbound call center system - with call flows (for queuing the received calls) and agents - (for answering the calls). - - The module implements the queuing system, the call distribution - to agents, agents managements, CDRs for the calls, statistics - on call distribution and agent's activity - basically - everything except the media playback (for the queue). This part - must be provided via a third party media server (FreeSwitch, - Asterisk or others). - - This is actually a Contact Center and it is able to handle both - RTP/audio calls and (multiple) MSRP/chat calls, in the same - time. - - The module provides an internal buit-in dispatching logic (for - sending the calls/chats to the agents), but also offers the - possibility to use an external logic to do the dispatching (see - cc_dispatch_call_to_agent MI command). - -1.2. How it works - - The main entities in the modules are the flows (queues) and - agents. - -1.2.1. DB tables - - Each entity has a corresponding table in the database, for - provisioning purposes - the cc_flows and cc_agents tables, see - DB schema. Data is loaded at startup and cached into memory ; - runtime reload is possible via the MI commands (see the - cc_reload command in Exported MI Functions). - - Additionally there is a table cc_cdrs for writing the CDRs - - this operation is done in realtime, after the call in - completed, covering all possible cases: call was dropped while - in queue, call was rejected by agent, call was accepted by - agent, call terminated with error - NOTE that a call may - generate more than one CDR (like call rejected by agent A, and - redistributed and accepted by agent B). - - The cc_calls table is used to store ongoing calls, regardless - it's state (in queue, to the agent, ended). It is populated at - runtime by the module and queried at startup. This table should - not be manually provisioned. - -1.2.2. Call Flows - - A flow is defined by a unique alphanumerical ID - the main - attribute of a flow is the skill - the skill is a capability - required by the flow for an agent to be able to answer the call - ; the concept of skills is the link between the flows and the - agents - telling what agents are serving what flows - the flows - require a skill, while the agents provide a set of skills. - Agents matching the required skill of a flow will automatically - receive calls from that flow. - - Additional, the flow has a priority - as agents may server - multiple flows in the same time (based on skills), you can - define priorities between the flows - if the flows has a higher - priority, its calls will be pushed (in deliver to agents and - queuing) in front of the calls from flows with a lower - priority. - - Configurable per flow, the module may do per-flow call - dissuading; this means to redirect a call to another - destination, if the queue/flow is overloaded: - * if the number of calls already in the queue exceeds the - diss_qsize_th threshold - * if the estimated time to wait of the queue exceeds the - diss_ewt_th threshold - * if the call was waiting in the queue for longer than - diss_onhold_th threshold - - Optionally, the flow may define a prependcid - a prefix to be - added to the CLI (Caller ID) when the call is delivered to the - agents - as an agent may receive call from multiple flows, it - is important for the user to see which was the queue a call was - received. - - In terms of media announcements, the flow defines the - message_welcome (optional, to be played in the call, before - doing anything with the call) and message_queue (mandatory, the - looping message providing infinite on hold media IMPORTANT - - this message must cycle and media server must never hung up on - it. Both announcements are provided as SIP URIs (where the call - has to be sent in order to get the playback). - - The flow also has an optional max_wrapup time, which acts as an - upper limit for the per-agent/global value (the flow forces a - ceiling of the wrapup value for all its calls). - -1.2.3. Agents - - An agent is defined by a unique alphanumerical ID - the main - attribute of an agent is its the set of skills. This set of - skills will tell what calls to be received (from which flows, - based on the skill matching). - - The agent may provide support for different optional media - types, like RTP/audio or MSRP/chat. Each supported media type - comes with the maximum supported number of sessions. Of course, - for audio the `1` value is hardocded. On the SIP side, each - media type comes with a locations. The location is a SIP URI - where to calls must be sent in order to be answered by the - agent. At least one media type should be defined. To specify - which media the agent support, just define the corresponding - SIP location in his profile. - - So, at a certain time, an agent may handle either a single - call, either several chat sessions. - - Additionally, the agent has a initial logstate - if he is - logged in or not (being logged in is a must in order to receive - calls). The log state may be changed at runtime via a dedicated - MI command cc_agent_login, see Exported MI Functions. - - There is an optional per-agent wrapup_time defined, saying the - time interval for an agent before getting a new call from the - system (after he finished a call). If no value is defined for - the agent, the global wrapup_time will be used. Note that the - resulting value may be upper limited by the per-flow - max_wrapup_time if defined. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * b2b_logic - B2bUA module - * database - one of the SQL DB modules - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. db_url (string) - - SQL address to the DB server -- database specific. This must be - the Database holding the provisioning tables (cc_flows, - cc_agents and cc_calls tables). - If not explicitly set, the global OpenSIPS DB URL will be used. - - Example 1.1. Set db_url parameter -... -modparam("call_center", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - -1.4.2. acc_db_url (string) - - SQL address to the DB server -- database specific. This must be - the Database where the CDRs table (cc_cdrs) is located. - If not explicitly set, the global OpenSIPS DB URL will be used. - - Example 1.2. Set acc_db_url parameter -... -modparam("call_center", "acc_db_url", - "mysql://opensips:opensipsrw@localhost/opensips_cdrs") -... - -1.4.3. rt_db_url (string) - - SQL address/URL of the DB server (database specific) where the - runtime tables (non provisioning tables) are located. The - runtime tables are the tables populated by OpenSIPS with data - learned during runtime. To be more specific, the only runtime - table we have so far is the "cc_calls" table. - If not explicitly set, the global OpenSIPS DB URL will be used. - - Example 1.3. Set rt_db_url parameter -... -modparam("call_center", "rt_db_url", - "mysql://opensips:opensipsrw@localhost/opensips_runtime") -... - -1.4.4. wrapup_time (integer) - - Time for an agent between finishing a call and receiving the - next call from the system. Even if there are queued calls, the - module will not deliver call to agent during this wrapup - interval. - - This value may be overwritten by the per-agent value (if - defined) and furher more, by the per-flow value (if defined). - - Default value is “30 seconds”. - - Example 1.4. Set wrapup_time parameter -... -modparam("call_center", "wrapup_time", 45) -... - -1.4.5. queue_pos_param (string) - - The name of an SIP URI parameter to be used to report the - position in the waiting queue when sending the call to media - server for onwait/queue playback. The position 0 means it is - the next call to be delivered to an agent. - - Default value is “empty(none)”. - - Example 1.5. Set queue_pos_param parameter -... -modparam("call_center", "queue_pos_param", "cc_pos") -... - -1.4.6. reject_on_no_agents (int) - - A parameter to tell if an incoming call should be rejected or - quueued if there are no logged in agents. Basically this allows - call queueing on flows with no agents yet. - - Default value is “1 (true)”. - - Example 1.6. Set reject_on_no_agents parameter -... -modparam("call_center", "reject_on_no_agents", 0) -... - -1.4.7. chat_dispatch_policy (int) - - A parameter to tell what should be the policy on dispatching - the chat/MSRP sessions to the agents, considering that an agent - may handle multiple such sessions/chats in the same time. - - Options are: - * balancing - the distribution will try to be even across the - agents, but by doing this you may end up waisting chat - sessions on agents and call starvation - agents are - partially used by chat sessions, so they cannot take calls - (of course, if you have mixed agetns with audio/chat) - * full-load - the distribution will try to make usage of an - agent in the best possible way when comes to chat sessions - - once the agent take a chat, all the following chats will - be assigned ot him - the idea is to try to be efficient in - using the resource/sessions of an agents, to leave as much - room as possible for calls. Of course, this may lead to an - un-even loading of chat agents - some will be full, others - empty. - - Default value is “balancing”. - - Example 1.7. Set chat_dispatch_policy parameter -... -modparam("call_center", "chat_dispatch_policy", "balancing") -... - -1.4.8. internal_call_dispatching (int) - - A parameter to tell if the internal/buit-in call dispatching to - agent should be used or not. If enabled, the module will - automatically dispatch (by itself) the queued/incoming calls to - the available agents. If disabled, the module will not do such - dispaching by itself and it is expected to use the - cc_dispatch_call_to_agent MI command to dispatch the queued - calls to agents. This allows the implementation of an external, - custom dispatching logic. The value of this setting may be - changed during runtime via the cc_internal_call_dispatching MI - command. - - Default value is “1” (enabled). - - Example 1.8. Set internal_call_dispatching parameter -... -modparam("call_center", "internal_call_dispatching", 0) -... - -1.4.9. cc_agents_table (string) - - Name to be used for the table holding the agents. - - Default value is “cc_agents”. - - Example 1.9. Set cc_agents_table parameter -... -modparam("call_center", "cc_agents_table", "my_agents") -... - -1.4.10. cca_agentid_column (string) - - Name to be used for the "agent id" (unique DB id) column in the - agents table. - - Default value is “agentid”. - - Example 1.10. Set cca_agentid_column parameter -... -modparam("call_center", "cca_agentid_column", "cid") -... - -1.4.11. cca_location_column (string) - - Name to be used for the calling/audio "location" (SIP URI) - column in the agents table. - - Default value is “location”. - - Example 1.11. Set cca_location_column parameter -... -modparam("call_center", "cca_location_column", "sip_uri") -... - -1.4.12. cca_msrp_location_column (string) - - Name to be used for the msrp/chat "location" (SIP URI) column - in the agents table. - - Default value is “msrp_location”. - - Example 1.12. Set cca_msrp_location_column parameter -... -modparam("call_center", "cca_msrp_location_column", "sip_uri") -... - -1.4.13. cca_msrp_max_sessions_column (string) - - Name to be used for the column (in the agents table) holding - the maximum number of chat sessions that can be handled by the - agent. - - Default value is “msrp_max_sessions”. - - Example 1.13. Set cca_msrp_max_sessions_column parameter -... -modparam("call_center", "cca_msrp_max_sessions_column", "max_chats") -... - -1.4.14. cca_skills_column (string) - - Name to be used for the "skills" (list of skills) column in the - agents table. - - Default value is “skills”. - - Example 1.14. Set cca_skills_column parameter -... -modparam("call_center", "cca_skills_column", "skills") -... - -1.4.15. cca_logstate_column (string) - - Name to be used for the "logstate" (original login state) - column in the agents table. - - Default value is “logstate”. - - Example 1.15. Set cca_logstate_column parameter -... -modparam("call_center", "cca_logstate_column", "log_state") -... - -1.4.16. cca_wrapuptime_column (string) - - Name to be used for the "wrapuptime" (per-agent wrapup time) - column in the agents table. - - Default value is “wrapup_time”. - - Example 1.16. Set cca_wrapuptime_column parameter -... -modparam("call_center", "cca_wrapuptime_column", "wtime") -... - -1.4.17. cca_wrapupend_column (string) - - Name to be used for the "wrapupend" (timestamp when the wrapup - ends) column in the agents table. - - Default value is “wrapup_end_time”. - - Example 1.17. Set cca_wrapupend_column parameter -... -modparam("call_center", "cca_wrapupend_column", "wrapup_ends") -... - -1.4.18. cc_flows_table (string) - - Name to be used for the table holding the definition of the - flows/queues. - - Default value is “cc_flows”. - - Example 1.18. Set cc_flows_table parameter -... -modparam("call_center", "cc_flows_table", "queues") -... - -1.4.19. ccf_flowid_column (string) - - Name to be used for the "flow id" (unique DB id) column in the - flows table. - - Default value is “flowid”. - - Example 1.19. Set ccf_flowid_column parameter -... -modparam("call_center", "ccf_flowid_column", "queue_id") -... - -1.4.20. ccf_priority_column (string) - - Name to be used for the "priority" column in the flows table. - - Default value is “priority”. - - Example 1.20. Set ccf_priority_column parameter -... -modparam("call_center", "ccf_priority_column", "queue_prio") -... - -1.4.21. ccf_skill_column (string) - - Name to be used for the "skill" column in the flows table. - - Default value is “skill”. - - Example 1.21. Set ccf_skill_column parameter -... -modparam("call_center", "ccf_skill_column", "queue_skill") -... - -1.4.22. ccf_cid_column (string) - - Name to be used for the "caller ID prefix" column in the flows - table. - - Default value is “prependcid”. - - Example 1.22. Set ccf_cid_column parameter -... -modparam("call_center", "ccf_cid_column", "queue_cli_prefix") -... - -1.4.23. ccf_max_wrapup_column (string) - - Name to be used for the "max limit for wrapup time" column in - the flows table. - - Default value is “max_wrapup_time”. - - Example 1.23. Set ccf_max_wrapup_column parameter -... -modparam("call_center", "ccf_max_wrapup_column", "queue_wrapup") -... - -1.4.24. ccf_dissuading_hangup_column (string) - - Name to be used for the "hangup after dissuading" column in the - flows table. - - Default value is “dissuading_hangup”. - - Example 1.24. Set ccf_dissuading_hangup_column parameter -... -modparam("call_center", "ccf_dissuading_hangup_column", "hangup_on_dissu -ading") -... - -1.4.25. ccf_dissuading_onhold_th_column (string) - - Name to be used for the "on-hold dissuading threshold" column - in the flows table. - - Default value is “dissuading_onhold_th”. - - Example 1.25. Set ccf_dissuading_onhold_th_column parameter -... -modparam("call_center", "ccf_dissuading_onhold_th_column", "th_diss_onho -ld") -... - -1.4.26. ccf_dissuading_ewt_th_column (string) - - Name to be used for the "EWT dissuading threshold" column in - the flows table. - - Default value is “dissuading_ewt_th”. - - Example 1.26. Set ccf_dissuading_ewt_th_column parameter -... -modparam("call_center", "ccf_dissuading_ewt_th_column", "th_diss_ewt") -... - -1.4.27. ccf_dissuading_qsize_th_column (string) - - Name to be used for the "queue size dissuading threshold" - column in the flows table. - - Default value is “dissuading_qsize_th”. - - Example 1.27. Set ccf_dissuading_qsize_th_column parameter -... -modparam("call_center", "ccf_dissuading_qsize_th_column", "th_diss_qsize -") -... - -1.4.28. ccf_m_welcome_column (string) - - Name to be used for the "audio message on welcome" column in - the flows table. - - Default value is “message_welcome”. - - Example 1.28. Set ccf_m_welcome_column parameter -... -modparam("call_center", "ccf_m_welcome_column", "audio_welcome") -... - -1.4.29. ccf_m_queue_column (string) - - Name to be used for the "audio message on queueing" column in - the flows table. - - Default value is “message_queue”. - - Example 1.29. Set ccf_m_queue_column parameter -... -modparam("call_center", "ccf_m_queue_column", "audio_queue") -... - -1.4.30. ccf_m_dissuading_column (string) - - Name to be used for the "audio message on dissuading" column in - the flows table. - - Default value is “message_dissuading”. - - Example 1.30. Set ccf_m_dissuading_column parameter -... -modparam("call_center", "ccf_m_dissuading_column", "audio_dissuading") -... - -1.4.31. ccf_m_flow_id_column (string) - - Name to be used for the "audio message on identifying the flow" - column in the flows table. - - Default value is “message_flow_id”. - - Example 1.31. Set ccf_m_flow_id_column parameter -... -modparam("call_center", "ccf_m_flow_id_column", "audio_flow_id") -... - -1.4.32. b2b_logic_ctx_param (string) - - The name of the $b2b_logic.ctx variable that can be used to - retrieve the value of the parameter passed to the - cc_handle_call function. - - This parameter will be copied throughout all the B2B scenarios - started by the call_center module. NOTE that you can change the - value of the current scenario by writing into it, but the - change will not be reflected in a different scenario. - - Default value is “call_center”. - - Example 1.32. Set b2b_logic_ctx_param parameter -... -modparam("call_center", "b2b_logic_ctx_param", "b2b_callid") -... -route[handle_call_center] { - ... - cc_handle_call("flow", $ci); - ... -} -... -route[b2b_handle_request] { - ... - xlog("Initial Callid is $b2b_logic.ctx(b2b_callid)\n"); - ... -} - -1.5. Exported Functions - -1.5.1. cc_handle_call( flowID [,param]) - - This must be used only for initial INVITE requests - the - function pushes the call to be handled by the call center - module (via a certain flow/queue). - - This function can be used from REQUEST_ROUTE. - - Parameters: - * flowID (string) - the ID of the flow to handle this call - (push the call to that flow). - * param (string, optional) - an opaque string to be passed as - parameter to the "callcenter" and "agent" B2B scenarios. It - is intended for custom integration of the call center - module and it is 100% up to the script writer about the - value and purpose of this parameter, OpenSIPS will not - touch or interpret it. You can retrieve the value of this - parameter using the $b2b_logic.ctx variable with the name - defined in the b2b_logic_ctx_param parameter. - - The function returns TRUE back to the script if the call was - successfully pushed and handled by the Call Center engine. - IMPORTANT: you must not do any signaling on the call (reply, - relay) after this point. - - In case of error, FALSE is returned to the script with the - following return codes: - * -1 - unable to get the flow ID from the parameter; - * -2 - unable to parse the FROM URI; - * -3 - flow with FlowID not found; - * -4 - no agents logged in the flow; - * -5 - internal error; - - Example 1.33. cc_handle_call usage -... -if (is_method("INVITE") and !has_totag()) { - if (!cc_handle_call("tech_support")) { - send_reply(403,"Cannot handle call"); - exit; - } -} -... - -1.5.2. cc_agent_login(agentID, state) - - This function sets the login (on or off) state for an agent. - - This function can be used from REQUEST_ROUTE. - - Parameters: - * agentID (string) - the ID of the agent - * state (int) - an integer value giving the new state - 0 - means logged off, anything else means logged in. - - Example 1.34. cc_agent_login usage -... -# log off the 'agentX' agent -cc_agent_login("agentX",0); -... - -1.6. Exported Statistics - -1.6.1. Global statistics - -1.6.1.1. ccg_incalls - - Total number of received calls. (counter type) - -1.6.1.2. ccg_awt - - Global avg. waiting time for calls. (realtime type) - -1.6.1.3. ccg_load - - Global load (across all flows). (realtime type) - -1.6.1.4. ccg_distributed_incalls - - Total number of distributed calls. (counter type) - -1.6.1.5. ccg_answered_incalls - - Total number of calls (audio/RTP and chat/MSRP) answered by - agents. (counter type) - -1.6.1.6. ccg_answered_inchats - - Total number of chat/MSRP only calls answered by agents. - (counter type) - -1.6.1.7. ccg_abandonned_incalls - - Total number of calls terminated by caller before being - answered by agents. (counter type) - -1.6.1.8. ccg_onhold_calls - - Total number of calls (audio/RTP and chat/MSRP) in the queues - (onhold). (realtime type) - -1.6.1.9. ccg_onhold_chats - - Total number of chat/MSRP only calls in the queues (onhold). - (realtime type) - -1.6.1.10. ccg_free_agents - - Total number of free agents (across all flows). (realtime type) - -1.6.2. Per-flow statistics (one set for each flow) - -1.6.2.1. ccf_incalls_flowID - - Number of received calls for the flow. (counter type) - -1.6.2.2. ccf_dist_incalls_flowID - - Number of distributed calls in this flow. (counter type) - -1.6.2.3. ccf_answ_incalls_flowID - - Nnumber of calls (audio/RTP and chat/MSRP) from the flow - answered by agents. (counter type) - -1.6.2.4. ccf_answ_incalls_flowID - - Nnumber of chat/MSRP only calls from the flow answered by - agents. (counter type) - -1.6.2.5. ccf_aban_incalls_flowID - - Number of calls (from the flow) terminated by caller before - being answered by agents. (counter type) - -1.6.2.6. ccf_onhold_incalls_flowID - - Number of calls (audio/RTP and chat/MSRP) -from the flow- which - are onhold. (realtime type) - -1.6.2.7. ccf_onhold_inchats_flowID - - Number of chat/MSRP only calls -from the flow- which are - onhold. (realtime type) - -1.6.2.8. ccf_queued_calls_flowID - - Number of calls which are queued for this flow. (realtime type) - -1.6.2.9. ccf_free_agents_flowID - - Number of free agents serving this flow. (realtime type) - -1.6.2.10. ccf_etw_flowID - - Estimated Time to Wait for this flow. (realtime type) - -1.6.2.11. ccf_awt_flowID - - Avg. Wating Time for this flow. (realtime type) - -1.6.2.12. ccg_load_flowID - - The load on the flow (number of queued calls versus number of - logged agents). (realtime type) - -1.6.3. Per-agent statistics (one set for each agent) - -1.6.3.1. cca_dist_incalls_agnetID - - Number of distributed calls to this agent. (counter type) - -1.6.3.2. cca_answ_incalls_agentID - - Number of calls (audio/RTP and chat/MSRP) answered by the - agent. (counter type) - -1.6.3.3. cca_answ_inchats_agentID - - Number of chat/MSRP only calls answered by the agent. (counter - type) - -1.6.3.4. cca_aban_incalls_agentID - - Number of calls (sent to this agent) terminated by caller - before being answered by agents. (counter type) - -1.6.3.5. cca_att_agentID - - Avg. Talk Time for this agent (realtime type) - -1.7. Exported MI Functions - -1.7.1. cc_reload - - Command to reload flows and agents definition from database. - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_reload - -1.7.2. cc_agent_login - - Command to login an agent into the Call Center engine. - - Parameters: - * agent_id - ID of the agent - * state - the new login state (0 - log off, 1 - log in) - - MI FIFO Command usage: -opensips-cli -x mi cc_agent_login agentX 0 - -1.7.3. cc_list_queue - - Command to list all the calls in queuing - for each call, the - following attributes will be printed: the call id, the calling - user info, the flow of the call, for how long the call is in - the queue, the ETW for the call, call priority and the call - skill (inherited from the flow). - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_list_queue - -1.7.4. cc_list_flows - - Command to list all the flows - for each flow, the following - attributes will be printed: the flow ID, the avg. call - duration, how many calls were processed, how many agents are - logged, and how many onging calls are. - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_list_flows - -1.7.5. cc_list_agents - - Command to list all the agents - for each agent, the following - attributes will be printed: agent ID, agent login state, agent - state (free, wrapup, incall) and info on ongoing sessions. - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_list_agents - -1.7.6. cc_list_calls - - Command to list all the ongoing calls - for each call, the - following attributes will be printed: call ID, call state - (welcome, queued, toagent, ended), call duration, flow it - belongs to, agent serving the call (if any). - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_list_agents - -1.7.7. cc_dispatch_call_to_agent - - This function sends a given call (from the queue) to a given - agent. For the operation to succeed, several conditions must be - met: - * the call must be in the queue - * the agent must be logged in - * the agent must support the skill required by the call - * the agent must support the media (RTP/MSRP) requiref by the - call - * the agent must have available sessions for the requested - media - - It takes two parameters. - * call_id - the ID of the call, as provided by the queue - listing MI command cc_list_queue - * agent_id - the ID of the call, as provided by the agents - listing MI command cc_list_agents - - IMPORTANT: in order to be used, you need to be sure that the - internal call dispatching is DISABLED via the - chat_internal_call_dispatching module parameter or the - cc_internal_call_dispatching MI command. - - MI FIFO Command usage: -opensips-cli -x mi cc_dispatch_call_to_agent B2B452.dee2.33 agentX - -1.7.8. cc_internal_call_dispatching - - Command to inspect and/or change the - chat_internal_call_dispatching setting - - It takes one optional parameter dispatching if the value of the - setting should be changed. A 0 value means disabling the - internal dispatching, a non zero means to enable it. - - MI FIFO Command usage: -opensips-cli -x mi cc_internal_call_dispatching 0 - -1.7.9. cc_reset_stats - - Command to reset all counter-like statistics. - - It takes no parameter. - - MI FIFO Command usage: -opensips-cli -x mi cc_reset_stats - -1.8. Exported Events - -1.8.1. E_CALLCENTER_AGENT_REPORT - - This event is raised when the status of an agent changes. - - Parameters: - * agent_id - the id of the agent. - * state - the status of the agent: - + offline - + free - + incall - + wrapup - * wrapup_ends - the timestamp when the wrapup state will end; - published only if the state is "wrapup" - * flow_id - the flow ID that delivered the call for this - agent; published only if the state is "incall" - -1.9. Exported Pseudo-Variables - -1. $cc_state - - Returns the state of a call. - - Possible values returned are: - - * welcome - the welcome message is played. - * dissuading1 - the first dissuading message is played. - * dissuading2 - the second dissuading message is played. - * queue - the call is in queue. - * preagent - the agent is being called. - * toagent - the agent is in call. - - Example 1.35. $rtpquery Usage -... - $json(reply) := $rtpquery; - xlog("Total RTP Stats: $json(reply/totals)\n"); -... - - NONE - -Chapter 2. Developer Guide - -2.1. Available Functions - - NONE - -Chapter 3. Frequently Asked Questions - - 3.1. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 3.2. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 3.3. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 110 44 6780 511 - 2. Razvan Crainea (@razvancrainea) 45 34 849 159 - 3. Vlad Patrascu (@rvlad-patrascu) 18 9 287 314 - 4. Liviu Chircu (@liviuchircu) 15 12 73 90 - 5. Maksym Sobolyev (@sobomax) 6 4 8 13 - 6. Walter Doekes (@wdoekes) 4 2 1 2 - 7. Peter Lemenkov (@lemenkov) 4 2 1 1 - 8. Vlad Paiu (@vladpaiu) 3 1 13 4 - 9. Alexandra Titoc 3 1 4 4 - 10. Dusan Klinec (@ph4r05) 3 1 1 1 - - All remaining contributors: Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jun 2014 - Aug 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 4. Razvan Crainea (@razvancrainea) Mar 2014 - Oct 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2014 - May 2023 - 6. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jan 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Sep 2018 - 10. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - - All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Zero - King (@l2dy), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2014 www.opensips-solutions.com diff --git a/modules/call_center/README.md b/modules/call_center/README.md new file mode 100644 index 00000000000..006e9751ee2 --- /dev/null +++ b/modules/call_center/README.md @@ -0,0 +1,1306 @@ +--- +title: "Call-Center Module" +description: "The Call Center module implements an inbound call center system with call flows (for queuing the received calls) and agents (for answering the calls)." +--- + +## Admin Guide + + +### Overview + + +The Call Center module implements an inbound call center system with call +flows (for queuing the received calls) and agents (for answering the +calls). + + +The module implements the queuing system, the call distribution +to agents, agents managements, CDRs for the calls, statistics on +call distribution and agent's activity - basically everything +except the media playback (for the queue). This part must be provided via +a third party media server (FreeSwitch, Asterisk or others). + + +This is actually a Contact Center and it is able to handle both +RTP/audio calls and (multiple) MSRP/chat calls, in the same time. + + +The module provides an internal buit-in dispatching logic (for sending the +calls/chats to the agents), but also offers the possibility to use an +external logic to do the dispatching +(see [mi cc dispatch call to agent](#mi_cc_dispatch_call_to_agent) MI command). + + +### How it works + + +The main entities in the modules are the flows (queues) and agents. + + +#### DB tables + + +Each entity has a corresponding table in the database, for +provisioning purposes - the *cc_flows* and +*cc_agents* tables, see +[DB schema](https://docs.opensips.org/manual/3-6/install-dbschema/). +Data is loaded at startup and cached into memory ; runtime reload is +possible via the MI commands (see the *cc_reload* +command in [exported mi functions](#exported_mi_functions)). + + +Additionally there is a table *cc_cdrs* for writing +the CDRs - this operation is done in realtime, after the call in +completed, covering all possible cases: call was dropped while in +queue, call was rejected by agent, call was accepted by agent, call +terminated with error - NOTE that a call may generate more than one +CDR (like call rejected by agent A, and redistributed and accepted by +agent B). + + +The *cc_calls* table is used to store ongoing calls, +regardless it's state (in queue, to the agent, ended). It is populated +at runtime by the module and queried at startup. This table should not +be manually provisioned. + + +#### Call Flows + + +A flow is defined by a unique alphanumerical ID - the main attribute +of a flow is the *skill* - the skill is a +capability required by the flow for an agent to be able to answer the +call ; the concept of *skills* is the link between +the flows and the agents - telling what agents are serving what flows + - the flows require a skill, while the agents provide a set of skills. +Agents matching the required skill of a flow will automatically +receive calls from that flow. + + +Additional, the flow has a *priority* - as agents +may server multiple flows in the same time (based on skills), you can +define priorities between the flows - if the flows has a higher +priority, its calls will be pushed (in deliver to agents and queuing) in +front of the calls from flows with a lower priority. + + +Configurable per flow, the module may do per-flow call dissuading; this +means to redirect a call to another destination, if the queue/flow +is overloaded: + + +- if the number of calls already in the queue exceeds the diss_qsize_th threshold +- if the estimated time to wait of the queue exceeds the diss_ewt_th threshold +- if the call was waiting in the queue for longer than diss_onhold_th threshold + + +Optionally, the flow may define a *prependcid* - a +prefix to be added to the CLI (Caller ID) when the call is delivered to +the agents - as an agent may receive call from multiple flows, it is +important for the user to see which was the queue a call was received. + + +In terms of media announcements, the flow defines the +*message_welcome* (optional, to be played in the +call, before doing anything with the call) and +*message_queue* (mandatory, the looping message +providing infinite on hold media IMPORTANT - this message must cycle +and media server must never hung up on it. Both announcements are +provided as SIP URIs (where the call has to be sent in order to get +the playback). + + +The flow also has an optional *max_wrapup time*, +which acts as an upper limit for the per-agent/global value (the flow +forces a ceiling of the wrapup value for all its calls). + + +#### Agents + + +An agent is defined by a unique alphanumerical ID - the main attribute +of an agent is its the set of *skills*. This set of +skills will tell what calls to be received (from which flows, based on +the skill matching). + + +The agent may provide support for different optional media types, like +RTP/audio or MSRP/chat. Each supported media type comes with the +maximum supported number of sessions. Of course, for audio the `1` +value is hardocded. On the SIP side, each media type comes with a +*locations*. The location is a SIP URI where to +calls must be sent in order to be answered by the agent. At least one +media type should be defined. To specify which media the agent +support, just define the corresponding SIP location in his profile. + + +So, at a certain time, an agent may handle either a single call, +either several chat sessions. + + +Additionally, the agent has a initial *logstate* - +if he is logged in or not (being logged in is a must in order to +receive calls). The log state may be changed at runtime via a +dedicated MI command *cc_agent_login*, see +[exported mi functions](#exported_mi_functions). + + +There is an optional per-agent *wrapup_time* +defined, saying the time interval for an agent before getting a new +call from the system (after he finished a call). If no value is defined +for the agent, the global *wrapup_time* will be +used. Note that the resulting value may be upper limited by the +per-flow *max_wrapup_time* if defined. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *b2b_logic* - B2bUA module +- *database* - one of the SQL DB modules + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +SQL address to the DB server -- database specific. This must be +the Database holding the provisioning tables (cc_flows, cc_agents +and cc_calls tables). + + +```opensips title="Set db_url parameter" +... +modparam("call_center", "db_url", + "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### acc_db_url (string) + + +SQL address to the DB server -- database specific. This must be +the Database where the CDRs table (cc_cdrs) is located. + + +```opensips title="Set acc_db_url parameter" +... +modparam("call_center", "acc_db_url", + "mysql://opensips:opensipsrw@localhost/opensips_cdrs") +... +``` + + +#### rt_db_url (string) + + +SQL address/URL of the DB server (database specific) where the +runtime tables (non provisioning tables) are located. The +runtime tables are the tables populated by OpenSIPS with data +learned during runtime. To be more specific, the only runtime +table we have so far is the "cc_calls" table. + + +```opensips title="Set rt_db_url parameter" +... +modparam("call_center", "rt_db_url", + "mysql://opensips:opensipsrw@localhost/opensips_runtime") +... +``` + + +#### wrapup_time (integer) + + +Time for an agent between finishing a call and receiving the next +call from the system. Even if there are queued calls, the module +will not deliver call to agent during this wrapup interval. + + +This value may be overwritten by the per-agent value (if defined) +and furher more, by the per-flow value (if defined). + + +*Default value is "30 seconds".* + + +```opensips title="Set wrapup_time parameter" +... +modparam("call_center", "wrapup_time", 45) +... +``` + + +#### queue_pos_param (string) + + +The name of an SIP URI parameter to be used to report the position +in the waiting queue when sending the call to media server for +onwait/queue playback. The position 0 means it is the next call +to be delivered to an agent. + + +*Default value is "empty(none)".* + + +```opensips title="Set queue_pos_param parameter" +... +modparam("call_center", "queue_pos_param", "cc_pos") +... +``` + + +#### reject_on_no_agents (int) + + +A parameter to tell if an incoming call should be rejected or +quueued if there are no logged in agents. Basically this allows +call queueing on flows with no agents yet. + + +*Default value is "1 (true)".* + + +```opensips title="Set reject_on_no_agents parameter" +... +modparam("call_center", "reject_on_no_agents", 0) +... +``` + + +#### chat_dispatch_policy (int) + + +A parameter to tell what should be the policy on dispatching the +chat/MSRP sessions to the agents, considering that an agent may +handle multiple such sessions/chats in the same time. + + +Options are: + + +- **balancing** - the distribution +will try to be even across the agents, but by doing this you may +end up waisting chat sessions on agents and call starvation - +agents are partially used by chat sessions, so they cannot take +calls (of course, if you have mixed agetns with audio/chat) +- **full-load** - the distribution +will try to make usage of an agent in the best possible way when +comes to chat sessions - once the agent take a chat, all the +following chats will be assigned ot him - the idea is to try to +be efficient in using the resource/sessions of an agents, to leave +as much room as possible for calls. Of course, this may lead to an +un-even loading of chat agents - some will be full, others empty. + + +*Default value is "balancing".* + + +```opensips title="Set chat_dispatch_policy parameter" +... +modparam("call_center", "chat_dispatch_policy", "balancing") +... +``` + + +#### internal_call_dispatching (int) + + +A parameter to tell if the internal/buit-in call dispatching to agent +should be used or not. If enabled, the module will automatically +dispatch (by itself) the queued/incoming calls to the available agents. +If disabled, the module will not do such dispaching by itself and it +is expected to use the [mi cc dispatch call to agent](#mi_cc_dispatch_call_to_agent) +MI command to dispatch the queued calls to agents. This allows the +implementation of an external, custom dispatching logic. The value of +this setting may be changed during runtime via the +[mi cc internal call dispatching](#mi_cc_internal_call_dispatching) MI command. + + +*Default value is "1" (enabled).* + + +```opensips title="Set internal_call_dispatching parameter" +... +modparam("call_center", "internal_call_dispatching", 0) +... +``` + + +#### cc_agents_table (string) + + +Name to be used for the table holding the agents. + + +*Default value is "cc_agents".* + + +```opensips title="Set cc_agents_table parameter" +... +modparam("call_center", "cc_agents_table", "my_agents") +... +``` + + +#### cca_agentid_column (string) + + +Name to be used for the "agent id" (unique DB id) column in the +agents table. + + +*Default value is "agentid".* + + +```opensips title="Set cca_agentid_column parameter" +... +modparam("call_center", "cca_agentid_column", "cid") +... +``` + + +#### cca_location_column (string) + + +Name to be used for the calling/audio "location" (SIP URI) column in +the agents table. + + +*Default value is "location".* + + +```opensips title="Set cca_location_column parameter" +... +modparam("call_center", "cca_location_column", "sip_uri") +... +``` + + +#### cca_msrp_location_column (string) + + +Name to be used for the msrp/chat "location" (SIP URI) column in the +agents table. + + +*Default value is "msrp_location".* + + +```opensips title="Set cca_msrp_location_column parameter" +... +modparam("call_center", "cca_msrp_location_column", "sip_uri") +... +``` + + +#### cca_msrp_max_sessions_column (string) + + +Name to be used for the column (in the agents table) holding the +maximum number of chat sessions that can be handled by the agent. + + +*Default value is "msrp_max_sessions".* + + +```opensips title="Set cca_msrp_max_sessions_column parameter" +... +modparam("call_center", "cca_msrp_max_sessions_column", "max_chats") +... +``` + + +#### cca_skills_column (string) + + +Name to be used for the "skills" (list of skills) column in the +agents table. + + +*Default value is "skills".* + + +```opensips title="Set cca_skills_column parameter" +... +modparam("call_center", "cca_skills_column", "skills") +... +``` + + +#### cca_logstate_column (string) + + +Name to be used for the "logstate" (original login state) column in the +agents table. + + +*Default value is "logstate".* + + +```opensips title="Set cca_logstate_column parameter" +... +modparam("call_center", "cca_logstate_column", "log_state") +... +``` + + +#### cca_wrapuptime_column (string) + + +Name to be used for the "wrapuptime" (per-agent wrapup time) column +in the agents table. + + +*Default value is "wrapup_time".* + + +```opensips title="Set cca_wrapuptime_column parameter" +... +modparam("call_center", "cca_wrapuptime_column", "wtime") +... +``` + + +#### cca_wrapupend_column (string) + + +Name to be used for the "wrapupend" (timestamp when the wrapup ends) +column in the agents table. + + +*Default value is "wrapup_end_time".* + + +```opensips title="Set cca_wrapupend_column parameter" +... +modparam("call_center", "cca_wrapupend_column", "wrapup_ends") +... +``` + + +#### cc_flows_table (string) + + +Name to be used for the table holding the definition of the +flows/queues. + + +*Default value is "cc_flows".* + + +```opensips title="Set cc_flows_table parameter" +... +modparam("call_center", "cc_flows_table", "queues") +... +``` + + +#### ccf_flowid_column (string) + + +Name to be used for the "flow id" (unique DB id) column in the +flows table. + + +*Default value is "flowid".* + + +```opensips title="Set ccf_flowid_column parameter" +... +modparam("call_center", "ccf_flowid_column", "queue_id") +... +``` + + +#### ccf_priority_column (string) + + +Name to be used for the "priority" column in the +flows table. + + +*Default value is "priority".* + + +```opensips title="Set ccf_priority_column parameter" +... +modparam("call_center", "ccf_priority_column", "queue_prio") +... +``` + + +#### ccf_skill_column (string) + + +Name to be used for the "skill" column in the +flows table. + + +*Default value is "skill".* + + +```opensips title="Set ccf_skill_column parameter" +... +modparam("call_center", "ccf_skill_column", "queue_skill") +... +``` + + +#### ccf_cid_column (string) + + +Name to be used for the "caller ID prefix" column in the +flows table. + + +*Default value is "prependcid".* + + +```opensips title="Set ccf_cid_column parameter" +... +modparam("call_center", "ccf_cid_column", "queue_cli_prefix") +... +``` + + +#### ccf_max_wrapup_column (string) + + +Name to be used for the "max limit for wrapup time" column in the +flows table. + + +*Default value is "max_wrapup_time".* + + +```opensips title="Set ccf_max_wrapup_column parameter" +... +modparam("call_center", "ccf_max_wrapup_column", "queue_wrapup") +... +``` + + +#### ccf_dissuading_hangup_column (string) + + +Name to be used for the "hangup after dissuading" column in the +flows table. + + +*Default value is "dissuading_hangup".* + + +```opensips title="Set ccf_dissuading_hangup_column parameter" +... +modparam("call_center", "ccf_dissuading_hangup_column", "hangup_on_dissuading") +... +``` + + +#### ccf_dissuading_onhold_th_column (string) + + +Name to be used for the "on-hold dissuading threshold" column in the +flows table. + + +*Default value is "dissuading_onhold_th".* + + +```opensips title="Set ccf_dissuading_onhold_th_column parameter" +... +modparam("call_center", "ccf_dissuading_onhold_th_column", "th_diss_onhold") +... +``` + + +#### ccf_dissuading_ewt_th_column (string) + + +Name to be used for the "EWT dissuading threshold" column in the +flows table. + + +*Default value is "dissuading_ewt_th".* + + +```opensips title="Set ccf_dissuading_ewt_th_column parameter" +... +modparam("call_center", "ccf_dissuading_ewt_th_column", "th_diss_ewt") +... +``` + + +#### ccf_dissuading_qsize_th_column (string) + + +Name to be used for the "queue size dissuading threshold" column in the +flows table. + + +*Default value is "dissuading_qsize_th".* + + +```opensips title="Set ccf_dissuading_qsize_th_column parameter" +... +modparam("call_center", "ccf_dissuading_qsize_th_column", "th_diss_qsize") +... +``` + + +#### ccf_m_welcome_column (string) + + +Name to be used for the "audio message on welcome" column in the +flows table. + + +*Default value is "message_welcome".* + + +```opensips title="Set ccf_m_welcome_column parameter" +... +modparam("call_center", "ccf_m_welcome_column", "audio_welcome") +... +``` + + +#### ccf_m_queue_column (string) + + +Name to be used for the "audio message on queueing" column in the +flows table. + + +*Default value is "message_queue".* + + +```opensips title="Set ccf_m_queue_column parameter" +... +modparam("call_center", "ccf_m_queue_column", "audio_queue") +... +``` + + +#### ccf_m_dissuading_column (string) + + +Name to be used for the "audio message on dissuading" column in the +flows table. + + +*Default value is "message_dissuading".* + + +```opensips title="Set ccf_m_dissuading_column parameter" +... +modparam("call_center", "ccf_m_dissuading_column", "audio_dissuading") +... +``` + + +#### ccf_m_flow_id_column (string) + + +Name to be used for the "audio message on identifying the flow" column +in the flows table. + + +*Default value is "message_flow_id".* + + +```opensips title="Set ccf_m_flow_id_column parameter" +... +modparam("call_center", "ccf_m_flow_id_column", "audio_flow_id") +... +``` + + +#### b2b_logic_ctx_param (string) + + +The name of the *$b2b_logic.ctx* variable that can be +used to retrieve the value of the parameter passed to +the [cc handle call](#func_cc_handle_call) function. + + +This parameter will be copied throughout all the B2B scenarios started +by the call_center module. NOTE that you can change the value of the current +scenario by writing into it, but the change will not be reflected in a +different scenario. + + +*Default value is "call_center".* + + +```opensips title="Set b2b_logic_ctx_param parameter" +... +modparam("call_center", "b2b_logic_ctx_param", "b2b_callid") +... +route[handle_call_center] { + ... + cc_handle_call("flow", $ci); + ... +} +... +route[b2b_handle_request] { + ... + xlog("Initial Callid is $b2b_logic.ctx(b2b_callid)\n"); + ... +} +``` + + +### Exported Functions + + +#### cc_handle_call( flowID [,param]) + + +This must be used only for initial INVITE requests - the function +pushes the call to be handled by the call center module (via a certain +flow/queue). + + +This function can be used from REQUEST_ROUTE. + + +Parameters: + + +- *flowID (string)* - the ID of the flow to +handle this call (push the call to that flow). +- *param (string, optional)* - an opaque +string to be passed as parameter to the "callcenter" and +"agent" B2B scenarios. It is +intended for custom integration of the call center module and +it is 100% up to the script writer about the value and purpose +of this parameter, OpenSIPS will not touch or interpret it. +You can retrieve the value of this parameter using the +*$b2b_logic.ctx* variable with the name +defined in the [b2b logic ctx param](#param_b2b_logic_ctx_param) +parameter. + + +The function returns TRUE back to the script if the call was +successfully pushed and handled by the Call Center engine. IMPORTANT: +you must not do any signaling on the call (reply, relay) after this +point. + + +In case of error, FALSE is returned to the script with the following +return codes: + + +- **-1** - unable to get the flow ID +from the parameter; +- **-2** - unable to parse the FROM URI; +- **-3** - flow with FlowID not found; +- **-4** - no agents logged in the flow; +- **-5** - internal error; + + +```opensips title="cc_handle_call usage" +... +if (is_method("INVITE") and !has_totag()) { + if (!cc_handle_call("tech_support")) { + send_reply(403,"Cannot handle call"); + exit; + } +} +... +``` + + +#### cc_agent_login(agentID, state) + + +This function sets the login (on or off) state for an agent. + + +This function can be used from REQUEST_ROUTE. + + +Parameters: + + +- *agentID (string)* - the ID of the agent +- *state (int)* - an integer value giving +the new state - 0 means logged off, anything else means logged in. + + +```opensips title="cc_agent_login usage" +... +# log off the 'agentX' agent +cc_agent_login("agentX",0); +... +``` + + +### Exported Statistics + + +#### Global statistics + + +##### ccg_incalls + + +Total number of received calls. (counter type) + + +##### ccg_awt + + +Global avg. waiting time for calls. (realtime type) + + +##### ccg_load + + +Global load (across all flows). (realtime type) + + +##### ccg_distributed_incalls + + +Total number of distributed calls. (counter type) + + +##### ccg_answered_incalls + + +Total number of calls (audio/RTP and chat/MSRP) answered by agents. (counter type) + + +##### ccg_answered_inchats + + +Total number of chat/MSRP only calls answered by agents. (counter type) + + +##### ccg_abandonned_incalls + + +Total number of calls terminated by caller before being +answered by agents. (counter type) + + +##### ccg_onhold_calls + + +Total number of calls (audio/RTP and chat/MSRP) in the queues (onhold). (realtime type) + + +##### ccg_onhold_chats + + +Total number of chat/MSRP only calls in the queues (onhold). (realtime type) + + +##### ccg_free_agents + + +Total number of free agents (across all flows). (realtime type) + + +#### Per-flow statistics (one set for each flow) + + +##### ccf_incalls_flowID + + +Number of received calls for the flow. (counter type) + + +##### ccf_dist_incalls_flowID + + +Number of distributed calls in this flow. (counter type) + + +##### ccf_answ_incalls_flowID + + +Nnumber of calls (audio/RTP and chat/MSRP) from the flow answered by agents. (counter type) + + +##### ccf_answ_incalls_flowID + + +Nnumber of chat/MSRP only calls from the flow answered by agents. (counter type) + + +##### ccf_aban_incalls_flowID + + +Number of calls (from the flow) terminated by caller before being +answered by agents. (counter type) + + +##### ccf_onhold_incalls_flowID + + +Number of calls (audio/RTP and chat/MSRP) -from the flow- which are onhold. +(realtime type) + + +##### ccf_onhold_inchats_flowID + + +Number of chat/MSRP only calls -from the flow- which are onhold. +(realtime type) + + +##### ccf_queued_calls_flowID + + +Number of calls which are queued for this flow. (realtime type) + + +##### ccf_free_agents_flowID + + +Number of free agents serving this flow. (realtime type) + + +##### ccf_etw_flowID + + +Estimated Time to Wait for this flow. (realtime type) + + +##### ccf_awt_flowID + + +Avg. Wating Time for this flow. (realtime type) + + +##### ccg_load_flowID + + +The load on the flow (number of queued calls versus number of +logged agents). (realtime type) + + +#### Per-agent statistics (one set for each agent) + + +##### cca_dist_incalls_agnetID + + +Number of distributed calls to this agent. (counter type) + + +##### cca_answ_incalls_agentID + + +Number of calls (audio/RTP and chat/MSRP) answered by the agent. (counter type) + + +##### cca_answ_inchats_agentID + + +Number of chat/MSRP only calls answered by the agent. (counter type) + + +##### cca_aban_incalls_agentID + + +Number of calls (sent to this agent) terminated by caller before +being answered by agents. (counter type) + + +##### cca_att_agentID + + +Avg. Talk Time for this agent (realtime type) + + +### Exported MI Functions + + +#### cc_reload + + +Command to reload flows and agents definition from database. + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_reload +``` + + +#### cc_agent_login + + +Command to login an agent into the Call Center engine. + + +Parameters: + + +- *agent_id* - ID of the agent +- *state* - the new login state (0 - log off, 1 - log in) + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_agent_login agentX 0 +``` + + +#### cc_list_queue + + +Command to list all the calls in queuing - for each call, the +following attributes will be printed: the call id, the calling +user info, the flow of the call, for how +long the call is in the queue, the ETW for the call, call priority +and the call skill (inherited from the flow). + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_list_queue +``` + + +#### cc_list_flows + + +Command to list all the flows - for each flow, the +following attributes will be printed: the flow ID, the avg. call +duration, how many calls were processed, how many agents are logged, +and how many onging calls are. + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_list_flows +``` + + +#### cc_list_agents + + +Command to list all the agents - for each agent, the +following attributes will be printed: agent ID, agent login state, +agent state (free, wrapup, incall) and info on ongoing sessions. + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_list_agents +``` + + +#### cc_list_calls + + +Command to list all the ongoing calls - for each call, the +following attributes will be printed: call ID, call state +(welcome, queued, toagent, ended), call duration, flow it belongs to, +agent serving the call (if any). + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_list_agents +``` + + +#### cc_dispatch_call_to_agent + + +This function sends a given call (from the queue) to a given agent. For +the operation to succeed, several conditions must be met: + + +- the call must be in the queue +- the agent must be logged in +- the agent must support the skill required by the call +- the agent must support the media (RTP/MSRP) requiref by the call +- the agent must have available sessions for the requested media + + +It takes two parameters. + + +- *call_id* - the ID of the call, as provided by +the queue listing MI command [mi cc list queue](#mi_cc_list_queue) +- *agent_id* - the ID of the call, as provided by +the agents listing MI command [mi cc list agents](#mi_cc_list_agents) + + +> [!IMPORTANT] +> In order to be used, you need to be sure that the internal +> call dispatching is DISABLED via the +> [internal call dispatching](#param_internal_call_dispatching) module parameter +> or the [mi internal call dispatching](#mi_internal_call_dispatching) MI command. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_dispatch_call_to_agent B2B452.dee2.33 agentX +``` + + +#### cc_internal_call_dispatching + + +Command to inspect and/or change the +[internal call dispatching](#param_internal_call_dispatching) setting + + +It takes one optional parameter `dispatching` if the +value of the setting should be changed. A 0 value means disabling +the internal dispatching, a non zero means to enable it. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_internal_call_dispatching 0 +``` + + +#### cc_reset_stats + + +Command to reset all counter-like statistics. + + +It takes no parameter. + + +MI FIFO Command usage: + + +```bash +opensips-cli -x mi cc_reset_stats +``` + + +### Exported Events + + +#### E_CALLCENTER_AGENT_REPORT + + +This event is raised when the status of an agent changes. + + +Parameters: + + +- *agent_id* - the id of the agent. +- *state* - the status of the agent: + * offline + * free + * incall + * wrapup +- *wrapup_ends* - the timestamp when the +wrapup state will end; published only if the state is +"wrapup" +- *flow_id* - the flow ID that delivered the +call for this agent; published only if the state is "incall" + + +### Exported Pseudo-Variables + + +`$cc_state` +Returns the state of a call. +Possible values returned are: +*welcome* - the welcome message is played. +*dissuading1* - the first dissuading message is played. +*dissuading2* - the second dissuading message is played. +*queue* - the call is in queue. +*preagent* - the agent is being called. +*toagent* - the agent is in call. + +## Frequently Asked Questions + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/call_center/doc/call_center.xml b/modules/call_center/doc/call_center.xml deleted file mode 100644 index 14c4d89f814..00000000000 --- a/modules/call_center/doc/call_center.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Call-Center Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2014 &osipssol; - - diff --git a/modules/call_center/doc/call_center_admin.xml b/modules/call_center/doc/call_center_admin.xml deleted file mode 100644 index f2dca530a06..00000000000 --- a/modules/call_center/doc/call_center_admin.xml +++ /dev/null @@ -1,1543 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Call Center module implements an inbound call center system with call - flows (for queuing the received calls) and agents (for answering the - calls). - - - The module implements the queuing system, the call distribution - to agents, agents managements, CDRs for the calls, statistics on - call distribution and agent's activity - basically everything - except the media playback (for the queue). This part must be provided via - a third party media server (FreeSwitch, Asterisk or others). - - - This is actually a Contact Center and it is able to handle both - RTP/audio calls and (multiple) MSRP/chat calls, in the same time. - - - The module provides an internal buit-in dispatching logic (for sending the - calls/chats to the agents), but also offers the possibility to use an - external logic to do the dispatching - (see MI command). - -
- -
- How it works - - The main entities in the modules are the flows (queues) and agents. - -
- DB tables - - Each entity has a corresponding table in the database, for - provisioning purposes - the cc_flows and - cc_agents tables, see - DB schema. - Data is loaded at startup and cached into memory ; runtime reload is - possible via the MI commands (see the cc_reload - command in ). - - - Additionally there is a table cc_cdrs for writing - the CDRs - this operation is done in realtime, after the call in - completed, covering all possible cases: call was dropped while in - queue, call was rejected by agent, call was accepted by agent, call - terminated with error - NOTE that a call may generate more than one - CDR (like call rejected by agent A, and redistributed and accepted by - agent B). - - - The cc_calls table is used to store ongoing calls, - regardless it's state (in queue, to the agent, ended). It is populated - at runtime by the module and queried at startup. This table should not - be manually provisioned. - -
- -
- Call Flows - - A flow is defined by a unique alphanumerical ID - the main attribute - of a flow is the skill - the skill is a - capability required by the flow for an agent to be able to answer the - call ; the concept of skills is the link between - the flows and the agents - telling what agents are serving what flows - - the flows require a skill, while the agents provide a set of skills. - Agents matching the required skill of a flow will automatically - receive calls from that flow. - - - Additional, the flow has a priority - as agents - may server multiple flows in the same time (based on skills), you can - define priorities between the flows - if the flows has a higher - priority, its calls will be pushed (in deliver to agents and queuing) in - front of the calls from flows with a lower priority. - - - Configurable per flow, the module may do per-flow call dissuading; this - means to redirect a call to another destination, if the queue/flow - is overloaded: - - - - if the number of calls already in the queue exceeds the diss_qsize_th threshold - - - if the estimated time to wait of the queue exceeds the diss_ewt_th threshold - - - if the call was waiting in the queue for longer than diss_onhold_th threshold - - - - Optionally, the flow may define a prependcid - a - prefix to be added to the CLI (Caller ID) when the call is delivered to - the agents - as an agent may receive call from multiple flows, it is - important for the user to see which was the queue a call was received. - - - In terms of media announcements, the flow defines the - message_welcome (optional, to be played in the - call, before doing anything with the call) and - message_queue (mandatory, the looping message - providing infinite on hold media IMPORTANT - this message must cycle - and media server must never hung up on it. Both announcements are - provided as SIP URIs (where the call has to be sent in order to get - the playback). - - - The flow also has an optional max_wrapup time, - which acts as an upper limit for the per-agent/global value (the flow - forces a ceiling of the wrapup value for all its calls). - -
- -
- Agents - - An agent is defined by a unique alphanumerical ID - the main attribute - of an agent is its the set of skills. This set of - skills will tell what calls to be received (from which flows, based on - the skill matching). - - - The agent may provide support for different optional media types, like - RTP/audio or MSRP/chat. Each supported media type comes with the - maximum supported number of sessions. Of course, for audio the `1` - value is hardocded. On the SIP side, each media type comes with a - locations. The location is a SIP URI where to - calls must be sent in order to be answered by the agent. At least one - media type should be defined. To specify which media the agent - support, just define the corresponding SIP location in his profile. - - - So, at a certain time, an agent may handle either a single call, - either several chat sessions. - - - Additionally, the agent has a initial logstate - - if he is logged in or not (being logged in is a must in order to - receive calls). The log state may be changed at runtime via a - dedicated MI command cc_agent_login, see - . - - - There is an optional per-agent wrapup_time - defined, saying the time interval for an agent before getting a new - call from the system (after he finished a call). If no value is defined - for the agent, the global wrapup_time will be - used. Note that the resulting value may be upper limited by the - per-flow max_wrapup_time if defined. - -
-
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - b2b_logic - B2bUA module - - - - - database - one of the SQL DB modules - - - - -
- - -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - SQL address to the DB server -- database specific. This must be - the Database holding the provisioning tables (cc_flows, cc_agents - and cc_calls tables). - - If not explicitly set, the global OpenSIPS DB URL will be used. - - - - Set <varname>db_url</varname> parameter - -... -modparam("call_center", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>acc_db_url</varname> (string) - - SQL address to the DB server -- database specific. This must be - the Database where the CDRs table (cc_cdrs) is located. - - If not explicitly set, the global OpenSIPS DB URL will be used. - - - - Set <varname>acc_db_url</varname> parameter - -... -modparam("call_center", "acc_db_url", - "mysql://opensips:opensipsrw@localhost/opensips_cdrs") -... - - -
- -
- <varname>rt_db_url</varname> (string) - - SQL address/URL of the DB server (database specific) where the - runtime tables (non provisioning tables) are located. The - runtime tables are the tables populated by OpenSIPS with data - learned during runtime. To be more specific, the only runtime - table we have so far is the "cc_calls" table. - - If not explicitly set, the global OpenSIPS DB URL will be used. - - - - Set <varname>rt_db_url</varname> parameter - -... -modparam("call_center", "rt_db_url", - "mysql://opensips:opensipsrw@localhost/opensips_runtime") -... - - -
- -
- <varname>wrapup_time</varname> (integer) - - Time for an agent between finishing a call and receiving the next - call from the system. Even if there are queued calls, the module - will not deliver call to agent during this wrapup interval. - - - This value may be overwritten by the per-agent value (if defined) - and furher more, by the per-flow value (if defined). - - - Default value is 30 seconds. - - - - Set <varname>wrapup_time</varname> parameter - -... -modparam("call_center", "wrapup_time", 45) -... - - -
- -
- <varname>queue_pos_param</varname> (string) - - The name of an SIP URI parameter to be used to report the position - in the waiting queue when sending the call to media server for - onwait/queue playback. The position 0 means it is the next call - to be delivered to an agent. - - - Default value is empty(none). - - - - Set <varname>queue_pos_param</varname> parameter - -... -modparam("call_center", "queue_pos_param", "cc_pos") -... - - -
- -
- <varname>reject_on_no_agents</varname> (int) - - A parameter to tell if an incoming call should be rejected or - quueued if there are no logged in agents. Basically this allows - call queueing on flows with no agents yet. - - - Default value is 1 (true). - - - - Set <varname>reject_on_no_agents</varname> parameter - -... -modparam("call_center", "reject_on_no_agents", 0) -... - - -
- -
- <varname>chat_dispatch_policy</varname> (int) - - A parameter to tell what should be the policy on dispatching the - chat/MSRP sessions to the agents, considering that an agent may - handle multiple such sessions/chats in the same time. - - - Options are: - - - - - balancing - the distribution - will try to be even across the agents, but by doing this you may - end up waisting chat sessions on agents and call starvation - - agents are partially used by chat sessions, so they cannot take - calls (of course, if you have mixed agetns with audio/chat) - - - - - full-load - the distribution - will try to make usage of an agent in the best possible way when - comes to chat sessions - once the agent take a chat, all the - following chats will be assigned ot him - the idea is to try to - be efficient in using the resource/sessions of an agents, to leave - as much room as possible for calls. Of course, this may lead to an - un-even loading of chat agents - some will be full, others empty. - - - - - Default value is balancing. - - - - Set <varname>chat_dispatch_policy</varname> parameter - -... -modparam("call_center", "chat_dispatch_policy", "balancing") -... - - -
- -
- <varname>internal_call_dispatching</varname> (int) - - A parameter to tell if the internal/buit-in call dispatching to agent - should be used or not. If enabled, the module will automatically - dispatch (by itself) the queued/incoming calls to the available agents. - If disabled, the module will not do such dispaching by itself and it - is expected to use the - MI command to dispatch the queued calls to agents. This allows the - implementation of an external, custom dispatching logic. The value of - this setting may be changed during runtime via the - MI command. - - - Default value is 1 (enabled). - - - - Set <varname>internal_call_dispatching</varname> parameter - -... -modparam("call_center", "internal_call_dispatching", 0) -... - - -
- -
- <varname>cc_agents_table</varname> (string) - - Name to be used for the table holding the agents. - - - Default value is cc_agents. - - - - Set <varname>cc_agents_table</varname> parameter - -... -modparam("call_center", "cc_agents_table", "my_agents") -... - - -
- -
- <varname>cca_agentid_column</varname> (string) - - Name to be used for the "agent id" (unique DB id) column in the - agents table. - - - Default value is agentid. - - - - Set <varname>cca_agentid_column</varname> parameter - -... -modparam("call_center", "cca_agentid_column", "cid") -... - - -
- -
- <varname>cca_location_column</varname> (string) - - Name to be used for the calling/audio "location" (SIP URI) column in - the agents table. - - - Default value is location. - - - - Set <varname>cca_location_column</varname> parameter - -... -modparam("call_center", "cca_location_column", "sip_uri") -... - - -
- -
- <varname>cca_msrp_location_column</varname> (string) - - Name to be used for the msrp/chat "location" (SIP URI) column in the - agents table. - - - Default value is msrp_location. - - - - Set <varname>cca_msrp_location_column</varname> parameter - -... -modparam("call_center", "cca_msrp_location_column", "sip_uri") -... - - -
- -
- <varname>cca_msrp_max_sessions_column</varname> (string) - - Name to be used for the column (in the agents table) holding the - maximum number of chat sessions that can be handled by the agent. - - - Default value is msrp_max_sessions. - - - - Set <varname>cca_msrp_max_sessions_column</varname> parameter - -... -modparam("call_center", "cca_msrp_max_sessions_column", "max_chats") -... - - -
- -
- <varname>cca_skills_column</varname> (string) - - Name to be used for the "skills" (list of skills) column in the - agents table. - - - Default value is skills. - - - - Set <varname>cca_skills_column</varname> parameter - -... -modparam("call_center", "cca_skills_column", "skills") -... - - -
- -
- <varname>cca_logstate_column</varname> (string) - - Name to be used for the "logstate" (original login state) column in the - agents table. - - - Default value is logstate. - - - - Set <varname>cca_logstate_column</varname> parameter - -... -modparam("call_center", "cca_logstate_column", "log_state") -... - - -
- -
- <varname>cca_wrapuptime_column</varname> (string) - - Name to be used for the "wrapuptime" (per-agent wrapup time) column - in the agents table. - - - Default value is wrapup_time. - - - - Set <varname>cca_wrapuptime_column</varname> parameter - -... -modparam("call_center", "cca_wrapuptime_column", "wtime") -... - - -
- -
- <varname>cca_wrapupend_column</varname> (string) - - Name to be used for the "wrapupend" (timestamp when the wrapup ends) - column in the agents table. - - - Default value is wrapup_end_time. - - - - Set <varname>cca_wrapupend_column</varname> parameter - -... -modparam("call_center", "cca_wrapupend_column", "wrapup_ends") -... - - -
- -
- <varname>cc_flows_table</varname> (string) - - Name to be used for the table holding the definition of the - flows/queues. - - - Default value is cc_flows. - - - - Set <varname>cc_flows_table</varname> parameter - -... -modparam("call_center", "cc_flows_table", "queues") -... - - -
- -
- <varname>ccf_flowid_column</varname> (string) - - Name to be used for the "flow id" (unique DB id) column in the - flows table. - - - Default value is flowid. - - - - Set <varname>ccf_flowid_column</varname> parameter - -... -modparam("call_center", "ccf_flowid_column", "queue_id") -... - - -
- -
- <varname>ccf_priority_column</varname> (string) - - Name to be used for the "priority" column in the - flows table. - - - Default value is priority. - - - - Set <varname>ccf_priority_column</varname> parameter - -... -modparam("call_center", "ccf_priority_column", "queue_prio") -... - - -
- -
- <varname>ccf_skill_column</varname> (string) - - Name to be used for the "skill" column in the - flows table. - - - Default value is skill. - - - - Set <varname>ccf_skill_column</varname> parameter - -... -modparam("call_center", "ccf_skill_column", "queue_skill") -... - - -
- -
- <varname>ccf_cid_column</varname> (string) - - Name to be used for the "caller ID prefix" column in the - flows table. - - - Default value is prependcid. - - - - Set <varname>ccf_cid_column</varname> parameter - -... -modparam("call_center", "ccf_cid_column", "queue_cli_prefix") -... - - -
- -
- <varname>ccf_max_wrapup_column</varname> (string) - - Name to be used for the "max limit for wrapup time" column in the - flows table. - - - Default value is max_wrapup_time. - - - - Set <varname>ccf_max_wrapup_column</varname> parameter - -... -modparam("call_center", "ccf_max_wrapup_column", "queue_wrapup") -... - - -
- -
- <varname>ccf_dissuading_hangup_column</varname> (string) - - Name to be used for the "hangup after dissuading" column in the - flows table. - - - Default value is dissuading_hangup. - - - - Set <varname>ccf_dissuading_hangup_column</varname> parameter - -... -modparam("call_center", "ccf_dissuading_hangup_column", "hangup_on_dissuading") -... - - -
- -
- <varname>ccf_dissuading_onhold_th_column</varname> (string) - - Name to be used for the "on-hold dissuading threshold" column in the - flows table. - - - Default value is dissuading_onhold_th. - - - - Set <varname>ccf_dissuading_onhold_th_column</varname> parameter - -... -modparam("call_center", "ccf_dissuading_onhold_th_column", "th_diss_onhold") -... - - -
- -
- <varname>ccf_dissuading_ewt_th_column</varname> (string) - - Name to be used for the "EWT dissuading threshold" column in the - flows table. - - - Default value is dissuading_ewt_th. - - - - Set <varname>ccf_dissuading_ewt_th_column</varname> parameter - -... -modparam("call_center", "ccf_dissuading_ewt_th_column", "th_diss_ewt") -... - - -
- -
- <varname>ccf_dissuading_qsize_th_column</varname> (string) - - Name to be used for the "queue size dissuading threshold" column in the - flows table. - - - Default value is dissuading_qsize_th. - - - - Set <varname>ccf_dissuading_qsize_th_column</varname> parameter - -... -modparam("call_center", "ccf_dissuading_qsize_th_column", "th_diss_qsize") -... - - -
- -
- <varname>ccf_m_welcome_column</varname> (string) - - Name to be used for the "audio message on welcome" column in the - flows table. - - - Default value is message_welcome. - - - - Set <varname>ccf_m_welcome_column</varname> parameter - -... -modparam("call_center", "ccf_m_welcome_column", "audio_welcome") -... - - -
- -
- <varname>ccf_m_queue_column</varname> (string) - - Name to be used for the "audio message on queueing" column in the - flows table. - - - Default value is message_queue. - - - - Set <varname>ccf_m_queue_column</varname> parameter - -... -modparam("call_center", "ccf_m_queue_column", "audio_queue") -... - - -
- -
- <varname>ccf_m_dissuading_column</varname> (string) - - Name to be used for the "audio message on dissuading" column in the - flows table. - - - Default value is message_dissuading. - - - - Set <varname>ccf_m_dissuading_column</varname> parameter - -... -modparam("call_center", "ccf_m_dissuading_column", "audio_dissuading") -... - - -
- -
- <varname>ccf_m_flow_id_column</varname> (string) - - Name to be used for the "audio message on identifying the flow" column - in the flows table. - - - Default value is message_flow_id. - - - - Set <varname>ccf_m_flow_id_column</varname> parameter - -... -modparam("call_center", "ccf_m_flow_id_column", "audio_flow_id") -... - - -
- -
- <varname>b2b_logic_ctx_param</varname> (string) - - The name of the $b2b_logic.ctx variable that can be - used to retrieve the value of the parameter passed to - the function. - - - This parameter will be copied throughout all the B2B scenarios started - by the call_center module. NOTE that you can change the value of the current - scenario by writing into it, but the change will not be reflected in a - different scenario. - - - Default value is call_center. - - - - Set <varname>b2b_logic_ctx_param</varname> parameter - -... -modparam("call_center", "b2b_logic_ctx_param", "b2b_callid") -... -route[handle_call_center] { - ... - cc_handle_call("flow", $ci); - ... -} -... -route[b2b_handle_request] { - ... - xlog("Initial Callid is $b2b_logic.ctx(b2b_callid)\n"); - ... -} - - -
- -
- - -
- Exported Functions -
- - <function>cc_handle_call( flowID [,param])</function> - - - This must be used only for initial INVITE requests - the function - pushes the call to be handled by the call center module (via a certain - flow/queue). - - - This function can be used from REQUEST_ROUTE. - - Parameters: - - - flowID (string) - the ID of the flow to - handle this call (push the call to that flow). - - - param (string, optional) - an opaque - string to be passed as parameter to the "callcenter" and - "agent" B2B scenarios. It is - intended for custom integration of the call center module and - it is 100% up to the script writer about the value and purpose - of this parameter, OpenSIPS will not touch or interpret it. - You can retrieve the value of this parameter using the - $b2b_logic.ctx variable with the name - defined in the - parameter. - - - - The function returns TRUE back to the script if the call was - successfully pushed and handled by the Call Center engine. IMPORTANT: - you must not do any signaling on the call (reply, relay) after this - point. - - - In case of error, FALSE is returned to the script with the following - return codes: - - - - -1 - unable to get the flow ID - from the parameter; - - - -2 - unable to parse the FROM URI; - - - -3 - flow with FlowID not found; - - - -4 - no agents logged in the flow; - - - -5 - internal error; - - - - <function>cc_handle_call</function> usage - -... -if (is_method("INVITE") and !has_totag()) { - if (!cc_handle_call("tech_support")) { - send_reply(403,"Cannot handle call"); - exit; - } -} -... - - -
- -
- - <function>cc_agent_login(agentID, state)</function> - - - This function sets the login (on or off) state for an agent. - - - This function can be used from REQUEST_ROUTE. - - Parameters: - - - agentID (string) - the ID of the agent - - - state (int) - an integer value giving - the new state - 0 means logged off, anything else means logged in. - - - - <function>cc_agent_login</function> usage - -... -# log off the 'agentX' agent -cc_agent_login("agentX",0); -... - - -
- -
- - -
- Exported Statistics - -
- Global statistics -
- ccg_incalls - - Total number of received calls. (counter type) - -
- -
- ccg_awt - - Global avg. waiting time for calls. (realtime type) - -
- -
- ccg_load - - Global load (across all flows). (realtime type) - -
- -
- ccg_distributed_incalls - - Total number of distributed calls. (counter type) - -
- -
- ccg_answered_incalls - - Total number of calls (audio/RTP and chat/MSRP) answered by agents. (counter type) - -
- -
- ccg_answered_inchats - - Total number of chat/MSRP only calls answered by agents. (counter type) - -
- -
- ccg_abandonned_incalls - - Total number of calls terminated by caller before being - answered by agents. (counter type) - -
- -
- ccg_onhold_calls - - Total number of calls (audio/RTP and chat/MSRP) in the queues (onhold). (realtime type) - -
- -
- ccg_onhold_chats - - Total number of chat/MSRP only calls in the queues (onhold). (realtime type) - -
- -
- ccg_free_agents - - Total number of free agents (across all flows). (realtime type) - -
-
- -
- Per-flow statistics (one set for each flow) -
- ccf_incalls_flowID - - Number of received calls for the flow. (counter type) - -
- -
- ccf_dist_incalls_flowID - - Number of distributed calls in this flow. (counter type) - -
- -
- ccf_answ_incalls_flowID - - Nnumber of calls (audio/RTP and chat/MSRP) from the flow answered by agents. (counter type) - -
- -
- ccf_answ_incalls_flowID - - Nnumber of chat/MSRP only calls from the flow answered by agents. (counter type) - -
- -
- ccf_aban_incalls_flowID - - Number of calls (from the flow) terminated by caller before being - answered by agents. (counter type) - -
- -
- ccf_onhold_incalls_flowID - - Number of calls (audio/RTP and chat/MSRP) -from the flow- which are onhold. - (realtime type) - -
- -
- ccf_onhold_inchats_flowID - - Number of chat/MSRP only calls -from the flow- which are onhold. - (realtime type) - -
- -
- ccf_queued_calls_flowID - - Number of calls which are queued for this flow. (realtime type) - -
- -
- ccf_free_agents_flowID - - Number of free agents serving this flow. (realtime type) - -
- -
- ccf_etw_flowID - - Estimated Time to Wait for this flow. (realtime type) - -
- -
- ccf_awt_flowID - - Avg. Wating Time for this flow. (realtime type) - -
- -
- ccg_load_flowID - - The load on the flow (number of queued calls versus number of - logged agents). (realtime type) - -
-
- -
- Per-agent statistics (one set for each agent) -
- cca_dist_incalls_agnetID - - Number of distributed calls to this agent. (counter type) - -
- -
- cca_answ_incalls_agentID - - Number of calls (audio/RTP and chat/MSRP) answered by the agent. (counter type) - -
- -
- cca_answ_inchats_agentID - - Number of chat/MSRP only calls answered by the agent. (counter type) - -
- -
- cca_aban_incalls_agentID - - Number of calls (sent to this agent) terminated by caller before - being answered by agents. (counter type) - -
- -
- cca_att_agentID - - Avg. Talk Time for this agent (realtime type) - -
-
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">cc_reload</function> - - - Command to reload flows and agents definition from database. - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_reload - -
- -
- - <function moreinfo="none">cc_agent_login</function> - - - Command to login an agent into the Call Center engine. - - Parameters: - - - agent_id - ID of the agent - - - state - the new login state (0 - log off, 1 - log in) - - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_agent_login agentX 0 - -
- -
- - <function moreinfo="none">cc_list_queue</function> - - - Command to list all the calls in queuing - for each call, the - following attributes will be printed: the call id, the calling - user info, the flow of the call, for how - long the call is in the queue, the ETW for the call, call priority - and the call skill (inherited from the flow). - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_list_queue - -
- -
- - <function moreinfo="none">cc_list_flows</function> - - - Command to list all the flows - for each flow, the - following attributes will be printed: the flow ID, the avg. call - duration, how many calls were processed, how many agents are logged, - and how many onging calls are. - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_list_flows - -
- -
- - <function moreinfo="none">cc_list_agents</function> - - - Command to list all the agents - for each agent, the - following attributes will be printed: agent ID, agent login state, - agent state (free, wrapup, incall) and info on ongoing sessions. - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_list_agents - -
- -
- - <function moreinfo="none">cc_list_calls</function> - - - Command to list all the ongoing calls - for each call, the - following attributes will be printed: call ID, call state - (welcome, queued, toagent, ended), call duration, flow it belongs to, - agent serving the call (if any). - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_list_agents - -
- -
- - <function moreinfo="none">cc_dispatch_call_to_agent</function> - - - This function sends a given call (from the queue) to a given agent. For - the operation to succeed, several conditions must be met: - - - - the call must be in the queue - - - the agent must be logged in - - - the agent must support the skill required by the call - - - the agent must support the media (RTP/MSRP) requiref by the call - - - the agent must have available sessions for the requested media - - - - It takes two parameters. - - - - call_id - the ID of the call, as provided by - the queue listing MI command - - - agent_id - the ID of the call, as provided by - the agents listing MI command - - - - IMPORTANT: in order to be used, you need to be sure that the internal - call dispatching is DISABLED via the - module parameter - or the MI command. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_dispatch_call_to_agent B2B452.dee2.33 agentX - -
- -
- - <function moreinfo="none">cc_internal_call_dispatching</function> - - - Command to inspect and/or change the - setting - - - It takes one optional parameter dispatching if the - value of the setting should be changed. A 0 value means disabling - the internal dispatching, a non zero means to enable it. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_internal_call_dispatching 0 - -
- - -
- - <function moreinfo="none">cc_reset_stats</function> - - - Command to reset all counter-like statistics. - - - It takes no parameter. - - - MI FIFO Command usage: - - -opensips-cli -x mi cc_reset_stats - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_CALLCENTER_AGENT_REPORT</function> - - - This event is raised when the status of an agent changes. - - Parameters: - - - agent_id - the id of the agent. - - - state - the status of the agent: - - offline - free - incall - wrapup - - - - wrapup_ends - the timestamp when the - wrapup state will end; published only if the state is - "wrapup" - - - flow_id - the flow ID that delivered the - call for this agent; published only if the state is "incall" - - -
-
- - -
- Exported Pseudo-Variables - -
- <function moreinfo="none">$cc_state</function> - - Returns the state of a call. - - - Possible values returned are: - - - - welcome - the welcome message is played. - - - dissuading1 - the first dissuading message is played. - - - dissuading2 - the second dissuading message is played. - - - queue - the call is in queue. - - - preagent - the agent is being called. - - - toagent - the agent is in call. - - - - - - - $rtpquery Usage - -... - $json(reply) := $rtpquery; - xlog("Total RTP Stats: $json(reply/totals)\n"); -... - - -
- NONE -
-
- - - -
- diff --git a/modules/call_center/doc/call_center_devel.xml b/modules/call_center/doc/call_center_devel.xml deleted file mode 100644 index b96223d7dd6..00000000000 --- a/modules/call_center/doc/call_center_devel.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - &develguide; -
- Available Functions - - NONE - -
- -
- diff --git a/modules/call_center/doc/call_center_faq.xml b/modules/call_center/doc/call_center_faq.xml deleted file mode 100644 index 4b1c4df9306..00000000000 --- a/modules/call_center/doc/call_center_faq.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - &faqguide; - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/call_center/doc/contributors.xml b/modules/call_center/doc/contributors.xml deleted file mode 100644 index 4ff65a8b37d..00000000000 --- a/modules/call_center/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 110 - 44 - 6780 - 511 - - - 2. - Razvan Crainea (@razvancrainea) - 45 - 34 - 849 - 159 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 18 - 9 - 287 - 314 - - - 4. - Liviu Chircu (@liviuchircu) - 15 - 12 - 73 - 90 - - - 5. - Maksym Sobolyev (@sobomax) - 6 - 4 - 8 - 13 - - - 6. - Walter Doekes (@wdoekes) - 4 - 2 - 1 - 2 - - - 7. - Peter Lemenkov (@lemenkov) - 4 - 2 - 1 - 1 - - - 8. - Vlad Paiu (@vladpaiu) - 3 - 1 - 13 - 4 - - - 9. - Alexandra Titoc - 3 - 1 - 4 - 4 - - - 10. - Dusan Klinec (@ph4r05) - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jun 2014 - Aug 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Mar 2014 - Oct 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2014 - May 2023 - - - 6. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jan 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Sep 2018 - - - 10. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Zero King (@l2dy), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/call_control/README b/modules/call_control/README deleted file mode 100644 index 92274fa1953..00000000000 --- a/modules/call_control/README +++ /dev/null @@ -1,573 +0,0 @@ -Call Control Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Description - 1.3. Features - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported parameters - - 1.5.1. disable (int) - 1.5.2. socket_name (string) - 1.5.3. socket_timeout (int) - 1.5.4. signaling_ip_avp (string) - 1.5.5. canonical_uri_avp (string) - 1.5.6. diverter_avp (string) - 1.5.7. prepaid_account_flag (string) - 1.5.8. call_limit_avp (string) - 1.5.9. call_token_avp (string) - 1.5.10. init (string) - 1.5.11. start (string) - 1.5.12. stop (string) - - 1.6. Exported Functions - - 1.6.1. call_control() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the disable parameter - 1.2. Setting the socket_name parameter - 1.3. Setting the socket_timeout parameter - 1.4. Setting the signaling_ip_avp parameter - 1.5. Setting the canonical_uri_avp parameter - 1.6. Setting the diverter_avp parameter - 1.7. Setting the prepaid_account_flag parameter - 1.8. Setting the call_limit_avp parameter - 1.9. Setting the call_token_avp parameter - 1.10. Setting the init parameter - 1.11. Setting the start parameter - 1.12. Setting the stop parameter - 1.13. Using the call_control function - -Chapter 1. Admin Guide - -1.1. Overview - - This module allows one to limit the duration of calls and - automatically end them when they exceed the imposed limit. Its - main use case is to implement a prepaid system, but it can also - be used to impose a global limit on all calls processed by the - proxy. - -1.2. Description - - Callcontrol consists of 3 components: - * The OpenSIPS call_control module - * An external application called callcontrol which keeps - track of the calls that have a time limit and automatically - ends them when they exceed it. This application receives - requests from OpenSIPS and makes requests to a rating - engine (see below) to find out if a call needs to be - limited or not. When a call ends (or is ended) it will also - instruct the rating engine to debit the balance for the - caller with the consumed amount. The callcontrol - application is available from - http://callcontrol.ag-projects.com/ - * A rating engine that is used to calculate the time limit - based on the caller's credit and the destination price and - to debit the caller's balance after a call ends. This is - available as part of CDRTool from - http://cdrtool.ag-projects.com/ - - The callcontrol application runs on the same machine as - OpenSIPS and they communicate over a filesystem socket, while - the rating engine can run on a different host and communicates - with the callcontrol application using a TCP connection. - - Callcontrol is invoked by calling the call_control() function - for the initial INVITE of every call we want to apply a limit - to. This will end up as a request to the callcontrol - application, which will interrogate the rating engine for a - time limit for the given caller and destination. The rating - engine will determine if the destination has any associated - cost and if the caller has any credit limit and if so will - return the amount of time he is allowed to call that - destination. Otherwise it will indicate that there is no limit - associated with the call. If there is a limit, the callcontrol - application will retain the session and attach a timer to it - that will expire after the given time causing it to call back - to OpenSIPS with a request to end the dialog. If the rating - engine returns that there is no limit for the call, the session - is discarded by the callcontrol application and it will allow - it to go proceed any limit. An appropriate response is returned - to the call_control module that is then returned by the - call_control() function call and allows the script to make a - decision based on the answer. - -1.3. Features - - * Very simple API consisting of a single function that needs - to be called once for the first INVITE of every call. The - rest is done automatically in the background using dialog - callbacks. - * Gracefully end dialogs when they exceed their time by - triggering a dlg_end_dlg request into the dialog module, - that will generate two BYE messages towards each endpoint, - ending the call cleanly. - * Allow parallel sessions using one balance per subscriber - * Integrates with mediaproxy's ability to detect when a call - does timeout sending media and is closed. In this case the - dlg_end_dlg that is triggered by mediaproxy will end the - callcontrol session before it reaches the limit and - consumes all the credit for a call that died and didn't - actually take place. For this mediaproxy has to be used and - it has to be started by engage_media_proxy() to be able to - keep track of the call's dialog and end it on timeout. - * Even when mediaproxy is unable to end the dialog because it - was not started with engage_media_proxy(), the callcantrol - application is still able to detect calls that did timeout - sending media, by looking in the radius accounting records - for entries recorded by mediaproxy for calls that did - timeout. These calls will also be ended gracefully by the - callcontrol application itself. - * If the prepaid_account_flag module parameter is defined, - the external application compares the OpenSIPS's and the - rating engine's views on whether the account calling is - prepaid or not and takes appropriate action if they - conflict. This provides protection against frauds in case - the rating engine malfunctions or there is an inconsistency - in the database. - * If the call_limit_avp is defined to a value greater than 0 - it will be passed to the CallControl application, which - will limit the number of concurrent calls the billing party - (From user or diverter) is able to make. If the limit is - reached the call_control function will return a specific - error value. - * The call_token_avp may be used to detect calls with a - duplicated CallID that could create potential problems in - call rating engines. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog module - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported parameters - -1.5.1. disable (int) - - Boolean flag that specifies if callcontrol should be disabled. - This is useful when you want to use the same OpenSIPS - configuration in two different context, one using callcontrol, - the other not. In the case callcontrol is disabled, calls to - the call_control() function will return a code indicating that - there is no limit associated with the call, allowing the use of - the same configuration without changes. - - Default value is “0”. - - Example 1.1. Setting the disable parameter -... -modparam("call_control", "disable", 1) -... - -1.5.2. socket_name (string) - - It is the path to the filesystem socket where the callcontrol - application listens for commands from the module. - - Default value is “/run/callcontrol/socket”. - - Example 1.2. Setting the socket_name parameter -... -modparam("call_control", "socket_name", "/run/callcontrol/socket") -... - -1.5.3. socket_timeout (int) - - How much time (in milliseconds) to wait for an answer from the - callcontrol application. - - Default value is “500” (ms). - - Example 1.3. Setting the socket_timeout parameter -... -modparam("call_control", "socket_timeout", 500) -... - -1.5.4. signaling_ip_avp (string) - - Specification of the AVP which holds the IP address from where - the SIP signaling originated. If this AVP is set it will be - used to get the signaling IP address, else the source IP - address from where the SIP message was received will be used. - This AVP is meant to be used in cases where there are more than - one proxy in the call setup path and the proxy that actually - starts callcontrol doesn't receive the SIP messages directly - from the UA and it cannot determine the NAT IP address from - where the signaling originated. In such a case attaching a SIP - header at the first proxy and then copying that header's value - into the signaling_ip_avp on the proxy that starts callcontrol - will allow it to get the correct NAT IP address from where the - SIP signaling originated. - - This is used by the rating engine which finds the rates to - apply to a call based on caller's SIP URI, caller's SIP domain - or caller's IP address (whichever yields a rate first, in this - order). - - Default value is “$avp(cc_signaling_ip)”. - - Example 1.4. Setting the signaling_ip_avp parameter -... -modparam("call_control", "signaling_ip_avp", "$avp(cc_signaling_ip)") -... - -1.5.5. canonical_uri_avp (string) - - Specification of the AVP which holds an optional application - defined canonical request URI. When this is set, it will be - used as the destination when computing the call price, - otherwise the request URI will be used. This is useful when the - username of the ruri needs to have a different, canonical form - in the rating engine computation than it has in the ruri. - - Default value is “$avp(cc_can_uri)”. - - Example 1.5. Setting the canonical_uri_avp parameter -... -modparam("call_control", "canonical_uri_avp", "$avp(cc_can_uri)") -... - -1.5.6. diverter_avp (string) - - Specification of the AVP which holds an optional application - defined diverter SIP URI. When this is set, it will be used by - the rating engine as the billing party when finding the rates - to apply to a given call, otherwise, the caller's URI taken - from the From field will be used. When set, this AVP should - contain a value in the form “user@domain” (no sip: prefix - should be used). - - This is useful when a destination diverts a call, thus becoming - the new caller. In this case the billing party is the diverter - and this AVP should be set to it, to allow the rating engine to - pick the right rates for the call. For example, if A calls B - and B diverts all its calls unconditionally to C, then the - diverter AVP should the set to B's URI, because B is the - billing party in the call not A after the call was diverted. - - Default value is “$avp(diverter)”. - - Example 1.6. Setting the diverter_avp parameter -... -modparam("call_control", "diverter_avp", "$avp(diverter)") - -route { - ... - # alice@example.com is paying for this call - $avp(diverter) = "alice@example.com"; - ... -} -... - -1.5.7. prepaid_account_flag (string) - - The flag that is used to specify whether the account making the - call is prepaid or postpaid. Setting this to a non-null value - will determine the module to pass the flag's value to the - external application. This will allow the external application - to compare OpenSIPS's and the rating engine's views on whether - the account calling is prepaid or not and take appropriate - action if they conflict. The flag should be set from the - OpenSIPS configuration for a prepaid account and reset for a - postpaid one. - - Default value is NULL (undefined). - - Example 1.7. Setting the prepaid_account_flag parameter -... -modparam("call_control", "prepaid_account_flag", "PP_ACC_FLAG") -... - -1.5.8. call_limit_avp (string) - - Specification of the AVP which holds an optional application - defined call limit. When this is set, it will be passed to the - CallControl application and if the limit is reached the - call_control function will return an error code of -4. - - Default value is “$avp(cc_call_limit)”. - - Example 1.8. Setting the call_limit_avp parameter -... -modparam("call_control", "call_limit_avp", "$avp(cc_call_limit)") -... - -1.5.9. call_token_avp (string) - - Specification of the AVP which holds an optional application - defined token. This token will be used to check if two calls - with the same CallID actually refer to the same call. If - call_control() is called multiple times for the same call (thus - same CallID) the token needs to be the same or call_control - will return -3 error, indicating that the CallID is duplicated. - - Default value is “$avp(cc_call_token)”. - - Example 1.9. Setting the call_token_avp parameter -... -modparam("call_control", "call_token_avp", "$avp(cc_call_token)") -... -$avp(cc_call_token) := $RANDOM; -... - -1.5.10. init (string) - - This parameter is used to describe custom call control - initialize messages. It represents a list of key value pairs - and has the following format: - * "string1 = var1 [string2 = var2]*" - - The left-hand side of the assignment can be any string. - - The right-hand side of the assignment must be a script pseudo - variable or a script AVP. For more information about them see - CookBooks - Scripting Variables. - - If the parameter is not set, the default initialize message is - sent. - - Default value is “NULL”. - - Example 1.10. Setting the init parameter - -... -modparam("call_control", "init", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - -1.5.11. start (string) - - This parameter is used to describe custom call control start - messages. It represents a list of key value pairs and has the - following format: - * "string1 = var1 [string2 = var2]*" - - The left-hand side of the assignment can be any string. - - The right-hand side of the assignment must be a script pseudo - variable or a script AVP. For more information about them see - CookBooks - Scripting Variables. - - If the parameter is not set, the default start message is sent. - - Default value is “NULL”. - - Example 1.11. Setting the start parameter - -... -modparam("call_control", "start", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - -1.5.12. stop (string) - - This parameter is used to describe custom call control stop - messages. It represents a list of key value pairs and has the - following format: - * "string1 = var1 [string2 = var2]*" - - The left-hand side of the assignment can be any string. - - The right-hand side of the assignment must be a script pseudo - variable or a script AVP. For more information about them see - CookBooks - Scripting Variables. - - If the parameter is not set, the default stop message is sent. - - Default value is “NULL”. - - Example 1.12. Setting the stop parameter - -... -modparam("call_control", "stop", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - -1.6. Exported Functions - -1.6.1. call_control() - - Trigger the use of callcontrol for the dialog started by the - INVITE for which this function is called (the function should - only be called for the first INVITE of a call). Further - in-dialog requests will be processed automatically using - internal bindings into the dialog state machine, allowing - callcontrol to update its internal state as the dialog - progresses, without any other intervention from the script. - - This function should be called right before the message is sent - out using t_relay(), when all the request uri modifications are - over and a final destination has been determined. - - This function has the following return codes: - - * +2 - call has no limit - * +1 - call has limit and is traced by callcontrol - * -1 - not enough credit to make the call - * -2 - call is locked by another call in progress - * -3 - duplicated callid - * -4 - call limit has been reached - * -5 - internal error (message parsing, communication, ...) - - This function can be used from REQUEST_ROUTE. - - Example 1.13. Using the call_control function - -... -if ($avp(805) != NULL) { - # the diverter AVP is set, use it as billing party - $avp(billing_party_domain) = $(avp(805){uri.domain}); -} else { - $avp(billing_party_domain) = $fd; -} - -if (is_method("INVITE") && !has_totag() && - is_domain_local($avp(billing_party_domain))) { - call_control(); - switch ($retcode) { - case 2: - # Call with no limit - case 1: - # Call has limit and is under callcontrol management - break; - case -1: - # Not enough credit (prepaid call) - sl_send_reply(402, "Not enough credit"); - exit; - break; - case -2: - # Locked by another call in progress (prepaid call) - sl_send_reply(403, "Call locked by another call in progress"); - exit; - break; - case -3: - # Duplicated callid - sl_send_reply(400, "Duplicated callid"); - exit; - break; - case -4: - # Call limit reached - sl_send_reply(503, "Too many concurrent calls"); - exit; - break; - default: - # Internal error (message parsing, communication, ...) - if (PREPAID_ACCOUNT) { - xlog("Call control: internal server error\n"); - sl_send_reply(500, "Internal server error"); - exit; - } else { - xlog("L_WARN", "Cannot set time limit for postpaid call\n"); - } - } -} -t_relay(); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Dan Pascu (@danpascu) 27 10 1621 177 - 2. Liviu Chircu (@liviuchircu) 16 13 56 67 - 3. Saúl Ibarra Corretgé (@saghul) 15 9 320 124 - 4. Razvan Crainea (@razvancrainea) 12 10 58 34 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 11 9 18 48 - 6. Irina-Maria Stanescu 6 2 356 17 - 7. Vlad Patrascu (@rvlad-patrascu) 5 3 11 9 - 8. Vlad Paiu (@vladpaiu) 4 2 5 12 - 9. Maksym Sobolyev (@sobomax) 4 2 3 4 - 10. Alexey Vasilyev (@vasilevalex) 3 1 3 3 - - All remaining contributors: Zero King (@l2dy), Julián Moreno - Patiño, Peter Lemenkov (@lemenkov), Mauro Davi. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 2. Razvan Crainea (@razvancrainea) Jul 2010 - Feb 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Alexey Vasilyev (@vasilevalex) Mar 2022 - Mar 2022 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2009 - May 2020 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Dan Pascu (@danpascu) Dec 2008 - Aug 2019 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Saúl Ibarra Corretgé (@saghul), - Vlad Paiu (@vladpaiu), Irina-Maria Stanescu, Mauro Davi. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Alexey - Vasilyev (@vasilevalex), Zero King (@l2dy), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Dan Pascu - (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu - (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Irina-Maria - Stanescu. - - Documentation Copyrights: - - Copyright © 2005-2008 Dan Pascu diff --git a/modules/call_control/README.md b/modules/call_control/README.md new file mode 100644 index 00000000000..c80e3c39241 --- /dev/null +++ b/modules/call_control/README.md @@ -0,0 +1,536 @@ +--- +title: "Call Control Module" +description: "This module allows one to limit the duration of calls and automatically end them when they exceed the imposed limit." +--- + +## Admin Guide + + +### Overview + + +This module allows one to limit the duration of calls and automatically +end them when they exceed the imposed limit. Its main use case is to +implement a prepaid system, but it can also be used to impose a global +limit on all calls processed by the proxy. + + +### Description + + +Callcontrol consists of 3 components: + + +- The OpenSIPS call_control module +- An external application called callcontrol which keeps track of +the calls that have a time limit and automatically ends them when +they exceed it. This application receives requests from OpenSIPS +and makes requests to a rating engine (see below) to find out if +a call needs to be limited or not. When a call ends (or is ended) +it will also instruct the rating engine to debit the balance for +the caller with the consumed amount. The callcontrol application +is available from http://callcontrol.ag-projects.com/ +- A rating engine that is used to calculate the time limit based on +the caller's credit and the destination price and to debit the +caller's balance after a call ends. This is available as part of +CDRTool from http://cdrtool.ag-projects.com/ + + +The callcontrol application runs on the same machine as OpenSIPS and they +communicate over a filesystem socket, while the rating engine can run on +a different host and communicates with the callcontrol application using +a TCP connection. + + +Callcontrol is invoked by calling the call_control() function for the +initial INVITE of every call we want to apply a limit to. This will end +up as a request to the callcontrol application, which will interrogate +the rating engine for a time limit for the given caller and destination. +The rating engine will determine if the destination has any associated +cost and if the caller has any credit limit and if so will return the +amount of time he is allowed to call that destination. Otherwise it will +indicate that there is no limit associated with the call. If there is a +limit, the callcontrol application will retain the session and attach +a timer to it that will expire after the given time causing it to call +back to OpenSIPS with a request to end the dialog. If the rating engine +returns that there is no limit for the call, the session is discarded +by the callcontrol application and it will allow it to go proceed any +limit. An appropriate response is returned to the call_control module +that is then returned by the call_control() function call and allows +the script to make a decision based on the answer. + + +### Features + + +- Very simple API consisting of a single function that needs to be +called once for the first INVITE of every call. The rest is done +automatically in the background using dialog callbacks. +- Gracefully end dialogs when they exceed their time by triggering +a dlg_end_dlg request into the dialog module, that will generate +two BYE messages towards each endpoint, ending the call cleanly. +- Allow parallel sessions using one balance per subscriber +- Integrates with mediaproxy's ability to detect when a call does +timeout sending media and is closed. In this case the dlg_end_dlg +that is triggered by mediaproxy will end the callcontrol session +before it reaches the limit and consumes all the credit for a call +that died and didn't actually take place. For this mediaproxy has +to be used and it has to be started by engage_media_proxy() to be +able to keep track of the call's dialog and end it on timeout. +- Even when mediaproxy is unable to end the dialog because it was +not started with engage_media_proxy(), the callcantrol application +is still able to detect calls that did timeout sending media, by +looking in the radius accounting records for entries recorded by +mediaproxy for calls that did timeout. These calls will also be +ended gracefully by the callcontrol application itself. +- If the prepaid_account_flag module parameter is defined, the +external application compares the OpenSIPS's and the rating engine's +views on whether the account calling is prepaid or not and takes +appropriate action if they conflict. This provides protection +against frauds in case the rating engine malfunctions or there is an +inconsistency in the database. +- If the call_limit_avp is defined to a value greater than 0 it will be +passed to the CallControl application, which will limit the number of concurrent +calls the billing party (From user or diverter) is able to make. If the limit +is reached the call_control function will return a specific error value. +- The call_token_avp may be used to detect calls with a duplicated CallID that could +create potential problems in call rating engines. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog* module + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### disable (int) + + +Boolean flag that specifies if callcontrol should be disabled. This +is useful when you want to use the same OpenSIPS configuration in +two different context, one using callcontrol, the other not. In the +case callcontrol is disabled, calls to the call_control() function +will return a code indicating that there is no limit associated with +the call, allowing the use of the same configuration without changes. + + +*Default value is "0".* + + +```opensips title="Setting the disable parameter" +... +modparam("call_control", "disable", 1) +... + +``` + + +#### socket_name (string) + + +It is the path to the filesystem socket where the callcontrol +application listens for commands from the module. + + +*Default value is +"/run/callcontrol/socket".* + + +```opensips title="Setting the socket_name parameter" +... +modparam("call_control", "socket_name", "/run/callcontrol/socket") +... + +``` + + +#### socket_timeout (int) + + +How much time (in milliseconds) to wait for an answer from the +callcontrol application. + + +*Default value is "500" (ms).* + + +```opensips title="Setting the socket_timeout parameter" +... +modparam("call_control", "socket_timeout", 500) +... + +``` + + +#### signaling_ip_avp (string) + + +Specification of the AVP which holds the IP address from where +the SIP signaling originated. If this AVP is set it will be used +to get the signaling IP address, else the source IP address +from where the SIP message was received will be used. +This AVP is meant to be used in cases where there are more than +one proxy in the call setup path and the proxy that actually +starts callcontrol doesn't receive the SIP messages directly +from the UA and it cannot determine the NAT IP address from +where the signaling originated. In such a case attaching a +SIP header at the first proxy and then copying that header's +value into the signaling_ip_avp on the proxy that starts +callcontrol will allow it to get the correct NAT IP address +from where the SIP signaling originated. + + +This is used by the rating engine which finds the rates to apply to a +call based on caller's SIP URI, caller's SIP domain or caller's IP +address (whichever yields a rate first, in this order). + + +*Default value is "$avp(cc_signaling_ip)".* + + +```opensips title="Setting the signaling_ip_avp parameter" +... +modparam("call_control", "signaling_ip_avp", "$avp(cc_signaling_ip)") +... + +``` + + +#### canonical_uri_avp (string) + + +Specification of the AVP which holds an optional application defined +canonical request URI. When this is set, it will be used as the +destination when computing the call price, otherwise the request URI +will be used. This is useful when the username of the ruri needs to +have a different, canonical form in the rating engine computation +than it has in the ruri. + + +*Default value is "$avp(cc_can_uri)".* + + +```opensips title="Setting the canonical_uri_avp parameter" +... +modparam("call_control", "canonical_uri_avp", "$avp(cc_can_uri)") +... + +``` + + +#### diverter_avp (string) + + +Specification of the AVP which holds an optional +application defined diverter SIP URI. When this is set, it will be +used by the rating engine as the billing party when finding the rates +to apply to a given call, otherwise, the caller's URI taken from the +From field will be used. When set, this AVP should contain a value in +the form "user@domain" (no sip: prefix should be used). + + +This is useful when a destination diverts a call, thus becoming the +new caller. In this case the billing party is the diverter and this +AVP should be set to it, to allow the rating engine to pick the right +rates for the call. For example, if A calls B and B diverts all its +calls unconditionally to C, then the diverter AVP should the set to +B's URI, because B is the billing party in the call not A after the +call was diverted. + + +*Default value is "$avp(diverter)".* + + +```opensips title="Setting the diverter_avp parameter" +... +modparam("call_control", "diverter_avp", "$avp(diverter)") + +route { + ... + # alice@example.com is paying for this call + $avp(diverter) = "alice@example.com"; + ... +} +... + +``` + + +#### prepaid_account_flag (string) + + +The flag that is used to specify whether the account making the call is +prepaid or postpaid. Setting this to a non-null value will determine +the module to pass the flag's value to the external application. This +will allow the external application to compare OpenSIPS's and the rating +engine's views on whether the account calling is prepaid or not and take +appropriate action if they conflict. The flag should be set from the +OpenSIPS configuration for a prepaid account and reset for a postpaid +one. + + +*Default value is NULL (undefined).* + + +```opensips title="Setting the prepaid_account_flag parameter" +... +modparam("call_control", "prepaid_account_flag", "PP_ACC_FLAG") +... + +``` + + +#### call_limit_avp (string) + + +Specification of the AVP which holds an optional application defined +call limit. When this is set, it will be passed to the CallControl +application and if the limit is reached the call_control function will +return an error code of -4. + + +*Default value is "$avp(cc_call_limit)".* + + +```opensips title="Setting the call_limit_avp parameter" +... +modparam("call_control", "call_limit_avp", "$avp(cc_call_limit)") +... + +``` + + +#### call_token_avp (string) + + +Specification of the AVP which holds an optional application defined +token. This token will be used to check if two calls with the same +CallID actually refer to the same call. If call_control() is called +multiple times for the same call (thus same CallID) the token needs +to be the same or call_control will return -3 error, indicating that +the CallID is duplicated. + + +*Default value is "$avp(cc_call_token)".* + + +```opensips title="Setting the call_token_avp parameter" +... +modparam("call_control", "call_token_avp", "$avp(cc_call_token)") +... +$avp(cc_call_token) := $RANDOM; +... + +``` + + +#### init (string) + + +This parameter is used to describe custom call control initialize messages. It represents a +list of key value pairs and has the following format: + + +- "string1 = var1 [string2 = var2]*" + + +The left-hand side of the assignment can be any string. + + +The right-hand side of the assignment must be a script pseudo variable or +a script AVP. For more information about them see [CookBooks - Scripting Variables](https://docs.opensips.org/manual/3-6/script-corevar/). + + +If the parameter is not set, the default initialize message is sent. + + +*Default value is "NULL".* + + +```opensips title="Setting the init parameter" + +... +modparam("call_control", "init", "call-id=$ci to=$tu from=$fu + authruri=$du another_field = $avp(10)") +... + +``` + + +#### start (string) + + +This parameter is used to describe custom call control start messages. It represents a +list of key value pairs and has the following format: + + +- "string1 = var1 [string2 = var2]*" + + +The left-hand side of the assignment can be any string. + + +The right-hand side of the assignment must be a script pseudo variable or +a script AVP. For more information about them see [CookBooks - Scripting Variables](https://docs.opensips.org/manual/3-6/script-corevar/). + + +If the parameter is not set, the default start message is sent. + + +*Default value is "NULL".* + + +```opensips title="Setting the start parameter" + +... +modparam("call_control", "start", "call-id=$ci to=$tu from=$fu + authruri=$du another_field = $avp(10)") +... + +``` + + +#### stop (string) + + +This parameter is used to describe custom call control stop messages. It represents a +list of key value pairs and has the following format: + + +- "string1 = var1 [string2 = var2]*" + + +The left-hand side of the assignment can be any string. + + +The right-hand side of the assignment must be a script pseudo variable or +a script AVP. For more information about them see [CookBooks - Scripting Variables](https://docs.opensips.org/manual/3-6/script-corevar/). + + +If the parameter is not set, the default stop message is sent. + + +*Default value is "NULL".* + + +```opensips title="Setting the stop parameter" + +... +modparam("call_control", "stop", "call-id=$ci to=$tu from=$fu + authruri=$du another_field = $avp(10)") +... + +``` + + +### Exported Functions + + +#### call_control() + + +Trigger the use of callcontrol for the dialog started by the INVITE +for which this function is called (the function should only be called +for the first INVITE of a call). Further in-dialog requests will be +processed automatically using internal bindings into the dialog state +machine, allowing callcontrol to update its internal state as the +dialog progresses, without any other intervention from the script. + + +This function should be called right before the message is sent out +using t_relay(), when all the request uri modifications are over and +a final destination has been determined. + + +This function has the following return codes: + + +- +2 - call has no limit +- +1 - call has limit and is traced by callcontrol +- -1 - not enough credit to make the call +- -2 - call is locked by another call in progress +- -3 - duplicated callid +- -4 - call limit has been reached +- -5 - internal error (message parsing, communication, ...) + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Using the call_control function" +... +if ($avp(805) != NULL) { + # the diverter AVP is set, use it as billing party + $avp(billing_party_domain) = $(avp(805){uri.domain}); +} else { + $avp(billing_party_domain) = $fd; +} + +if (is_method("INVITE") && !has_totag() && + is_domain_local($avp(billing_party_domain))) { + call_control(); + switch ($retcode) { + case 2: + # Call with no limit + case 1: + # Call has limit and is under callcontrol management + break; + case -1: + # Not enough credit (prepaid call) + sl_send_reply(402, "Not enough credit"); + exit; + break; + case -2: + # Locked by another call in progress (prepaid call) + sl_send_reply(403, "Call locked by another call in progress"); + exit; + break; + case -3: + # Duplicated callid + sl_send_reply(400, "Duplicated callid"); + exit; + break; + case -4: + # Call limit reached + sl_send_reply(503, "Too many concurrent calls"); + exit; + break; + default: + # Internal error (message parsing, communication, ...) + if (PREPAID_ACCOUNT) { + xlog("Call control: internal server error\n"); + sl_send_reply(500, "Internal server error"); + exit; + } else { + xlog("L_WARN", "Cannot set time limit for postpaid call\n"); + } + } +} +t_relay(); +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/call_control/doc/call_control.xml b/modules/call_control/doc/call_control.xml deleted file mode 100644 index 491d8f49580..00000000000 --- a/modules/call_control/doc/call_control.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Call Control Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2008 Dan Pascu - diff --git a/modules/call_control/doc/call_control_admin.xml b/modules/call_control/doc/call_control_admin.xml deleted file mode 100644 index f26c92a1ea0..00000000000 --- a/modules/call_control/doc/call_control_admin.xml +++ /dev/null @@ -1,699 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module allows one to limit the duration of calls and automatically - end them when they exceed the imposed limit. Its main use case is to - implement a prepaid system, but it can also be used to impose a global - limit on all calls processed by the proxy. - -
- -
- Description - - Callcontrol consists of 3 components: - - - The &osips; call_control module - - - - An external application called callcontrol which keeps track of - the calls that have a time limit and automatically ends them when - they exceed it. This application receives requests from &osips; - and makes requests to a rating engine (see below) to find out if - a call needs to be limited or not. When a call ends (or is ended) - it will also instruct the rating engine to debit the balance for - the caller with the consumed amount. The callcontrol application - is available from http://callcontrol.ag-projects.com/ - - - - - A rating engine that is used to calculate the time limit based on - the caller's credit and the destination price and to debit the - caller's balance after a call ends. This is available as part of - CDRTool from http://cdrtool.ag-projects.com/ - - - - - - - The callcontrol application runs on the same machine as &osips; and they - communicate over a filesystem socket, while the rating engine can run on - a different host and communicates with the callcontrol application using - a TCP connection. - - - - Callcontrol is invoked by calling the call_control() function for the - initial INVITE of every call we want to apply a limit to. This will end - up as a request to the callcontrol application, which will interrogate - the rating engine for a time limit for the given caller and destination. - The rating engine will determine if the destination has any associated - cost and if the caller has any credit limit and if so will return the - amount of time he is allowed to call that destination. Otherwise it will - indicate that there is no limit associated with the call. If there is a - limit, the callcontrol application will retain the session and attach - a timer to it that will expire after the given time causing it to call - back to &osips; with a request to end the dialog. If the rating engine - returns that there is no limit for the call, the session is discarded - by the callcontrol application and it will allow it to go proceed any - limit. An appropriate response is returned to the call_control module - that is then returned by the call_control() function call and allows - the script to make a decision based on the answer. - -
- -
- Features - - - - - Very simple API consisting of a single function that needs to be - called once for the first INVITE of every call. The rest is done - automatically in the background using dialog callbacks. - - - - - - Gracefully end dialogs when they exceed their time by triggering - a dlg_end_dlg request into the dialog module, that will generate - two BYE messages towards each endpoint, ending the call cleanly. - - - - - - Allow parallel sessions using one balance per subscriber - - - - - - Integrates with mediaproxy's ability to detect when a call does - timeout sending media and is closed. In this case the dlg_end_dlg - that is triggered by mediaproxy will end the callcontrol session - before it reaches the limit and consumes all the credit for a call - that died and didn't actually take place. For this mediaproxy has - to be used and it has to be started by engage_media_proxy() to be - able to keep track of the call's dialog and end it on timeout. - - - - - - Even when mediaproxy is unable to end the dialog because it was - not started with engage_media_proxy(), the callcantrol application - is still able to detect calls that did timeout sending media, by - looking in the radius accounting records for entries recorded by - mediaproxy for calls that did timeout. These calls will also be - ended gracefully by the callcontrol application itself. - - - - - - If the prepaid_account_flag module parameter is defined, the - external application compares the &osips;'s and the rating engine's - views on whether the account calling is prepaid or not and takes - appropriate action if they conflict. This provides protection - against frauds in case the rating engine malfunctions or there is an - inconsistency in the database. - - - - - - If the call_limit_avp is defined to a value greater than 0 it will be - passed to the CallControl application, which will limit the number of concurrent - calls the billing party (From user or diverter) is able to make. If the limit - is reached the call_control function will return a specific error value. - - - - - - The call_token_avp may be used to detect calls with a duplicated CallID that could - create potential problems in call rating engines. - - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog module - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported parameters -
- <varname>disable</varname> (int) - - Boolean flag that specifies if callcontrol should be disabled. This - is useful when you want to use the same &osips; configuration in - two different context, one using callcontrol, the other not. In the - case callcontrol is disabled, calls to the call_control() function - will return a code indicating that there is no limit associated with - the call, allowing the use of the same configuration without changes. - - - - - Default value is 0. - - - - - Setting the <varname>disable</varname> parameter - -... -modparam("call_control", "disable", 1) -... - - -
- -
- <varname>socket_name</varname> (string) - - It is the path to the filesystem socket where the callcontrol - application listens for commands from the module. - - - - - Default value is - /run/callcontrol/socket. - - - - - Setting the <varname>socket_name</varname> parameter - -... -modparam("call_control", "socket_name", "/run/callcontrol/socket") -... - - -
- -
- <varname>socket_timeout</varname> (int) - - How much time (in milliseconds) to wait for an answer from the - callcontrol application. - - - - - Default value is 500 (ms). - - - - - Setting the <varname>socket_timeout</varname> parameter - -... -modparam("call_control", "socket_timeout", 500) -... - - -
- -
- <varname>signaling_ip_avp</varname> (string) - - Specification of the AVP which holds the IP address from where - the SIP signaling originated. If this AVP is set it will be used - to get the signaling IP address, else the source IP address - from where the SIP message was received will be used. - This AVP is meant to be used in cases where there are more than - one proxy in the call setup path and the proxy that actually - starts callcontrol doesn't receive the SIP messages directly - from the UA and it cannot determine the NAT IP address from - where the signaling originated. In such a case attaching a - SIP header at the first proxy and then copying that header's - value into the signaling_ip_avp on the proxy that starts - callcontrol will allow it to get the correct NAT IP address - from where the SIP signaling originated. - - - - This is used by the rating engine which finds the rates to apply to a - call based on caller's SIP URI, caller's SIP domain or caller's IP - address (whichever yields a rate first, in this order). - - - - - Default value is $avp(cc_signaling_ip). - - - - - Setting the <varname>signaling_ip_avp</varname> parameter - -... -modparam("call_control", "signaling_ip_avp", "$avp(cc_signaling_ip)") -... - - -
- -
- <varname>canonical_uri_avp</varname> (string) - - Specification of the AVP which holds an optional application defined - canonical request URI. When this is set, it will be used as the - destination when computing the call price, otherwise the request URI - will be used. This is useful when the username of the ruri needs to - have a different, canonical form in the rating engine computation - than it has in the ruri. - - - - - Default value is $avp(cc_can_uri). - - - - - Setting the <varname>canonical_uri_avp</varname> parameter - -... -modparam("call_control", "canonical_uri_avp", "$avp(cc_can_uri)") -... - - -
- -
- <varname>diverter_avp</varname> (string) - - Specification of the AVP which holds an optional - application defined diverter SIP URI. When this is set, it will be - used by the rating engine as the billing party when finding the rates - to apply to a given call, otherwise, the caller's URI taken from the - From field will be used. When set, this AVP should contain a value in - the form user@domain (no sip: prefix should be used). - - - This is useful when a destination diverts a call, thus becoming the - new caller. In this case the billing party is the diverter and this - AVP should be set to it, to allow the rating engine to pick the right - rates for the call. For example, if A calls B and B diverts all its - calls unconditionally to C, then the diverter AVP should the set to - B's URI, because B is the billing party in the call not A after the - call was diverted. - - - - - Default value is $avp(diverter). - - - - - Setting the <varname>diverter_avp</varname> parameter - -... -modparam("call_control", "diverter_avp", "$avp(diverter)") - -route { - ... - # alice@example.com is paying for this call - $avp(diverter) = "alice@example.com"; - ... -} -... - - -
- -
- <varname>prepaid_account_flag</varname> (string) - - The flag that is used to specify whether the account making the call is - prepaid or postpaid. Setting this to a non-null value will determine - the module to pass the flag's value to the external application. This - will allow the external application to compare &osips;'s and the rating - engine's views on whether the account calling is prepaid or not and take - appropriate action if they conflict. The flag should be set from the - &osips; configuration for a prepaid account and reset for a postpaid - one. - - - - - Default value is NULL (undefined). - - - - - Setting the <varname>prepaid_account_flag</varname> parameter - -... -modparam("call_control", "prepaid_account_flag", "PP_ACC_FLAG") -... - - -
- -
- <varname>call_limit_avp</varname> (string) - - Specification of the AVP which holds an optional application defined - call limit. When this is set, it will be passed to the CallControl - application and if the limit is reached the call_control function will - return an error code of -4. - - - - - Default value is $avp(cc_call_limit). - - - - - Setting the <varname>call_limit_avp</varname> parameter - -... -modparam("call_control", "call_limit_avp", "$avp(cc_call_limit)") -... - - -
- -
- <varname>call_token_avp</varname> (string) - - Specification of the AVP which holds an optional application defined - token. This token will be used to check if two calls with the same - CallID actually refer to the same call. If call_control() is called - multiple times for the same call (thus same CallID) the token needs - to be the same or call_control will return -3 error, indicating that - the CallID is duplicated. - - - - - Default value is $avp(cc_call_token). - - - - - Setting the <varname>call_token_avp</varname> parameter - -... -modparam("call_control", "call_token_avp", "$avp(cc_call_token)") -... -$avp(cc_call_token) := $RANDOM; -... - - -
- -
- <varname>init</varname> (string) - - This parameter is used to describe custom call control initialize messages. It represents a - list of key value pairs and has the following format: - - - - - "string1 = var1 [string2 = var2]*" - - - - - The left-hand side of the assignment can be any string. - - - The right-hand side of the assignment must be a script pseudo variable or - a script AVP. For more information about them see - CookBooks - Scripting Variables. - - - If the parameter is not set, the default initialize message is sent. - - - - Default value is NULL. - - - - - Setting the <varname>init</varname> parameter - - -... -modparam("call_control", "init", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - - -
- -
- <varname>start</varname> (string) - - This parameter is used to describe custom call control start messages. It represents a - list of key value pairs and has the following format: - - - - - "string1 = var1 [string2 = var2]*" - - - - - The left-hand side of the assignment can be any string. - - - The right-hand side of the assignment must be a script pseudo variable or - a script AVP. For more information about them see - CookBooks - Scripting Variables. - - - If the parameter is not set, the default start message is sent. - - - - Default value is NULL. - - - - - Setting the <varname>start</varname> parameter - - -... -modparam("call_control", "start", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - - -
-
- <varname>stop</varname> (string) - - This parameter is used to describe custom call control stop messages. It represents a - list of key value pairs and has the following format: - - - - - "string1 = var1 [string2 = var2]*" - - - - - The left-hand side of the assignment can be any string. - - - The right-hand side of the assignment must be a script pseudo variable or - a script AVP. For more information about them see - CookBooks - Scripting Variables. - - - If the parameter is not set, the default stop message is sent. - - - - Default value is NULL. - - - - - Setting the <varname>stop</varname> parameter - - -... -modparam("call_control", "stop", "call-id=$ci to=$tu from=$fu - authruri=$du another_field = $avp(10)") -... - - -
- - - - -
- -
- Exported Functions -
- <function moreinfo="none">call_control()</function> - - Trigger the use of callcontrol for the dialog started by the INVITE - for which this function is called (the function should only be called - for the first INVITE of a call). Further in-dialog requests will be - processed automatically using internal bindings into the dialog state - machine, allowing callcontrol to update its internal state as the - dialog progresses, without any other intervention from the script. - - - - This function should be called right before the message is sent out - using t_relay(), when all the request uri modifications are over and - a final destination has been determined. - - - This function has the following return codes: - - - - +2 - call has no limit - - - +1 - call has limit and is traced by callcontrol - - - -1 - not enough credit to make the call - - - -2 - call is locked by another call in progress - - - -3 - duplicated callid - - - -4 - call limit has been reached - - - -5 - internal error (message parsing, communication, ...) - - - - - - This function can be used from REQUEST_ROUTE. - - - - Using the <function>call_control</function> function - - -... -if ($avp(805) != NULL) { - # the diverter AVP is set, use it as billing party - $avp(billing_party_domain) = $(avp(805){uri.domain}); -} else { - $avp(billing_party_domain) = $fd; -} - -if (is_method("INVITE") && !has_totag() && - is_domain_local($avp(billing_party_domain))) { - call_control(); - switch ($retcode) { - case 2: - # Call with no limit - case 1: - # Call has limit and is under callcontrol management - break; - case -1: - # Not enough credit (prepaid call) - sl_send_reply(402, "Not enough credit"); - exit; - break; - case -2: - # Locked by another call in progress (prepaid call) - sl_send_reply(403, "Call locked by another call in progress"); - exit; - break; - case -3: - # Duplicated callid - sl_send_reply(400, "Duplicated callid"); - exit; - break; - case -4: - # Call limit reached - sl_send_reply(503, "Too many concurrent calls"); - exit; - break; - default: - # Internal error (message parsing, communication, ...) - if (PREPAID_ACCOUNT) { - xlog("Call control: internal server error\n"); - sl_send_reply(500, "Internal server error"); - exit; - } else { - xlog("L_WARN", "Cannot set time limit for postpaid call\n"); - } - } -} -t_relay(); -... - - -
-
- -
- diff --git a/modules/call_control/doc/contributors.xml b/modules/call_control/doc/contributors.xml deleted file mode 100644 index 65aef96478a..00000000000 --- a/modules/call_control/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Dan Pascu (@danpascu) - 27 - 10 - 1621 - 177 - - - 2. - Liviu Chircu (@liviuchircu) - 16 - 13 - 56 - 67 - - - 3. - Saúl Ibarra Corretgé (@saghul) - 15 - 9 - 320 - 124 - - - 4. - Razvan Crainea (@razvancrainea) - 12 - 10 - 58 - 34 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 11 - 9 - 18 - 48 - - - 6. - Irina-Maria Stanescu - 6 - 2 - 356 - 17 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 11 - 9 - - - 8. - Vlad Paiu (@vladpaiu) - 4 - 2 - 5 - 12 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 10. - Alexey Vasilyev (@vasilevalex) - 3 - 1 - 3 - 3 - - - -
-All remaining contributors: Zero King (@l2dy), Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Mauro Davi. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Jul 2010 - Feb 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Alexey Vasilyev (@vasilevalex) - Mar 2022 - Mar 2022 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2009 - May 2020 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Dan Pascu (@danpascu) - Dec 2008 - Aug 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Saúl Ibarra Corretgé (@saghul), Vlad Paiu (@vladpaiu), Irina-Maria Stanescu, Mauro Davi. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Alexey Vasilyev (@vasilevalex), Zero King (@l2dy), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Irina-Maria Stanescu. -
- -
diff --git a/modules/callops/README b/modules/callops/README deleted file mode 100644 index 36409078307..00000000000 --- a/modules/callops/README +++ /dev/null @@ -1,484 +0,0 @@ -Calling Operations Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. mode (string/integer) - 1.3.2. match_param (string) - - 1.4. Exported Functions - - 1.4.1. call_blind_replace(callid[, leg]) - 1.4.2. call_transfer_notify() - 1.4.3. call_transfer(leg, destination) or - 1.4.4. call_transfer(leg, transfer_callid, - transfer_leg[, destination]) or - - 1.5. Exported MI Functions - - 1.5.1. call_transfer - 1.5.2. call_hold - 1.5.3. call_unhold - - 1.6. Exported Events - - 1.6.1. E_CALL_TRANSFER - 1.6.2. E_CALL_HOLD - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Drop automatically handled NOTIFY refer events - 1.2. Set mode parameter - 1.3. Set match_param parameter - 1.4. Use call_blind_replace() function to match an existing - leg. - - 1.5. Use call_transfer_notify() function to handle NOTIFY refer - requests. - - 1.6. Use call_transfer() function to do a blind transfer of the - caller to a new destination. - - 1.7. Use call_transfer() function to do an attended transfer of - the caller to the callee of a different call. - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a set of functions that allow the user to - control ongoing calls. It can be used to trigger a call (either - blind or attended) transfer, or put a call on hold from the - proxy side, rather than the end-device side. The module binds - on top of the OpenSIPS Dialog module to get information about - the ongoing calls, as well as storing information about new - calls that will be started. - - The module also triggers a set of events over Event Interface, - providing to external applications details about how calls are - being transferred, and how they link between them. These events - can be used to track down all the legs involved in a call - transfer. - - One of the biggest challenge when doing Call Transfer scenarios - is linking new calls to the old calls being transferred, - especially in blind call transfer scenarios. In order to solve - this challenge, the module can be configured to refer old legs - in two different modes, changeable using the mode parameter: - * Automatically (default mode), by adding a special parameter - to the destination URI that is being sent in the REFER. - When the new call comes back, the parameter will be present - in the Request URI of the new call. The module will find - it, link the new call to the old call, and remove the - parameter from the URI. - * Manually, by using custom/external logic (such as a - database, or local storage), to match the old call. In this - mode, the user has to explicitly call the - call_blind_replace() function to link the two calls - together. - - The module can also be used to catch Notify refer events and - reply to them from the OpenSIPS level. However, note that in - auto mode even if the NOTIFY is handled when the dialog is - matched, the request will still continue its execution of the - script, unlike when manual mode is used with the - call_transfer_notify() function. In order to avoid sending the - NOTIFY to the end-point, you have to drop it, like below: - - Example 1.1. Drop automatically handled NOTIFY refer events -... -if (has_totag() && loose_route() && - is_method("NOTIFY") && $hdr(Event) == "refer") - drop; -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction module. - * Dialog - Dialog module for keeping track of the proxied - calls. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. mode (string/integer) - - This parameter can be used to change the mode that the module - uses to match a transferred leg. Supported values are: - * param / 0 - when doing a blind transfer, the destination - sent in the refer message will contain a parameter used to - identify the dialog that is being replaced. this parameter - will be automatically removed when the new call is - received. - * manual / 1 - the user will create its own logic to match - the new calls, and will call the call_blind_replace() - function to make OpenSIPS aware of the pair. Note that this - mode does not handle automatically the Notify refer either, - so you also have to use the call_transfer_notify() function - to handle them. - * callid / 2 - similar to the param value, except that - instead of storing in the Request URI the dialog id of the - call to be transfered, the actual callid is used as - identifier. - - Default value is “0 (auto mode using parameters)”. - - Example 1.2. Set mode parameter -... -modparam("callops", "mode", "manual") # use your own logic -... - -1.3.2. match_param (string) - - The parameter used to match the different calls together. This - is mainly using in the param mode, but it is also used - internally to store different values inside the transferred - dialog - make sure it does not overlap with existing dialog - values. - - Default value is “osid”. - - Example 1.3. Set match_param parameter -... -modparam("callops", "match_param", "call") -... - -1.4. Exported Functions - -1.4.1. call_blind_replace(callid[, leg]) - - When manual mode is used, this function is called to create a - mapping between the transferring call and the transferred call. - It should be called when OpenSIPS receives a new call that is - transferring an existing call. - - Parameters: - * callid (string) - the existing call that is being - transferred. - * leg (string, optional) - the leg that is being transferred. - If not specified, and OpenSIPS cannot determine the leg - based on its destination, the unknown tag should be used. - - This function can be used only from a request route. - - Example 1.4. Use call_blind_replace() function to match an - existing leg. -... -if (!has_totag() && is_method("INVITE")) { - if (cache_fetch("local", "callid_$si", $avp(callid))) { - call_blind_replace($avp(callid)); - } -} -... - -1.4.2. call_transfer_notify() - - When manual mode is used, this function should be called on - in-dialog NOTIFY requests for an Event: refer header, to handle - them accordingly. - - Note that if the function successfully handles the NOTIFY - request, the script no longer continues its execution. - - This function can be used from a request route, failure route - and local route. - - Example 1.5. Use call_transfer_notify() function to handle - NOTIFY refer requests. -... -if (has_totag() && is_method("NOTIFY") && loose_route()) { - call_transfer_notify(); -} -... - -1.4.3. call_transfer(leg, destination) or - - This function triggers a blind call transfer by sending a REFER - message during an ongoing call. The function needs to be run - inside the context of the dialog you are transferring. - - Parameters: - * leg (string) - the leg that is being transferred. Must be - one of the caller or callee values. - * destination (string) - SIP URI of the destination where the - leg is being transferred. - - This function can be used from any route that has a dialog - context. - - Example 1.6. Use call_transfer() function to do a blind - transfer of the caller to a new destination. -... -if (has_totag() && && loose_route()) { - call_transfer("caller", "sip:announcement@127.0.0.1"); -} -... - -1.4.4. call_transfer(leg, transfer_callid, transfer_leg[, -destination]) or - - This function triggers an attended call transfer by sending a - REFER message during an ongoing call. The function needs to be - run inside the context of the dialog you are transferring. - - Parameters: - * leg (string) - the leg that is being transferred. Must be - one of the caller or callee values. - * transfer_callid (string) - the callid of the second dialog - that is being transferred. - * transfer_leg (string) - the leg within the second call that - will be transferred to leg. Must be one of the caller or - callee values. - * destination (string, optional) - SIP URI of the destination - where the leg is being transferred. If missing, the From/To - URI of the initial call are used. - - This function can be used from any route that has a dialog - context. - - Example 1.7. Use call_transfer() function to do an attended - transfer of the caller to the callee of a different call. -... -if (has_totag() && && loose_route()) { - call_transfer("caller", "ba55b1b3-459d-4e84-a6f8-14c40e4f6ace", -"callee"); -} -... - -1.5. Exported MI Functions - -1.5.1. call_transfer - - MI command to transfer an ongoing call to a new destination. - - Depending on the parameters used, this command can do both - blind and attended transfers scenarios. When the - transfer_callid is used, then an attended transfer is - performed, other wise a blind transfer is issued. - - Name: call_transfer - - Parameters - * callid (string) - the callid of the dialog that is being - transferred. - * leg (string) - indicates the leg of the callid call that is - being transferred/kept in the new transferring call. - Possible values are “caller”, “callee” or “both”. - * destination (string, optional) - the URI where the call is - being transferred. This parameter is mandatory for blind - transfers, and optional for attended transfers. In the case - of an attended transfer, if it is missing, the destination - of the call is taken from the URIs in the transfer dialog. - * transfer_callid (string, optional) - mandatory in case of - an attended transfer, to specify the call of the Bleg in - the new call. - * transfer_leg (string, optional) - in case of an attended - transfer, it specifies the participant of the - transfer_callid call that will be bridged with the leg of - the callid. If missing, transfer_fromtag and transfer_totag - must be used to identify the tag. - * transfer_fromtag and transfer_totag (string, optional) - - these parameters should always be specified together, and - are used in call attended transfer scenarios where the - dialog of the Bleg that is being transferred is not managed - by OpenSIPS. Note that for these scenarios only the A-leg - dialog will receive events about the call transfer. - - MI FIFO Command Format: -# blind transfer to sip:agent@127.0.0.1 -opensips-cli -x mi call_transfer \ - callid=4b664b48-5639-40bf-bff8-3a866c145c3b \ - leg=caller \ - destination=sip:agent@217.0.0.1 - -# attended transfer between two calls -opensips-cli -x mi call_transfer \ - callid=e8d024db-78e5-4d18-9794-5b8ba837bed4 - leg=caller \ - transfer_callid=559abf97-9834-4380-bba1-a036eb245450 \ - transfer_leg=calee - -1.5.2. call_hold - - MI command to put an ongoing call on hold. - - Command returns OK if any of the legs of the call have been put - on hold. If the call is already on hold, an error is returned. - - Name: call_hold - - Parameters - * callid (string) - the callid of the dialog that is being - put on hold. - - MI FIFO Command Format: -# put a call on hold -opensips-cli -x mi call_hold \ - callid=921b00e4-fec0-4a36-9397-a40ab74e1893 - -1.5.3. call_unhold - - MI command to resume a call from an onhold state put by the - call_hold call. - - Command returns OK if any of the legs are resumed, or an error - if no leg had been previously put on hold. - - Name: call_unhold - - Parameters - * callid (string) - the callid of the dialog that is being - resumed. - - MI FIFO Command Format: -opensips-cli -x mi call_unhold \ - callid=921b00e4-fec0-4a36-9397-a40ab74e1893 - -1.6. Exported Events - -1.6.1. E_CALL_TRANSFER - - This event is triggered during a call transfer scenario. - - For a specific call transfer, multiple events are triggered, - starting when the transfer is initiated, until the transfer is - completed. The state parameter indicates the state of the call - transfer. - - For a blind transfer scenario, only one set of events are - triggered, whereas for attended transfer, you will get a set of - events for both dialogs involved in the transfer, as long as - both are proxied through OpenSIPS - - Parameters: - * callid - the callid of the call that is being transferred. - * leg - the leg (caller or callee) of the call that is being - transferred. - * transfer_callid - the callid of the new call that is - transferring the old callid call. - * destination - the URI destination where the leg is being - transferred. - * state - the state of the transfer: - + start - triggered when the REFER message is being sent - out to the transferred participant. - + notify - triggered when a NOTIFY refer event is - received from the transferred participant. The status - parameter contains extra information about the status - of the transferring call. - + ok - triggered when the transfer is completed - the - call is answered by the transferred participant. - + fail - triggered when a transfer has failed due to - various reasons. If we were unable to start the call - transfer (i.e. send the REFER), the status parameter - is empty, otherwise it contains information about the - failure. - * status - contains extra information about the success or - failure of the call. - -1.6.2. E_CALL_HOLD - - Triggered during the process of putting a call on hold, or - resuming a call from an on hold state. - - This event is triggered twice per each leg of the call - first - when the leg starts to be put on hold, and then when the leg - accepts or rejects the state. - - Parameters: - * callid - the callid of the call that is being put on hold, - or resumed. - * leg - the leg (caller or callee) affected by the call on - hold, or resumed. - * action - hold or unhold action that is being performed. - * state - the state of the action that is being performed. - + start - triggered when the re-INVITE is being sent out - to the participant being put on hold. - + ok - triggered when the on hold/resume action is - successfully completed. - + fail - triggered when the action failed. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 46 23 2273 163 - 2. Vlad Patrascu (@rvlad-patrascu) 5 1 123 66 - 3. Maksym Sobolyev (@sobomax) 4 2 4 5 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 2 1 - 5. Liviu Chircu (@liviuchircu) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2020 - Mar 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2023 - Apr 2023 - 3. Vlad Patrascu (@rvlad-patrascu) Mar 2023 - Mar 2023 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Liviu Chircu (@liviuchircu) Jan 2021 - Jan 2021 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2020 www.opensips-solutions.com diff --git a/modules/callops/README.md b/modules/callops/README.md new file mode 100644 index 00000000000..e2d3ad84d8c --- /dev/null +++ b/modules/callops/README.md @@ -0,0 +1,498 @@ +--- +title: "Calling Operations Module" +description: "This module provides a set of functions that allow the user to control ongoing calls." +--- + +## Admin Guide + + +### Overview + + +This module provides a set of functions that allow the user to control +ongoing calls. It can be used to trigger a call (either blind or attended) +transfer, or put a call on hold from the proxy side, rather than the +end-device side. +The module binds on top of the [OpenSIPS Dialog +module](../dialog) to get information about the ongoing calls, as well as +storing information about new calls that will be started. + + +The module also triggers a set of events over Event Interface, providing +to external applications details about how calls are being transferred, and +how they link between them. These events can be used to track down all the +legs involved in a call transfer. + + +One of the biggest challenge when doing Call Transfer scenarios is linking +new calls to the old calls being transferred, especially in blind call +transfer scenarios. In order to solve this challenge, the module can be +configured to refer old legs in two different modes, changeable using the +[mode](#param_mode) parameter: + + +- Automatically (default mode), by adding a special parameter to the +destination URI that is being sent in the REFER. When the new call +comes back, the parameter will be present in the Request URI of the +new call. The module will find it, link the new call to the old call, +and remove the parameter from the URI. +- Manually, by using custom/external logic (such as a database, or +local storage), to match the old call. In this mode, the user has to +explicitly call the [call blind replace](#func_call_blind_replace) +function to link the two calls together. + + +The module can also be used to catch *Notify refer* events +and reply to them from the OpenSIPS level. However, note that in *auto* mode even if the NOTIFY is handled when the dialog is matched, +the request will still continue its execution of the script, unlike when +*manual* mode is used with the +[call transfer notify](#func_call_transfer_notify) function. In order to avoid sending +the NOTIFY to the end-point, you have to drop it, like below: + + +```opensips title="Drop automatically handled NOTIFY refer events" +... +if (has_totag() && loose_route() && + is_method("NOTIFY") && $hdr(Event) == "refer") + drop; +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM* - Transaction module. +- *Dialog* - Dialog module for keeping track of the proxied calls. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### mode (string/integer) + + +This parameter can be used to change the mode that the module +uses to match a transferred leg. Supported values are: + + +- *param* / *0* - when +doing a blind transfer, the destination sent in the +refer message will contain a parameter used to identify +the dialog that is being replaced. this parameter will be +automatically removed when the new call is received. +- *manual* / *1* - the user +will create its own logic to match the new calls, and will +call the [call blind replace](#func_call_blind_replace) function +to make OpenSIPS aware of the pair. Note that this mode does +not handle automatically the *Notify refer* +either, so you also have to use the +[call transfer notify](#func_call_transfer_notify) function to handle +them. +- *callid* / *2* - similar +to the *param* value, except that instead +of storing in the Request URI the dialog id of the call to +be transfered, the actual callid is used as identifier. + + +*Default value is "0 (auto mode using parameters)".* + + +```opensips title="Set mode parameter" +... +modparam("callops", "mode", "manual") # use your own logic +... +``` + + +#### match_param (string) + + +The parameter used to match the different calls together. This is +mainly using in the *param* mode, but it is also +used internally to store different values inside the transferred +dialog - make sure it does not overlap with existing dialog values. + + +*Default value is "osid".* + + +```opensips title="Set match_param parameter" +... +modparam("callops", "match_param", "call") +... +``` + + +### Exported Functions + + +#### call_blind_replace(callid[, leg]) + + +When *manual mode* is used, this function is +called to create a mapping between the transferring call and the +transferred call. It should be called when OpenSIPS receives a +new call that is transferring an existing call. + + +Parameters: + + +- *callid* (string) - the existing call that +is being transferred. +- *leg* (string, optional) - the leg that is +being transferred. If not specified, and OpenSIPS cannot +determine the leg based on its destination, the +*unknown* tag should be used. + + +This function can be used only from a request route. + + +```opensips title="Use call_blind_replace() function to match an existing leg." +... +if (!has_totag() && is_method("INVITE")) { + if (cache_fetch("local", "callid_$si", $avp(callid))) { + call_blind_replace($avp(callid)); + } +} +... + +``` + + +#### call_transfer_notify() + + +When *manual mode* is used, this function should +be called on in-dialog NOTIFY requests for an *Event: refer* +header, to handle them accordingly. + + +Note that if the function successfully handles the NOTIFY request, +the script no longer continues its execution. + + +This function can be used from a request route, failure route and local route. + + +```opensips title="Use call_transfer_notify() function to handle NOTIFY refer requests." +... +if (has_totag() && is_method("NOTIFY") && loose_route()) { + call_transfer_notify(); +} +... + +``` + + +#### call_transfer(leg, destination) or + + +This function triggers a blind call transfer by sending a REFER +message during an ongoing call. The function needs to be run inside +the context of the dialog you are transferring. + + +Parameters: + + +- *leg* (string) - the leg that is +being transferred. Must be one of the *caller* +or *callee* values. +- *destination* (string) - SIP URI of the destination +where the leg is being transferred. + + +This function can be used from any route that has a dialog context. + + +```opensips title="Use call_transfer() function to do a blind transfer of the caller to a new destination." +... +if (has_totag() && && loose_route()) { + call_transfer("caller", "sip:announcement@127.0.0.1"); +} +... + +``` + + +#### call_transfer(leg, transfer_callid, transfer_leg[, destination]) or + + +This function triggers an attended call transfer by sending a REFER +message during an ongoing call. The function needs to be run inside +the context of the dialog you are transferring. + + +Parameters: + + +- *leg* (string) - the leg that is +being transferred. Must be one of the *caller* +or *callee* values. +- *transfer_callid* (string) - the callid of the +second dialog that is being transferred. +- *transfer_leg* (string) - the leg within the +second call that will be transferred to *leg*. +Must be one of the *caller* or +*callee* values. +- *destination* (string, optional) - SIP URI of the +destination where the leg is being transferred. If missing, the +From/To URI of the initial call are used. + + +This function can be used from any route that has a dialog context. + + +```opensips title="Use call_transfer() function to do an attended transfer of the caller to the callee of a different call." +... +if (has_totag() && && loose_route()) { + call_transfer("caller", "ba55b1b3-459d-4e84-a6f8-14c40e4f6ace", "callee"); +} +... + +``` + + +### Exported MI Functions + + +#### call_transfer + + +MI command to transfer an ongoing call to a new destination. + + +Depending on the parameters used, this command can do both +blind and attended transfers scenarios. When the +*transfer_callid* is used, then an attended +transfer is performed, other wise a blind transfer is issued. + + +Name: *call_transfer* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that is being transferred. +- *leg* (string) - indicates the +leg of the *callid* call that is being +transferred/kept in the new transferring call. +Possible values are "caller", +"callee" or "both". +- *destination* (string, optional) - the URI +where the call is being transferred. This parameter is +mandatory for blind transfers, and optional for attended +transfers. In the case of an attended transfer, if it is +missing, the destination of the call is taken from the +URIs in the transfer dialog. +- *transfer_callid* (string, optional) - +mandatory in case of an attended transfer, to specify the +call of the Bleg in the new call. +- *transfer_leg* (string, optional) - +in case of an attended transfer, it specifies the participant +of the *transfer_callid* call that will be +bridged with the *leg* of the +*callid*. If missing, +*transfer_fromtag* and +*transfer_totag* must be used to identify +the tag. +- *transfer_fromtag* and +*transfer_totag* (string, optional) - +these parameters should always be specified together, and are +used in call attended transfer scenarios where the dialog of the +Bleg that is being transferred is not managed by OpenSIPS. +Note that for these scenarios only the A-leg dialog will +receive events about the call transfer. + + +MI FIFO Command Format: + + +```bash +# blind transfer to sip:agent@127.0.0.1 +opensips-cli -x mi call_transfer \ + callid=4b664b48-5639-40bf-bff8-3a866c145c3b \ + leg=caller \ + destination=sip:agent@217.0.0.1 + +``` + + +```bash +# attended transfer between two calls +opensips-cli -x mi call_transfer \ + callid=e8d024db-78e5-4d18-9794-5b8ba837bed4 + leg=caller \ + transfer_callid=559abf97-9834-4380-bba1-a036eb245450 \ + transfer_leg=calee + +``` + + +#### call_hold + + +MI command to put an ongoing call on hold. + + +Command returns *OK* if any of the legs +of the call have been put on hold. If the call is already +on hold, an error is returned. + + +Name: *call_hold* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that is being put on hold. + + +MI FIFO Command Format: + + +```bash +# put a call on hold +opensips-cli -x mi call_hold \ + callid=921b00e4-fec0-4a36-9397-a40ab74e1893 + +``` + + +#### call_unhold + + +MI command to resume a call from an onhold state put by the +[mi call hold](#mi_call_hold) call. + + +Command returns *OK* if any of the legs +are resumed, or an error if no leg had been previously put +on hold. + + +Name: *call_unhold* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that is being resumed. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi call_unhold \ + callid=921b00e4-fec0-4a36-9397-a40ab74e1893 + +``` + + +### Exported Events + + +#### E_CALL_TRANSFER + + +This event is triggered during a call transfer scenario. + + +For a specific call transfer, multiple events are triggered, +starting when the transfer is initiated, until the transfer +is completed. The *state* parameter indicates +the state of the call transfer. + + +For a blind transfer scenario, only one set of events are +triggered, whereas for attended transfer, you will get a set +of events for both dialogs involved in the transfer, as long +as both are proxied through OpenSIPS + + +Parameters: + + +- *callid* - the callid of the call +that is being transferred. +- *leg* - the leg (*caller* or *callee*) of the call +that is being transferred. +- *transfer_callid* - the callid of the +new call that is transferring the old *callid* call. +- *destination* - the URI destination +where the *leg* is being transferred. +- *state* - the state of the transfer: + * *start* - triggered when the + REFER message is being sent out to the transferred participant. + * *notify* - triggered when + a NOTIFY refer event is received from the transferred participant. + The *status* parameter contains extra + information about the status of the transferring call. + * *ok* - triggered when + the transfer is completed - the call is answered by + the transferred participant. + * *fail* - triggered when + a transfer has failed due to various reasons. If we were + unable to start the call transfer (i.e. send the REFER), + the *status* parameter is empty, + otherwise it contains information about the failure. +- *status* - contains extra information about +the success or failure of the call. + + +#### E_CALL_HOLD + + +Triggered during the process of putting a call on hold, or resuming +a call from an on hold state. + + +This event is triggered twice per each leg of the call - first when +the leg starts to be put on hold, and then when the leg accepts or +rejects the state. + + +Parameters: + + +- *callid* - the callid of the call +that is being put on hold, or resumed. +- *leg* - the leg (*caller* or *callee*) affected +by the call on hold, or resumed. +- *action* - *hold* or +*unhold* action that is being performed. +- *state* - the state of the action that +is being performed. + * *start* - triggered when the re-INVITE is being sent out to the participant being put on hold. + * *ok* - triggered when the on hold/resume action is successfully completed. + * *fail* - triggered when the action failed. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/callops/doc/callops.xml b/modules/callops/doc/callops.xml deleted file mode 100644 index 5b0b52ebe8d..00000000000 --- a/modules/callops/doc/callops.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Calling Operations Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2020 &osipssol; - diff --git a/modules/callops/doc/callops_admin.xml b/modules/callops/doc/callops_admin.xml deleted file mode 100644 index 78d122f0844..00000000000 --- a/modules/callops/doc/callops_admin.xml +++ /dev/null @@ -1,616 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a set of functions that allow the user to control - ongoing calls. It can be used to trigger a call (either blind or attended) - transfer, or put a call on hold from the proxy side, rather than the - end-device side. - The module binds on top of the &osips; Dialog - module to get information about the ongoing calls, as well as - storing information about new calls that will be started. - - - The module also triggers a set of events over Event Interface, providing - to external applications details about how calls are being transferred, and - how they link between them. These events can be used to track down all the - legs involved in a call transfer. - - - One of the biggest challenge when doing Call Transfer scenarios is linking - new calls to the old calls being transferred, especially in blind call - transfer scenarios. In order to solve this challenge, the module can be - configured to refer old legs in two different modes, changeable using the - parameter: - - - - Automatically (default mode), by adding a special parameter to the - destination URI that is being sent in the REFER. When the new call - comes back, the parameter will be present in the Request URI of the - new call. The module will find it, link the new call to the old call, - and remove the parameter from the URI. - - - - - Manually, by using custom/external logic (such as a database, or - local storage), to match the old call. In this mode, the user has to - explicitly call the - function to link the two calls together. - - - - - - The module can also be used to catch Notify refer events - and reply to them from the &osips; level. However, note that in - auto mode even if the NOTIFY is handled when the dialog is matched, - the request will still continue its execution of the script, unlike when - manual mode is used with the - function. In order to avoid sending - the NOTIFY to the end-point, you have to drop it, like below: - - Drop automatically handled NOTIFY refer events - -... -if (has_totag() && loose_route() && - is_method("NOTIFY") && $hdr(Event) == "refer") - drop; -... - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction module. - - - - - Dialog - Dialog module for keeping track of the proxied calls. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>mode</varname> (string/integer) - - This parameter can be used to change the mode that the module - uses to match a transferred leg. Supported values are: - - - - param / 0 - when - doing a blind transfer, the destination sent in the - refer message will contain a parameter used to identify - the dialog that is being replaced. this parameter will be - automatically removed when the new call is received. - - - - - manual / 1 - the user - will create its own logic to match the new calls, and will - call the function - to make &osips; aware of the pair. Note that this mode does - not handle automatically the Notify refer - either, so you also have to use the - function to handle - them. - - - - - callid / 2 - similar - to the param value, except that instead - of storing in the Request URI the dialog id of the call to - be transfered, the actual callid is used as identifier. - - - - - - - Default value is 0 (auto mode using parameters). - - - - Set <varname>mode</varname> parameter - -... -modparam("callops", "mode", "manual") # use your own logic -... - - -
-
- <varname>match_param</varname> (string) - - The parameter used to match the different calls together. This is - mainly using in the param mode, but it is also - used internally to store different values inside the transferred - dialog - make sure it does not overlap with existing dialog values. - - - - Default value is osid. - - - - Set <varname>match_param</varname> parameter - -... -modparam("callops", "match_param", "call") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">call_blind_replace(callid[, leg])</function> - - - When manual mode is used, this function is - called to create a mapping between the transferring call and the - transferred call. It should be called when &osips; receives a - new call that is transferring an existing call. - - - Parameters: - - - callid (string) - the existing call that - is being transferred. - - - leg (string, optional) - the leg that is - being transferred. If not specified, and &osips; cannot - determine the leg based on its destination, the - unknown tag should be used. - - - - - This function can be used only from a request route. - - - Use <function>call_blind_replace()</function> function to match - an existing leg. - -... -if (!has_totag() && is_method("INVITE")) { - if (cache_fetch("local", "callid_$si", $avp(callid))) { - call_blind_replace($avp(callid)); - } -} -... - - -
-
- - <function moreinfo="none">call_transfer_notify()</function> - - - When manual mode is used, this function should - be called on in-dialog NOTIFY requests for an Event: refer - header, to handle them accordingly. - - - Note that if the function successfully handles the NOTIFY request, - the script no longer continues its execution. - - - This function can be used from a request route, failure route and local route. - - - Use <function>call_transfer_notify()</function> function to handle - NOTIFY refer requests. - -... -if (has_totag() && is_method("NOTIFY") && loose_route()) { - call_transfer_notify(); -} -... - - -
-
- - <function moreinfo="none">call_transfer(leg, destination)</function> or - - - This function triggers a blind call transfer by sending a REFER - message during an ongoing call. The function needs to be run inside - the context of the dialog you are transferring. - - - Parameters: - - - leg (string) - the leg that is - being transferred. Must be one of the caller - or callee values. - - - destination (string) - SIP URI of the destination - where the leg is being transferred. - - - - - This function can be used from any route that has a dialog context. - - - Use <function>call_transfer()</function> function to do a blind - transfer of the caller to a new destination. - -... -if (has_totag() && && loose_route()) { - call_transfer("caller", "sip:announcement@127.0.0.1"); -} -... - - -
-
- - <function moreinfo="none">call_transfer(leg, transfer_callid, transfer_leg[, destination])</function> or - - - This function triggers an attended call transfer by sending a REFER - message during an ongoing call. The function needs to be run inside - the context of the dialog you are transferring. - - - Parameters: - - - leg (string) - the leg that is - being transferred. Must be one of the caller - or callee values. - - - transfer_callid (string) - the callid of the - second dialog that is being transferred. - - - transfer_leg (string) - the leg within the - second call that will be transferred to leg. - Must be one of the caller or - callee values. - - - destination (string, optional) - SIP URI of the - destination where the leg is being transferred. If missing, the - From/To URI of the initial call are used. - - - - - This function can be used from any route that has a dialog context. - - - Use <function>call_transfer()</function> function to do an - attended transfer of the caller to the callee of a different call. - -... -if (has_totag() && && loose_route()) { - call_transfer("caller", "ba55b1b3-459d-4e84-a6f8-14c40e4f6ace", "callee"); -} -... - - -
-
- -
- Exported MI Functions - -
- - <function moreinfo="none">call_transfer</function> - - - MI command to transfer an ongoing call to a new destination. - - - Depending on the parameters used, this command can do both - blind and attended transfers scenarios. When the - transfer_callid is used, then an attended - transfer is performed, other wise a blind transfer is issued. - - - Name: call_transfer - - Parameters - - - callid (string) - the callid of the - dialog that is being transferred. - - - leg (string) - indicates the - leg of the callid call that is being - transferred/kept in the new transferring call. - Possible values are caller, - callee or both. - - - destination (string, optional) - the URI - where the call is being transferred. This parameter is - mandatory for blind transfers, and optional for attended - transfers. In the case of an attended transfer, if it is - missing, the destination of the call is taken from the - URIs in the transfer dialog. - - - transfer_callid (string, optional) - - mandatory in case of an attended transfer, to specify the - call of the Bleg in the new call. - - - transfer_leg (string, optional) - - in case of an attended transfer, it specifies the participant - of the transfer_callid call that will be - bridged with the leg of the - callid. If missing, - transfer_fromtag and - transfer_totag must be used to identify - the tag. - - - transfer_fromtag and - transfer_totag (string, optional) - - these parameters should always be specified together, and are - used in call attended transfer scenarios where the dialog of the - Bleg that is being transferred is not managed by &osips;. - Note that for these scenarios only the A-leg dialog will - receive events about the call transfer. - - - - MI FIFO Command Format: - - -# blind transfer to sip:agent@127.0.0.1 -opensips-cli -x mi call_transfer \ - callid=4b664b48-5639-40bf-bff8-3a866c145c3b \ - leg=caller \ - destination=sip:agent@217.0.0.1 - - -# attended transfer between two calls -opensips-cli -x mi call_transfer \ - callid=e8d024db-78e5-4d18-9794-5b8ba837bed4 - leg=caller \ - transfer_callid=559abf97-9834-4380-bba1-a036eb245450 \ - transfer_leg=calee - -
- -
- - <function moreinfo="none">call_hold</function> - - - MI command to put an ongoing call on hold. - - - Command returns OK if any of the legs - of the call have been put on hold. If the call is already - on hold, an error is returned. - - - Name: call_hold - - Parameters - - - callid (string) - the callid of the - dialog that is being put on hold. - - - - MI FIFO Command Format: - - -# put a call on hold -opensips-cli -x mi call_hold \ - callid=921b00e4-fec0-4a36-9397-a40ab74e1893 - -
- -
- - <function moreinfo="none">call_unhold</function> - - - MI command to resume a call from an onhold state put by the - call. - - - Command returns OK if any of the legs - are resumed, or an error if no leg had been previously put - on hold. - - - Name: call_unhold - - Parameters - - - callid (string) - the callid of the - dialog that is being resumed. - - - - MI FIFO Command Format: - - -opensips-cli -x mi call_unhold \ - callid=921b00e4-fec0-4a36-9397-a40ab74e1893 - -
-
- -
- Exported Events -
- - <function moreinfo="none">E_CALL_TRANSFER</function> - - - This event is triggered during a call transfer scenario. - - - For a specific call transfer, multiple events are triggered, - starting when the transfer is initiated, until the transfer - is completed. The state parameter indicates - the state of the call transfer. - - - For a blind transfer scenario, only one set of events are - triggered, whereas for attended transfer, you will get a set - of events for both dialogs involved in the transfer, as long - as both are proxied through &osips; - - Parameters: - - - callid - the callid of the call - that is being transferred. - - - leg - the leg (caller - or callee) of the call - that is being transferred. - - - transfer_callid - the callid of the - new call that is transferring the old callid - call. - - - destination - the URI destination - where the leg is being transferred. - - - state - the state of the transfer: - - start - triggered when the - REFER message is being sent out to the transferred participant. - - notify - triggered when - a NOTIFY refer event is received from the transferred participant. - The status parameter contains extra - information about the status of the transferring call. - - ok - triggered when - the transfer is completed - the call is answered by - the transferred participant. - - fail - triggered when - a transfer has failed due to various reasons. If we were - unable to start the call transfer (i.e. send the REFER), - the status parameter is empty, - otherwise it contains information about the failure. - - - - - status - contains extra information about - the success or failure of the call. - - -
-
- - <function moreinfo="none">E_CALL_HOLD</function> - - - Triggered during the process of putting a call on hold, or resuming - a call from an on hold state. - - - This event is triggered twice per each leg of the call - first when - the leg starts to be put on hold, and then when the leg accepts or - rejects the state. - - Parameters: - - - callid - the callid of the call - that is being put on hold, or resumed. - - - leg - the leg (caller - or callee) affected - by the call on hold, or resumed. - - - action - hold or - unhold action that is being performed. - - - state - the state of the action that - is being performed. - - start - triggered when the - re-INVITE is being sent out to the participant being put on hold. - - ok - triggered when - the on hold/resume action is successfully completed. - - fail - triggered when - the action failed. - - - - -
-
- -
diff --git a/modules/callops/doc/contributors.xml b/modules/callops/doc/contributors.xml deleted file mode 100644 index e83f7c0aeae..00000000000 --- a/modules/callops/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 46 - 23 - 2273 - 163 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 5 - 1 - 123 - 66 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 5 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 2 - 1 - - - 5. - Liviu Chircu (@liviuchircu) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2020 - Mar 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2023 - Apr 2023 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - Mar 2023 - Mar 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Liviu Chircu (@liviuchircu) - Jan 2021 - Jan 2021 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/carrierroute/README b/modules/carrierroute/README deleted file mode 100644 index 073f30a0a20..00000000000 --- a/modules/carrierroute/README +++ /dev/null @@ -1,1292 +0,0 @@ -carrierroute - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. id_column (string) - 1.3.4. carrier_column (string) - 1.3.5. scan_prefix_column (string) - 1.3.6. domain_column (string) - 1.3.7. flags_column (string) - 1.3.8. mask_column (string) - 1.3.9. prob_column (string) - 1.3.10. rewrite_host_column (string) - 1.3.11. strip_column (string) - 1.3.12. comment_column (string) - 1.3.13. carrier_table (string) - 1.3.14. rewrite_prefix_column (string) - 1.3.15. rewrite_suffix_column (string) - 1.3.16. carrier_id_col (string) - 1.3.17. carrier_name_col (string) - 1.3.18. subscriber_table (string) - 1.3.19. subscriber_user_col (string) - 1.3.20. subscriber_domain_col (string) - 1.3.21. subscriber_carrier_col (string) - 1.3.22. config_source (string) - 1.3.23. config_file (string) - 1.3.24. default_tree (string) - 1.3.25. use_domain (int) - 1.3.26. fallback_default (int) - 1.3.27. db_failure_table (string) - 1.3.28. failure_id_column (string) - 1.3.29. failure_carrier_column (string) - 1.3.30. failure_scan_prefix_column (string) - 1.3.31. failure_domain_column (string) - 1.3.32. failure_host_name_column (string) - 1.3.33. failure_reply_code_column (string) - 1.3.34. failure_flags_column (string) - 1.3.35. failure_mask_column (string) - 1.3.36. failure_next_domain_column (string) - 1.3.37. failure_comment_column (string) - - 1.4. Exported Functions - - 1.4.1. cr_user_carrier(user, domain, dst_avp) - 1.4.2. cr_route(carrier, domain, prefix_matching, - rewrite_user, hash_source, [dst_avp]) - - 1.4.3. cr_prime_route(carrier, domain, - prefix_matching, rewrite_user, hash_source, - [dst_avp]) - - 1.4.4. cr_next_domain(carrier, domain, - prefix_matching, host, reply_code, dst_avp) - - 1.5. Exported MI Functions - - 1.5.1. cr_reload_routes - 1.5.2. cr_dump_routes - 1.5.3. cr_replace_host - 1.5.4. cr_deactivate_host - 1.5.5. cr_activate_host - 1.5.6. cr_add_host - 1.5.7. cr_delete_host - - 1.6. Examples - 1.7. Installation and Running - - 1.7.1. Database setup - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set db_table parameter - 1.3. Set id_column parameter - 1.4. Set carrier_column parameter - 1.5. Set scan_prefix_column parameter - 1.6. Set domain_column parameter - 1.7. Set flags_column parameter - 1.8. Set mask_column parameter - 1.9. Set prob_column parameter - 1.10. Set rewrite_host_column parameter - 1.11. Set strip_column parameter - 1.12. Set comment_column parameter - 1.13. Set carrier_table parameter - 1.14. Set rewrite_prefix_column parameter - 1.15. Set rewrite_suffix_column parameter - 1.16. Set id_col parameter - 1.17. Set carrier_name_col parameter - 1.18. Set subscriber_table parameter - 1.19. Set subscriber_user_col parameter - 1.20. Set subscriber_domain_col parameter - 1.21. Set subscriber_carrier_col parameter - 1.22. Set config_source parameter - 1.23. Set config_file parameter - 1.24. Set default_tree parameter - 1.25. Set use_domain parameter - 1.26. Set fallback_default parameter - 1.27. Set db_failure_table parameter - 1.28. Set failure_id_column parameter - 1.29. Set failure_carrier_column parameter - 1.30. Set failure_scan_prefix_column parameter - 1.31. Set failure_domain_column parameter - 1.32. Set failure_host_name_column parameter - 1.33. Set failure_reply_code_column parameter - 1.34. Set failure_flags_column parameter - 1.35. Set failure_mask_column parameter - 1.36. Set failure_next_domain_column parameter - 1.37. Set failure_comment_column parameter - 1.38. cr_replace_host usage - 1.39. cr_deactivate_host usage - 1.40. cr_activate_host usage - 1.41. cr_add_host usage - 1.42. cr_delete_host usage - 1.43. Configuration example - Routing to default tree - 1.44. Configuration example - Routing to user tree - 1.45. Configuration example - module configuration - 1.46. Example database content - carrierroute table - 1.47. Example database content - simple carrierfailureroute - table - - 1.48. Example database content - more complex - carrierfailureroute table - - 1.49. Example database content - route_tree table - 1.50. Necessary extensions for the user table - -Chapter 1. Admin Guide - -1.1. Overview - - A module which provides routing, balancing and blacklisting - capabilities. - - The module provides routing, balancing and blacklisting - capabilities. It reads routing entries from a database source - or from a config file at OpenSIPS startup. It can uses one - routing tree (for one carrier), or if needed for every user a - different routing tree (unique for each carrier) for number - prefix based routing. It supports several route tree domains, - e.g. for failback routes or different routing rules for VoIP - and PSTN targets. - - Based on the tree, the module decides which number prefixes are - forwarded to which gateway. It can also distribute the traffic - by ratio parameters. Furthermore, the requests can be - distributed by a hash funcion to predictable destinations. The - hash source is configurable, two different hash functions are - available. - - This modules scales up to more than a few million users, and is - able to handle more than several hundred thousand routing table - entries. It should be able to handle more, but this is not that - much tested at the moment. In load balancing scenarios the - usage of the config file mode is recommended, to avoid the - additional complexity that the database driven routing creates. - - Routing tables can be reloaded and edited (in config file mode) - with the MI interface, the config file is updated according the - changes. This is not implemented for the db interface, because - its easier to do the changes directly on the db. But the reload - and dump functions works of course here too. - - Some module functionality is not fully available in the config - file mode, as it is not possible to specify all information - that can be stored in the database tables in the config file. - Further information about these limitations is given in later - sections. For user based routing or LCR you should use the - database mode. - - Basically this module could be used as an replacement for the - lcr and the dispatcher module, if you have certain performance, - flexibility and/or integration requirements that these modules - don't handle properly. But for small installations it probably - make more sense to use the lcr and dispatcher module. - - If you want to use this module in failure routes, then you need - to call “append_branch()” after rewriting the request URI in - order to relay the message to the new target. Its also - supportes the usage of database derived failure routing - descisions with the carrierfailureroute table. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following module must be loaded before this module: - * a database module, when a database is used as configuration - data source. Only SQL based databases are supported, as - this module needs the capability to issue raw queries. Its - not possible to use the dbtext or db_berkeley module at the - moment. - * The tm module, when you want to use the $T_reply_code - pseudo-variable in the “cr_next_domain” function. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libconfuse, a configuration file parser library. ( - http://www.nongnu.org/confuse/ ) - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Url to the database containing the routing data. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("carrierroute", "db_url", "dbdriver://username:password@dbhost/ -dbname") -... - -1.3.2. db_table (string) - - Name of the table where the routing data is stored. - - Default value is “carrierroute”. - - Example 1.2. Set db_table parameter -... -modparam("carrierroute", "db_table", "carrierroute") -... - -1.3.3. id_column (string) - - Name of the column containing the id identifier. - - Default value is “id”. - - Example 1.3. Set id_column parameter -... -modparam("carrierroute", "id_column", "id") -... - -1.3.4. carrier_column (string) - - Name of the column containing the carrier id. - - Default value is “carrier”. - - Example 1.4. Set carrier_column parameter -... -modparam("carrierroute", "carrier_column", "carrier") -... - -1.3.5. scan_prefix_column (string) - - Name of column containing the scan prefixes. Scan prefixes - define the matching portion of a phone number, e.g. when we - have the scan prefixes 49721 and 49, the called number is - 49721913740, it matches 49721, because the longest match is - taken. If no prefix matches, the number is not routed. To - prevent this, an empty prefix value of “” could be added. - - Default value is “scan_prefix”. - - Example 1.5. Set scan_prefix_column parameter -... -modparam("carrierroute", "scan_prefix_column", "scan_prefix") -... - -1.3.6. domain_column (string) - - Name of column containing the rule domain. You can define - several routing domains to have different routing rules. Maybe - you use domain 0 for normal routing and domain 1 if domain 0 - failed. - - Default value is “domain”. - - Example 1.6. Set domain_column parameter -... -modparam("carrierroute", "domain_column", "domain") -... - -1.3.7. flags_column (string) - - Name of the column containing the flags. - - Default value is “flags”. - - Example 1.7. Set flags_column parameter -... -modparam("carrierroute", "flags_column", "flags") -... - -1.3.8. mask_column (string) - - Name of the column containing the flags mask. - - Default value is “mask”. - - Example 1.8. Set mask_column parameter -... -modparam("carrierroute", "mask_column", "mask") -... - -1.3.9. prob_column (string) - - Name of column containing probability. The probability value is - used to distribute the traffic between several gateways. Let's - say 70 % of the traffic shall be routed to gateway A, the other - 30 % shall be routed to gateway B, we define a rule for gateway - A with a prob value of 0.7 and a rule for gateway B with a prob - value of 0.3. - - If all probabilities for a given prefix, tree and domain don't - add to 100%, the prefix values will be adjusted according the - given prob values. E.g. if three hosts with prob values of 0.5, - 0.5 and 0.4 are defined, the resulting probabilities are - 35.714, 35.714 and 28.571%. But its better to choose meaningful - values in the first place because of clarity. - - Default value is “prob”. - - Example 1.9. Set prob_column parameter -... -modparam("carrierroute", "prob_column", "prob") -... - -1.3.10. rewrite_host_column (string) - - Name of column containing rewrite host value. An empty field - represents a blacklist entry, anything else is put as domain - part into the Request URI of the SIP message. - - Default value is “rewrite_host”. - - Example 1.10. Set rewrite_host_column parameter -... -modparam("carrierroute", "rewrite_host_column", "rewrite_host") -... - -1.3.11. strip_column (string) - - Name of the column containing the number of digits to be - stripped of the userpart of an URI before prepending - rewrite_prefix. - - Default value is “strip”. - - Example 1.11. Set strip_column parameter -... -modparam("carrierroute", "strip_column", "strip") -... - -1.3.12. comment_column (string) - - Name of the column containing an optional comment (useful in - large routing tables) The comment is also displayed by the fifo - cmd "cr_dump_routes". - - Default value is “description”. - - Example 1.12. Set comment_column parameter -... -modparam("carrierroute", "comment_column", "description") -... - -1.3.13. carrier_table (string) - - The name of the table containing the existing carriers, - consisting of the ids and corresponding names. - - Default value is “route_tree”. - - Example 1.13. Set carrier_table parameter -... -modparam("carrierroute", "carrier_table", "route_tree") -... - -1.3.14. rewrite_prefix_column (string) - - Name of column containing rewrite prefixes. Here you can define - a rewrite prefix for the localpart of the SIP URI. - - Default value is “rewrite_prefix”. - - Example 1.14. Set rewrite_prefix_column parameter -... -modparam("carrierroute", "rewrite_prefix_column", "rewrite_prefix") -... - -1.3.15. rewrite_suffix_column (string) - - Name of column containing rewrite suffixes. Here you can define - a rewrite suffix for the localpart of the SIP URI. - - Default value is “rewrite_suffix”. - - Example 1.15. Set rewrite_suffix_column parameter - ... -modparam("carrierroute", "rewrite_suffix_column", "rewrite_suffix") - ... - -1.3.16. carrier_id_col (string) - - The name of the column in the carrier table containing the - carrier id. - - Default value is “id”. - - Example 1.16. Set id_col parameter -... -modparam("carrierroute", "carrier_id_col", "id") -... - -1.3.17. carrier_name_col (string) - - The name of the column in the carrier table containing the - carrier name. - - Default value is “carrier”. - - Example 1.17. Set carrier_name_col parameter -... -modparam("carrierroute", "carrier_name_col", "carrier") -... - -1.3.18. subscriber_table (string) - - The name of the table containing the subscribers - - Default value is “subscriber”. - - Example 1.18. Set subscriber_table parameter -... -modparam("carrierroute", "subscriber_table", "subscriber") -... - -1.3.19. subscriber_user_col (string) - - The name of the column in the subscriber table containing the - usernames. - - Default value is “username”. - - Example 1.19. Set subscriber_user_col parameter -... -modparam("carrierroute", "subscriber_user_col", "username") -... - -1.3.20. subscriber_domain_col (string) - - The name of the column in the subscriber table containing the - domain of the subscriber. - - Default value is “domain”. - - Example 1.20. Set subscriber_domain_col parameter -... -modparam("carrierroute", "subscriber_domain_col", "domain") -... - -1.3.21. subscriber_carrier_col (string) - - The name of the column in the subscriber table containing the - carrier id of the subscriber. - - Default value is “cr_preferred_carrier”. - - Example 1.21. Set subscriber_carrier_col parameter -... -modparam("carrierroute", "subscriber_carrier_col", "cr_preferred_carrier -") -... - -1.3.22. config_source (string) - - Specifies whether the module loads its config data from a file - or from a database. Possible values are file or db. - - Default value is “file”. - - Example 1.22. Set config_source parameter -... -modparam("carrierroute", "config_source", "file") -... - -1.3.23. config_file (string) - - Specifies the path to the config file. - - Default value is “/etc/opensips/carrierroute.conf”. - - Example 1.23. Set config_file parameter -... -modparam("carrierroute", "config_file", "/etc/opensips/carrierroute.conf -") -... - -1.3.24. default_tree (string) - - The name of the carrier tree used per default (if the current - subscriber has no preferred tree) - - Default value is “default”. - - Example 1.24. Set default_tree parameter -... -modparam("carrierroute", "default_tree", "default") -... - -1.3.25. use_domain (int) - - When using tree lookup per user, this parameter specifies - whether to use the domain part for user matching or not. - - Default value is “0”. - - Example 1.25. Set use_domain parameter -... -modparam("carrierroute", "use_domain", 0) -... - -1.3.26. fallback_default (int) - - This parameter defines the behaviour when using user-based tree - lookup. If the user has a non-existing tree set and - fallback_default is set to 1, the default tree is used. - Otherwise, cr_user_rewrite_uri returns an error. - - Default value is “1”. - - Example 1.26. Set fallback_default parameter -... -modparam("carrierroute", "fallback_default", 1) -... - -1.3.27. db_failure_table (string) - - Name of the table where the failure routing data is stored. - - Default value is “carrierfailureroute”. - - Example 1.27. Set db_failure_table parameter -... -modparam("carrierroute", "db_failure_table", "carrierfailureroute") -... - -1.3.28. failure_id_column (string) - - Name of the column containing the id identifier. - - Default value is “id”. - - Example 1.28. Set failure_id_column parameter -... -modparam("carrierroute", "failure_id_column", "id") -... - -1.3.29. failure_carrier_column (string) - - Name of the column containing the carrier id. - - Default value is “carrier”. - - Example 1.29. Set failure_carrier_column parameter -... -modparam("carrierroute", "failure_carrier_column", "carrier") -... - -1.3.30. failure_scan_prefix_column (string) - - Name of column containing the scan prefixes. Scan prexies - define the matching portion of a phone number, e.g. we have the - scan prefixes 49721 and 49, the called number is 49721913740, - it matches 49721, because the longest match is taken. If no - prefix matches, the number is not failure routed. To prevent - this, an empty prefix value of “” could be added. - - Default value is “scan_prefix”. - - Example 1.30. Set failure_scan_prefix_column parameter -... -modparam("carrierroute", "failure_scan_prefix_column", "scan_prefix") -... - -1.3.31. failure_domain_column (string) - - Name of column containing the rule domain. You can define - several routing domains to have different routing rules. Maybe - you use domain 0 for normal routing and domain 1 if domain 0 - failed. - - Default value is “domain”. - - Example 1.31. Set failure_domain_column parameter -... -modparam("carrierroute", "failure_domain_column", "domain") -... - -1.3.32. failure_host_name_column (string) - - Name of the column containing the host name of the last routing - destination. - - Default value is “host_name”. - - Example 1.32. Set failure_host_name_column parameter -... -modparam("carrierroute", "failure_host_name_column", "host_name") -... - -1.3.33. failure_reply_code_column (string) - - Name of the column containing the reply code. - - Default value is “reply_code”. - - Example 1.33. Set failure_reply_code_column parameter -... -modparam("carrierroute", "failure_reply_code_column", "reply_code") -... - -1.3.34. failure_flags_column (string) - - Name of the column containing the flags. - - Default value is “flags”. - - Example 1.34. Set failure_flags_column parameter -... -modparam("carrierroute", "failure_flags_column", "flags") -... - -1.3.35. failure_mask_column (string) - - Name of the column containing the flags mask. - - Default value is “mask”. - - Example 1.35. Set failure_mask_column parameter -... -modparam("carrierroute", "failure_mask_column", "mask") -... - -1.3.36. failure_next_domain_column (string) - - Name of the column containing the next routing domain. - - Default value is “next_domain”. - - Example 1.36. Set failure_next_domain_column parameter -... -modparam("carrierroute", "failure_next_domain_column", "next_domain") -... - -1.3.37. failure_comment_column (string) - - Name of the column containing an optional comment. - - Default value is “description”. - - Example 1.37. Set failure_comment_column parameter -... -modparam("carrierroute", "failure_comment_column", "description") -... - -1.4. Exported Functions - - Previous versions of carrierroute had some more function. All - the old semantics can be achieved by using the few new - functions like this: -cr_rewrite_uri(domain, hash_source) --> cr_route("default", domain, $rU, $rU, hash_source) - -cr_prime_balance_uri(domain, hash_source) --> cr_prime_route("default", domain, $rU, $rU, hash_source) - -cr_rewrite_by_to(domain, hash_source) --> cr_route("default", domain, $tU, $rU, hash_source) - -cr_prime_balance_by_to(domain, hash_source) --> cr_prime_route("default", domain, $tU, $rU, hash_source) - -cr_rewrite_by_from(domain, hash_source) --> cr_route("default", domain, $fU, $rU, hash_source) - -cr_prime_balance_by_from(domain, hash_source) --> cr_prime_route("default", domain, $fU, $rU, hash_source) - -cr_user_rewrite_uri(uri, domain) --> cr_user_carrier(user, domain, $avp(tree_avp)) --> cr_route($avp(tree_avp), domain, $rU, $rU, "call_id") - -cr_tree_rewrite_uri(tree, domain) --> cr_route(tree, domain, $rU, $rU, "call_id") - -1.4.1. cr_user_carrier(user, domain, dst_avp) - - This function loads the carrier and stores it in an AVP. It - cannot be used in the config file mode, as it needs a mapping - of the given user to a certain carrier. The is derived from a - database entry belonging to the user parameter. This mapping - must be available in the table that is specified in the - “subscriber_table” variable. This data is not cached in memory, - that means for every execution of this function a database - query will be done. - - Parameters: - * user (string) - Name of the user for the carrier tree - lookup - * domain (string) - Name of the routing domain to be used - * dst_avp (var) - Name of an AVP where to store the carrier - id - -1.4.2. cr_route(carrier, domain, prefix_matching, rewrite_user, -hash_source, [dst_avp]) - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier - tree. The Request URI is rewritten using rewrite_user and the - given hash source and algorithm. Returns -1 if there is no data - found or an empty rewrite host on the longest match is found. - Otherwise the rewritten host is stored in the given AVP (if - obmitted, the host is not stored in an AVP). This function is - only usable with rewrite_user and prefix_matching containing a - valid numerical only string. It uses the standard crc32 - algorithm to calculate the hash values. - - Parameters: - * carrier (string) - The routing tree to be used - * domain (string) - Name of the routing domain to be used - * prefix_matching (string) - User name to be used for prefix - matching in the routing tree - * rewrite_user (string) - The user name to be used for - applying the rewriting rule. Usually, this is the user part - of the request URI - * hash_source (string) - The hash values of the destination - set must be a contiguous range starting at 1, limited by - the configuration parameter max_targets. Possible values - for hash_source are: call_id, from_uri, from_user, to_uri - and to_user. - * dst_avp (var, optional) - Optional AVP where to store the - rewritten host - -1.4.3. cr_prime_route(carrier, domain, prefix_matching, -rewrite_user, hash_source, [dst_avp]) - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier - tree. The Request URI is rewritten using rewrite_user and the - given hash source and algorithm. Returns -1 if there is no data - found or an empty rewrite host on the longest match is found. - Otherwise the rewritten host is stored in the given AVP (if - obmitted, the host is not stored in an AVP). This function is - only usable with rewrite_user and prefix_matching containing a - valid numerical only string. It uses the prime hash algorithm - to calculate the hash values. - - Meaning of the parameters is as follows: - * carrier (string) - The routing tree to be used - * domain (string) - Name of the routing domain to be used - * prefix_matching (string) - User name to be used for prefix - matching in the routing tree - * rewrite_user (string) - The user name to be used for - applying the rewriting rule. Usually, this is the user part - of the request URI - * hash_source (string) - The hash values of the destination - set must be a contiguous range starting at 1, limited by - the configuration parameter max_targets. Possible values - for hash_source are: call_id, from_uri, from_user, to_uri - and to_user. - * dst_avp (var, optional) - Optional AVP where to store the - rewritten host - -1.4.4. cr_next_domain(carrier, domain, prefix_matching, host, -reply_code, dst_avp) - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier - failure tree. It tries to find a next domain matching the given - host, reply_code and the message flags. The matching is done in - this order: host, reply_code and then flags. The more wildcards - in reply_code and the more bits used in flags, the lower the - priority. Returns -1 if there is no data found or an empty - next_domain on the longest match is found. Otherwise the next - domain is stored in the given AVP. This function is only usable - with prefix_matching containing a valid numerical only string. - - Meaning of the parameters is as follows: - * carrier (string) - The routing tree to be used any - pseudo-variable could be used as input. - * domain (string) - Name of the routing domain to be used - * prefix_matching (string) - User name to be used for prefix - matching in the routing tree - * host (string) - The host name to be used for failure route - rule matching. Usually, this is the last tried routing - destination stored in an avp by cr_route - * reply_code (string) - The reply code to be used for failure - route rule matching - * dst_avp (var) - AVP where to store the next routing domain. - -1.5. Exported MI Functions - - All commands understand the "-?" parameter to print a short - help message. The options have to be quoted as one string to be - passed to MI interface. Each option except host and new host - can be wildcarded by * (but only * and not things like "-d - prox*"). - -1.5.1. cr_reload_routes - - This command reloads the routing data from the data source. - - Important: When new domains have been added, a restart of the - server must be done, because the mapping of the ids used in the - config script cannot be updated at runtime at the moment. So a - reload could result in a wrong routing behaviour, because the - ids used in the script could differ from the one used - internally from the server. Modifying of already existing - domains is no problem. - -1.5.2. cr_dump_routes - - This command prints the route rules on the command line. - -1.5.3. cr_replace_host - - This command can replace the rewrite_host of a route rule, it - is only usable in file mode. Following options are possible: - * -d - the domain containing the host - * -p - the prefix containing the host - * -h - the host to be replaced - * -t - the new host - - Use the "null" prefix to specify an empty prefix. - - Example 1.38. cr_replace_host usage -... -opensips-cli -x mi cr_replace_host "-d proxy -p 49 -h proxy1 -t proxy2" -... - -1.5.4. cr_deactivate_host - - This command deactivates the specified host, i.e. it sets its - status to 0. It is only usable in file mode. Following options - are possible: - * -d - the domain containing the host - * -p - the prefix containing the host - * -h - the host to be deactivated - * -t - the new host used as backup - - When -t (new_host) is specified, the portion of traffic for the - deactivated host is routed to the host given by -t. This is - indicated in the output of dump_routes. The backup route is - deactivated if the host is activated again. - - Use the "null" prefix to specify an empty prefix. - - Example 1.39. cr_deactivate_host usage -... -opensips-cli -x mi cr_deactivate_host "-d proxy -p 49 -h proxy1" -... - -1.5.5. cr_activate_host - - This command activates the specified host, i.e. it sets its - status to 1. It is only usable in file mode. Following options - are possible: - * -d - the domain containing the host - * -p - the prefix containing the host - * -h - the host to be activated - - Use the "null" prefix to specify an empty prefix. - - Example 1.40. cr_activate_host usage -... -opensips-cli -x mi cr_activate_host "-d proxy -p 49 -h proxy1" -... - -1.5.6. cr_add_host - - This command adds a route rule, it is only usable in file mode. - Following options are possible: - * -d - the domain containing the host - * -p - the prefix containing the host - * -h - the host to be added - * -w - the weight of the rule - * -P - an optional rewrite prefix - * -S - an optional rewrite suffix - * -i - an optional hash index - * -s - an optional strip value - - Use the "null" prefix to specify an empty prefix. - - Example 1.41. cr_add_host usage -... -opensips-cli -x mi cr_add_host "-d proxy -p 49 -h proxy1 -w 0.25" -... - -1.5.7. cr_delete_host - - This command delete the specified hosts or rules, i.e. remove - them from the route tree. It is only usable in file mode. - Following options are possible: - * -d - the domain containing the host - * -p - the prefix containing the host - * -h - the host to be added - * -w - the weight of the rule - * -P - an optional rewrite prefix - * -S - an optional rewrite suffix - * -i - an optional hash index - * -s - an optional strip value - - Use the "null" prefix to specify an empty prefix. - - Example 1.42. cr_delete_host usage -... -opensips-cli -x mi cr_delete_host "-d proxy -p 49 -h proxy1 -w 0.25" -... - -1.6. Examples - - Example 1.43. Configuration example - Routing to default tree -... -route { - # route calls based on hash over callid - # choose route domain 0 of the default carrier - - if(!cr_route("default", "0", "$rU", "$rU", "call_id", "crc32")){ - sl_send_reply(403, "Not allowed"); - } else { - # In case of failure, re-route the request - t_on_failure("1"); - # Relay the request to the gateway - t_relay(); - } -} - -failure_route[1] { - # In case of failure, send it to an alternative route: - if (t_check_status("408|5[0-9][0-9]")) { - #choose route domain 1 of the default carrier - if(!cr_route("default", "1", "$rU", "$rU", "call_id", "crc32")){ - t_reply(403, "Not allowed"); - } else { - t_on_failure("2"); - t_relay(); - } - } -} - -failure_route[2] { - # further processing -} - - - Example 1.44. Configuration example - Routing to user tree -... -route[1] { - cr_user_carrier("$fU", "$fd", "$avp(carrier)"); - - # just an example domain - $avp(domain)="start"; - if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", - "call_id", "$avp(host)")) { - xlog("L_ERR", "cr_route failed\n"); - exit; - } - t_on_failure("1"); - if (!t_relay()) { - sl_reply_error(); - }; -} - -failure_route[1] { - revert_uri(); - if (!cr_next_domain("$avp(carrier)", "$avp(domain)", "$rU", - "$avp(host)", "$T_reply_code", "$avp(domain)")) -{ - xlog("L_ERR", "cr_next_domain failed\n"); - exit; - } - if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", - "call_id", "$avp(host)")) { - xlog("L_ERR", "cr_route failed\n"); - exit; - } - t_on_failure("1"); - append_branch(); - if (!t_relay()) { - xlog("L_ERR", "t_relay failed\n"); - exit; - }; -} -... - - Example 1.45. Configuration example - module configuration - - The following config file specifies within the default carrier - two domains, each with an prefix that contains two hosts. It is - not possible to specify another carrier if you use the config - file as data source. - - All traffic will be equally distributed between the hosts, both - are active. The hash algorithm will working over the [1,2] set, - messages hashed to one will go to the first host, the other to - the second one. Don't use a hash index value of zero. If you - ommit the hash completly, the module gives them a autogenerated - value, starting from one. - - Use the “NULL” prefix to specify an empty prefix in the config - file. Please note that the prefix is matched against the - request URI (or to URI), if they did not contain a valid - numerical URI, no match is possible. So for loadbalancing - purposes e.g. for your registrars, you should use an empty - prefix. -... -domain proxy { - prefix 49 { - max_targets = 2 - target proxy1.localdomain { - prob = 0.500000 - hash_index = 1 - status = 1 - comment = "test target 1" - } - target proxy2.localdomain { - prob = 0.500000 - hash_index = 2 - status = 1 - comment = "test target 2" - } - } -} - -domain register { - prefix NULL { - max_targets = 2 - target register1.localdomain { - prob = 0.500000 - hash_index = 1 - status = 1 - comment = "test target 1" - } - target register2.localdomain { - prob = 0.500000 - hash_index = 2 - status = 1 - comment = "test target 2" - } - } -} -... - -1.7. Installation and Running - -1.7.1. Database setup - - Before running OpenSIPS with carrierroute, you have to setup - the database table where the module will store the routing - data. For that, if the table was not created by the - installation script or you choose to install everything by - yourself you can use the carrierroute-create.sql SQL script in - the database directories in the opensips/scripts folder as - template. Database and table name can be set with module - parameters so they can be changed, but the name of the columns - must be as they are in the SQL script. You can also find the - complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. The flags - and mask columns have the same function as in the - carrierfailureroute table. A zero value in the flags and mask - column means that any message flags will match this rule. - - For a minimal configuration either use the config file given - above, or insert some data into the tables of the module. - - Example 1.46. Example database content - carrierroute table -... -+----+---------+--------+-------------+-------+------+---------------+ -| id | carrier | domain | scan_prefix | flags | prob | rewrite_host | -+----+---------+--------+-------------+-------+------+---------------+ -| 1 | 1 | 0 | 49 | 0 | 0.5 | de-1.carrier1 | -| 2 | 1 | 0 | 49 | 0 | 0.5 | de-2.carrier1 | -| 3 | 1 | 0 | 49 | 16 | 1 | de-3.carrier1 | -| 4 | 1 | 0 | | 0 | 1 | gw.carrier1-1 | -| 5 | 1 | 1 | 49 | 0 | 1 | gw.carrier1-1 | -| 6 | 1 | 2 | | 0 | 1 | gw.carrier1-2 | -| 7 | 1 | 3 | | 0 | 1 | gw.carrier1-3 | -| 8 | 2 | 0 | 49 | 0 | 0.5 | de-1.carrier2 | -| 9 | 2 | 0 | 49 | 0 | 0.5 | de-2.carrier2 | -| 10 | 2 | 0 | | 0 | 1 | gw.carrier2 | -| 11 | 2 | 1 | 49 | 0 | 1 | gw.carrier2 | -| 12 | 3 | start | 49 | 0 | 1 | de-gw.default | -| 13 | 3 | start | | 0 | 1 | gw.default | -+----+---------+--------+-------------+-------+------+---------------+ -... - - This table contains three routes to two gateways for the “49” - prefix, and a default route for other prefixes over carrier 2 - and carrier 1. The gateways for the default carrier will be - used for functions that don't support the user specific carrier - lookup. The routing rules for carrier 1 and carrier 2 for the - “49” prefix contains a additional rule with the domain 1, that - can be used for example as fallback if the gateways in domain 0 - are not reachable. Two more fallback rules (domain 2 and 3) for - carrier 1 are also supplied to support the functionality of the - carrierfailureroute table example that is provided in the next - section. The usage of strings for the domains is also possible, - for example at carrier 3. - - This table provides also a “carrier1” routing rule for the “49” - prefix, that is only choosen if some message flags are set. If - this flags are not set, the other two rules are used. The - “strip”, “mask” and “comment” colums are omitted for brevity. - - Example 1.47. Example database content - simple - carrierfailureroute table -... -+----+---------+--------+---------------+------------+-------------+ -| id | carrier | domain | host_name | reply_code | next_domain | -+----+---------+--------+---------------+------------+-------------+ -| 1 | 1 | 0 | gw.carrier1-2 | ... | 3 | -| 2 | 1 | 0 | gw.carrier1-3 | ... | 2 | -+----+---------+--------+---------------+------------+-------------+ -... - - This table contains two failure routes for the “gw.carrier1-1” - and “-2” gateways. For any (failure) reply code the respective - next domain is choosen. After that no more failure routes are - available, an error will be returned from the “cr_next_domain” - function. Not all table colums are show here for brevity. - - For each failure route domain and carrier that is added to the - carrierfailureroute table there must be at least one - corresponding entry in the carrierroute table, otherwise the - module will not load the routing data. - - Example 1.48. Example database content - more complex - carrierfailureroute table -... -+----+---------+-----------+------------+--------+-----+-------------+ -| id | domain | host_name | reply_code | flags | mask | next_domain | -+----+---------+-----------+------------+-------+------+-------------+ -| 1 | 99 | | 408 | 16 | 16 | | -| 2 | 99 | gw1 | 404 | 0 | 0 | 100 | -| 3 | 99 | gw2 | 50. | 0 | 0 | 100 | -| 4 | 99 | | 404 | 2048 | 2112 | asterisk-1 | -+----+---------+-----------+------------+-------+------+-------------+ -... - - This table contains four failure routes that shows the usage of - more advanced features. The first route matches to a 408, and - to some flag for example that indicates that ringing has - happened. If this flag is set, there will be no further - forwarding, because next_domain is empty. In the second and - third routes are certain gateway errors matched, if this errors - have occurred, then the next domain will be chosen. The last - route does forwarding according some flags, e.g. the customer - came from a certain carrier, and has call-forwarding - deactivated. In order to use the routing that is specified - above, a matching carrierroute table must be provided, that - holds domain entries for this routing rules. Not all table - colums are show here for brevity. - - Example 1.49. Example database content - route_tree table -... -+----+----------+ -| id | carrier | -+----+----------+ -| 1 | carrier1 | -| 2 | carrier2 | -| 3 | default | -+----+----------+ -... - - This table contains the mapping of the carrier id to actual - names. - - For a functional routing the “cr_preferred_carrier” column must - be added to the subscriber table (or to the table and column - that you specified as modul parameter) to choose the actual - carrier for the users. - - Example 1.50. Necessary extensions for the user table - - Suggested changes: -... -ALTER TABLE subscriber ADD cr_preferred_carrier int(10) default NULL; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Henning Westerholt (@henningw) 125 80 2085 1607 - 2. Jonas Appel 54 1 6240 0 - 3. Hardy Kahl 49 3 2713 1360 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 29 24 131 154 - 5. Razvan Crainea (@razvancrainea) 23 20 109 108 - 6. Vlad Patrascu (@rvlad-patrascu) 22 5 384 764 - 7. Liviu Chircu (@liviuchircu) 19 13 134 210 - 8. Daniel-Constantin Mierla (@miconda) 9 7 34 30 - 9. Alexandra Titoc 5 3 13 2 - 10. Maksym Sobolyev (@sobomax) 4 2 5 5 - - All remaining contributors: Carsten Bock, Bob Atkins, Julián - Moreno Patiño, Ovidiu Sas (@ovidiusas), Sergio Gutierrez, Iouri - Kharon, UnixDev, Zero King (@l2dy), ihsinme, Ken Rice, Peter - Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Edson Gellert - Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 5. ihsinme Feb 2022 - Feb 2022 - 6. Razvan Crainea (@razvancrainea) Jun 2011 - Jan 2021 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2019 - 9. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2007 - Apr 2019 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Julián Moreno Patiño, Walter Doekes - (@wdoekes), Ovidiu Sas (@ovidiusas), UnixDev, Henning - Westerholt (@henningw), Sergio Gutierrez, Iouri Kharon, Hardy - Kahl, Daniel-Constantin Mierla (@miconda), Edson Gellert - Schubert, Bob Atkins, Carsten Bock, Jonas Appel. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Julián Moreno - Patiño, Bogdan-Andrei Iancu (@bogdan-iancu), Henning Westerholt - (@henningw), Iouri Kharon, Hardy Kahl, Daniel-Constantin Mierla - (@miconda), Edson Gellert Schubert, Carsten Bock, Jonas Appel. - - Documentation Copyrights: - - Copyright © 2007 1&1 Internet AG diff --git a/modules/carrierroute/README.md b/modules/carrierroute/README.md new file mode 100644 index 00000000000..1278d8541f6 --- /dev/null +++ b/modules/carrierroute/README.md @@ -0,0 +1,1386 @@ +--- +title: "carrierroute" +description: "A module which provides routing, balancing and blacklisting capabilities." +--- + +## Admin Guide + + +### Overview + + +A module which provides routing, balancing and blacklisting capabilities. + + +The module provides routing, balancing and blacklisting capabilities. +It reads routing entries from a database source or from a config file at OpenSIPS +startup. It can uses one routing tree (for one carrier), or if needed for every user +a different routing tree (unique for each carrier) for number prefix based routing. +It supports several route tree domains, e.g. for failback routes or different routing +rules for VoIP and PSTN targets. + + +Based on the tree, the module decides which number prefixes are forwarded to which +gateway. It can also distribute the traffic by ratio parameters. Furthermore, the +requests can be distributed by a hash funcion to predictable destinations. The hash +source is configurable, two different hash functions are available. + + +This modules scales up to more than a few million users, and is able to handle +more than several hundred thousand routing table entries. It should be able to handle +more, but this is not that much tested at the moment. In load balancing scenarios the +usage of the config file mode is recommended, to avoid the additional complexity that +the database driven routing creates. + + +Routing tables can be reloaded and edited (in config file mode) with the MI +interface, the config file is updated according the changes. This is not +implemented for the db interface, because its easier to do the changes +directly on the db. But the reload and dump functions works of course here +too. + + +Some module functionality is not fully available in the config file mode, as +it is not possible to specify all information that can be stored in the database +tables in the config file. Further information about these limitations is given +in later sections. For user based routing or LCR you should use the database mode. + + +Basically this module could be used as an replacement for the lcr and the +dispatcher module, if you have certain performance, flexibility and/or +integration requirements that these modules don't handle properly. But for +small installations it probably make more sense to use the lcr and dispatcher +module. + + +If you want to use this module in failure routes, then you need to call +"append_branch()" after rewriting the request URI in order to +relay the message to the new target. Its also supportes the usage of database +derived failure routing descisions with the carrierfailureroute table. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following module must be loaded before this module: + + +- *a database module*, when a database is used as configuration data source. +Only SQL based databases are supported, as this module needs the capability to +issue raw queries. Its not possible to use the dbtext or db_berkeley module at the moment. +- The *tm module*, when you want to use the $T_reply_code pseudo-variable in +the "cr_next_domain" function. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libconfuse*, a configuration file parser library. +( http://www.nongnu.org/confuse/ ) + + +### Exported Parameters + + +#### db_url (string) + + +Url to the database containing the routing data. + + +*Default value is "mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("carrierroute", "db_url", "dbdriver://username:password@dbhost/dbname") +... + +``` + + +#### db_table (string) + + +Name of the table where the routing data is stored. + + +*Default value is "carrierroute".* + + +```opensips title="Set db_table parameter" +... +modparam("carrierroute", "db_table", "carrierroute") +... + +``` + + +#### id_column (string) + + +Name of the column containing the id identifier. + + +*Default value is "id".* + + +```opensips title="Set id_column parameter" +... +modparam("carrierroute", "id_column", "id") +... + +``` + + +#### carrier_column (string) + + +Name of the column containing the carrier id. + + +*Default value is "carrier".* + + +```opensips title="Set carrier_column parameter" +... +modparam("carrierroute", "carrier_column", "carrier") +... + +``` + + +#### scan_prefix_column (string) + + +Name of column containing the scan prefixes. Scan prefixes define +the matching portion of a phone number, e.g. when we have the scan +prefixes 49721 and 49, the called number is 49721913740, it matches +49721, because the longest match is taken. If no prefix matches, +the number is not routed. To prevent this, an empty prefix value +of "" could be added. + + +*Default value is "scan_prefix".* + + +```opensips title="Set scan_prefix_column parameter" +... +modparam("carrierroute", "scan_prefix_column", "scan_prefix") +... + +``` + + +#### domain_column (string) + + +Name of column containing the rule domain. You can define several routing +domains to have different routing rules. Maybe you use domain 0 for normal +routing and domain 1 if domain 0 failed. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("carrierroute", "domain_column", "domain") +... + +``` + + +#### flags_column (string) + + +Name of the column containing the flags. + + +*Default value is "flags".* + + +```opensips title="Set flags_column parameter" +... +modparam("carrierroute", "flags_column", "flags") +... + +``` + + +#### mask_column (string) + + +Name of the column containing the flags mask. + + +*Default value is "mask".* + + +```opensips title="Set mask_column parameter" +... +modparam("carrierroute", "mask_column", "mask") +... + +``` + + +#### prob_column (string) + + +Name of column containing probability. The probability value is used to +distribute the traffic between several gateways. Let's say 70 % of the +traffic shall be routed to gateway A, the other 30 % shall be routed to +gateway B, we define a rule for gateway A with a prob value of 0.7 and a +rule for gateway B with a prob value of 0.3. + + +If all probabilities for a given prefix, tree and domain don't add to 100%, +the prefix values will be adjusted according the given prob values. E.g. if +three hosts with prob values of 0.5, 0.5 and 0.4 are defined, the resulting +probabilities are 35.714, 35.714 and 28.571%. But its better to choose meaningful +values in the first place because of clarity. + + +*Default value is "prob".* + + +```opensips title="Set prob_column parameter" +... +modparam("carrierroute", "prob_column", "prob") +... + +``` + + +#### rewrite_host_column (string) + + +Name of column containing rewrite host value. An empty field represents a +blacklist entry, anything else is put as domain part into the Request URI +of the SIP message. + + +*Default value is "rewrite_host".* + + +```opensips title="Set rewrite_host_column parameter" +... +modparam("carrierroute", "rewrite_host_column", "rewrite_host") +... + +``` + + +#### strip_column (string) + + +Name of the column containing the number of digits to be stripped of the +userpart of an URI before prepending rewrite_prefix. + + +*Default value is "strip".* + + +```opensips title="Set strip_column parameter" +... +modparam("carrierroute", "strip_column", "strip") +... + +``` + + +#### comment_column (string) + + +Name of the column containing an optional comment (useful in large routing tables) +The comment is also displayed by the fifo cmd "cr_dump_routes". + + +*Default value is "description".* + + +```opensips title="Set comment_column parameter" +... +modparam("carrierroute", "comment_column", "description") +... + +``` + + +#### carrier_table (string) + + +The name of the table containing the existing carriers, consisting +of the ids and corresponding names. + + +*Default value is "route_tree".* + + +```opensips title="Set carrier_table parameter" +... +modparam("carrierroute", "carrier_table", "route_tree") +... + +``` + + +#### rewrite_prefix_column (string) + + +Name of column containing rewrite prefixes. Here you can define a rewrite +prefix for the localpart of the SIP URI. + + +*Default value is "rewrite_prefix".* + + +```opensips title="Set rewrite_prefix_column parameter" +... +modparam("carrierroute", "rewrite_prefix_column", "rewrite_prefix") +... + +``` + + +#### rewrite_suffix_column (string) + + +Name of column containing rewrite suffixes. Here you can define a rewrite +suffix for the localpart of the SIP URI. + + +*Default value is "rewrite_suffix".* + + +```opensips title="Set rewrite_suffix_column parameter" +... +modparam("carrierroute", "rewrite_suffix_column", "rewrite_suffix") +... + +``` + + +#### carrier_id_col (string) + + +The name of the column in the carrier table containing the carrier id. + + +*Default value is "id".* + + +```opensips title="Set id_col parameter" +... +modparam("carrierroute", "carrier_id_col", "id") +... + +``` + + +#### carrier_name_col (string) + + +The name of the column in the carrier table containing the carrier name. + + +*Default value is "carrier".* + + +```opensips title="Set carrier_name_col parameter" +... +modparam("carrierroute", "carrier_name_col", "carrier") +... + +``` + + +#### subscriber_table (string) + + +The name of the table containing the subscribers + + +*Default value is "subscriber".* + + +```opensips title="Set subscriber_table parameter" +... +modparam("carrierroute", "subscriber_table", "subscriber") +... + +``` + + +#### subscriber_user_col (string) + + +The name of the column in the subscriber table containing the usernames. + + +*Default value is "username".* + + +```opensips title="Set subscriber_user_col parameter" +... +modparam("carrierroute", "subscriber_user_col", "username") +... + +``` + + +#### subscriber_domain_col (string) + + +The name of the column in the subscriber table containing the domain of +the subscriber. + + +*Default value is "domain".* + + +```opensips title="Set subscriber_domain_col parameter" +... +modparam("carrierroute", "subscriber_domain_col", "domain") +... + +``` + + +#### subscriber_carrier_col (string) + + +The name of the column in the subscriber table containing the carrier id +of the subscriber. + + +*Default value is "cr_preferred_carrier".* + + +```opensips title="Set subscriber_carrier_col parameter" +... +modparam("carrierroute", "subscriber_carrier_col", "cr_preferred_carrier") +... + +``` + + +#### config_source (string) + + +Specifies whether the module loads its config data from a file or from a +database. Possible values are file or db. + + +*Default value is "file".* + + +```opensips title="Set config_source parameter" +... +modparam("carrierroute", "config_source", "file") +... + +``` + + +#### config_file (string) + + +Specifies the path to the config file. + + +*Default value is "/etc/opensips/carrierroute.conf".* + + +```opensips title="Set config_file parameter" +... +modparam("carrierroute", "config_file", "/etc/opensips/carrierroute.conf") +... + +``` + + +#### default_tree (string) + + +The name of the carrier tree used per default (if the current +subscriber has no preferred tree) + + +*Default value is "default".* + + +```opensips title="Set default_tree parameter" +... +modparam("carrierroute", "default_tree", "default") +... + +``` + + +#### use_domain (int) + + +When using tree lookup per user, this parameter specifies whether +to use the domain part for user matching or not. + + +*Default value is "0".* + + +```opensips title="Set use_domain parameter" +... +modparam("carrierroute", "use_domain", 0) +... + +``` + + +#### fallback_default (int) + + +This parameter defines the behaviour when using user-based tree +lookup. If the user has a non-existing tree set and fallback_default +is set to 1, the default tree is used. Otherwise, cr_user_rewrite_uri +returns an error. + + +*Default value is "1".* + + +```opensips title="Set fallback_default parameter" +... +modparam("carrierroute", "fallback_default", 1) +... + +``` + + +#### db_failure_table (string) + + +Name of the table where the failure routing data is stored. + + +*Default value is "carrierfailureroute".* + + +```opensips title="Set db_failure_table parameter" +... +modparam("carrierroute", "db_failure_table", "carrierfailureroute") +... + +``` + + +#### failure_id_column (string) + + +Name of the column containing the id identifier. + + +*Default value is "id".* + + +```opensips title="Set failure_id_column parameter" +... +modparam("carrierroute", "failure_id_column", "id") +... + +``` + + +#### failure_carrier_column (string) + + +Name of the column containing the carrier id. + + +*Default value is "carrier".* + + +```opensips title="Set failure_carrier_column parameter" +... +modparam("carrierroute", "failure_carrier_column", "carrier") +... + +``` + + +#### failure_scan_prefix_column (string) + + +Name of column containing the scan prefixes. Scan prexies +define the matching portion of a phone number, e.g. we have the +scan prefixes 49721 and 49, the called number is 49721913740, +it matches 49721, because the longest match is taken. If no +prefix matches, the number is not failure routed. To prevent +this, an empty prefix value of "" could be added. + + +*Default value is "scan_prefix".* + + +```opensips title="Set failure_scan_prefix_column parameter" +... +modparam("carrierroute", "failure_scan_prefix_column", "scan_prefix") +... + +``` + + +#### failure_domain_column (string) + + +Name of column containing the rule domain. You can define +several routing domains to have different routing rules. Maybe +you use domain 0 for normal routing and domain 1 if domain 0 +failed. + + +*Default value is "domain".* + + +```opensips title="Set failure_domain_column parameter" +... +modparam("carrierroute", "failure_domain_column", "domain") +... + +``` + + +#### failure_host_name_column (string) + + +Name of the column containing the host name of the last routing +destination. + + +*Default value is "host_name".* + + +```opensips title="Set failure_host_name_column parameter" +... +modparam("carrierroute", "failure_host_name_column", "host_name") +... + +``` + + +#### failure_reply_code_column (string) + + +Name of the column containing the reply code. + + +*Default value is "reply_code".* + + +```opensips title="Set failure_reply_code_column parameter" +... +modparam("carrierroute", "failure_reply_code_column", "reply_code") +... + +``` + + +#### failure_flags_column (string) + + +Name of the column containing the flags. + + +*Default value is "flags".* + + +```opensips title="Set failure_flags_column parameter" +... +modparam("carrierroute", "failure_flags_column", "flags") +... + +``` + + +#### failure_mask_column (string) + + +Name of the column containing the flags mask. + + +*Default value is "mask".* + + +```opensips title="Set failure_mask_column parameter" +... +modparam("carrierroute", "failure_mask_column", "mask") +... + +``` + + +#### failure_next_domain_column (string) + + +Name of the column containing the next routing domain. + + +*Default value is "next_domain".* + + +```opensips title="Set failure_next_domain_column parameter" +... +modparam("carrierroute", "failure_next_domain_column", "next_domain") +... + +``` + + +#### failure_comment_column (string) + + +Name of the column containing an optional comment. + + +*Default value is "description".* + + +```opensips title="Set failure_comment_column parameter" +... +modparam("carrierroute", "failure_comment_column", "description") +... + +``` + + +### Exported Functions + + +Previous versions of carrierroute had some more function. All the +old semantics can be achieved by using the few new functions +like this: + + +```opensips +cr_rewrite_uri(domain, hash_source) +-> cr_route("default", domain, $rU, $rU, hash_source) + +cr_prime_balance_uri(domain, hash_source) +-> cr_prime_route("default", domain, $rU, $rU, hash_source) + +cr_rewrite_by_to(domain, hash_source) +-> cr_route("default", domain, $tU, $rU, hash_source) + +cr_prime_balance_by_to(domain, hash_source) +-> cr_prime_route("default", domain, $tU, $rU, hash_source) + +cr_rewrite_by_from(domain, hash_source) +-> cr_route("default", domain, $fU, $rU, hash_source) + +cr_prime_balance_by_from(domain, hash_source) +-> cr_prime_route("default", domain, $fU, $rU, hash_source) + +cr_user_rewrite_uri(uri, domain) +-> cr_user_carrier(user, domain, $avp(tree_avp)) +-> cr_route($avp(tree_avp), domain, $rU, $rU, "call_id") + +cr_tree_rewrite_uri(tree, domain) +-> cr_route(tree, domain, $rU, $rU, "call_id") + +``` + + +#### cr_user_carrier(user, domain, dst_avp) + + +This function loads the carrier and stores it in an AVP. +It cannot be used in the config file mode, as it needs a mapping of the +given user to a certain carrier. The is derived from a database entry +belonging to the user parameter. This mapping must be available in the +table that is specified in the "subscriber_table" variable. +This data is not cached in memory, that means for every execution of this +function a database query will be done. + + +Parameters: + + +- *user (string)* - Name of the user for the +carrier tree lookup +- *domain (string)* - Name of the routing +domain to be used +- *dst_avp (var)* - Name of an AVP where to +store the carrier id + + +#### cr_route(carrier, domain, prefix_matching, rewrite_user, hash_source, [dst_avp]) + + +This function searches for the longest match for the user given +in prefix_matching at the given domain in the given carrier tree. +The Request URI is rewritten using rewrite_user and the given +hash source and algorithm. Returns -1 if there is no data found +or an empty rewrite host on the longest match is found. Otherwise +the rewritten host is stored in the given AVP (if obmitted, the +host is not stored in an AVP). +This function is only usable with rewrite_user and prefix_matching +containing a valid numerical only string. It uses the standard crc32 algorithm +to calculate the hash values. + + +Parameters: + + +- *carrier (string)* - The routing tree to +be used +- *domain (string)* - Name of the routing +domain to be used +- *prefix_matching (string)* - User name +to be used for prefix matching in the routing tree +- *rewrite_user (string)* - The user name +to be used for applying the rewriting rule. Usually, this is +the user part of the request URI +- *hash_source (string)* - The hash values +of the destination set must be a contiguous range starting at 1, +limited by the configuration parameter max_targets. Possible +values for hash_source are: call_id, from_uri, from_user, to_uri +and to_user. +- *dst_avp (var, optional)* - Optional AVP +where to store the rewritten host + + +#### cr_prime_route(carrier, domain, prefix_matching, rewrite_user, hash_source, [dst_avp]) + + +This function searches for the longest match for the user given +in prefix_matching at the given domain in the given carrier tree. +The Request URI is rewritten using rewrite_user and the given +hash source and algorithm. Returns -1 if there is no data found +or an empty rewrite host on the longest match is found. Otherwise +the rewritten host is stored in the given AVP (if obmitted, the +host is not stored in an AVP). +This function is only usable with rewrite_user and prefix_matching +containing a valid numerical only string. It uses the prime hash algorithm +to calculate the hash values. + + +Meaning of the parameters is as follows: + + +- *carrier (string)* - The routing tree to +be used +- *domain (string)* - Name of the routing +domain to be used +- *prefix_matching (string)* - User name +to be used for prefix matching in the routing tree +- *rewrite_user (string)* - The user name +to be used for applying the rewriting rule. Usually, this is +the user part of the request URI +- *hash_source (string)* - The hash values +of the destination set must +be a contiguous range starting at 1, limited by the +configuration parameter max_targets. Possible values for +hash_source are: call_id, from_uri, from_user, to_uri +and to_user. +- *dst_avp (var, optional)* - Optional AVP +where to store the rewritten host + + +#### cr_next_domain(carrier, domain, prefix_matching, host, reply_code, dst_avp) + + +This function searches for the longest match for the user given +in prefix_matching at the given domain in the given carrier +failure tree. It tries to find a next domain matching the given +host, reply_code and the message flags. The matching is done in this order: +host, reply_code and then flags. The more wildcards in reply_code +and the more bits used in flags, the lower the priority. +Returns -1 if there is no data found or an empty next_domain on +the longest match is found. Otherwise the next domain is stored +in the given AVP. +This function is only usable with prefix_matching containing a +valid numerical only string. + + +Meaning of the parameters is as follows: + + +- *carrier (string)* - The routing tree to be used +any pseudo-variable could be used as input. +- *domain (string)* - Name of the routing domain to be used +- *prefix_matching (string)* - User name to be used for prefix matching +in the routing tree +- *host (string)* - The host name to be used for failure route rule +matching. Usually, this is the last tried routing destination +stored in an avp by cr_route +- *reply_code (string)* - The reply code to be used for failure route rule +matching +- *dst_avp (var)* - AVP where to store the next routing domain. + + +### Exported MI Functions + + +All commands understand the "-?" parameter to print a short help message. +The options have to be quoted as one string to be passed to MI interface. +Each option except host and new host can be wildcarded by * (but only * and not things +like "-d prox*"). + + +#### cr_reload_routes + + +This command reloads the routing data from the data source. + + +Important: When new domains have been added, a restart of the server must be +done, because the mapping of the ids used in the config script cannot be +updated at runtime at the moment. So a reload could result in a wrong routing +behaviour, because the ids used in the script could differ from the one used +internally from the server. Modifying of already existing domains is no problem. + + +#### cr_dump_routes + + +This command prints the route rules on the command line. + + +#### cr_replace_host + + +This command can replace the rewrite_host of a route rule, it is only +usable in file mode. Following options are possible: + + +- *-d* - the domain containing the host +- *-p* - the prefix containing the host +- *-h* - the host to be replaced +- *-t* - the new host + + +Use the "null" prefix to specify an empty prefix. + + +```bash title="cr_replace_host usage" +... +opensips-cli -x mi cr_replace_host "-d proxy -p 49 -h proxy1 -t proxy2" +... + +``` + + +#### cr_deactivate_host + + +This command deactivates the specified host, i.e. it sets its status to 0. +It is only usable in file mode. Following options are possible: + + +- *-d* - the domain containing the host +- *-p* - the prefix containing the host +- *-h* - the host to be deactivated +- *-t* - the new host used as backup + + +When -t (new_host) is specified, the portion of traffic for the deactivated host +is routed to the host given by -t. This is indicated in the output of dump_routes. +The backup route is deactivated if the host is activated again. + + +Use the "null" prefix to specify an empty prefix. + + +```bash title="cr_deactivate_host usage" +... +opensips-cli -x mi cr_deactivate_host "-d proxy -p 49 -h proxy1" +... + +``` + + +#### cr_activate_host + + +This command activates the specified host, i.e. it sets its status to 1. +It is only usable in file mode. Following options are possible: + + +- *-d* - the domain containing the host +- *-p* - the prefix containing the host +- *-h* - the host to be activated + + +Use the "null" prefix to specify an empty prefix. + + +```bash title="cr_activate_host usage" +... +opensips-cli -x mi cr_activate_host "-d proxy -p 49 -h proxy1" +... + +``` + + +#### cr_add_host + + +This command adds a route rule, it is only usable in file mode. Following options +are possible: + + +- *-d* - the domain containing the host +- *-p* - the prefix containing the host +- *-h* - the host to be added +- *-w* - the weight of the rule +- *-P* - an optional rewrite prefix +- *-S* - an optional rewrite suffix +- *-i* - an optional hash index +- *-s* - an optional strip value + + +Use the "null" prefix to specify an empty prefix. + + +```bash title="cr_add_host usage" +... +opensips-cli -x mi cr_add_host "-d proxy -p 49 -h proxy1 -w 0.25" +... + +``` + + +#### cr_delete_host + + +This command delete the specified hosts or rules, i.e. remove +them from the route tree. It is only usable in file mode. +Following options are possible: + + +- *-d* - the domain containing the host +- *-p* - the prefix containing the host +- *-h* - the host to be added +- *-w* - the weight of the rule +- *-P* - an optional rewrite prefix +- *-S* - an optional rewrite suffix +- *-i* - an optional hash index +- *-s* - an optional strip value + + +Use the "null" prefix to specify an empty prefix. + + +```bash title="cr_delete_host usage" +... +opensips-cli -x mi cr_delete_host "-d proxy -p 49 -h proxy1 -w 0.25" +... + +``` + + +### Examples + + +```opensips title="Configuration example - Routing to default tree" +... +route { + # route calls based on hash over callid + # choose route domain 0 of the default carrier + + if(!cr_route("default", "0", "$rU", "$rU", "call_id", "crc32")){ + sl_send_reply(403, "Not allowed"); + } else { + # In case of failure, re-route the request + t_on_failure("1"); + # Relay the request to the gateway + t_relay(); + } +} + +failure_route[1] { + # In case of failure, send it to an alternative route: + if (t_check_status("408|5[0-9][0-9]")) { + #choose route domain 1 of the default carrier + if(!cr_route("default", "1", "$rU", "$rU", "call_id", "crc32")){ + t_reply(403, "Not allowed"); + } else { + t_on_failure("2"); + t_relay(); + } + } +} + +failure_route[2] { + # further processing +} + + +``` + + +```opensips title="Configuration example - Routing to user tree" +... +route[1] { + cr_user_carrier("$fU", "$fd", "$avp(carrier)"); + + # just an example domain + $avp(domain)="start"; + if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", + "call_id", "$avp(host)")) { + xlog("L_ERR", "cr_route failed\n"); + exit; + } + t_on_failure("1"); + if (!t_relay()) { + sl_reply_error(); + }; +} + +failure_route[1] { + revert_uri(); + if (!cr_next_domain("$avp(carrier)", "$avp(domain)", "$rU", + "$avp(host)", "$T_reply_code", "$avp(domain)")) { + xlog("L_ERR", "cr_next_domain failed\n"); + exit; + } + if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", + "call_id", "$avp(host)")) { + xlog("L_ERR", "cr_route failed\n"); + exit; + } + t_on_failure("1"); + append_branch(); + if (!t_relay()) { + xlog("L_ERR", "t_relay failed\n"); + exit; + }; +} +... + +``` + + +The following config file specifies within the default carrier two +domains, each with an prefix that contains two hosts. It is not possible +to specify another carrier if you use the config file as data source. + + +All traffic will be equally distributed between the hosts, both are +active. The hash algorithm will working over the [1,2] set, messages +hashed to one will go to the first host, the other to the second one. +Don't use a hash index value of zero. If you ommit the hash completly, +the module gives them a autogenerated value, starting from one. + + +Use the "NULL" prefix to specify an empty prefix in the config file. +Please note that the prefix is matched against the request URI (or to URI), +if they did not contain a valid numerical URI, no match is possible. So +for loadbalancing purposes e.g. for your registrars, you should use an empty +prefix. + + +```c title="Configuration example - module configuration" +... +domain proxy { + prefix 49 { + max_targets = 2 + target proxy1.localdomain { + prob = 0.500000 + hash_index = 1 + status = 1 + comment = "test target 1" + } + target proxy2.localdomain { + prob = 0.500000 + hash_index = 2 + status = 1 + comment = "test target 2" + } + } +} + +domain register { + prefix NULL { + max_targets = 2 + target register1.localdomain { + prob = 0.500000 + hash_index = 1 + status = 1 + comment = "test target 1" + } + target register2.localdomain { + prob = 0.500000 + hash_index = 2 + status = 1 + comment = "test target 2" + } + } +} +... + +``` + + +### Installation and Running + + +#### Database setup + + +Before running OpenSIPS with carrierroute, you have to setup the database +table where the module will store the routing data. For that, if +the table was not created by the installation script or you choose +to install everything by yourself you can use the carrierroute-create.sql +SQL script in the database directories in the +opensips/scripts folder as template. +Database and table name can be set with module parameters so they +can be changed, but the name of the columns must be as they are +in the SQL script. +You can also find the complete database documentation on the +project webpage, https://opensips.org/docs/db/db-schema-devel.html. +The flags and mask columns have the same function as in the +carrierfailureroute table. A zero value in the flags and mask +column means that any message flags will match this rule. + + +For a minimal configuration either use the config file given above, or +insert some data into the tables of the module. + + +```c title="Example database content - carrierroute table" +... ++----+---------+--------+-------------+-------+------+---------------+ +| id | carrier | domain | scan_prefix | flags | prob | rewrite_host | ++----+---------+--------+-------------+-------+------+---------------+ +| 1 | 1 | 0 | 49 | 0 | 0.5 | de-1.carrier1 | +| 2 | 1 | 0 | 49 | 0 | 0.5 | de-2.carrier1 | +| 3 | 1 | 0 | 49 | 16 | 1 | de-3.carrier1 | +| 4 | 1 | 0 | | 0 | 1 | gw.carrier1-1 | +| 5 | 1 | 1 | 49 | 0 | 1 | gw.carrier1-1 | +| 6 | 1 | 2 | | 0 | 1 | gw.carrier1-2 | +| 7 | 1 | 3 | | 0 | 1 | gw.carrier1-3 | +| 8 | 2 | 0 | 49 | 0 | 0.5 | de-1.carrier2 | +| 9 | 2 | 0 | 49 | 0 | 0.5 | de-2.carrier2 | +| 10 | 2 | 0 | | 0 | 1 | gw.carrier2 | +| 11 | 2 | 1 | 49 | 0 | 1 | gw.carrier2 | +| 12 | 3 | start | 49 | 0 | 1 | de-gw.default | +| 13 | 3 | start | | 0 | 1 | gw.default | ++----+---------+--------+-------------+-------+------+---------------+ +... + +``` + + +This table contains three routes to two gateways for the "49" prefix, +and a default route for other prefixes over carrier 2 and carrier 1. The +gateways for the default carrier will be used for functions that don't +support the user specific carrier lookup. The routing rules for carrier 1 +and carrier 2 for the "49" prefix contains a additional rule +with the domain 1, that can be used for example as fallback if the gateways +in domain 0 are not reachable. Two more fallback rules (domain 2 and 3) for +carrier 1 are also supplied to support the functionality of the carrierfailureroute +table example that is provided in the next section. The usage of strings +for the domains is also possible, for example at carrier 3. + + +This table provides also a "carrier1" routing rule for the +"49" prefix, that is only choosen if some message flags are set. +If this flags are not set, the other two rules are used. The "strip", +"mask" and "comment" colums are omitted for brevity. + + +```c title="Example database content - simple carrierfailureroute table" +... ++----+---------+--------+---------------+------------+-------------+ +| id | carrier | domain | host_name | reply_code | next_domain | ++----+---------+--------+---------------+------------+-------------+ +| 1 | 1 | 0 | gw.carrier1-2 | ... | 3 | +| 2 | 1 | 0 | gw.carrier1-3 | ... | 2 | ++----+---------+--------+---------------+------------+-------------+ +... +``` + + +This table contains two failure routes for the "gw.carrier1-1" and +"-2" gateways. For any (failure) reply code the respective next +domain is choosen. After that no more failure routes are available, an error will +be returned from the "cr_next_domain" function. Not all table +colums are show here for brevity. + + +For each failure route domain and carrier that is added to the carrierfailureroute +table there must be at least one corresponding entry in the carrierroute table, +otherwise the module will not load the routing data. + + +```c title="Example database content - more complex carrierfailureroute table" +... ++----+---------+-----------+------------+--------+-----+-------------+ +| id | domain | host_name | reply_code | flags | mask | next_domain | ++----+---------+-----------+------------+-------+------+-------------+ +| 1 | 99 | | 408 | 16 | 16 | | +| 2 | 99 | gw1 | 404 | 0 | 0 | 100 | +| 3 | 99 | gw2 | 50. | 0 | 0 | 100 | +| 4 | 99 | | 404 | 2048 | 2112 | asterisk-1 | ++----+---------+-----------+------------+-------+------+-------------+ +... +``` + + +This table contains four failure routes that shows the usage of more +advanced features. The first route matches to a 408, and to some flag +for example that indicates that ringing has happened. If this flag is set, +there will be no further forwarding, because next_domain is empty. In the +second and third routes are certain gateway errors matched, if this errors +have occurred, then the next domain will be chosen. The last route does +forwarding according some flags, e.g. the customer came from a certain carrier, +and has call-forwarding deactivated. In order to use the routing that is +specified above, a matching carrierroute table must be provided, that holds +domain entries for this routing rules. Not all table colums are show here for +brevity. + + +```c title="Example database content - route_tree table" +... ++----+----------+ +| id | carrier | ++----+----------+ +| 1 | carrier1 | +| 2 | carrier2 | +| 3 | default | ++----+----------+ +... + +``` + + +This table contains the mapping of the carrier id to actual names. + + +For a functional routing the "cr_preferred_carrier" column must +be added to the subscriber table (or to the table and column that you specified +as modul parameter) to choose the actual carrier for the users. + + +Suggested changes: + + +```sql title="Necessary extensions for the user table" +... +ALTER TABLE subscriber ADD cr_preferred_carrier int(10) default NULL; +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/carrierroute/doc/carrierroute.xml b/modules/carrierroute/doc/carrierroute.xml deleted file mode 100644 index a1541c173f5..00000000000 --- a/modules/carrierroute/doc/carrierroute.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - carrierroute - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 1&1 Internet AG - diff --git a/modules/carrierroute/doc/carrierroute_admin.xml b/modules/carrierroute/doc/carrierroute_admin.xml deleted file mode 100644 index c885b2a1f63..00000000000 --- a/modules/carrierroute/doc/carrierroute_admin.xml +++ /dev/null @@ -1,1616 +0,0 @@ - - - - &adminguide; - -
- Overview - A module which provides routing, balancing and blacklisting capabilities. - - The module provides routing, balancing and blacklisting capabilities. - It reads routing entries from a database source or from a config file at OpenSIPS - startup. It can uses one routing tree (for one carrier), or if needed for every user - a different routing tree (unique for each carrier) for number prefix based routing. - It supports several route tree domains, e.g. for failback routes or different routing - rules for VoIP and PSTN targets. - - - Based on the tree, the module decides which number prefixes are forwarded to which - gateway. It can also distribute the traffic by ratio parameters. Furthermore, the - requests can be distributed by a hash funcion to predictable destinations. The hash - source is configurable, two different hash functions are available. - - - This modules scales up to more than a few million users, and is able to handle - more than several hundred thousand routing table entries. It should be able to handle - more, but this is not that much tested at the moment. In load balancing scenarios the - usage of the config file mode is recommended, to avoid the additional complexity that - the database driven routing creates. - - - Routing tables can be reloaded and edited (in config file mode) with the MI - interface, the config file is updated according the changes. This is not - implemented for the db interface, because its easier to do the changes - directly on the db. But the reload and dump functions works of course here - too. - - - Some module functionality is not fully available in the config file mode, as - it is not possible to specify all information that can be stored in the database - tables in the config file. Further information about these limitations is given - in later sections. For user based routing or LCR you should use the database mode. - - - Basically this module could be used as an replacement for the lcr and the - dispatcher module, if you have certain performance, flexibility and/or - integration requirements that these modules don't handle properly. But for - small installations it probably make more sense to use the lcr and dispatcher - module. - - - If you want to use this module in failure routes, then you need to call - append_branch() after rewriting the request URI in order to - relay the message to the new target. Its also supportes the usage of database - derived failure routing descisions with the carrierfailureroute table. - -
-
- Dependencies -
- &osips; Modules - - The following module must be loaded before this module: - - - - a database module, when a database is used as configuration data source. - Only SQL based databases are supported, as this module needs the capability to - issue raw queries. Its not possible to use the dbtext or db_berkeley module at the moment. - - - - - The tm module, when you want to use the $T_reply_code pseudo-variable in - the cr_next_domain function. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libconfuse, a configuration file parser library. - ( http://www.nongnu.org/confuse/ ) - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (string) - - Url to the database containing the routing data. - - - - Default value is &defaultrodb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("carrierroute", "db_url", "&exampledb;") -... - - -
- -
- <varname>db_table</varname> (string) - - Name of the table where the routing data is stored. - - - - Default value is carrierroute. - - - - Set <varname>db_table</varname> parameter - -... -modparam("carrierroute", "db_table", "carrierroute") -... - - -
- -
- <varname>id_column</varname> (string) - - Name of the column containing the id identifier. - - - - Default value is id. - - - - Set <varname>id_column</varname> parameter - -... -modparam("carrierroute", "id_column", "id") -... - - -
- -
- <varname>carrier_column</varname> (string) - - Name of the column containing the carrier id. - - - - Default value is carrier. - - - - Set <varname>carrier_column</varname> parameter - -... -modparam("carrierroute", "carrier_column", "carrier") -... - - -
- -
- <varname>scan_prefix_column</varname> (string) - - Name of column containing the scan prefixes. Scan prefixes define - the matching portion of a phone number, e.g. when we have the scan - prefixes 49721 and 49, the called number is 49721913740, it matches - 49721, because the longest match is taken. If no prefix matches, - the number is not routed. To prevent this, an empty prefix value - of could be added. - - - - Default value is scan_prefix. - - - - Set <varname>scan_prefix_column</varname> parameter - -... -modparam("carrierroute", "scan_prefix_column", "scan_prefix") -... - - -
- -
- <varname>domain_column</varname> (string) - - Name of column containing the rule domain. You can define several routing - domains to have different routing rules. Maybe you use domain 0 for normal - routing and domain 1 if domain 0 failed. - - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - -... -modparam("carrierroute", "domain_column", "domain") -... - - -
- -
- <varname>flags_column</varname> (string) - - Name of the column containing the flags. - - - - Default value is flags. - - - - Set <varname>flags_column</varname> parameter - -... -modparam("carrierroute", "flags_column", "flags") -... - - -
- -
- <varname>mask_column</varname> (string) - - Name of the column containing the flags mask. - - - - Default value is mask. - - - - Set <varname>mask_column</varname> parameter - -... -modparam("carrierroute", "mask_column", "mask") -... - - -
- -
- <varname>prob_column</varname> (string) - - Name of column containing probability. The probability value is used to - distribute the traffic between several gateways. Let's say 70 % of the - traffic shall be routed to gateway A, the other 30 % shall be routed to - gateway B, we define a rule for gateway A with a prob value of 0.7 and a - rule for gateway B with a prob value of 0.3. - - - If all probabilities for a given prefix, tree and domain don't add to 100%, - the prefix values will be adjusted according the given prob values. E.g. if - three hosts with prob values of 0.5, 0.5 and 0.4 are defined, the resulting - probabilities are 35.714, 35.714 and 28.571%. But its better to choose meaningful - values in the first place because of clarity. - - - - Default value is prob. - - - - Set <varname>prob_column</varname> parameter - -... -modparam("carrierroute", "prob_column", "prob") -... - - -
- -
- <varname>rewrite_host_column</varname> (string) - - Name of column containing rewrite host value. An empty field represents a - blacklist entry, anything else is put as domain part into the Request URI - of the SIP message. - - - - Default value is rewrite_host. - - - - Set <varname>rewrite_host_column</varname> parameter - -... -modparam("carrierroute", "rewrite_host_column", "rewrite_host") -... - - -
- -
- <varname>strip_column</varname> (string) - - Name of the column containing the number of digits to be stripped of the - userpart of an URI before prepending rewrite_prefix. - - - - Default value is strip. - - - - Set <varname>strip_column</varname> parameter - -... -modparam("carrierroute", "strip_column", "strip") -... - - -
- -
- <varname>comment_column</varname> (string) - - Name of the column containing an optional comment (useful in large routing tables) - The comment is also displayed by the fifo cmd "cr_dump_routes". - - - - Default value is description. - - - - Set <varname>comment_column</varname> parameter - -... -modparam("carrierroute", "comment_column", "description") -... - - -
- -
- <varname>carrier_table</varname> (string) - - The name of the table containing the existing carriers, consisting - of the ids and corresponding names. - - - - Default value is route_tree. - - - - Set <varname>carrier_table</varname> parameter - -... -modparam("carrierroute", "carrier_table", "route_tree") -... - - -
- -
- <varname>rewrite_prefix_column</varname> (string) - - Name of column containing rewrite prefixes. Here you can define a rewrite - prefix for the localpart of the SIP URI. - - - - Default value is rewrite_prefix. - - - - Set <varname>rewrite_prefix_column</varname> parameter - -... -modparam("carrierroute", "rewrite_prefix_column", "rewrite_prefix") -... - - -
- -
- <varname>rewrite_suffix_column</varname> (string) - - Name of column containing rewrite suffixes. Here you can define a rewrite - suffix for the localpart of the SIP URI. - - - - Default value is rewrite_suffix. - - - - Set <varname>rewrite_suffix_column</varname> parameter - - ... -modparam("carrierroute", "rewrite_suffix_column", "rewrite_suffix") - ... - - -
- -
- <varname>carrier_id_col</varname> (string) - - The name of the column in the carrier table containing the carrier id. - - - - Default value is id. - - - - Set <varname>id_col</varname> parameter - -... -modparam("carrierroute", "carrier_id_col", "id") -... - - -
- -
- <varname>carrier_name_col</varname> (string) - - The name of the column in the carrier table containing the carrier name. - - - - Default value is carrier. - - - - Set <varname>carrier_name_col</varname> parameter - -... -modparam("carrierroute", "carrier_name_col", "carrier") -... - - -
- -
- <varname>subscriber_table</varname> (string) - - The name of the table containing the subscribers - - - - Default value is subscriber. - - - - Set <varname>subscriber_table</varname> parameter - -... -modparam("carrierroute", "subscriber_table", "subscriber") -... - - -
- -
- <varname>subscriber_user_col</varname> (string) - - The name of the column in the subscriber table containing the usernames. - - - - Default value is username. - - - - Set <varname>subscriber_user_col</varname> parameter - -... -modparam("carrierroute", "subscriber_user_col", "username") -... - - -
- -
- <varname>subscriber_domain_col</varname> (string) - - The name of the column in the subscriber table containing the domain of - the subscriber. - - - - Default value is domain. - - - - Set <varname>subscriber_domain_col</varname> parameter - -... -modparam("carrierroute", "subscriber_domain_col", "domain") -... - - -
- -
- <varname>subscriber_carrier_col</varname> (string) - - The name of the column in the subscriber table containing the carrier id - of the subscriber. - - - - - Default value is cr_preferred_carrier. - - - - Set <varname>subscriber_carrier_col</varname> parameter - -... -modparam("carrierroute", "subscriber_carrier_col", "cr_preferred_carrier") -... - - -
- -
- <varname>config_source</varname> (string) - - Specifies whether the module loads its config data from a file or from a - database. Possible values are file or db. - - - - Default value is file. - - - - Set <varname>config_source</varname> parameter - -... -modparam("carrierroute", "config_source", "file") -... - - -
- -
- <varname>config_file</varname> (string) - - Specifies the path to the config file. - - - - Default value is /etc/opensips/carrierroute.conf. - - - - Set <varname>config_file</varname> parameter - -... -modparam("carrierroute", "config_file", "/etc/opensips/carrierroute.conf") -... - - -
- -
- <varname>default_tree</varname> (string) - - The name of the carrier tree used per default (if the current - subscriber has no preferred tree) - - - - Default value is default. - - - - Set <varname>default_tree</varname> parameter - -... -modparam("carrierroute", "default_tree", "default") -... - - -
- -
- <varname>use_domain</varname> (int) - - When using tree lookup per user, this parameter specifies whether - to use the domain part for user matching or not. - - - - Default value is 0. - - - - Set <varname>use_domain</varname> parameter - -... -modparam("carrierroute", "use_domain", 0) -... - - -
- -
- <varname>fallback_default</varname> (int) - - This parameter defines the behaviour when using user-based tree - lookup. If the user has a non-existing tree set and fallback_default - is set to 1, the default tree is used. Otherwise, cr_user_rewrite_uri - returns an error. - - - - Default value is 1. - - - - Set <varname>fallback_default</varname> parameter - -... -modparam("carrierroute", "fallback_default", 1) -... - - -
- -
- <varname>db_failure_table</varname> (string) - - Name of the table where the failure routing data is stored. - - - - Default value is carrierfailureroute. - - - - Set <varname>db_failure_table</varname> parameter - -... -modparam("carrierroute", "db_failure_table", "carrierfailureroute") -... - - -
- -
- <varname>failure_id_column</varname> (string) - - Name of the column containing the id identifier. - - - - Default value is id. - - - - Set <varname>failure_id_column</varname> parameter - -... -modparam("carrierroute", "failure_id_column", "id") -... - - -
- -
- <varname>failure_carrier_column</varname> (string) - - Name of the column containing the carrier id. - - - - Default value is carrier. - - - - Set <varname>failure_carrier_column</varname> parameter - -... -modparam("carrierroute", "failure_carrier_column", "carrier") -... - - -
- -
- <varname>failure_scan_prefix_column</varname> (string) - - Name of column containing the scan prefixes. Scan prexies - define the matching portion of a phone number, e.g. we have the - scan prefixes 49721 and 49, the called number is 49721913740, - it matches 49721, because the longest match is taken. If no - prefix matches, the number is not failure routed. To prevent - this, an empty prefix value of could be added. - - - - Default value is scan_prefix. - - - - Set <varname>failure_scan_prefix_column</varname> parameter - -... -modparam("carrierroute", "failure_scan_prefix_column", "scan_prefix") -... - - -
- -
- <varname>failure_domain_column</varname> (string) - - Name of column containing the rule domain. You can define - several routing domains to have different routing rules. Maybe - you use domain 0 for normal routing and domain 1 if domain 0 - failed. - - - - Default value is domain. - - - - Set <varname>failure_domain_column</varname> parameter - -... -modparam("carrierroute", "failure_domain_column", "domain") -... - - -
- -
- <varname>failure_host_name_column</varname> (string) - - Name of the column containing the host name of the last routing - destination. - - - - Default value is host_name. - - - - Set <varname>failure_host_name_column</varname> parameter - -... -modparam("carrierroute", "failure_host_name_column", "host_name") -... - - -
- -
- <varname>failure_reply_code_column</varname> (string) - - Name of the column containing the reply code. - - - - Default value is reply_code. - - - - Set <varname>failure_reply_code_column</varname> parameter - -... -modparam("carrierroute", "failure_reply_code_column", "reply_code") -... - - -
- -
- <varname>failure_flags_column</varname> (string) - - Name of the column containing the flags. - - - - Default value is flags. - - - - Set <varname>failure_flags_column</varname> parameter - -... -modparam("carrierroute", "failure_flags_column", "flags") -... - - -
- -
- <varname>failure_mask_column</varname> (string) - - Name of the column containing the flags mask. - - - - Default value is mask. - - - - Set <varname>failure_mask_column</varname> parameter - -... -modparam("carrierroute", "failure_mask_column", "mask") -... - - -
- -
- <varname>failure_next_domain_column</varname> (string) - - Name of the column containing the next routing domain. - - - - Default value is next_domain. - - - - Set <varname>failure_next_domain_column</varname> parameter - -... -modparam("carrierroute", "failure_next_domain_column", "next_domain") -... - - -
- -
- <varname>failure_comment_column</varname> (string) - - Name of the column containing an optional comment. - - - - Default value is description. - - - - Set <varname>failure_comment_column</varname> parameter - -... -modparam("carrierroute", "failure_comment_column", "description") -... - - -
- -
-
- Exported Functions - - Previous versions of carrierroute had some more function. All the - old semantics can be achieved by using the few new functions - like this: - - - -cr_rewrite_uri(domain, hash_source) --> cr_route("default", domain, $rU, $rU, hash_source) - -cr_prime_balance_uri(domain, hash_source) --> cr_prime_route("default", domain, $rU, $rU, hash_source) - -cr_rewrite_by_to(domain, hash_source) --> cr_route("default", domain, $tU, $rU, hash_source) - -cr_prime_balance_by_to(domain, hash_source) --> cr_prime_route("default", domain, $tU, $rU, hash_source) - -cr_rewrite_by_from(domain, hash_source) --> cr_route("default", domain, $fU, $rU, hash_source) - -cr_prime_balance_by_from(domain, hash_source) --> cr_prime_route("default", domain, $fU, $rU, hash_source) - -cr_user_rewrite_uri(uri, domain) --> cr_user_carrier(user, domain, $avp(tree_avp)) --> cr_route($avp(tree_avp), domain, $rU, $rU, "call_id") - -cr_tree_rewrite_uri(tree, domain) --> cr_route(tree, domain, $rU, $rU, "call_id") - - -
- - <function moreinfo="none">cr_user_carrier(user, domain, dst_avp)</function> - - - This function loads the carrier and stores it in an AVP. - It cannot be used in the config file mode, as it needs a mapping of the - given user to a certain carrier. The is derived from a database entry - belonging to the user parameter. This mapping must be available in the - table that is specified in the subscriber_table variable. - This data is not cached in memory, that means for every execution of this - function a database query will be done. - - Parameters: - - - user (string) - Name of the user for the - carrier tree lookup - - - - domain (string) - Name of the routing - domain to be used - - - - dst_avp (var) - Name of an AVP where to - store the carrier id - - - -
-
- - <function moreinfo="none">cr_route(carrier, domain, prefix_matching, rewrite_user, hash_source, [dst_avp])</function> - - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier tree. - The Request URI is rewritten using rewrite_user and the given - hash source and algorithm. Returns -1 if there is no data found - or an empty rewrite host on the longest match is found. Otherwise - the rewritten host is stored in the given AVP (if obmitted, the - host is not stored in an AVP). - This function is only usable with rewrite_user and prefix_matching - containing a valid numerical only string. It uses the standard crc32 algorithm - to calculate the hash values. - - Parameters: - - - carrier (string) - The routing tree to - be used - - - - domain (string) - Name of the routing - domain to be used - - - - prefix_matching (string) - User name - to be used for prefix matching in the routing tree - - - - rewrite_user (string) - The user name - to be used for applying the rewriting rule. Usually, this is - the user part of the request URI - - - - hash_source (string) - The hash values - of the destination set must be a contiguous range starting at 1, - limited by the configuration parameter max_targets. Possible - values for hash_source are: call_id, from_uri, from_user, to_uri - and to_user. - - - - dst_avp (var, optional) - Optional AVP - where to store the rewritten host - - - -
-
- - <function moreinfo="none">cr_prime_route(carrier, domain, prefix_matching, rewrite_user, hash_source, [dst_avp])</function> - - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier tree. - The Request URI is rewritten using rewrite_user and the given - hash source and algorithm. Returns -1 if there is no data found - or an empty rewrite host on the longest match is found. Otherwise - the rewritten host is stored in the given AVP (if obmitted, the - host is not stored in an AVP). - This function is only usable with rewrite_user and prefix_matching - containing a valid numerical only string. It uses the prime hash algorithm - to calculate the hash values. - - Meaning of the parameters is as follows: - - - carrier (string) - The routing tree to - be used - - - - domain (string) - Name of the routing - domain to be used - - - - prefix_matching (string) - User name - to be used for prefix matching in the routing tree - - - - rewrite_user (string) - The user name - to be used for applying the rewriting rule. Usually, this is - the user part of the request URI - - - - hash_source (string) - The hash values - of the destination set must - be a contiguous range starting at 1, limited by the - configuration parameter max_targets. Possible values for - hash_source are: call_id, from_uri, from_user, to_uri - and to_user. - - - - dst_avp (var, optional) - Optional AVP - where to store the rewritten host - - - -
- -
- - <function moreinfo="none">cr_next_domain(carrier, domain, prefix_matching, host, reply_code, dst_avp)</function> - - - This function searches for the longest match for the user given - in prefix_matching at the given domain in the given carrier - failure tree. It tries to find a next domain matching the given - host, reply_code and the message flags. The matching is done in this order: - host, reply_code and then flags. The more wildcards in reply_code - and the more bits used in flags, the lower the priority. - Returns -1 if there is no data found or an empty next_domain on - the longest match is found. Otherwise the next domain is stored - in the given AVP. - This function is only usable with prefix_matching containing a - valid numerical only string. - - Meaning of the parameters is as follows: - - - carrier (string) - The routing tree to be used - any pseudo-variable could be used as input. - - - - domain (string) - Name of the routing domain to be used - - - - prefix_matching (string) - User name to be used for prefix matching - in the routing tree - - - - host (string) - The host name to be used for failure route rule - matching. Usually, this is the last tried routing destination - stored in an avp by cr_route - - - - reply_code (string) - The reply code to be used for failure route rule - matching - - - - dst_avp (var) - AVP where to store the next routing domain. - - - -
-
- -
- Exported MI Functions - All commands understand the "-?" parameter to print a short help message. - The options have to be quoted as one string to be passed to MI interface. - Each option except host and new host can be wildcarded by * (but only * and not things - like "-d prox*"). -
- <function moreinfo="none">cr_reload_routes</function> - - This command reloads the routing data from the data source. - - - Important: When new domains have been added, a restart of the server must be - done, because the mapping of the ids used in the config script cannot be - updated at runtime at the moment. So a reload could result in a wrong routing - behaviour, because the ids used in the script could differ from the one used - internally from the server. Modifying of already existing domains is no problem. - -
-
- <function moreinfo="none">cr_dump_routes</function> - - This command prints the route rules on the command line. - -
-
- <function moreinfo="none">cr_replace_host</function> - - This command can replace the rewrite_host of a route rule, it is only - usable in file mode. Following options are possible: - - - - -d - the domain containing the host - - - -p - the prefix containing the host - - - -h - the host to be replaced - - - -t - the new host - - - Use the "null" prefix to specify an empty prefix. - - <function>cr_replace_host</function> usage - -... -opensips-cli -x mi cr_replace_host "-d proxy -p 49 -h proxy1 -t proxy2" -... - - -
-
- <function moreinfo="none">cr_deactivate_host</function> - - This command deactivates the specified host, i.e. it sets its status to 0. - It is only usable in file mode. Following options are possible: - - - - -d - the domain containing the host - - - -p - the prefix containing the host - - - -h - the host to be deactivated - - - -t - the new host used as backup - - - When -t (new_host) is specified, the portion of traffic for the deactivated host - is routed to the host given by -t. This is indicated in the output of dump_routes. - The backup route is deactivated if the host is activated again. - Use the "null" prefix to specify an empty prefix. - - <function>cr_deactivate_host</function> usage - -... -opensips-cli -x mi cr_deactivate_host "-d proxy -p 49 -h proxy1" -... - - -
-
- <function moreinfo="none">cr_activate_host</function> - - This command activates the specified host, i.e. it sets its status to 1. - It is only usable in file mode. Following options are possible: - - - - -d - the domain containing the host - - - -p - the prefix containing the host - - - -h - the host to be activated - - - Use the "null" prefix to specify an empty prefix. - - <function>cr_activate_host</function> usage - -... -opensips-cli -x mi cr_activate_host "-d proxy -p 49 -h proxy1" -... - - -
- -
- <function moreinfo="none">cr_add_host</function> - - This command adds a route rule, it is only usable in file mode. Following options - are possible: - - - - -d - the domain containing the host - - - -p - the prefix containing the host - - - -h - the host to be added - - - -w - the weight of the rule - - - -P - an optional rewrite prefix - - - -S - an optional rewrite suffix - - - -i - an optional hash index - - - -s - an optional strip value - - - Use the "null" prefix to specify an empty prefix. - - <function>cr_add_host</function> usage - -... -opensips-cli -x mi cr_add_host "-d proxy -p 49 -h proxy1 -w 0.25" -... - - -
- -
- <function moreinfo="none">cr_delete_host</function> - - This command delete the specified hosts or rules, i.e. remove - them from the route tree. It is only usable in file mode. - Following options are possible: - - - - -d - the domain containing the host - - - -p - the prefix containing the host - - - -h - the host to be added - - - -w - the weight of the rule - - - -P - an optional rewrite prefix - - - -S - an optional rewrite suffix - - - -i - an optional hash index - - - -s - an optional strip value - - - Use the "null" prefix to specify an empty prefix. - - <function>cr_delete_host</function> usage - -... -opensips-cli -x mi cr_delete_host "-d proxy -p 49 -h proxy1 -w 0.25" -... - - -
-
-
- Examples - - Configuration example - Routing to default tree - -... -route { - # route calls based on hash over callid - # choose route domain 0 of the default carrier - - if(!cr_route("default", "0", "$rU", "$rU", "call_id", "crc32")){ - sl_send_reply(403, "Not allowed"); - } else { - # In case of failure, re-route the request - t_on_failure("1"); - # Relay the request to the gateway - t_relay(); - } -} - -failure_route[1] { - # In case of failure, send it to an alternative route: - if (t_check_status("408|5[0-9][0-9]")) { - #choose route domain 1 of the default carrier - if(!cr_route("default", "1", "$rU", "$rU", "call_id", "crc32")){ - t_reply(403, "Not allowed"); - } else { - t_on_failure("2"); - t_relay(); - } - } -} - -failure_route[2] { - # further processing -} - - - - - - Configuration example - Routing to user tree - -... -route[1] { - cr_user_carrier("$fU", "$fd", "$avp(carrier)"); - - # just an example domain - $avp(domain)="start"; - if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", - "call_id", "$avp(host)")) { - xlog("L_ERR", "cr_route failed\n"); - exit; - } - t_on_failure("1"); - if (!t_relay()) { - sl_reply_error(); - }; -} - -failure_route[1] { - revert_uri(); - if (!cr_next_domain("$avp(carrier)", "$avp(domain)", "$rU", - "$avp(host)", "$T_reply_code", "$avp(domain)")) { - xlog("L_ERR", "cr_next_domain failed\n"); - exit; - } - if (!cr_route("$avp(carrier)", "$avp(domain)", "$rU", "$rU", - "call_id", "$avp(host)")) { - xlog("L_ERR", "cr_route failed\n"); - exit; - } - t_on_failure("1"); - append_branch(); - if (!t_relay()) { - xlog("L_ERR", "t_relay failed\n"); - exit; - }; -} -... - - - - - - Configuration example - module configuration - - The following config file specifies within the default carrier two - domains, each with an prefix that contains two hosts. It is not possible - to specify another carrier if you use the config file as data source. - - - All traffic will be equally distributed between the hosts, both are - active. The hash algorithm will working over the [1,2] set, messages - hashed to one will go to the first host, the other to the second one. - Don't use a hash index value of zero. If you ommit the hash completly, - the module gives them a autogenerated value, starting from one. - - - Use the NULL prefix to specify an empty prefix in the config file. - Please note that the prefix is matched against the request URI (or to URI), - if they did not contain a valid numerical URI, no match is possible. So - for loadbalancing purposes e.g. for your registrars, you should use an empty - prefix. - - -... -domain proxy { - prefix 49 { - max_targets = 2 - target proxy1.localdomain { - prob = 0.500000 - hash_index = 1 - status = 1 - comment = "test target 1" - } - target proxy2.localdomain { - prob = 0.500000 - hash_index = 2 - status = 1 - comment = "test target 2" - } - } -} - -domain register { - prefix NULL { - max_targets = 2 - target register1.localdomain { - prob = 0.500000 - hash_index = 1 - status = 1 - comment = "test target 1" - } - target register2.localdomain { - prob = 0.500000 - hash_index = 2 - status = 1 - comment = "test target 2" - } - } -} -... - - -
- -
- Installation and Running -
- Database setup - - Before running &osips; with carrierroute, you have to setup the database - table where the module will store the routing data. For that, if - the table was not created by the installation script or you choose - to install everything by yourself you can use the carrierroute-create.sql - SQL script in the database directories in the - opensips/scripts folder as template. - Database and table name can be set with module parameters so they - can be changed, but the name of the columns must be as they are - in the SQL script. - You can also find the complete database documentation on the - project webpage, &osipsdbdocs;. - The flags and mask columns have the same function as in the - carrierfailureroute table. A zero value in the flags and mask - column means that any message flags will match this rule. - - - For a minimal configuration either use the config file given above, or - insert some data into the tables of the module. - - - Example database content - carrierroute table - -... -+----+---------+--------+-------------+-------+------+---------------+ -| id | carrier | domain | scan_prefix | flags | prob | rewrite_host | -+----+---------+--------+-------------+-------+------+---------------+ -| 1 | 1 | 0 | 49 | 0 | 0.5 | de-1.carrier1 | -| 2 | 1 | 0 | 49 | 0 | 0.5 | de-2.carrier1 | -| 3 | 1 | 0 | 49 | 16 | 1 | de-3.carrier1 | -| 4 | 1 | 0 | | 0 | 1 | gw.carrier1-1 | -| 5 | 1 | 1 | 49 | 0 | 1 | gw.carrier1-1 | -| 6 | 1 | 2 | | 0 | 1 | gw.carrier1-2 | -| 7 | 1 | 3 | | 0 | 1 | gw.carrier1-3 | -| 8 | 2 | 0 | 49 | 0 | 0.5 | de-1.carrier2 | -| 9 | 2 | 0 | 49 | 0 | 0.5 | de-2.carrier2 | -| 10 | 2 | 0 | | 0 | 1 | gw.carrier2 | -| 11 | 2 | 1 | 49 | 0 | 1 | gw.carrier2 | -| 12 | 3 | start | 49 | 0 | 1 | de-gw.default | -| 13 | 3 | start | | 0 | 1 | gw.default | -+----+---------+--------+-------------+-------+------+---------------+ -... - - - - This table contains three routes to two gateways for the 49 prefix, - and a default route for other prefixes over carrier 2 and carrier 1. The - gateways for the default carrier will be used for functions that don't - support the user specific carrier lookup. The routing rules for carrier 1 - and carrier 2 for the 49 prefix contains a additional rule - with the domain 1, that can be used for example as fallback if the gateways - in domain 0 are not reachable. Two more fallback rules (domain 2 and 3) for - carrier 1 are also supplied to support the functionality of the carrierfailureroute - table example that is provided in the next section. The usage of strings - for the domains is also possible, for example at carrier 3. - - - This table provides also a carrier1 routing rule for the - 49 prefix, that is only choosen if some message flags are set. - If this flags are not set, the other two rules are used. The strip, - mask and comment colums are omitted for brevity. - - - Example database content - simple carrierfailureroute table - -... -+----+---------+--------+---------------+------------+-------------+ -| id | carrier | domain | host_name | reply_code | next_domain | -+----+---------+--------+---------------+------------+-------------+ -| 1 | 1 | 0 | gw.carrier1-2 | ... | 3 | -| 2 | 1 | 0 | gw.carrier1-3 | ... | 2 | -+----+---------+--------+---------------+------------+-------------+ -... - - - - This table contains two failure routes for the gw.carrier1-1 and - -2 gateways. For any (failure) reply code the respective next - domain is choosen. After that no more failure routes are available, an error will - be returned from the cr_next_domain function. Not all table - colums are show here for brevity. - - - For each failure route domain and carrier that is added to the carrierfailureroute - table there must be at least one corresponding entry in the carrierroute table, - otherwise the module will not load the routing data. - - - - Example database content - more complex carrierfailureroute table - -... -+----+---------+-----------+------------+--------+-----+-------------+ -| id | domain | host_name | reply_code | flags | mask | next_domain | -+----+---------+-----------+------------+-------+------+-------------+ -| 1 | 99 | | 408 | 16 | 16 | | -| 2 | 99 | gw1 | 404 | 0 | 0 | 100 | -| 3 | 99 | gw2 | 50. | 0 | 0 | 100 | -| 4 | 99 | | 404 | 2048 | 2112 | asterisk-1 | -+----+---------+-----------+------------+-------+------+-------------+ -... - - - - This table contains four failure routes that shows the usage of more - advanced features. The first route matches to a 408, and to some flag - for example that indicates that ringing has happened. If this flag is set, - there will be no further forwarding, because next_domain is empty. In the - second and third routes are certain gateway errors matched, if this errors - have occurred, then the next domain will be chosen. The last route does - forwarding according some flags, e.g. the customer came from a certain carrier, - and has call-forwarding deactivated. In order to use the routing that is - specified above, a matching carrierroute table must be provided, that holds - domain entries for this routing rules. Not all table colums are show here for - brevity. - - - - Example database content - route_tree table - -... -+----+----------+ -| id | carrier | -+----+----------+ -| 1 | carrier1 | -| 2 | carrier2 | -| 3 | default | -+----+----------+ -... - - - - This table contains the mapping of the carrier id to actual names. - - - For a functional routing the cr_preferred_carrier column must - be added to the subscriber table (or to the table and column that you specified - as modul parameter) to choose the actual carrier for the users. - - - Necessary extensions for the user table - Suggested changes: - -... -ALTER TABLE subscriber ADD cr_preferred_carrier int(10) default NULL; -... - - -
-
-
- diff --git a/modules/carrierroute/doc/contributors.xml b/modules/carrierroute/doc/contributors.xml deleted file mode 100644 index f64400c098e..00000000000 --- a/modules/carrierroute/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Henning Westerholt (@henningw) - 125 - 80 - 2085 - 1607 - - - 2. - Jonas Appel - 54 - 1 - 6240 - 0 - - - 3. - Hardy Kahl - 49 - 3 - 2713 - 1360 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 29 - 24 - 131 - 154 - - - 5. - Razvan Crainea (@razvancrainea) - 23 - 20 - 109 - 108 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 22 - 5 - 384 - 764 - - - 7. - Liviu Chircu (@liviuchircu) - 19 - 13 - 134 - 210 - - - 8. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 34 - 30 - - - 9. - Alexandra Titoc - 5 - 3 - 13 - 2 - - - 10. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - -
-All remaining contributors: Carsten Bock, Bob Atkins, Julián Moreno Patiño, Ovidiu Sas (@ovidiusas), Sergio Gutierrez, Iouri Kharon, UnixDev, Zero King (@l2dy), ihsinme, Ken Rice, Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 5. - ihsinme - Feb 2022 - Feb 2022 - - - 6. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jan 2021 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2019 - - - 9. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2007 - Apr 2019 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Julián Moreno Patiño, Walter Doekes (@wdoekes), Ovidiu Sas (@ovidiusas), UnixDev, Henning Westerholt (@henningw), Sergio Gutierrez, Iouri Kharon, Hardy Kahl, Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Bob Atkins, Carsten Bock, Jonas Appel. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Bogdan-Andrei Iancu (@bogdan-iancu), Henning Westerholt (@henningw), Iouri Kharon, Hardy Kahl, Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Carsten Bock, Jonas Appel. -
- -
diff --git a/modules/cfgutils/README b/modules/cfgutils/README deleted file mode 100644 index 3d578d9986d..00000000000 --- a/modules/cfgutils/README +++ /dev/null @@ -1,1012 +0,0 @@ -cfgutils Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. initial_probability (string) - 1.3.2. hash_file (string) - 1.3.3. shv_hash_size (integer) - 1.3.4. shvset (string) - 1.3.5. varset (string) - 1.3.6. lock_pool_size (integer) - - 1.4. Exported Functions - - 1.4.1. rand_event([probability]) - 1.4.2. rand_set_prob(probability) - 1.4.3. rand_reset_prob() - 1.4.4. rand_get_prob() - 1.4.5. sleep(time) - 1.4.6. usleep(time) - 1.4.7. abort() - 1.4.8. pkg_status() - 1.4.9. shm_status() - 1.4.10. set_count(var_to_count, ret_var) - 1.4.11. set_select_weight(int_list_var) - 1.4.12. ts_usec_delta(t1_sec, t1_usec, t2_sec, - t2_usec, [delta_str], [delta_int]) - - 1.4.13. check_time_rec(time_string, [timestamp]) - 1.4.14. get_static_lock(key) - 1.4.15. release_static_lock(key) - 1.4.16. get_dynamic_lock(key) - 1.4.17. release_dynamic_lock(key) - 1.4.18. strings_share_lock(key1, key2) - 1.4.19. get_accurate_time(sec, usec, [str_sec_usec]) - - 1.4.20. shuffle_avps(name) - - 1.5. Exported Asyncronous Functions - - 1.5.1. sleep(seconds) - 1.5.2. usleep(seconds) - - 1.6. Exported MI Functions - - 1.6.1. rand_set_prop - 1.6.2. rand_reset_prob - 1.6.3. rand_get_prob - 1.6.4. check_config_hash - 1.6.5. get_config_hash - 1.6.6. shv_set - 1.6.7. shv_get - - 1.7. Exported Pseudo-Variables - - 1.7.1. $env(name) - 1.7.2. $RANDOM - 1.7.3. $ctime(name) - 1.7.4. $shv(name) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. initial_probability parameter usage - 1.2. hash_file parameter usage - 1.3. shv_hash_size parameter usage - 1.4. shvset parameter usage - 1.5. varset parameter usage - 1.6. Setting lock_pool_size module parameter - 1.7. rand_event() usage - 1.8. rand_set_prob() usage - 1.9. rand_reset_prob() usage - 1.10. rand_get_prob() usage - 1.11. sleep usage - 1.12. usleep usage - 1.13. abort usage - 1.14. pkg_status usage - 1.15. shm_status usage - 1.16. set_count usage - 1.17. set_select_weight usage - 1.18. ts_usec_delta usage - 1.19. check_time_rec usage - 1.20. get_static_lock usage - 1.21. release_static_lock usage - 1.22. get_dynamic_lock usage - 1.23. release_dynamic_lock usage - 1.24. strings_share_lock usage - 1.25. get_accurate_time usage - 1.26. shuffle_avps usage - 1.27. async sleep usage - 1.28. async usleep usage - 1.29. rand_set_prob usage - 1.30. rand_reset_prob usage - 1.31. rand_get_prob usage - 1.32. check_config_hash usage - 1.33. get_config_hash usage - 1.34. shv_set usage - 1.35. shv_get usage - 1.36. env(name) pseudo-variable usage - 1.37. RANDOM pseudo-variable usage - 1.38. ctime(name) pseudo-variable usage - 1.39. shv(name) pseudo-variable usage - -Chapter 1. Admin Guide - -1.1. Overview - - Useful extensions for the server configuration. - - The cfgutils module can be used to introduce randomness to the - behaviour of the server. It provides setup functions and the - “rand_event” function. This function return either true or - false, depending on a random value and a specified probability. - E.g. if you set via fifo or script a probability value of 5%, - then 5% of all calls to rand_event will return false. The - pseudovariable “$RANDOM” could be used to introduce random - values e.g. into a SIP reply. - - The benefit of this module is the probability of the decision - can be manipulated by external applications such as web - interface or command line tools. The probability must be - specified as percent value, ranging from 0 to 100. - - The module exports commands to FIFO server that can be used to - change the global settings via FIFO interface. The FIFO - commands are: “set_prob”, “reset_prob” and “get_prob”. - - This module can be used for simple load-shedding, e.g. reply 5% - of the Invites with a 503 error and a adequate random - Retry-After value. - - The module provides as well functions to delay the execution of - the server. The functions “sleep” and “usleep” could be used to - let the server wait a specific time interval. - - It can also hash the config file used from the server with a - (weak) cryptographic hash function on startup. This value is - saved and can be later compared to the actual hash, to detect - modifications of this file after the server start. This - functions are available as the FIFO commands - “check_config_hash” and “get_config_hash”. - -1.2. Dependencies - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * none - -1.3. Exported Parameters - -1.3.1. initial_probability (string) - - The initial value of the probability. - - Default value is “10”. - - Example 1.1. initial_probability parameter usage - -modparam("cfgutils", "initial_probability", 15) - - -1.3.2. hash_file (string) - - The config file name for that a hash value should be calculated - on startup. - - There is no default value, is no parameter is given the hash - functionality is disabled. - - Example 1.2. hash_file parameter usage - -modparam("cfgutils", "hash_file", "/etc/opensips/opensips.cfg") - - -1.3.3. shv_hash_size (integer) - - The size of the hash table used to store the shared variables - ($shv). - - Default value is “64”. - - Example 1.3. shv_hash_size parameter usage - -modparam("cfgutils", "shv_hash_size", 1024) - - -1.3.4. shvset (string) - - Set the value of a shared variable ($shv(name)). The parameter - can be set many times. - - The value of the parameter has the format: _name_ '=' _type_ - ':' _value_ - * _name_: shared variable name - * _type_: type of the value - + “i”: integer value - + “s”: string value - * _value_: value to be set - - Default value is “NULL”. - - Example 1.4. shvset parameter usage -... -modparam("cfgutils", "shvset", "debug=i:1") -modparam("cfgutils", "shvset", "pstngw=s:sip:10.10.10.10") -... - -1.3.5. varset (string) - - Set the value of a script variable ($var(name)). The parameter - can be set many times. - - The value of the parameter has the format: _name_ '=' _type_ - ':' _value_ - * _name_: shared variable name - * _type_: type of the value - + “i”: integer value - + “s”: string value - * _value_: value to be set - - Default value is “NULL”. - - Example 1.5. varset parameter usage -... -modparam("cfgutils", "varset", "init=i:1") -modparam("cfgutils", "varset", "gw=s:sip:11.11.11.11;transport=tcp") -... - -1.3.6. lock_pool_size (integer) - - The number of dynamic script locks to be allocated at OpenSIPS - startup. This number must be a power of 2. (i.e. 1, 2, 4, 8, - 16, 32, 64 ...) - - Note that the lock_pool_size parameter only affects the number - of dynamic locks created at startup. The pool of static locks - only depends on the number of unique static strings supplied - throughout the script to the set of static lock functions. - - Default value is “32”. - - Example 1.6. Setting lock_pool_size module parameter -modparam("cfgutils", "lock_pool_size", 64) - -1.4. Exported Functions - -1.4.1. rand_event([probability]) - - Generates a random floating point value between 0 - 100 and - returns true if the value is less or equal to the currently set - probability. If "probability" parameter is given, it will - override the global parameter set by rand_set_prob(). - - Parameters: - * probability (int, optional) - probability override - - Example 1.7. rand_event() usage -... -if (rand_event()) { - append_to_reply("Retry-After: 120\n"); - sl_send_reply(503, "Try later"); - exit; -} -# normal message processing follows -... - -1.4.2. rand_set_prob(probability) - - Set the “probability” of the decision. - - Parameters: - * probability (int) - number ranging from 0 - 99, inclusively - - Example 1.8. rand_set_prob() usage -... -rand_set_prob(4); -... - -1.4.3. rand_reset_prob() - - Reset the probability back to the initial_probability value. - - Example 1.9. rand_reset_prob() usage -... -rand_reset_prob(); -... - -1.4.4. rand_get_prob() - - Return the current probability setting, e.g. for logging - purposes. - - Example 1.10. rand_get_prob() usage -... -rand_get_prob(); - - -1.4.5. sleep(time) - - Waits "time" seconds. - - Meaning of the parameters is as follows: - * time (int) - time to wait in seconds - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.11. sleep usage -... -sleep(1); -... -$var(secs) = 10; -sleep($var(secs)); -... - -1.4.6. usleep(time) - - Waits "time" micro-seconds. - - Meaning of the parameters is as follows: - * time (int) - time to wait in micro-seconds - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.12. usleep usage -... -usleep(500000); # sleep half a sec -... - -1.4.7. abort() - - Debugging function that aborts the server. Depending on the - configuration of the server a core dump will be created. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.13. abort usage -... -abort(); -... - -1.4.8. pkg_status() - - Debugging function that dumps the status for the private (PKG) - memory. This information is logged to the default log facility, - depending on the general log level and the memlog setting. You - need to compile the server with activated memory debugging to - get detailed informations. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.14. pkg_status usage -... -pkg_status(); -... - -1.4.9. shm_status() - - Debugging function that dumps the status for the shared (SHM) - memory. This information is logged to the default log facility, - depending on the general log level and the memlog setting. You - need to compile the server with activated memory debugging to - get detailed informations. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.15. shm_status usage -... -shm_status(); -... - -1.4.10. set_count(var_to_count, ret_var) - - Counts the number of values of a given variable. It makes sense - to call this function only for variables that can take more - values (AVPs, headers). - - The result is returned in the second parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.16. set_count usage -... -set_count($avp(dids), $var(num_dids)); -... - -1.4.11. set_select_weight(int_list_var) - - This function selects an element from a set formed by the - integer values of the given "int_list_var" variable. It applies - the genetic algorithm - roulette-wheel selection to choose an - element from a set. The probability of selecting a certain - element is proportionate with its weight. It will return the - index of that selected element. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.17. set_select_weight usage -... -$var(next_gw_idx) = set_select_weight($avp(gw_success_rates)); -... - -1.4.12. ts_usec_delta(t1_sec, t1_usec, t2_sec, t2_usec, [delta_str], -[delta_int]) - - This function returns the absolute difference between the two - given timestamps. The result is expressed as microseconds and - can be returned as either string or integer. - - WARNING: when using delta_int, the function will return error - code -1 in case the difference overflows the signed integer - holder! (i.e. a diff of ~35 minutes or more) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.18. ts_usec_delta usage -... -ts_usec_delta($var(t1s), 300, 10, $var(t2us), $var(diff_str)); -... - -1.4.13. check_time_rec(time_string, [timestamp]) - - The function returns a positive value if the specified time - recurrence string matches the current time, or a negative value - otherwise. - - For checking some other Unix timestamp than the current one, - the second parameter will contain the intended timestamp to - check. - - The syntax of each field is identical to the corresponding - field from RFC 2445. - - This function may be used from any route. It returns 1 on - success and -1, -2 or -3 on failure, parsing or internal - errors, respectively. - - Meaning of the parameters is as follows: - * time_string (string) - Time recurrence string which will be - matched against the current time. Its fields are separated - by "|" and the order in which they are given is: "timezone - | dtstart | dtend | duration | freq | until | interval | - byday | bymday | byyday | byweekno | bymonth". - None of the fields following "freq" is used unless "freq" - is defined. If the string ends in multiple null fields, - they can all be ommited. - The "timezone" field is optional. It represents the - timezone in which to interpret the time recurrence elements - (e.g. dtstart, dtend, until). By default, the system time - zone is used. - * timestamp (string, optional) - A specific Unix time to - check. The function simply expects the actual Unix time - here, there is no need to perform any timezone adjustments. - - Additionally, more complex time recurrence strings may be built - by connecting multiple time recurrence strings (described - above) using the logical AND ("&"), OR ("/") and NEG ("!") - operators. Furthermore, the expressions may be paranthesized. - Some examples: - * 20210104T080000|20211231T180000||WEEKLY|||MO,TU,WE,TH,FR & - !20210104T120000|20211231T140000||WEEKLY|||MO,TU,WE,TH,FR - This example multi-recurrence expresses the working days - schedule for company X during 2021: workdays from 8-18, - except the 12-14 interval, when everyone is out for lunch - break and the business is closed. Since the timezone is - omitted from each schedule, the operating system timezone - will be used instead. - * America/New_York|20210104T090000|20210104T170000||WEEKLY||| - MO,TU,WE,TH,FR & - !(Europe/Amsterdam|20210427T000000|20210428T000000 / - Europe/London|20211227T000000|20211228T000000) - This example multi-recurrence expresses the working days - schedule for US-based company Y during 2021: workdays from - 9-17 (NY timezone), except european holidays such as King's - Day (April 27th, NL) or the Spring Bank Holiday (May 31st, - UK), when most of its workforce will have flown back to - Europe. - - Example 1.19. check_time_rec usage -... -# Only passing if still in 2012 and on a Bucharest-compatible timezone -if (check_time_rec("Europe/Bucharest|20120101T000000|20130101T000000")) - xlog("Current system time matches the given Romanian time interv -al\n"); -... -# Only passing if less than 30 days have passed from "dtstart", system t -imezone -if (check_time_rec("20121101T000000||p30d")) - xlog("Current time matches the given interval\n"); -... - -1.4.14. get_static_lock(key) - - Acquire the static lock which corresponds to "key". In case the - lock is taken by another process, script execution will halt - until the lock is released. Attempting to acquire the lock a - second time by the same process, without releasing it first, - will result in a deadlock. - - The static lock functions guarantee that two different strings - will never point to the same lock, thus avoiding introducing - unnecessary (and transparent!) synchronization between - processes. Their disadvantage is the nature of their parameters - (static strings), making them inappropriate in certain - scenarios. - - Meaning of the parameters is as follows: - * key (static string) - key to be hashed in order to obtain - the index of a static lock - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE, EVENT_ROUTE. - - Example 1.20. get_static_lock usage -# acquire and release a static lock -... -get_static_lock("Zone_1"); -... -release_static_lock("Zone_1"); -... - -1.4.15. release_static_lock(key) - - Release the static lock corresponding to "key". Nothing will - happen if the lock is not acquired. - - Meaning of the parameters is as follows: - * key (static string) - key to be hashed in order to obtain - the index of a static lock. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE|EVENT_ROUTE. - - Example 1.21. release_static_lock usage -# acquire and release a static lock -... -get_static_lock("Zone_1"); -... -release_static_lock("Zone_1"); -... - -1.4.16. get_dynamic_lock(key) - - Acquire the dynamic lock corresponding to "key". In case the - lock is taken by another process, script execution will halt - until the lock is released. Attempting to acquire the lock a - second time by the same process, without releasing it first, - will result in a deadlock. - - The dynamic lock functions have the advantage of allowing - string variables to be given as parameters, but the drawback to - this is that two strings may have the same hashed value, thus - pointing to the same lock. As a consequence, either two totally - separate regions of the script will be synchronized (they will - not execute in parallel), or a process could end up in a - deadlock by acquiring two locks in a row on two different (but - equally hashed) strings. To address the latter issue, use the - strings_share_lock() function to test if two strings hash into - the same dynamic lock. - - Meaning of the parameters is as follows: - * key (var) - key to be hashed in order to obtain the index - of a dynamic lock from the pool - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE|EVENT_ROUTE. - - Example 1.22. get_dynamic_lock usage -... -# acquire and release a dynamic lock on the "Call-ID" header field value -if (!get_dynamic_lock($ci)) { - xlog("Error while getting dynamic lock!\n"); -} -... -if (!release_dynamic_lock($ci) { - xlog("Error while releasing dynamic lock!\n"); -} -... - -1.4.17. release_dynamic_lock(key) - - Release the dynamic lock corresponding to "key". Nothing will - happen if the lock is not acquired. - - Meaning of the parameters is as follows: - * key (var) - key to be hashed in order to obtain the index - of a dynamic lock from the pool - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE|EVENT_ROUTE. - - Example 1.23. release_dynamic_lock usage -... -# acquire and release a dynamic lock on the "Call-ID" header field value -if (!get_dynamic_lock($ci)) { - xlog("Error while getting dynamic lock!\n"); -} -... -if (!release_dynamic_lock($ci) { - xlog("Error while releasing dynamic lock!\n"); -} -... - -1.4.18. strings_share_lock(key1, key2) - - A function used to test if two strings will generate the same - hash value. Its purpose is to prevent deadlocks resulted when a - process successively acquires two dynamic locks on two strings - which happen to point to the same lock. - - Theoretically, the chance of two strings generating the same - hash value decreases proportionally to the increase of the - lock_pool_size parameter. In other words, the more dynamic - locks you configure the module with, the higher the chance that - all individual protected regions of your script will run in - parallel, without waiting for each other. - - Meaning of the parameters is as follows: - * key1, key2 (string) - strings which will have their hash - values compared - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE|EVENT_ROUTE. - - Example 1.24. strings_share_lock usage -... -# Proper way of acquiring two dynamic locks successively -if (!get_dynamic_lock($avp(foo))) { - xlog("Error while getting dynamic lock!\n"); -} - -if (!strings_share_lock($avp(foo), $avp(bar)) { - if (!get_dynamic_lock($avp(bar))) { - xlog("Error while getting dynamic lock!\n"); - } -} -... -if (!strings_share_lock($avp(foo), $avp(bar)) { - if (!release_dynamic_lock($avp(bar)) { - xlog("Error while releasing dynamic lock!\n"); - } -} - -if (!release_dynamic_lock($avp(foo)) { - xlog("Error while releasing dynamic lock!\n"); -} -... - -1.4.19. get_accurate_time(sec, usec, [str_sec_usec]) - - Fetch the current Unix time epoch with microsecond precision. - Optionally, print this value as a floating point number (3rd - parameter). - - Meaning of the parameters is as follows: - * sec (int) - the current Unix timestamp (integer part) - * usec (int) - the current Unix timestamp (decimal part) - * str_sec_usec (string, optional) - the current Unix - timestamp as a floating point number (6-digit precision) - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE, EVENT_ROUTE. - - Example 1.25. get_accurate_time usage -... -get_accurate_time($var(sec), $var(usec)); -xlog("Current Unix timestamp: $var(sec) s, $var(usec) us\n"); -... - -1.4.20. shuffle_avps(name) - - Randomly shuffles AVPs with name. - - Meaning of the parameters is as follows: - * name (variable) - name of AVP to shuffle. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.26. shuffle_avps usage -... -$avp(foo) := "str1"; -$avp(foo) = "str2"; -$avp(foo) = "str3"; -xlog("Initial AVP list is: $(avp(foo)[*])\n"); # str3 str2 str1 -if(shuffle_avps( $avp(foo) )) - xlog("Shuffled AVP list is: $(avp(foo)[*])\n"); # str1, str3, str2 -(for example) -... - -1.5. Exported Asyncronous Functions - -1.5.1. sleep(seconds) - - Waits a number of seconds. This function does exactly the same - as sleep(), but in an asynchronous way. The script execution is - suspended until the waiting is done; then OpenSIPS resumes the - script execution via the resume route. - - To read and understand more on the asynchronous functions, how - to use them and what are their advantages, please refer to the - OpenSIPS online Manual. - - Example 1.27. async sleep usage -{ -... -async( sleep("5"), after_sleep ); -} - -route[after_sleep] { -... -} - -1.5.2. usleep(seconds) - - Waits a number of micro-seconds. This function does exactly the - same as usleep(), but in an asynchronous way. The script - execution is suspended until the waiting is done; then OpenSIPS - resumes the script execution via the resume route. - - To read and understand more on the asynchronous functions, how - to use them and what are their advantages, please refer to the - OpenSIPS online Manual. - - Example 1.28. async usleep usage -{ -... -async( usleep("1000"), after_usleep ); -} - -route[after_usleep] { -... -} - -1.6. Exported MI Functions - -1.6.1. rand_set_prop - - Set the probability value to the given parameter. - - Parameters: - * prob_proc - the parameter should be a percent value (number - from 0 to 99). - - Example 1.29. rand_set_prob usage -... -$ opensips-cli -x mi rand_set_prob 10 -... - -1.6.2. rand_reset_prob - - Reset the probability value to the inital start value. - - This command don't need a parameter. - - Example 1.30. rand_reset_prob usage -... -$ opensips-cli -x mi rand_reset_prob -... - -1.6.3. rand_get_prob - - Return the actual probability setting. - - The function return the actual probability value. - - Example 1.31. rand_get_prob usage -... -$ opensips-cli -x mi get_prob -The actual probability is 50 percent. -... - -1.6.4. check_config_hash - - Check if the actual config file hash is identical to the stored - one. - - The function returns 200 OK if the hash values are identical, - 400 if there are not identical, 404 if no file for hashing has - been configured and 500 on errors. Additional a short text - message is printed. - - Example 1.32. check_config_hash usage -... -$ opensips-cli -x mi check_config_hash -The actual config file hash is identical to the stored one. -... - -1.6.5. get_config_hash - - Return the stored config file hash. - - The function returns 200 OK and the hash value on success or - 404 if no file for hashing has been configured. - - Example 1.33. get_config_hash usage -... -$ opensips-cli -x mi get_config_hash -1580a37104eb4de69ab9f31ce8d6e3e0 -... - -1.6.6. shv_set - - Set the value of a shared variable ($shv(name)). - - Parameters: - * name : shared variable name - * type : type of the value - + “int”: integer value - + “str”: string value - * value : value to be set - - Example 1.34. shv_set usage -... -$ opensips-cli -x mi shv_set debug int 0 -... - -1.6.7. shv_get - - Get the value of a shared variable ($shv(name)). - - Parameters: - * name : shared variable name. If this parameter is missing, - all shared variables are returned. - - Example 1.35. shv_get usage -... -$ opensips-cli -x mi shv_get debug -$ opensips-cli -x mi shv_get -... - -1.7. Exported Pseudo-Variables - -1.7.1. $env(name) - - This PV provides access to the environment variable 'name'. - - Example 1.36. env(name) pseudo-variable usage -... -xlog("PATH environment variable is $env(PATH)\n"); -... - -1.7.2. $RANDOM - - Returns a random value from the [0 - 2^31) range. - - Example 1.37. RANDOM pseudo-variable usage -... -$avp(10) = ($RANDOM / 16777216); # 2^24 -if ($avp(10) < 10) { - $avp(10) = 10; -} -append_to_reply("Retry-After: $avp(10)\n"); -sl_send_reply(503, "Try later"); -exit; -# normal message processing follows - - -1.7.3. $ctime(name) - - The PV provides access to broken-down time attributes. - - The “name” can be: - * sec - return seconds (int 0-59) - * min - return minutes (int 0-59) - * hour - return hours (int 0-23) - * mday - return the day of month (int 0-59) - * mon - return the month (int 1-12) - * year - return the year (int, e.g., 2008) - * wday - return the day of week (int, 1=Sunday - 7=Saturday) - * yday - return the day of year (int, 1-366) - * isdst - return daylight saving time status (int, 0 - DST - off, >0 DST on) - - Example 1.38. ctime(name) pseudo-variable usage -... -if ($ctime(year) == 2008) { - xlog("request: $rm from $fu to $ru in year 2008\n"); -} -... - -1.7.4. $shv(name) - - It is a class of pseudo-variables stored in shared memory. The - value of $shv(name) is visible across all opensips processes. - Each “shv” has single value and it is initialized to integer 0. - You can use “shvset” parameter to initialize the shared - variable. The module exports a set of MI functions to get/set - the value of shared variables. - - Example 1.39. shv(name) pseudo-variable usage -... -modparam("cfgutils", "shvset", "debug=i:1") -... -if ($shv(debug) == 1) { - xlog("request: $rm from $fu to $ru\n"); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 94 44 2966 1512 - 2. Henning Westerholt (@henningw) 30 18 1088 86 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 29 23 462 109 - 4. Vlad Patrascu (@rvlad-patrascu) 21 7 357 548 - 5. Razvan Crainea (@razvancrainea) 20 15 289 79 - 6. Elena-Ramona Modroiu 14 3 1183 7 - 7. Daniel-Constantin Mierla (@miconda) 12 10 84 32 - 8. Maksym Sobolyev (@sobomax) 7 5 24 18 - 9. Anca Vamanu 6 3 220 14 - 10. Ionel Cerghit (@ionel-cerghit) 5 1 18 161 - - All remaining contributors: Vlad Paiu (@vladpaiu), Sergio - Gutierrez, Konstantin Bokarius, Walter Doekes (@wdoekes), Peter - Lemenkov (@lemenkov), Edson Gellert Schubert, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Sep 2012 - May 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Feb 2024 - 4. Maksym Sobolyev (@sobomax) Dec 2015 - Nov 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 6. Razvan Crainea (@razvancrainea) Oct 2010 - Jan 2020 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionel Cerghit (@ionel-cerghit) Dec 2015 - Dec 2015 - 9. Walter Doekes (@wdoekes) Jan 2015 - Jan 2015 - 10. Vlad Paiu (@vladpaiu) Jan 2013 - Jul 2014 - - All remaining contributors: Anca Vamanu, Sergio Gutierrez, - Henning Westerholt (@henningw), Daniel-Constantin Mierla - (@miconda), Elena-Ramona Modroiu, Konstantin Bokarius, Edson - Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter - Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Anca - Vamanu, Sergio Gutierrez, Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Elena-Ramona Modroiu, - Konstantin Bokarius, Edson Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007-2008 1und1 Internet AG - - Copyright © 2007-2008 BASIS AudioNet GmbH - - Copyright © 2007-2008 Elena-Ramona Modroiu diff --git a/modules/cfgutils/README.md b/modules/cfgutils/README.md new file mode 100644 index 00000000000..d406fe5797c --- /dev/null +++ b/modules/cfgutils/README.md @@ -0,0 +1,1070 @@ +--- +title: "cfgutils Module" +description: "Useful extensions for the server configuration." +--- + +## Admin Guide + + +### Overview + + +Useful extensions for the server configuration. + + +The cfgutils module can be used to introduce randomness to +the behaviour of the server. It provides setup functions +and the "rand_event" function. This function return either +true or false, depending on a random value and a specified probability. +E.g. if you set via fifo or script a probability value of 5%, then 5% of +all calls to rand_event will return false. +The pseudovariable "$RANDOM" could be used to introduce +random values e.g. into a SIP reply. + + +The benefit of this module is the probability of the decision +can be manipulated by external applications such as web interface +or command line tools. The probability must be specified as +percent value, ranging from 0 to 100. + + +The module exports commands to FIFO server that can be used to change +the global settings via FIFO interface. The FIFO commands are: +"set_prob", "reset_prob" and +"get_prob". + + +This module can be used for simple load-shedding, e.g. reply 5% of +the Invites with a 503 error and a adequate random Retry-After value. + + +The module provides as well functions to delay the execution of the +server. The functions "sleep" and "usleep" could +be used to let the server wait a specific time interval. + + +It can also hash the config file used from the server with a (weak) +cryptographic hash function on startup. This value is saved and can be +later compared to the actual hash, to detect modifications of this file +after the server start. This functions are available as the FIFO commands +"check_config_hash" and "get_config_hash". + + +### Dependencies + + +The module depends on the following modules (in the other words the +listed modules must be loaded before this module): + + +- *none* + + +### Exported Parameters + + +#### initial_probability (string) + + +The initial value of the probability. + + +*Default value is "10".* + + +```opensips title="initial_probability parameter usage" + +modparam("cfgutils", "initial_probability", 15) + +``` + + +#### hash_file (string) + + +The config file name for that a hash value should be calculated on startup. + + +There is no default value, is no parameter is given the hash functionality +is disabled. + + +```opensips title="hash_file parameter usage" + +modparam("cfgutils", "hash_file", "/etc/opensips/opensips.cfg") + +``` + + +#### shv_hash_size (integer) + + +The size of the hash table used to store the shared variables ($shv). + + +*Default value is "64".* + + +```opensips title="shv_hash_size parameter usage" +modparam("cfgutils", "shv_hash_size", 1024) +``` + + +#### shvset (string) + + +Set the value of a shared variable ($shv(name)). The parameter +can be set many times. + + +The value of the parameter has the format: +_name_ '=' _type_ ':' _value_ + + +- _name_: shared variable name +- _type_: type of the value + + - "i": integer value + - "s": string value +- _value_: value to be set + + +*Default value is "NULL".* + + +```opensips title="shvset parameter usage" +... +modparam("cfgutils", "shvset", "debug=i:1") +modparam("cfgutils", "shvset", "pstngw=s:sip:10.10.10.10") +... +``` + + +#### varset (string) + + +Set the value of a script variable ($var(name)). The parameter +can be set many times. + + +The value of the parameter has the format: +_name_ '=' _type_ ':' _value_ + + +- _name_: shared variable name +- _type_: type of the value + + - "i": integer value + - "s": string value +- _value_: value to be set + + +Default value is "NULL". + + +```opensips title="varset parameter usage" +... +modparam("cfgutils", "varset", "init=i:1") +modparam("cfgutils", "varset", "gw=s:sip:11.11.11.11;transport=tcp") +... +``` + + +#### lock_pool_size (integer) + + +The number of dynamic script locks to be allocated at OpenSIPS startup. This +number must be a power of 2. (i.e. 1, 2, 4, 8, 16, 32, 64 ...) + + +Note that the *lock_pool_size* parameter only affects +the number of dynamic locks created at startup. The pool of static locks +only depends on the number of unique static strings supplied throughout +the script to the set of static lock functions. + + +*Default value is "32".* + + +```opensips title="Setting lock_pool_size module parameter" +modparam("cfgutils", "lock_pool_size", 64) +``` + + +### Exported Functions + + +#### rand_event([probability]) + + +Generates a random floating point value between 0 - 100 and returns +true if the value is less or equal to the currently set probability. +If "probability" parameter is given, it will +override the global parameter set by [rand set prob](#func_rand_set_prob). + + +Parameters: + + +- probability (int, optional) - probability override + + +```opensips title="rand_event() usage" +... +if (rand_event()) { + append_to_reply("Retry-After: 120\n"); + sl_send_reply(503, "Try later"); + exit; +} +# normal message processing follows +... +``` + + +#### rand_set_prob(probability) + + +Set the "probability" of the decision. + + +Parameters: + + +- probability (int) - number ranging from 0 - 99, inclusively + + +```opensips title="rand_set_prob() usage" +... +rand_set_prob(4); +... +``` + + +#### rand_reset_prob() + + +Reset the probability back to the +[initial probability](#param_initial_probability) value. + + +```opensips title="rand_reset_prob() usage" +... +rand_reset_prob(); +... +``` + + +#### rand_get_prob() + + +Return the current probability setting, e.g. for logging purposes. + + +```opensips title="rand_get_prob() usage" +... +rand_get_prob(); + +``` + + +#### sleep(time) + + +Waits "time" seconds. + + +Meaning of the parameters is as follows: + + +- *time (int)* - time to wait in seconds + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="sleep usage" +... +sleep(1); +... +$var(secs) = 10; +sleep($var(secs)); +... + +``` + + +#### usleep(time) + + +Waits "time" micro-seconds. + + +Meaning of the parameters is as follows: + + +- *time (int)* - time to wait in micro-seconds + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="usleep usage" +... +usleep(500000); # sleep half a sec +... + +``` + + +#### abort() + + +Debugging function that aborts the server. Depending on the +configuration of the server a core dump will be created. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="abort usage" +... +abort(); +... + +``` + + +#### pkg_status() + + +Debugging function that dumps the status for the private (PKG) memory. +This information is logged to the default log facility, depending on +the general log level and the memlog setting. You need to compile +the server with activated memory debugging to get detailed informations. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="pkg_status usage" +... +pkg_status(); +... + +``` + + +#### shm_status() + + +Debugging function that dumps the status for the shared (SHM) memory. +This information is logged to the default log facility, depending on +the general log level and the memlog setting. You need to compile +the server with activated memory debugging to get detailed informations. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="shm_status usage" +... +shm_status(); +... + +``` + + +#### set_count(var_to_count, ret_var) + + +Counts the number of values of a given variable. +It makes sense to call this function only for variables that can +take more values (AVPs, headers). + + +The result is returned in the second parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="set_count usage" +... +set_count($avp(dids), $var(num_dids)); +... + +``` + + +#### set_select_weight(int_list_var) + + +This function selects an element from a set formed by the integer +values of the given "int_list_var" variable. It applies the genetic +algorithm - roulette-wheel selection to choose an element from a set. +The probability of selecting a certain element is proportionate with +its weight. It will return the index of that selected element. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="set_select_weight usage" +... +$var(next_gw_idx) = set_select_weight($avp(gw_success_rates)); +... + +``` + + +#### ts_usec_delta(t1_sec, t1_usec, t2_sec, t2_usec, [delta_str], [delta_int]) + + +This function returns the absolute difference between the two given +timestamps. The result is expressed as *microseconds* +and can be returned as either string or integer. + + +**WARNING:** when using +*delta_int*, the function will return error code +**-1** in case the difference overflows +the signed integer holder! (i.e. a diff of ~35 minutes or more) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="ts_usec_delta usage" +... +ts_usec_delta($var(t1s), 300, 10, $var(t2us), $var(diff_str)); +... + +``` + + +#### check_time_rec(time_string, [timestamp]) + + +The function returns a positive value if the specified time recurrence string +matches the current time, or a negative value otherwise. + + +For checking some other Unix timestamp than the current one, the second +parameter will contain the intended timestamp to check. + + +The syntax of each field is identical to the corresponding field from +RFC 2445. + + +This function may be used from any route. It returns 1 on success +and -1, -2 or -3 on failure, parsing or internal errors, respectively. + + +Meaning of the parameters is as follows: + + +- *time_string (string)* - Time recurrence string which +will be matched against the current time. Its fields are separated by "|" and +the order in which they are given is: "timezone | dtstart | dtend | duration | freq +| until | interval | byday | bymday | byyday | byweekno | bymonth". +None of the fields following "freq" is used unless +"freq" is defined. If the string ends in multiple null fields, +they can all be ommited. +The "timezone" field is optional. It represents the timezone in +which to interpret the time recurrence elements (e.g. dtstart, +dtend, until). By default, the system time zone is used. +- *timestamp (string, optional)* - A +specific Unix time to check. The function simply expects the +actual Unix time here, there is no need to perform any timezone +adjustments. + + +Additionally, more complex time recurrence strings may be built by +connecting multiple time recurrence strings (described above) using +the logical AND ("&"), OR ("/") and NEG ("!") operators. +Furthermore, the expressions may be paranthesized. Some examples: + + +- 20210104T080000|20211231T180000||WEEKLY|||MO,TU,WE,TH,FR +& +!20210104T120000|20211231T140000||WEEKLY|||MO,TU,WE,TH,FR +This example multi-recurrence expresses the working days schedule for +company X during 2021: workdays from 8-18, except the 12-14 interval, +when everyone is out for lunch break and the business is closed. +Since the timezone is omitted from each schedule, the operating +system timezone will be used instead. +- America/New_York|20210104T090000|20210104T170000||WEEKLY|||MO,TU,WE,TH,FR +& +!(Europe/Amsterdam|20210427T000000|20210428T000000 / Europe/London|20211227T000000|20211228T000000) +This example multi-recurrence expresses the working days schedule for +US-based company Y during 2021: workdays from 9-17 (NY timezone), +except european holidays such as King's Day (April 27th, NL) or +the Spring Bank Holiday (May 31st, UK), when most of its +workforce will have flown back to Europe. + + +```opensips title="check_time_rec usage" +... +# Only passing if still in 2012 and on a Bucharest-compatible timezone +if (check_time_rec("Europe/Bucharest|20120101T000000|20130101T000000")) + xlog("Current system time matches the given Romanian time interval\n"); +... +# Only passing if less than 30 days have passed from "dtstart", system timezone +if (check_time_rec("20121101T000000||p30d")) + xlog("Current time matches the given interval\n"); +... + +``` + + +#### get_static_lock(key) + + +Acquire the static lock which corresponds to "key". In case the +lock is taken by another process, script execution will halt until the +lock is released. Attempting to acquire the lock a second time by the +same process, without releasing it first, will result in a deadlock. + + +The static lock functions guarantee that two different strings will never +point to the same lock, thus avoiding introducing unnecessary +(and transparent!) synchronization between processes. Their disadvantage is +the nature of their parameters (static strings), making them inappropriate in +certain scenarios. + + +Meaning of the parameters is as follows: + + +- *key (static string)* - key to be hashed in +order to obtain the index of a static lock + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. + + +```opensips title="get_static_lock usage" +# acquire and release a static lock +... +get_static_lock("Zone_1"); +... +release_static_lock("Zone_1"); +... +``` + + +#### release_static_lock(key) + + +Release the static lock corresponding to "key". Nothing will happen if +the lock is not acquired. + + +Meaning of the parameters is as follows: + + +- *key (static string)* - key to be hashed in +order to obtain the index of a static lock. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. + + +```opensips title="release_static_lock usage" +# acquire and release a static lock +... +get_static_lock("Zone_1"); +... +release_static_lock("Zone_1"); +... +``` + + +#### get_dynamic_lock(key) + + +Acquire the dynamic lock corresponding to "key". In case the lock is +taken by another process, script execution will halt until the lock is +released. Attempting to acquire the lock a second time by +the same process, without releasing it first, will result in a deadlock. + + +The dynamic lock functions have the advantage of allowing string +variables to be given as parameters, but the drawback to this is that +two strings may have the same hashed value, thus pointing to the same lock. +As a consequence, either two totally separate regions of the script will be +synchronized (they will not execute in parallel), or a process could end up +in a deadlock by acquiring two locks in a row on two different (but equally +hashed) strings. To address the latter issue, use the +[strings share lock](#func_strings_share_lock) function to test if two +strings hash into the same dynamic lock. + + +Meaning of the parameters is as follows: + + +- *key (var)* - key to be hashed in order to +obtain the index of a dynamic lock from the pool + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. + + +```opensips title="get_dynamic_lock usage" +... +# acquire and release a dynamic lock on the "Call-ID" header field value +if (!get_dynamic_lock($ci)) { + xlog("Error while getting dynamic lock!\n"); +} +... +if (!release_dynamic_lock($ci) { + xlog("Error while releasing dynamic lock!\n"); +} +... +``` + + +#### release_dynamic_lock(key) + + +Release the dynamic lock corresponding to "key". Nothing will happen +if the lock is not acquired. + + +Meaning of the parameters is as follows: + + +- *key (var)* - key to be hashed in order to +obtain the index of a dynamic lock from the pool + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. + + +```opensips title="release_dynamic_lock usage" +... +# acquire and release a dynamic lock on the "Call-ID" header field value +if (!get_dynamic_lock($ci)) { + xlog("Error while getting dynamic lock!\n"); +} +... +if (!release_dynamic_lock($ci) { + xlog("Error while releasing dynamic lock!\n"); +} +... +``` + + +#### strings_share_lock(key1, key2) + + +A function used to test if two strings will generate the same hash value. +Its purpose is to prevent deadlocks resulted when a process successively +acquires two dynamic locks on two strings which happen to point to the same +lock. + + +Theoretically, the chance of two strings generating the same hash value +decreases proportionally to the increase of the +[lock pool size](#param_lock_pool_size) parameter. In +other words, the more dynamic locks you configure the module with, the higher +the chance that all individual protected regions of your script will run in +parallel, without waiting for each other. + + +Meaning of the parameters is as follows: + + +- *key1, key2 (string)* - strings which will have +their hash values compared + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. + + +```opensips title="strings_share_lock usage" +... +# Proper way of acquiring two dynamic locks successively +if (!get_dynamic_lock($avp(foo))) { + xlog("Error while getting dynamic lock!\n"); +} + +if (!strings_share_lock($avp(foo), $avp(bar)) { + if (!get_dynamic_lock($avp(bar))) { + xlog("Error while getting dynamic lock!\n"); + } +} +... +if (!strings_share_lock($avp(foo), $avp(bar)) { + if (!release_dynamic_lock($avp(bar)) { + xlog("Error while releasing dynamic lock!\n"); + } +} + +if (!release_dynamic_lock($avp(foo)) { + xlog("Error while releasing dynamic lock!\n"); +} +... +``` + + +#### get_accurate_time(sec, usec, [str_sec_usec]) + + +Fetch the current Unix time epoch with microsecond precision. +Optionally, print this value as a floating point number (3rd parameter). + + +Meaning of the parameters is as follows: + + +- *sec (int)* - the current Unix timestamp (integer part) +- *usec (int)* - the current Unix timestamp (decimal part) +- *str_sec_usec (string, optional)* - the current Unix +timestamp as a floating point number (6-digit precision) + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. + + +```opensips title="get_accurate_time usage" +... +get_accurate_time($var(sec), $var(usec)); +xlog("Current Unix timestamp: $var(sec) s, $var(usec) us\n"); +... +``` + + +#### shuffle_avps(name) + + +Randomly shuffles AVPs with *name*. + + +Meaning of the parameters is as follows: + + +- *name (variable)* - name of AVP to shuffle. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="shuffle_avps usage" +... +$avp(foo) := "str1"; +$avp(foo) = "str2"; +$avp(foo) = "str3"; +xlog("Initial AVP list is: $(avp(foo)[*])\n"); # str3 str2 str1 +if(shuffle_avps( $avp(foo) )) + xlog("Shuffled AVP list is: $(avp(foo)[*])\n"); # str1, str3, str2 (for example) +... + +``` + + +### Exported Asynchronous Functions + + +#### sleep(seconds) + + +Waits a number of seconds. This function does exactly the same as +[sleep](#func_sleep), +but in an asynchronous way. The script execution is suspended until +the waiting is done; then OpenSIPS resumes the script execution via +the resume route. + + +To read and understand more on the asynchronous functions, how to +use them and what are their advantages, please refer to the OpenSIPS +online Manual. + + +```opensips title="async sleep usage" +{ +... +async( sleep(5), after_sleep ); +} + +route[after_sleep] { +... +} +``` + + +#### usleep(seconds) + + +Waits a number of micro-seconds. This function does exactly the same as +[usleep](#func_usleep), +but in an asynchronous way. The script execution is suspended until +the waiting is done; then OpenSIPS resumes the script execution via +the resume route. + + +To read and understand more on the asynchronous functions, how to +use them and what are their advantages, please refer to the OpenSIPS +online Manual. + + +```opensips title="async usleep usage" +{ +... +async( usleep(1000), after_usleep ); +} + +route[after_usleep] { +... +} +``` + + +### Exported MI Functions + + +#### rand_set_prop + + +Set the probability value to the given parameter. + + +Parameters: + + +- *prob_proc* - the parameter should be +a percent value (number from 0 to 99). + + +```bash title="rand_set_prob usage" +... +$ opensips-cli -x mi rand_set_prob 10 +... +``` + + +#### rand_reset_prob + + +Reset the probability value to the inital start value. + + +This command don't need a parameter. + + +```bash title="rand_reset_prob usage" +... +$ opensips-cli -x mi rand_reset_prob +... +``` + + +#### rand_get_prob + + +Return the actual probability setting. + + +The function return the actual probability value. + + +```bash title="rand_get_prob usage" +... +$ opensips-cli -x mi get_prob +The actual probability is 50 percent. +... +``` + + +#### check_config_hash + + +Check if the actual config file hash is identical to the stored one. + + +The function returns 200 OK if the hash values are identical, 400 if +there are not identical, 404 if no file for hashing has been configured +and 500 on errors. Additional a short text message is printed. + + +```bash title="check_config_hash usage" +... +$ opensips-cli -x mi check_config_hash +The actual config file hash is identical to the stored one. +... +``` + + +#### get_config_hash + + +Return the stored config file hash. + + +The function returns 200 OK and the hash value on success or 404 if no +file for hashing has been configured. + + +```bash title="get_config_hash usage" +... +$ opensips-cli -x mi get_config_hash +1580a37104eb4de69ab9f31ce8d6e3e0 +... +``` + + +#### shv_set + + +Set the value of a shared variable ($shv(name)). + + +Parameters: + + +- *name* : shared variable name +- *type* : type of the value + + - "int": integer value + - "str": string value +- *value* : value to be set + + +```bash title="shv_set usage" +... +$ opensips-cli -x mi shv_set debug int 0 +... +``` + + +#### shv_get + + +Get the value of a shared variable ($shv(name)). + + +Parameters: + + +- *name* : shared variable name. If this parameter +is missing, all shared variables are returned. + + +```bash title="shv_get usage" +... +$ opensips-cli -x mi shv_get debug +$ opensips-cli -x mi shv_get +... +``` + + +### Exported Pseudo-Variables + + +#### $env(name) + + +This PV provides access to the environment variable 'name'. + + +```opensips title="env(name) pseudo-variable usage" +... +xlog("PATH environment variable is $env(PATH)\n"); +... + +``` + + +#### $RANDOM + + +Returns a random value from the [0 - 2^31) range. + + +```opensips title="RANDOM pseudo-variable usage" +... +$avp(10) = ($RANDOM / 16777216); # 2^24 +if ($avp(10) < 10) { + $avp(10) = 10; +} +append_to_reply("Retry-After: $avp(10)\n"); +sl_send_reply(503, "Try later"); +exit; +# normal message processing follows + + +``` + + +#### $ctime(name) + + +The PV provides access to broken-down time attributes. + + +The "name" can be: + + +- *sec* - return seconds (int 0-59) +- *min* - return minutes (int 0-59) +- *hour* - return hours (int 0-23) +- *mday* - return the day of month (int 0-59) +- *mon* - return the month (int 1-12) +- *year* - return the year (int, e.g., 2008) +- *wday* - return the day of week (int, 1=Sunday - 7=Saturday) +- *yday* - return the day of year (int, 1-366) +- *isdst* - return daylight saving time status (int, 0 - DST off, >0 DST on) + + +```opensips title="ctime(name) pseudo-variable usage" +... +if ($ctime(year) == 2008) { + xlog("request: $rm from $fu to $ru in year 2008\n"); +} +... + +``` + + +#### $shv(name) + + +It is a class of pseudo-variables stored in shared memory. The +value of $shv(name) is visible across all opensips processes. +Each "shv" has single value and it is initialized +to integer 0. You can use "shvset" parameter to +initialize the shared variable. The module exports a set of MI +functions to get/set the value of shared variables. + + +```opensips title="shv(name) pseudo-variable usage" +... +modparam("cfgutils", "shvset", "debug=i:1") +... +if ($shv(debug) == 1) { + xlog("request: $rm from $fu to $ru\n"); +} +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cfgutils/doc/cfgutils.xml b/modules/cfgutils/doc/cfgutils.xml deleted file mode 100644 index 1b08d6d86e8..00000000000 --- a/modules/cfgutils/doc/cfgutils.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - cfgutils Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007-2008 1und1 Internet AG - ©right; 2007-2008 BASIS AudioNet GmbH - ©right; 2007-2008 Elena-Ramona Modroiu - - diff --git a/modules/cfgutils/doc/cfgutils_admin.xml b/modules/cfgutils/doc/cfgutils_admin.xml deleted file mode 100644 index 9e65effe64f..00000000000 --- a/modules/cfgutils/doc/cfgutils_admin.xml +++ /dev/null @@ -1,1212 +0,0 @@ - - - - - &adminguide; - -
- Overview - Useful extensions for the server configuration. - - The cfgutils module can be used to introduce randomness to - the behaviour of the server. It provides setup functions - and the rand_event function. This function return either - true or false, depending on a random value and a specified probability. - E.g. if you set via fifo or script a probability value of 5%, then 5% of - all calls to rand_event will return false. - The pseudovariable $RANDOM could be used to introduce - random values e.g. into a SIP reply. - - - The benefit of this module is the probability of the decision - can be manipulated by external applications such as web interface - or command line tools. The probability must be specified as - percent value, ranging from 0 to 100. - - - The module exports commands to FIFO server that can be used to change - the global settings via FIFO interface. The FIFO commands are: - set_prob, reset_prob and - get_prob. - - - This module can be used for simple load-shedding, e.g. reply 5% of - the Invites with a 503 error and a adequate random Retry-After value. - - - The module provides as well functions to delay the execution of the - server. The functions sleep and usleep could - be used to let the server wait a specific time interval. - - It can also hash the config file used from the server with a (weak) - cryptographic hash function on startup. This value is saved and can be - later compared to the actual hash, to detect modifications of this file - after the server start. This functions are available as the FIFO commands - check_config_hash and get_config_hash. - -
-
- Dependencies - - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): - - - none - - - -
-
- Exported Parameters - -
- <varname>initial_probability</varname> (string) - - The initial value of the probability. - - - Default value is - 10. - - - <varname>initial_probability</varname> parameter usage - - -modparam("cfgutils", "initial_probability", 15) - - - -
- -
- <varname>hash_file</varname> (string) - - The config file name for that a hash value should be calculated on startup. - - - There is no default value, is no parameter is given the hash functionality - is disabled. - - - <varname>hash_file</varname> parameter usage - - -modparam("cfgutils", "hash_file", "/etc/opensips/opensips.cfg") - - - -
- -
- <varname>shv_hash_size</varname> (integer) - - The size of the hash table used to store the shared variables ($shv). - - - Default value is 64. - - - <varname>shv_hash_size</varname> parameter usage - - -modparam("cfgutils", "shv_hash_size", 1024) - - - -
- -
- <varname>shvset</varname> (string) - - Set the value of a shared variable ($shv(name)). The parameter - can be set many times. - - - The value of the parameter has the format: - _name_ '=' _type_ ':' _value_ - - - _name_: shared variable name - - _type_: type of the value - - i: integer value - s: string value - - - - _value_: value to be set - - - Default value is NULL. - - - <varname>shvset</varname> parameter usage - -... -modparam("cfgutils", "shvset", "debug=i:1") -modparam("cfgutils", "shvset", "pstngw=s:sip:10.10.10.10") -... - - -
- -
- <varname>varset</varname> (string) - - Set the value of a script variable ($var(name)). The parameter - can be set many times. - - - The value of the parameter has the format: - _name_ '=' _type_ ':' _value_ - - - _name_: shared variable name - - _type_: type of the value - - i: integer value - s: string value - - - - _value_: value to be set - - - Default value is NULL. - - - <varname>varset</varname> parameter usage - -... -modparam("cfgutils", "varset", "init=i:1") -modparam("cfgutils", "varset", "gw=s:sip:11.11.11.11;transport=tcp") -... - - -
- -
- <varname>lock_pool_size</varname> (integer) - - The number of dynamic script locks to be allocated at &osips; startup. This - number must be a power of 2. (i.e. 1, 2, 4, 8, 16, 32, 64 ...) - - - Note that the lock_pool_size parameter only affects - the number of dynamic locks created at startup. The pool of static locks - only depends on the number of unique static strings supplied throughout - the script to the set of static lock functions. - - - Default value is 32. - - - Setting lock_pool_size module parameter - -modparam("cfgutils", "lock_pool_size", 64) - - -
-
- -
- Exported Functions -
- <function moreinfo="none">rand_event([probability])</function> - - Generates a random floating point value between 0 - 100 and returns - true if the value is less or equal to the currently set probability. - If "probability" parameter is given, it will - override the global parameter set by . - - Parameters: - - - probability (int, optional) - probability override - - - - <function moreinfo="none">rand_event()</function> usage - -... -if (rand_event()) { - append_to_reply("Retry-After: 120\n"); - sl_send_reply(503, "Try later"); - exit; -} -# normal message processing follows -... - - -
- -
- <function moreinfo="none">rand_set_prob(probability)</function> - - Set the probability of the decision. - - Parameters: - - - probability (int) - number ranging from 0 - 99, inclusively - - - - <function moreinfo="none">rand_set_prob()</function> usage - -... -rand_set_prob(4); -... - - -
- -
- <function moreinfo="none">rand_reset_prob()</function> - - Reset the probability back to the - value. - - - <function moreinfo="none">rand_reset_prob()</function> usage - -... -rand_reset_prob(); -... - - -
- -
- <function moreinfo="none">rand_get_prob()</function> - - Return the current probability setting, e.g. for logging purposes. - - - <function moreinfo="none">rand_get_prob()</function> usage - -... -rand_get_prob(); - - - -
-
- - <function moreinfo="none">sleep(time)</function> - - - Waits "time" seconds. - - Meaning of the parameters is as follows: - - - time (int) - time to wait in seconds - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>sleep</function> usage - -... -sleep(1); -... -$var(secs) = 10; -sleep($var(secs)); -... - - -
- -
- - <function moreinfo="none">usleep(time)</function> - - - Waits "time" micro-seconds. - - Meaning of the parameters is as follows: - - - time (int) - time to wait in micro-seconds - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>usleep</function> usage - -... -usleep(500000); # sleep half a sec -... - - -
- -
- - <function moreinfo="none">abort()</function> - - - Debugging function that aborts the server. Depending on the - configuration of the server a core dump will be created. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>abort</function> usage - -... -abort(); -... - - -
- -
- - <function moreinfo="none">pkg_status()</function> - - - Debugging function that dumps the status for the private (PKG) memory. - This information is logged to the default log facility, depending on - the general log level and the memlog setting. You need to compile - the server with activated memory debugging to get detailed informations. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>pkg_status</function> usage - -... -pkg_status(); -... - - -
- -
- - <function moreinfo="none">shm_status()</function> - - - Debugging function that dumps the status for the shared (SHM) memory. - This information is logged to the default log facility, depending on - the general log level and the memlog setting. You need to compile - the server with activated memory debugging to get detailed informations. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>shm_status</function> usage - -... -shm_status(); -... - - -
-
- - <function moreinfo="none">set_count(var_to_count, ret_var)</function> - - - Counts the number of values of a given variable. - It makes sense to call this function only for variables that can - take more values (AVPs, headers). - - - The result is returned in the second parameter. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>set_count</function> usage - -... -set_count($avp(dids), $var(num_dids)); -... - - -
-
- - <function moreinfo="none">set_select_weight(int_list_var)</function> - - - This function selects an element from a set formed by the integer - values of the given "int_list_var" variable. It applies the genetic - algorithm - roulette-wheel selection to choose an element from a set. - The probability of selecting a certain element is proportionate with - its weight. It will return the index of that selected element. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>set_select_weight</function> usage - -... -$var(next_gw_idx) = set_select_weight($avp(gw_success_rates)); -... - - -
-
- - <function moreinfo="none">ts_usec_delta(t1_sec, t1_usec, t2_sec, t2_usec, [delta_str], [delta_int])</function> - - - This function returns the absolute difference between the two given - timestamps. The result is expressed as microseconds - and can be returned as either string or integer. - - - WARNING: when using - delta_int, the function will return error code - -1 in case the difference overflows - the signed integer holder! (i.e. a diff of ~35 minutes or more) - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>ts_usec_delta</function> usage - -... -ts_usec_delta($var(t1s), 300, 10, $var(t2us), $var(diff_str)); -... - - -
-
- - <function moreinfo="none">check_time_rec(time_string, [timestamp])</function> - - - The function returns a positive value if the specified time recurrence string - matches the current time, or a negative value otherwise. - - - For checking some other Unix timestamp than the current one, the second - parameter will contain the intended timestamp to check. - - - The syntax of each field is identical to the corresponding field from - RFC 2445. - - - This function may be used from any route. It returns 1 on success - and -1, -2 or -3 on failure, parsing or internal errors, respectively. - - Meaning of the parameters is as follows: - - - time_string (string) - Time recurrence string which - will be matched against the current time. Its fields are separated by "|" and - the order in which they are given is: "timezone | dtstart | dtend | duration | freq - | until | interval | byday | bymday | byyday | byweekno | bymonth". - None of the fields following "freq" is used unless - "freq" is defined. If the string ends in multiple null fields, - they can all be ommited. - - The "timezone" field is optional. It represents the timezone in - which to interpret the time recurrence elements (e.g. dtstart, - dtend, until). By default, the system time zone is used. - - - - timestamp (string, optional) - A - specific Unix time to check. The function simply expects the - actual Unix time here, there is no need to perform any timezone - adjustments. - - - - - Additionally, more complex time recurrence strings may be built by - connecting multiple time recurrence strings (described above) using - the logical AND ("&"), OR ("/") and NEG ("!") operators. - Furthermore, the expressions may be paranthesized. Some examples: - - - - - 20210104T080000|20211231T180000||WEEKLY|||MO,TU,WE,TH,FR - & - !20210104T120000|20211231T140000||WEEKLY|||MO,TU,WE,TH,FR - - - This example multi-recurrence expresses the working days schedule for - company X during 2021: workdays from 8-18, except the 12-14 interval, - when everyone is out for lunch break and the business is closed. - Since the timezone is omitted from each schedule, the operating - system timezone will be used instead. - - - - - America/New_York|20210104T090000|20210104T170000||WEEKLY|||MO,TU,WE,TH,FR - & - !(Europe/Amsterdam|20210427T000000|20210428T000000 / Europe/London|20211227T000000|20211228T000000) - - - This example multi-recurrence expresses the working days schedule for - US-based company Y during 2021: workdays from 9-17 (NY timezone), - except european holidays such as King's Day (April 27th, NL) or - the Spring Bank Holiday (May 31st, UK), when most of its - workforce will have flown back to Europe. - - - - - <function>check_time_rec</function> usage - -... -# Only passing if still in 2012 and on a Bucharest-compatible timezone -if (check_time_rec("Europe/Bucharest|20120101T000000|20130101T000000")) - xlog("Current system time matches the given Romanian time interval\n"); -... -# Only passing if less than 30 days have passed from "dtstart", system timezone -if (check_time_rec("20121101T000000||p30d")) - xlog("Current time matches the given interval\n"); -... - - -
-
- - <function moreinfo="none">get_static_lock(key)</function> - - - Acquire the static lock which corresponds to "key". In case the - lock is taken by another process, script execution will halt until the - lock is released. Attempting to acquire the lock a second time by the - same process, without releasing it first, will result in a deadlock. - - - The static lock functions guarantee that two different strings will never - point to the same lock, thus avoiding introducing unnecessary - (and transparent!) synchronization between processes. Their disadvantage is - the nature of their parameters (static strings), making them inappropriate in - certain scenarios. - - Meaning of the parameters is as follows: - - - key (static string) - key to be hashed in - order to obtain the index of a static lock - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. - - - <function moreinfo="none">get_static_lock</function> usage - -# acquire and release a static lock -... -get_static_lock("Zone_1"); -... -release_static_lock("Zone_1"); -... - - -
-
- - <function moreinfo="none">release_static_lock(key)</function> - - - Release the static lock corresponding to "key". Nothing will happen if - the lock is not acquired. - - Meaning of the parameters is as follows: - - - key (static string) - key to be hashed in - order to obtain the index of a static lock. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. - - - <function moreinfo="none">release_static_lock</function> usage - -# acquire and release a static lock -... -get_static_lock("Zone_1"); -... -release_static_lock("Zone_1"); -... - - -
-
- - <function moreinfo="none">get_dynamic_lock(key)</function> - - - Acquire the dynamic lock corresponding to "key". In case the lock is - taken by another process, script execution will halt until the lock is - released. Attempting to acquire the lock a second time by - the same process, without releasing it first, will result in a deadlock. - - - The dynamic lock functions have the advantage of allowing string - variables to be given as parameters, but the drawback to this is that - two strings may have the same hashed value, thus pointing to the same lock. - As a consequence, either two totally separate regions of the script will be - synchronized (they will not execute in parallel), or a process could end up - in a deadlock by acquiring two locks in a row on two different (but equally - hashed) strings. To address the latter issue, use the - function to test if two - strings hash into the same dynamic lock. - - Meaning of the parameters is as follows: - - - key (var) - key to be hashed in order to - obtain the index of a dynamic lock from the pool - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. - - - <function moreinfo="none">get_dynamic_lock</function> usage - -... -# acquire and release a dynamic lock on the "Call-ID" header field value -if (!get_dynamic_lock($ci)) { - xlog("Error while getting dynamic lock!\n"); -} -... -if (!release_dynamic_lock($ci) { - xlog("Error while releasing dynamic lock!\n"); -} -... - - -
-
- - <function moreinfo="none">release_dynamic_lock(key)</function> - - - Release the dynamic lock corresponding to "key". Nothing will happen - if the lock is not acquired. - - Meaning of the parameters is as follows: - - - key (var) - key to be hashed in order to - obtain the index of a dynamic lock from the pool - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. - - - <function moreinfo="none">release_dynamic_lock</function> usage - -... -# acquire and release a dynamic lock on the "Call-ID" header field value -if (!get_dynamic_lock($ci)) { - xlog("Error while getting dynamic lock!\n"); -} -... -if (!release_dynamic_lock($ci) { - xlog("Error while releasing dynamic lock!\n"); -} -... - - -
-
- - <function moreinfo="none">strings_share_lock(key1, key2)</function> - - - A function used to test if two strings will generate the same hash value. - Its purpose is to prevent deadlocks resulted when a process successively - acquires two dynamic locks on two strings which happen to point to the same - lock. - - - Theoretically, the chance of two strings generating the same hash value - decreases proportionally to the increase of the - parameter. In - other words, the more dynamic locks you configure the module with, the higher - the chance that all individual protected regions of your script will run in - parallel, without waiting for each other. - - Meaning of the parameters is as follows: - - - key1, key2 (string) - strings which will have - their hash values compared - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE|EVENT_ROUTE. - - - <function moreinfo="none">strings_share_lock</function> usage - -... -# Proper way of acquiring two dynamic locks successively -if (!get_dynamic_lock($avp(foo))) { - xlog("Error while getting dynamic lock!\n"); -} - -if (!strings_share_lock($avp(foo), $avp(bar)) { - if (!get_dynamic_lock($avp(bar))) { - xlog("Error while getting dynamic lock!\n"); - } -} -... -if (!strings_share_lock($avp(foo), $avp(bar)) { - if (!release_dynamic_lock($avp(bar)) { - xlog("Error while releasing dynamic lock!\n"); - } -} - -if (!release_dynamic_lock($avp(foo)) { - xlog("Error while releasing dynamic lock!\n"); -} -... - - -
- -
- - <function moreinfo="none">get_accurate_time(sec, usec, [str_sec_usec])</function> - - - Fetch the current Unix time epoch with microsecond precision. - Optionally, print this value as a floating point number (3rd parameter). - - Meaning of the parameters is as follows: - - - sec (int) - the current Unix timestamp (integer part) - - - - usec (int) - the current Unix timestamp (decimal part) - - - - str_sec_usec (string, optional) - the current Unix - timestamp as a floating point number (6-digit precision) - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. - - - <function moreinfo="none">get_accurate_time</function> usage - -... -get_accurate_time($var(sec), $var(usec)); -xlog("Current Unix timestamp: $var(sec) s, $var(usec) us\n"); -... - - -
- -
- - <function moreinfo="none">shuffle_avps(name) - </function> - - - Randomly shuffles AVPs with name. - - Meaning of the parameters is as follows: - - - name (variable) - name of AVP to shuffle. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - <function>shuffle_avps</function> usage - -... -$avp(foo) := "str1"; -$avp(foo) = "str2"; -$avp(foo) = "str3"; -xlog("Initial AVP list is: $(avp(foo)[*])\n"); # str3 str2 str1 -if(shuffle_avps( $avp(foo) )) - xlog("Shuffled AVP list is: $(avp(foo)[*])\n"); # str1, str3, str2 (for example) -... - - -
-
- -
- Exported Asyncronous Functions -
- - <function moreinfo="none">sleep(seconds)</function> - - - Waits a number of seconds. This function does exactly the same as - , - but in an asynchronous way. The script execution is suspended until - the waiting is done; then OpenSIPS resumes the script execution via - the resume route. - - - To read and understand more on the asynchronous functions, how to - use them and what are their advantages, please refer to the OpenSIPS - online Manual. - - - <function moreinfo="none">async sleep</function> usage - -{ -... -async( sleep("5"), after_sleep ); -} - -route[after_sleep] { -... -} - - -
- -
- - <function moreinfo="none">usleep(seconds)</function> - - - Waits a number of micro-seconds. This function does exactly the same as - , - but in an asynchronous way. The script execution is suspended until - the waiting is done; then OpenSIPS resumes the script execution via - the resume route. - - - To read and understand more on the asynchronous functions, how to - use them and what are their advantages, please refer to the OpenSIPS - online Manual. - - - <function moreinfo="none">async usleep</function> usage - -{ -... -async( usleep("1000"), after_usleep ); -} - -route[after_usleep] { -... -} - - -
- -
- -
- Exported MI Functions -
- <function moreinfo="none">rand_set_prop</function> - - Set the probability value to the given parameter. - - Parameters: - - - prob_proc - the parameter should be - a percent value (number from 0 to 99). - - - - <function moreinfo="none">rand_set_prob</function> usage - -... -$ opensips-cli -x mi rand_set_prob 10 -... - - - -
-
- <function moreinfo="none">rand_reset_prob</function> - - Reset the probability value to the inital start value. - - - This command don't need a parameter. - - - - <function moreinfo="none">rand_reset_prob</function> usage - -... -$ opensips-cli -x mi rand_reset_prob -... - - -
-
- <function moreinfo="none">rand_get_prob</function> - - Return the actual probability setting. - - - The function return the actual probability value. - - - <function moreinfo="none">rand_get_prob</function> usage - -... -$ opensips-cli -x mi get_prob -The actual probability is 50 percent. -... - - -
-
- <function moreinfo="none">check_config_hash</function> - - Check if the actual config file hash is identical to the stored one. - - - The function returns 200 OK if the hash values are identical, 400 if - there are not identical, 404 if no file for hashing has been configured - and 500 on errors. Additional a short text message is printed. - - - <function moreinfo="none">check_config_hash</function> usage - -... -$ opensips-cli -x mi check_config_hash -The actual config file hash is identical to the stored one. -... - - -
-
- <function moreinfo="none">get_config_hash</function> - - Return the stored config file hash. - - - The function returns 200 OK and the hash value on success or 404 if no - file for hashing has been configured. - - - <function moreinfo="none">get_config_hash</function> usage - -... -$ opensips-cli -x mi get_config_hash -1580a37104eb4de69ab9f31ce8d6e3e0 -... - - -
-
- <function moreinfo="none">shv_set</function> - - Set the value of a shared variable ($shv(name)). - - Parameters: - - name : shared variable name - - type : type of the value - - int: integer value - str: string value - - - - value : value to be set - - - <function moreinfo="none">shv_set</function> usage - -... -$ opensips-cli -x mi shv_set debug int 0 -... - - -
-
- <function moreinfo="none">shv_get</function> - - Get the value of a shared variable ($shv(name)). - - Parameters: - - name : shared variable name. If this parameter - is missing, all shared variables are returned. - - - <function moreinfo="none">shv_get</function> usage - -... -$ opensips-cli -x mi shv_get debug -$ opensips-cli -x mi shv_get -... - - -
-
- -
- Exported Pseudo-Variables -
- <varname>$env(name)</varname> - - This PV provides access to the environment variable 'name'. - - - <function moreinfo="none">env(name) pseudo-variable</function> usage - -... -xlog("PATH environment variable is $env(PATH)\n"); -... - - -
-
- <varname>$RANDOM</varname> - - Returns a random value from the [0 - 2^31) range. - - - <function moreinfo="none">RANDOM pseudo-variable</function> usage - -... -$avp(10) = ($RANDOM / 16777216); # 2^24 -if ($avp(10) < 10) { - $avp(10) = 10; -} -append_to_reply("Retry-After: $avp(10)\n"); -sl_send_reply(503, "Try later"); -exit; -# normal message processing follows - - - -
-
- <varname>$ctime(name)</varname> - - The PV provides access to broken-down time attributes. - - - The name can be: - - - - sec - return seconds (int 0-59) - - - min - return minutes (int 0-59) - - - hour - return hours (int 0-23) - - - mday - return the day of month (int 0-59) - - - mon - return the month (int 1-12) - - - year - return the year (int, e.g., 2008) - - - wday - return the day of week (int, 1=Sunday - 7=Saturday) - - - yday - return the day of year (int, 1-366) - - - isdst - return daylight saving time status (int, 0 - DST off, >0 DST on) - - - - <function moreinfo="none">ctime(name) pseudo-variable</function> usage - -... -if ($ctime(year) == 2008) { - xlog("request: $rm from $fu to $ru in year 2008\n"); -} -... - - -
-
- <varname>$shv(name)</varname> - - It is a class of pseudo-variables stored in shared memory. The - value of $shv(name) is visible across all opensips processes. - Each shv has single value and it is initialized - to integer 0. You can use shvset parameter to - initialize the shared variable. The module exports a set of MI - functions to get/set the value of shared variables. - - - <function moreinfo="none">shv(name) pseudo-variable</function> usage - -... -modparam("cfgutils", "shvset", "debug=i:1") -... -if ($shv(debug) == 1) { - xlog("request: $rm from $fu to $ru\n"); -} -... - - -
-
-
- diff --git a/modules/cfgutils/doc/contributors.xml b/modules/cfgutils/doc/contributors.xml deleted file mode 100644 index 08b45b8f8b3..00000000000 --- a/modules/cfgutils/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 94 - 44 - 2966 - 1512 - - - 2. - Henning Westerholt (@henningw) - 30 - 18 - 1088 - 86 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 29 - 23 - 462 - 109 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 21 - 7 - 357 - 548 - - - 5. - Razvan Crainea (@razvancrainea) - 20 - 15 - 289 - 79 - - - 6. - Elena-Ramona Modroiu - 14 - 3 - 1183 - 7 - - - 7. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 84 - 32 - - - 8. - Maksym Sobolyev (@sobomax) - 7 - 5 - 24 - 18 - - - 9. - Anca Vamanu - 6 - 3 - 220 - 14 - - - 10. - Ionel Cerghit (@ionel-cerghit) - 5 - 1 - 18 - 161 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Sergio Gutierrez, Konstantin Bokarius, Walter Doekes (@wdoekes), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Sep 2012 - May 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Feb 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Dec 2015 - Nov 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 6. - Razvan Crainea (@razvancrainea) - Oct 2010 - Jan 2020 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionel Cerghit (@ionel-cerghit) - Dec 2015 - Dec 2015 - - - 9. - Walter Doekes (@wdoekes) - Jan 2015 - Jan 2015 - - - 10. - Vlad Paiu (@vladpaiu) - Jan 2013 - Jul 2014 - - - -
-All remaining contributors: Anca Vamanu, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Elena-Ramona Modroiu, Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Anca Vamanu, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Elena-Ramona Modroiu, Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/cfgutils/shvar.c b/modules/cfgutils/shvar.c index ca871a86b50..0380b6a8128 100644 --- a/modules/cfgutils/shvar.c +++ b/modules/cfgutils/shvar.c @@ -314,6 +314,7 @@ int pv_get_shvar(struct sip_msg *msg, pv_param_t *param, return pv_get_null(msg, param, res); } + param->pvv_flags = PV_PARAM_PVV_SHM; memcpy(param->pvv.s, shv->v.value.s.s, shv->v.value.s.len); param->pvv.len = shv->v.value.s.len; param->pvv.s[param->pvv.len] = '\0'; diff --git a/modules/cgrates/README b/modules/cgrates/README deleted file mode 100644 index 47f615ffd91..00000000000 --- a/modules/cgrates/README +++ /dev/null @@ -1,771 +0,0 @@ -CGRateS Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Authorization - 1.3. Accounting - 1.4. Other Commands - 1.5. CGRateS Failover - 1.6. CGRateS Compatibility - 1.7. Dependencies - - 1.7.1. OpenSIPS Modules - 1.7.2. External Libraries or Applications - - 1.8. Exported Parameters - - 1.8.1. cgrates_engine (string) - 1.8.2. bind_ip (string) - 1.8.3. max_async_connections (integer) - 1.8.4. retry_timeout (integer) - 1.8.5. compat_mode (integer) - - 1.9. Exported Functions - - 1.9.1. cgrates_acc([flags[, account[, destination[, - session]]]]) - - 1.9.2. cgrates_auth([account[, destination[, - session]]]) - - 1.9.3. cgrates_cmd(command[, session]) - - 1.10. Exported Pseudo-Variables - - 1.10.1. $cgr(name) / $(cgr(name)[session]) - 1.10.2. $cgr_opt(name) / $(cgr_opt(name)[session]) - 1.10.3. $cgr_ret(name) - - 1.11. Exported Asynchronous Functions - - 1.11.1. cgrates_auth([account[, destination[, - session]]]) - - 1.11.2. cgrates_cmd(command[, session]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cgrates_engine parameter - 1.2. Set bind_ip parameter - 1.3. Set max_async_connections parameter - 1.4. Set retry_timeout parameter - 1.5. Set compat_mode parameter - 1.6. cgrates_acc() usage - 1.7. cgrates_auth() usage - 1.8. cgrates_auth() usage with attributes parsing - 1.9. cgrates_cmd() usage - 1.10. $cgr(name) simple usage - 1.11. $cgr(name) multiple sessions usage - 1.12. $cgr_opt(name) usage - 1.13. $cgr_ret(name) usage - 1.14. async cgrates_auth usage - 1.15. async cgrates_cmd compat_mode usage - 1.16. async cgrates_cmd new usage - -Chapter 1. Admin Guide - -1.1. Overview - - CGRateS is an open-source rating engine used for carrier-grade, - multi-tenant, real-time billing. It is able to do both postpaid - and prepaid rating for multiple concurrent sessions - with different balance units (eg: Monetary, SMS, Internet - Traffic). CGRateS can also export accurate CDRs in various - formats. - - This module can be used to communicate with the CGRates engine - in order to do call authorization and accounting for billing - purposes. The OpenSIPS module does not do any billing by - itself, but provides an interface to communicate with the - CGRateS engine using efficient JSON-RPC APIs in both - synchronous and asynchronous ways. For each command the user - can provide a set of parameters that will be forwarded to the - CGRateS engine, using the $cgr() variable. You can find usage - examples in the following sections. - - The module also has support for multiple parallel billing - sessions to CGRateS. This can be useful in scenarios that - involve complex billing logic, such as double billing (both - customer and carrier billing), or multi-leg calls - (serial/parallel forking). Each billing session is independent - and has a specific tag that can be use throughout the call - lifetime. - - The module can be used to implement the following features: - -1.2. Authorization - - The authorization is used to check if an account is allowed to - start a new call and it has enough credit to call to that - destination. This is done using the cgrates_auth() command, - which returns the number of seconds a call is allowed to run in - the $cgr_ret pseudo-variable. - - Usage example: - ... - if (cgrates_auth("$fU", "$rU")) - xlog("Call is allowed to run $cgr_ret seconds\n" -); - } - ... - -1.3. Accounting - - The accounting mode is used to start and stop a CGRateS - session. This can be used for both prepaid and postpaid - billing. The cgrates_acc() function starts the CGRateS session - when the call is answered (the 200 OK message is received) and - ends it when the call is ended (a BYE message is received). - This is done automatically using the dialog module. - - Note that it is important to first authorize the call (using - the cgrates_auth() command) before starting accounting. If you - do not do this and the user is not authorized to call, the - dialog will be immediately closed, resulting in a 0-duration - call. If the call is allowed to go on, the dialog lifetime will - be set to the duration indicated by the CGRateS engine. - Therefore, the dialog will be automatically ended if the call - would have been longer. - - After the call is ended (by a BYE message), the CGRateS session - is also ended. At this point, you can generate a CDR. To do - this, you have to set the cdr flag to the cgrates_acc() - command. CDRs can also be generated for missed calls by using - the missed flag. - - Usage example: - ... - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - xlog("Call is allowed to run $cgr_ret seconds\n"); - # do accounting for this call - cgrates_acc("cdr", "$fU", "$rU"); - ... - - Note that when using the cdr flag, CDRs are exported by the - CGRateS engine in various formats, not by OpenSIPS. Check the - CGRateS documentation for more information. - -1.4. Other Commands - - You can use the cgrates_cmd() to send arbitrary commands to the - CGRateS engine, and use the $cgr_ret pseudo-variable to - retrieve the response. - - The following example simulates the cgrates_auth() CGRateS - call: - ... - $cgr_opt(Tenant) = $fd; # or $cgr(Tenant) = $fd; /* in c -ompat mode */ - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - cgrates_cmd("SessionSv1.AuthorizeEvent"); - xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\ -n"); - ... - -1.5. CGRateS Failover - - Multiple CGRateS engines can be provisioned to use in a - failover manner: in case one engine is down, the next one is - used. Currently there is no load balancing logic between the - servers, but this is a feature one of the CGRateS component - does starting with newer versions. - - Each CGRateS engine has assigned up to max_async_connections - connections, plus one used for synchronous commands. If a - connection fails (due to network issues, or server issues), it - is marked as closed and a new one is tried. If all connections - to that engine are down, then the entire engine is marked as - disabled, and a new engine is queried. After an engine is down - for more than retry_timeout seconds, OpenSIPS tries to connect - once again to that server. If it succeeds, that server is - enabled. Otherwise, the other engines are used, until none is - available and the command fails. - -1.6. CGRateS Compatibility - - The module supports two different versions of CGRateS: the - compat_mode one, which works with pre-rc8 releases, and a new - one which works with the post-rc8 releases. The difference - between the two versions consist in the way the requests and - responses to and from CGRateS are built. In the - non-compat_mode/new version, a new variable, $cgr_opt(), is - available, and can be used to tune the request options. This - variable should not be used in compat_mode mode to avoid - abiguities, but if it is used, it behaves exactly as $cgr(). By - default compat_mode is disabled. - -1.7. Dependencies - -1.7.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog -- in case CGRateS accounting is used. - -1.7.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libjson - -1.8. Exported Parameters - -1.8.1. cgrates_engine (string) - - This parameter is used to specify a CGRateS engine connection. - The format is IP[:port]. The port is optional, and if missing, - 2014 is used. - - This parameter can have multiple values, for each server used - for failover. At least one server should be provisioned. - - Default value is “None”. - - Example 1.1. Set cgrates_engine parameter -... -modparam("cgrates", "cgrates_engine", "127.0.0.1") -modparam("cgrates", "cgrates_engine", "127.0.0.1:2013") -... - -1.8.2. bind_ip (string) - - IP used to bind the socket that communicates with the CGRateS - engines. This is useful to set when the engine is runing in a - local, secure LAN, and you want to use that network to - communicate with your servers. The parameter is optional. - - Default value is “not set - any IP is used”. - - Example 1.2. Set bind_ip parameter -... -modparam("cgrates", "bind_ip", "10.0.0.100") -... - -1.8.3. max_async_connections (integer) - - The maximum number of simultaneous asynchronous connections to - a CGRateS engine. - - Default value is “10”. - - Example 1.3. Set max_async_connections parameter -... -modparam("cgrates", "max_async_connections", 20) -... - -1.8.4. retry_timeout (integer) - - The number of seconds after which a disabled connection/engine - is retried. - - Default value is “60”. - - Example 1.4. Set retry_timeout parameter -... -modparam("cgrates", "retry_timeout", 120) -... - -1.8.5. compat_mode (integer) - - Indicates whether OpenSIPS should use the old (compat_mode) - CGRateS version API (pre-rc8). - - Default value is “false (0)”. - - Example 1.5. Set compat_mode parameter -... -modparam("cgrates", "compat_mode", 1) -... - -1.9. Exported Functions - -1.9.1. cgrates_acc([flags[, account[, destination[, session]]]]) - - cgrates_acc() starts an accounting session on the CGRateS - engine for the current dialog. It also ends the session when - the dialog is ended. This function requires a dialog, so in - case create_dialog() was not previously used, it will - internally call that function. - - Note that the cgrates_acc() function does not send any message - to the CGRateS engine when it is called, but only when the call - is answered and the CGRateS session should be started (a 200 OK - message is received). - - When called in REQUEST_ROUTE or FAILURE_ROUTE, accounting for - this session is done for all the branches created. When called - in BRANCH_ROUTE or ONREPLY_ROUTE, acccounting is done only if - that branch is successful (terminates with a 2xx reply code). - - The cgrates_acc() function should only be called on initial - INVITEs. For more infirmation check Section 1.3, “Accounting”. - - Meaning of the parameters is as follows: - * flags (string, optional) - indicates whether OpenSIPS - should generate a CDR at the end of the call. If the - parameter is missing, no CDR is generated - the session is - only passed through CGRateS. The following values can be - used, separated by '|': - + cdr - also generate a CDR; - + missed - generate a CDR even for missed calls; this - flag only makes sense if the cdr flag is used; - * account (string, optional) - the account that will be - charged in CGrateS. If not specified, the user in the From - header is used. - * destination (string, optional) - the dialled number. If not - present the request URI user is used. - * session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. - This parameter indicates what set of data from the $cgr() - variable should be considered. If missing, the default set - is used. - - The function can return the following values: - * 1 - successful call - the CGRateS accouting was - successfully setup for the call. - * -1 - OpenSIPS returned an internal error (i.e. the dialog - cannot be created, or the server is out of memory). - * -2 - the SIP message is invalid: either it has missing - headers, or it is not an initial INVITE. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.6. cgrates_acc() usage - ... - if (!has_totag()) { - ... - if (cgrates_auth($fU, $rU)) - cgrates_acc("cdr|missed", $fU, $rU); - ... - } - ... - -1.9.2. cgrates_auth([account[, destination[, session]]]) - - cgrates_auth() does call authorization through using the - CGRateS engine. - - Meaning of the parameters is as follows: - * account (string, optional) - the account that will be - checked in CGrateS. If not specified, the user in the From - header is used. - * destination (string, optional) - the dialled number. If not - present the request URI user is used. - * session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. - This parameter indicates what set of data from the $cgr() - variable should be considered. If missing, the default set - is used. - - The function can return the following values: - * 1 - successful call - the CGRateS account is allowed to - make the call. - * -1 - OpenSIPS returned an internal error (i.e. server is - out of memory). - * -2 - the CGRateS engine returned error. - * -3 - No suitable CGRateS server found. message type (not an - initial INVITE). - * -4 - the SIP message is invalid: either it has missing - headers, or it is not an initial INVITE. - * -5 - CGRateS returned an invalid message. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.7. cgrates_auth() usage - ... - if (!has_totag()) { - ... - if (!cgrates_auth($fU, $rU)) { - sl_send_reply(403, "Forbidden"); - exit; - } - ... - } - ... - - Example 1.8. cgrates_auth() usage with attributes parsing - ... - if (!has_totag()) { - ... - $cgr_opt(GetAttributes) = 1; - if (!cgrates_auth($fU, $rU)) { - sl_send_reply(403, "Forbidden"); - exit; - } - # move attributes from AttributesDigest variable - to plain AVPs - $var(idx) = 0; - while ($(cgr_ret(AttributesDigest){s.select,$var -(idx),,}) != NULL) { - $avp($(cgr_ret(AttributesDigest){s.selec -t,$var(idx),,}{s.select,0,:})) - = $(cgr_ret(AttributesDigest){s. -select,$var(idx),,}{s.select,1,:}); - $var(idx) = $var(idx) + 1; - } - ... - } - ... - -1.9.3. cgrates_cmd(command[, session]) - - cgrates_cmd() can send arbitrary commands to the CGRateS - engine. - - Meaning of the parameters is as follows: - * command (string) - the command sent to the CGRateS engine. - * session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. - This parameter indicates what set of data from the $cgr() - variable should be considered. If missing, the default set - is used. - - The function can return the following values: - * 1 - successful call - the CGRateS account is allowed to - make the call. - * -1 - OpenSIPS returned an internal error (i.e. server is - out of memory). - * -2 - the CGRateS engine returned error. - * -3 - No suitable CGRateS server found. message type (not an - initial INVITE). - - This function can be used from any route. - - Example 1.9. cgrates_cmd() usage - ... - # cgrates_auth($fU, $rU); simulation - $cgr_opt(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - cgrates_cmd("SessionSv1.AuthorizeEvent"); - xlog("Call is allowed to run $cgr_ret seconds\n"); - ... - -1.10. Exported Pseudo-Variables - -1.10.1. $cgr(name) / $(cgr(name)[session]) - - Pseudo-variable used to set different parameters for the - CGRateS command. Each name-value pair will be encoded as a - string - value attribute in the JSON message sent to CGRateS. - - The name-values pairs are stored in the transaction (if tm - module is loaded). Therefore the values are accessible in the - reply. - - When the cgrates_acc() function is called, all the name-value - pairs are moved in the dialog. Therefore the values will be - accessible along the dialog's lifetime. - - This variable consists of serveral sets of name-value pairs. - Each set corresponds to a session. The variable can be indexed - by a session tag. The sets are completely indepdendent from one - another. if the session tag does not exist, the default (no - name) one is used. - - When assigned with the := operator, the value is treated as a - JSON, rather than a string/integer. However, the evaluation of - the JSON is late, therefore when the CGRateS request is built, - if the module is unable to parse the JSON, the value is sent as - a string. - - Example 1.10. $cgr(name) simple usage - ... - if (!has_totag()) { - ... - $cgr_opt(Tenant) = $fd; # set the From domain as - a tenant - $cgr(RequestType) = "*prepaid"; # do prepaid acc -ounting - $cgr(AttributeIDs) := '["+5551234"]'; # treat as - array - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - } - ... - - Example 1.11. $cgr(name) multiple sessions usage - ... - if (!has_totag()) { - ... - # first session - authorize the user - $cgr_opt(Tenant) = $fd; # set the From domain as - a tenant - $cgr(RequestType) = "*prepaid"; # do prepaid acc -ounting - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - - # second session - authorize the carrier - $(cgr_opt(Tenant)[carrier]) = $td; - $(cgr(RequestType)[carrier]) = "*postpaid"; - if (!cgrates_auth("$tU", "$fU", "carrier")) { - # use a different carrier - return; - } - - # if everything is successful start accounting o -n both - cgrates_acc("cdr", "$fU", "rU"); - cgrates_acc("cdr", "$tU", "$fU", "carrier"); - } - ... - -1.10.2. $cgr_opt(name) / $(cgr_opt(name)[session]) - - Used to tune the request parameter of a CGRateS request when - used in non-compat_mode. - - Note: for all request options integer values act as boolean - values: 0 disables the feature and 1(or different than 0 value) - enables it. String variables are passed just as they are set. - - Possible values at the time the documentation was written: - * Tenant - tune CGRateS Tenant. - * GetAttributes - requests the account attributes from the - CGRateS DB. - * GetMaxUsage - request the maximum time the call is allowed - to run. - * GetSuppliers - request an array with all the suppliers for - that can terminate that call. - - Example 1.12. $cgr_opt(name) usage - ... - $cgr_opt(Tenant) = "cgrates.org"; - $cgr_opt(GetMaxUsage) = 1; # also retrieve the max usage - if (!cgrates_auth("$fU", "$rU")) { - # call rejected - } - ... - -1.10.3. $cgr_ret(name) - - Returns the reply message of a CGRateS command in script, or - when used in the non-compat mode, one of the objects within the - reply. - - Example 1.13. $cgr_ret(name) usage - ... - cgrates_auth("$fU", "$rU"); - - # in compat mode - xlog("Call is allowed to run $cgr_ret seconds\n"); - - # in non-compat mode - xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\ -n"); - ... - -1.11. Exported Asynchronous Functions - -1.11.1. cgrates_auth([account[, destination[, session]]]) - - Does the CGRateS authorization call in an asynchronous way. - Script execution is suspended until the CGRateS engine sends - the reply back. - - Meaning of the parameters is as follows: - * account - the account that will be checked in CGRateS. This - parameter is optional, and if not specified, the user in - the From header is used. - * destination - the dialled number. Optional parameter, if - not present the request URI user is used. - * session - the tag of the session that will be started if - the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable should - be considered. If missing, the default set is used. - - The function can return the following values: - * 1 - successful call - the CGRateS account is allowed to - make the call. - * -1 - OpenSIPS returned an internal error (i.e. server is - out of memory). - * -2 - the CGRateS engine returned error. - * -3 - No suitable CGRateS server found. message type (not an - initial INVITE). - * -4 - the SIP message is invalid: either it has missing - headers, or it is not an initial INVITE. - * -5 - CGRateS returned an invalid message. - - Example 1.14. async cgrates_auth usage -route { - ... - async(cgrates_auth("$fU", "$rU"), auth_reply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: code=$cgr_ret!\n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - -1.11.2. cgrates_cmd(command[, session]) - - Can run an arbitrary CGRateS command in an asynchronous way. - The execution is suspended until the CGRateS engine sends the - reply back. - - Meaning of the parameters is as follows: - * command - the command sent to the CGRateS engine. This is a - mandatory parameter. - * session - the tag of the session that will be started if - the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable should - be considered. If missing, the default set is used. - - The function can return the following values: - * 1 - successful call - the CGRateS account is allowed to - make the call. - * -1 - OpenSIPS returned an internal error (i.e. server is - out of memory). - * -2 - the CGRateS engine returned error. - * -3 - No suitable CGRateS server found. message type (not an - initial INVITE). - - Example 1.15. async cgrates_cmd compat_mode usage -route { - ... - $cgr(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - async(cgrates_cmd("SMGenericV1.GetMaxUsage"), auth_reply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: code=$cgr_ret!\n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - - Example 1.16. async cgrates_cmd new usage -route { - ... - $cgr_opt(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - async(cgrates_cmd("SessionSv1.AuthorizeEventWithDigest"), auth_r -eply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: MaxUsage=$cgr_ret(MaxUsage)!\ -n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 192 99 7282 1877 - 2. Vlad Patrascu (@rvlad-patrascu) 16 10 138 190 - 3. Liviu Chircu (@liviuchircu) 14 11 56 65 - 4. Maksym Sobolyev (@sobomax) 7 5 18 18 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 20 21 - 6. wuhanck 3 1 3 3 - 7. James Stanley 3 1 1 1 - 8. Nick Altmann (@nikbyte) 3 1 1 1 - 9. Bradley Jokinen 2 1 6 0 - 10. Razvan 2 1 4 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Dec 2016 - Jun 2025 - 2. Nick Altmann (@nikbyte) Feb 2025 - Feb 2025 - 3. Liviu Chircu (@liviuchircu) Nov 2017 - Apr 2024 - 4. Maksym Sobolyev (@sobomax) Jul 2017 - Nov 2023 - 5. James Stanley Mar 2023 - Mar 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2017 - Mar 2020 - 8. Razvan Dec 2018 - Dec 2018 - 9. wuhanck Apr 2018 - Apr 2018 - 10. Bradley Jokinen Jul 2017 - Jul 2017 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2017 Răzvan Crainea diff --git a/modules/cgrates/README.md b/modules/cgrates/README.md new file mode 100644 index 00000000000..a05b799b01e --- /dev/null +++ b/modules/cgrates/README.md @@ -0,0 +1,777 @@ +--- +title: "CGRateS Module" +description: "[CGRateS](http://www.cgrates.org/) is an open-source rating engine used for carrier-grade, multi-tenant, real-time billing. This module can be used to communicate with the CGRates engine in order to do call authorization and accounting for billing purposes." +--- + +## Admin Guide + + +### Overview + + +[*CGRateS*](http://www.cgrates.org/) +is an open-source rating engine used for carrier-grade, multi-tenant, +real-time billing. It is able to do both postpaid and prepaid rating +for multiple concurrent sessions with different balance units (eg: Monetary, +SMS, Internet Traffic). CGRateS can also export accurate CDRs in various +formats. + + +This module can be used to communicate with the CGRates engine in order to do +call authorization and accounting for billing purposes. The OpenSIPS module does +not do any billing by itself, but provides an interface to communicate with the +CGRateS engine using efficient [JSON-RPC](http://json-rpc.org/) +APIs in both synchronous and asynchronous ways. For each command the user can +provide a set of parameters that will be forwarded to the CGRateS engine, using +the *$cgr()* variable. You can find usage examples in the +following sections. + + +The module also has support for multiple parallel billing sessions to CGRateS. +This can be useful in scenarios that involve complex billing logic, such as +double billing (both customer and carrier billing), or multi-leg calls +(serial/parallel forking). Each billing session is independent and +has a specific *tag* that can be use throughout the call +lifetime. + + +The module can be used to implement the following features: + + +### Authorization + + +The authorization is used to check if an account is allowed to start a new call +and it has enough credit to call to that destination. This is done using the +*cgrates_auth()* command, which returns the number of seconds +a call is allowed to run in the *$cgr_ret* pseudo-variable. + + +Usage example: + + +```opensips +... +if (cgrates_auth("$fU", "$rU")) + xlog("Call is allowed to run $cgr_ret seconds\n"); +} +... +``` + + +### Accounting + + +The accounting mode is used to start and stop a CGRateS session. This can be +used for both prepaid and postpaid billing. The *cgrates_acc()* +function starts the CGRateS session when the call is answered (the 200 OK message +is received) and ends it when the call is ended (a BYE message is received). This +is done automatically using the *dialog* module. + + +Note that it is important to first authorize the call (using the +*cgrates_auth()* command) before starting accounting. If you do +not do this and the user is not authorized to call, the dialog will be immediately +closed, resulting in a 0-duration call. If the call is allowed to go on, the +dialog lifetime will be set to the duration indicated by the CGRateS engine. +Therefore, the dialog will be automatically ended if the call would have been longer. + + +After the call is ended (by a BYE message), the CGRateS session is also ended. +At this point, you can generate a CDR. To do this, you have to set the +*cdr* flag to the *cgrates_acc()* command. +CDRs can also be generated for missed calls by using the *missed* +flag. + + +Usage example: + + +```opensips +... +if (!cgrates_auth("$fU", "$rU")) { + sl_send_reply(403, "Forbidden"); + exit; +} +xlog("Call is allowed to run $cgr_ret seconds\n"); +# do accounting for this call +cgrates_acc("cdr", "$fU", "$rU"); +... +``` + + +Note that when using the *cdr* flag, CDRs are exported by +the CGRateS engine in various formats, not by OpenSIPS. Check the CGRateS +documentation for more information. + + +### Other Commands + + +You can use the *cgrates_cmd()* to send arbitrary +commands to the CGRateS engine, and use the *$cgr_ret* +pseudo-variable to retrieve the response. + + +The following example simulates the *cgrates_auth()* CGRateS call: + + +```opensips +... +$cgr_opt(Tenant) = $fd; # or $cgr(Tenant) = $fd; /* in compat mode */ +$cgr(Account) = $fU; +$cgr(OriginID) = $ci; +$cgr(SetupTime) = "" + $Ts; +$cgr(RequestType) = "*prepaid"; +$cgr(Destination) = $rU; +cgrates_cmd("SessionSv1.AuthorizeEvent"); +xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\n"); +... + +``` + + +### CGRateS Failover + + +Multiple CGRateS engines can be provisioned to use in a failover manner: in +case one engine is down, the next one is used. Currently there is no load +balancing logic between the servers, but this is a feature one of the CGRateS +component does starting with newer versions. + + +Each CGRateS engine has assigned up to +*max_async_connections* connections, plus one +used for synchronous commands. If a connection fails (due to network +issues, or server issues), it is marked as closed and a new one is +tried. If all connections to that engine are down, then the entire +engine is marked as disabled, and a new engine is queried. After an +engine is down for more than *retry_timeout* +seconds, OpenSIPS tries to connect once again to that server. If it +succeeds, that server is enabled. Otherwise, the other engines are +used, until none is available and the command fails. + + +### CGRateS Compatibility + + +The module supports two different versions of CGRateS: the +*compat_mode* one, which works with pre-rc8 releases, and a +new one which works with the post-rc8 releases. The difference between the two +versions consist in the way the requests and responses to and from CGRateS +are built. In the non-*compat_mode*/new version, a new +variable, *$cgr_opt()*, is available, and can be used to +tune the request options. This variable should not be used in +*compat_mode* mode to avoid abiguities, but if it is used, +it behaves exactly as *$cgr()*. By default +*compat_mode* is disabled. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog* -- in case CGRateS +accounting is used. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libjson* + + +### Exported Parameters + + +#### cgrates_engine (string) + + +This parameter is used to specify a CGRateS engine connection. +The format is *IP[:port]*. The port is optional, +and if missing, *2014* is used. + + +This parameter can have multiple values, for each server +used for failover. At least one server should be provisioned. + + +*Default value is "None".* + + +```opensips title="Set cgrates_engine parameter" +... +modparam("cgrates", "cgrates_engine", "127.0.0.1") +modparam("cgrates", "cgrates_engine", "127.0.0.1:2013") +... +``` + + +#### bind_ip (string) + + +IP used to bind the socket that communicates with the +CGRateS engines. This is useful to set when the engine +is runing in a local, secure LAN, and you want to use +that network to communicate with your servers. +The parameter is optional. + + +*Default value is "not set - any IP is used".* + + +```opensips title="Set bind_ip parameter" +... +modparam("cgrates", "bind_ip", "10.0.0.100") +... +``` + + +#### max_async_connections (integer) + + +The maximum number of simultaneous asynchronous connections +to a CGRateS engine. + + +*Default value is "10".* + + +```opensips title="Set max_async_connections parameter" +... +modparam("cgrates", "max_async_connections", 20) +... +``` + + +#### retry_timeout (integer) + + +The number of seconds after which a disabled connection/engine +is retried. + + +*Default value is "60".* + + +```opensips title="Set retry_timeout parameter" +... +modparam("cgrates", "retry_timeout", 120) +... +``` + + +#### compat_mode (integer) + + +Indicates whether OpenSIPS should use the old (compat_mode) +CGRateS version API (pre-rc8). + + +*Default value is "false (0)".* + + +```opensips title="Set compat_mode parameter" +... +modparam("cgrates", "compat_mode", 1) +... +``` + + +### Exported Functions + + +#### cgrates_acc([flags[, account[, destination[, session]]]]) + + +`cgrates_acc()` starts an accounting +session on the CGRateS engine for the current dialog. It also ends the +session when the dialog is ended. This function requires a dialog, so in +case create_dialog() was not previously used, it will internally call +that function. + + +Note that the `cgrates_acc()` function +does not send any message to the CGRateS engine when it is called, but only +when the call is answered and the CGRateS session should be started (a 200 +OK message is received). + + +When called in *REQUEST_ROUTE* or +*FAILURE_ROUTE*, accounting for this session is done +for all the branches created. When called in *BRANCH_ROUTE* +or *ONREPLY_ROUTE*, acccounting is done only if that +branch is successful (terminates with a 2xx reply code). + + +The `cgrates_acc()` function should +only be called on initial INVITEs. For more infirmation check +[accounting](#accounting). + + +Meaning of the parameters is as follows: + + +- *flags* (string, optional) - indicates whether OpenSIPS +should generate a CDR at the end of the call. If the parameter is missing, +no CDR is generated - the session is only passed through CGRateS. +The following values can be used, separated by '|': + + - *cdr* - also generate a CDR; + - *missed* - generate a CDR even for missed +calls; this flag only makes sense if the *cdr* +flag is used; +- *account* (string, optional) - the account that will be charged +in CGrateS. If not specified, the user in the From header is used. +- *destination* (string, optional) - the dialled number. +If not present the request URI user is used. +- *session* (string, optional) - the tag of the session that +will be started if the branch/call completes with success. This parameter +indicates what set of data from the *$cgr()* variable +should be considered. If missing, the default set is used. + + +The function can return the following values: + + +- *1* - successful call - the CGRateS accouting +was successfully setup for the call. +- *-1* - OpenSIPS returned an internal error +(i.e. the dialog cannot be created, or the server is out of memory). +- *-2* - the SIP message is invalid: either +it has missing headers, or it is not an initial INVITE. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="cgrates_acc() usage" +... +if (!has_totag()) { + ... + if (cgrates_auth($fU, $rU)) + cgrates_acc("cdr|missed", $fU, $rU); + ... +} +... + +``` + + +#### cgrates_auth([account[, destination[, session]]]) + + +`cgrates_auth()` does call authorization +through using the CGRateS engine. + + +Meaning of the parameters is as follows: + + +- *account* (string, optional) - the account that will be checked +in CGrateS. If not specified, the user in the From header is used. +- *destination* (string, optional) - the dialled number. +If not present the request URI user is used. +- *session* (string, optional) - the tag of the session that +will be started if the branch/call completes with success. This parameter +indicates what set of data from the *$cgr()* variable +should be considered. If missing, the default set is used. + + +The function can return the following values: + + +- *1* - successful call - the CGRateS account +is allowed to make the call. +- *-1* - OpenSIPS returned an internal error +(i.e. server is out of memory). +- *-2* - the CGRateS engine returned error. +- *-3* - No suitable CGRateS server found. +message type (not an initial INVITE). +- *-4* - the SIP message is invalid: either +it has missing headers, or it is not an initial INVITE. +- *-5* - CGRateS returned an invalid message. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="cgrates_auth() usage" +... +if (!has_totag()) { + ... + if (!cgrates_auth($fU, $rU)) { + sl_send_reply(403, "Forbidden"); + exit; + } + ... +} +... + +``` + + +```opensips title="cgrates_auth() usage with attributes parsing" +... +if (!has_totag()) { + ... + $cgr_opt(GetAttributes) = 1; + if (!cgrates_auth($fU, $rU)) { + sl_send_reply(403, "Forbidden"); + exit; + } + # move attributes from AttributesDigest variable to plain AVPs + $var(idx) = 0; + while ($(cgr_ret(AttributesDigest){s.select,$var(idx),,}) != NULL) { + $avp($(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,0,:})) + = $(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,1,:}); + $var(idx) = $var(idx) + 1; + } + ... +} +... + +``` + + +#### cgrates_cmd(command[, session]) + + +`cgrates_cmd()` can send +arbitrary commands to the CGRateS engine. + + +Meaning of the parameters is as follows: + + +- *command* (string) - the command sent to the +CGRateS engine. +- *session* (string, optional) - the tag of the session that +will be started if the branch/call completes with success. This parameter +indicates what set of data from the *$cgr()* variable +should be considered. If missing, the default set is used. + + +The function can return the following values: + + +- *1* - successful call - the CGRateS account +is allowed to make the call. +- *-1* - OpenSIPS returned an internal error +(i.e. server is out of memory). +- *-2* - the CGRateS engine returned error. +- *-3* - No suitable CGRateS server found. +message type (not an initial INVITE). + + +This function can be used from any route. + + +```opensips title="cgrates_cmd() usage" +... +# cgrates_auth($fU, $rU); simulation +$cgr_opt(Tenant) = $fd; +$cgr(Account) = $fU; +$cgr(OriginID) = $ci; +$cgr(SetupTime) = "" + $Ts; +$cgr(RequestType) = "*prepaid"; +$cgr(Destination) = $rU; +cgrates_cmd("SessionSv1.AuthorizeEvent"); +xlog("Call is allowed to run $cgr_ret seconds\n"); +... + +``` + + +### Exported Pseudo-Variables + + +#### $cgr(name) / $(cgr(name)[session]) + + +Pseudo-variable used to set different parameters for the +CGRateS command. Each name-value pair will be encoded as +a *string - value* attribute in the +JSON message sent to CGRateS. + + +The name-values pairs are stored in the transaction (if +tm module is loaded). Therefore the values are accessible +in the reply. + + +When the *cgrates_acc()* function is +called, all the name-value pairs are moved in the dialog. +Therefore the values will be accessible along the dialog's +lifetime. + + +This variable consists of serveral sets of name-value pairs. +Each set corresponds to a session. The variable can be +indexed by a *session tag*. The sets +are completely indepdendent from one another. if the +*session tag* does not exist, the default +(no name) one is used. + + +When assigned with the *:=* operator, +the value is treated as a JSON, rather than a string/integer. +However, the evaluation of the JSON is late, therefore when +the CGRateS request is built, if the module is unable to parse +the JSON, the value is sent as a string. + + +```opensips title="$cgr(name) simple usage" +... +if (!has_totag()) { + ... + $cgr_opt(Tenant) = $fd; # set the From domain as a tenant + $cgr(RequestType) = "*prepaid"; # do prepaid accounting + $cgr(AttributeIDs) := '["+5551234"]'; # treat as array + if (!cgrates_auth("$fU", "$rU")) { + sl_send_reply(403, "Forbidden"); + exit; + } +} +... + +``` + + +```opensips title="$cgr(name) multiple sessions usage" +... +if (!has_totag()) { + ... + # first session - authorize the user + $cgr_opt(Tenant) = $fd; # set the From domain as a tenant + $cgr(RequestType) = "*prepaid"; # do prepaid accounting + if (!cgrates_auth("$fU", "$rU")) { + sl_send_reply(403, "Forbidden"); + exit; + } + + # second session - authorize the carrier + $(cgr_opt(Tenant)[carrier]) = $td; + $(cgr(RequestType)[carrier]) = "*postpaid"; + if (!cgrates_auth("$tU", "$fU", "carrier")) { + # use a different carrier + return; + } + + # if everything is successful start accounting on both + cgrates_acc("cdr", "$fU", "rU"); + cgrates_acc("cdr", "$tU", "$fU", "carrier"); +} +... + +``` + + +#### $cgr_opt(name) / $(cgr_opt(name)[session]) + + +Used to tune the request parameter of a CGRateS request when used in +non-*compat_mode*. + + +*Note:* for all request options integer values act as +boolean values: *0* disables the feature and +*1*(or different than 0 value) enables it. String +variables are passed just as they are set. + + +Possible values at the time the documentation was written: + + +- *Tenant* - tune CGRateS Tenant. +- *GetAttributes* - requests the account +attributes from the CGRateS DB. +- *GetMaxUsage* - request the maximum time +the call is allowed to run. +- *GetSuppliers* - request an array with +all the suppliers for that can terminate that call. + + +```opensips title="$cgr_opt(name) usage" +... +$cgr_opt(Tenant) = "cgrates.org"; +$cgr_opt(GetMaxUsage) = 1; # also retrieve the max usage +if (!cgrates_auth("$fU", "$rU")) { + # call rejected +} +... + +``` + + +#### $cgr_ret(name) + + +Returns the reply message of a CGRateS command in script, +or when used in the non-compat mode, one of the objects +within the reply. + + +```opensips title="$cgr_ret(name) usage" +... +cgrates_auth("$fU", "$rU"); + +# in compat mode +xlog("Call is allowed to run $cgr_ret seconds\n"); + +# in non-compat mode +xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\n"); +... + +``` + + +### Exported Asynchronous Functions + + +#### cgrates_auth([account[, destination[, session]]]) + + +Does the CGRateS authorization call in an asynchronous way. Script +execution is suspended until the CGRateS engine sends the reply back. + + +Meaning of the parameters is as follows: + + +- *account* - the account that will be checked +in CGRateS. This parameter is optional, and if not specified, +the user in the From header is used. +- *destination* - the dialled number. Optional +parameter, if not present the request URI user is used. +- *session* - the tag of the session that +will be started if the branch/call completes with success. This parameter +indicates what set of data from the *$cgr()* variable +should be considered. If missing, the default set is used. + + +The function can return the following values: + + +- *1* - successful call - the CGRateS account +is allowed to make the call. +- *-1* - OpenSIPS returned an internal error +(i.e. server is out of memory). +- *-2* - the CGRateS engine returned error. +- *-3* - No suitable CGRateS server found. +message type (not an initial INVITE). +- *-4* - the SIP message is invalid: either +it has missing headers, or it is not an initial INVITE. +- *-5* - CGRateS returned an invalid message. + + +```opensips title="async cgrates_auth usage" +route { + ... + async(cgrates_auth("$fU", "$rU"), auth_reply); +} + +route [auth_reply] +{ + if ($rc < 0) { + xlog("Call not authorized: code=$cgr_ret!\n"); + send_reply(403, "Forbidden"); + exit; + } + ... +} +``` + + +#### cgrates_cmd(command[, session]) + + +Can run an arbitrary CGRateS command in an asynchronous way. The +execution is suspended until the CGRateS engine sends the reply back. + + +Meaning of the parameters is as follows: + + +- *command* - the command sent to the +CGRateS engine. This is a mandatory parameter. +- *session* - the tag of the session that +will be started if the branch/call completes with success. This parameter +indicates what set of data from the *$cgr()* variable +should be considered. If missing, the default set is used. + + +The function can return the following values: + + +- *1* - successful call - the CGRateS account +is allowed to make the call. +- *-1* - OpenSIPS returned an internal error +(i.e. server is out of memory). +- *-2* - the CGRateS engine returned error. +- *-3* - No suitable CGRateS server found. +message type (not an initial INVITE). + + +```opensips title="async cgrates_cmd compat_mode usage" +route { + ... + $cgr(Tenant) = $fd; + $cgr(Account) = $fU; + $cgr(OriginID) = $ci; + $cgr(SetupTime) = "" + $Ts; + $cgr(RequestType) = "*prepaid"; + $cgr(Destination) = $rU; + async(cgrates_cmd("SMGenericV1.GetMaxUsage"), auth_reply); +} + +route [auth_reply] +{ + if ($rc < 0) { + xlog("Call not authorized: code=$cgr_ret!\n"); + send_reply(403, "Forbidden"); + exit; + } + ... +} +``` + + +```opensips title="async cgrates_cmd new usage" +route { + ... + $cgr_opt(Tenant) = $fd; + $cgr(Account) = $fU; + $cgr(OriginID) = $ci; + $cgr(SetupTime) = "" + $Ts; + $cgr(RequestType) = "*prepaid"; + $cgr(Destination) = $rU; + async(cgrates_cmd("SessionSv1.AuthorizeEventWithDigest"), auth_reply); +} + +route [auth_reply] +{ + if ($rc < 0) { + xlog("Call not authorized: MaxUsage=$cgr_ret(MaxUsage)!\n"); + send_reply(403, "Forbidden"); + exit; + } + ... +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cgrates/cgrates.c b/modules/cgrates/cgrates.c index 7e4c7e31925..04b18dac12d 100644 --- a/modules/cgrates/cgrates.c +++ b/modules/cgrates/cgrates.c @@ -138,6 +138,7 @@ static const dep_export_t deps = { { MOD_TYPE_NULL, NULL, 0 }, }, { /* modparam dependencies */ + { NULL, NULL }, }, }; diff --git a/modules/cgrates/cgrates_acc.c b/modules/cgrates/cgrates_acc.c index e8611b5cae6..38b97e13929 100644 --- a/modules/cgrates/cgrates_acc.c +++ b/modules/cgrates/cgrates_acc.c @@ -38,6 +38,8 @@ static void cgr_tmcb_func( struct cell* t, int type, struct tmcb_params *ps); static void cgr_tmcb_func_free(void *param); static void cgr_dlg_callback(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params); +static void cgr_dlg_process_vars(struct dlg_cell *dlg, int type, + struct dlg_cb_params *_params); static str cgr_ctx_str = str_init("cgrX_ctx"); static str cgr_serial_str = str_init("cgrX_serial"); @@ -60,6 +62,30 @@ int cgr_acc_init(void) return 0; } +static int cgr_restore_acc_ctx(struct dlg_cell *dlg, struct cgr_acc_ctx *ctx) +{ + int_str ctxstr; + int_str new_ctxstr; + int val_type; + struct cgr_acc_ctx *stored_ctx = NULL; + + if (cgr_dlgb.fetch_dlg_value(dlg, &cgr_ctx_str, &val_type, + &ctxstr, 0) == 0 && + val_type == DLG_VAL_TYPE_STR && + ctxstr.s.len == sizeof(struct cgr_acc_ctx *)) { + stored_ctx = *(struct cgr_acc_ctx **)ctxstr.s.s; + if (stored_ctx == ctx) + return 0; + } + + LM_DBG("resetting dialog acc ctx from %p to %p\n", stored_ctx, ctx); + new_ctxstr.s.len = sizeof(ctx); + new_ctxstr.s.s = (char *)&ctx; + + return cgr_dlgb.store_dlg_value(dlg, &cgr_ctx_str, &new_ctxstr, + DLG_VAL_TYPE_STR); +} + static inline struct cgr_acc_ctx *cgr_new_acc_ctx(struct dlg_cell *dlg) { int_str ctxstr; @@ -980,6 +1006,12 @@ int w_cgr_acc(struct sip_msg* msg, void *flag_c, str* acc_c, str *dst_c, return -1; } + if (cgr_dlgb.register_dlgcb(dlg, DLGCB_PROCESS_VARS, + cgr_dlg_process_vars, ctx, NULL) != 0) { + LM_ERR("cannot register callback for context replication!\n"); + return -1; + } + if (cgr_dlgb.register_dlgcb(dlg, DLGCB_DESTROY, cgr_dlg_destroy, NULL, NULL) != 0) LM_ERR("cannot register callback for context release! context might leak!\n"); @@ -1035,14 +1067,14 @@ static void cgr_tmcb_func(struct cell* t, int type, struct tmcb_params *ps) si->branch_mask = 0; } } - goto unref; + return; } /* we start a session only for successful calls */ dlg = cgr_dlgb.get_dlg(); if (!dlg) { LM_ERR("cannot find dialog!\n"); - goto unref; + return; } time(&ctx->answer_time); list_for_each(l, ctx->sessions) { @@ -1067,7 +1099,7 @@ static void cgr_tmcb_func(struct cell* t, int type, struct tmcb_params *ps) si->flags |= CGRF_ENGAGED; } - /* should have reffed engaged and unref tm, so we simply exit :D */ + /* the tm ref is released by the callback release hook */ return; error: /* TODO: should we close all the started sessions now? */ @@ -1076,8 +1108,6 @@ static void cgr_tmcb_func(struct cell* t, int type, struct tmcb_params *ps) if (cgr_dlgb.terminate_dlg(NULL, dlg->h_entry, dlg->h_id, &terminate_str) >= 0) return; LM_ERR("cannot terminate the dialog!\n"); -unref: - cgr_ref_acc_ctx(ctx, -1, "tm"); } static void cgr_cdr_cb(struct cell* t, int type, struct tmcb_params *ps) @@ -1101,6 +1131,8 @@ static void cgr_cdr_cb(struct cell* t, int type, struct tmcb_params *ps) continue; cgr_cdr(ps->req, ctx, s, &dlg->callid); } + if (cgr_restore_acc_ctx(dlg, NULL) < 0) + LM_ERR("cannot reset context %p in dialog %p\n", ctx, dlg); cgr_ref_acc_ctx(ctx, -1, "engaged"); } @@ -1304,6 +1336,12 @@ void cgr_loaded_callback(struct dlg_cell *dlg, int type, goto internal_error; } + if (cgr_dlgb.register_dlgcb(dlg, DLGCB_PROCESS_VARS, + cgr_dlg_process_vars, ctx, NULL) != 0) { + LM_ERR("cannot register callback for context replication!\n"); + goto internal_error; + } + if (cgr_dlgb.register_dlgcb(dlg, DLGCB_DESTROY, cgr_dlg_destroy, NULL, NULL) != 0) LM_ERR("cannot register callback for context release! context might leak!\n"); @@ -1315,6 +1353,28 @@ void cgr_loaded_callback(struct dlg_cell *dlg, int type, } #undef CGR_CTX_COPY +static void cgr_dlg_process_vars(struct dlg_cell *dlg, int type, + struct dlg_cb_params *_params) +{ + struct cgr_acc_ctx *ctx; + str *name; + + if (!_params || !_params->param || !*_params->param) { + LM_ERR("no context specified to process replicated vars\n"); + return; + } + + ctx = *_params->param; + name = (str *)_params->dlg_data; + + if (name && (name->len != cgr_ctx_str.len || + memcmp(name->s, cgr_ctx_str.s, name->len) != 0)) + return; + + if (cgr_restore_acc_ctx(dlg, ctx) < 0) + LM_ERR("cannot restore context %p in dialog %p\n", ctx, dlg); +} + static void cgr_dlg_callback(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) { @@ -1371,8 +1431,11 @@ static void cgr_dlg_callback(struct dlg_cell *dlg, int type, } } } - if (!registered) + if (!registered) { + if (cgr_restore_acc_ctx(dlg, NULL) < 0) + LM_ERR("cannot reset context %p in dialog %p\n", ctx, dlg); cgr_ref_acc_ctx(ctx, -1, "dialog"); + } } int cgr_acc_terminate(json_object *param, json_object **ret) diff --git a/modules/cgrates/doc/cgrates.xml b/modules/cgrates/doc/cgrates.xml deleted file mode 100644 index 272023a0c91..00000000000 --- a/modules/cgrates/doc/cgrates.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - CGRateS Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2017 Răzvan Crainea - diff --git a/modules/cgrates/doc/cgrates_admin.xml b/modules/cgrates/doc/cgrates_admin.xml deleted file mode 100644 index e2c1f2ac92c..00000000000 --- a/modules/cgrates/doc/cgrates_admin.xml +++ /dev/null @@ -1,962 +0,0 @@ - - - - - &adminguide; - -
- Overview - - CGRateS - is an open-source rating engine used for carrier-grade, multi-tenant, - real-time billing. It is able to do both postpaid and prepaid rating - for multiple concurrent sessions with different balance units (eg: Monetary, - SMS, Internet Traffic). CGRateS can also export accurate CDRs in various - formats. - - - - This module can be used to communicate with the CGRates engine in order to do - call authorization and accounting for billing purposes. The &osips; module does - not do any billing by itself, but provides an interface to communicate with the - CGRateS engine using efficient JSON-RPC - APIs in both synchronous and asynchronous ways. For each command the user can - provide a set of parameters that will be forwarded to the CGRateS engine, using - the $cgr() variable. You can find usage examples in the - following sections. - - - - The module also has support for multiple parallel billing sessions to CGRateS. - This can be useful in scenarios that involve complex billing logic, such as - double billing (both customer and carrier billing), or multi-leg calls - (serial/parallel forking). Each billing session is independent and - has a specific tag that can be use throughout the call - lifetime. - - - - The module can be used to implement the following features: - -
- -
- Authorization - - The authorization is used to check if an account is allowed to start a new call - and it has enough credit to call to that destination. This is done using the - cgrates_auth() command, which returns the number of seconds - a call is allowed to run in the $cgr_ret pseudo-variable. - - - Usage example: - - ... - if (cgrates_auth("$fU", "$rU")) - xlog("Call is allowed to run $cgr_ret seconds\n"); - } - ... - - -
- -
- Accounting - - The accounting mode is used to start and stop a CGRateS session. This can be - used for both prepaid and postpaid billing. The cgrates_acc() - function starts the CGRateS session when the call is answered (the 200 OK message - is received) and ends it when the call is ended (a BYE message is received). This - is done automatically using the dialog module. - - - Note that it is important to first authorize the call (using the - cgrates_auth() command) before starting accounting. If you do - not do this and the user is not authorized to call, the dialog will be immediately - closed, resulting in a 0-duration call. If the call is allowed to go on, the - dialog lifetime will be set to the duration indicated by the CGRateS engine. - Therefore, the dialog will be automatically ended if the call would have been longer. - - - After the call is ended (by a BYE message), the CGRateS session is also ended. - At this point, you can generate a CDR. To do this, you have to set the - cdr flag to the cgrates_acc() command. - CDRs can also be generated for missed calls by using the missed - flag. - - - Usage example: - - ... - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - xlog("Call is allowed to run $cgr_ret seconds\n"); - # do accounting for this call - cgrates_acc("cdr", "$fU", "$rU"); - ... - - - - Note that when using the cdr flag, CDRs are exported by - the CGRateS engine in various formats, not by &osips;. Check the CGRateS - documentation for more information. - -
- -
- Other Commands - - You can use the cgrates_cmd() to send arbitrary - commands to the CGRateS engine, and use the $cgr_ret - pseudo-variable to retrieve the response. - - - The following example simulates the cgrates_auth() CGRateS call: - - ... - $cgr_opt(Tenant) = $fd; # or $cgr(Tenant) = $fd; /* in compat mode */ - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - cgrates_cmd("SessionSv1.AuthorizeEvent"); - xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\n"); - ... - - -
- -
- CGRateS Failover - - Multiple CGRateS engines can be provisioned to use in a failover manner: in - case one engine is down, the next one is used. Currently there is no load - balancing logic between the servers, but this is a feature one of the CGRateS - component does starting with newer versions. - - - Each CGRateS engine has assigned up to - max_async_connections connections, plus one - used for synchronous commands. If a connection fails (due to network - issues, or server issues), it is marked as closed and a new one is - tried. If all connections to that engine are down, then the entire - engine is marked as disabled, and a new engine is queried. After an - engine is down for more than retry_timeout - seconds, &osips; tries to connect once again to that server. If it - succeeds, that server is enabled. Otherwise, the other engines are - used, until none is available and the command fails. - -
- -
- CGRateS Compatibility - - The module supports two different versions of CGRateS: the - compat_mode one, which works with pre-rc8 releases, and a - new one which works with the post-rc8 releases. The difference between the two - versions consist in the way the requests and responses to and from CGRateS - are built. In the non-compat_mode/new version, a new - variable, $cgr_opt(), is available, and can be used to - tune the request options. This variable should not be used in - compat_mode mode to avoid abiguities, but if it is used, - it behaves exactly as $cgr(). By default - compat_mode is disabled. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog -- in case CGRateS - accounting is used. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libjson - - - - -
-
- -
- Exported Parameters -
- <varname>cgrates_engine</varname> (string) - - This parameter is used to specify a CGRateS engine connection. - The format is IP[:port]. The port is optional, - and if missing, 2014 is used. - - - This parameter can have multiple values, for each server - used for failover. At least one server should be provisioned. - - - - Default value is None. - - - - Set <varname>cgrates_engine</varname> parameter - -... -modparam("cgrates", "cgrates_engine", "127.0.0.1") -modparam("cgrates", "cgrates_engine", "127.0.0.1:2013") -... - - -
-
- <varname>bind_ip</varname> (string) - - IP used to bind the socket that communicates with the - CGRateS engines. This is useful to set when the engine - is runing in a local, secure LAN, and you want to use - that network to communicate with your servers. - The parameter is optional. - - - - Default value is not set - any IP is used. - - - - Set <varname>bind_ip</varname> parameter - -... -modparam("cgrates", "bind_ip", "10.0.0.100") -... - - -
-
- <varname>max_async_connections</varname> (integer) - - The maximum number of simultaneous asynchronous connections - to a CGRateS engine. - - - - Default value is 10. - - - - Set <varname>max_async_connections</varname> parameter - -... -modparam("cgrates", "max_async_connections", 20) -... - - -
-
- <varname>retry_timeout</varname> (integer) - - The number of seconds after which a disabled connection/engine - is retried. - - - - Default value is 60. - - - - Set <varname>retry_timeout</varname> parameter - -... -modparam("cgrates", "retry_timeout", 120) -... - - -
-
- <varname>compat_mode</varname> (integer) - - Indicates whether OpenSIPS should use the old (compat_mode) - CGRateS version API (pre-rc8). - - - - Default value is false (0). - - - - Set <varname>compat_mode</varname> parameter - -... -modparam("cgrates", "compat_mode", 1) -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">cgrates_acc([flags[, account[, destination[, session]]]])</function> - - - cgrates_acc() starts an accounting - session on the CGRateS engine for the current dialog. It also ends the - session when the dialog is ended. This function requires a dialog, so in - case create_dialog() was not previously used, it will internally call - that function. - - - - Note that the cgrates_acc() function - does not send any message to the CGRateS engine when it is called, but only - when the call is answered and the CGRateS session should be started (a 200 - OK message is received). - - - - When called in REQUEST_ROUTE or - FAILURE_ROUTE, accounting for this session is done - for all the branches created. When called in BRANCH_ROUTE - or ONREPLY_ROUTE, acccounting is done only if that - branch is successful (terminates with a 2xx reply code). - - - - The cgrates_acc() function should - only be called on initial INVITEs. For more infirmation check - . - - - - Meaning of the parameters is as follows: - - - - flags (string, optional) - indicates whether &osips; - should generate a CDR at the end of the call. If the parameter is missing, - no CDR is generated - the session is only passed through CGRateS. - The following values can be used, separated by '|': - - - cdr - also generate a CDR; - - - missed - generate a CDR even for missed - calls; this flag only makes sense if the cdr - flag is used; - - - - - account (string, optional) - the account that will be charged - in CGrateS. If not specified, the user in the From header is used. - - - - destination (string, optional) - the dialled number. - If not present the request URI user is used. - - - - session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable - should be considered. If missing, the default set is used. - - - - - - The function can return the following values: - - - - 1 - successful call - the CGRateS accouting - was successfully setup for the call. - - - - -1 - &osips; returned an internal error - (i.e. the dialog cannot be created, or the server is out of memory). - - - - -2 - the SIP message is invalid: either - it has missing headers, or it is not an initial INVITE. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - cgrates_acc() usage - - ... - if (!has_totag()) { - ... - if (cgrates_auth($fU, $rU)) - cgrates_acc("cdr|missed", $fU, $rU); - ... - } - ... - - - -
-
- - <function moreinfo="none">cgrates_auth([account[, destination[, session]]])</function> - - - cgrates_auth() does call authorization - through using the CGRateS engine. - - - - Meaning of the parameters is as follows: - - - - account (string, optional) - the account that will be checked - in CGrateS. If not specified, the user in the From header is used. - - - - destination (string, optional) - the dialled number. - If not present the request URI user is used. - - - - session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable - should be considered. If missing, the default set is used. - - - - - - The function can return the following values: - - - - 1 - successful call - the CGRateS account - is allowed to make the call. - - - - -1 - &osips; returned an internal error - (i.e. server is out of memory). - - - - -2 - the CGRateS engine returned error. - - - - -3 - No suitable CGRateS server found. - message type (not an initial INVITE). - - - - -4 - the SIP message is invalid: either - it has missing headers, or it is not an initial INVITE. - - - - -5 - CGRateS returned an invalid message. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - cgrates_auth() usage - - ... - if (!has_totag()) { - ... - if (!cgrates_auth($fU, $rU)) { - sl_send_reply(403, "Forbidden"); - exit; - } - ... - } - ... - - - - - cgrates_auth() usage with attributes parsing - - ... - if (!has_totag()) { - ... - $cgr_opt(GetAttributes) = 1; - if (!cgrates_auth($fU, $rU)) { - sl_send_reply(403, "Forbidden"); - exit; - } - # move attributes from AttributesDigest variable to plain AVPs - $var(idx) = 0; - while ($(cgr_ret(AttributesDigest){s.select,$var(idx),,}) != NULL) { - $avp($(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,0,:})) - = $(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,1,:}); - $var(idx) = $var(idx) + 1; - } - ... - } - ... - - - -
-
- - <function moreinfo="none">cgrates_cmd(command[, session])</function> - - - cgrates_cmd() can send - arbitrary commands to the CGRateS engine. - - - - Meaning of the parameters is as follows: - - - - command (string) - the command sent to the - CGRateS engine. - - - - session (string, optional) - the tag of the session that - will be started if the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable - should be considered. If missing, the default set is used. - - - - - - The function can return the following values: - - - - 1 - successful call - the CGRateS account - is allowed to make the call. - - - - -1 - &osips; returned an internal error - (i.e. server is out of memory). - - - - -2 - the CGRateS engine returned error. - - - - -3 - No suitable CGRateS server found. - message type (not an initial INVITE). - - - - - - This function can be used from any route. - - - - cgrates_cmd() usage - - ... - # cgrates_auth($fU, $rU); simulation - $cgr_opt(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - cgrates_cmd("SessionSv1.AuthorizeEvent"); - xlog("Call is allowed to run $cgr_ret seconds\n"); - ... - - - -
-
- -
- Exported Pseudo-Variables - -
- <varname>$cgr(name) / $(cgr(name)[session])</varname> - - Pseudo-variable used to set different parameters for the - CGRateS command. Each name-value pair will be encoded as - a string - value attribute in the - JSON message sent to CGRateS. - - - The name-values pairs are stored in the transaction (if - tm module is loaded). Therefore the values are accessible - in the reply. - - - When the cgrates_acc() function is - called, all the name-value pairs are moved in the dialog. - Therefore the values will be accessible along the dialog's - lifetime. - - - This variable consists of serveral sets of name-value pairs. - Each set corresponds to a session. The variable can be - indexed by a session tag. The sets - are completely indepdendent from one another. if the - session tag does not exist, the default - (no name) one is used. - - - When assigned with the := operator, - the value is treated as a JSON, rather than a string/integer. - However, the evaluation of the JSON is late, therefore when - the CGRateS request is built, if the module is unable to parse - the JSON, the value is sent as a string. - - - $cgr(name) simple usage - - ... - if (!has_totag()) { - ... - $cgr_opt(Tenant) = $fd; # set the From domain as a tenant - $cgr(RequestType) = "*prepaid"; # do prepaid accounting - $cgr(AttributeIDs) := '["+5551234"]'; # treat as array - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - } - ... - - - - $cgr(name) multiple sessions usage - - ... - if (!has_totag()) { - ... - # first session - authorize the user - $cgr_opt(Tenant) = $fd; # set the From domain as a tenant - $cgr(RequestType) = "*prepaid"; # do prepaid accounting - if (!cgrates_auth("$fU", "$rU")) { - sl_send_reply(403, "Forbidden"); - exit; - } - - # second session - authorize the carrier - $(cgr_opt(Tenant)[carrier]) = $td; - $(cgr(RequestType)[carrier]) = "*postpaid"; - if (!cgrates_auth("$tU", "$fU", "carrier")) { - # use a different carrier - return; - } - - # if everything is successful start accounting on both - cgrates_acc("cdr", "$fU", "rU"); - cgrates_acc("cdr", "$tU", "$fU", "carrier"); - } - ... - - -
-
- <varname>$cgr_opt(name) / $(cgr_opt(name)[session])</varname> - - Used to tune the request parameter of a CGRateS request when used in - non-compat_mode. - - - Note: for all request options integer values act as - boolean values: 0 disables the feature and - 1(or different than 0 value) enables it. String - variables are passed just as they are set. - - - Possible values at the time the documentation was written: - - - Tenant - tune CGRateS Tenant. - - - GetAttributes - requests the account - attributes from the CGRateS DB. - - - GetMaxUsage - request the maximum time - the call is allowed to run. - - - GetSuppliers - request an array with - all the suppliers for that can terminate that call. - - - - - $cgr_opt(name) usage - - ... - $cgr_opt(Tenant) = "cgrates.org"; - $cgr_opt(GetMaxUsage) = 1; # also retrieve the max usage - if (!cgrates_auth("$fU", "$rU")) { - # call rejected - } - ... - - -
-
- <varname>$cgr_ret(name)</varname> - - Returns the reply message of a CGRateS command in script, - or when used in the non-compat mode, one of the objects - within the reply. - - - $cgr_ret(name) usage - - ... - cgrates_auth("$fU", "$rU"); - - # in compat mode - xlog("Call is allowed to run $cgr_ret seconds\n"); - - # in non-compat mode - xlog("Call is allowed to run $cgr_ret(MaxUsage) seconds\n"); - ... - - -
- -
- -
- Exported Asynchronous Functions -
- - <function moreinfo="none">cgrates_auth([account[, destination[, session]]])</function> - - - Does the CGRateS authorization call in an asynchronous way. Script - execution is suspended until the CGRateS engine sends the reply back. - - - Meaning of the parameters is as follows: - - - - account - the account that will be checked - in CGRateS. This parameter is optional, and if not specified, - the user in the From header is used. - - - - destination - the dialled number. Optional - parameter, if not present the request URI user is used. - - - - session - the tag of the session that - will be started if the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable - should be considered. If missing, the default set is used. - - - - - - The function can return the following values: - - - - 1 - successful call - the CGRateS account - is allowed to make the call. - - - - -1 - &osips; returned an internal error - (i.e. server is out of memory). - - - - -2 - the CGRateS engine returned error. - - - - -3 - No suitable CGRateS server found. - message type (not an initial INVITE). - - - - -4 - the SIP message is invalid: either - it has missing headers, or it is not an initial INVITE. - - - - -5 - CGRateS returned an invalid message. - - - - - <function moreinfo="none">async cgrates_auth</function> usage - -route { - ... - async(cgrates_auth("$fU", "$rU"), auth_reply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: code=$cgr_ret!\n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - - -
-
- - <function moreinfo="none">cgrates_cmd(command[, session])</function> - - - Can run an arbitrary CGRateS command in an asynchronous way. The - execution is suspended until the CGRateS engine sends the reply back. - - - Meaning of the parameters is as follows: - - - - command - the command sent to the - CGRateS engine. This is a mandatory parameter. - - - - session - the tag of the session that - will be started if the branch/call completes with success. This parameter - indicates what set of data from the $cgr() variable - should be considered. If missing, the default set is used. - - - - - - The function can return the following values: - - - - 1 - successful call - the CGRateS account - is allowed to make the call. - - - -1 - &osips; returned an internal error - (i.e. server is out of memory). - - - - -2 - the CGRateS engine returned error. - - - - -3 - No suitable CGRateS server found. - message type (not an initial INVITE). - - - - - <function moreinfo="none">async cgrates_cmd compat_mode</function> usage - -route { - ... - $cgr(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - async(cgrates_cmd("SMGenericV1.GetMaxUsage"), auth_reply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: code=$cgr_ret!\n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - - - - <function moreinfo="none">async cgrates_cmd new</function> usage - -route { - ... - $cgr_opt(Tenant) = $fd; - $cgr(Account) = $fU; - $cgr(OriginID) = $ci; - $cgr(SetupTime) = "" + $Ts; - $cgr(RequestType) = "*prepaid"; - $cgr(Destination) = $rU; - async(cgrates_cmd("SessionSv1.AuthorizeEventWithDigest"), auth_reply); -} - -route [auth_reply] -{ - if ($rc < 0) { - xlog("Call not authorized: MaxUsage=$cgr_ret(MaxUsage)!\n"); - send_reply(403, "Forbidden"); - exit; - } - ... -} - - -
-
- -
- diff --git a/modules/cgrates/doc/contributors.xml b/modules/cgrates/doc/contributors.xml deleted file mode 100644 index 34190a4c6e8..00000000000 --- a/modules/cgrates/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 192 - 99 - 7282 - 1877 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 16 - 10 - 138 - 190 - - - 3. - Liviu Chircu (@liviuchircu) - 14 - 11 - 56 - 65 - - - 4. - Maksym Sobolyev (@sobomax) - 7 - 5 - 18 - 18 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 20 - 21 - - - 6. - wuhanck - 3 - 1 - 3 - 3 - - - 7. - James Stanley - 3 - 1 - 1 - 1 - - - 8. - Nick Altmann (@nikbyte) - 3 - 1 - 1 - 1 - - - 9. - Bradley Jokinen - 2 - 1 - 6 - 0 - - - 10. - Razvan - 2 - 1 - 4 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Dec 2016 - Jun 2025 - - - 2. - Nick Altmann (@nikbyte) - Feb 2025 - Feb 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Nov 2017 - Apr 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Jul 2017 - Nov 2023 - - - 5. - James Stanley - Mar 2023 - Mar 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2017 - Mar 2020 - - - 8. - Razvan - Dec 2018 - Dec 2018 - - - 9. - wuhanck - Apr 2018 - Apr 2018 - - - 10. - Bradley Jokinen - Jul 2017 - Jul 2017 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/clusterer/README b/modules/clusterer/README deleted file mode 100644 index cb46a60389a..00000000000 --- a/modules/clusterer/README +++ /dev/null @@ -1,1519 +0,0 @@ -CLUSTERER Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Capabilities layer - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. my_node_id - 1.4.2. db_mode - 1.4.3. db_url - 1.4.4. db_table - 1.4.5. sharing_tag - 1.4.6. my_node_info - 1.4.7. neighbor_node_info - 1.4.8. ping_interval - 1.4.9. ping_timeout - 1.4.10. node_timeout - 1.4.11. seed_fallback_interval - 1.4.12. sync_timeout - 1.4.13. sync_packet_size - 1.4.14. dispatch_jobs - 1.4.15. id_col - 1.4.16. cluster_id_col - 1.4.17. node_id_col - 1.4.18. url_col - 1.4.19. state_col - 1.4.20. no_ping_retries_col - 1.4.21. priority_col - 1.4.22. sip_addr_col - 1.4.23. flags_col - 1.4.24. description_col - 1.4.25. enable_stats (integer) - 1.4.26. enable_rerouting (integer) - - 1.5. Exported Functions - - 1.5.1. cluster_send_req(cluster_id, dst_id, msg, - [tag]) - - 1.5.2. cluster_send_rpl(cluster_id, dst_id, msg, - tag) - - 1.5.3. cluster_broadcast_req(cluster_id, msg, [tag], - [include_self]) - - 1.5.4. cluster_check_addr(cluster_id, ip, addr_type) - - 1.6. Exported MI Functions - - 1.6.1. clusterer_reload - 1.6.2. clusterer_list - 1.6.3. clusterer_list_topology - 1.6.4. clusterer_set_status - 1.6.5. clusterer_remove_node - 1.6.6. cluster_send_mi - 1.6.7. cluster_broadcast_mi - 1.6.8. clusterer_list_cap - 1.6.9. clusterer_set_cap_status - 1.6.10. clusterer_shtag_set_active - 1.6.11. clusterer_list_shtags - - 1.7. Exported Script Variables - - 1.7.1. $cluster.sh_tag - - 1.8. Exported Events - - 1.8.1. E_CLUSTERER_REQ_RECEIVED - 1.8.2. E_CLUSTERER_RPL_RECEIVED - 1.8.3. E_CLUSTERER_NODE_STATE_CHANGED - 1.8.4. E_CLUSTERER_SHARING_TAG_CHANGED - - 1.9. Exported Status/Report Identifiers - - 1.9.1. sharing_tags - 1.9.2. node_states - 1.9.3. cap:[capability_name] - - 1.10. Usage Example - 1.11. Exported Statistics - - 1.11.1. clusterer_nodes - 1.11.2. clusterer_nodes_up - 1.11.3. clusterer_nodes_down - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. get_nodes(cluster_id) - 2.1.2. free_nodes(list) - 2.1.3. set_state(cluster_id, state) - 2.1.4. check_addr(cluster_id, su) - 2.1.5. get_my_id() - 2.1.6. send_to(packet, cluster_id, node_id) - 2.1.7. send_all(packet, cluster_id) - 2.1.8. get_next_hop(cluster_id, node_id) - 2.1.9. free_next_hop(next_hop) - 2.1.10. register_module(mod_name, cb, auth_check, - accept_clusters_ids, no_accept_clusters) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set my_node_id parameter - 1.2. Set db_mode parameter - 1.3. Set db_url parameter - 1.4. Set db_table parameter - 1.5. Set sharing_tag parameter - 1.6. Set my_node_info parameter - 1.7. Set neighbor_node_info parameter - 1.8. Set ping_interval parameter - 1.9. Set ping_timeout parameter - 1.10. Set node_timeout parameter - 1.11. Set seed_fallback_interval parameter - 1.12. Set sync_timeout parameter - 1.13. Set sync_packet_size parameter - 1.14. Set dispatch_jobs parameter - 1.15. Set id_col parameter - 1.16. Set cluster_id_col parameter - 1.17. Set node_id_col parameter - 1.18. Set url_col parameter - 1.19. Set state_col parameter - 1.20. Set no_ping_retries_col parameter - 1.21. Set priority_col parameter - 1.22. Set sip_addr_col parameter - 1.23. Set flags_col parameter - 1.24. Set description_col parameter - 1.25. Set enable_stats parameter - 1.26. Set enable_rerouting parameter - 1.27. cluster_send_req() usage - 1.28. cluster_send_rpl() usage - 1.29. cluster_broadcast_req() usage - 1.30. cluster_check_addr() usage - 1.31. clusterer_list usage - 1.32. clusterer_list_topology usage - 1.33. clusterer_list_cap usage - 1.34. Example database content - clusterer table - 1.35. Node A configuration - 1.36. Node B configuration - -Chapter 1. Admin Guide - -1.1. Overview - - The clusterer module is used to organize multiple OpenSIPS - instances into groups(clusters) in which the nodes can - communicate with each other in order to replicate, share - information or perform distributed tasks. The distributed logic - is performed either by different modules that use the clusterer - interface (i.e. the dialog module can replicate - dialogs/profiles, the ratelimit module can share pipes across - multiple instances etc.) or at the script level. The clusterer - module itself only provides an interface to send/receive BIN - packets and get notifications about node availability. It - achieves this by internally learning the cluster topology and - state of the nodes. Provisioning the nodes within a cluster is - done over the database or through the configuration script. The - node-related information can be checked and triggered to be - reloaded by sending commands over the MI interface. - - The topology established by the clusterer module is an overlay - of nodes where the "links" represent communication availability - at BIN interface level. For this purpose, a probing mechanism - is used, consisting of regular pings to all nodes in a cluster - for which replies must be received within a given interval. All - nodes in the cluster exchange information about the state of - their links with other nodes and compute a "routing table" - which gives a next hop for each destination. The metric for the - shortest path is the number of hops. When there is no direct - link to a destination, the BIN packet sent by a module is - transparently routed through the cluster. - - Note that an OpenSIPS instance can belong to multiple clusters, - communicating and establishing the topology separately for each - one. In order to provision this in the database or the script, - each node has an unique ID at global level, which can be - referenced in each cluster. - - An OpenSIPS instance can dynamically learn all the nodes in the - cluster if database provisioning is not desired. It is enough - to define at least one neigbour in the script in order to - discover all the cluster components. - -1.2. Capabilities layer - - The clusterer module also keeps track of the state of the nodes - in terms of data synchronization for the functionalities (or - "capabilities") implemented on top by other modules. Some - capabilities require a full data sync(at OpenSIPS startup or at - runtime via MI) from a valid "donor" node in the cluster that - has the full data set. Furthermore, a capability can query the - clusterer module in order to partition some distributed logic - only over the synchronized nodes in the cluster. - - Each node in the cluster starts with an empty dataset and tries - to find a suitable node to pull data from. In order to help - "bootstrap" the cluster, a "seed" node should be defined. This - is done by setting the value seed for the flags column in the - clusterer table(or the property with the same name in the - my_node_info parameter). The seed node will simply fall back to - a "synced" state after a configurable interval( - seed_fallback_interval parameter). Note that this mechanism is - required only for capabilities that synchronize data at - startup, so check the corresponding modules documentation. - - The clusterer module transparently exposes the sip_addr column - from the clusterer table(or the property with the same name in - the my_node_info parameter) to the modules on top so check the - corresponding modules documentation for the use of this node - related information. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module - if db_mode is 1. - * proto_bin module. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. my_node_id - - The id of the local instance. This parameter must be equal to - one of the node_id fields in the database. - - No default value. This parameter must be explicitly set to a - value greater than zero. - - Example 1.1. Set my_node_id parameter -... -modparam("clusterer", "my_node_id", 1) -... - -1.4.2. db_mode - - Specifies whether the node information for the local instance, - as well as other instances in the cluster, should be loaded - from the database or configured in the script(see my_node_info - and neighbor_node_info). A value of “0” means that DB is not - used and the cluster topology in terms of node information will - be discovered dynamically at runtime. - - If DB mode is enabled, only the nodes defined in the database - will be accepted by this instance. - - Default value is “1” - - Example 1.2. Set db_mode parameter -... -modparam("clusterer", "db_mode", 0) -... - -1.4.3. db_url - - The database url. - - Default value is “NULL”. - - Example 1.3. Set db_url parameter -... -modparam("clusterer", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - -1.4.4. db_table - - The name of the table storing the clustering information. - - Default value is “clusterer”. - - Example 1.4. Set db_table parameter -... -modparam("clusterer", "db_table", "clusterer") -... - -1.4.5. sharing_tag - - The definition of a sharing tag. The sharing tag is managed by - the clusterer module, but can be used (in terms of reading its - state) by any module build on top of clusterer engine, like - dialog or presence. - - Note that other tags may be dynamically learned during runtime - via clustering communication with other nodes. - - The format for this value is “tag_name / cluster_id = - active/backup”. - - Multiple definitions of this parameter are allowed. The default - value is “none”. - - Example 1.5. Set sharing_tag parameter -... -modparam("clusterer", "sharing_tag", "vip1/2=active") -modparam("clusterer", "sharing_tag", "node/10=backup") -... - -1.4.6. my_node_info - - Node specification similar to the information provided by a row - in the clusterer DB table corresponding to the local instance. - This parameter can be set multiple times in order to include - the local node in multiple clusters. - - Parameter format: multiple "prop=value" property definitions - separated by ',' where the name of the properties is the same - as the DB column names. At least the cluster_id and url - properties must be defined. - - This parameter is required if db_mode is set to “0” in order to - properly advertise information about the local instance in the - dynamic node learning process. - - Example 1.6. Set my_node_info parameter -... -modparam("clusterer", "my_node_info", "cluster_id=1, url=bin:192.168.0.5 -:5566") -... - -1.4.7. neighbor_node_info - - Node specification similar to the information provided by a row - in the clusterer DB table corresponding to another instance in - the cluster. This node will be the entry point in the cluster - for the local instance in the dynamic node learning process. - This parameter can be set multiple times to define multiple - neigbors to connect to (or the same neighbor but in different - clusters). - - Parameter format: multiple "prop=value" property definitions - separated by ',' where the name of the properties is the same - as the DB column names. At least the cluster_id, node_id and - url properties must be defined. - - This parameter should be set at least once if db_mode is set to - 0 in order to properly learn the cluster topology. If not set, - the only way to learn the node topology is by other nodes - connecting to the local instance. - - Example 1.7. Set neighbor_node_info parameter -... -modparam("clusterer", "neighbor_node_info", "cluster_id=1,node_id=2,url= -bin:192.168.0.6:5566") -... - -1.4.8. ping_interval - - The interval in seconds between regular pings sent to a - neighbour node. - - Default value is “4” - - Example 1.8. Set ping_interval parameter -... -modparam("clusterer", "ping_interval", 1) -... - -1.4.9. ping_timeout - - The time in milliseconds to wait for a reply to a previously - sent ping before retrying or considering the link with the - neighbour node down. This is also the interval between - successive retries if the send fails. - - Default value is “1000” - - Example 1.9. Set ping_timeout parameter -... -modparam("clusterer", "ping_timeout", 500) -... - -1.4.10. node_timeout - - The time in seconds to wait before pinging is restarted for a - failed node. - - Default value is “60” - - Example 1.10. Set node_timeout parameter -... -modparam("clusterer", "node_timeout", 10) -... - -1.4.11. seed_fallback_interval - - Only relevant for "seed" nodes. The time, in seconds, to wait - for a suitable donor node before falling back to a "synced" - state, following a node restart or an MI cluster sync command. - - Default value is “5”. - - Example 1.11. Set seed_fallback_interval parameter -... -modparam("clusterer", "seed_fallback_interval", 10) -... - -1.4.12. sync_timeout - - The inteval, in seconds, since the last sync data packet - received after which to consider the sync process as failed and - revert the node to the not synced state. - - Default value is “15”. - - Example 1.12. Set sync_timeout parameter -... -modparam("clusterer", "sync_timeout", 5) -... - -1.4.13. sync_packet_size - - The maximum size of the BIN packets sent while doing data - synchronization. This is only a suggested value as the actual - size of the packets may be slightly larger. - - Default value is “65535”. - - Example 1.13. Set sync_packet_size parameter -... -modparam("clusterer", "sync_packet_size", 32765) -... - -1.4.14. dispatch_jobs - - Enables the dispatching of jobs(processing replicated data - packets) from the receiving TCP worker process to free opensips - workers (including UDP, timer processes etc.). - - This generally improves the performance of handling replication - packets in high traffic scenarios and should not be disabled. - - Nevertheless there are cases where the "thundering herd" - problem occurs which causes abnormaly high CPU loads. Disabling - this dispatching mechanism solves such issues. - - Default value is “1” (enabled). - - Example 1.14. Set dispatch_jobs parameter -... -modparam("clusterer", "dispatch_jobs", 0) -... - -1.4.15. id_col - - The name of the column storing an id for the table rows. - - Default value is “id”. - - Example 1.15. Set id_col parameter -... -modparam("clusterer", "id_col", "id") -... - -1.4.16. cluster_id_col - - The name of the column to store the id of a cluster. - - Default value is “cluster_id”. - - Example 1.16. Set cluster_id_col parameter -... -modparam("clusterer", "cluster_id_col", "cluster_id") -... - -1.4.17. node_id_col - - The name of the column to store the id of an instance. The - values must be greater than 0. - - Default value is “node_id”. - - Example 1.17. Set node_id_col parameter -... -modparam("clusterer", "node_id_col", "node_id") -... - -1.4.18. url_col - - The name of the column containing the instance url. The values - must be greater than 0. - - Default value is “url”. - - Example 1.18. Set url_col parameter -... -modparam("clusterer", "url_col", "url") -... - -1.4.19. state_col - - The name of the column storing the state of the - node(enabled/disabled). - - Default value is “state”. - - Example 1.19. Set state_col parameter -... -modparam("clusterer", "state_col", "state") -... - -1.4.20. no_ping_retries_col - - The name of the column containing the maximum number of ping - retries before the link with the neighbour node is considered - down. - - Default value is “no_ping_retries”. - - Example 1.20. Set no_ping_retries_col parameter -... -modparam("clusterer", "no_ping_retries_col", "no_ping_retries") -... - -1.4.21. priority_col - - The name of the column storing the node priority to be chosen - as next hop in case of same length(number of hops) paths when - rerouting messages. - - Default value is “priority”. - - Example 1.21. Set priority_col parameter -... -modparam("clusterer", "priority_col", "priority") -... - -1.4.22. sip_addr_col - - The name of the column containing a SIP address for the node. - - Default value is “sip_addr”. - - Example 1.22. Set sip_addr_col parameter -... -modparam("clusterer", "sip_addr_col", "sip_addr") -... - -1.4.23. flags_col - - The name of the column containing the node flags. - - Default value is “flags”. - - Example 1.23. Set flags_col parameter -... -modparam("clusterer", "flags_col", "flags") -... - -1.4.24. description_col - - The name of the column containing a node description. - - Default value is “description”. - - Example 1.24. Set description_col parameter -... -modparam("clusterer", "description_col", "description") -... - -1.4.25. enable_stats (integer) - - If the statistics support should be enabled or not. Via - statistic variables, the module provide information about the - cluster nodes. Set it to zero to disable or to non-zero to - enable it. - - Default value is “1 (enabled)”. - - Example 1.25. Set enable_stats parameter -... -modparam("clusterer", "enable_stats", 0) -... - -1.4.26. enable_rerouting (integer) - - If packets should be rerouted via another node if a direct - route to destination is unavailible. Disabling may improve - stability in two-node topologies. Set it to zero to disable or - to non-zero to enable it. - - Default value is “1 (enabled)”. - - Example 1.26. Set enable_rerouting parameter -... -modparam("clusterer", "enable_rerouting", 0) -... - -1.5. Exported Functions - -1.5.1. cluster_send_req(cluster_id, dst_id, msg, [tag]) - - This function is used to send a generic, request-like message, - containing custom data, to a specific node in a cluster, - directly from the script. The message is not a "request" per se - but according to the logic on the receiving side, that node can - send back a reply. In order to correlate a received reply with - the request sent out, the function returns, through the tag - parameter, a randomly generated communication tag, which is - sent along in the the original message, that can be checked - against the tag received in a reply. - - Meaning of the parameters is as follows: - * cluster_id (int) - the cluster ID of the destination node; - * dst_id (int) - the ID of the destiantion node; - * msg (string) - actual message payload; - * tag (var, optional) - randomly generated communication tag. - - The function can return the following values: - * 1 - successfully sent message to destination node or a - valid next hop - * -1 - local node is disabled so sending is impossbile - * -2 - destination node is not reachable through any path - according to the discovered topology - * -3 - destination node or valid next hop appear to be - reachable but send failed or other OpenSIPS internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - Example 1.27. cluster_send_req() usage -... -# send a request -cluster_send_req(1, 1, "Check USER: $fU", $var(req_tag)); -# wait for reply -$avp(filter) = "tag=" + $var(req_tag); -async(wait_for_event("E_CLUSTERER_RPL_RECEIVED", $avp(filter), 5), rpl_r -esume); -# done -... -route[rpl_resume] { - xlog("Received reply: $avp(msg)\n"); -} -... - -1.5.2. cluster_send_rpl(cluster_id, dst_id, msg, tag) - - This function is used to send a generic, reply-like message, - containing custom data, to a specific node in a cluster, - directly from the script. The message is marked as a "reply" so - this function should ony be used for replying to a previously - request-like message received. In order for the other node, - which initially sent a request, to be able to correlate it with - this reply, a communication tag, received along with the - request, should be passed to the function. - - Meaning of the parameters is as follows: - * cluster_id (int) - the cluster ID of the destination node; - * dst_id (int) - the ID of the destiantion node; - * msg (string) - actual message payload; - * tag (var) - communication tag. - - The function can return the following values: - * 1 - successfully sent message to destination node or a - valid next hop - * -1 - local node is disabled so sending is impossbile - * -2 - destination node is not reachable through any path - according to the discovered topology - * -3 - destination node or valid next hop appear to be - reachable but send failed or other OpenSIPS internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - Example 1.28. cluster_send_rpl() usage -... -event_route[E_CLUSTERER_REQ_RECEIVED] { - cluster_send_rpl($param(cluster_id), $param(src_id), $var(my_reply), $ -param(tag)); -} -... - -1.5.3. cluster_broadcast_req(cluster_id, msg, [tag], [include_self]) - - This function has a similar behaviour to the cluster_send_req() - function with the exception that the message is sent to all the - nodes in the specified cluster. - * include_self (bool, optional, default: false) - raise the - event for current node as well, but without actually - sending a packet (both req and rpl). - - The function can return the following values: - * 1 - successfully sent message to at least one node; - * -1 - local node is disabled so sending is impossbile; - * -2 - all nodes in the cluster are unreachable according to - the discovered topology; - * -3 - send failed for all nodes in the cluster or other - OpenSIPS internal error. - - The meaning of the parameters is the same as for - cluster_send_req(). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - Example 1.29. cluster_broadcast_req() usage -... -# also raise the event for current node -cluster_broadcast_req($var(cl_id), $var(share_data), , true); -... - -1.5.4. cluster_check_addr(cluster_id, ip, addr_type) - - This function checks whether the given IP address belongs to - one of the nodes in the cluster. - - Parameters: - * cluster_id (int) - * ip (string) - * addr_type (string, optional) - select the address of the - node that the comparison is made against, with the possible - values of: - + "sip" (default) - a node's DB provisioned SIP address - + "bin" - a node's BIN interface listener - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - Example 1.30. cluster_check_addr() usage -... -if (cluster_check_addr(1, $si)) { - ... -} -... - -1.6. Exported MI Functions - -1.6.1. clusterer_reload - - Reloads data from the clusterer database. The currently - established topology will be lost and the node will rediscover - the new topology. - - Name: clusterer_reload - - Parameters:none - - MI FIFO Command Format: - opensips-cli -x mi clusterer_reload - -1.6.2. clusterer_list - - Lists information(node id, URL, link state with that node etc.) - about the other nodes in each cluster. - - Name: clusterer_list - - Parameters:none - - Example 1.31. clusterer_list usage -$ opensips-cli -x mi clusterer_list -{ - "Clusters": [ - { - "cluster_id": 1, - "Nodes": [ - { - "node_id": 1, - "db_id": 1, - "url": "bin:127.0.0.1", - "link_state": "Up", - "next_hop": "1", - "description": "none" - } - ] - } - ] -} - -1.6.3. clusterer_list_topology - - Lists each cluster's topology from the local node's perspective - as an adjacency list. A node appears as a neighbour if the link - with that node is up. - - Note that if a node id appears in multiple clusters, it refers - to the same instance that belongs to different clusters, for - which it has a different topology. - - Name: clusterer_list_topology - - Parameters:none - - Example 1.32. clusterer_list_topology usage -$ opensips-cli -x mi clusterer_list_topology -{ - "Clusters": [ - { - "cluster_id": 1, - "Nodes": [ - { - "node_id": 2, - "Neighbours": [ - 1 - ] - }, - { - "node_id": 1, - "Neighbours": [ - 2 - ] - } - ] - } - ] -} - -1.6.4. clusterer_set_status - - Sets the status(Enabled/Disabled) of a node. If the local - instance is disabled, the node will not send any messages and - ignore received ones thus appearing as a failed node in the - topology (from the other node's perspective). If a different - node is disabled, the specified node will simply be ignored by - the local instance in terms of sending/receiving any messages, - as if no longer part of the topology. - - Name: clusterer_set_status - - Parameters: - * cluster_id - indicates the id of the cluster. - * node_id (optional) - indicates the id of the node to be - disabled. If missing, the local instance will be disalbed. - * status - indicates the new status(0 - Disabled, 1 - - Enabled). - - MI FIFO Command Format: - #disable the local instance - opensips-cli -x mi clusterer_set_status 1 0 - #disable node ID 3 - opensips-cli -x mi clusterer_set_status 1 3 0 - -1.6.5. clusterer_remove_node - - Removes a node from the cluster's topology. It is enough to run - the function on a single node in order to remove the target - node from all the other nodes in the cluster. If the node to be - removed is running when triggering this function, it will be - automatically disabled (equivalent to running - clusterer_set_status on that specific node). - - This function can only be used when db_mode is set to 0 - (disabled). - - Name: clusterer_remove_node - - Parameters: - * cluster_id - cluster ID - * node_id - ID of the node to be removed. - - MI FIFO Command Format: - opensips-cli -x mi clusterer_remove_node 1 3 - -1.6.6. cluster_send_mi - - Dispatches a given MI command to be run on a specific node in - the cluster. - - Name: cluster_send_mi - - Parameters: - * cluster_id - id of the cluster. - * destination - id of the destination node - * cmd_name - name of the MI command to be run - * cmd_params (optional) - array of parameters for the MI - command to be run - - Note that MI commands that require named parameters or arrays - as parameter values are not currently supported. - - MI FIFO Command Format: -opensips-cli -x mi cluster_send_mi 1 3 lb_reload - -1.6.7. cluster_broadcast_mi - - Dispatches a given MI command to be run on all the nodes in a - cluster. The command is also executed locally. - - Name: cluster_broadcast_mi - - Parameters: - * cluster_id - id of the cluster. - * cmd_name - name of the MI command to be run - * cmd_params (optional) - array of parameters for the MI - command to be run - - Note that MI commands that require named parameters or arrays - as parameter values are not currently supported. - - MI FIFO Command Format: -opensips-cli -x mi cluster_broadcast_mi 1 dr_reload partition_5 - -1.6.8. clusterer_list_cap - - Lists the registered capabilities and their states. - - Name: clusterer_list_cap - - Parameters:none - - Example 1.33. clusterer_list_cap usage -$ opensips-cli -x mi clusterer_list_cap -{ - "Clusters": [ - { - "cluster_id": 1, - "Capabilities": [ - { - "name": "dialog-dlg-repl", - "state": "Ok", - "enabled": "yes" - }, - { - "name": "dialog-prof-repl", - "state": "Ok", - "enabled": "yes" - } - ] - } - ] -} - -1.6.9. clusterer_set_cap_status - - Sets the status(Enabled/Disabled) of a capability. If a - capability is disabled, the node will not send any - replication/sync messages belonging to that capability. - Likewise, received messages will be dropped. Also, the - cabability will transition to a "not synced" state and the node - will no longer be able to be a donor for syncing. - - Name: clusterer_set_cap_status - - Parameters: - * cluster_id - the id of the cluster - * capability - name of the capability, as listed by - clusterer_list_cap - * status - indicates the new status(0 - Disabled, 1 - - Enabled). - - MI FIFO Command Format: - #disable dialog replication in cluster 1 - opensips-cli -x mi clusterer_set_cap_status 1 dialog-dlg --repl 0 - #enable dialog profile replication in cluster 2 - opensips-cli -x mi clusterer_set_cap_status 2 dialog-pro -f-repl 1 - -1.6.10. clusterer_shtag_set_active - - Set the given sharing tag to the active state. The information - about this change is also broadcasted in the cluster in order - to force any other node that may be active on this tag to step - down to backup. - - Name: clusterer_shtag_set_active - - Parameters: tag - the name of the tag to be set active and the - cluster it belogs to, in the format 'tag/cluster_id'. - - MI FIFO Command Format: - opensips-cli -x mi clusterer_shtag_set_active vip1/3 - -1.6.11. clusterer_list_shtags - - Lists all known sharing tags and their states. - - Name: clusterer_list_shtags - - Parameters: Command takes no parameters - - MI FIFO Command Format: - opensips-cli -x mi clusterer_list_shtags - -1.7. Exported Script Variables - -1.7.1. $cluster.sh_tag - - This is a read/write variable that allows access to the sharing - tags managed by the clusterer module. - - The name of such a variable has the format of - tag_name/cluster_id, like $cluster.sh_tag(vip/3) accessing the - sharing tag "vip" from cluster ID 3. - - When setting, a sharing tag may be only switched to active by - assigned it: - * "active" string value - * 1 or higher numerical value - - When reading it value, a sharing tag returns: - * "active" or 1 if active - * "backup" or 0 if backup - - A NULL value may returned only as a result of an internal error - (like memory errors). - -1.8. Exported Events - -1.8.1. E_CLUSTERER_REQ_RECEIVED - - This event is raised when a generic, request-like, clusterer - message is received. This type of message is sent directly from - the script and not by an OpenSIPS module. - - Parameters: - * cluster_id - The cluster ID of the source node. - * src_id - The ID of the source node. - * msg - The actual message payload. - * tag - The communication tag of this message, generated by - the source node. This could be used to send a reply - corresponding to the received message by providing the tag - to the cluster_send_rpl() function. - -1.8.2. E_CLUSTERER_RPL_RECEIVED - - This event is raised when a generic, reply-like, clusterer - message is received. This type of message is sent directly from - the script and not by an OpenSIPS module. - - Parameters: - * cluster_id - The cluster ID of the source node. - * src_id - The ID of the source node. - * msg - The actual message payload. - * tag - The communication tag of this message. This could be - used to match the received reply with a request sent with - the cluster_send_req() or cluster_broadcast_req() - functions. - -1.8.3. E_CLUSTERER_NODE_STATE_CHANGED - - This event is raised when the state of a node changes in terms - of availability. - - Parameters: - * cluster_id - The cluster ID. - * node_id - The ID of the node. - * new_state - The new state of the node, with the possible - values: 0 - down, 1 - up. - -1.8.4. E_CLUSTERER_SHARING_TAG_CHANGED - - This event is raised when the state of a sharing tag changes. - - Parameters: - * name - The name of the sharing tag. - * cluster - The cluster ID. - * state - The new state of the sharing tag, the possible - values: "active" or "backup". - * reason - short text describing what triggered the change of - the state, like a another node stepping as active, an MI - command or script variable. - -1.9. Exported Status/Report Identifiers - - The module provides the clusterer Status/Report group. - -1.9.1. sharing_tags - - The sharing_tags identifier is provided for reporting state - changes of the sharing_tags (between active and backup), along - with the reason of the change. This identifier has a 200 - records history before discarding the old ones. -{ - "Name": "sharing_tags", - "Reports": [ - { - "Timestamp": 1652367224, - "Date": "Thu May 12 17:53:44 2022", - "Log": "TAG , cluster 1, became backup due to cluster br -oadcast from 2" - }, - { - "Timestamp": 1652367326, - "Date": "Thu May 12 17:55:26 2022", - "Log": "TAG , cluster 1, became active due to MI command -" - } - ] -} - - -1.9.2. node_states - - The node_states identifier is used for reporting node state - changes (in terms of availability). This identifier has a 200 - records history before discarding the old ones. -{ - "Name": "node_states", - "Reports": [ - { - "Timestamp": 1656489246, - "Date": "Wed Jun 29 10:54:06 2022", - "Log": "Node [2], cluster [1] is UP" - }, - { - "Timestamp": 1656489261, - "Date": "Wed Jun 29 10:54:21 2022", - "Log": "Node [2], cluster [1] is DOWN" - } - ] -} - - -1.9.3. cap:[capability_name] - - Each capability registered to the clusterer module has a - corresponding identifier, named cap:[capability_name], used for - providing the status of the data syncing for that capability. - This status reflects the progress of the syncing process and - can have the following values: - * -3 - not synced - * -2 - sync pending (waiting for either a suitable donor node - or actual sync data) - * -1 - sync in progress - * 1 - synced (either sync has completed or the capability - does not require data syncing at all) - -{ - "Name": "cap:dialog-dlg-repl", - "Readiness": true, - "Status": 1, - "Details": "synced" -}, - - The capability identifiers also provide reports regarding the - main stages of the sync process. These identifiers have a 200 - records history before discarding the old ones. -{ - "Name": "cap:dialog-dlg-repl", - "Reports": [ - { - "Timestamp": 1656966903, - "Date": "Mon Jul 4 23:35:03 2022", - "Log": "Sync requested" - }, - { - "Timestamp": 1656966904, - "Date": "Mon Jul 4 23:35:04 2022", - "Log": "Sync started from node [1]" - }, - { - "Timestamp": 1656966906, - "Date": "Mon Jul 4 23:35:06 2022", - "Log": "Sync completed, received [10000] chunks" - } - ] -}, - - - For how to access and use the Status/Report information, please - see Status/Report Interface documentation. - -1.10. Usage Example - - This section provides an usage example for replicating - ratelimit pipes between two OpenSIPS instances. It uses the - clusterer module to manage the replicating nodes, and along - with the proto_bin module, to send the replicated information. - - The setup topology is simple: we have two OpenSIPS nodes - running on two separate machines (although they could run on - the same machine as well): Node A has IP 192.168.0.5 and Node B - has IP 192.168.0.6. Both have, besides the traffic listeners - (UDP, TCP, etc.), BIN listeners bound on port 5566. These - listeners will be used for the binary communication. - - We insert in the the clusterer table the following: - - Example 1.34. Example database content - clusterer table -+----+------------+---------+----------------------+-------+------------ ------+----------+----------+-------+-------------+ -| id | cluster_id | node_id | url | state | no_ping_ret -ries | priority | sip_addr | flags | description | -+----+------------+---------+----------------------+-------+------------ ------+----------+----------+-------+-------------+ -| 10 | 1 | 1 | bin:192.168.0.5:5566 | 1 | - 3| 50 | NULL | NULL | Node A | -| 20 | 1 | 2 | bin:192.168.0.6:5566 | 1 | - 3| 50 | NULL | NULL | Node B | -+----+------------+---------+----------------------+-------+------------ ------+----------+----------+-------+-------------+ - - * “cluster_id” - identifier of the cluster. All nodes within - a group/cluster should have the same id (in our example, - both nodes have ID 1). The values must be greater than 0. - * “node_id” - identifier of the machine/node so each instance - within a cluster should have a different ID. The values - must be greater than 0. In our example, Node A will have ID - 1, and Node B ID 2. - * “url” - address where all the BIN packets for that instance - will be sent to. - * “state” - state of the node: 1 means Enabled, 0 means - Disabled. A disabled node will not send any BIN packets and - will drop received ones. - * “no_ping_retries” - maximum number of ping retries before - the link with a node is considered down. - * “priority” - the priority of a node to be chosen as next - hop in case of same length(number of hops) paths when - rerouting messages; it is not relevant for this two-node - topology example. - * “sip_addr” - SIP address for the node that is transparently - provided to modules; it has no use for the ratelimit module - in our example. - * “flags” - used to define a seed node; it has no use in our - example. - * “description” - an opaque value used to describe the node - - After provisioning the two nodes in the database, we have to - configure the two instances of OpenSIPS. First, we configure - Node A: - - Example 1.35. Node A configuration -... -socket= bin:192.168.0.5:5566 # bin listener for Node A - -loadmodule "proto_bin.so" - -loadmodule "clusterer.so" -modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") -modparam("clusterer", "my_node_id", 1) # node_id for Node A - -loadmodule "ratelimit.so" -modparam("ratelimit", "pipe_replication_cluster", 1) -... - - Similarly, the configuration for Node B is as follows: - - Example 1.36. Node B configuration -... -socket= bin:192.168.0.6:5566 # bin listener for Node B - -loadmodule "proto_bin.so" - -loadmodule "clusterer.so" -# ideally, use the same database for both nodes -modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") -modparam("clusterer", "my_node_id", 2) # node_id for Node B - -loadmodule "ratelimit.so" -modparam("ratelimit", "pipe_replication_cluster", 1) -... - - Starting the two OpenSIPS instances with the above - configurations provides your platform the ability to used - shared ratelimit pipes in a very efficient and scalable way. - -1.11. Exported Statistics - -1.11.1. clusterer_nodes - - Returns the total number of cluster nodes. - -1.11.2. clusterer_nodes_up - - Returns the total number of cluster nodes in the UP state. - -1.11.3. clusterer_nodes_down - - Returns the total number of cluster nodes not in the UP state. - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. get_nodes(cluster_id) - - This function will return a list of all the reachable nodes(if - the direct link is down/probing, a path through intermediary - nodes is considered) in the specified cluster. - - The returned nodes structure: -... -typedef struct clusterer_node { - int node_id; - union sockaddr_union addr; - str sip_addr; - str description; - struct clusterer_node *next; -} clusterer_node_t; -... - - Meaning of the parameters is as follows: - * int cluster_id - the cluster id - -2.1.2. free_nodes(list) - - This function will free the lits of nodes returned by - get_nodes. - - Meaning of the parameters is as follows: - * clusterer_node_t *list - list header - -2.1.3. set_state(cluster_id, state) - - This function sets the state(enabled/disabled) of the current - node in the specified cluster. - - Meaning of the parameters is as follows: - * int cluster_id - the cluster id - * enum cl_node_state state - the new state; possible values: - + STATE_DISABLED - + STATE_ENABLED - -2.1.4. check_addr(cluster_id, su) - - This function checks if a given address belongs to one of the - nodes in the cluster. - - Meaning of the parameters is as follows: - * int cluster_id - the cluster id - * union sockaddr_union* su - socket address - -2.1.5. get_my_id() - - This function will return the id of the current node. - -2.1.6. send_to(packet, cluster_id, node_id) - - This functon will send the given BIN packet to the specified - node in the cluster. If the direct link is down/probing, it - will send the packet to an intermediary node if the destination - node is reachable through another path in the cluster topology. - - Meaning of the parameters is as follows: - * bin_packet_t packet - the packet to be sent - * int cluster_id - the cluster id - * int node_id - the id of the destination node - - The function returns one of the following: - * CLUSTERER_SEND_SUCCESS - successfully sent packet to - destination node or a valid next hop - * CLUSTERER_CURR_DISABLED - current node is disabled so - sending is impossbile - * CLUSTERER_DEST_DOWN - destination node is not reachable - through any path according to the discovered topology - * CLUSTERER_SEND_ERR - destination node or valid next hop - appear to be reachable but send failed - -2.1.7. send_all(packet, cluster_id) - - Send the given BIN packet to all the nodes in the specified - cluster. The function operates similarly to send_to. - - Meaning of the parameters is as follows: - * bin_packet_t packet - the packet to be sent - * int cluster_id - the cluster id - - The function returns one of the following: - * CLUSTERER_SEND_SUCCESS - successfully sent packet to at - least one node - * CLUSTERER_CURR_DISABLED - current node is disabled so - sending is impossbile - * CLUSTERER_DEST_DOWN - all nodes in the cluster are - unreachable according to the discovered topology - * CLUSTERER_SEND_ERR - send failed for all nodes in the - cluster - -2.1.8. get_next_hop(cluster_id, node_id) - - This function returns the next hop from the computed shortest - path to the given destination node in the specified cluster. - This is the node that is the actual destination for the send_to - and send_all functions when the direct link with the intended - destination is down. The function returns the same structure as - get_nodes. - - Meaning of the parameters is as follows: - * int cluster_id - the cluster id - * int node_id - the node id of the destination for which the - next hop is returned. - -2.1.9. free_next_hop(next_hop) - - This function will free the next hop returned by get_next_hop. - - Meaning of the parameters is as follows: - * clusterer_node_t *next_hop - next hop to be freed - -2.1.10. register_module(mod_name, cb, auth_check, -accept_clusters_ids, no_accept_clusters) - - This function registers an OpenSIPS module in order to receive - BIN packets and cluster notifications. A certain module can - accept packets from multiple clusters and provides a single - callback function that will be called for each received packet. - This function will also be called to notify cluster events like - nodes becoming reachable/unreachable. - - Meaning of the parameters is as follows: - * char *mod_name - module name - * clusterer_cb_f cb - callback function - * int auth_check - 0 - no check, 1 - for every BIN packet - received check if source IP belongs to one of the nodes in - the cluster - * int* accept_clusters_ids - array of cluster ids from which - packets are accepted - * int no_accept_clusters - length of accept_clusters_ids - array - - The callback function prototype: -... -typedef void (*clusterer_cb_f)(enum clusterer_event ev,bin_packet_t *, i -nt packet_type, - struct receive_info *ri, int cluster_id, int src_id, int - dest_id); -... - - Possble values for the event signaled through ev parameter of - the callback funtion: - * CLUSTER_RECV_MSG - received BIN message - * CLUSTER_ROUTE_FAILED - failed to route a received BIN - packet destined for another node in the cluster - * CLUSTER_NODE_UP - a node became reachable - * CLUSTER_NODE_DOWN - a node became unreachable - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 366 135 13387 7101 - 2. Liviu Chircu (@liviuchircu) 73 55 915 595 - 3. Eseanu Marius Cristian (@eseanucristian) 46 10 3142 534 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 32 17 1343 132 - 5. Razvan Crainea (@razvancrainea) 27 21 327 148 - 6. Ionel Cerghit (@ionel-cerghit) 9 2 250 212 - 7. Maksym Sobolyev (@sobomax) 8 6 12 13 - 8. Alexandra Titoc 6 4 18 4 - 9. Jasper Hafkenscheid 4 2 107 2 - 10. Fabian Gast (@fgast) 4 2 3 3 - - All remaining contributors: Peter Lemenkov (@lemenkov), Gohar - Ahmed (@goharahmed), kworm83, Shanee Vanstone. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Peter Lemenkov (@lemenkov) Jun 2018 - Jul 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2016 - Jun 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2016 - Apr 2025 - 4. Razvan Crainea (@razvancrainea) Nov 2015 - Sep 2024 - 5. Alexandra Titoc Sep 2024 - Sep 2024 - 6. Shanee Vanstone Mar 2024 - Mar 2024 - 7. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 8. Vlad Patrascu (@rvlad-patrascu) Jul 2016 - Jul 2023 - 9. Jasper Hafkenscheid May 2022 - Jul 2022 - 10. kworm83 Feb 2021 - Feb 2021 - - All remaining contributors: Fabian Gast (@fgast), Gohar Ahmed - (@goharahmed), Ionel Cerghit (@ionel-cerghit), Eseanu Marius - Cristian (@eseanucristian). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Shanee Vanstone, Vlad Patrascu - (@rvlad-patrascu), Jasper Hafkenscheid, Fabian Gast (@fgast), - Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), - Eseanu Marius Cristian (@eseanucristian). - - Documentation Copyrights: - - Copyright © 2015-2017 www.opensips-solutions.com diff --git a/modules/clusterer/README.md b/modules/clusterer/README.md new file mode 100644 index 00000000000..9f8554070c6 --- /dev/null +++ b/modules/clusterer/README.md @@ -0,0 +1,1606 @@ +--- +title: "CLUSTERER Module" +description: "The clusterer module is used to organize multiple OpenSIPS instances into groups (clusters) in which the nodes can communicate with each other in order to replicate, share information or perform distributed tasks." +--- + +## Admin Guide + + +### Overview + + +The *clusterer* module is used to organize multiple OpenSIPS instances into groups(clusters) in which the nodes can communicate with each other in order to replicate, share information or perform distributed tasks. The distributed logic is performed either by different modules that use the *clusterer* interface (i.e. the *dialog* module can replicate dialogs/profiles, the *ratelimit* module can share pipes across multiple +instances etc.) or at the script level. The *clusterer* module itself only provides an interface to send/receive BIN packets and get notifications about node availability. It achieves this by internally learning the cluster topology and state of the nodes. Provisioning the nodes within a cluster is done over the database or through the configuration script. The node-related information can be checked and triggered to be reloaded by sending commands over the MI interface. + + +The topology established by the *clusterer* module is an overlay of nodes where the "links" represent communication availability at BIN interface level. For this purpose, a probing mechanism is used, consisting of regular pings to all nodes in a cluster for which replies must be received within a given interval. All nodes in the cluster exchange information about the state of their links with other nodes and compute a "routing table" which gives a next hop for each destination. The metric for the shortest path is the number of hops. When there is no direct link to a destination, the BIN packet sent by a module is transparently routed through the cluster. + + +Note that an OpenSIPS instance can belong to multiple clusters, communicating and establishing the topology separately for each one. In order to provision this in the database or the script, each node has an unique ID at global level, which can be referenced in each cluster. + + +An OpenSIPS instance can dynamically learn all the nodes in the cluster if database provisioning is not desired. It is enough to define at least one neigbour in the script in order to discover all the cluster components. + + +### Capabilities layer + + +The clusterer module also keeps track of the state of the nodes in terms of data synchronization for the functionalities (or "capabilities") implemented on top by other modules. Some capabilities require a full data sync(at OpenSIPS startup or at runtime via MI) from a valid "donor" node in the cluster that has the full data set. Furthermore, a capability can query the clusterer module in order to partition some distributed logic only over the synchronized nodes in the cluster. + + +Each node in the cluster starts with an empty dataset and tries to find +a suitable node to pull data from. In order to help "bootstrap" the +cluster, a "seed" node should be defined. This is done by setting the value +*seed* for the **flags** +column in the clusterer table(or the property with the same name in the +*my_node_info* parameter). The seed node will simply +fall back to a "synced" state after a configurable interval( +[seed fallback interval](#param_seed_fallback_interval) parameter). Note that +this mechanism is required only for capabilities that synchronize data +at startup, so check the corresponding modules documentation. + + +The clusterer module transparently exposes the *sip_addr* column from the clusterer table(or the property with the same name in the *my_node_info* parameter) to the modules on top so check the corresponding modules documentation for the use of this node related information. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module* - if [db mode](#param_db_mode) +is *1*. +- *proto_bin module*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### my_node_id + + +The id of the local instance. This parameter must be equal to one of the +*node_id* fields in the database. + + +*No default value. This parameter must be explicitly set to a value greater than zero.* + + +```opensips title="Set my_node_id parameter" +... +modparam("clusterer", "my_node_id", 1) +... + +``` + + +#### db_mode + + +Specifies whether the node information for the local instance, +as well as other instances in the cluster, should be loaded from +the database or configured in the script(see [my node info](#param_my_node_info) +and [neighbor node info](#param_neighbor_node_info)). A value of "0" +means that DB is not used and the cluster topology in terms of node +information will be discovered dynamically at runtime. + + +If DB mode is enabled, only the nodes defined in the database will be +accepted by this instance. + + +*Default value is "1"* + + +```opensips title="Set db_mode parameter" +... +modparam("clusterer", "db_mode", 0) +... + +``` + + +#### db_url + + +The database url. + + +*Default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("clusterer", "db_url", + "mysql://opensips:opensipsrw@localhost/opensips") +... + +``` + + +#### db_table + + +The name of the table storing the clustering information. + + +*Default value is "clusterer".* + + +```opensips title="Set db_table parameter" +... +modparam("clusterer", "db_table", "clusterer") +... + +``` + + +#### sharing_tag + + +The definition of a sharing tag. The sharing tag is +managed by the clusterer module, but can be used (in terms +of reading its state) by any module build on top of +clusterer engine, like dialog or presence. + + +Note that other tags may be dynamically learned during runtime via +clustering communication with other nodes. + + +The format for this value is "tag_name / cluster_id = active/backup". + + +Multiple definitions of this parameter are allowed. The default value is "none". + + +```opensips title="Set sharing_tag parameter" +... +modparam("clusterer", "sharing_tag", "vip1/2=active") +modparam("clusterer", "sharing_tag", "node/10=backup") +... +``` + + +#### my_node_info + + +Node specification similar to the information provided by a row in +the clusterer DB table corresponding to the local instance. This +parameter can be set multiple times in order to include the local +node in multiple clusters. + + +Parameter format: multiple "*prop=value*" property +definitions separated by '*,*' where the name of the +properties is the same as the DB column names. At least the +*cluster_id* and *url* +properties must be defined. + + +This parameter is required if [db mode](#param_db_mode) is set +to "0" in order to properly advertise information about +the local instance in the dynamic node learning process. + + +```opensips title="Set my_node_info parameter" +... +modparam("clusterer", "my_node_info", "cluster_id=1, url=bin:192.168.0.5:5566") +... + +``` + + +#### neighbor_node_info + + +Node specification similar to the information provided by a row in +the clusterer DB table corresponding to another instance in the +cluster. This node will be the entry point in the cluster for the +local instance in the dynamic node learning process. This parameter +can be set multiple times to define multiple neigbors to connect to (or +the same neighbor but in different clusters). + + +Parameter format: multiple "*prop=value*" property +definitions separated by '*,*' where the name of +the properties is the same as the DB column names. At least the +*cluster_id*, *node_id* +and *url* properties must be defined. + + +This parameter should be set at least once if +[db mode](#param_db_mode) is set to *0* in order +to properly learn the cluster topology. If not set, the only way to learn +the node topology is by other nodes connecting to the local instance. + + +```opensips title="Set neighbor_node_info parameter" +... +modparam("clusterer", "neighbor_node_info", "cluster_id=1,node_id=2,url=bin:192.168.0.6:5566") +... + +``` + + +#### ping_interval + + +The interval in seconds between regular pings sent to a neighbour node. + + +*Default value is "4"* + + +```opensips title="Set ping_interval parameter" +... +modparam("clusterer", "ping_interval", 1) +... + +``` + + +#### ping_timeout + + +The time in milliseconds to wait for a reply to a previously sent ping before retrying or considering the link with the neighbour node down. This is also the interval between successive retries if the send fails. + + +*Default value is "1000"* + + +```opensips title="Set ping_timeout parameter" +... +modparam("clusterer", "ping_timeout", 500) +... + +``` + + +#### node_timeout + + +The time in seconds to wait before pinging is restarted for a failed node. + + +*Default value is "60"* + + +```opensips title="Set node_timeout parameter" +... +modparam("clusterer", "node_timeout", 10) +... + +``` + + +#### seed_fallback_interval + + +Only relevant for "seed" nodes. The time, in seconds, to wait +for a suitable donor node before falling back to a "synced" +state, following a node restart or an MI cluster sync command. + + +*Default value is "5".* + + +```opensips title="Set seed_fallback_interval parameter" +... +modparam("clusterer", "seed_fallback_interval", 10) +... + +``` + + +#### sync_timeout + + +The inteval, in seconds, since the last sync data packet received +after which to consider the sync process as failed and revert the +node to the not synced state. + + +*Default value is "15".* + + +```opensips title="Set sync_timeout parameter" +... +modparam("clusterer", "sync_timeout", 5) +... + +``` + + +#### sync_packet_size + + +The maximum size of the BIN packets sent while doing data synchronization. This is only a suggested value as the actual size of the packets may be slightly larger. + + +*Default value is "65535".* + + +```opensips title="Set sync_packet_size parameter" +... +modparam("clusterer", "sync_packet_size", 32765) +... + +``` + + +#### dispatch_jobs + + +Enables the dispatching of jobs(processing replicated data packets) +from the receiving TCP worker process to free opensips workers +(including UDP, timer processes etc.). + + +This generally improves the performance of handling replication packets +in high traffic scenarios and should not be disabled. + + +Nevertheless there are cases where the "thundering herd" problem occurs +which causes abnormaly high CPU loads. Disabling this dispatching +mechanism solves such issues. + + +*Default value is "1" (enabled).* + + +```opensips title="Set dispatch_jobs parameter" +... +modparam("clusterer", "dispatch_jobs", 0) +... + +``` + + +#### id_col + + +The name of the column storing an id for the table rows. + + +*Default value is "id".* + + +```opensips title="Set id_col parameter" +... +modparam("clusterer", "id_col", "id") +... + +``` + + +#### cluster_id_col + + +The name of the column to store the id of a cluster. + + +*Default value is "cluster_id".* + + +```opensips title="Set cluster_id_col parameter" +... +modparam("clusterer", "cluster_id_col", "cluster_id") +... + +``` + + +#### node_id_col + + +The name of the column to store the id of an instance. The values must be greater than 0. + + +*Default value is "node_id".* + + +```opensips title="Set node_id_col parameter" +... +modparam("clusterer", "node_id_col", "node_id") +... + +``` + + +#### url_col + + +The name of the column containing the instance url. The values must be greater than 0. + + +*Default value is "url".* + + +```opensips title="Set url_col parameter" +... +modparam("clusterer", "url_col", "url") +... + +``` + + +#### state_col + + +The name of the column storing the state of the node(enabled/disabled). + + +*Default value is "state".* + + +```opensips title="Set state_col parameter" +... +modparam("clusterer", "state_col", "state") +... + +``` + + +#### no_ping_retries_col + + +The name of the column containing the maximum number of ping retries before the link with the neighbour node is considered down. + + +*Default value is "no_ping_retries".* + + +```opensips title="Set no_ping_retries_col parameter" +... +modparam("clusterer", "no_ping_retries_col", "no_ping_retries") +... + +``` + + +#### priority_col + + +The name of the column storing the node priority to be chosen as next hop in case of same length(number of hops) paths when rerouting messages. + + +*Default value is "priority".* + + +```opensips title="Set priority_col parameter" +... +modparam("clusterer", "priority_col", "priority") +... + +``` + + +#### sip_addr_col + + +The name of the column containing a SIP address for the node. + + +*Default value is "sip_addr".* + + +```opensips title="Set sip_addr_col parameter" +... +modparam("clusterer", "sip_addr_col", "sip_addr") +... + +``` + + +#### flags_col + + +The name of the column containing the node flags. + + +*Default value is "flags".* + + +```opensips title="Set flags_col parameter" +... +modparam("clusterer", "flags_col", "flags") +... + +``` + + +#### description_col + + +The name of the column containing a node description. + + +*Default value is "description".* + + +```opensips title="Set description_col parameter" +... +modparam("clusterer", "description_col", "description") +... + +``` + + +#### enable_stats (integer) + + +If the statistics support should be enabled or not. Via statistic +variables, the module provide information about the cluster nodes. +Set it to zero to disable or to non-zero to enable it. + + +*Default value is "1 (enabled)".* + + +```opensips title="Set enable_stats parameter" +... +modparam("clusterer", "enable_stats", 0) +... + +``` + + +#### enable_rerouting (integer) + + +If packets should be rerouted via another node if a direct route +to destination is unavailible. Disabling may improve stability in +two-node topologies. +Set it to zero to disable or to non-zero to enable it. + + +*Default value is "1 (enabled)".* + + +```opensips title="Set enable_rerouting parameter" +... +modparam("clusterer", "enable_rerouting", 0) +... + +``` + + +### Exported Functions + + +#### cluster_send_req(cluster_id, dst_id, msg, [tag]) + + +This function is used to send a generic, request-like message, containing custom data, to a specific node in a cluster, directly from the script. The message is not a "request" per se but according to the logic on the receiving side, that node can send back a reply. In order to correlate a received reply with the request sent out, the function returns, through the *tag* parameter, a randomly generated communication tag, which is sent along in the the original message, that can be checked against the tag received in a reply. + + +Meaning of the parameters is as follows: + + +- *cluster_id* (int) - the cluster ID of the destination node; +- *dst_id* (int) - the ID of the destiantion node; +- *msg* (string) - actual message payload; +- *tag* (var, optional) - randomly generated communication tag. + + +The function can return the following values: + + +- *1* - successfully sent message to destination node or a valid next hop +- *-1* - local node is disabled so sending is impossbile +- *-2* - destination node is not reachable through any path according to the discovered topology +- *-3* - destination node or valid next hop appear to be reachable but send failed or other OpenSIPS internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. + + +```opensips title="cluster_send_req() usage" +... +# send a request +cluster_send_req(1, 1, "Check USER: $fU", $var(req_tag)); +# wait for reply +$avp(filter) = "tag=" + $var(req_tag); +async(wait_for_event("E_CLUSTERER_RPL_RECEIVED", $avp(filter), 5), rpl_resume); +# done +... +route[rpl_resume] { + xlog("Received reply: $avp(msg)\n"); +} +... + +``` + + +#### cluster_send_rpl(cluster_id, dst_id, msg, tag) + + +This function is used to send a generic, reply-like message, containing custom data, to a specific node in a cluster, directly from the script. The message is marked as a "reply" so this function should ony be used for replying to a previously request-like message received. In order for the other node, which initially sent a request, to be able to correlate it with this reply, a communication tag, received along with the request, should be passed to the function. + + +Meaning of the parameters is as follows: + + +- *cluster_id* (int) - the cluster ID of the destination node; +- *dst_id* (int) - the ID of the destiantion node; +- *msg* (string) - actual message payload; +- *tag* (var) - communication tag. + + +The function can return the following values: + + +- *1* - successfully sent message to destination node or a valid next hop +- *-1* - local node is disabled so sending is impossbile +- *-2* - destination node is not reachable through any path according to the discovered topology +- *-3* - destination node or valid next hop appear to be reachable but send failed or other OpenSIPS internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. + + +```opensips title="cluster_send_rpl() usage" +... +event_route[E_CLUSTERER_REQ_RECEIVED] { + cluster_send_rpl($param(cluster_id), $param(src_id), $var(my_reply), $param(tag)); +} +... + +``` + + +#### cluster_broadcast_req(cluster_id, msg, [tag], [include_self]) + + +This function has a similar behaviour to the `cluster_send_req()` function with the exception that the message is sent to all the nodes in the specified cluster. + + +- *include_self* (bool, optional, default: *false*) - raise the event for current node as well, but without actually sending a packet (both req and rpl). + + +The function can return the following values: + + +- *1* - successfully sent message to at least one node; +- *-1* - local node is disabled so sending is impossbile; +- *-2* - all nodes in the cluster are unreachable according to the discovered topology; +- *-3* - send failed for all nodes in the cluster or other OpenSIPS internal error. + + +The meaning of the parameters is the same as for `cluster_send_req()`. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. + + +```opensips title="cluster_broadcast_req() usage" +... +# also raise the event for current node +cluster_broadcast_req($var(cl_id), $var(share_data), , true); +... + +``` + + +#### cluster_check_addr(cluster_id, ip, addr_type) + + +This function checks whether the given IP address belongs +to one of the nodes in the cluster. + + +Parameters: + + +- *cluster_id* (int) +- *ip* (string) +- *addr_type* (string, optional) - +select the address of the node that the comparison +is made against, with the possible values of: + * *"sip"* (default) - a node's DB provisioned SIP address + * *"bin"* - a node's BIN interface listener + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. + + +```opensips title="cluster_check_addr() usage" +... +if (cluster_check_addr(1, $si)) { + ... +} +... + +``` + + +### Exported MI Functions + + +#### clusterer_reload + + +Reloads data from the clusterer database. The currently established topology will be lost and the node will rediscover the new topology. + + +Name: *clusterer_reload* + + +Parameters:*none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi clusterer_reload +``` + + +#### clusterer_list + + +Lists information(node id, URL, link state with that node etc.) about the other nodes in each cluster. + + +Name: *clusterer_list* + + +Parameters:*none* + + +```bash title="clusterer_list usage" +$ opensips-cli -x mi clusterer_list +{ + "Clusters": [ + { + "cluster_id": 1, + "Nodes": [ + { + "node_id": 1, + "db_id": 1, + "url": "bin:127.0.0.1", + "link_state": "Up", + "next_hop": "1", + "description": "none" + } + ] + } + ] +} +``` + + +#### clusterer_list_topology + + +Lists each cluster's topology from the local node's perspective as an adjacency list. A node appears as a neighbour if the link with that node is up. + + +Note that if a node id appears in multiple clusters, it refers to the same instance that belongs to different clusters, for which it has a different topology. + + +Name: *clusterer_list_topology* + + +Parameters:*none* + + +```bash title="clusterer_list_topology usage" +$ opensips-cli -x mi clusterer_list_topology +{ + "Clusters": [ + { + "cluster_id": 1, + "Nodes": [ + { + "node_id": 2, + "Neighbours": [ + 1 + ] + }, + { + "node_id": 1, + "Neighbours": [ + 2 + ] + } + ] + } + ] +} +``` + + +#### clusterer_set_status + + +Sets the status(Enabled/Disabled) of a node. If the local instance is disabled, the node will not send any messages and ignore received ones thus appearing as a failed node in the topology (from the other node's perspective). If a different node is disabled, the specified node will simply be ignored by the local instance in terms of sending/receiving any messages, as if no longer part of the topology. + + +Name: *clusterer_set_status* + + +Parameters: + + +- *cluster_id* - indicates the id of the cluster. +- *node_id* (optional) - indicates the id of the node to be disabled. +If missing, the local instance will be disalbed. +- *status* - indicates the new status(0 - Disabled, 1 - Enabled). + + +MI FIFO Command Format: + + +```bash +#disable the local instance +opensips-cli -x mi clusterer_set_status 1 0 +#disable node ID 3 +opensips-cli -x mi clusterer_set_status 1 3 0 +``` + + +#### clusterer_remove_node + + +Removes a node from the cluster's topology. It is enough to run the function +on a single node in order to remove the target node from all the other +nodes in the cluster. If the node to be removed is running when triggering +this function, it will be automatically disabled (equivalent to running +[mi clusterer set status](#mi_clusterer_set_status) on that specific node). + + +This function can only be used when [db mode](#param_db_mode) is set to +*0* (disabled). + + +Name: *clusterer_remove_node* + + +Parameters: + + +- *cluster_id* - cluster ID +- *node_id* - ID of the node to be removed. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi clusterer_remove_node 1 3 +``` + + +#### cluster_send_mi + + +Dispatches a given MI command to be run on a specific node in the cluster. + + +Name: *cluster_send_mi* + + +Parameters: + + +- *cluster_id* - id of the cluster. +- *destination* - id of the destination node +- *cmd_name* - name of the MI command to be run +- *cmd_params* (optional) - array of parameters for +the MI command to be run + + +Note that MI commands that require named parameters or arrays as +parameter values are not currently supported. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi cluster_send_mi 1 3 lb_reload +``` + + +#### cluster_broadcast_mi + + +Dispatches a given MI command to be run on all the nodes in a cluster. The command is also executed locally. + + +Name: *cluster_broadcast_mi* + + +Parameters: + + +- *cluster_id* - id of the cluster. +- *cmd_name* - name of the MI command to be run +- *cmd_params* (optional) - array of parameters for +the MI command to be run + + +Note that MI commands that require named parameters or arrays as +parameter values are not currently supported. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi cluster_broadcast_mi 1 dr_reload partition_5 +``` + + +#### clusterer_list_cap + + +Lists the registered capabilities and their states. + + +Name: *clusterer_list_cap* + + +Parameters:*none* + + +```bash title="clusterer_list_cap usage" +$ opensips-cli -x mi clusterer_list_cap +{ + "Clusters": [ + { + "cluster_id": 1, + "Capabilities": [ + { + "name": "dialog-dlg-repl", + "state": "Ok", + "enabled": "yes" + }, + { + "name": "dialog-prof-repl", + "state": "Ok", + "enabled": "yes" + } + ] + } + ] +} +``` + + +#### clusterer_set_cap_status + + +Sets the status(Enabled/Disabled) of a capability. If a capability is disabled, the node will not send any replication/sync messages belonging to that capability. Likewise, received messages will be dropped. Also, the cabability will transition to a "not synced" state and the node will no longer be able to be a donor for syncing. + + +Name: *clusterer_set_cap_status* + + +Parameters: + + +- *cluster_id* - the id of the cluster +- *capability* - name of the capability, as listed by +[mi clusterer list cap](#mi_clusterer_list_cap) +- *status* - indicates the new status(0 - Disabled, 1 - Enabled). + + +MI FIFO Command Format: + + +```bash +#disable dialog replication in cluster 1 +opensips-cli -x mi clusterer_set_cap_status 1 dialog-dlg-repl 0 +#enable dialog profile replication in cluster 2 +opensips-cli -x mi clusterer_set_cap_status 2 dialog-prof-repl 1 +``` + + +#### clusterer_shtag_set_active + + +Set the given sharing tag to the *active* state. +The information about this change is also broadcasted in the cluster +in order to force any other node that may be active on this tag to +step down to backup. + + +Name: *clusterer_shtag_set_active* + + +Parameters: *tag* - the name of +the tag to be set active and the cluster it belogs to, in the +format 'tag/cluster_id'. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi clusterer_shtag_set_active vip1/3 +``` + + +#### clusterer_list_shtags + + +Lists all known sharing tags and their states. + + +Name: *clusterer_list_shtags* + + +Parameters: *Command takes no parameters* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi clusterer_list_shtags +``` + + +### Exported Script Variables + + +#### $cluster.sh_tag + + +This is a read/write variable that allows access to the +sharing tags managed by the clusterer module. + + +The name of such a variable has the format of +*tag_name/cluster_id*, like +*$cluster.sh_tag(vip/3)* accessing the +sharing tag "vip" from cluster ID 3. + + +When setting, a sharing tag may be only switched to active by +assigned it: + + +- "active" +- 1 + + +When reading it value, a sharing tag returns: + + +- "active" or 1 +- "backup" or 0 + + +A NULL value may returned only as a result of an internal error +(like memory errors). + + +### Exported Events + + +#### E_CLUSTERER_REQ_RECEIVED + + +This event is raised when a generic, request-like, clusterer message is received. This type of message is sent directly from the script and not by an OpenSIPS module. + + +Parameters: + + +- *cluster_id* - The cluster ID of the source node. +- *src_id* - The ID of the source node. +- *msg* - The actual message payload. +- *tag* - The communication tag of this message, generated by the source node. This could be used to send a reply corresponding to the received message by providing the tag to the `cluster_send_rpl()` function. + + +#### E_CLUSTERER_RPL_RECEIVED + + +This event is raised when a generic, reply-like, clusterer message is received. This type of message is sent directly from the script and not by an OpenSIPS module. + + +Parameters: + + +- *cluster_id* - The cluster ID of the source node. +- *src_id* - The ID of the source node. +- *msg* - The actual message payload. +- *tag* - The communication tag of this message. This could be used to match the received reply with a request sent with the `cluster_send_req()` or `cluster_broadcast_req()` functions. + + +#### E_CLUSTERER_NODE_STATE_CHANGED + + +This event is raised when the state of a node changes in terms of +availability. + + +Parameters: + + +- *cluster_id* - The cluster ID. +- *node_id* - The ID of the node. +- *new_state* - The new state of the node, with +the possible values: 0 - down, 1 - up. + + +#### E_CLUSTERER_SHARING_TAG_CHANGED + + +This event is raised when the state of a sharing tag changes. + + +Parameters: + + +- *name* - The name of the sharing tag. +- *cluster* - The cluster ID. +- *state* - The new state of the sharing tag, +the possible values: "active" or "backup". +- *reason* - short text describing what +triggered the change of the state, like a another node +stepping as active, an MI command or script variable. + + +### Exported Status/Report Identifiers + + +The module provides the *clusterer* Status/Report group. + + +#### sharing_tags + + +The *sharing_tags* identifier is provided for reporting state +changes of the sharing_tags (between active and backup), along with the reason of +the change. This identifier has a 200 records history before discarding the old ones. + + +```json +{ + "Name": "sharing_tags", + "Reports": [ + { + "Timestamp": 1652367224, + "Date": "Thu May 12 17:53:44 2022", + "Log": "TAG , cluster 1, became backup due to cluster broadcast from 2" + }, + { + "Timestamp": 1652367326, + "Date": "Thu May 12 17:55:26 2022", + "Log": "TAG , cluster 1, became active due to MI command" + } + ] +} + + +``` + + +#### node_states + + +The *node_states* identifier is used for reporting node state +changes (in terms of availability). This identifier has a 200 records history +before discarding the old ones. + + +```json +{ + "Name": "node_states", + "Reports": [ + { + "Timestamp": 1656489246, + "Date": "Wed Jun 29 10:54:06 2022", + "Log": "Node [2], cluster [1] is UP" + }, + { + "Timestamp": 1656489261, + "Date": "Wed Jun 29 10:54:21 2022", + "Log": "Node [2], cluster [1] is DOWN" + } + ] +} + + +``` + + +#### cap:[capability_name] + + +Each capability registered to the clusterer module has a corresponding +identifier, named *cap:[capability_name]*, used for +providing the status of the data syncing for that capability. This status +reflects the progress of the syncing process and can have the following values: + + +- *-3* - not synced +- *-2* - sync pending (waiting for either a suitable +donor node or actual sync data) +- *-1* - sync in progress +- *1* - synced (either sync has completed or the +capability does not require data syncing at all) + + +```json +{ + "Name": "cap:dialog-dlg-repl", + "Readiness": true, + "Status": 1, + "Details": "synced" +}, + +``` + + +The capability identifiers also provide reports regarding the main stages of +the sync process. These identifiers have a 200 records history before discarding +the old ones. + + +```json +{ + "Name": "cap:dialog-dlg-repl", + "Reports": [ + { + "Timestamp": 1656966903, + "Date": "Mon Jul 4 23:35:03 2022", + "Log": "Sync requested" + }, + { + "Timestamp": 1656966904, + "Date": "Mon Jul 4 23:35:04 2022", + "Log": "Sync started from node [1]" + }, + { + "Timestamp": 1656966906, + "Date": "Mon Jul 4 23:35:06 2022", + "Log": "Sync completed, received [10000] chunks" + } + ] +}, + + +``` + + +For how to access and use the Status/Report information, please see +[Status/Report Interface documentation](https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +### Usage Example + + +This section provides an usage example for replicating ratelimit +pipes between two OpenSIPS instances. It uses the clusterer module to +manage the replicating nodes, and along with the +*proto_bin* module, to send the replicated information. + + +The setup topology is simple: we have two OpenSIPS nodes running on +two separate machines (although they could run on the same machine as +well): *Node A* has IP 192.168.0.5 and +*Node B* has IP 192.168.0.6. Both have, besides the +traffic listeners (UDP, TCP, etc.), BIN listeners bound on port +*5566*. These listeners will be used for the binary +communication. + + +We insert in the the *clusterer* table the following: + + +```c title="Example database content - clusterer table" ++----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ +| id | cluster_id | node_id | url | state | no_ping_retries | priority | sip_addr | flags | description | ++----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ +| 10 | 1 | 1 | bin:192.168.0.5:5566 | 1 | 3| 50 | NULL | NULL | Node A | +| 20 | 1 | 2 | bin:192.168.0.6:5566 | 1 | 3| 50 | NULL | NULL | Node B | ++----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ + +``` + + +- "cluster_id" - identifier of the cluster. All nodes within a +group/cluster should have the same id (in our example, +both nodes have ID *1*). The values must be greater than 0. +- "node_id" - identifier of the machine/node so each instance within a +cluster should have a different ID. The values must be greater than 0. In our example, +*Node A* will have ID 1, and +*Node B* ID 2. +- "url" - address where all the BIN packets for that instance will be +sent to. +- "state" - state of the node: *1* means Enabled, +*0* means Disabled. A disabled node will not send any BIN packets +and will drop received ones. +- "no_ping_retries" - maximum number of ping retries before the link +with a node is considered down. +- "priority" - the priority of a node to be chosen +as next hop in case of same length(number of hops) paths when rerouting messages; +it is not relevant for this two-node topology example. +- "sip_addr" - SIP address for the node that is transparently +provided to modules; it has no use for the ratelimit module in our example. +- "flags" - used to define a seed node; it has no use in our example. +- "description" - an opaque value used to +describe the node + + +After provisioning the two nodes in the database, we have to configure +the two instances of OpenSIPS. First, we configure *Node +A*: + + +```opensips title="*Node A* configuration" +... +socket= bin:192.168.0.5:5566 # bin listener for Node A + +loadmodule "proto_bin.so" + +loadmodule "clusterer.so" +modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") +modparam("clusterer", "my_node_id", 1) # node_id for Node A + +loadmodule "ratelimit.so" +modparam("ratelimit", "pipe_replication_cluster", 1) +... + +``` + + +Similarly, the configuration for *Node B* is as follows: + + +```opensips title="*Node B* configuration" +... +socket= bin:192.168.0.6:5566 # bin listener for Node B + +loadmodule "proto_bin.so" + +loadmodule "clusterer.so" +# ideally, use the same database for both nodes +modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") +modparam("clusterer", "my_node_id", 2) # node_id for Node B + +loadmodule "ratelimit.so" +modparam("ratelimit", "pipe_replication_cluster", 1) +... + +``` + + +Starting the two OpenSIPS instances with the above configurations provides +your platform the ability to used shared ratelimit pipes in a very +efficient and scalable way. + + +### Exported Statistics + + +#### clusterer_nodes + + +Returns the total number of cluster nodes. + + +#### clusterer_nodes_up + + +Returns the total number of cluster nodes in the UP state. + + +#### clusterer_nodes_down + + +Returns the total number of cluster nodes not in the UP state. + + +## Developer Guide + + +### Available Functions + + +#### get_nodes(cluster_id) + + +This function will return a list of all the reachable nodes(if the direct link is down/probing, a path through intermediary nodes is considered) in the specified cluster. + + +The returned nodes structure: + + +```c +... +typedef struct clusterer_node { + int node_id; + union sockaddr_union addr; + str sip_addr; + str description; + struct clusterer_node *next; +} clusterer_node_t; +... + +``` + + +Meaning of the parameters is as follows: + + +- *int cluster_id* - the cluster id + + +#### free_nodes(list) + + +This function will free the lits of nodes returned by *get_nodes*. + + +Meaning of the parameters is as follows: + + +- *clusterer_node_t *list* - list header + + +#### set_state(cluster_id, state) + + +This function sets the state(enabled/disabled) of the current node in the specified cluster. + + +Meaning of the parameters is as follows: + + +- *int cluster_id* - the cluster id +- *enum cl_node_state state* - the new state; possible values: + + - *STATE_DISABLED* + - *STATE_ENABLED* + + +#### check_addr(cluster_id, su) + + +This function checks if a given address belongs to one of the nodes in the cluster. + + +Meaning of the parameters is as follows: + + +- *int cluster_id* - the cluster id +- *union sockaddr_union* su* - socket address + + +#### get_my_id() + + +This function will return the id of the current node. + + +#### send_to(packet, cluster_id, node_id) + + +This functon will send the given BIN packet to the specified node in the cluster. If the direct link is down/probing, it will send the packet to an intermediary node if the destination node is reachable through another path in the cluster topology. + + +Meaning of the parameters is as follows: + + +- *bin_packet_t packet* - the packet to be sent +- *int cluster_id* - the cluster id +- *int node_id* - the id of the destination node + + +The function returns one of the following: + + +- *CLUSTERER_SEND_SUCCESS* - successfully sent packet to destination node or a valid next hop +- *CLUSTERER_CURR_DISABLED* - current node is disabled so sending is impossbile +- *CLUSTERER_DEST_DOWN* - destination node is not reachable through any path according to the discovered topology +- *CLUSTERER_SEND_ERR* - destination node or valid next hop appear to be reachable but send failed + + +#### send_all(packet, cluster_id) + + +Send the given BIN packet to all the nodes in the specified cluster. The function operates similarly to *send_to*. + + +Meaning of the parameters is as follows: + + +- *bin_packet_t packet* - the packet to be sent +- *int cluster_id* - the cluster id + + +The function returns one of the following: + + +- *CLUSTERER_SEND_SUCCESS* - successfully sent packet to at least one node +- *CLUSTERER_CURR_DISABLED* - current node is disabled so sending is impossbile +- *CLUSTERER_DEST_DOWN* - all nodes in the cluster are unreachable according to the discovered topology +- *CLUSTERER_SEND_ERR* - send failed for all nodes in the cluster + + +#### get_next_hop(cluster_id, node_id) + + +This function returns the next hop from the computed shortest path to the given destination node in the specified cluster. This is the node that is the actual destination for the *send_to* and *send_all* functions when the direct link with the intended destination is down. The function returns the same structure as *get_nodes*. + + +Meaning of the parameters is as follows: + + +- *int cluster_id* - the cluster id +- *int node_id* - the node id of the destination for which the next hop is returned. + + +#### free_next_hop(next_hop) + + +This function will free the next hop returned by *get_next_hop*. + + +Meaning of the parameters is as follows: + + +- *clusterer_node_t *next_hop* - next hop to be freed + + +#### register_module(mod_name, cb, auth_check, accept_clusters_ids, no_accept_clusters) + + +This function registers an OpenSIPS module in order to receive BIN packets and cluster notifications. A certain module can accept packets from multiple clusters and provides a single callback function that will be called for each received packet. This function will also be called to notify cluster events like nodes becoming reachable/unreachable. + + +Meaning of the parameters is as follows: + + +- *char *mod_name* - module name +- *clusterer_cb_f cb* - callback function +- *int auth_check* - 0 - no check, 1 - for every BIN packet received check if source IP belongs to one of the nodes in the cluster +- *int* accept_clusters_ids* - array of cluster ids from which packets are accepted +- *int no_accept_clusters* - length of *accept_clusters_ids* array + + +The callback function prototype: + + +```c +... +typedef void (*clusterer_cb_f)(enum clusterer_event ev,bin_packet_t *, int packet_type, + struct receive_info *ri, int cluster_id, int src_id, int dest_id); +... +``` + + +Possble values for the event signaled through *ev* parameter of the callback funtion: + + +- *CLUSTER_RECV_MSG* - received BIN message +- *CLUSTER_ROUTE_FAILED* - failed to route a received BIN packet destined for another node in the cluster +- *CLUSTER_NODE_UP* - a node became reachable +- *CLUSTER_NODE_DOWN* - a node became unreachable + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/clusterer/clusterer.c b/modules/clusterer/clusterer.c index 01d150c6c14..164af2c4799 100644 --- a/modules/clusterer/clusterer.c +++ b/modules/clusterer/clusterer.c @@ -984,7 +984,7 @@ void handle_cl_gen_msg(bin_packet_t *packet, int cluster_id, int source_id) static void handle_cl_mi_msg(bin_packet_t *packet) { - str cmd_params[MI_CMD_MAX_NR_PARAMS]; + str cmd_params[MAX_MI_PARAMS]; str cmd_name; int i, no_params; int rc; @@ -993,6 +993,11 @@ static void handle_cl_mi_msg(bin_packet_t *packet) LM_DBG("Received MI command <%.*s>\n", cmd_name.len, cmd_name.s); bin_pop_int(packet, &no_params); + if (no_params>MAX_MI_PARAMS) { + LM_ERR("MI command <%.*s> got more params (%d) than supported (%d)\n", + cmd_name.len, cmd_name.s, no_params, MAX_MI_PARAMS); + return; + } for (i = 0; i < no_params; i++) bin_pop_str(packet, &cmd_params[i]); diff --git a/modules/clusterer/clusterer.h b/modules/clusterer/clusterer.h index 906fcb2b899..2d513b85fba 100644 --- a/modules/clusterer/clusterer.h +++ b/modules/clusterer/clusterer.h @@ -45,8 +45,6 @@ #define TAG_RAND_LEN 24 #define TAG_FIX_MAXLEN 6 /* "XX-YY-" */ -#define MI_CMD_MAX_NR_PARAMS 15 - /* node flags */ #define NODE_STATE_ENABLED (1<<0) #define NODE_EVENT_DOWN (1<<1) diff --git a/modules/clusterer/doc/clusterer.xml b/modules/clusterer/doc/clusterer.xml deleted file mode 100644 index 5c4033340e0..00000000000 --- a/modules/clusterer/doc/clusterer.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - CLUSTERER Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2015-2017 &osipssol; - diff --git a/modules/clusterer/doc/clusterer_admin.xml b/modules/clusterer/doc/clusterer_admin.xml deleted file mode 100644 index 87eaa081f0d..00000000000 --- a/modules/clusterer/doc/clusterer_admin.xml +++ /dev/null @@ -1,1676 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The clusterer module is used to organize multiple &osips; instances into groups(clusters) in which the nodes can communicate with each other in order to replicate, share information or perform distributed tasks. The distributed logic is performed either by different modules that use the clusterer interface (i.e. the dialog module can replicate dialogs/profiles, the ratelimit module can share pipes across multiple - instances etc.) or at the script level. The clusterer module itself only provides an interface to send/receive BIN packets and get notifications about node availability. It achieves this by internally learning the cluster topology and state of the nodes. Provisioning the nodes within a cluster is done over the database or through the configuration script. The node-related information can be checked and triggered to be reloaded by sending commands over the MI interface. - - - The topology established by the clusterer module is an overlay of nodes where the "links" represent communication availability at BIN interface level. For this purpose, a probing mechanism is used, consisting of regular pings to all nodes in a cluster for which replies must be received within a given interval. All nodes in the cluster exchange information about the state of their links with other nodes and compute a "routing table" which gives a next hop for each destination. The metric for the shortest path is the number of hops. When there is no direct link to a destination, the BIN packet sent by a module is transparently routed through the cluster. - - - Note that an &osips; instance can belong to multiple clusters, communicating and establishing the topology separately for each one. In order to provision this in the database or the script, each node has an unique ID at global level, which can be referenced in each cluster. - - - An &osips; instance can dynamically learn all the nodes in the cluster if database provisioning is not desired. It is enough to define at least one neigbour in the script in order to discover all the cluster components. - -
- -
- Capabilities layer - - The clusterer module also keeps track of the state of the nodes in terms of data synchronization for the functionalities (or "capabilities") implemented on top by other modules. Some capabilities require a full data sync(at &osips; startup or at runtime via MI) from a valid "donor" node in the cluster that has the full data set. Furthermore, a capability can query the clusterer module in order to partition some distributed logic only over the synchronized nodes in the cluster. - - - Each node in the cluster starts with an empty dataset and tries to find - a suitable node to pull data from. In order to help "bootstrap" the - cluster, a "seed" node should be defined. This is done by setting the value - seed for the flags - column in the clusterer table(or the property with the same name in the - my_node_info parameter). The seed node will simply - fall back to a "synced" state after a configurable interval( - parameter). Note that - this mechanism is required only for capabilities that synchronize data - at startup, so check the corresponding modules documentation. - - - The clusterer module transparently exposes the sip_addr column from the clusterer table(or the property with the same name in the my_node_info parameter) to the modules on top so check the corresponding modules documentation for the use of this node related information. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module - if - is 1. - - - - - proto_bin module. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - -
- <varname>my_node_id</varname> - - The id of the local instance. This parameter must be equal to one of the - node_id fields in the database. - - - - No default value. This parameter must be explicitly set to a value greater than zero. - - - - Set <varname>my_node_id</varname> parameter - -... -modparam("clusterer", "my_node_id", 1) -... - - -
- -
- <varname>db_mode</varname> - - Specifies whether the node information for the local instance, - as well as other instances in the cluster, should be loaded from - the database or configured in the script(see - and ). A value of 0 - means that DB is not used and the cluster topology in terms of node - information will be discovered dynamically at runtime. - - - If DB mode is enabled, only the nodes defined in the database will be - accepted by this instance. - - - - Default value is 1 - - - - Set <varname>db_mode</varname> parameter - -... -modparam("clusterer", "db_mode", 0) -... - - -
- -
- <varname>db_url</varname> - - The database url. - - - - Default value is NULL. - - - - Set <varname>db_url</varname> parameter - -... -modparam("clusterer", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>db_table</varname> - - The name of the table storing the clustering information. - - - - Default value is clusterer. - - - - Set <varname>db_table</varname> parameter - -... -modparam("clusterer", "db_table", "clusterer") -... - - -
- -
- <varname>sharing_tag</varname> - - The definition of a sharing tag. The sharing tag is - managed by the clusterer module, but can be used (in terms - of reading its state) by any module build on top of - clusterer engine, like dialog or presence. - - - Note that other tags may be dynamically learned during runtime via - clustering communication with other nodes. - - - The format for this value is tag_name / cluster_id = active/backup. - - - Multiple definitions of this parameter are allowed. The default value is none. - - - Set <varname>sharing_tag</varname> parameter - -... -modparam("clusterer", "sharing_tag", "vip1/2=active") -modparam("clusterer", "sharing_tag", "node/10=backup") -... - - -
- -
- <varname>my_node_info</varname> - - Node specification similar to the information provided by a row in - the clusterer DB table corresponding to the local instance. This - parameter can be set multiple times in order to include the local - node in multiple clusters. - - - Parameter format: multiple "prop=value" property - definitions separated by ',' where the name of the - properties is the same as the DB column names. At least the - cluster_id and url - properties must be defined. - - - This parameter is required if is set - to 0 in order to properly advertise information about - the local instance in the dynamic node learning process. - - - Set <varname>my_node_info</varname> parameter - -... -modparam("clusterer", "my_node_info", "cluster_id=1, url=bin:192.168.0.5:5566") -... - - -
- -
- <varname>neighbor_node_info</varname> - - Node specification similar to the information provided by a row in - the clusterer DB table corresponding to another instance in the - cluster. This node will be the entry point in the cluster for the - local instance in the dynamic node learning process. This parameter - can be set multiple times to define multiple neigbors to connect to (or - the same neighbor but in different clusters). - - - Parameter format: multiple "prop=value" property - definitions separated by ',' where the name of - the properties is the same as the DB column names. At least the - cluster_id, node_id - and url properties must be defined. - - - This parameter should be set at least once if - is set to 0 in order - to properly learn the cluster topology. If not set, the only way to learn - the node topology is by other nodes connecting to the local instance. - - - Set <varname>neighbor_node_info</varname> parameter - -... -modparam("clusterer", "neighbor_node_info", "cluster_id=1,node_id=2,url=bin:192.168.0.6:5566") -... - - -
- -
- <varname>ping_interval</varname> - - The interval in seconds between regular pings sent to a neighbour node. - - - - Default value is 4 - - - - Set <varname>ping_interval</varname> parameter - -... -modparam("clusterer", "ping_interval", 1) -... - - -
- -
- <varname>ping_timeout</varname> - - The time in milliseconds to wait for a reply to a previously sent ping before retrying or considering the link with the neighbour node down. This is also the interval between successive retries if the send fails. - - - - Default value is 1000 - - - - Set <varname>ping_timeout</varname> parameter - -... -modparam("clusterer", "ping_timeout", 500) -... - - -
- -
- <varname>node_timeout</varname> - - The time in seconds to wait before pinging is restarted for a failed node. - - - - Default value is 60 - - - - Set <varname>node_timeout</varname> parameter - -... -modparam("clusterer", "node_timeout", 10) -... - - -
- -
- <varname>seed_fallback_interval</varname> - - Only relevant for "seed" nodes. The time, in seconds, to wait - for a suitable donor node before falling back to a "synced" - state, following a node restart or an MI cluster sync command. - - - - Default value is 5. - - - - Set <varname>seed_fallback_interval</varname> parameter - -... -modparam("clusterer", "seed_fallback_interval", 10) -... - - -
- -
- <varname>sync_timeout</varname> - - The inteval, in seconds, since the last sync data packet received - after which to consider the sync process as failed and revert the - node to the not synced state. - - - - Default value is 15. - - - - Set <varname>sync_timeout</varname> parameter - -... -modparam("clusterer", "sync_timeout", 5) -... - - -
- -
- <varname>sync_packet_size</varname> - - The maximum size of the BIN packets sent while doing data synchronization. This is only a suggested value as the actual size of the packets may be slightly larger. - - - - Default value is 65535. - - - - Set <varname>sync_packet_size</varname> parameter - -... -modparam("clusterer", "sync_packet_size", 32765) -... - - -
- -
- <varname>dispatch_jobs</varname> - - Enables the dispatching of jobs(processing replicated data packets) - from the receiving TCP worker process to free opensips workers - (including UDP, timer processes etc.). - - - This generally improves the performance of handling replication packets - in high traffic scenarios and should not be disabled. - - - Nevertheless there are cases where the "thundering herd" problem occurs - which causes abnormaly high CPU loads. Disabling this dispatching - mechanism solves such issues. - - - - Default value is 1 (enabled). - - - - Set <varname>dispatch_jobs</varname> parameter - -... -modparam("clusterer", "dispatch_jobs", 0) -... - - -
- -
- <varname>id_col</varname> - - The name of the column storing an id for the table rows. - - - - Default value is id. - - - - Set <varname>id_col</varname> parameter - -... -modparam("clusterer", "id_col", "id") -... - - -
- -
- <varname>cluster_id_col</varname> - - The name of the column to store the id of a cluster. - - - - Default value is cluster_id. - - - - Set <varname>cluster_id_col</varname> parameter - -... -modparam("clusterer", "cluster_id_col", "cluster_id") -... - - -
- -
- <varname>node_id_col</varname> - - The name of the column to store the id of an instance. The values must be greater than 0. - - - - Default value is node_id. - - - - Set <varname>node_id_col</varname> parameter - -... -modparam("clusterer", "node_id_col", "node_id") -... - - -
- -
- <varname>url_col</varname> - - The name of the column containing the instance url. The values must be greater than 0. - - - - Default value is url. - - - - Set <varname>url_col</varname> parameter - -... -modparam("clusterer", "url_col", "url") -... - - -
- -
- <varname>state_col</varname> - - The name of the column storing the state of the node(enabled/disabled). - - - - Default value is state. - - - - Set <varname>state_col</varname> parameter - -... -modparam("clusterer", "state_col", "state") -... - - -
- -
- <varname>no_ping_retries_col</varname> - - The name of the column containing the maximum number of ping retries before the link with the neighbour node is considered down. - - - - Default value is no_ping_retries. - - - - Set <varname>no_ping_retries_col</varname> parameter - -... -modparam("clusterer", "no_ping_retries_col", "no_ping_retries") -... - - -
- -
- <varname>priority_col</varname> - - The name of the column storing the node priority to be chosen as next hop in case of same length(number of hops) paths when rerouting messages. - - - - Default value is priority. - - - - Set <varname>priority_col</varname> parameter - -... -modparam("clusterer", "priority_col", "priority") -... - - -
- -
- <varname>sip_addr_col</varname> - - The name of the column containing a SIP address for the node. - - - - Default value is sip_addr. - - - - Set <varname>sip_addr_col</varname> parameter - -... -modparam("clusterer", "sip_addr_col", "sip_addr") -... - - -
- -
- <varname>flags_col</varname> - - The name of the column containing the node flags. - - - - Default value is flags. - - - - Set <varname>flags_col</varname> parameter - -... -modparam("clusterer", "flags_col", "flags") -... - - -
- -
- <varname>description_col</varname> - - The name of the column containing a node description. - - - - Default value is description. - - - - Set <varname>description_col</varname> parameter - -... -modparam("clusterer", "description_col", "description") -... - - -
- -
- <varname>enable_stats</varname> (integer) - - If the statistics support should be enabled or not. Via statistic - variables, the module provide information about the cluster nodes. - Set it to zero to disable or to non-zero to enable it. - - - - Default value is 1 (enabled). - - - - Set <varname>enable_stats</varname> parameter - -... -modparam("clusterer", "enable_stats", 0) -... - - -
- -
- <varname>enable_rerouting</varname> (integer) - - If packets should be rerouted via another node if a direct route - to destination is unavailible. Disabling may improve stability in - two-node topologies. - Set it to zero to disable or to non-zero to enable it. - - - - Default value is 1 (enabled). - - - - Set <varname>enable_rerouting</varname> parameter - -... -modparam("clusterer", "enable_rerouting", 0) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">cluster_send_req(cluster_id, dst_id, msg, [tag])</function> - - - This function is used to send a generic, request-like message, containing custom data, to a specific node in a cluster, directly from the script. The message is not a "request" per se but according to the logic on the receiving side, that node can send back a reply. In order to correlate a received reply with the request sent out, the function returns, through the tag parameter, a randomly generated communication tag, which is sent along in the the original message, that can be checked against the tag received in a reply. - - - Meaning of the parameters is as follows: - - - cluster_id (int) - the cluster ID of the destination node; - - - dst_id (int) - the ID of the destiantion node; - - - msg (string) - actual message payload; - - - tag (var, optional) - randomly generated communication tag. - - - - - The function can return the following values: - - - 1 - successfully sent message to destination node or a valid next hop - - - -1 - local node is disabled so sending is impossbile - - - -2 - destination node is not reachable through any path according to the discovered topology - - - -3 - destination node or valid next hop appear to be reachable but send failed or other &osips; internal error - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - - - cluster_send_req() usage - -... -# send a request -cluster_send_req(1, 1, "Check USER: $fU", $var(req_tag)); -# wait for reply -$avp(filter) = "tag=" + $var(req_tag); -async(wait_for_event("E_CLUSTERER_RPL_RECEIVED", $avp(filter), 5), rpl_resume); -# done -... -route[rpl_resume] { - xlog("Received reply: $avp(msg)\n"); -} -... - - -
-
- - <function moreinfo="none">cluster_send_rpl(cluster_id, dst_id, msg, tag)</function> - - - This function is used to send a generic, reply-like message, containing custom data, to a specific node in a cluster, directly from the script. The message is marked as a "reply" so this function should ony be used for replying to a previously request-like message received. In order for the other node, which initially sent a request, to be able to correlate it with this reply, a communication tag, received along with the request, should be passed to the function. - - - Meaning of the parameters is as follows: - - - cluster_id (int) - the cluster ID of the destination node; - - - dst_id (int) - the ID of the destiantion node; - - - msg (string) - actual message payload; - - - tag (var) - communication tag. - - - - - The function can return the following values: - - - 1 - successfully sent message to destination node or a valid next hop - - - -1 - local node is disabled so sending is impossbile - - - -2 - destination node is not reachable through any path according to the discovered topology - - - -3 - destination node or valid next hop appear to be reachable but send failed or other &osips; internal error - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - - cluster_send_rpl() usage - -... -event_route[E_CLUSTERER_REQ_RECEIVED] { - cluster_send_rpl($param(cluster_id), $param(src_id), $var(my_reply), $param(tag)); -} -... - - -
- -
- - <function moreinfo="none">cluster_broadcast_req(cluster_id, msg, [tag], [include_self])</function> - - - This function has a similar behaviour to the cluster_send_req() function with the exception that the message is sent to all the nodes in the specified cluster. - - - - include_self (bool, optional, default: false) - raise the event for current node as well, but without actually sending a packet (both req and rpl). - - - - The function can return the following values: - - - 1 - successfully sent message to at least one node; - - - -1 - local node is disabled so sending is impossbile; - - - -2 - all nodes in the cluster are unreachable according to the discovered topology; - - - -3 - send failed for all nodes in the cluster or other &osips; internal error. - - - - - The meaning of the parameters is the same as for cluster_send_req(). - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - - cluster_broadcast_req() usage - -... -# also raise the event for current node -cluster_broadcast_req($var(cl_id), $var(share_data), , true); -... - - -
- -
- - <function moreinfo="none">cluster_check_addr(cluster_id, ip, addr_type)</function> - - - This function checks whether the given IP address belongs - to one of the nodes in the cluster. - - Parameters: - - - cluster_id (int) - - - ip (string) - - - addr_type (string, optional) - - select the address of the node that the comparison - is made against, with the possible values of: - - - "sip" (default) - a node's DB provisioned SIP address - - - "bin" - a node's BIN interface listener - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE and EVENT_ROUTE. - - - cluster_check_addr() usage - -... -if (cluster_check_addr(1, $si)) { - ... -} -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">clusterer_reload</function> - - - Reloads data from the clusterer database. The currently established topology will be lost and the node will rediscover the new topology. - - - Name: clusterer_reload - - Parameters:none - - MI FIFO Command Format: - - - opensips-cli -x mi clusterer_reload - -
- -
- - <function moreinfo="none">clusterer_list</function> - - - Lists information(node id, URL, link state with that node etc.) about the other nodes in each cluster. - - - Name: clusterer_list - - Parameters:none - - <function>clusterer_list</function> usage - -$ opensips-cli -x mi clusterer_list -{ - "Clusters": [ - { - "cluster_id": 1, - "Nodes": [ - { - "node_id": 1, - "db_id": 1, - "url": "bin:127.0.0.1", - "link_state": "Up", - "next_hop": "1", - "description": "none" - } - ] - } - ] -} - - -
- -
- - <function moreinfo="none">clusterer_list_topology</function> - - - Lists each cluster's topology from the local node's perspective as an adjacency list. A node appears as a neighbour if the link with that node is up. - - - Note that if a node id appears in multiple clusters, it refers to the same instance that belongs to different clusters, for which it has a different topology. - - - Name: clusterer_list_topology - - Parameters:none - - <function>clusterer_list_topology</function> usage - -$ opensips-cli -x mi clusterer_list_topology -{ - "Clusters": [ - { - "cluster_id": 1, - "Nodes": [ - { - "node_id": 2, - "Neighbours": [ - 1 - ] - }, - { - "node_id": 1, - "Neighbours": [ - 2 - ] - } - ] - } - ] -} - - -
- -
- - <function moreinfo="none">clusterer_set_status</function> - - - Sets the status(Enabled/Disabled) of a node. If the local instance is disabled, the node will not send any messages and ignore received ones thus appearing as a failed node in the topology (from the other node's perspective). If a different node is disabled, the specified node will simply be ignored by the local instance in terms of sending/receiving any messages, as if no longer part of the topology. - - - Name: clusterer_set_status - - Parameters: - - - cluster_id - indicates the id of the cluster. - - - node_id (optional) - indicates the id of the node to be disabled. - If missing, the local instance will be disalbed. - - - status - indicates the new status(0 - Disabled, 1 - Enabled). - - - - MI FIFO Command Format: - - - #disable the local instance - opensips-cli -x mi clusterer_set_status 1 0 - #disable node ID 3 - opensips-cli -x mi clusterer_set_status 1 3 0 - -
- -
- - <function moreinfo="none">clusterer_remove_node</function> - - - Removes a node from the cluster's topology. It is enough to run the function - on a single node in order to remove the target node from all the other - nodes in the cluster. If the node to be removed is running when triggering - this function, it will be automatically disabled (equivalent to running - on that specific node). - - - This function can only be used when is set to - 0 (disabled). - - - Name: clusterer_remove_node - - Parameters: - - - cluster_id - cluster ID - - - node_id - ID of the node to be removed. - - - - MI FIFO Command Format: - - - opensips-cli -x mi clusterer_remove_node 1 3 - -
- -
- - <function moreinfo="none">cluster_send_mi</function> - - - Dispatches a given MI command to be run on a specific node in the cluster. - - - Name: cluster_send_mi - - Parameters: - - - cluster_id - id of the cluster. - - - destination - id of the destination node - - - cmd_name - name of the MI command to be run - - - cmd_params (optional) - array of parameters for - the MI command to be run - - - - Note that MI commands that require named parameters or arrays as - parameter values are not currently supported. - - - MI FIFO Command Format: - - -opensips-cli -x mi cluster_send_mi 1 3 lb_reload - -
- -
- - <function moreinfo="none">cluster_broadcast_mi</function> - - - Dispatches a given MI command to be run on all the nodes in a cluster. The command is also executed locally. - - - Name: cluster_broadcast_mi - - Parameters: - - - cluster_id - id of the cluster. - - - cmd_name - name of the MI command to be run - - - cmd_params (optional) - array of parameters for - the MI command to be run - - - - Note that MI commands that require named parameters or arrays as - parameter values are not currently supported. - - - MI FIFO Command Format: - - -opensips-cli -x mi cluster_broadcast_mi 1 dr_reload partition_5 - -
- -
- - <function moreinfo="none">clusterer_list_cap</function> - - - Lists the registered capabilities and their states. - - - Name: clusterer_list_cap - - Parameters:none - - <function>clusterer_list_cap</function> usage - -$ opensips-cli -x mi clusterer_list_cap -{ - "Clusters": [ - { - "cluster_id": 1, - "Capabilities": [ - { - "name": "dialog-dlg-repl", - "state": "Ok", - "enabled": "yes" - }, - { - "name": "dialog-prof-repl", - "state": "Ok", - "enabled": "yes" - } - ] - } - ] -} - - -
- -
- - <function moreinfo="none">clusterer_set_cap_status</function> - - - Sets the status(Enabled/Disabled) of a capability. If a capability is disabled, the node will not send any replication/sync messages belonging to that capability. Likewise, received messages will be dropped. Also, the cabability will transition to a "not synced" state and the node will no longer be able to be a donor for syncing. - - - Name: clusterer_set_cap_status - - Parameters: - - - cluster_id - the id of the cluster - - - capability - name of the capability, as listed by - - - - status - indicates the new status(0 - Disabled, 1 - Enabled). - - - - MI FIFO Command Format: - - - #disable dialog replication in cluster 1 - opensips-cli -x mi clusterer_set_cap_status 1 dialog-dlg-repl 0 - #enable dialog profile replication in cluster 2 - opensips-cli -x mi clusterer_set_cap_status 2 dialog-prof-repl 1 - -
- -
- <function moreinfo="none">clusterer_shtag_set_active</function> - - Set the given sharing tag to the active state. - The information about this change is also broadcasted in the cluster - in order to force any other node that may be active on this tag to - step down to backup. - - - Name: clusterer_shtag_set_active - - Parameters: tag - the name of - the tag to be set active and the cluster it belogs to, in the - format 'tag/cluster_id'. - - - MI FIFO Command Format: - - - opensips-cli -x mi clusterer_shtag_set_active vip1/3 - -
- -
- <function moreinfo="none">clusterer_list_shtags</function> - - Lists all known sharing tags and their states. - - - Name: clusterer_list_shtags - - Parameters: Command takes no parameters - - - MI FIFO Command Format: - - - opensips-cli -x mi clusterer_list_shtags - -
- -
- - -
- Exported Script Variables -
- <varname>$cluster.sh_tag</varname> - - This is a read/write variable that allows access to the - sharing tags managed by the clusterer module. - - - The name of such a variable has the format of - tag_name/cluster_id, like - $cluster.sh_tag(vip/3) accessing the - sharing tag "vip" from cluster ID 3. - - - When setting, a sharing tag may be only switched to active by - assigned it: - - - "active" string value - - - 1 or higher numerical value - - - - - When reading it value, a sharing tag returns: - - - "active" or 1 if active - - - "backup" or 0 if backup - - - A NULL value may returned only as a result of an internal error - (like memory errors). - -
-
- -
-Exported Events -
- - <function moreinfo="none">E_CLUSTERER_REQ_RECEIVED</function> - - - This event is raised when a generic, request-like, clusterer message is received. This type of message is sent directly from the script and not by an &osips; module. - - Parameters: - - - cluster_id - The cluster ID of the source node. - - - src_id - The ID of the source node. - - - msg - The actual message payload. - - - tag - The communication tag of this message, generated by the source node. This could be used to send a reply corresponding to the received message by providing the tag to the cluster_send_rpl() function. - - -
- -
- - <function moreinfo="none">E_CLUSTERER_RPL_RECEIVED</function> - - - This event is raised when a generic, reply-like, clusterer message is received. This type of message is sent directly from the script and not by an &osips; module. - - Parameters: - - - cluster_id - The cluster ID of the source node. - - - src_id - The ID of the source node. - - - msg - The actual message payload. - - - tag - The communication tag of this message. This could be used to match the received reply with a request sent with the cluster_send_req() or cluster_broadcast_req() functions. - - -
- -
- - <function moreinfo="none">E_CLUSTERER_NODE_STATE_CHANGED</function> - - - This event is raised when the state of a node changes in terms of - availability. - - Parameters: - - - cluster_id - The cluster ID. - - - node_id - The ID of the node. - - - new_state - The new state of the node, with - the possible values: 0 - down, 1 - up. - - -
- -
- - <function moreinfo="none">E_CLUSTERER_SHARING_TAG_CHANGED</function> - - - This event is raised when the state of a sharing tag changes. - - Parameters: - - - name - The name of the sharing tag. - - - cluster - The cluster ID. - - - state - The new state of the sharing tag, - the possible values: "active" or "backup". - - - reason - short text describing what - triggered the change of the state, like a another node - stepping as active, an MI command or script variable. - - -
- -
- -
- Exported Status/Report Identifiers - - - The module provides the clusterer Status/Report group. - -
- <varname>sharing_tags</varname> - - The sharing_tags identifier is provided for reporting state - changes of the sharing_tags (between active and backup), along with the reason of - the change. This identifier has a 200 records history before discarding the old ones. - - -{ - "Name": "sharing_tags", - "Reports": [ - { - "Timestamp": 1652367224, - "Date": "Thu May 12 17:53:44 2022", - "Log": "TAG <HA>, cluster 1, became backup due to cluster broadcast from 2" - }, - { - "Timestamp": 1652367326, - "Date": "Thu May 12 17:55:26 2022", - "Log": "TAG <HA>, cluster 1, became active due to MI command" - } - ] -} - - -
-
- <varname>node_states</varname> - - The node_states identifier is used for reporting node state - changes (in terms of availability). This identifier has a 200 records history - before discarding the old ones. - - -{ - "Name": "node_states", - "Reports": [ - { - "Timestamp": 1656489246, - "Date": "Wed Jun 29 10:54:06 2022", - "Log": "Node [2], cluster [1] is UP" - }, - { - "Timestamp": 1656489261, - "Date": "Wed Jun 29 10:54:21 2022", - "Log": "Node [2], cluster [1] is DOWN" - } - ] -} - - -
-
- <varname>cap:[capability_name]</varname> - - Each capability registered to the clusterer module has a corresponding - identifier, named cap:[capability_name], used for - providing the status of the data syncing for that capability. This status - reflects the progress of the syncing process and can have the following values: - - - -3 - not synced - - - -2 - sync pending (waiting for either a suitable - donor node or actual sync data) - - - -1 - sync in progress - - - 1 - synced (either sync has completed or the - capability does not require data syncing at all) - - - - -{ - "Name": "cap:dialog-dlg-repl", - "Readiness": true, - "Status": 1, - "Details": "synced" -}, - - - The capability identifiers also provide reports regarding the main stages of - the sync process. These identifiers have a 200 records history before discarding - the old ones. - - -{ - "Name": "cap:dialog-dlg-repl", - "Reports": [ - { - "Timestamp": 1656966903, - "Date": "Mon Jul 4 23:35:03 2022", - "Log": "Sync requested" - }, - { - "Timestamp": 1656966904, - "Date": "Mon Jul 4 23:35:04 2022", - "Log": "Sync started from node [1]" - }, - { - "Timestamp": 1656966906, - "Date": "Mon Jul 4 23:35:06 2022", - "Log": "Sync completed, received [10000] chunks" - } - ] -}, - - -
- - For how to access and use the Status/Report information, please see - Status/Report Interface documentation. - - -
- - - -
- Usage Example - This section provides an usage example for replicating ratelimit - pipes between two &osips; instances. It uses the clusterer module to - manage the replicating nodes, and along with the - proto_bin module, to send the replicated information. - - The setup topology is simple: we have two &osips; nodes running on - two separate machines (although they could run on the same machine as - well): Node A has IP 192.168.0.5 and - Node B has IP 192.168.0.6. Both have, besides the - traffic listeners (UDP, TCP, etc.), BIN listeners bound on port - 5566. These listeners will be used for the binary - communication. - - - We insert in the the clusterer table the following: - - - Example database content - clusterer table - -+----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ -| id | cluster_id | node_id | url | state | no_ping_retries | priority | sip_addr | flags | description | -+----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ -| 10 | 1 | 1 | bin:192.168.0.5:5566 | 1 | 3| 50 | NULL | NULL | Node A | -| 20 | 1 | 2 | bin:192.168.0.6:5566 | 1 | 3| 50 | NULL | NULL | Node B | -+----+------------+---------+----------------------+-------+-----------------+----------+----------+-------+-------------+ - - - - - - cluster_id - identifier of the cluster. All nodes within a - group/cluster should have the same id (in our example, - both nodes have ID 1). The values must be greater than 0. - - - - node_id - identifier of the machine/node so each instance within a - cluster should have a different ID. The values must be greater than 0. In our example, - Node A will have ID 1, and - Node B ID 2. - - - - url - address where all the BIN packets for that instance will be - sent to. - - - - state - state of the node: 1 means Enabled, - 0 means Disabled. A disabled node will not send any BIN packets - and will drop received ones. - - - - no_ping_retries - maximum number of ping retries before the link - with a node is considered down. - - - - priority - the priority of a node to be chosen - as next hop in case of same length(number of hops) paths when rerouting messages; - it is not relevant for this two-node topology example. - - - - sip_addr - SIP address for the node that is transparently - provided to modules; it has no use for the ratelimit module in our example. - - - - flags - used to define a seed node; it has no use in our example. - - - - description - an opaque value used to - describe the node - - - - - - After provisioning the two nodes in the database, we have to configure - the two instances of &osips;. First, we configure Node - A: - - - <emphasis>Node A</emphasis> configuration - -... -socket= bin:192.168.0.5:5566 # bin listener for Node A - -loadmodule "proto_bin.so" - -loadmodule "clusterer.so" -modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") -modparam("clusterer", "my_node_id", 1) # node_id for Node A - -loadmodule "ratelimit.so" -modparam("ratelimit", "pipe_replication_cluster", 1) -... - - - - Similarly, the configuration for Node B is as follows: - - - <emphasis>Node B</emphasis> configuration - -... -socket= bin:192.168.0.6:5566 # bin listener for Node B - -loadmodule "proto_bin.so" - -loadmodule "clusterer.so" -# ideally, use the same database for both nodes -modparam("clusterer", "db_url", "mysql://opensips@192.168.0.7/opensips") -modparam("clusterer", "my_node_id", 2) # node_id for Node B - -loadmodule "ratelimit.so" -modparam("ratelimit", "pipe_replication_cluster", 1) -... - - -
- - - Starting the two &osips; instances with the above configurations provides - your platform the ability to used shared ratelimit pipes in a very - efficient and scalable way. - - -
- Exported Statistics -
- - <varname>clusterer_nodes</varname> - - - Returns the total number of cluster nodes. - -
-
- - <varname>clusterer_nodes_up</varname> - - - Returns the total number of cluster nodes in the UP state. - -
-
- - <varname>clusterer_nodes_down</varname> - - - Returns the total number of cluster nodes not in the UP state. - -
-
- -
diff --git a/modules/clusterer/doc/clusterer_devel.xml b/modules/clusterer/doc/clusterer_devel.xml deleted file mode 100644 index 7b89e03b1a9..00000000000 --- a/modules/clusterer/doc/clusterer_devel.xml +++ /dev/null @@ -1,275 +0,0 @@ - - - - - &develguide; -
- Available Functions - -
- - <function moreinfo="none">get_nodes(cluster_id)</function> - - - This function will return a list of all the reachable nodes(if the direct link is down/probing, a path through intermediary nodes is considered) in the specified cluster. - - The returned nodes structure: - -... -typedef struct clusterer_node { - int node_id; - union sockaddr_union addr; - str sip_addr; - str description; - struct clusterer_node *next; -} clusterer_node_t; -... - - Meaning of the parameters is as follows: - - - int cluster_id - the cluster id - - - -
- -
- - <function moreinfo="none">free_nodes(list)</function> - - - This function will free the lits of nodes returned by get_nodes. - - Meaning of the parameters is as follows: - - - clusterer_node_t *list - list header - - - -
- -
- - <function moreinfo="none">set_state(cluster_id, state)</function> - - - This function sets the state(enabled/disabled) of the current node in the specified cluster. - - Meaning of the parameters is as follows: - - - int cluster_id - the cluster id - - - - enum cl_node_state state - the new state; possible values: - - - STATE_DISABLED - STATE_ENABLED - - - -
- -
- - <function moreinfo="none">check_addr(cluster_id, su)</function> - - - This function checks if a given address belongs to one of the nodes in the cluster. - - Meaning of the parameters is as follows: - - - int cluster_id - the cluster id - - - - union sockaddr_union* su - socket address - - - -
- -
- - <function moreinfo="none">get_my_id()</function> - - - This function will return the id of the current node. - -
- -
- - <function moreinfo="none">send_to(packet, cluster_id, node_id)</function> - - - This functon will send the given BIN packet to the specified node in the cluster. If the direct link is down/probing, it will send the packet to an intermediary node if the destination node is reachable through another path in the cluster topology. - - Meaning of the parameters is as follows: - - - bin_packet_t packet - the packet to be sent - - - - int cluster_id - the cluster id - - - - int node_id - the id of the destination node - - - - The function returns one of the following: - - - CLUSTERER_SEND_SUCCESS - successfully sent packet to destination node or a valid next hop - - - CLUSTERER_CURR_DISABLED - current node is disabled so sending is impossbile - - - CLUSTERER_DEST_DOWN - destination node is not reachable through any path according to the discovered topology - - - CLUSTERER_SEND_ERR - destination node or valid next hop appear to be reachable but send failed - - -
- -
- - <function moreinfo="none">send_all(packet, cluster_id)</function> - - - Send the given BIN packet to all the nodes in the specified cluster. The function operates similarly to send_to. - - Meaning of the parameters is as follows: - - - bin_packet_t packet - the packet to be sent - - - - int cluster_id - the cluster id - - - - The function returns one of the following: - - - CLUSTERER_SEND_SUCCESS - successfully sent packet to at least one node - - - CLUSTERER_CURR_DISABLED - current node is disabled so sending is impossbile - - - CLUSTERER_DEST_DOWN - all nodes in the cluster are unreachable according to the discovered topology - - - CLUSTERER_SEND_ERR - send failed for all nodes in the cluster - - -
- -
- - <function moreinfo="none">get_next_hop(cluster_id, node_id)</function> - - - This function returns the next hop from the computed shortest path to the given destination node in the specified cluster. This is the node that is the actual destination for the send_to and send_all functions when the direct link with the intended destination is down. The function returns the same structure as get_nodes. - - Meaning of the parameters is as follows: - - - int cluster_id - the cluster id - - - - int node_id - the node id of the destination for which the next hop is returned. - - - -
- -
- - <function moreinfo="none">free_next_hop(next_hop)</function> - - - This function will free the next hop returned by get_next_hop. - - Meaning of the parameters is as follows: - - - clusterer_node_t *next_hop - next hop to be freed - - - -
- -
- - <function moreinfo="none">register_module(mod_name, cb, auth_check, accept_clusters_ids, no_accept_clusters)</function> - - - This function registers an &osips; module in order to receive BIN packets and cluster notifications. A certain module can accept packets from multiple clusters and provides a single callback function that will be called for each received packet. This function will also be called to notify cluster events like nodes becoming reachable/unreachable. - - Meaning of the parameters is as follows: - - - char *mod_name - module name - - - - clusterer_cb_f cb - callback function - - - - int auth_check - 0 - no check, 1 - for every BIN packet received check if source IP belongs to one of the nodes in the cluster - - - - int* accept_clusters_ids - array of cluster ids from which packets are accepted - - - - int no_accept_clusters - length of accept_clusters_ids array - - - - The callback function prototype: - -... -typedef void (*clusterer_cb_f)(enum clusterer_event ev,bin_packet_t *, int packet_type, - struct receive_info *ri, int cluster_id, int src_id, int dest_id); -... - - - Possble values for the event signaled through ev parameter of the callback funtion: - - - - CLUSTER_RECV_MSG - received BIN message - - - CLUSTER_ROUTE_FAILED - failed to route a received BIN packet destined for another node in the cluster - - - CLUSTER_NODE_UP - a node became reachable - - - CLUSTER_NODE_DOWN - a node became unreachable - - -
- - -
- -
diff --git a/modules/clusterer/doc/clusterer_sync_cap.xml b/modules/clusterer/doc/clusterer_sync_cap.xml deleted file mode 100644 index 14155b01667..00000000000 --- a/modules/clusterer/doc/clusterer_sync_cap.xml +++ /dev/null @@ -1,9 +0,0 @@ - -This OpenSIPS cluster exposes the "&my_cl_sync_cap;" -capability in order to mark nodes as eligible for becoming data donors during an -arbitrary sync request. Consequently, the cluster must have at least -one node marked with the "seed" value -as the clusterer.flags column/property in order to be fully functional. -Consult the clusterer - Capabilities -chapter for more details. - diff --git a/modules/clusterer/doc/contributors.xml b/modules/clusterer/doc/contributors.xml deleted file mode 100644 index 5cb35ef4518..00000000000 --- a/modules/clusterer/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 366 - 135 - 13387 - 7101 - - - 2. - Liviu Chircu (@liviuchircu) - 73 - 55 - 915 - 595 - - - 3. - Eseanu Marius Cristian (@eseanucristian) - 46 - 10 - 3142 - 534 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 32 - 17 - 1343 - 132 - - - 5. - Razvan Crainea (@razvancrainea) - 27 - 21 - 327 - 148 - - - 6. - Ionel Cerghit (@ionel-cerghit) - 9 - 2 - 250 - 212 - - - 7. - Maksym Sobolyev (@sobomax) - 8 - 6 - 12 - 13 - - - 8. - Alexandra Titoc - 6 - 4 - 18 - 4 - - - 9. - Jasper Hafkenscheid - 4 - 2 - 107 - 2 - - - 10. - Fabian Gast (@fgast) - 4 - 2 - 3 - 3 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Gohar Ahmed (@goharahmed), kworm83, Shanee Vanstone. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jul 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2016 - Jun 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2016 - Apr 2025 - - - 4. - Razvan Crainea (@razvancrainea) - Nov 2015 - Sep 2024 - - - 5. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 6. - Shanee Vanstone - Mar 2024 - Mar 2024 - - - 7. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - Jul 2016 - Jul 2023 - - - 9. - Jasper Hafkenscheid - May 2022 - Jul 2022 - - - 10. - kworm83 - Feb 2021 - Feb 2021 - - - -
-All remaining contributors: Fabian Gast (@fgast), Gohar Ahmed (@goharahmed), Ionel Cerghit (@ionel-cerghit), Eseanu Marius Cristian (@eseanucristian). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Shanee Vanstone, Vlad Patrascu (@rvlad-patrascu), Jasper Hafkenscheid, Fabian Gast (@fgast), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Eseanu Marius Cristian (@eseanucristian). -
- -
diff --git a/modules/compression/README b/modules/compression/README deleted file mode 100644 index 7bd2f2f11b9..00000000000 --- a/modules/compression/README +++ /dev/null @@ -1,353 +0,0 @@ -compression Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Usage cases - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - - 1.5. External Libraries or Applications - 1.6. Exported Parameters - - 1.6.1. mc_level (int) - - 1.7. Exported Functions - - 1.7.1. mc_compress([algo], flags, [whitelist]) - 1.7.2. mc_compact([whitelist], flags) - 1.7.3. mc_decompress() - - 1.8. Compression performance test for sip messages - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 1.1. mc_compress performance test results - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set mc_level parameter - 1.2. mc_compress usage - 1.3. mc_compress usage - 1.4. mc_compress usage - 1.5. mc_decompress usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements message compression/decompression and - base64 encoding for sip messages using deflate and gzip - algorithm/headers. Another feature of this module is reducing - headers to compact for as specified in SIP RFC's, sdp body - codec unnecessary description removal (for codecs 0-97), - whitelist for headers not be removed (excepting necessary - headers). - -1.2. How it works - - The module is using zlib library to implement compression and - base64 encoding for converting the message to human readable - characters. It also uses callbacks to do the - compression/compaction of the message in order for this - operations to be done after all the other script functions have - been applied to the message. - -1.3. Usage cases - - As we know, udp fragmentation is a big problem these days, so - this module comes to try making the message smaller by any - means. The module can be used to compress the body or some - headers found in the message or it can decompress compressed - messages. There are more possibilities to do this: the body can - be compressed along with the specified headers or the headers - can be compressed isolated from the body in a specific header. - - Also the module does message compaction: reduction of sip - header names to short form (for example "Via" becomes 'v' and - so on), sdp body codec attributes unnecesary description - ("a=rtpmap:0 PCMU/8000" becomes "a=rtpmap:0"), unwanted headers - removal by specfing the ones you want to keep in a whitelist. - - The module also does message decompresion and base64 decoding. - It can detect the algorithm used for compression from the - Content-Encoding header. At this moment only gzip and deflate - algorithms are supported. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None - -1.5. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * zlib-dev - the development libraries of zlib. - -1.6. Exported Parameters - -1.6.1. mc_level (int) - - This parameter ranges from 1 to 9 and it specifies the level of - compression you want to do. Default is 6. 9 is the best, but - the longest time consuming algorithm and 1 is the worst. If, by - mistake, you set a lower or a higher level, the default, 6, - will be used, but you will receive a warning. - - Example 1.1. Set mc_level parameter -... -modparam("mc", "mc_level", "3") -... - -1.7. Exported Functions - -1.7.1. mc_compress([algo], flags, [whitelist]) - - This function will compress the current message as specified in - the parameters. Keep in mind that the compression is done just - before the message is sent, so that all your lumps can be - applied. - - Meaning of the parameters is as follows: - * algo (int, optional) - The algorithm used for compression. - Currently implemented are deflate ('0') and gzip ('1'). - * flags (string) - Specifies on what to apply the compression - and where to put the result of the compression. - The flags parameter can have the following values: - + “b” - specifies that the body of the message shall be - compressed. Notice that if the message has no body, - the flag will have no effect. - + “h” - specifies that all the headers, except the - mandatory ones (which will be specified in "whitelist" - parameter section) and the ones in the whitelist shall - be compressed. - + “s” - the headers and the body shall be compressed - Separately, meaning that a new header named - "Comp-Hdrs" will be created, and this header will keep - the content of the compressed headers. Also, - "Headers-Encoding" header will be created in order to - keep the algorithm used to compress the headers. If - this flag is not specified, the headers and the body - (if 'b' and 'h' flags are specified) will be - compressed alltogether in the new body of the message. - + “e” - specify that you want base64 Encoding. If you do - not specify this flag, by default the module will send - the raw compressed message in deflate/gzip format. - * whitelist (string, optional) - header names list, separated - by '|' which will specify which headers shall not be - compressed, along with the mandatory ones, which can never - be compressed. The mandatory headers are the following: - VIA, FROM, TO, CSEQ, ROUTE, RECORD_ROUTE, CALLID. Also, - CONTENT_TYPE is mandatory only if CONTENT-LENGTH > 0. Also, - in case you do not want to use body compression, the - Content-Length header will become a mandatory header, which - can not be compressed. In case you do want body - compression, the old Content-Length Header will be - compressed, and a new content length will be calculated. - When you will want to do decompression, the compressed - length will be removed, and the content length header will - be the same as the one before the compression. - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, - FAILURE_ROUTE. - - Example 1.2. mc_compress usage -... -if (!mc_compress(0, "bhs", "Max-Forwards|Subject|P-Asserted-Identity")) - xlog("compression failed\n"); -... - - Example 1.3. mc_compress usage -... -$avp(algo) = 1; -$var(flags) = "bs"; -$var(list) = "Max-Forwards | Contact"; -mc_compres($avp(algo), $var(flags), $var(list); -xlog("compression registered\n"); -... - -1.7.2. mc_compact([whitelist], flags) - - This function will realise four different things: headers which - are not mandatory and are not in the whitelist will be removed, - headers of same type will be merged together, separated by ',', - header names which have a short form will be reduced to that - short form (unless the n flag has been set) and SDP rtpmap - attribute headers which contain a value lower than 96 will be - removed, because they are not mandatory. Lumps are not affected - by this function, because it is applied after all messages - changes are processed. done. The mc_compact supported short - forms are: - * “c” - Content-Type (RFC 3261) - * “f” - From (RFC 3261) - * “i” - Call-ID (RFC 3261) - * “k” - Supported (RFC 3261) - * “l” - Content-Length (RFC 3261) - * “m” - Contact (RFC 3261) - * “s” - Subject (RFC 3261) - * “t” - To (RFC 3261) - * “v” - Via (RFC 3261) - * “x” - Session-Expires (RFC 4028) - - Meaning of the parameters is as follows: - * whitelist (string, optional) - Whitelist of headers not to - be removed, except from the mandatory ones. The whitelist - header names must pe separated by '|'. - * flags (string) - Controls the behavior of the function. - Possible flags are: - + “n” - Do not use short form of headers. - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, - FAILURE_ROUTE. - - Example 1.4. mc_compress usage -... -if (!mc_compact("Max-Forwards|P-Asserted-Identity")) - xlog("compaction failed\n"); -... - -1.7.3. mc_decompress() - - This function does the reverse of mc_compress, meaning that it - does base64 decoding and gzip/deflate decompression. Keep in - mind that gzip decompression is a little bit more efficient - because it is being known the size of the compressed buffer as - against deflate which does not hold the size of the buffer, so - the decompression will be made in a static buffer. - - This function requests no parameters. - - WARNING: This function replaces the original buffer of the - message with the decompressed buffer, so any processing you do - to the message will not be taken into consideration. Try - applying the decompression function, before you do any other - processing to the message. - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, - FAILURE_ROUTE. - - Example 1.5. mc_decompress usage -... -if (!mc_decompress()) - xlog("decompression failed\n"); -... - -1.8. Compression performance test for sip messages - - The following results have been obtained using the compression - function included in the module. Using this results, you can - improve the usage of this module, in order to compress only - when you think it is favorable enough for you. The algorithm - used is deflate for all cases because gzip is always 16 bytes - higher than deflate, which represents the uncompressed size - modulo 4GB. For the subtests in the same test, the same SIP - message have been used. - - Table 1.1. mc_compress performance test results - Test Number Subtest Number Body Size Headers to Compress Size - Compressed Content Compressed Content Size Compression level - Compressed size Compression ratio - 1 1 179 82 Body + Headers 261 1 284 0.91 - 1 2 179 82 Body + Headers 261 9 284 0.91 - 1 3 179 82 Body 179 1 196 0.91 - 1 4 179 82 Body 179 9 196 0.91 - 2 1 838 392 Body + Headers 1230 1 898 1.36 - 2 2 838 392 Body + Headers 1230 9 872 1.41 - 2 3 838 392 Body 838 1 568 1.47 - 2 4 838 392 Body 838 1 540 1.55 - 3 1 1329 607 Body + Headers 1936 1 1396 1.38 - 3 2 1329 607 Body + Headers 1936 9 1352 1.43 - 3 3 1329 607 Body 1329 1 840 1.58 - 3 4 1329 607 Body + Headers 1329 9 804 1.65 - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ionut Ionita (@ionutrazvanionita) 50 12 3976 192 - 2. Razvan Crainea (@razvancrainea) 32 20 283 518 - 3. Liviu Chircu (@liviuchircu) 9 7 31 46 - 4. Vlad Patrascu (@rvlad-patrascu) 6 4 8 11 - 5. Aron Podrigal (@ar45) 6 3 126 43 - 6. Alexandra Titoc 5 3 8 5 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 4 2 - 8. Maksym Sobolyev (@sobomax) 4 2 3 3 - 9. Ryan Bullock 3 1 4 4 - 10. Julián Moreno Patiño 3 1 2 2 - - All remaining contributors: Peter Lemenkov (@lemenkov), Ryan - Bullock (@rrb3942), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Apr 2018 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Ryan Bullock Jan 2023 - Jan 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2014 - Apr 2022 - 6. Aron Podrigal (@ar45) Nov 2021 - Apr 2022 - 7. Razvan Crainea (@razvancrainea) Dec 2014 - Jul 2020 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 10. Ryan Bullock (@rrb3942) Mar 2019 - Mar 2019 - - All remaining contributors: Peter Lemenkov (@lemenkov), Ionut - Ionita (@ionutrazvanionita), Julián Moreno Patiño. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Aron - Podrigal (@ar45), Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter - Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2014 Voice Sistem SRL diff --git a/modules/compression/README.md b/modules/compression/README.md new file mode 100644 index 00000000000..493b67c5024 --- /dev/null +++ b/modules/compression/README.md @@ -0,0 +1,280 @@ +--- +title: "compression Module" +description: "This module implements message compression/decompression and base64 encoding for sip messages using deflate and gzip algorithm/headers." +--- + +## Admin Guide + + +### Overview + + +This module implements message compression/decompression and base64 encoding +for sip messages using deflate and gzip algorithm/headers. Another feature of +this module is reducing headers to compact for as specified in SIP RFC's, +sdp body codec unnecessary description removal (for codecs 0-97), whitelist +for headers not be removed (excepting necessary headers). + + +### How it works + + +The module is using zlib library to implement compression and base64 encoding +for converting the message to human readable characters. It also uses +callbacks to do the compression/compaction of the message in order for this +operations to be done after all the other script functions have been applied +to the message. + + +### Usage cases + + +As we know, udp fragmentation is a big problem these days, so this module +comes to try making the message smaller by any means. The module can be +used to compress the body or some headers found in the message or it can +decompress compressed messages. There are more possibilities to do this: +the body can be compressed along with the specified headers or the +headers can be compressed isolated from the body in a specific header. + + +Also the module does message compaction: reduction of sip header names +to short form (for example "Via" becomes 'v' and so on), sdp body +codec attributes unnecesary description ("a=rtpmap:0 PCMU/8000" becomes +"a=rtpmap:0"), unwanted headers removal by specfing the ones you want +to keep in a whitelist. + + +The module also does message decompresion and base64 decoding. It can +detect the algorithm used for compression from the Content-Encoding +header. At this moment only gzip and deflate algorithms are supported. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None* + + +### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *zlib-dev - the development libraries of [zlib](http://www.zlib.net/)*. + + +### Exported Parameters + + +#### mc_level (int) + + +This parameter ranges from 1 to 9 and it specifies the level of compression you want to do. +Default is 6. 9 is the best, but the longest time consuming algorithm and 1 is the worst. +If, by mistake, you set a lower or a higher level, the default, 6, will be used, but you will +receive a warning. + + +```opensips title="Set mc_level parameter" +... +modparam("mc", "mc_level", "3") +... + +``` + + +### Exported Functions + + +#### mc_compress([algo], flags, [whitelist]) + + +This function will compress the current message as specified in the parameters. Keep in mind +that the compression is done just before the message is sent, so that all your lumps can be +applied. + + +Meaning of the parameters is as follows: + + +- *algo* (int, optional) - The algorithm used for compression. Currently +implemented are deflate ('0') and gzip ('1'). +- *flags* (string) - Specifies on what to apply the compression and where +to put the result of the compression. +The *flags* parameter can have the following values: + + - "b" - specifies that the body of the message shall be +compressed. Notice that if the message has no body, the flag will have +no effect. + - "h" - specifies that all the headers, except the mandatory +ones (which will be specified in "whitelist" parameter section) and the +ones in the whitelist shall be compressed. + - "s" - the headers and the body shall be compressed Separately, +meaning that a new header named "Comp-Hdrs" will be created, and this +header will keep the content of the compressed headers. Also, "Headers-Encoding" +header will be created in order to keep the algorithm used to compress the +headers. If this flag is not specified, the headers and the body (if 'b' and 'h' +flags are specified) will be compressed alltogether in the new body of the +message. + - "e" - specify that you want base64 Encoding. If you do not specify +this flag, by default the module will send the raw compressed message in +deflate/gzip format. +- *whitelist* (string, optional) - header names list, separated by '|' which will specify +which headers shall not be compressed, along with the mandatory ones, which can never be +compressed. The mandatory headers are the following: VIA, FROM, TO, CSEQ, ROUTE, RECORD_ROUTE, +CALLID. Also, CONTENT_TYPE is mandatory only if CONTENT-LENGTH > 0. +Also, in case you do not want to use body compression, the Content-Length header will +become a mandatory header, which can not be compressed. In case you do want body +compression, the old Content-Length Header will be compressed, and a new content length +will be calculated. When you will want to do decompression, the compressed length will +be removed, and the content length header will be the same as the one before the +compression. + + +This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. + + +```opensips title="mc_compress usage" +... +if (!mc_compress(0, "bhs", "Max-Forwards|Subject|P-Asserted-Identity")) + xlog("compression failed\n"); +... + +``` + + +```opensips title="mc_compress usage" +... +$avp(algo) = 1; +$var(flags) = "bs"; +$var(list) = "Max-Forwards | Contact"; +mc_compres($avp(algo), $var(flags), $var(list); +xlog("compression registered\n"); +... + +``` + + +#### mc_compact([whitelist], flags) + + +This function will realise four different things: headers which are not mandatory +and are not in the whitelist will be removed, headers of same type will be merged +together, separated by ',', header names which have a short form +will be reduced to that short form (unless the *n* flag has been set) +and SDP rtpmap attribute headers which contain a value lower than 96 will be removed, +because they are not mandatory. Lumps are not affected by this function, because it is +applied after all messages changes are processed. +done. +The *mc_compact* supported short forms are: + + +- "c" - Content-Type (RFC 3261) +- "f" - From (RFC 3261) +- "i" - Call-ID (RFC 3261) +- "k" - Supported (RFC 3261) +- "l" - Content-Length (RFC 3261) +- "m" - Contact (RFC 3261) +- "s" - Subject (RFC 3261) +- "t" - To (RFC 3261) +- "v" - Via (RFC 3261) +- "x" - Session-Expires (RFC 4028) + + +Meaning of the parameters is as follows: + + +- *whitelist* (string, optional) - Whitelist of headers not to be +removed, except from the mandatory ones. The whitelist header names +must pe separated by '|'. +- *flags* (string) - Controls the behavior of the function. Possible flags are: + + - "n" - Do not use short form of headers. + + +This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. + + +```opensips title="mc_compress usage" +... +if (!mc_compact("Max-Forwards|P-Asserted-Identity")) + xlog("compaction failed\n"); +... + +``` + + +#### mc_decompress() + + +This function does the reverse of mc_compress, meaning that it does base64 +decoding and gzip/deflate decompression. Keep in mind that gzip decompression +is a little bit more efficient because it is being known the size of the +compressed buffer as against deflate which does not hold the size of the buffer, +so the decompression will be made in a static buffer. + + +This function requests no parameters. + + +WARNING: This function replaces the original buffer of the message with the +decompressed buffer, so any processing you do to the message will not be taken +into consideration. Try applying the decompression function, before you do +any other processing to the message. + + +This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. + + +```opensips title="mc_decompress usage" +... +if (!mc_decompress()) + xlog("decompression failed\n"); +... + +``` + + +### Compression performance test for sip messages + + +The following results have been obtained using the compression function +included in the module. Using this results, you can improve the usage of +this module, in order to compress only when you think it is favorable +enough for you. The algorithm used is deflate for all cases because +gzip is always 16 bytes higher than deflate, which represents the +uncompressed size modulo 4GB. For the subtests in the same test, the +same SIP message have been used. + + +**mc_compress performance test results** + + +| | | | | | | | | | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | +| `Test Number` | `Subtest Number` | `Body Size` | `Headers to Compress Size` | `Compressed Content` | `Compressed Content Size` | `Compression level` | `Compressed size` | `Compression ratio` | +| `1` | `1` | `179` | `82` | `Body + Headers` | `261` | `1` | `284` | `0.91` | +| `1` | `2` | `179` | `82` | `Body + Headers` | `261` | `9` | `284` | `0.91` | +| `1` | `3` | `179` | `82` | `Body` | `179` | `1` | `196` | `0.91` | +| `1` | `4` | `179` | `82` | `Body` | `179` | `9` | `196` | `0.91` | +| `2` | `1` | `838` | `392` | `Body + Headers` | `1230` | `1` | `898` | `1.36` | +| `2` | `2` | `838` | `392` | `Body + Headers` | `1230` | `9` | `872` | `1.41` | +| `2` | `3` | `838` | `392` | `Body` | `838` | `1` | `568` | `1.47` | +| `2` | `4` | `838` | `392` | `Body` | `838` | `1` | `540` | `1.55` | +| `3` | `1` | `1329` | `607` | `Body + Headers` | `1936` | `1` | `1396` | `1.38` | +| `3` | `2` | `1329` | `607` | `Body + Headers` | `1936` | `9` | `1352` | `1.43` | +| `3` | `3` | `1329` | `607` | `Body` | `1329` | `1` | `840` | `1.58` | +| `3` | `4` | `1329` | `607` | `Body + Headers` | `1329` | `9` | `804` | `1.65` | + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/compression/compression.c b/modules/compression/compression.c index 34c2541b94d..35660215ce8 100644 --- a/modules/compression/compression.c +++ b/modules/compression/compression.c @@ -91,7 +91,6 @@ #define WORD(p) (*(p + 0) + (*(p + 1) << 8)) #define DWORD(p) (*(p+0) + (*(p+1) << 8) + (*(p+2) << 16) + (*(p+3) << 24)) -#define LOWER_CASE(p) (*(p) & 0x20) #define BUFLEN 4096 #define COMPACT_FORMS "cfiklmstvx" @@ -898,32 +897,19 @@ static int mc_compact_cb(char** buf_p, struct mc_compact_args *mc_compact_args, i = HDR_OTHER_T; again: if (hdr_mask[i]) { - /* Compact form name so the header have - to be built */ - if (LOWER_CASE(hdr_mask[i]->name.s) || - hdr_mask[i]->type == HDR_CONTENTLENGTH_T) { - /* Copy the name of the header */ - wrap_copy_and_update(&new_buf.s, - hdr_mask[i]->name.s, - hdr_mask[i]->name.len, &new_buf.len); - - /* Copy the ': ' delimiter*/ - wrap_copy_and_update(&new_buf.s, DELIM, - DELIM_LEN, &new_buf.len); - /* Copy the first field of the header*/ - wrap_copy_and_update(&new_buf.s, - hdr_mask[i]->body.s, - hdr_mask[i]->body.len, &new_buf.len); - /* Normal form header so it can be copied in one step */ - } else { - wrap_copy_and_update( - &new_buf.s, - hdr_mask[i]->name.s, - /* Possible siblings. No CRLF yet */ - hdr_mask[i]->len - CRLF_LEN, - &new_buf.len - ); - } + /* Copy the name of the header */ + wrap_copy_and_update(&new_buf.s, + hdr_mask[i]->name.s, + hdr_mask[i]->name.len, &new_buf.len); + + /* Copy the ': ' delimiter*/ + wrap_copy_and_update(&new_buf.s, DELIM, + DELIM_LEN, &new_buf.len); + + /* Copy the first field of the header*/ + wrap_copy_and_update(&new_buf.s, + hdr_mask[i]->body.s, + hdr_mask[i]->body.len, &new_buf.len); /* Copy the rest of the header fields(siblings) if they exist */ @@ -1005,6 +991,10 @@ static int mc_compact_cb(char** buf_p, struct mc_compact_args *mc_compact_args, memcpy(*buf_p, new_buf.s, new_buf.len); *olen = new_buf.len; + if (new_buf.len > msg_total_len) + LM_BUG("buffer overflow: "\ + "calculated=%d, actual=%d\n", msg_total_len, new_buf.len); + /* Free the vector */ pkg_free(hdr_mask); @@ -1833,7 +1823,7 @@ static int mc_decompress(struct sip_msg* msg) switch (hdrs_algo) { case 0: /* deflate */ - temp = (unsigned long)BUFLEN; + temp = (unsigned long)sizeof(hdr_buf); rc = uncompress((unsigned char*)hdr_buf, &temp, diff --git a/modules/compression/doc/compression.xml b/modules/compression/doc/compression.xml deleted file mode 100644 index 40b28af1d58..00000000000 --- a/modules/compression/doc/compression.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - compression Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2014 &voicesystem; - diff --git a/modules/compression/doc/compression_admin.xml b/modules/compression/doc/compression_admin.xml deleted file mode 100644 index 60b2b9705c5..00000000000 --- a/modules/compression/doc/compression_admin.xml +++ /dev/null @@ -1,651 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module implements message compression/decompression and base64 encoding - for sip messages using deflate and gzip algorithm/headers. Another feature of - this module is reducing headers to compact for as specified in SIP RFC's, - sdp body codec unnecessary description removal (for codecs 0-97), whitelist - for headers not be removed (excepting necessary headers). - -
- -
- How it works - - The module is using zlib library to implement compression and base64 encoding - for converting the message to human readable characters. It also uses - callbacks to do the compression/compaction of the message in order for this - operations to be done after all the other script functions have been applied - to the message. - -
- -
- Usage cases - - As we know, udp fragmentation is a big problem these days, so this module - comes to try making the message smaller by any means. The module can be - used to compress the body or some headers found in the message or it can - decompress compressed messages. There are more possibilities to do this: - the body can be compressed along with the specified headers or the - headers can be compressed isolated from the body in a specific header. - - - Also the module does message compaction: reduction of sip header names - to short form (for example "Via" becomes 'v' and so on), sdp body - codec attributes unnecesary description ("a=rtpmap:0 PCMU/8000" becomes - "a=rtpmap:0"), unwanted headers removal by specfing the ones you want - to keep in a whitelist. - - - The module also does message decompresion and base64 decoding. It can - detect the algorithm used for compression from the Content-Encoding - header. At this moment only gzip and deflate algorithms are supported. - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None - - - - -
-
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - zlib-dev - the development libraries of zlib. - - - - -
- - -
- Exported Parameters - -
- <varname>mc_level</varname> (int) - - This parameter ranges from 1 to 9 and it specifies the level of compression you want to do. - Default is 6. 9 is the best, but the longest time consuming algorithm and 1 is the worst. - If, by mistake, you set a lower or a higher level, the default, 6, will be used, but you will - receive a warning. - - - - Set <varname>mc_level</varname> parameter - -... -modparam("mc", "mc_level", "3") -... - - -
- - -
- -
- Exported Functions - -
- - <function moreinfo="none">mc_compress([algo], flags, [whitelist])</function> - - - This function will compress the current message as specified in the parameters. Keep in mind - that the compression is done just before the message is sent, so that all your lumps can be - applied. - - Meaning of the parameters is as follows: - - - - algo (int, optional) - The algorithm used for compression. Currently - implemented are deflate ('0') and gzip ('1'). - - - - - - flags (string) - Specifies on what to apply the compression and where - to put the result of the compression. - - - The flags parameter can have the following values: - - - - - b - specifies that the body of the message shall be - compressed. Notice that if the message has no body, the flag will have - no effect. - - - - - - h - specifies that all the headers, except the mandatory - ones (which will be specified in "whitelist" parameter section) and the - ones in the whitelist shall be compressed. - - - - - - s - the headers and the body shall be compressed Separately, - meaning that a new header named "Comp-Hdrs" will be created, and this - header will keep the content of the compressed headers. Also, "Headers-Encoding" - header will be created in order to keep the algorithm used to compress the - headers. If this flag is not specified, the headers and the body (if 'b' and 'h' - flags are specified) will be compressed alltogether in the new body of the - message. - - - - - - e - specify that you want base64 Encoding. If you do not specify - this flag, by default the module will send the raw compressed message in - deflate/gzip format. - - - - - - - - - - whitelist (string, optional) - header names list, separated by '|' which will specify - which headers shall not be compressed, along with the mandatory ones, which can never be - compressed. The mandatory headers are the following: VIA, FROM, TO, CSEQ, ROUTE, RECORD_ROUTE, - CALLID. Also, CONTENT_TYPE is mandatory only if CONTENT-LENGTH > 0. - Also, in case you do not want to use body compression, the Content-Length header will - become a mandatory header, which can not be compressed. In case you do want body - compression, the old Content-Length Header will be compressed, and a new content length - will be calculated. When you will want to do decompression, the compressed length will - be removed, and the content length header will be the same as the one before the - compression. - - - - - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. - - - <function>mc_compress</function> usage - -... -if (!mc_compress(0, "bhs", "Max-Forwards|Subject|P-Asserted-Identity")) - xlog("compression failed\n"); -... - - - - <function>mc_compress</function> usage - -... -$avp(algo) = 1; -$var(flags) = "bs"; -$var(list) = "Max-Forwards | Contact"; -mc_compres($avp(algo), $var(flags), $var(list); -xlog("compression registered\n"); -... - - -
- -
- - <function moreinfo="none">mc_compact([whitelist], flags)</function> - - - This function will realise four different things: headers which are not mandatory - and are not in the whitelist will be removed, headers of same type will be merged - together, separated by ',', header names which have a short form - will be reduced to that short form (unless the n flag has been set) - and SDP rtpmap attribute headers which contain a value lower than 96 will be removed, - because they are not mandatory. Lumps are not affected by this function, because it is - applied after all messages changes are processed. - done. - The mc_compact supported short forms are: - - - - c - Content-Type (RFC 3261) - - - - - - f - From (RFC 3261) - - - - - - i - Call-ID (RFC 3261) - - - - - - k - Supported (RFC 3261) - - - - - - l - Content-Length (RFC 3261) - - - - - - m - Contact (RFC 3261) - - - - - - s - Subject (RFC 3261) - - - - - - t - To (RFC 3261) - - - - - - v - Via (RFC 3261) - - - - - - x - Session-Expires (RFC 4028) - - - - - Meaning of the parameters is as follows: - - - - whitelist (string, optional) - Whitelist of headers not to be - removed, except from the mandatory ones. The whitelist header names - must pe separated by '|'. - - - - - flags (string) - Controls the behavior of the function. Possible flags are: - - - - - n - Do not use short form of headers. - - - - - - - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. - - - <function>mc_compress</function> usage - -... -if (!mc_compact("Max-Forwards|P-Asserted-Identity")) - xlog("compaction failed\n"); -... - - - -
- -
- - <function moreinfo="none">mc_decompress()</function> - - - This function does the reverse of mc_compress, meaning that it does base64 - decoding and gzip/deflate decompression. Keep in mind that gzip decompression - is a little bit more efficient because it is being known the size of the - compressed buffer as against deflate which does not hold the size of the buffer, - so the decompression will be made in a static buffer. - - This function requests no parameters. - WARNING: This function replaces the original buffer of the message with the - decompressed buffer, so any processing you do to the message will not be taken - into consideration. Try applying the decompression function, before you do - any other processing to the message. - - - This function can be used from REQUEST_ROUTE, LOCAL_ROUTE, FAILURE_ROUTE. - - - <function>mc_decompress</function> usage - -... -if (!mc_decompress()) - xlog("decompression failed\n"); -... - - -
- -
- -
- Compression performance test for sip messages - The following results have been obtained using the compression function - included in the module. Using this results, you can improve the usage of - this module, in order to compress only when you think it is favorable - enough for you. The algorithm used is deflate for all cases because - gzip is always 16 bytes higher than deflate, which represents the - uncompressed size modulo 4GB. For the subtests in the same test, the - same SIP message have been used. - - - - mc_compress performance test results - - - - - Test Number - - Subtest Number - - Body Size - - Headers to Compress Size - - Compressed Content - - Compressed Content Size - - Compression level - - Compressed size - - Compression ratio - - - - 1 - - 1 - - 179 - - 82 - - Body + Headers - - 261 - - 1 - - 284 - - 0.91 - - - - 1 - - 2 - - 179 - - 82 - - Body + Headers - - 261 - - 9 - - 284 - - 0.91 - - - - 1 - - 3 - - 179 - - 82 - - Body - - 179 - - 1 - - 196 - - 0.91 - - - - 1 - - 4 - - 179 - - 82 - - Body - - 179 - - 9 - - 196 - - 0.91 - - - - 2 - - 1 - - 838 - - 392 - - Body + Headers - - 1230 - - 1 - - 898 - - 1.36 - - - - 2 - - 2 - - 838 - - 392 - - Body + Headers - - 1230 - - 9 - - 872 - - 1.41 - - - - 2 - - 3 - - 838 - - 392 - - Body - - 838 - - 1 - - 568 - - 1.47 - - - - - 2 - - 4 - - 838 - - 392 - - Body - - 838 - - 1 - - 540 - - 1.55 - - - - 3 - - 1 - - 1329 - - 607 - - Body + Headers - - 1936 - - 1 - - 1396 - - 1.38 - - - - 3 - - 2 - - 1329 - - 607 - - Body + Headers - - 1936 - - 9 - - 1352 - - 1.43 - - - - 3 - - 3 - - 1329 - - 607 - - Body - - 1329 - - 1 - - 840 - - 1.58 - - - - 3 - - 4 - - 1329 - - 607 - - Body + Headers - - 1329 - - 9 - - 804 - - 1.65 - - - -
-
- -
diff --git a/modules/compression/doc/contributors.xml b/modules/compression/doc/contributors.xml deleted file mode 100644 index 515bde4b302..00000000000 --- a/modules/compression/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ionut Ionita (@ionutrazvanionita) - 50 - 12 - 3976 - 192 - - - 2. - Razvan Crainea (@razvancrainea) - 32 - 20 - 283 - 518 - - - 3. - Liviu Chircu (@liviuchircu) - 9 - 7 - 31 - 46 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 8 - 11 - - - 5. - Aron Podrigal (@ar45) - 6 - 3 - 126 - 43 - - - 6. - Alexandra Titoc - 5 - 3 - 8 - 5 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 4 - 2 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 3 - - - 9. - Ryan Bullock - 3 - 1 - 4 - 4 - - - 10. - Julián Moreno Patiño - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Ryan Bullock (@rrb3942), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Apr 2018 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Ryan Bullock - Jan 2023 - Jan 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2014 - Apr 2022 - - - 6. - Aron Podrigal (@ar45) - Nov 2021 - Apr 2022 - - - 7. - Razvan Crainea (@razvancrainea) - Dec 2014 - Jul 2020 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 10. - Ryan Bullock (@rrb3942) - Mar 2019 - Mar 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Aron Podrigal (@ar45), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/compression/gz_helpers.c b/modules/compression/gz_helpers.c index ba8469b743e..da3fb133c15 100644 --- a/modules/compression/gz_helpers.c +++ b/modules/compression/gz_helpers.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "zlib.h" #include "compression_helpers.h" @@ -117,9 +118,9 @@ int gzip_uncompress(unsigned char* in, unsigned long ilen, str* out, unsigned lo z_stream zlibStream; int rc, neededSize; - if (!in || !ilen) { - LM_ERR("nothing to compress\n"); - return -1; + if (!in || ilen < 4) { + LM_ERR("invalid gzip input\n"); + return Z_DATA_ERROR; } /* Gzip holds the length of the original message @@ -128,6 +129,10 @@ int gzip_uncompress(unsigned char* in, unsigned long ilen, str* out, unsigned lo ((unsigned long)in[ilen-2] << 16) + ((unsigned long)in[ilen-3] << 8) + (unsigned long)in[ilen-4]; + if (*olen > INT_MAX - 1) { + LM_ERR("uncompressed gzip size too large: %lu\n", *olen); + return Z_BUF_ERROR; + } neededSize = *olen+1; /*'\0'*/ zlibStream.zalloc = Z_NULL; @@ -178,7 +183,7 @@ int gzip_uncompress(unsigned char* in, unsigned long ilen, str* out, unsigned lo } } while (rc != Z_STREAM_END); - deflateEnd(&zlibStream); + inflateEnd(&zlibStream); return Z_OK; memerr: inflateEnd(&zlibStream); diff --git a/modules/config/README b/modules/config/README deleted file mode 100644 index 115e49f1e63..00000000000 --- a/modules/config/README +++ /dev/null @@ -1,352 +0,0 @@ -Config Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Restart Persistent Memory - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. table_name (string) - 1.3.3. name_column (string) - 1.3.4. value_column (string) - 1.3.5. description_column (string) - 1.3.6. enable_restart_persistency (integer) - 1.3.7. hash_size (integer) - - 1.4. Exported Pseudo-Variables - - 1.4.1. $config(name) - 1.4.2. $config.description(name) - - 1.5. MI Commands - - 1.5.1. config_reload - 1.5.2. config_list - 1.5.3. config_push - 1.5.4. config_push_bulk - 1.5.5. config_flush - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “db_url” parameter - 1.2. Set “table_name” parameter - 1.3. Set “name_column” parameter - 1.4. Set “value_column” parameter - 1.5. Set “desctiption_column” parameter - 1.6. Set “restart_persistent_memory” parameter - 1.7. Set “hash_size” parameter - 1.8. Usage of $config(...) - 1.9. Usage of $config.description(name) - -Chapter 1. Admin Guide - -1.1. Overview - - The config module enables dynamic, runtime configuration of - OpenSIPS parameters by loading them from persistent storage at - startup and exposing them to the script level via the - $config(...) pseudo-variable. - - All configuration variables are stored in OpenSIPS' internal - cache, allowing fast access during SIP processing to maintain - high performance. The cache can be updated in three ways: - * Script – Assigning a value to the $config(...) - pseudo-variable updates the in-memory cache, but this - change is not persisted to the database. - * MI Commands – Using config_push or config_push_bulk updates - one or more variables in the runtime cache. These updates - are also not saved to the database. - * Database – Manually modifying values in the database, then - triggering the config_reload command, will refresh the - in-memory cache with updated values from the database. - -1.1.1. Restart Persistent Memory - - By default, the configuration cache is initialized at startup - by reading from the database and persists only during the - runtime. Any temporary changes made through the script or MI - commands that are not explicitly flushed to the database using - the config_flush command will be lost after a restart. - - In such cases, restart persistent memory becomes useful. When - enabled via the enable_restart_persistency parameter, OpenSIPS - no longer loads configuration values from the database on - startup. Instead, it restores the previously saved in-memory - cache, preserving runtime changes across restarts. - - If needed, you can still manually re-initialize the cache from - the database by running the config_reload MI command. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * A database module is needed to read the initial cache. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Database URL used to load the initial configuration values, and - flush them at runtime using the config_flush MI command. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set “db_url” parameter -... -modparam("config", "db_url", "dbdriver://username:password@dbhost/dbname -") -... - -1.3.2. table_name (string) - - Name of the table where configuration entries are stored. - - Default value is “config”. - - Example 1.2. Set “table_name” parameter -... -modparam("config", "table_name", "configuration") -... - -1.3.3. name_column (string) - - Name of the column storing configuration variable names. - - Default value is “name”. - - Example 1.3. Set “name_column” parameter -... -modparam("config", "name_column", "key") -... - -1.3.4. value_column (string) - - Name of the column storing configuration variable values. - - Default value is “value”. - - Example 1.4. Set “value_column” parameter -... -modparam("config", "value_column", "val") -... - -1.3.5. description_column (string) - - Name of the column storing variable descriptions. - - Default value is “description”. - - Example 1.5. Set “desctiption_column” parameter -... -modparam("config", "description_column", "desc") -... - -1.3.6. enable_restart_persistency (integer) - - Enables restart persistency. Check the Restart Persistent - Memory for more information. - - Default value is “0 / disabled”. - - Example 1.6. Set “restart_persistent_memory” parameter -... -modparam("config", "restart_persistent_memory", yes) -... - -1.3.7. hash_size (integer) - - Size of the internal hash table used to store config variables. - Must be a power of 2 number, otherwise its value will be - rounded to the closest value of 2 smaller than the provided - value. - - Default value is “16”. - - Example 1.7. Set “hash_size” parameter -... -modparam("config", "hash_size", 32) -... - -1.4. Exported Pseudo-Variables - -1.4.1. $config(name) - - Returns the value of the given config variable by name. Can - also be used for temporarily changing the value. - - Example 1.8. Usage of $config(...) - ... - xlog("Config value: $config(debug_mode)\n"); # r -eading the value - $config(debug_mode) = 1; # temporarily changing -the value - ... - -1.4.2. $config.description(name) - - Returns the description of a config variable if available. - - This variable is read-only. - - Example 1.9. Usage of $config.description(name) - ... - xlog("Description: $config.description(debug_mod -e)\n"); - ... - -1.5. MI Commands - -1.5.1. config_reload - - Reloads all configuration variables from the database. - - MI FIFO Command Format: - ## reload configuration cache from the database - opensips-mi config_reload - opensips-cli -x mi config_reload - -1.5.2. config_list - - Lists all config variables currently loaded in cache, printing - temporary values as well. If the optional description parameter - is provided and different than 0, it returns an array - containing the description of the values as well. - - MI FIFO Command Format: - ## list all configuration cache - opensips-mi config_list - opensips-cli -x mi config_list 1 - -1.5.3. config_push - - Temporarily pushes a single configuration variable. - - Expected parameters are: - * name – (string) the name of the variable - * value – (string) the value of the variable - * description – (string, optional) the description of the - variable; if missing the description is inheritted, or a - null value is used if the variable is new. - - MI FIFO Command Format: - ## push temporarily debug_mode configuration value - opensips-mi config_push debug_mode 1 "Enable Debug mode" - opensips-cli -x mi config_list 1 - -1.5.4. config_push_bulk - - Pushes multiple temporarily configuration variables in memory. - - Expected parameters are: - * configs – (json) a JSON array containing a set of variables - to be pushed. Each variable should be described as a JSON - object with the following keys: - + name – (string) the name of the variable to be - changed. - + value – (string or null) the new value of the - variable. - + description – (string, optional) the description of - the variable. - - MI FIFO Command Format: - ## push bulk temporarily values to the config cache - opensips-mi config_push_bulk -j '[[{"name":"debug_mode", -"value":"1"},{"name":"debug_level","value":"5"}]]' - - The command returns the number of values successfully pushed. - -1.5.5. config_flush - - Flushes the variables from the memory to the database. - - Expected parameters are: - * name – (string, optional) if present, flushes only a - specific config variable in database, otherwise the entire - cache. - - MI FIFO Command Format: - ## Flush config variables to the database - opensips-mi config_flush - opensips-cli -x mi config_flush debug_mode - - The command returns the number of values successfully flushed. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 14 1 1437 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2025 - May 2025 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2025 OpenSIPS Solutions; diff --git a/modules/config/README.md b/modules/config/README.md new file mode 100644 index 00000000000..51930fe3324 --- /dev/null +++ b/modules/config/README.md @@ -0,0 +1,367 @@ +--- +title: "Config Module" +description: "The *config* module enables dynamic, runtime configuration of OpenSIPS parameters by loading them from persistent storage at startup and exposing them to the script level via the [config](#pv_config) pseudo-variable." +--- + +## Admin Guide + + +### Overview + + +The *config* +module enables dynamic, runtime configuration of OpenSIPS +parameters by loading them from persistent storage at startup and +exposing them to the script level via the [config](#pv_config) +pseudo-variable. + + +All configuration variables are stored in OpenSIPS' internal +cache, allowing fast access during SIP processing to maintain high +performance. The cache can be updated in three ways: + + +- *Script* – Assigning a value to the +[config](#pv_config) pseudo-variable updates the +in-memory cache, but this change is not persisted to the database. +- *MI Commands* – Using +[mi config push](#mi_config_push) or +[mi config push bulk](#mi_config_push_bulk) updates one or more variables +in the runtime cache. These updates are also not saved to the database. +- *Database* – Manually modifying values in the +database, then triggering the [mi config reload](#mi_config_reload) +command, will refresh the in-memory cache with updated values from +the database. + + +#### Restart Persistent Memory + + +By default, the configuration cache is initialized +at startup by reading from the database and +persists only during the runtime. Any temporary +changes made through the script or MI commands +that are not explicitly flushed to the database +using the +[mi config flush](#mi_config_flush) +command will be lost after a restart. + + +In such cases, restart persistent memory becomes useful. When enabled +via the [enable rpm](#param_enable_restart_persistency) parameter, OpenSIPS no longer +loads configuration values from the database on startup. Instead, it +restores the previously saved in-memory cache, preserving runtime changes +across restarts. + + +If needed, you can still manually re-initialize the cache from the +database by running the [mi config reload](#mi_config_reload) MI command. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *A database module is needed to read the initial cache*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +Database URL used to load the initial configuration values, +and flush them at runtime using the +[mi config flush](#mi_config_flush) MI command. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set 'db_url' parameter" +... +modparam("config", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### table_name (string) + + +Name of the table where configuration entries are stored. + + +*Default value is "config".* + + +```opensips title="Set 'table_name' parameter" +... +modparam("config", "table_name", "configuration") +... +``` + + +#### name_column (string) + + +Name of the column storing configuration variable names. + + +*Default value is "name".* + + +```opensips title="Set 'name_column' parameter" +... +modparam("config", "name_column", "key") +... +``` + + +#### value_column (string) + + +Name of the column storing configuration variable values. + + +*Default value is "value".* + + +```opensips title="Set 'value_column' parameter" +... +modparam("config", "value_column", "val") +... +``` + + +#### description_column (string) + + +Name of the column storing variable descriptions. + + +*Default value is "description".* + + +```opensips title="Set 'desctiption_column' parameter" +... +modparam("config", "description_column", "desc") +... +``` + + +#### enable_restart_persistency (integer) + + +Enables restart persistency. Check the +[restart persistent memory](#restart_persistent_memory) for more information. + + +*Default value is "0 / disabled".* + + +```opensips title="Set 'restart_persistent_memory' parameter" +... +modparam("config", "restart_persistent_memory", yes) +... +``` + + +#### hash_size (integer) + + +Size of the internal hash table used to store config variables. +Must be a power of 2 number, otherwise its value will be rounded to the +closest value of 2 smaller than the provided value. + + +*Default value is "16".* + + +```opensips title="Set 'hash_size' parameter" +... +modparam("config", "hash_size", 32) +... +``` + + +### Exported Pseudo-Variables + + +#### $config(name) + + +Returns the value of the given config variable by name. +Can also be used for temporarily changing the value. + + +```opensips title="Usage of $config(...)" +... +xlog("Config value: $config(debug_mode)\n"); # reading the value +$config(debug_mode) = 1; # temporarily changing the value +... + +``` + + +#### $config.description(name) + + +Returns the description of a config variable if available. + + +This variable is read-only. + + +```opensips title="Usage of $config.description(name)" +... +xlog("Description: $config.description(debug_mode)\n"); +... + +``` + + +### Exported MI Functions + + +#### config_reload + + +Reloads all configuration variables from the database. + + +MI FIFO Command Format: + + +```bash +## reload configuration cache from the database +opensips-mi config_reload +opensips-cli -x mi config_reload +``` + + +#### config_list + + +Lists all config variables currently loaded in cache, +printing temporary values as well. +If the optional *description* parameter +is provided and different than *0*, it +returns an array containing the description of the values +as well. + + +MI FIFO Command Format: + + +```bash +## list all configuration cache +opensips-mi config_list +opensips-cli -x mi config_list 1 +``` + + +#### config_push + + +Temporarily pushes a single configuration variable. + + +Expected parameters are: + + +- *name* – (string) the name of the variable +- *value* – (string) the value of the variable +- *description* – (string, optional) the +description of the variable; if missing the description is +inheritted, or a null value is used if the variable is new. + + +MI FIFO Command Format: + + +```bash +## push temporarily debug_mode configuration value +opensips-mi config_push debug_mode 1 "Enable Debug mode" +opensips-cli -x mi config_list 1 +``` + + +#### config_push_bulk + + +Pushes multiple temporarily configuration variables in memory. + + +Expected parameters are: + + +- *configs* – (json) a JSON +array containing a set of variables to be pushed. Each +variable should be described as a JSON object with the following +keys: + * *name* – (string) the + name of the variable to be changed. + * *value* – (string or null) the + new value of the variable. + * *description* – (string, optional) + the description of the variable. + + +MI FIFO Command Format: + + +```bash +## push bulk temporarily values to the config cache +opensips-mi config_push_bulk -j '[[{"name":"debug_mode","value":"1"},{"name":"debug_level","value":"5"}]]' +``` + + +The command returns the number of values successfully pushed. + + +#### config_flush + + +Flushes the variables from the memory to the database. + + +Expected parameters are: + + +- *name* – (string, optional) if present, +flushes only a specific config variable in database, otherwise +the entire cache. + + +MI FIFO Command Format: + + +```bash +## Flush config variables to the database +opensips-mi config_flush +opensips-cli -x mi config_flush debug_mode +``` + + +The command returns the number of values successfully flushed. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/config/doc/config.xml b/modules/config/doc/config.xml deleted file mode 100644 index 1cd47f12678..00000000000 --- a/modules/config/doc/config.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Config Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2025 OpenSIPS Solutions; - diff --git a/modules/config/doc/config_admin.xml b/modules/config/doc/config_admin.xml deleted file mode 100644 index cbd2d588fd1..00000000000 --- a/modules/config/doc/config_admin.xml +++ /dev/null @@ -1,425 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The config - module enables dynamic, runtime configuration of OpenSIPS - parameters by loading them from persistent storage at startup and - exposing them to the script level via the - pseudo-variable. - - - All configuration variables are stored in OpenSIPS' internal - cache, allowing fast access during SIP processing to maintain high - performance. The cache can be updated in three ways: - - - Script – Assigning a value to the - pseudo-variable updates the - in-memory cache, but this change is not persisted to the database. - - - - MI Commands – Using - or - updates one or more variables - in the runtime cache. These updates are also not saved to the database. - - - - Database – Manually modifying values in the - database, then triggering the - command, will refresh the in-memory cache with updated values from - the database. - - - - - -
- Restart Persistent Memory - - By default, the configuration cache is initialized - at startup by reading from the database and - persists only during the runtime. Any temporary - changes made through the script or MI commands - that are not explicitly flushed to the database - using the - - command will be lost after a restart. - - - In such cases, restart persistent memory becomes useful. When enabled - via the parameter, OpenSIPS no longer - loads configuration values from the database on startup. Instead, it - restores the previously saved in-memory cache, preserving runtime changes - across restarts. - - - If needed, you can still manually re-initialize the cache from the - database by running the MI command. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - A database module is needed to read the initial cache. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - Database URL used to load the initial configuration values, - and flush them at runtime using the - MI command. - - - - Default value is &defaultdb;. - - - - Set <quote>db_url</quote> parameter - -... -modparam("config", "db_url", "&exampledb;") -... - - -
- -
- <varname>table_name</varname> (string) - Name of the table where configuration entries are stored. - - - Default value is config. - - - - Set <quote>table_name</quote> parameter - -... -modparam("config", "table_name", "configuration") -... - - -
- -
- <varname>name_column</varname> (string) - Name of the column storing configuration variable names. - - - Default value is name. - - - - Set <quote>name_column</quote> parameter - -... -modparam("config", "name_column", "key") -... - - -
- -
- <varname>value_column</varname> (string) - Name of the column storing configuration variable values. - - - Default value is value. - - - - Set <quote>value_column</quote> parameter - -... -modparam("config", "value_column", "val") -... - - -
- -
- <varname>description_column</varname> (string) - Name of the column storing variable descriptions. - - - Default value is description. - - - - Set <quote>desctiption_column</quote> parameter - -... -modparam("config", "description_column", "desc") -... - - -
- -
- <varname>enable_restart_persistency</varname> (integer) - - Enables restart persistency. Check the - for more information. - - - - Default value is 0 / disabled. - - - - Set <quote>restart_persistent_memory</quote> parameter - -... -modparam("config", "restart_persistent_memory", yes) -... - - -
- -
- <varname>hash_size</varname> (integer) - Size of the internal hash table used to store config variables. - Must be a power of 2 number, otherwise its value will be rounded to the - closest value of 2 smaller than the provided value. - - - - Default value is 16. - - - - Set <quote>hash_size</quote> parameter - -... -modparam("config", "hash_size", 32) -... - - -
-
- -
- Exported Pseudo-Variables - -
- <varname>$config(name)</varname> - - Returns the value of the given config variable by name. - Can also be used for temporarily changing the value. - - - Usage of <varname>$config(...)</varname> - - ... - xlog("Config value: $config(debug_mode)\n"); # reading the value - $config(debug_mode) = 1; # temporarily changing the value - ... - - -
- -
- <varname>$config.description(name)</varname> - - Returns the description of a config variable if available. - - - This variable is read-only. - - - Usage of <varname>$config.description(name)</varname> - - ... - xlog("Description: $config.description(debug_mode)\n"); - ... - - -
-
- -
- MI Commands - -
- <command>config_reload</command> - Reloads all configuration variables from the database. - - MI FIFO Command Format: - - - ## reload configuration cache from the database - opensips-mi config_reload - opensips-cli -x mi config_reload - -
- -
- <command>config_list</command> - Lists all config variables currently loaded in cache, - printing temporary values as well. - If the optional description parameter - is provided and different than 0, it - returns an array containing the description of the values - as well. - - - MI FIFO Command Format: - - - ## list all configuration cache - opensips-mi config_list - opensips-cli -x mi config_list 1 - -
- -
- <command>config_push</command> - - Temporarily pushes a single configuration variable. - - - Expected parameters are: - - - name – (string) the name of the variable - - - - value – (string) the value of the variable - - - - description – (string, optional) the - description of the variable; if missing the description is - inheritted, or a null value is used if the variable is new. - - - - - - MI FIFO Command Format: - - - ## push temporarily debug_mode configuration value - opensips-mi config_push debug_mode 1 "Enable Debug mode" - opensips-cli -x mi config_list 1 - -
- -
- <command>config_push_bulk</command> - - Pushes multiple temporarily configuration variables in memory. - - - Expected parameters are: - - - configs – (json) a JSON - array containing a set of variables to be pushed. Each - variable should be described as a JSON object with the following - keys: - - - name – (string) the - name of the variable to be changed. - - - - value – (string or null) the - new value of the variable. - - - - description – (string, optional) - the description of the variable. - - - - - - - - - MI FIFO Command Format: - - - ## push bulk temporarily values to the config cache - opensips-mi config_push_bulk -j '[[{"name":"debug_mode","value":"1"},{"name":"debug_level","value":"5"}]]' - - - The command returns the number of values successfully pushed. - -
- -
- <command>config_flush</command> - - Flushes the variables from the memory to the database. - - - Expected parameters are: - - - name – (string, optional) if present, - flushes only a specific config variable in database, otherwise - the entire cache. - - - - - - MI FIFO Command Format: - - - ## Flush config variables to the database - opensips-mi config_flush - opensips-cli -x mi config_flush debug_mode - - - The command returns the number of values successfully flushed. - -
- -
- -
diff --git a/modules/config/doc/contributors.xml b/modules/config/doc/contributors.xml deleted file mode 100644 index 4d27e157788..00000000000 --- a/modules/config/doc/contributors.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 14 - 1 - 1437 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2025 - May 2025 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/cpl_c/README b/modules/cpl_c/README deleted file mode 100644 index ebaa66e07b6..00000000000 --- a/modules/cpl_c/README +++ /dev/null @@ -1,574 +0,0 @@ -cpl_c Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. username_column (string) - 1.3.4. domain_column (string) - 1.3.5. cpl_xml_column (string) - 1.3.6. cpl_bin_column (string) - 1.3.7. cpl_dtd_file (string) - 1.3.8. log_dir (string) - 1.3.9. proxy_recurse (int) - 1.3.10. proxy_route (string) - 1.3.11. case_sensitive (int) - 1.3.12. realm_prefix (string) - 1.3.13. lookup_domain (string) - 1.3.14. lookup_append_branches (int) - 1.3.15. use_domain (integer) - - 1.4. Exported Functions - - 1.4.1. cpl_run_script(type,mode) - 1.4.2. cpl_process_register() - 1.4.3. cpl_process_register_norpl() - - 1.5. Exported MI Functions - - 1.5.1. LOAD_CPL - 1.5.2. REMOVE_CPL - 1.5.3. GET_CPL - - 1.6. Installation and Running - - 1.6.1. Database setup - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set db_table parameter - 1.3. Set username_column parameter - 1.4. Set domain_column parameter - 1.5. Set cpl_xml_column parameter - 1.6. Set cpl_bin_column parameter - 1.7. Set cpl_dtd_file parameter - 1.8. Set log_dir parameter - 1.9. Set proxy_recurse parameter - 1.10. Set proxy_route parameter - 1.11. Set case_sensitive parameter - 1.12. Set realm_prefix parameter - 1.13. Set lookup_domain parameter - 1.14. Set lookup_append_branches parameter - 1.15. Set use_domain parameter - 1.16. cpl_run_script usage - 1.17. cpl_process_register usage - 1.18. cpl_process_register_norpl usage - -Chapter 1. Admin Guide - -1.1. Overview - - cpl_c modules implements a CPL (Call Processing Language) - interpreter. Support for uploading/downloading/removing scripts - via SIP REGISTER method is present. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * any DB module- a DB module for interfacing the DB - operations (modules like mysql, postgres, dbtext, etc) - * TM (Transaction) module- used for proxying/forking requests - * SL (StateLess) module - used for sending stateless reply - when responding to REGISTER request or for sending back - error responses - * USRLOC (User Location) module - used for implementing - lookup("registration") tag (adding into location set of the - users' contact) - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml2 and libxml2-devel - on some SO, these to packages - are merged into libxml2. This library contains an engine - for XML parsing, DTD validation and DOM manipulation. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - A SQL URL have to be given to the module for knowing where the - database containing the table with CPL scripts is locates. If - required a user name and password can be specified for allowing - the module to connect to the database server. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("cpl_c","db_url","dbdriver://username:password@dbhost/dbname") -... - -1.3.2. db_table (string) - - Indicates the name of the table that store the CPL scripts. - This table must be locate into the database specified by - “db_url” parameter. For more about the format of the CPL table - please see the modules/cpl_c/init.mysql file. - - Default value is “cpl”. - - Example 1.2. Set db_table parameter -... -modparam("cpl_c","cpl_table","cpl") -... - -1.3.3. username_column (string) - - Indicates the name of the column used for storing the username. - - Default value is “username”. - - Example 1.3. Set username_column parameter -... -modparam("cpl_c","username_column","username") -... - -1.3.4. domain_column (string) - - Indicates the name of the column used for storing the domain. - - Default value is “domain”. - - Example 1.4. Set domain_column parameter -... -modparam("cpl_c","domain_column","domain") -... - -1.3.5. cpl_xml_column (string) - - Indicates the name of the column used for storing the the XML - version of the cpl script. - - Default value is “cpl_xml”. - - Example 1.5. Set cpl_xml_column parameter -... -modparam("cpl_c","cpl_xml_column","cpl_xml") -... - -1.3.6. cpl_bin_column (string) - - Indicates the name of the column used for storing the the - binary version of the cpl script (compiled version). - - Default value is “cpl_bin”. - - Example 1.6. Set cpl_bin_column parameter -... -modparam("cpl_c","cpl_bin_column","cpl_bin") -... - -1.3.7. cpl_dtd_file (string) - - Points to the DTD file describing the CPL grammar. The file - name may include also the path to the file. This path can be - absolute or relative (be careful the path will be relative to - the starting directory of OpenSIPS). - - This parameter is MANDATORY! - - Example 1.7. Set cpl_dtd_file parameter -... -modparam("cpl_c","cpl_dtd_file","/etc/opensips/cpl-06.dtd") -... - -1.3.8. log_dir (string) - - Points to a directory where should be created all the log file - generated by the LOG CPL node. A log file per user will be - created (on demand) having the name username.log. - - If this parameter is absent, the logging will be disabled - without generating error on execution. - - Example 1.8. Set log_dir parameter -... -modparam("cpl_c","log_dir","/var/log/opensips/cpl") -... - -1.3.9. proxy_recurse (int) - - Tells for how many time is allow to have recurse for PROXY CPL - node If it has value 2, when doing proxy, only twice the proxy - action will be re-triggered by a redirect response; the third - time, the proxy execution will end by going on REDIRECTION - branch. The recurse feature can be disable by setting this - parameter to 0 - - Default value of this parameter is 0. - - Example 1.9. Set proxy_recurse parameter -... -modparam("cpl_c","proxy_recurse",2) -... - -1.3.10. proxy_route (string) - - Before doing proxy (forward), a script route can be executed. - All modifications made by that route will be reflected only for - the current branch. - - Default value of this parameter is NULL (none). - - Example 1.10. Set proxy_route parameter -... -modparam("cpl_c","proxy_route", "1") -... - -1.3.11. case_sensitive (int) - - Tells if the username matching should be perform case sensitive - or not. Set it to a non zero value to force a case sensitive - handling of usernames. - - Default value of this parameter is 0. - - Example 1.11. Set case_sensitive parameter -... -modparam("cpl_c","case_sensitive",1) -... - -1.3.12. realm_prefix (string) - - Defines a prefix for the domain part which should be ignored in - handling users and scripts. - - Default value of this parameter is empty string. - - Example 1.12. Set realm_prefix parameter -... -modparam("cpl_c","realm_prefix","sip.") -... - -1.3.13. lookup_domain (string) - - Used by lookup tag to indicate where to perform user location. - Basically this is the name of the usrloc domain (table) where - the user registrations are kept. - - If set to empty string, the lookup node will be disabled - no - user location will be performed. - - Default value of this parameter is NULL. - - Example 1.13. Set lookup_domain parameter -... -modparam("cpl_c","lookup_domain","location") -... - -1.3.14. lookup_append_branches (int) - - Tells if the lookup tag should append branches (to do parallel - forking) if user_location lookup returns more than one contact. - Set it to a non zero value to enable parallel forking for - location lookup tag. - - Default value of this parameter is 0. - - Example 1.14. Set lookup_append_branches parameter -... -modparam("cpl_c","lookup_append_branches",1) -... - -1.3.15. use_domain (integer) - - Indicates if the domain part of the URI should be used in user - identification (otherwise only username part will be used). - - Default value is “0 (disabled)”. - - Example 1.15. Set use_domain parameter -... -modparam("cpl_c","use_domain",1) -... - -1.4. Exported Functions - -1.4.1. cpl_run_script(type,mode) - - Starts the execution of the CPL script. The user name is - fetched from new_uri or requested uri or from To header -in - this order- (for incoming execution) or from FROM header (for - outgoing execution). Regarding the stateful/stateless message - processing, the function is very flexible, being able to run in - different modes (see below the"mode" parameter). Normally this - function will end script execution. There is no guaranty that - the CPL script interpretation ended when OpenSIPS script ended - also (for the same INVITE ;-)) - this can happen when the CPL - script does a PROXY and the script interpretation pause after - proxying and it will be resume when some reply is received - (this can happen in a different process of OpenSIPS). - - If the function returns true to script, if value "1" is - returned, the SIP server should continue with the normal - behavior as if no script existed; if value (2) is returned, it - means no script was found, so nothing was done. - - When some error is reported (a false return code), the function - itself haven't sent any SIP error reply (this can be done from - script). - - Meaning of the parameters is as follows: - * type (string) - which part of the script should be run; set - it to "incoming" for having the incoming part of script - executed (when an INVITE is received) or to "outgoing" for - running the outgoing part of script (when a user is - generating an INVITE - call). - * mode (string) - sets the interpreter mode as - stateless/stateful behavior. The following modes are - accepted: - + IS_STATELESS - the current INVITE has no transaction - created yet. All replies (redirection or deny) will be - done is a stateless way. The execution will switch to - stateful only when proxy is done. So, if the function - returns, will be in stateless mode. - + IS_STATEFUL - the current INVITE has already a - transaction associated. All signaling operations - (replies or proxy) will be done in stateful way.So, if - the function returns, will be in stateful mode. - + FORCE_STATEFUL - the current INVITE has no transaction - created yet. All signaling operations will be done is - a stateful way (on signaling, the transaction will be - created from within the interpreter). So, if the - function returns, will be in stateless mode. - HINT: is_stateful is very difficult to manage from the - routing script (script processing can continue in stateful - mode); is_stateless is the fastest and less resources - consumer (transaction is created only if proxying is done), - but there is minimal protection against retransmissions - (since replies are send stateless); force_stateful is a - good compromise - all signaling is done stateful - (retransmission protection) and in the same time, if - returning to script, it will be in stateless mode (easy to - continue the routing script execution) - - This function can be used from REQUEST_ROUTE. - - Example 1.16. cpl_run_script usage -... -cpl_run_script("incoming","force_stateful"); -... - -1.4.2. cpl_process_register() - - This function MUST be called only for REGISTER requests. It - checks if the current REGISTER request is related or not with - CPL script upload/download/ remove. If it is, all the needed - operation will be done. For checking if the REGISTER is CPL - related, the function looks fist to "Content-Type" header. If - it exists and has a the mime type set to "application/cpl+xml" - means this is a CPL script upload/remove operation. The - distinction between to case is made by looking at - "Content-Disposition" header; id its value is - "script;action=store", means it's an upload; if it's - "script;action=remove", means it's a remove operation; other - values are considered to be errors. If no "Content-Type" header - is present, the function looks to "Accept" header and if it - contains the "*" or "application/cpl-xml" the request it will - be consider one for downloading CPL scripts. The functions - returns to script only if the REGISTER is not related to CPL. - In other case, the function will send by itself the necessary - replies (stateless - using sl), including for errors. - - This function can be used from REQUEST_ROUTE. - - Example 1.17. cpl_process_register usage -... -if ($rm=="REGISTER") { - cpl_process_register(); -} -... - -1.4.3. cpl_process_register_norpl() - - Same as “cpl_process_register” without internally generating - the reply. All information (script) is appended to the reply - but without sending it out. - - Main purpose of this function is to allow integration between - CPL and UserLocation services via same REGISTER messages. - - This function can be used from REQUEST_ROUTE. - - Example 1.18. cpl_process_register_norpl usage -... -if ($rm=="REGISTER") { - cpl_process_register(); - # continue with usrloc part - save("location"); -} -... - -1.5. Exported MI Functions - -1.5.1. LOAD_CPL - - For the given user, loads the XML cpl file, compiles it into - binary format and stores both format into database. - - Name: LOAD_CPL - - Parameters: - * username : name of the user - * cpl_filename: file name - - MI FIFO Command format: - opensips-cli -x mi LOAD_CPL sip:bob@domain.com cpl_scri -pt.xml - -1.5.2. REMOVE_CPL - - For the given user, removes the entire database record (XML cpl - and binary cpl); user with empty cpl scripts are not accepted. - - Name: REMOVE_CPL - - Parameters: - * username : name of the user - - MI FIFO Command format: - opensips-cli -x mi REMOVE_CPL sip:bob@domain.com - -1.5.3. GET_CPL - - For the given user, returns the CPL script in XML format. - - Name: GET_CPL - - Parameters: - * username : name of the user - - MI FIFO Command format: - opensips-cli -x mi GET_CPL sip:bob@domain.com - -1.6. Installation and Running - -1.6.1. Database setup - - Before running OpenSIPS with cpl_c, you have to setup the - database table where the module will store the CPL scripts. For - that, if the table was not created by the installation script - or you choose to install everything by yourself you can use the - cpc-create.sql SQL script in the database directories in the - opensips/scripts folder as template. Database and table name - can be set with module parameters so they can be changed, but - the name of the columns must be as they are in the SQL script. - You can also find the complete database documentation on the - project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 412 172 15560 6552 - 2. Razvan Crainea (@razvancrainea) 24 17 265 221 - 3. Daniel-Constantin Mierla (@miconda) 18 15 80 73 - 4. Liviu Chircu (@liviuchircu) 18 15 72 119 - 5. Jan Janak (@janakj) 18 10 463 219 - 6. Henning Westerholt (@henningw) 16 12 108 132 - 7. Vlad Patrascu (@rvlad-patrascu) 11 8 117 111 - 8. Andrei Pelinescu-Onciul 9 7 107 60 - 9. Maksym Sobolyev (@sobomax) 7 5 9 11 - 10. Jiri Kuthan (@jiriatipteldotorg) 7 2 372 25 - - All remaining contributors: Elena-Ramona Modroiu, Alexandra - Titoc, Eric Tamme (@etamme), Dan Pascu (@danpascu), Nick - Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Konstantin - Bokarius, Jesus Rodrigues, Norman Brandinger (@NormB), Andreas - Granig, Ionel Cerghit (@ionel-cerghit), Julián Moreno Patiño, - Ken Rice, Peter Lemenkov (@lemenkov), UnixDev, Edson Gellert - Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2002 - May 2025 - 3. Maksym Sobolyev (@sobomax) Feb 2017 - Apr 2025 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 6. Razvan Crainea (@razvancrainea) Sep 2010 - Sep 2023 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Eric Tamme (@etamme) Sep 2017 - Sep 2017 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Nick Altmann (@nikbyte), Ionel - Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas), UnixDev, Dan - Pascu (@danpascu), Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu, Norman - Brandinger (@NormB), Andreas Granig, Andrei Pelinescu-Onciul, - Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Nick Altmann (@nikbyte), Bogdan-Andrei Iancu - (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Jesus Rodrigues, Elena-Ramona Modroiu, Jan Janak - (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/cpl_c/README.md b/modules/cpl_c/README.md new file mode 100644 index 00000000000..c0c0858dc5b --- /dev/null +++ b/modules/cpl_c/README.md @@ -0,0 +1,568 @@ +--- +title: "cpl_c Module" +description: "cpl_c modules implements a CPL (Call Processing Language) interpreter." +--- + +## Admin Guide + + +### Overview + + +cpl_c modules implements a CPL (Call Processing Language) +interpreter. Support for uploading/downloading/removing scripts via +SIP REGISTER method is present. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *any DB module- a DB module for interfacing the DB +operations (modules like mysql, postgres, dbtext, etc)* +- *TM (Transaction) module- used for proxying/forking +requests* +- *SL (StateLess) module - used for sending stateless +reply when responding to REGISTER request or for sending back +error responses* +- *USRLOC (User Location) module - used for implementing +lookup("registration") tag (adding into location set of the +users' contact)* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *libxml2 and libxml2-devel - on some SO, these to +packages are merged into libxml2. This library contains an +engine for XML parsing, DTD validation and +DOM manipulation.* + + +### Exported Parameters + + +#### db_url (string) + + +A SQL URL have to be given to the module for knowing where the +database containing the table with CPL scripts is locates. If +required a user name and password can be specified for allowing +the module to connect to the database server. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("cpl_c","db_url","dbdriver://username:password@dbhost/dbname") +... +``` + + +#### db_table (string) + + +Indicates the name of the table that store the CPL scripts. +This table must be locate into the database specified by +"db_url" parameter. For more about the format of the CPL +table please see the modules/cpl_c/init.mysql file. + + +*Default value is "cpl".* + + +```opensips title="Set db_table parameter" +... +modparam("cpl_c","cpl_table","cpl") +... +``` + + +#### username_column (string) + + +Indicates the name of the column used for storing the username. + + +*Default value is "username".* + + +```opensips title="Set username_column parameter" +... +modparam("cpl_c","username_column","username") +... +``` + + +#### domain_column (string) + + +Indicates the name of the column used for storing the domain. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("cpl_c","domain_column","domain") +... +``` + + +#### cpl_xml_column (string) + + +Indicates the name of the column used for storing the +the XML version of the cpl script. + + +*Default value is "cpl_xml".* + + +```opensips title="Set cpl_xml_column parameter" +... +modparam("cpl_c","cpl_xml_column","cpl_xml") +... +``` + + +#### cpl_bin_column (string) + + +Indicates the name of the column used for storing the +the binary version of the cpl script (compiled version). + + +*Default value is "cpl_bin".* + + +```opensips title="Set cpl_bin_column parameter" +... +modparam("cpl_c","cpl_bin_column","cpl_bin") +... +``` + + +#### cpl_dtd_file (string) + + +Points to the DTD file describing the CPL grammar. The file +name may include also the path to the file. This path can be +absolute or relative (be careful the path will be relative +to the starting directory of OpenSIPS). + + +*This parameter is MANDATORY!* + + +```opensips title="Set cpl_dtd_file parameter" +... +modparam("cpl_c","cpl_dtd_file","/etc/opensips/cpl-06.dtd") +... +``` + + +#### log_dir (string) + + +Points to a directory where should be created all the log file +generated by the LOG CPL node. A log file per user will be +created (on demand) having the name username.log. + + +*If this parameter is absent, the logging will be disabled +without generating error on execution.* + + +```opensips title="Set log_dir parameter" +... +modparam("cpl_c","log_dir","/var/log/opensips/cpl") +... +``` + + +#### proxy_recurse (int) + + +Tells for how many time is allow to have recurse for PROXY CPL +node If it has value 2, when doing proxy, only twice the proxy +action will be re-triggered by a redirect response; the third +time, the proxy execution will end by going on REDIRECTION +branch. The recurse feature can be disable by setting this +parameter to 0 + + +*Default value of this parameter is 0.* + + +```opensips title="Set proxy_recurse parameter" +... +modparam("cpl_c","proxy_recurse",2) +... +``` + + +#### proxy_route (string) + + +Before doing proxy (forward), a script route can be executed. +All modifications made by that route will be reflected only for +the current branch. + + +*Default value of this parameter is NULL (none).* + + +```opensips title="Set proxy_route parameter" +... +modparam("cpl_c","proxy_route", "1") +... +``` + + +#### case_sensitive (int) + + +Tells if the username matching should be perform case +sensitive or not. Set it to a non zero value to force +a case sensitive handling of usernames. + + +*Default value of this parameter is 0.* + + +```opensips title="Set case_sensitive parameter" +... +modparam("cpl_c","case_sensitive",1) +... +``` + + +#### realm_prefix (string) + + +Defines a prefix for the domain part which should be ignored +in handling users and scripts. + + +*Default value of this parameter is empty string.* + + +```opensips title="Set realm_prefix parameter" +... +modparam("cpl_c","realm_prefix","sip.") +... +``` + + +#### lookup_domain (string) + + +Used by lookup tag to indicate where to perform user location. +Basically this is the name of the usrloc domain (table) where +the user registrations are kept. + + +If set to empty string, the lookup node will be disabled - no +user location will be performed. + + +*Default value of this parameter is NULL.* + + +```opensips title="Set lookup_domain parameter" +... +modparam("cpl_c","lookup_domain","location") +... +``` + + +#### lookup_append_branches (int) + + +Tells if the lookup tag should append branches (to do parallel +forking) if user_location lookup returns more than one contact. +Set it to a non zero value to enable parallel forking for +location lookup tag. + + +*Default value of this parameter is 0.* + + +```opensips title="Set lookup_append_branches parameter" +... +modparam("cpl_c","lookup_append_branches",1) +... +``` + + +#### use_domain (integer) + + +Indicates if the domain part of the URI should be used in +user identification (otherwise only username part will be +used). + + +*Default value is "0 (disabled)".* + + +```opensips title="Set use_domain parameter" +... +modparam("cpl_c","use_domain",1) +... +``` + + +### Exported Functions + + +#### cpl_run_script(type,mode) + + +Starts the execution of the CPL script. The user name is +fetched from new_uri or requested uri or from To header -in +this order- (for incoming execution) or from FROM header (for +outgoing execution). +Regarding the stateful/stateless message processing, the +function is very flexible, being able to run in different +modes (see below the"mode" parameter). +Normally this function will end script execution. There is no +guaranty that the CPL script interpretation ended when OpenSIPS +script ended also (for the same INVITE ;-)) - this can happen +when the CPL script does a PROXY and the script interpretation +pause after proxying and it will be resume when some reply is +received (this can happen in a different process of OpenSIPS). + + +If the function returns true to script, if value "1" is +returned, the SIP server should continue with the normal +behavior as if no script existed; if value (2) is returned, it +means no script was found, so nothing was done. + + +When some error is reported (a false return code), the +function itself haven't sent any SIP error reply (this can +be done from script). + + +Meaning of the parameters is as follows: + + +- *type (string)* - which part of the script +should be run; set it to "incoming" for having the incoming +part of script executed (when an INVITE is received) or to +"outgoing" for running the outgoing part of script (when a +user is generating an INVITE - call). +- *mode (string)* - sets the interpreter mode as +stateless/stateful behavior. The following modes are accepted: + + - *IS_STATELESS* - the current INVITE has +no transaction created yet. All replies (redirection or +deny) will be done is a stateless way. The execution will +switch to stateful only when proxy is done. So, if the +function returns, will be in stateless mode. + - *IS_STATEFUL* - the current INVITE has +already a transaction associated. All signaling operations +(replies or proxy) will be done in stateful way.So, if +the function returns, will be in stateful mode. + - *FORCE_STATEFUL* - the current INVITE +has no transaction created yet. All signaling operations +will be done is a stateful way (on signaling, the +transaction will be created from within the interpreter). +So, if the function returns, will be in stateless mode. +*HINT*: is_stateful is very +difficult to manage from the routing script (script processing +can continue in stateful mode); is_stateless is the fastest and +less resources consumer (transaction is created only if +proxying is done), but there is minimal protection against +retransmissions (since replies are send stateless); +force_stateful is a good compromise - all signaling is done +stateful (retransmission protection) and in the same time, if +returning to script, it will be in stateless mode (easy to +continue the routing script execution) + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="cpl_run_script usage" +... +cpl_run_script("incoming","force_stateful"); +... +``` + + +#### cpl_process_register() + + +This function MUST be called only for REGISTER requests. It +checks if the current REGISTER request is related or not with +CPL script upload/download/ remove. If it is, all the needed +operation will be done. For checking if the REGISTER is CPL +related, the function looks fist to "Content-Type" header. If +it exists and has a the mime type set to "application/cpl+xml" +means this is a CPL script upload/remove operation. The +distinction between to case is made by looking at +"Content-Disposition" header; id its value is +"script;action=store", means it's an upload; if it's +"script;action=remove", means it's a remove operation; other +values are considered to be errors. If no "Content-Type" +header is present, the function looks to "Accept" header and +if it contains the "*" or "application/cpl-xml" the request +it will be consider one for downloading CPL scripts. +The functions returns to script only if the REGISTER is +not related to CPL. In other case, the function will send by +itself the necessary replies (stateless - using sl), including +for errors. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="cpl_process_register usage" +... +if ($rm=="REGISTER") { + cpl_process_register(); +} +... +``` + + +#### cpl_process_register_norpl() + + +Same as "cpl_process_register" without +internally generating the reply. All information (script) is +appended to the reply but without sending it out. + + +Main purpose of this function is to allow integration +between CPL and UserLocation services via same REGISTER +messages. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="cpl_process_register_norpl usage" +... +if ($rm=="REGISTER") { + cpl_process_register(); + # continue with usrloc part + save("location"); +} +... +``` + + +### Exported MI Functions + + +#### LOAD_CPL + + +For the given user, loads the XML cpl file, compiles it into +binary format and stores both format into database. + + +Name: *LOAD_CPL* + + +Parameters: + + +- username : name of the user +- cpl_filename: file name + + +MI FIFO Command format: + + +```bash +opensips-cli -x mi LOAD_CPL sip:bob@domain.com cpl_script.xml +``` + + +#### REMOVE_CPL + + +For the given user, removes the entire database record +(XML cpl and binary cpl); user with empty cpl scripts are not +accepted. + + +Name: *REMOVE_CPL* + + +Parameters: + + +- username : name of the user + + +MI FIFO Command format: + + +```bash +opensips-cli -x mi REMOVE_CPL sip:bob@domain.com +``` + + +#### GET_CPL + + +For the given user, returns the CPL script in XML format. + + +Name: *GET_CPL* + + +Parameters: + + +- username : name of the user + + +MI FIFO Command format: + + +```bash +opensips-cli -x mi GET_CPL sip:bob@domain.com +``` + + +### Installation and Running + + +#### Database setup + + +Before running OpenSIPS with cpl_c, you have to setup the database +table where the module will store the CPL scripts. For that, if +the table was not created by the installation script or you choose +to install everything by yourself you can use the cpc-create.sql +SQL script in the database directories in the +opensips/scripts folder as template. +Database and table name can be set with module parameters so they +can be changed, but the name of the columns must be as they are +in the SQL script. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/cpl_c/doc/contributors.xml b/modules/cpl_c/doc/contributors.xml deleted file mode 100644 index 2f33bc0fbc2..00000000000 --- a/modules/cpl_c/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 412 - 172 - 15560 - 6552 - - - 2. - Razvan Crainea (@razvancrainea) - 24 - 17 - 265 - 221 - - - 3. - Daniel-Constantin Mierla (@miconda) - 18 - 15 - 80 - 73 - - - 4. - Liviu Chircu (@liviuchircu) - 18 - 15 - 72 - 119 - - - 5. - Jan Janak (@janakj) - 18 - 10 - 463 - 219 - - - 6. - Henning Westerholt (@henningw) - 16 - 12 - 108 - 132 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 11 - 8 - 117 - 111 - - - 8. - Andrei Pelinescu-Onciul - 9 - 7 - 107 - 60 - - - 9. - Maksym Sobolyev (@sobomax) - 7 - 5 - 9 - 11 - - - 10. - Jiri Kuthan (@jiriatipteldotorg) - 7 - 2 - 372 - 25 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Alexandra Titoc, Eric Tamme (@etamme), Dan Pascu (@danpascu), Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Konstantin Bokarius, Jesus Rodrigues, Norman Brandinger (@NormB), Andreas Granig, Ionel Cerghit (@ionel-cerghit), Julián Moreno Patiño, Ken Rice, Peter Lemenkov (@lemenkov), UnixDev, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2002 - May 2025 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2017 - Apr 2025 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 6. - Razvan Crainea (@razvancrainea) - Sep 2010 - Sep 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Eric Tamme (@etamme) - Sep 2017 - Sep 2017 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Nick Altmann (@nikbyte), Ionel Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas), UnixDev, Dan Pascu (@danpascu), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu, Norman Brandinger (@NormB), Andreas Granig, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Nick Altmann (@nikbyte), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jesus Rodrigues, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/cpl_c/doc/cpl_c.xml b/modules/cpl_c/doc/cpl_c.xml deleted file mode 100644 index 33810195bcc..00000000000 --- a/modules/cpl_c/doc/cpl_c.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - cpl_c Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/cpl_c/doc/cpl_c_admin.xml b/modules/cpl_c/doc/cpl_c_admin.xml deleted file mode 100644 index 61907b9db36..00000000000 --- a/modules/cpl_c/doc/cpl_c_admin.xml +++ /dev/null @@ -1,668 +0,0 @@ - - - - - &adminguide; - - -
- Overview - cpl_c modules implements a CPL (Call Processing Language) - interpreter. Support for uploading/downloading/removing scripts via - SIP REGISTER method is present. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - any DB module- a DB module for interfacing the DB - operations (modules like mysql, postgres, dbtext, etc) - - - - - - TM (Transaction) module- used for proxying/forking - requests - - - - - - SL (StateLess) module - used for sending stateless - reply when responding to REGISTER request or for sending back - error responses - - - - - - USRLOC (User Location) module - used for implementing - lookup("registration") tag (adding into location set of the - users' contact) - - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - libxml2 and libxml2-devel - on some SO, these to - packages are merged into libxml2. This library contains an - engine for XML parsing, DTD validation and - DOM manipulation. - - - - - -
-
- - -
- Exported Parameters -
- <varname>db_url</varname> (string) - - A SQL URL have to be given to the module for knowing where the - database containing the table with CPL scripts is locates. If - required a user name and password can be specified for allowing - the module to connect to the database server. - - - - Default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("cpl_c","db_url","&exampledb;") -... - - -
-
- <varname>db_table</varname> (string) - - Indicates the name of the table that store the CPL scripts. - This table must be locate into the database specified by - db_url parameter. For more about the format of the CPL - table please see the modules/cpl_c/init.mysql file. - - - - Default value is cpl. - - - - Set <varname>db_table</varname> parameter - -... -modparam("cpl_c","cpl_table","cpl") -... - - -
-
- <varname>username_column</varname> (string) - - Indicates the name of the column used for storing the username. - - - - Default value is username. - - - - Set <varname>username_column</varname> parameter - -... -modparam("cpl_c","username_column","username") -... - - -
-
- <varname>domain_column</varname> (string) - - Indicates the name of the column used for storing the domain. - - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - -... -modparam("cpl_c","domain_column","domain") -... - - -
-
- <varname>cpl_xml_column</varname> (string) - - Indicates the name of the column used for storing the - the XML version of the cpl script. - - - - Default value is cpl_xml. - - - - Set <varname>cpl_xml_column</varname> parameter - -... -modparam("cpl_c","cpl_xml_column","cpl_xml") -... - - -
-
- <varname>cpl_bin_column</varname> (string) - - Indicates the name of the column used for storing the - the binary version of the cpl script (compiled version). - - - - Default value is cpl_bin. - - - - Set <varname>cpl_bin_column</varname> parameter - -... -modparam("cpl_c","cpl_bin_column","cpl_bin") -... - - -
-
- <varname>cpl_dtd_file</varname> (string) - - Points to the DTD file describing the CPL grammar. The file - name may include also the path to the file. This path can be - absolute or relative (be careful the path will be relative - to the starting directory of &osips;). - - - - This parameter is MANDATORY! - - - - Set <varname>cpl_dtd_file</varname> parameter - -... -modparam("cpl_c","cpl_dtd_file","/etc/opensips/cpl-06.dtd") -... - - -
-
- <varname>log_dir</varname> (string) - - Points to a directory where should be created all the log file - generated by the LOG CPL node. A log file per user will be - created (on demand) having the name username.log. - - - - If this parameter is absent, the logging will be disabled - without generating error on execution. - - - - Set <varname>log_dir</varname> parameter - -... -modparam("cpl_c","log_dir","/var/log/opensips/cpl") -... - - -
-
- <varname>proxy_recurse</varname> (int) - - Tells for how many time is allow to have recurse for PROXY CPL - node If it has value 2, when doing proxy, only twice the proxy - action will be re-triggered by a redirect response; the third - time, the proxy execution will end by going on REDIRECTION - branch. The recurse feature can be disable by setting this - parameter to 0 - - - - Default value of this parameter is 0. - - - - Set <varname>proxy_recurse</varname> parameter - -... -modparam("cpl_c","proxy_recurse",2) -... - - -
-
- <varname>proxy_route</varname> (string) - - Before doing proxy (forward), a script route can be executed. - All modifications made by that route will be reflected only for - the current branch. - - - - Default value of this parameter is NULL (none). - - - - Set <varname>proxy_route</varname> parameter - -... -modparam("cpl_c","proxy_route", "1") -... - - -
-
- <varname>case_sensitive</varname> (int) - - Tells if the username matching should be perform case - sensitive or not. Set it to a non zero value to force - a case sensitive handling of usernames. - - - - Default value of this parameter is 0. - - - - Set <varname>case_sensitive</varname> parameter - -... -modparam("cpl_c","case_sensitive",1) -... - - -
-
- <varname>realm_prefix</varname> (string) - - Defines a prefix for the domain part which should be ignored - in handling users and scripts. - - - - Default value of this parameter is empty string. - - - - Set <varname>realm_prefix</varname> parameter - -... -modparam("cpl_c","realm_prefix","sip.") -... - - -
-
- <varname>lookup_domain</varname> (string) - - Used by lookup tag to indicate where to perform user location. - Basically this is the name of the usrloc domain (table) where - the user registrations are kept. - - - If set to empty string, the lookup node will be disabled - no - user location will be performed. - - - - Default value of this parameter is NULL. - - - - Set <varname>lookup_domain</varname> parameter - -... -modparam("cpl_c","lookup_domain","location") -... - - -
-
- <varname>lookup_append_branches</varname> (int) - - Tells if the lookup tag should append branches (to do parallel - forking) if user_location lookup returns more than one contact. - Set it to a non zero value to enable parallel forking for - location lookup tag. - - - - Default value of this parameter is 0. - - - - Set <varname>lookup_append_branches</varname> - parameter - -... -modparam("cpl_c","lookup_append_branches",1) -... - - -
-
- <varname>use_domain</varname> (integer) - - Indicates if the domain part of the URI should be used in - user identification (otherwise only username part will be - used). - - - - Default value is 0 (disabled). - - - - Set <varname>use_domain</varname> parameter - -... -modparam("cpl_c","use_domain",1) -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">cpl_run_script(type,mode)</function> - - - Starts the execution of the CPL script. The user name is - fetched from new_uri or requested uri or from To header -in - this order- (for incoming execution) or from FROM header (for - outgoing execution). - Regarding the stateful/stateless message processing, the - function is very flexible, being able to run in different - modes (see below the"mode" parameter). - Normally this function will end script execution. There is no - guaranty that the CPL script interpretation ended when &osips; - script ended also (for the same INVITE ;-)) - this can happen - when the CPL script does a PROXY and the script interpretation - pause after proxying and it will be resume when some reply is - received (this can happen in a different process of OpenSIPS). - - - If the function returns true to script, if value "1" is - returned, the SIP server should continue with the normal - behavior as if no script existed; if value (2) is returned, it - means no script was found, so nothing was done. - - - When some error is reported (a false return code), the - function itself haven't sent any SIP error reply (this can - be done from script). - - Meaning of the parameters is as follows: - - - type (string) - which part of the script - should be run; set it to "incoming" for having the incoming - part of script executed (when an INVITE is received) or to - "outgoing" for running the outgoing part of script (when a - user is generating an INVITE - call). - - - - mode (string) - sets the interpreter mode as - stateless/stateful behavior. The following modes are accepted: - - - - - IS_STATELESS - the current INVITE has - no transaction created yet. All replies (redirection or - deny) will be done is a stateless way. The execution will - switch to stateful only when proxy is done. So, if the - function returns, will be in stateless mode. - - - - - IS_STATEFUL - the current INVITE has - already a transaction associated. All signaling operations - (replies or proxy) will be done in stateful way.So, if - the function returns, will be in stateful mode. - - - - - FORCE_STATEFUL - the current INVITE - has no transaction created yet. All signaling operations - will be done is a stateful way (on signaling, the - transaction will be created from within the interpreter). - So, if the function returns, will be in stateless mode. - - - - - HINT: is_stateful is very - difficult to manage from the routing script (script processing - can continue in stateful mode); is_stateless is the fastest and - less resources consumer (transaction is created only if - proxying is done), but there is minimal protection against - retransmissions (since replies are send stateless); - force_stateful is a good compromise - all signaling is done - stateful (retransmission protection) and in the same time, if - returning to script, it will be in stateless mode (easy to - continue the routing script execution) - - - - - This function can be used from REQUEST_ROUTE. - - - <function>cpl_run_script</function> usage - -... -cpl_run_script("incoming","force_stateful"); -... - - -
-
- - <function moreinfo="none">cpl_process_register()</function> - - - This function MUST be called only for REGISTER requests. It - checks if the current REGISTER request is related or not with - CPL script upload/download/ remove. If it is, all the needed - operation will be done. For checking if the REGISTER is CPL - related, the function looks fist to "Content-Type" header. If - it exists and has a the mime type set to "application/cpl+xml" - means this is a CPL script upload/remove operation. The - distinction between to case is made by looking at - "Content-Disposition" header; id its value is - "script;action=store", means it's an upload; if it's - "script;action=remove", means it's a remove operation; other - values are considered to be errors. If no "Content-Type" - header is present, the function looks to "Accept" header and - if it contains the "*" or "application/cpl-xml" the request - it will be consider one for downloading CPL scripts. - The functions returns to script only if the REGISTER is - not related to CPL. In other case, the function will send by - itself the necessary replies (stateless - using sl), including - for errors. - - - This function can be used from REQUEST_ROUTE. - - - <function>cpl_process_register</function> usage - -... -if ($rm=="REGISTER") { - cpl_process_register(); -} -... - - -
-
- - <function moreinfo="none">cpl_process_register_norpl()</function> - - - Same as cpl_process_register without - internally generating the reply. All information (script) is - appended to the reply but without sending it out. - - - Main purpose of this function is to allow integration - between CPL and UserLocation services via same REGISTER - messages. - - - This function can be used from REQUEST_ROUTE. - - - <function>cpl_process_register_norpl</function> usage - - -... -if ($rm=="REGISTER") { - cpl_process_register(); - # continue with usrloc part - save("location"); -} -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">LOAD_CPL</function> - - - For the given user, loads the XML cpl file, compiles it into - binary format and stores both format into database. - - - Name: LOAD_CPL - - Parameters: - - username : name of the user - cpl_filename: file name - - - MI FIFO Command format: - - - opensips-cli -x mi LOAD_CPL sip:bob@domain.com cpl_script.xml - -
- -
- - <function moreinfo="none">REMOVE_CPL</function> - - - For the given user, removes the entire database record - (XML cpl and binary cpl); user with empty cpl scripts are not - accepted. - - - Name: REMOVE_CPL - - Parameters: - - username : name of the user - - - MI FIFO Command format: - - - opensips-cli -x mi REMOVE_CPL sip:bob@domain.com - -
- -
- - <function moreinfo="none">GET_CPL</function> - - - For the given user, returns the CPL script in XML format. - - - Name: GET_CPL - - Parameters: - - username : name of the user - - - MI FIFO Command format: - - - opensips-cli -x mi GET_CPL sip:bob@domain.com - -
-
- -
- Installation and Running -
- Database setup - - Before running &osips; with cpl_c, you have to setup the database - table where the module will store the CPL scripts. For that, if - the table was not created by the installation script or you choose - to install everything by yourself you can use the cpc-create.sql - SQL script in the database directories in the - opensips/scripts folder as template. - Database and table name can be set with module parameters so they - can be changed, but the name of the columns must be as they are - in the SQL script. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
-
-
- diff --git a/modules/db_berkeley/README b/modules/db_berkeley/README deleted file mode 100644 index 5ed09e4a734..00000000000 --- a/modules/db_berkeley/README +++ /dev/null @@ -1,523 +0,0 @@ -Berkeley DB Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. auto_reload (integer) - 1.3.2. log_enable (integer) - 1.3.3. journal_roll_interval (integer seconds) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. bdb_reload - - 1.6. Installation and Running - 1.7. Database Schema and Metadata - 1.8. METADATA_COLUMNS (required) - 1.9. METADATA_KEYS (required) - 1.10. METADATA_READONLY (optional) - 1.11. METADATA_LOGFLAGS (optional) - 1.12. DB Recovery : bdb_recover - 1.13. Known Limitations - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set auto_reload parameter - 1.2. Set log_enable parameter - 1.3. Set journal_roll_interval parameter - 1.4. METADATA_COLUMNS - 1.5. contents of version table - 1.6. METADATA_COLUMNS - 1.7. METADATA_KEYS - 1.8. METADATA_LOGFLAGS - 1.9. bdb_recover usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which integrates the Berkeley DB into - OpenSIPS. It implements the DB API defined in OpenSIPS. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * Berkeley Berkeley DB 4.6 - an embedded database. - -1.3. Exported Parameters - -1.3.1. auto_reload (integer) - - The auto-reload will close and reopen a Berkeley DB when the - files inode has changed. The operation occurs only duing a - query. Other operations such as insert or delete, do not invoke - auto_reload. - - Default value is 0 (1 - on / 0 - off). - - Example 1.1. Set auto_reload parameter -... -modparam("db_berkeley", "auto_reload", 1) -... - -1.3.2. log_enable (integer) - - The log_enable boolean controls when to create journal files. - The following operations can be journaled: INSERT, UPDATE, - DELETE. Other operations such as SELECT, do not. This - journaling are required if you need to recover from a corrupt - DB file. That is, bdb_recover requires these to rebuild the db - file. If you find this log feature useful, you may also be - interested in the METADATA_LOGFLAGS bitfield that each table - has. It will allow you to control which operations to journal, - and the destination (like syslog, stdout, local-file). Refer to - bdblib_log() and documentation on METADATA. - - Default value is 0 (1 - on / 0 - off). - - Example 1.2. Set log_enable parameter -... -modparam("db_berkeley", "log_enable", 1) -... - -1.3.3. journal_roll_interval (integer seconds) - - The journal_roll_interval will close and open a new log file. - The roll operation occurs only at the end of writing a log, so - it is not guaranteed to to roll 'on time'. - - Default value is 0 (off). - - Example 1.3. Set journal_roll_interval parameter -... -modparam("db_berkeley", "journal_roll_interval", 3600) -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Exported MI Functions - -1.5.1. bdb_reload - - Causes db_berkeley module to re-read the contents of specified - table (or dbenv). The db_berkeley DB actually loads each table - on demand, as opposed to loading all at mod_init time. The - bdb_reload operation is implemented as a close followed by a - reopen. Note- bdb_reload will fail if a table has not been - accessed before (because the close will fail). - - Name: bdb_reload - - Parameters: - * table_path - to reload a particular table provide the - tablename as the arguement; to reload all tables provide - the db_path to the db files. The path can be found in - opensipsc-cli config variable. - - MI FIFO Command Format: - opensips-cli -x mi bdb_reload subscriber - -1.6. Installation and Running - - First download, compile and install the Berkeley DB. This is - outside the scope of this document. Documentation for this - procedure is available on the Internet. - - Next, prepare to compile OpenSIPS with the db_berkeley module. - In the directory /modules/db_berkeley, modify the Makefile to - point to your distribution of Berkeley DB. You may also define - 'BDB_EXTRA_DEBUG' to compile in extra debug logs. However, it - is not a recommended deployment to production servers. - - Because the module dependes on an external library, the - db_berkeley module is not compiled and installed by default. - You can use one of the next options. - * edit the "Makefile" and remove "db_berkeley" from - "excluded_modules" list. Then follow the standard procedure - to install OpenSIPS: "make all; make install". - * from command line use: 'make all - include_modules="db_berkeley"; make install - include_modules="db_berkeley"'. - - Installation of OpenSIPS is performed by simply running make - install as root user of the main directory. This will install - the binaries in /usr/local/sbin/. If this was successful, - OpenSIPS control engine files should now be installed as - /usr/local/sbin/opensipsdbctl. - - Decide where (on the filesystem) you want to install the - Berkeley DB files. For instance, - '/usr/local/etc/opensips/db_berkeley' directory. Make note of - this directory as we need to add this path to the opensips-cli - config file. Note: OpenSIPS will not startup without these DB - files. - - (Optional) Pre creation step- Customize your meta-data. The DB - files are initially seeded with necessary meta-data. This is a - good time to review the meta-data section details, before - making modifications to your tables dbschema. By default, the - files are installed in - '/usr/local/share/opensips/db_berkeley/opensips' By default - these tables are created Read/Write and without any journalling - as shown. These settings can be modified on a per table basis. - Note: If you plan to use bdb_recover, you must change the - LOGFLAGS. - METADATA_READONLY - 0 - METADATA_LOGFLAGS - 0 - - Execute opensipsdbctl - There are three (3) groups of tables - you may need depending on your situation. - opensipsdbctl create (required) - opensipsdbctl presence (optional) - opensipsdbctl extra (optional) - - Modify the OpenSIPS configuration file to use db_berkeley - module. The database URL for modules must be the path to the - directory where the Berkeley DB table-files are located, - prefixed by "berkeley://", e.g., - "berkeley:///usr/local/etc/opensips/db_berkeley". - - A couple other IMPORTANT things to consider are the 'db_mode' - and the 'use_domain' modparams. The description of these - parameters are found in usrloc documentation. - - Note on db_mode- The db_berkeley module will only journal the - moment usrloc writes back to the DB. The safest mode is mode 3 - , since the db_berkeley journal files will always be - up-to-date. The main point is the db_mode vs. recovery by - journal file interaction. Writing journal entries is 'best - effort'. So if the hard drive becomes full, the attempt to - write a journal entry may fail. - - Note on use_domain- The db_berkeley module will attempt natural - joins when performing a query. This is basically a - lexigraphical string compare using the keys provided. In most - places in the db_berkeley dbschema (unless you customize), the - domainname is identified as a natural key. Consider an example - where use_domain = 0. In table subscriber, the db will be - keying on 'username|NULL' because the default value will be - used when that key column is not provided. This effectivly - means that later queries must consistently use the username - (w.o domain) in order to find a result to that particular - subscriber query. The main point is 'use_domain' can not be - changed once the db_berkeley is setup. - -1.7. Database Schema and Metadata - - All Berkeley DB tables are created via the opensipsdbctl - script. This section provides details as to the content and - format of the DB file upon creation. - - Since the Berkeley DB stores key value pairs, the database is - seeded with a few meta-data rows . The keys to these rows must - begin with 'METADATA'. Here is an example of table meta-data, - taken from the table 'version'. - - Note on reserved character- The '|' pipe character is used as a - record delimiter within the Berkeley DB implementation and must - not be present in any DB field. - - Example 1.4. METADATA_COLUMNS -METADATA_COLUMNS -table_name(str) table_version(int) -METADATA_KEY -0 - - In the above example, the row METADATA_COLUMNS defines the - column names and type, and the row METADATA_KEY defines which - column(s) form the key. Here the value of 0 indicates that - column 0 is the key(ie table_name). With respect to column - types, the db_berkeley modules only has the following types: - string, str, int, double, and datetime. The default type is - string, and is used when one of the others is not specified. - The columns of the meta-data are delimited by whitespace. - - The actual column data is stored as a string value, and - delimited by the '|' pipe character. Since the code tokenizes - on this delimiter, it is important that this character not - appear in any valid data field. The following is the output of - the 'db_berkeley.sh dump version' command. It shows contents of - table 'version' in plain text. - - Example 1.5. contents of version table -VERSION=3 -format=print -type=hash -h_nelem=21 -db_pagesize=4096 -HEADER=END - METADATA_READONLY - 1 - address| - address|3 - aliases| - aliases|1004 - dbaliases| - dbaliases|1 - domain| - domain|1 - speed_dial| - speed_dial|2 - subscriber| - subscriber|6 - uri| - uri|1 - METADATA_COLUMNS - table_name(str) table_version(int) - METADATA_KEY - 0 - acc| - acc|4 - grp| - grp|2 - location| - location|1004 - missed_calls| - missed_calls|3 - re_grp| - re_grp|1 - silo| - silo|5 - trusted| - trusted|4 - usr_preferences| - usr_preferences|2 -DATA=END - -1.8. METADATA_COLUMNS (required) - - The METADATA_COLUMNS row contains the column names and types. - Each is space delimited. Here is an example of the data taken - from table subscriber : - - Example 1.6. METADATA_COLUMNS -METADATA_COLUMNS -username(str) domain(str) password(str) ha1(str) ha1b(str) first_name(st -r) last_name(str) email_address(str) datetime_created(datetime) timezone -(str) rpid(str) - - Related (hardcoded) limitations: - * maximum of 32 columns per table. - * maximum tablename size is 64. - * maximum data length is 2048 - - Currently supporting these five types: str, datetime, int, - double, string. - -1.9. METADATA_KEYS (required) - - The METADATA_KEYS row indicates the indexes of the key columns, - with respect to the order specified in METADATA_COLUMNS. Here - is an example taken from table subscriber that brings up a good - point: - - Example 1.7. METADATA_KEYS - METADATA_KEY - 0 1 - - The point is that both the username and domain name are require - as the key to this record. Thus, usrloc modparam use_domain = 1 - must be set for this to work. - -1.10. METADATA_READONLY (optional) - - The METADATA_READONLY row contains a boolean 0 or 1. By - default, its value is 0. On startup the DB will open initially - as read-write (loads metadata) and then if this is set=1, it - will close and reopen as read only (ro). I found this useful - because readonly has impacts on the internal db locking etc. - -1.11. METADATA_LOGFLAGS (optional) - - The METADATA_LOGFLAGS row contains a bitfield that customizes - the journaling on a per table basis. If not present the default - value is taken as 0. Here are the masks so far (taken from - bdb_lib.h): - - Example 1.8. METADATA_LOGFLAGS -#define JLOG_NONE 0 -#define JLOG_INSERT 1 -#define JLOG_DELETE 2 -#define JLOG_UPDATE 4 -#define JLOG_STDOUT 8 -#define JLOG_SYSLOG 16 - - This means that if you want to journal INSERTS to local file - and syslog the value should be set to 1+16=17. Or if you do not - want to journal at all, set this to 0. - -1.12. DB Recovery : bdb_recover - - The db_berkeley module uses the Concurrent Data Store (CDS) - architecture. As such, no transaction or journaling is provided - by the DB natively. The application bdb_recover is specifically - written to recover data from journal files that OpenSIPS - creates. The bdb_recover application requires an additional - text file that contains the table schema. - - The schema is loaded with the '-s' option and is required for - all operations. Provide the path to the db_berkeley plain-text - schema files. By default, these install to - '/usr/local/share/opensips/db_berkeley/opensips/'. - - The '-h' home option is the DB_PATH path. Unlike the Berkeley - utilities, this application does not look for the DB_PATH - environment variable, so you have to specify it. If not - specified, it will assume the current working directory. The - last argument is the operation. There are fundamentally only - two operations- create and recover. - - The following illustrates the four operations available to the - administrator. - - Example 1.9. bdb_recover usage -usage: ./bdb_recover -s schemadir [-h home] [-c tablename] - This will create a brand new DB file with metadata. - -usage: ./bdb_recover -s schemadir [-h home] [-C all] - This will create all the core tables, each with metadata. - -usage: ./bdb_recover -s schemadir [-h home] [-r journal-file] - This will rebuild a DB and populate it with operation from journ -al-file. - The table name is embedded in the journal-file name by conventio -n. - -usage: ./bdb_recover -s schemadir [-h home] [-R lastN] - This will iterate over all core tables enumerated. If journal fi -les exist in 'home', - a new DB file will be created and populated with the data found -in the last N files. - The files are 'replayed' in chronological order (oldest to newes -t). This - allows the administrator to rebuild the db with a subset of all -possible - operations if needed. For example, you may only be interested in - - the last hours data in table location. - - Important note- A corrupted DB file must be moved out of the - way before bdb_recover is executed. - -1.13. Known Limitations - - The Berkeley DB does not nativly support an autoincrement (or - sequence) mechanism. Consequently, this version does not - support surragate keys in dbschema. These are the id columns in - the tables. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. William Quan 41 1 4682 0 - 2. Razvan Crainea (@razvancrainea) 30 25 157 156 - 3. Henning Westerholt (@henningw) 26 10 381 688 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 24 19 149 170 - 5. Anonymous 16 4 681 341 - 6. Liviu Chircu (@liviuchircu) 13 10 19 79 - 7. Daniel-Constantin Mierla (@miconda) 10 8 47 30 - 8. Vlad Patrascu (@rvlad-patrascu) 6 4 34 28 - 9. Andrei Dragus 5 1 135 103 - 10. Maksym Sobolyev (@sobomax) 4 2 5 5 - - All remaining contributors: Jan Janak (@janakj), Konstantin - Bokarius, Razvan Pistolea, Walter Doekes (@wdoekes), Peter - Lemenkov (@lemenkov), Edson Gellert Schubert, Ovidiu Sas - (@ovidiusas). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Sep 2011 - Jul 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2008 - Apr 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Walter Doekes (@wdoekes) May 2014 - May 2014 - 8. Ovidiu Sas (@ovidiusas) Oct 2010 - Oct 2010 - 9. Andrei Dragus Oct 2009 - Oct 2009 - 10. Razvan Pistolea Jul 2009 - Jul 2009 - - All remaining contributors: Jan Janak (@janakj), - Daniel-Constantin Mierla (@miconda), Henning Westerholt - (@henningw), Konstantin Bokarius, Edson Gellert Schubert, - Anonymous, William Quan. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas - (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Anonymous, William Quan. - - Documentation Copyrights: - - Copyright © 2007 Cisco Systems diff --git a/modules/db_berkeley/README.md b/modules/db_berkeley/README.md new file mode 100644 index 00000000000..03ff9bd2192 --- /dev/null +++ b/modules/db_berkeley/README.md @@ -0,0 +1,472 @@ +--- +title: "Berkeley DB Module" +description: "This is a module which integrates the Berkeley DB into OpenSIPS. It implements the DB API defined in OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This is a module which integrates the Berkeley DB into OpenSIPS. +It implements the DB API defined in OpenSIPS. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *Berkeley Berkeley DB 4.6* - an embedded database. + + +### Exported Parameters + + +#### auto_reload (integer) + + +The auto-reload will close and reopen a Berkeley DB when the +files inode has changed. The operation occurs only duing a query. +Other operations such as insert or delete, do not invoke auto_reload. + + +*Default value is 0 (1 - on / 0 - off).* + + +```opensips title="Set auto_reload parameter" +... +modparam("db_berkeley", "auto_reload", 1) +... + +``` + + +#### log_enable (integer) + + +The log_enable boolean controls when to create journal files. +The following operations can be journaled: +INSERT, UPDATE, DELETE. Other operations such as SELECT, do not. +This journaling are required if you need to recover from a corrupt +DB file. That is, bdb_recover requires these to rebuild +the db file. If you find this log feature useful, you may +also be interested in the METADATA_LOGFLAGS bitfield that each +table has. It will allow you to control which operations to +journal, and the destination (like syslog, stdout, local-file). +Refer to bdblib_log() and documentation on METADATA. + + +*Default value is 0 (1 - on / 0 - off).* + + +```opensips title="Set log_enable parameter" +... +modparam("db_berkeley", "log_enable", 1) +... + +``` + + +#### journal_roll_interval (integer seconds) + + +The journal_roll_interval will close and open a new log file. +The roll operation occurs only at the end of writing a log, +so it is not guaranteed to to roll 'on time'. + + +*Default value is 0 (off).* + + +```opensips title="Set journal_roll_interval parameter" +... +modparam("db_berkeley", "journal_roll_interval", 3600) +... + +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Exported MI Functions + + +#### bdb_reload + + +Causes db_berkeley module to re-read the contents of specified table (or dbenv). +The db_berkeley DB actually loads each table on demand, as opposed to loading all +at mod_init time. The bdb_reload operation is implemented as a close followed by a reopen. +Note- bdb_reload will fail if a table has not been accessed before (because the close +will fail). + + +Name: *bdb_reload* + + +Parameters: + + +- *table_path* - to reload a particular table +provide the tablename as the arguement; to reload +all tables provide the db_path to the db files. The path can be found +in opensipsc-cli config variable. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi bdb_reload subscriber + +``` + + +### Installation and Running + + +First download, compile and install the Berkeley DB. This is +outside the scope of this document. Documentation for this +procedure is available on the Internet. + + +Next, prepare to compile OpenSIPS with the db_berkeley module. +In the directory /modules/db_berkeley, modify the Makefile to point +to your distribution of Berkeley DB. You may also define 'BDB_EXTRA_DEBUG' +to compile in extra debug logs. However, it is not a recommended +deployment to production servers. + + +Because the module dependes on an external library, the db_berkeley module is not +compiled and installed by default. You can use one of the next options. + + +- edit the "Makefile" and remove "db_berkeley" from "excluded_modules" +list. Then follow the standard procedure to install OpenSIPS: +"make all; make install". +- from command line use: 'make all include_modules="db_berkeley"; +make install include_modules="db_berkeley"'. + + +Installation of OpenSIPS is performed by simply running make install +as root user of the main directory. This will install the binaries +in /usr/local/sbin/. +If this was successful, OpenSIPS control engine files should now +be installed as /usr/local/sbin/opensipsdbctl. + + +Decide where (on the filesystem) you want to install the Berkeley DB files. +For instance, '/usr/local/etc/opensips/db_berkeley' directory. +Make note of this directory as we need to add this path to the opensips-cli config file. +Note: OpenSIPS will not startup without these DB files. + + +(Optional) Pre creation step- Customize your meta-data. +The DB files are initially seeded with necessary meta-data. +This is a good time to review the meta-data section details, +before making modifications to your tables dbschema. +By default, the files are installed in '/usr/local/share/opensips/db_berkeley/opensips' +By default these tables are created Read/Write and without any journalling as +shown. These settings can be modified on a per table basis. +Note: If you plan to use bdb_recover, you must change the LOGFLAGS. + + +```c +METADATA_READONLY +0 +METADATA_LOGFLAGS +0 +``` + + +Execute opensipsdbctl - There are three (3) groups of tables you may need depending +on your situation. + + +```c +opensipsdbctl create (required) +opensipsdbctl presence (optional) +opensipsdbctl extra (optional) +``` + + +Modify the OpenSIPS configuration file to use db_berkeley module. +The database URL for modules must be the path to the directory where +the Berkeley DB table-files are located, prefixed by "berkeley://", +e.g., "berkeley:///usr/local/etc/opensips/db_berkeley". + + +A couple other IMPORTANT things to consider are the 'db_mode' and the 'use_domain' +modparams. The description of these parameters are found in usrloc documentation. + + +Note on db_mode- +The db_berkeley module will only journal the moment usrloc writes back +to the DB. The safest mode is mode 3 , since the db_berkeley journal files will always +be up-to-date. The main point is the db_mode vs. recovery by journal file interaction. + +Writing journal entries is 'best effort'. So if the hard drive becomes full, the +attempt to write a journal entry may fail. + + +Note on use_domain- +The db_berkeley module will attempt natural joins when performing a query. +This is basically a lexigraphical string compare using the keys provided. +In most places in the db_berkeley dbschema (unless you customize), the domainname +is identified as a natural key. +Consider an example where use_domain = 0. In table subscriber, the db will be keying on +'username|NULL' because the default value will be used when that key column is not provided. +This effectivly means that later queries must consistently use the username (w.o domain) +in order to find a result to that particular subscriber query. +The main point is 'use_domain' can not be changed once the db_berkeley is setup. + + +### Database Schema and Metadata + + +All Berkeley DB tables are created via the opensipsdbctl script. +This section provides details as to the content and +format of the DB file upon creation. + + +Since the Berkeley DB stores key value pairs, the database is seeded +with a few meta-data rows . The keys to these rows must begin with 'METADATA'. +Here is an example of table meta-data, taken from the table 'version'. + + +Note on reserved character- +The '|' pipe character is used as a record delimiter within the +Berkeley DB implementation and must not be present in any DB field. + + +```c title="METADATA_COLUMNS" +METADATA_COLUMNS +table_name(str) table_version(int) +METADATA_KEY +0 +``` + + +In the above example, the row METADATA_COLUMNS defines the column names +and type, and the row METADATA_KEY defines which column(s) form the key. +Here the value of 0 indicates that column 0 is the key(ie table_name). +With respect to column types, the db_berkeley modules only has the following +types: string, str, int, double, and datetime. The default type is string, +and is used when one of the others is not specified. The columns of the +meta-data are delimited by whitespace. + + +The actual column data is stored as a string value, and delimited by +the '|' pipe character. Since the code tokenizes on this delimiter, +it is important that this character not appear in any valid data field. +The following is the output of the 'db_berkeley.sh dump version' command. +It shows contents of table 'version' in plain text. + + +```c title="contents of version table" +VERSION=3 + format=print + type=hash + h_nelem=21 + db_pagesize=4096 +HEADER=END +METADATA_READONLY + 1 + address| + address|3 + aliases| + aliases|1004 + dbaliases| + dbaliases|1 + domain| + domain|1 + speed_dial| + speed_dial|2 + subscriber| + subscriber|6 + uri| + uri|1 + METADATA_COLUMNS + table_name(str) table_version(int) + METADATA_KEY + 0 + acc| + acc|4 + grp| + grp|2 + location| + location|1004 + missed_calls| + missed_calls|3 + re_grp| + re_grp|1 + silo| + silo|5 + trusted| + trusted|4 + usr_preferences| + usr_preferences|2 +DATA=END + +``` + + +### METADATA_COLUMNS (required) + + +The METADATA_COLUMNS row contains the column names and types. +Each is space delimited. Here is an example of the data taken from table subscriber: + + +```c title="METADATA_COLUMNS" +METADATA_COLUMNS +username(str) domain(str) password(str) ha1(str) ha1b(str) first_name(str) last_name(str) email_address(str) datetime_created(datetime) timezone(str) rpid(str) +``` + + +Related (hardcoded) limitations: + + +- maximum of 32 columns per table. +- maximum tablename size is 64. +- maximum data length is 2048 + + +Currently supporting these five types: str, datetime, int, double, string. + + +### METADATA_KEYS (required) + + +The METADATA_KEYS row indicates the indexes of the key columns, +with respect to the order specified in METADATA_COLUMNS. +Here is an example taken from table subscriber that brings up a good point: + + +```c title="METADATA_KEYS" +METADATA_KEY +0 1 +``` + + +The point is that both the username and domain name are require +as the key to this record. Thus, usrloc modparam +use_domain = 1 must be set for this to work. + + +### METADATA_READONLY (optional) + + +The METADATA_READONLY row contains a boolean 0 or 1. +By default, its value is 0. On startup the DB will +open initially as read-write (loads metadata) and then if this +is set=1, it will close and reopen as read only (ro). +I found this useful because readonly has impacts on the +internal db locking etc. + + +### METADATA_LOGFLAGS (optional) + + +The METADATA_LOGFLAGS row contains a bitfield that customizes the +journaling on a per table basis. If not present the default value +is taken as 0. Here are the masks so far (taken from bdb_lib.h): + + +```c title="METADATA_LOGFLAGS" +#define JLOG_NONE 0 +#define JLOG_INSERT 1 +#define JLOG_DELETE 2 +#define JLOG_UPDATE 4 +#define JLOG_STDOUT 8 +#define JLOG_SYSLOG 16 + +``` + + +This means that if you want to journal INSERTS to local file and syslog the value +should be set to 1+16=17. Or if you do not want to journal at all, set this to 0. + + +### DB Recovery : bdb_recover + + +The db_berkeley module uses the Concurrent Data Store (CDS) architecture. +As such, no transaction or journaling is provided by the DB natively. +The application bdb_recover is specifically written to recover data from +journal files that OpenSIPS creates. +The bdb_recover application requires an additional text file that contains +the table schema. + + +The schema is loaded with the '-s' option and is required for all operations. +Provide the path to the db_berkeley plain-text schema files. By default, these +install to '/usr/local/share/opensips/db_berkeley/opensips/'. + + +The '-h' home option is the DB_PATH path. Unlike the Berkeley utilities, +this application does not look for the DB_PATH environment variable, +so you have to specify it. If not specified, it will assume the current +working directory. The last argument is the operation. +There are fundamentally only two operations- create and recover. + + +The following illustrates the four operations available to the administrator. + + +```bash title="bdb_recover usage" +usage: ./bdb_recover -s schemadir [-h home] [-c tablename] + This will create a brand new DB file with metadata. + +usage: ./bdb_recover -s schemadir [-h home] [-C all] + This will create all the core tables, each with metadata. + +usage: ./bdb_recover -s schemadir [-h home] [-r journal-file] + This will rebuild a DB and populate it with operation from journal-file. + The table name is embedded in the journal-file name by convention. + +usage: ./bdb_recover -s schemadir [-h home] [-R lastN] + This will iterate over all core tables enumerated. If journal files exist in 'home', + a new DB file will be created and populated with the data found in the last N files. + The files are 'replayed' in chronological order (oldest to newest). This + allows the administrator to rebuild the db with a subset of all possible + operations if needed. For example, you may only be interested in + the last hours data in table location. + +``` + +> [!NOTE] +> A corrupted DB file must be moved out of the way before bdb_recover is executed. + + +### Known Limitations + + +The Berkeley DB does not nativly support an autoincrement (or sequence) mechanism. +Consequently, this version does not support surragate keys in dbschema. These +are the id columns in the tables. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_berkeley/doc/contributors.xml b/modules/db_berkeley/doc/contributors.xml deleted file mode 100644 index 3c4da81e037..00000000000 --- a/modules/db_berkeley/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - William Quan - 41 - 1 - 4682 - 0 - - - 2. - Razvan Crainea (@razvancrainea) - 30 - 25 - 157 - 156 - - - 3. - Henning Westerholt (@henningw) - 26 - 10 - 381 - 688 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 24 - 19 - 149 - 170 - - - 5. - Anonymous - 16 - 4 - 681 - 341 - - - 6. - Liviu Chircu (@liviuchircu) - 13 - 10 - 19 - 79 - - - 7. - Daniel-Constantin Mierla (@miconda) - 10 - 8 - 47 - 30 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 34 - 28 - - - 9. - Andrei Dragus - 5 - 1 - 135 - 103 - - - 10. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - -
-All remaining contributors: Jan Janak (@janakj), Konstantin Bokarius, Razvan Pistolea, Walter Doekes (@wdoekes), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Ovidiu Sas (@ovidiusas). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Sep 2011 - Jul 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2008 - Apr 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - 8. - Ovidiu Sas (@ovidiusas) - Oct 2010 - Oct 2010 - - - 9. - Andrei Dragus - Oct 2009 - Oct 2009 - - - 10. - Razvan Pistolea - Jul 2009 - Jul 2009 - - - -
-All remaining contributors: Jan Janak (@janakj), Daniel-Constantin Mierla (@miconda), Henning Westerholt (@henningw), Konstantin Bokarius, Edson Gellert Schubert, Anonymous, William Quan. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Anonymous, William Quan. -
- -
diff --git a/modules/db_berkeley/doc/db_berkeley.xml b/modules/db_berkeley/doc/db_berkeley.xml deleted file mode 100644 index 40e06afa7d5..00000000000 --- a/modules/db_berkeley/doc/db_berkeley.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Berkeley DB Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Cisco Systems - - diff --git a/modules/db_berkeley/doc/db_berkeley_admin.xml b/modules/db_berkeley/doc/db_berkeley_admin.xml deleted file mode 100644 index 7ee17b246d1..00000000000 --- a/modules/db_berkeley/doc/db_berkeley_admin.xml +++ /dev/null @@ -1,546 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module which integrates the Berkeley DB into OpenSIPS. - It implements the DB API defined in OpenSIPS. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - Berkeley Berkeley DB 4.6 - an embedded database. - - - - -
-
-
- Exported Parameters -
- <varname>auto_reload</varname> (integer) - - The auto-reload will close and reopen a Berkeley DB when the - files inode has changed. The operation occurs only duing a query. - Other operations such as insert or delete, do not invoke auto_reload. - - - - Default value is 0 (1 - on / 0 - off). - - - - Set <varname>auto_reload</varname> parameter - -... -modparam("db_berkeley", "auto_reload", 1) -... - - -
- -
- <varname>log_enable</varname> (integer) - - The log_enable boolean controls when to create journal files. - The following operations can be journaled: - INSERT, UPDATE, DELETE. Other operations such as SELECT, do not. - This journaling are required if you need to recover from a corrupt - DB file. That is, bdb_recover requires these to rebuild - the db file. If you find this log feature useful, you may - also be interested in the METADATA_LOGFLAGS bitfield that each - table has. It will allow you to control which operations to - journal, and the destination (like syslog, stdout, local-file). - Refer to bdblib_log() and documentation on METADATA. - - - - Default value is 0 (1 - on / 0 - off). - - - - Set <varname>log_enable</varname> parameter - -... -modparam("db_berkeley", "log_enable", 1) -... - - -
- -
- <varname>journal_roll_interval</varname> (integer seconds) - - The journal_roll_interval will close and open a new log file. - The roll operation occurs only at the end of writing a log, - so it is not guaranteed to to roll 'on time'. - - - - Default value is 0 (off). - - - - Set <varname>journal_roll_interval</varname> parameter - -... -modparam("db_berkeley", "journal_roll_interval", 3600) -... - - -
-
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Exported MI Functions -
- <function moreinfo="none">bdb_reload</function> - - Causes db_berkeley module to re-read the contents of specified table (or dbenv). - The db_berkeley DB actually loads each table on demand, as opposed to loading all - at mod_init time. The bdb_reload operation is implemented as a close followed by a reopen. - Note- bdb_reload will fail if a table has not been accessed before (because the close - will fail). - - - Name: bdb_reload - - Parameters: - - - table_path - to reload a particular table - provide the tablename as the arguement; to reload - all tables provide the db_path to the db files. The path can be found - in opensipsc-cli config variable. - - - - MI FIFO Command Format: - - - opensips-cli -x mi bdb_reload subscriber - -
-
- -
- Installation and Running - - First download, compile and install the Berkeley DB. This is - outside the scope of this document. Documentation for this - procedure is available on the Internet. - - - - Next, prepare to compile OpenSIPS with the db_berkeley module. - In the directory /modules/db_berkeley, modify the Makefile to point - to your distribution of Berkeley DB. You may also define 'BDB_EXTRA_DEBUG' - to compile in extra debug logs. However, it is not a recommended - deployment to production servers. - - - - Because the module dependes on an external library, the db_berkeley module is not - compiled and installed by default. You can use one of the next options. - - - - - - edit the "Makefile" and remove "db_berkeley" from "excluded_modules" - list. Then follow the standard procedure to install &osips;: - "make all; make install". - - - - - from command line use: 'make all include_modules="db_berkeley"; - make install include_modules="db_berkeley"'. - - - - - - Installation of OpenSIPS is performed by simply running make install - as root user of the main directory. This will install the binaries - in /usr/local/sbin/. - If this was successful, &osips; control engine files should now - be installed as /usr/local/sbin/opensipsdbctl. - - - - Decide where (on the filesystem) you want to install the Berkeley DB files. - For instance, '/usr/local/etc/opensips/db_berkeley' directory. - Make note of this directory as we need to add this path to the opensips-cli config file. - Note: OpenSIPS will not startup without these DB files. - - - - (Optional) Pre creation step- Customize your meta-data. - The DB files are initially seeded with necessary meta-data. - This is a good time to review the meta-data section details, - before making modifications to your tables dbschema. - By default, the files are installed in '/usr/local/share/opensips/db_berkeley/opensips' - By default these tables are created Read/Write and without any journalling as - shown. These settings can be modified on a per table basis. - Note: If you plan to use bdb_recover, you must change the LOGFLAGS. - - - METADATA_READONLY - 0 - METADATA_LOGFLAGS - 0 - - - - - Execute opensipsdbctl - There are three (3) groups of tables you may need depending - on your situation. - - - opensipsdbctl create (required) - opensipsdbctl presence (optional) - opensipsdbctl extra (optional) - - - - Modify the OpenSIPS configuration file to use db_berkeley module. - The database URL for modules must be the path to the directory where - the Berkeley DB table-files are located, prefixed by "berkeley://", - e.g., "berkeley:///usr/local/etc/opensips/db_berkeley". - - - - A couple other IMPORTANT things to consider are the 'db_mode' and the 'use_domain' - modparams. The description of these parameters are found in usrloc documentation. - - - - Note on db_mode- - The db_berkeley module will only journal the moment usrloc writes back - to the DB. The safest mode is mode 3 , since the db_berkeley journal files will always - be up-to-date. The main point is the db_mode vs. recovery by journal file interaction. - - Writing journal entries is 'best effort'. So if the hard drive becomes full, the - attempt to write a journal entry may fail. - - - - Note on use_domain- - The db_berkeley module will attempt natural joins when performing a query. - This is basically a lexigraphical string compare using the keys provided. - In most places in the db_berkeley dbschema (unless you customize), the domainname - is identified as a natural key. - Consider an example where use_domain = 0. In table subscriber, the db will be keying on - 'username|NULL' because the default value will be used when that key column is not provided. - This effectivly means that later queries must consistently use the username (w.o domain) - in order to find a result to that particular subscriber query. - The main point is 'use_domain' can not be changed once the db_berkeley is setup. - - -
- -
- Database Schema and Metadata - - - All Berkeley DB tables are created via the opensipsdbctl script. - This section provides details as to the content and - format of the DB file upon creation. - - - - Since the Berkeley DB stores key value pairs, the database is seeded - with a few meta-data rows . The keys to these rows must begin with 'METADATA'. - Here is an example of table meta-data, taken from the table 'version'. - - - - Note on reserved character- - The '|' pipe character is used as a record delimiter within the - Berkeley DB implementation and must not be present in any DB field. - - - - METADATA_COLUMNS - -METADATA_COLUMNS -table_name(str) table_version(int) -METADATA_KEY -0 - - - - - In the above example, the row METADATA_COLUMNS defines the column names - and type, and the row METADATA_KEY defines which column(s) form the key. - Here the value of 0 indicates that column 0 is the key(ie table_name). - With respect to column types, the db_berkeley modules only has the following - types: string, str, int, double, and datetime. The default type is string, - and is used when one of the others is not specified. The columns of the - meta-data are delimited by whitespace. - - - - The actual column data is stored as a string value, and delimited by - the '|' pipe character. Since the code tokenizes on this delimiter, - it is important that this character not appear in any valid data field. - The following is the output of the 'db_berkeley.sh dump version' command. - It shows contents of table 'version' in plain text. - - - - contents of version table - -VERSION=3 -format=print -type=hash -h_nelem=21 -db_pagesize=4096 -HEADER=END - METADATA_READONLY - 1 - address| - address|3 - aliases| - aliases|1004 - dbaliases| - dbaliases|1 - domain| - domain|1 - speed_dial| - speed_dial|2 - subscriber| - subscriber|6 - uri| - uri|1 - METADATA_COLUMNS - table_name(str) table_version(int) - METADATA_KEY - 0 - acc| - acc|4 - grp| - grp|2 - location| - location|1004 - missed_calls| - missed_calls|3 - re_grp| - re_grp|1 - silo| - silo|5 - trusted| - trusted|4 - usr_preferences| - usr_preferences|2 -DATA=END - - -
- -
- METADATA_COLUMNS (required) - - The METADATA_COLUMNS row contains the column names and types. - Each is space delimited. Here is an example of the data taken from table subscriber : - - - - METADATA_COLUMNS - -METADATA_COLUMNS -username(str) domain(str) password(str) ha1(str) ha1b(str) first_name(str) last_name(str) email_address(str) datetime_created(datetime) timezone(str) rpid(str) - - - - - Related (hardcoded) limitations: - - - maximum of 32 columns per table. - - - - maximum tablename size is 64. - - - - maximum data length is 2048 - - - - - - Currently supporting these five types: str, datetime, int, double, string. - - -
- -
- METADATA_KEYS (required) - - The METADATA_KEYS row indicates the indexes of the key columns, - with respect to the order specified in METADATA_COLUMNS. - Here is an example taken from table subscriber that brings up a good point: - - - - METADATA_KEYS - - METADATA_KEY - 0 1 - - - - - The point is that both the username and domain name are require - as the key to this record. Thus, usrloc modparam - use_domain = 1 must be set for this to work. - - -
- -
- METADATA_READONLY (optional) - - The METADATA_READONLY row contains a boolean 0 or 1. - By default, its value is 0. On startup the DB will - open initially as read-write (loads metadata) and then if this - is set=1, it will close and reopen as read only (ro). - I found this useful because readonly has impacts on the - internal db locking etc. - - -
- -
- METADATA_LOGFLAGS (optional) - - The METADATA_LOGFLAGS row contains a bitfield that customizes the - journaling on a per table basis. If not present the default value - is taken as 0. Here are the masks so far (taken from bdb_lib.h): - - - - METADATA_LOGFLAGS - -#define JLOG_NONE 0 -#define JLOG_INSERT 1 -#define JLOG_DELETE 2 -#define JLOG_UPDATE 4 -#define JLOG_STDOUT 8 -#define JLOG_SYSLOG 16 - - - - - This means that if you want to journal INSERTS to local file and syslog the value - should be set to 1+16=17. Or if you do not want to journal at all, set this to 0. - - -
- -
- DB Recovery : bdb_recover - - The db_berkeley module uses the Concurrent Data Store (CDS) architecture. - As such, no transaction or journaling is provided by the DB natively. - The application bdb_recover is specifically written to recover data from - journal files that OpenSIPS creates. - The bdb_recover application requires an additional text file that contains - the table schema. - - - - The schema is loaded with the '-s' option and is required for all operations. - Provide the path to the db_berkeley plain-text schema files. By default, these - install to '/usr/local/share/opensips/db_berkeley/opensips/'. - - - - The '-h' home option is the DB_PATH path. Unlike the Berkeley utilities, - this application does not look for the DB_PATH environment variable, - so you have to specify it. If not specified, it will assume the current - working directory. The last argument is the operation. - There are fundamentally only two operations- create and recover. - - - - The following illustrates the four operations available to the administrator. - - bdb_recover usage - -usage: ./bdb_recover -s schemadir [-h home] [-c tablename] - This will create a brand new DB file with metadata. - -usage: ./bdb_recover -s schemadir [-h home] [-C all] - This will create all the core tables, each with metadata. - -usage: ./bdb_recover -s schemadir [-h home] [-r journal-file] - This will rebuild a DB and populate it with operation from journal-file. - The table name is embedded in the journal-file name by convention. - -usage: ./bdb_recover -s schemadir [-h home] [-R lastN] - This will iterate over all core tables enumerated. If journal files exist in 'home', - a new DB file will be created and populated with the data found in the last N files. - The files are 'replayed' in chronological order (oldest to newest). This - allows the administrator to rebuild the db with a subset of all possible - operations if needed. For example, you may only be interested in - the last hours data in table location. - - - - - - Important note- A corrupted DB file must be moved out of the way before bdb_recover is executed. - - -
- -
- Known Limitations - - The Berkeley DB does not nativly support an autoincrement (or sequence) mechanism. - Consequently, this version does not support surragate keys in dbschema. These - are the id columns in the tables. - -
- -
- diff --git a/modules/db_cachedb/README b/modules/db_cachedb/README deleted file mode 100644 index 64e8d2ce561..00000000000 --- a/modules/db_cachedb/README +++ /dev/null @@ -1,215 +0,0 @@ -db_cachedb Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. The idea - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. cachedb_url (str) - - 1.4. Examples of Usage - - 1.4.1. Distributed Subscriber Base - - 1.5. Current Limitations - - 1.5.1. CacheDB modules integration - 1.5.2. Extensive Testing Needed - 1.5.3. CacheDB Specific 'schema' and other - incompatibilities - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. OpenSIPS CFG Snippet for using DB_CACHEDB - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. The idea - - The db_cachedb module will expose the same front db api, - however it will run on top of a NoSQL back-end, emulating the - SQL calls to the back-end specific queries. Thus, any OpenSIPS - module that would regularily need a regular SQL-based database, - will now be able to run over a NoSQL back-end, allowing for a - much easier distribution and integration of the currently - existing OpenSIPS modules in a distributed environment. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * At least one NoSQL cachedb_* module. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. cachedb_url (str) - - The URL for the CacheDB back-end to be used. It can be set more - than one time. - - Example 1.1. Set cachedb_url parameter -... -modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017 -/db.col") -... - -1.4. Examples of Usage - -1.4.1. Distributed Subscriber Base - - In order to achieve such a setup, one would have to set the - db_url parameter of the auth_db module to point to the - DB_CACHEDB URL. - - Example 1.2. OpenSIPS CFG Snippet for using DB_CACHEDB -loadmodule "auth_db.so" -modparam("auth_db", "load_credentials", "$avp(user_rpid)=rpid") - -loadmodule "db_cachedb.so" -loadmodule "cachedb_mongodb.so" -... -modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017 -/my_db.col") -modparam("auth_db","db_url","cachedb://mongodb:mycluster") -... - - With such a setup, the auth_db module will load the subscribers - from the MongoDB cluster, in the 'my_db' database, in the - 'subscriber' collection. - - The same mechanism/setup can be used to run other modules ( - like usrloc, dialog, permissions, drouting, etc ) on top of a - cachedb cluster. - -1.5. Current Limitations - -1.5.1. CacheDB modules integration - - Currently the only cachedb_* module that implements this - functionality is the cachedb_mongodb module, so currently you - can only emulate SQL queries to a MongoDB instance/cluster. - There are plans to also extend this functionality to other - cachedb_* backends, like Cassandra and CouchBase. - -1.5.2. Extensive Testing Needed - - Since there are many OpenSIPS modules that currently use the DB - interface, it wasn't feasible to test all scenarios with all - modules, and there still might be some incompatibilities. The - module was tested with some regularily used modules ( like - usrloc, dialog, permissions, drouting ), but more testing is - very much welcome, and feedback is appreciated. - -1.5.3. CacheDB Specific 'schema' and other incompatibilities - - Since the NoSQL backends do not usually have a strict schema - involved, we do not provide scripts for creating such schemas, - since the insertion ops will trigger the dynamically creation - of the schema and info. Still, a specific data collection needs - to be present, and that is the equivalent of the 'version' - table from the SQL. Since most modules check the version table - at the module setup, it's the user's responsability to setup - such a 'version' collection in the respective NoSQL back-end. - For example, for the MongoDB cluster, 'version' is a reserved - keyword, so one would have to change the default version table - that OpenSIPS uses ( via the 'db_version_table' global - parameter ) and then manually insert the version number with - something like db.my_version_table.insert({table_version : - NumberInt(5), table_name : "address"}) - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 10 8 34 35 - 2. Vlad Paiu (@vladpaiu) 10 3 626 7 - 3. Razvan Crainea (@razvancrainea) 7 5 7 5 - 4. Maksym Sobolyev (@sobomax) 4 2 3 4 - 5. Vlad Patrascu (@rvlad-patrascu) 4 2 3 2 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 3 1 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - 8. Walter Doekes (@wdoekes) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Walter Doekes (@wdoekes) May 2014 - May 2014 - 8. Vlad Paiu (@vladpaiu) Feb 2013 - Mar 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Walter Doekes (@wdoekes), Vlad Paiu - (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/db_cachedb/README.md b/modules/db_cachedb/README.md new file mode 100644 index 00000000000..4d1fd69dce4 --- /dev/null +++ b/modules/db_cachedb/README.md @@ -0,0 +1,120 @@ +--- +title: "db_cachedb Module" +--- + +## Admin Guide + + +### Overview + + +#### The idea + + +The db_cachedb module will expose the same front db api, however it will run on top +of a NoSQL back-end, emulating the SQL calls to the back-end specific queries. + +Thus, any OpenSIPS module that would regularily need a regular SQL-based database, +will now be able to run over a NoSQL back-end, allowing for a much easier distribution +and integration of the currently existing OpenSIPS modules in a distributed environment. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *At least one NoSQL cachedb_* module*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### cachedb_url (str) + + +The URL for the CacheDB back-end to be used. It can be set more than one time. + + +```opensips title="Set cachedb_url parameter" +... +modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017/db.col") +... +``` + + +### Examples of Usage + + +#### Distributed Subscriber Base + + +In order to achieve such a setup, one would have to set the db_url parameter of the auth_db module to point to the DB_CACHEDB URL. + + +```opensips title="OpenSIPS CFG Snippet for using DB_CACHEDB" +loadmodule "auth_db.so" +modparam("auth_db", "load_credentials", "$avp(user_rpid)=rpid") + +loadmodule "db_cachedb.so" +loadmodule "cachedb_mongodb.so" +... +modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017/my_db.col") +modparam("auth_db","db_url","cachedb://mongodb:mycluster") +... +``` + + +With such a setup, the auth_db module will load the subscribers from the MongoDB cluster, in the 'my_db' database, in the 'subscriber' collection. + + +The same mechanism/setup can be used to run other modules ( like usrloc, dialog, permissions, drouting, etc ) on top of a cachedb cluster. + + +### Current Limitations + + +#### CacheDB modules integration + + +Currently the only cachedb_* module that implements this functionality is the cachedb_mongodb module, so currently you can only emulate SQL queries to a MongoDB instance/cluster. + +There are plans to also extend this functionality to other cachedb_* backends, like Cassandra and CouchBase. + + +#### Extensive Testing Needed + + +Since there are many OpenSIPS modules that currently use the DB interface, it wasn't feasible to test all scenarios with all modules, and there still might be some incompatibilities. + +The module was tested with some regularily used modules ( like usrloc, dialog, permissions, drouting ), but more testing is very much welcome, and feedback is appreciated. + + +#### CacheDB Specific 'schema' and other incompatibilities + + +Since the NoSQL backends do not usually have a strict schema involved, +we do not provide scripts for creating such schemas, since the insertion ops will trigger the dynamically creation of the schema and info. + +Still, a specific data collection needs to be present, and that is the equivalent of the 'version' table from the SQL. Since most modules check the version table at the module setup, it's the user's responsability to setup such a 'version' collection in the respective NoSQL back-end. + +For example, for the MongoDB cluster, 'version' is a reserved keyword, so one would have to change the default version table that OpenSIPS uses ( via the 'db_version_table' global parameter ) and then manually insert the version number with something like db.my_version_table.insert({table_version : NumberInt(5), table_name : "address"}) + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_cachedb/doc/contributors.xml b/modules/db_cachedb/doc/contributors.xml deleted file mode 100644 index 91a54e97a24..00000000000 --- a/modules/db_cachedb/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 10 - 8 - 34 - 35 - - - 2. - Vlad Paiu (@vladpaiu) - 10 - 3 - 626 - 7 - - - 3. - Razvan Crainea (@razvancrainea) - 7 - 5 - 7 - 5 - - - 4. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 3 - 2 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 3 - 1 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 8. - Walter Doekes (@wdoekes) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - 8. - Vlad Paiu (@vladpaiu) - Feb 2013 - Mar 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/db_cachedb/doc/db_cachedb.xml b/modules/db_cachedb/doc/db_cachedb.xml deleted file mode 100644 index 9a30e813c9c..00000000000 --- a/modules/db_cachedb/doc/db_cachedb.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - -db_cachedb Module -&osipsname; - - - -&admin; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - - diff --git a/modules/db_cachedb/doc/db_cachedb_admin.xml b/modules/db_cachedb/doc/db_cachedb_admin.xml deleted file mode 100644 index caa2f6c4b0a..00000000000 --- a/modules/db_cachedb/doc/db_cachedb_admin.xml +++ /dev/null @@ -1,152 +0,0 @@ - - - - - &adminguide; - -
- Overview - -
- The idea - - The db_cachedb module will expose the same front db api, however it will run on top - of a NoSQL back-end, emulating the SQL calls to the back-end specific queries. - - Thus, any OpenSIPS module that would regularily need a regular SQL-based database, - will now be able to run over a NoSQL back-end, allowing for a much easier distribution - and integration of the currently existing OpenSIPS modules in a distributed environment. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - - At least one NoSQL cachedb_* module. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - None. - - - - -
-
- -
- Exported Parameters -
- - <varname>cachedb_url</varname> (str) - - - The URL for the CacheDB back-end to be used. It can be set more than one time. - - - Set - <varname>cachedb_url</varname> parameter - - -... -modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017/db.col") -... - - - -
-
- -
- Examples of Usage -
- - <varname>Distributed Subscriber Base</varname> - - - In order to achieve such a setup, one would have to set the db_url parameter of the auth_db module to point to the DB_CACHEDB URL. - - - OpenSIPS CFG Snippet for using DB_CACHEDB - - -loadmodule "auth_db.so" -modparam("auth_db", "load_credentials", "$avp(user_rpid)=rpid") - -loadmodule "db_cachedb.so" -loadmodule "cachedb_mongodb.so" -... -modparam("db_cachedb","cachedb_url","mongodb:mycluster://127.0.0.1:27017/my_db.col") -modparam("auth_db","db_url","cachedb://mongodb:mycluster") -... - - - - - With such a setup, the auth_db module will load the subscribers from the MongoDB cluster, in the 'my_db' database, in the 'subscriber' collection. - - - The same mechanism/setup can be used to run other modules ( like usrloc, dialog, permissions, drouting, etc ) on top of a cachedb cluster. - -
-
- -
- Current Limitations -
- - <varname>CacheDB modules integration</varname> - - - Currently the only cachedb_* module that implements this functionality is the cachedb_mongodb module, so currently you can only emulate SQL queries to a MongoDB instance/cluster. - - There are plans to also extend this functionality to other cachedb_* backends, like Cassandra and CouchBase. - -
- -
- - <varname>Extensive Testing Needed</varname> - - - Since there are many OpenSIPS modules that currently use the DB interface, it wasn't feasible to test all scenarios with all modules, and there still might be some incompatibilities. - - The module was tested with some regularily used modules ( like usrloc, dialog, permissions, drouting ), but more testing is very much welcome, and feedback is appreciated. - -
- -
- - <varname>CacheDB Specific 'schema' and other incompatibilities</varname> - - - Since the NoSQL backends do not usually have a strict schema involved, - we do not provide scripts for creating such schemas, since the insertion ops will trigger the dynamically creation of the schema and info. - - Still, a specific data collection needs to be present, and that is the equivalent of the 'version' table from the SQL. Since most modules check the version table at the module setup, it's the user's responsability to setup such a 'version' collection in the respective NoSQL back-end. - - For example, for the MongoDB cluster, 'version' is a reserved keyword, so one would have to change the default version table that OpenSIPS uses ( via the 'db_version_table' global parameter ) and then manually insert the version number with something like db.my_version_table.insert({table_version : NumberInt(5), table_name : "address"}) - -
-
-
- diff --git a/modules/db_flatstore/README b/modules/db_flatstore/README deleted file mode 100644 index 3efe2d91a1e..00000000000 --- a/modules/db_flatstore/README +++ /dev/null @@ -1,304 +0,0 @@ -Flatstore Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Rotating Log Files - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. flush (integer) - 1.3.2. delimiter (char) - 1.3.3. suffix (string) - 1.3.4. prefix (string) - 1.3.5. single_file (integer) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. flat_rotate - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “flush” parameter - 1.2. Set “delimiter” parameter - 1.3. Set “suffix” parameter - 1.4. Set “prefix” parameter - 1.5. Set “single_file” parameter - -Chapter 1. Admin Guide - -1.1. Overview - - Flatstore is one of so-called OpenSIPS database modules. It - does not export any functions executable from the configuration - scripts, but it exports a subset of functions from the database - API and thus other module can use it instead of, for example, - mysql module. - - The module does not export all functions of the database API, - it supports only one function, insert. The module is limited - but very fast. It is especially suitable for storing accounting - information on sites with extremely high traffic. If MySQL is - too slow or if you get a huge amount of accounting data then - you can consider using this module. Note that the acc module is - the only module that was tested with flastore. - - The format of the files produced by this module is plain text. - Each line consists of several fields, fields are separated by - default by the | character. New information is always appended - at the end of the file, searching, deleting and updating of - existing data is not supported by the module. - - The acc module can be configured to use flatstore module as - database backend using the db_url_parameter: -modparam("acc", "db_url", "flatstore:/var/log/acc") - - This configuration options tells acc module that it should use - the flatstore module and the flatstore module should create all - files in /var/log/acc directory. The directory must exist and - OpenSIPS processes must have permissions to create files in - that directory. - - Name of files in that directory will follow the following - pattern: -[_] - - For example, without setting any module parameter, the entries - writen by OpenSIPS process 8 into acc table would be written in - file acc_8.log. For each table there will be several files, one - file for every OpenSIPS process that wrote some data into that - table. The main reason why there are several files for each - table is that it is much faster to have one file per process, - because it does not require any locking and thus OpenSIPS - processes will not block each other. To get the complete data - for a table you can simply concatenate the contents of files - with the same table name but different process id. - Alternatively, you can use the single_file parameter, and all - processes will dump the data into the same file. Note that this - will induce some latency. - -1.1.1. Rotating Log Files - - There is a new OpenSIPS MI (management interface) command - called flat_rotate. When OpenSIPS receives the command then it - will close and reopen all files used by flatstore module. The - rotation itself has to be done by another application (such as - logrotate). Follow these steps to rotate files generated by - flatstore module: - * Rename the files that you want to rotate: -cd /var/log/acc -mv acc_1.log acc_1.log.20050605 -mv acc_2.log acc_2.log.20050605 -mv acc_4.log acc_3.log.20050605 -... - - Note that at this point OpenSIPS will still be writing all - data into the renamed files. - * Send OpenSIPS the MI command to close and reopen the - renamed files. For example, using FIFO: -opensips-cli -x mi flat_rotate - - This will force OpenSIPS to close the renamed files and - open new ones with original names, such as acc_1.log. New - files will be open at the point when OpenSIPS has some data - to write. It is normal that the files will be not created - immediately if there is no traffic on the proxy server. - Note that the suffix and prefix parameters are re-evaluated - each time the flat_rotate command is issued. Therefore, - after a rotate command, it is possible to open a different - file than previous one. - * Move the renamed files somewhere else and process them. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. flush (integer) - - Enable or disable flushing after each write. - - Default value is 1. - - Example 1.1. Set “flush” parameter -... -modparam("db_flatstore", "flush", 0) -... - -1.3.2. delimiter (char) - - Delimiter used to separate the values. - - Default value is '|'. - - Example 1.2. Set “delimiter” parameter -... -modparam("db_flatstore", "delimiter", ";") -... - -1.3.3. suffix (string) - - The suffix appended to the table name. Can be a pseudo - variable. - - Default value is ".log". - - Example 1.3. Set “suffix” parameter -... -modparam("db_flatstore", "suffix", "$time(%H)") -... - -1.3.4. prefix (string) - - The table name prefix. Can be a pseudo variable. - - Defaul value is none. - - Example 1.4. Set “prefix” parameter -... -modparam("db_flatstore", "prefix", "$time(%H)") -... - -1.3.5. single_file (integer) - - Specifies if all the processes should dump the data into a - single file. - - Default value is 0. - - Example 1.5. Set “single_file” parameter -... -modparam("db_flatstore", "single_file", 1) -... - -1.4. Exported Functions - - There are no function exported to routing script. - -1.5. Exported MI Functions - -1.5.1. flat_rotate - - It changes the name of the files where it is written. - - Name: flat_rotate - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi flat_rotate - -Chapter 2. Developer Guide - - The module implements the DB API. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 35 26 557 230 - 2. Razvan Crainea (@razvancrainea) 17 10 481 99 - 3. Jan Janak (@janakj) 16 4 1232 20 - 4. Liviu Chircu (@liviuchircu) 15 12 84 94 - 5. Daniel-Constantin Mierla (@miconda) 12 10 60 40 - 6. Vlad Patrascu (@rvlad-patrascu) 6 4 34 41 - 7. Henning Westerholt (@henningw) 6 4 24 35 - 8. Elena-Ramona Modroiu 4 2 23 1 - 9. Maksym Sobolyev (@sobomax) 4 2 4 3 - 10. Andrei Pelinescu-Onciul 3 1 29 3 - - All remaining contributors: Konstantin Bokarius, Razvan - Pistolea, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2017 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - Apr 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Razvan Pistolea Jul 2009 - Jul 2009 - 8. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - 9. Konstantin Bokarius Mar 2008 - Mar 2008 - 10. Edson Gellert Schubert Feb 2008 - Feb 2008 - - All remaining contributors: Henning Westerholt (@henningw), - Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak - (@janakj). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona - Modroiu. - - Documentation Copyrights: - - Copyright © 2004-2005 FhG FOKUS diff --git a/modules/db_flatstore/README.md b/modules/db_flatstore/README.md new file mode 100644 index 00000000000..8d93701b6b9 --- /dev/null +++ b/modules/db_flatstore/README.md @@ -0,0 +1,262 @@ +--- +title: "Flatstore Module" +description: "Flatstore is one of so-called OpenSIPS database modules. It does not export any functions executable from the configuration scripts, but it exports a subset of functions from the database API and thus other module can use it instead of, for example, mysql module." +--- + +## Admin Guide + + +### Overview + + +Flatstore is one of so-called OpenSIPS database modules. It does not +export any functions executable from the configuration scripts, but +it exports a subset of functions from the database API and thus +other module can use it instead of, for example, mysql module. + + +The module does not export all functions of the database API, it +supports only one function, insert. The module is limited but very +fast. It is especially suitable for storing accounting information +on sites with extremely high traffic. If MySQL is too slow or if +you get a huge amount of accounting data then you can consider +using this module. Note that the acc module is the only module that +was tested with flastore. + + +The format of the files produced by this module is plain text. Each +line consists of several fields, fields are separated by default by +the | character. New information is always appended at the end of the +file, searching, deleting and updating of existing data is not +supported by the module. + + +The acc module can be configured to use flatstore module as +database backend using the db_url_parameter: + + +```opensips +modparam("acc", "db_url", "flatstore:/var/log/acc") +``` + + +This configuration options tells acc module that it should use the +flatstore module and the flatstore module should create all files +in /var/log/acc directory. The directory must exist and OpenSIPS +processes must have permissions to create files in that directory. + + +Name of files in that directory will follow the following pattern: + + +```xml +[_] +``` + + +For example, without setting any module parameter, the +entries writen by OpenSIPS process 8 into acc table would +be written in file acc_8.log. For each table there will be several +files, one file for every OpenSIPS process that wrote some data into +that table. The main reason why there are several files for each +table is that it is much faster to have one file per process, +because it does not require any locking and thus OpenSIPS processes will +not block each other. To get the complete data for a table you can +simply concatenate the contents of files with the same table name +but different process id. Alternatively, you can use the single_file +parameter, and all processes will dump the data into the same file. Note +that this will induce some latency. + + +#### Rotating Log Files + + +There is a new OpenSIPS MI (management interface) command called +flat_rotate. +When OpenSIPS receives the command then it will close and reopen all +files used by flatstore module. The rotation itself has to be +done by another application (such as logrotate). Follow these +steps to rotate files generated by flatstore module: + + +- Rename the files that you want to rotate: + +```bash + +cd /var/log/acc +mv acc_1.log acc_1.log.20050605 +mv acc_2.log acc_2.log.20050605 +mv acc_4.log acc_3.log.20050605 +... +``` + +> [!NOTE] +> At this point OpenSIPS will still be writing all +> data into the renamed files. +- Send OpenSIPS the MI command to close and reopen the +renamed files. For example, using FIFO: + +```bash +opensips-cli -x mi flat_rotate +``` +This will force OpenSIPS to close the renamed files and open +new ones with original names, such as +`acc_1.log`. New files will be open +at the point when OpenSIPS has some data to write. It is +normal that the files will be not created immediately +if there is no traffic on the proxy server. + +> [!NOTE] +> The suffix and prefix parameters are re-evaluated +> each time the flat_rotate command is issued. Therefore, after +> a rotate command, it is possible to open a different file than +> previous one. + +- Move the renamed files somewhere else and process them. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### flush (integer) + + +Enable or disable flushing after each write. + + +*Default value is 1.* + + +```opensips title="Set 'flush' parameter" +... +modparam("db_flatstore", "flush", 0) +... +``` + + +#### delimiter (char) + + +Delimiter used to separate the values. + + +*Default value is '|'.* + + +```opensips title="Set 'delimiter' parameter" +... +modparam("db_flatstore", "delimiter", ";") +... +``` + + +#### suffix (string) + + +The suffix appended to the table name. Can be a pseudo +variable. + + +*Default value is ".log".* + + +```opensips title="Set 'suffix' parameter" +... +modparam("db_flatstore", "suffix", "$time(%H)") +... +``` + + +#### prefix (string) + + +The table name prefix. Can be a pseudo variable. + + +*Defaul value is none.* + + +```opensips title="Set 'prefix' parameter" +... +modparam("db_flatstore", "prefix", "$time(%H)") +... +``` + + +#### single_file (integer) + + +Specifies if all the processes should dump the data +into a single file. + + +*Default value is 0.* + + +```opensips title="Set 'single_file' parameter" +... +modparam("db_flatstore", "single_file", 1) +... +``` + + +### Exported Functions + + +There are no function exported to routing script. + + +### Exported MI Functions + + +#### flat_rotate + + +It changes the name of the files where it is written. + + +Name: *flat_rotate* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi flat_rotate +``` + + +## Developer Guide + + +The module implements the DB API. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_flatstore/doc/contributors.xml b/modules/db_flatstore/doc/contributors.xml deleted file mode 100644 index a32a3289e2a..00000000000 --- a/modules/db_flatstore/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 35 - 26 - 557 - 230 - - - 2. - Razvan Crainea (@razvancrainea) - 17 - 10 - 481 - 99 - - - 3. - Jan Janak (@janakj) - 16 - 4 - 1232 - 20 - - - 4. - Liviu Chircu (@liviuchircu) - 15 - 12 - 84 - 94 - - - 5. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 60 - 40 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 34 - 41 - - - 7. - Henning Westerholt (@henningw) - 6 - 4 - 24 - 35 - - - 8. - Elena-Ramona Modroiu - 4 - 2 - 23 - 1 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 3 - - - 10. - Andrei Pelinescu-Onciul - 3 - 1 - 29 - 3 - - - -
-All remaining contributors: Konstantin Bokarius, Razvan Pistolea, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2017 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - Apr 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Razvan Pistolea - Jul 2009 - Jul 2009 - - - 8. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - 9. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 10. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona Modroiu. -
- -
diff --git a/modules/db_flatstore/doc/db_flatstore.xml b/modules/db_flatstore/doc/db_flatstore.xml deleted file mode 100644 index 7f02524829c..00000000000 --- a/modules/db_flatstore/doc/db_flatstore.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Flatstore Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2004-2005 &fhg; - - diff --git a/modules/db_flatstore/doc/db_flatstore_admin.xml b/modules/db_flatstore/doc/db_flatstore_admin.xml deleted file mode 100644 index 39ad7367337..00000000000 --- a/modules/db_flatstore/doc/db_flatstore_admin.xml +++ /dev/null @@ -1,281 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Flatstore is one of so-called &osips; database modules. It does not - export any functions executable from the configuration scripts, but - it exports a subset of functions from the database API and thus - other module can use it instead of, for example, mysql module. - - - The module does not export all functions of the database API, it - supports only one function, insert. The module is limited but very - fast. It is especially suitable for storing accounting information - on sites with extremely high traffic. If MySQL is too slow or if - you get a huge amount of accounting data then you can consider - using this module. Note that the acc module is the only module that - was tested with flastore. - - - The format of the files produced by this module is plain text. Each - line consists of several fields, fields are separated by default by - the | character. New information is always appended at the end of the - file, searching, deleting and updating of existing data is not - supported by the module. - - - The acc module can be configured to use flatstore module as - database backend using the db_url_parameter: - - -modparam("acc", "db_url", "flatstore:/var/log/acc") - - - This configuration options tells acc module that it should use the - flatstore module and the flatstore module should create all files - in /var/log/acc directory. The directory must exist and &osips; - processes must have permissions to create files in that directory. - - - Name of files in that directory will follow the following pattern: - - -<prefix><table_name>[_<process_name>]<suffix> - - - For example, without setting any module parameter, the - entries writen by &osips; process 8 into acc table would - be written in file acc_8.log. For each table there will be several - files, one file for every &osips; process that wrote some data into - that table. The main reason why there are several files for each - table is that it is much faster to have one file per process, - because it does not require any locking and thus &osips; processes will - not block each other. To get the complete data for a table you can - simply concatenate the contents of files with the same table name - but different process id. Alternatively, you can use the single_file - parameter, and all processes will dump the data into the same file. Note - that this will induce some latency. - - -
- Rotating Log Files - - There is a new &osips; MI (management interface) command called - flat_rotate. - When &osips; receives the command then it will close and reopen all - files used by flatstore module. The rotation itself has to be - done by another application (such as logrotate). Follow these - steps to rotate files generated by flatstore module: - - - - - Rename the files that you want to rotate: - -cd /var/log/acc -mv acc_1.log acc_1.log.20050605 -mv acc_2.log acc_2.log.20050605 -mv acc_4.log acc_3.log.20050605 -... - - Note that at this point &osips; will still be writing all - data into the renamed files. - - - - - Send &osips; the MI command to close and reopen the - renamed files. For example, using FIFO: - -opensips-cli -x mi flat_rotate - - This will force &osips; to close the renamed files and open - new ones with original names, such as - acc_1.log. New files will be open - at the point when &osips; has some data to write. It is - normal that the files will be not created immediately - if there is no traffic on the proxy server. - - - Note that the suffix and prefix parameters are re-evaluated - each time the flat_rotate command is issued. Therefore, after - a rotate command, it is possible to open a different file than - previous one. - - - - - Move the renamed files somewhere else and process them. - - - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>flush</varname> (integer) - - Enable or disable flushing after each write. - - - - Default value is 1. - - - - Set <quote>flush</quote> parameter - -... -modparam("db_flatstore", "flush", 0) -... - - -
-
- <varname>delimiter</varname> (char) - - Delimiter used to separate the values. - - - - Default value is '|'. - - - - Set <quote>delimiter</quote> parameter - -... -modparam("db_flatstore", "delimiter", ";") -... - - -
-
- <varname>suffix</varname> (string) - - The suffix appended to the table name. Can be a pseudo - variable. - - - - Default value is ".log". - - - - Set <quote>suffix</quote> parameter - -... -modparam("db_flatstore", "suffix", "$time(%H)") -... - - -
-
- <varname>prefix</varname> (string) - - The table name prefix. Can be a pseudo variable. - - - - Defaul value is none. - - - - Set <quote>prefix</quote> parameter - -... -modparam("db_flatstore", "prefix", "$time(%H)") -... - - -
-
- <varname>single_file</varname> (integer) - - Specifies if all the processes should dump the data - into a single file. - - - - Default value is 0. - - - - Set <quote>single_file</quote> parameter - -... -modparam("db_flatstore", "single_file", 1) -... - - -
-
- -
- Exported Functions - - There are no function exported to routing script. - -
- -
- Exported MI Functions -
- - <function moreinfo="none">flat_rotate</function> - - - It changes the name of the files where it is written. - - - Name: flat_rotate - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi flat_rotate - -
-
-
- diff --git a/modules/db_flatstore/doc/db_flatstore_devel.xml b/modules/db_flatstore/doc/db_flatstore_devel.xml deleted file mode 100644 index 7b511cb6933..00000000000 --- a/modules/db_flatstore/doc/db_flatstore_devel.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - &develguide; - - The module implements the DB API. - - - diff --git a/modules/db_http/README b/modules/db_http/README deleted file mode 100644 index aec198c06f5..00000000000 --- a/modules/db_http/README +++ /dev/null @@ -1,533 +0,0 @@ -DB_HTTP Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. SSL(int) - 1.3.2. cap_raw_query(int) - 1.3.3. cap_replace(int) - 1.3.4. cap_insert_update(int) - 1.3.5. cap_last_inserted_id(int) - 1.3.6. field_delimiter (str) - 1.3.7. row_delimiter (str) - 1.3.8. quote_delimiter (str) - 1.3.9. value_delimiter (str) - 1.3.10. timeout (int) - 1.3.11. disable_expect (int) - - 1.4. Exported Functions - 1.5. Server specifications - - 1.5.1. Queries - 1.5.2. Variables - 1.5.3. Query Types - 1.5.4. NULL values in queries - 1.5.5. Server Replies - 1.5.6. Reply Quoting - 1.5.7. Last inserted id - 1.5.8. Authentication and SSL - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting db_url for a module - 1.2. Set SSL parameter - 1.3. Set cap_raw_query parameter - 1.4. Set cap_replace parameter - 1.5. Set cap_insert_update parameter - 1.6. Set cap_last_inserted_id parameter - 1.7. Set field_delimiter parameter - 1.8. Set row_delimiter parameter - 1.9. Set quote_delimiter parameter - 1.10. Set value_delimiter parameter - 1.11. Set timeout parameter - 1.12. Set disable_expect parameter - 1.13. Example query. - 1.14. Example query with variables. - 1.15. More query examples. - 1.16. NULL query example. - 1.17. Example Reply. - 1.18. Quoting Example. - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides access to a database that is implemented - as a HTTP server. It may be used in special cases where - traversing firewalls is a problem, or where data encryption is - required. - - In order to use this module you must have a server that can - communicate via HTTP or HTTPS with this module that follows - exactly the format decribed in the specifications section. - - The module can provide SSL, authentication, and all the - functionalities of an opensips db as long as the server - supports them ( except result_fetch). - - There is a slight difference between the url of db_http and the - urls of the other db modules. The url doesn't have to contain - the database name. Instead, everything that is after the - address is considered to be a path to the db resource, it may - be missing. - - Even if using HTTPS the url must begin with "http://" , and the - SSL parameter for the module must be set to 1. - - Example 1.1. Setting db_url for a module -... -modparam("presence", "db_url","http://user:pass@localhost:13100") -or -modparam("presence", "db_url","http://user:pass@www.some.com/some/some") -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - This module does not depend on other modules. - -1.2.2. External Libraries or Applications - - * libcurl. - -1.3. Exported Parameters - -1.3.1. SSL(int) - - Whether or not to use SSL. - - If value is 1 the module will use https otherwise it will use - http. - - Default value is “ 0 ”. - - Example 1.2. Set SSL parameter -... -modparam("db_http", "SSL",1) -... - -1.3.2. cap_raw_query(int) - - Whether or not the server supports raw queries. - - Default value is “0”. - - Example 1.3. Set cap_raw_query parameter -... -modparam("db_http", "cap_raw_query", 1) -... - -1.3.3. cap_replace(int) - - Whether or not the server supports replace capabilities. - - Default value is “0”. - - Example 1.4. Set cap_replace parameter -... -modparam("db_http", "cap_replace", 1) -... - -1.3.4. cap_insert_update(int) - - Whether or not the server supports insert_update capabilities. - - Default value is “0”. - - Example 1.5. Set cap_insert_update parameter -... -modparam("db_http", "cap_insert_update", 1) -... - -1.3.5. cap_last_inserted_id(int) - - Whether or not the server supports last_inserted_id - capabilities. - - Default value is “0”. - - Example 1.6. Set cap_last_inserted_id parameter -... -modparam("db_http", "cap_last_inserted_id", 1) -... - -1.3.6. field_delimiter (str) - - Character to be used to delimit fields in the reply.Only one - char may be set. - - Default value is “;” - - Example 1.7. Set field_delimiter parameter -... -modparam("db_http", "field_delimiter",";") -... - -1.3.7. row_delimiter (str) - - Character to be used to delimit rows in the reply.Only one char - may be set. - - Default value is “\n” - - Example 1.8. Set row_delimiter parameter -... -modparam("db_http", "row_delimiter","\n") -... - -1.3.8. quote_delimiter (str) - - Character to be used to quote fields that require quoting in - the reply.Only one char may be set. - - Default value is “|” - - Example 1.9. Set quote_delimiter parameter -... -modparam("db_http", "quote_delimiter","|") -... - -1.3.9. value_delimiter (str) - - The delimiter used to separate multiple fields of a single - variable (see Section 1.5.2, “Variables”). Only one char may be - set. - - Default value is “,” - - Example 1.10. Set value_delimiter parameter -... -modparam("db_http", "value_delimiter",";") -... - -1.3.10. timeout (int) - - The maximum number of milliseconds that the HTTP ops are - allowed to last - - Default value is “30000 ( 30 seconds )” - - Example 1.11. Set timeout parameter -... -modparam("db_http", "timeout",5000) -... - -1.3.11. disable_expect (int) - - Disables automatic 'Expect: 100-continue' behavior in libcurl - for requests over 1024 bytes in size. This can help reduce - latency by saving a network round-trip for large records. For - more information on this behavior please seee rfc2616 section - 8.2.3. - - Default value is “0 (off)” - - Example 1.12. Set disable_expect parameter -... -modparam("db_http", "disable_expect",1) -... - -1.4. Exported Functions - - This module does not export any functions. - -1.5. Server specifications - -1.5.1. Queries - - The server must accept queries as HTTP queries. - - The queries are of 2 types : GET and POST.Both set variables - that must be interpreted by the server. All values are - URL-encoded. - - There are several types of queries and the server can tell them - apart by the query_type variable. Each type of query uses - specific variables simillar to those in the opensips db_api. - - Example 1.13. Example query. -... -GET /presentity/?c=username,domain,event,expires HTTP/1.1 -... - -1.5.2. Variables - - A description of all the variables. Each variable can have - either a single value or a comma-separated list of values. Each - variable has a special meaning and can be used only with - certain queries. - - The table on which operations will take place will be encoded - in the url as the end of the url ( www.some.com/users will - point to the users table). - * k= - Describes the keys (columns) that will be used for - comparison.Can have multiple values. - * op= - Describes the operators that will be used for - comparison.Can have multiple values. - * v= - Describes the values that columns will be compaired - against. Can have multiple values. - * c= - Describes the columns that will be selected from the - result.Can have multiple values. - * o= - The column that the result will be ordered by. Has a single - value. - * uk= - The keys(columns) that will be updated. Can have multiple - values. - * uv= - The new values that will be put in the columns. Can have - multiple values. - * q= - Describes a raw query. Will only be used if the server - supports raw queries. Has a single value. - * query_type= - Describes the type of the current query. Can have a single - value as described in the Query Types section.Has a single - value. Will be present in all queries except the "SELECT" - (normal query). - - Example 1.14. Example query with variables. -... -GET /presentity/?c=username,domain,event,expires HTTP/1.1 -GET /version/?k=table_name&v=xcap&c=table_version HTTP/1.1 -... -... -POST /active_watchers HTTP/1.1 - -k=id&v=100&query_type=insert -... - - -1.5.3. Query Types - - The types of the queries are described by the query_type - variable. The value of the variable will be set to the exact - name of the query. - - Queries for "SELECT" use GET and the rest use POST (insert, - update, delete, replace, insert_update). - * normal query - Uses the k, op, v, c and o variables. This will not set the - query_type variable and will use GET. - * delete - Uses the k, op and v variables. - * insert - Uses the k and v variables. - * update - Uses the k,op,v,uk and uv variables. - * replace - Uses the k and v variables. This is an optional type of - query. If the module is not configured to use it it will - not. - * insert_update - Uses the k and v variables. This is an optional type of - query. If the module is not configured to use it it will - not. - * custom - Uses the q variable. This is an optional type of query. If - the module is not configured to use it it will not. - - Example 1.15. More query examples. - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=100&query_type=delete -... - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=100&uk=id&uv=101&query_type=update -... - - -1.5.4. NULL values in queries - - NULL values in queries are represented as a string of length 1 - containing a single character with value '\0'. - - Example 1.16. NULL query example. - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=%00&query_type=delete -... - - - -1.5.5. Server Replies - - If the query is ok (even if the answer is empty) the server - must reply with a 200 OK HTTP reply with a body containing the - types and values of the columns. - - The server must reply with a delimiter separated list of values - and columns. - - Each element in the list must be seperated from the one before - it by a field delimiter that must be the same as the one set as - a parameter from the script for the module. The last element of - each line must not be followed by a field delimiter, but by a - row delimiter. - - The first line of the reply must contain a list of the types of - values of each column. The types can be any from the list: - integer, string, str, blob, date. - - Each following line contains the values of each row from the - result. - - If the query produced an error the server must reply with a - HTTP 500 reply, or with a corresponding error code (404, 401). - - Example 1.17. Example Reply. -... -int;string;blob -6;something=something;1000 -100;mine;10002030 -... - -1.5.6. Reply Quoting - - Because the values may contain delimiters inside, the server - must perform quoting when necessary (there is no problem if it - does it even when it is not necessary). - - A quote delimiter must be defined and must be the same as the - one set from the script ( by default it is "|" ). - - If a value contains a field , row or a quote delimiter it must - be placed under quotes. A quote delimiter inside a value must - be preceeded by another quote delimiter. - - Example 1.18. Quoting Example. -... -int;string;blob -6;|ana;maria|;1000 -100;mine;10002030 -3;mine;|some||more;| -... - -1.5.7. Last inserted id - - This is an optional feature and may be enabled if one wants to - use it. - - In order to use this feature the server must place the id of - the last insert in the 200 reply for each insert query. - -1.5.8. Authentication and SSL - - If the server supports authentication and SSL, the module can - be enabled to use SSL. Authentication will always be used if - needed. - - The module will try to use the most secure type of - authentication that is provided by the server from: Basic, - Digest,GSSNEGOTIATE and NTLM. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Andrei Dragus 23 2 2289 5 - 2. Razvan Crainea (@razvancrainea) 17 15 74 26 - 3. Liviu Chircu (@liviuchircu) 10 8 25 48 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 9 7 48 52 - 5. Vlad Paiu (@vladpaiu) 6 4 65 7 - 6. Vlad Patrascu (@rvlad-patrascu) 6 4 62 9 - 7. Ryan Bullock (@rrb3942) 5 3 42 1 - 8. Alexandra Titoc 5 3 25 17 - 9. Peter Lemenkov (@lemenkov) 4 2 6 6 - 10. Maksym Sobolyev (@sobomax) 4 2 5 5 - - All remaining contributors: Dusan Klinec (@ph4r05), Ovidiu Sas - (@ovidiusas), Anca Vamanu, Ezequiel Lovelle (@lovelle), Ken - Rice, Stephane Alnet. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2009 - Nov 2025 - 2. Peter Lemenkov (@lemenkov) Jun 2018 - Oct 2025 - 3. Ken Rice Sep 2025 - Sep 2025 - 4. Razvan Crainea (@razvancrainea) Oct 2011 - Sep 2024 - 5. Alexandra Titoc Sep 2024 - Sep 2024 - 6. Liviu Chircu (@liviuchircu) Mar 2014 - May 2023 - 7. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2021 - 9. Ovidiu Sas (@ovidiusas) Mar 2020 - Mar 2020 - 10. Ryan Bullock (@rrb3942) Jan 2019 - Feb 2019 - - All remaining contributors: Dusan Klinec (@ph4r05), Ezequiel - Lovelle (@lovelle), Stephane Alnet, Vlad Paiu (@vladpaiu), Anca - Vamanu, Andrei Dragus. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ryan Bullock (@rrb3942), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Stephane Alnet, Vlad Paiu (@vladpaiu), - Bogdan-Andrei Iancu (@bogdan-iancu), Andrei Dragus. - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/db_http/README.md b/modules/db_http/README.md new file mode 100644 index 00000000000..4531e271331 --- /dev/null +++ b/modules/db_http/README.md @@ -0,0 +1,500 @@ +--- +title: "DB_HTTP Module" +description: "This module provides access to a database that is implemented as a HTTP server. It may be used in special cases where traversing firewalls is a problem, or where data encryption is required." +--- + +## Admin Guide + + +### Overview + + +This module provides access to a database that is implemented +as a HTTP server. It may be used in special cases where traversing +firewalls is a problem, or where data encryption is required. + + +In order to use this module you must have a server that can communicate +via HTTP or HTTPS with this module that follows exactly the format +decribed in the specifications section. + + +The module can provide SSL, authentication, and all the functionalities +of an opensips db as long as the server supports them ( except result_fetch). + + +There is a slight difference between the url of db_http and +the urls of the other db modules. The url doesn't have to contain +the database name. Instead, everything that is after the +address is considered to be a path to the db resource, it may be +missing. + + +Even if using HTTPS the url must begin with "http://" , and the +SSL parameter for the module must be set to 1. + + +```opensips title="Setting db_url for a module" +... +modparam("presence", "db_url","http://user:pass@localhost:13100") +or +modparam("presence", "db_url","http://user:pass@www.some.com/some/some") +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +This module does not depend on other modules. + + +#### External Libraries or Applications + + +- *libcurl*. + + +### Exported Parameters + + +#### SSL(int) + + +Whether or not to use SSL. + + +If value is 1 the module will use https otherwise +it will use http. + + +*Default value is " 0 ".* + + +```opensips title="Set SSL parameter" +... +modparam("db_http", "SSL",1) +... +``` + + +#### cap_raw_query(int) + + +Whether or not the server supports raw queries. + + +*Default value is "0".* + + +```opensips title="Set cap_raw_query parameter" +... +modparam("db_http", "cap_raw_query", 1) +... +``` + + +#### cap_replace(int) + + +Whether or not the server supports replace capabilities. + + +*Default value is "0".* + + +```opensips title="Set cap_replace parameter" +... +modparam("db_http", "cap_replace", 1) +... +``` + + +#### cap_insert_update(int) + + +Whether or not the server supports insert_update capabilities. + + +*Default value is "0".* + + +```opensips title="Set cap_insert_update parameter" +... +modparam("db_http", "cap_insert_update", 1) +... +``` + + +#### cap_last_inserted_id(int) + + +Whether or not the server supports last_inserted_id capabilities. + + +*Default value is "0".* + + +```opensips title="Set cap_last_inserted_id parameter" +... +modparam("db_http", "cap_last_inserted_id", 1) +... +``` + + +#### field_delimiter (str) + + +Character to be used to delimit fields in the reply.Only +one char may be set. + + +*Default value is ";"* + + +```opensips title="Set field_delimiter parameter" +... +modparam("db_http", "field_delimiter",";") +... +``` + + +#### row_delimiter (str) + + +Character to be used to delimit rows in the reply.Only +one char may be set. + + +*Default value is "\n"* + + +```opensips title="Set row_delimiter parameter" +... +modparam("db_http", "row_delimiter","\n") +... +``` + + +#### quote_delimiter (str) + + +Character to be used to quote fields that require quoting +in the reply.Only one char may be set. + + +*Default value is "|"* + + +```opensips title="Set quote_delimiter parameter" +... +modparam("db_http", "quote_delimiter","|") +... +``` + + +#### value_delimiter (str) + + +The delimiter used to separate multiple fields of a single +variable (see [http variables](#variables)). +Only one char may be set. + + +*Default value is ","* + + +```opensips title="Set value_delimiter parameter" +... +modparam("db_http", "value_delimiter",";") +... +``` + + +#### timeout (int) + + +The maximum number of milliseconds that the HTTP ops are allowed to last + + +*Default value is "30000 ( 30 seconds )"* + + +```opensips title="Set timeout parameter" +... +modparam("db_http", "timeout",5000) +... +``` + + +#### disable_expect (int) + + +Disables automatic 'Expect: 100-continue' behavior in libcurl for requests over 1024 bytes in size. +This can help reduce latency by saving a network round-trip for large records. +For more information on this behavior please seee rfc2616 section 8.2.3. + + +*Default value is "0 (off)"* + + +```opensips title="Set disable_expect parameter" +... +modparam("db_http", "disable_expect",1) +... +``` + + +### Exported Functions + + +### Server specifications + + +#### Queries + + +The server must accept queries as HTTP queries. + + +The queries are of 2 types : GET and POST.Both +set variables that must be interpreted by the server. +All values are URL-encoded. + + +There are several types of queries and the server can tell +them apart by the query_type variable. Each type of query uses +specific variables simillar to those in the opensips db_api. + + +```c title="Example query." +... +GET /presentity/?c=username,domain,event,expires HTTP/1.1 +... +``` + + +#### Variables + + +A description of all the variables. Each variable can have +either a single value or a comma-separated list of values. Each +variable has a special meaning and can be used only with +certain queries. + + +The table on which operations will take place will be encoded +in the url as the end of the url ( www.some.com/users will point +to the users table). + + +- k= +Describes the keys (columns) that will +be used for comparison.Can have multiple values. +- op= +Describes the operators that will +be used for comparison.Can have multiple values. +- v= +Describes the values that columns will be +compaired against. Can have multiple values. +- c= +Describes the columns that will be selected +from the result.Can have multiple values. +- o= +The column that the result will be ordered by. +Has a single value. +- uk= +The keys(columns) that will be updated. +Can have multiple values. +- uv= +The new values that will be put in the columns. +Can have multiple values. +- q= +Describes a raw query. Will only be used if +the server supports raw queries. Has a single +value. +- query_type= +Describes the type of the current query. +Can have a single value as described in the +Query Types section.Has a single value. +Will be present in all queries except the +"SELECT" (normal query). + + +```c title="Example query with variables." +... +GET /presentity/?c=username,domain,event,expires HTTP/1.1 +GET /version/?k=table_name&v=xcap&c=table_version HTTP/1.1 +... +... +POST /active_watchers HTTP/1.1 + +k=id&v=100&query_type=insert +... +``` + + +#### Query Types + + +The types of the queries are described by the +query_type variable. The value of the variable +will be set to the exact name of the query. + + +Queries for "SELECT" use GET and the rest use POST +(insert, update, delete, replace, insert_update). + + +- normal query +Uses the k, op, v, c and o variables. +This will not set the query_type variable and +will use GET. +- delete +Uses the k, op and v variables. +- insert +Uses the k and v variables. +- update +Uses the k,op,v,uk and uv variables. +- replace +Uses the k and v variables. This is an optional +type of query. If the module is not configured to use it +it will not. +- insert_update +Uses the k and v variables. This is an optional +type of query. If the module is not configured to use it +it will not. +- custom +Uses the q variable. This is an optional +type of query. If the module is not configured to use it +it will not. + + +```c title="More query examples." +... +POST /active_watchers HTTP/1.1 + +k=id&op=%3D&v=100&query_type=delete +... + +... +POST /active_watchers HTTP/1.1 + +k=id&op=%3D&v=100&uk=id&uv=101&query_type=update +... +``` + + +#### NULL values in queries + + +NULL values in queries are represented as a string of length 1 +containing a single character with value '\0'. + + +```c title="NULL query example." +... +POST /active_watchers HTTP/1.1 + +k=id&op=%3D&v=%00&query_type=delete +... +``` + + +#### Server Replies + + +If the query is ok (even if the answer is empty) +the server must reply with a 200 OK HTTP reply with +a body containing the types and values of the columns. + + +The server must reply with a delimiter separated list of +values and columns. + + +Each element in the list must be seperated from the +one before it by a field delimiter that must be the same +as the one set as a parameter from the script for the module. +The last element of each line must not be followed by +a field delimiter, but by a row delimiter. + + +The first line of the reply must contain a list of the types +of values of each column. The types can be any from the list: +integer, string, str, blob, date. + + +Each following line contains the values of each row from the result. + + +If the query produced an error the server must reply with a +HTTP 500 reply, or with a corresponding error code (404, 401). + + +``` title="Example Reply." +... +int;string;blob +6;something=something;1000 +100;mine;10002030 +... +``` + + +#### Reply Quoting + + +Because the values may contain delimiters inside, +the server must perform quoting when necessary (there is no +problem if it does it even when it is not necessary). + + +A quote delimiter must be defined and must be the same as +the one set from the script ( by default it is "|" ). + + +If a value contains a field , row or a quote delimiter +it must be placed under quotes. A quote delimiter inside a value +must be preceeded by another quote delimiter. + + +``` title="Quoting Example." +... +int;string;blob +6;|ana;maria|;1000 +100;mine;10002030 +3;mine;|some||more;| +... +``` + + +#### Last inserted id + + +This is an optional feature and may be enabled if one wants +to use it. + + +In order to use this feature the server must place the id +of the last insert in the 200 reply for each insert query. + + +#### Authentication and SSL + + +If the server supports authentication and SSL, the module +can be enabled to use SSL. Authentication will always be used +if needed. + + +The module will try to use the most secure type of +authentication that is provided by the server from: +Basic, Digest, GSSNEGOTIATE and NTLM. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_http/doc/contributors.xml b/modules/db_http/doc/contributors.xml deleted file mode 100644 index a1d8dfdbe6f..00000000000 --- a/modules/db_http/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Andrei Dragus - 23 - 2 - 2289 - 5 - - - 2. - Razvan Crainea (@razvancrainea) - 17 - 15 - 74 - 26 - - - 3. - Liviu Chircu (@liviuchircu) - 10 - 8 - 25 - 48 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 7 - 48 - 52 - - - 5. - Vlad Paiu (@vladpaiu) - 6 - 4 - 65 - 7 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 62 - 9 - - - 7. - Ryan Bullock (@rrb3942) - 5 - 3 - 42 - 1 - - - 8. - Alexandra Titoc - 5 - 3 - 25 - 17 - - - 9. - Peter Lemenkov (@lemenkov) - 4 - 2 - 6 - 6 - - - 10. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - -
-All remaining contributors: Dusan Klinec (@ph4r05), Ovidiu Sas (@ovidiusas), Anca Vamanu, Ezequiel Lovelle (@lovelle), Ken Rice, Stephane Alnet. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2009 - Nov 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jun 2018 - Oct 2025 - - - 3. - Ken Rice - Sep 2025 - Sep 2025 - - - 4. - Razvan Crainea (@razvancrainea) - Oct 2011 - Sep 2024 - - - 5. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2023 - - - 7. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2021 - - - 9. - Ovidiu Sas (@ovidiusas) - Mar 2020 - Mar 2020 - - - 10. - Ryan Bullock (@rrb3942) - Jan 2019 - Feb 2019 - - - -
-All remaining contributors: Dusan Klinec (@ph4r05), Ezequiel Lovelle (@lovelle), Stephane Alnet, Vlad Paiu (@vladpaiu), Anca Vamanu, Andrei Dragus. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ryan Bullock (@rrb3942), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Stephane Alnet, Vlad Paiu (@vladpaiu), Bogdan-Andrei Iancu (@bogdan-iancu), Andrei Dragus. -
- -
diff --git a/modules/db_http/doc/db_http.xml b/modules/db_http/doc/db_http.xml deleted file mode 100644 index 4e23d23afa5..00000000000 --- a/modules/db_http/doc/db_http.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - DB_HTTP Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - - - - diff --git a/modules/db_http/doc/db_http_admin.xml b/modules/db_http/doc/db_http_admin.xml deleted file mode 100644 index 2d9e2856c08..00000000000 --- a/modules/db_http/doc/db_http_admin.xml +++ /dev/null @@ -1,715 +0,0 @@ - - - - &adminguide; - -
- Overview - This module provides access to a database that is implemented - as a HTTP server. It may be used in special cases where traversing - firewalls is a problem, or where data encryption is required. - - - In order to use this module you must have a server that can communicate - via HTTP or HTTPS with this module that follows exactly the format - decribed in the specifications section. - - - The module can provide SSL, authentication, and all the functionalities - of an opensips db as long as the server supports them ( except result_fetch). - - - There is a slight difference between the url of db_http and - the urls of the other db modules. The url doesn't have to contain - the database name. Instead, everything that is after the - address is considered to be a path to the db resource, it may be - missing. - - - Even if using HTTPS the url must begin with "http://" , and the - SSL parameter for the module must be set to 1. - - - - Setting db_url for a module - -... -modparam("presence", "db_url","http://user:pass@localhost:13100") -or -modparam("presence", "db_url","http://user:pass@www.some.com/some/some") -... - - - -
- -
- Dependencies -
- &osips; Modules - - This module does not depend on other modules. - -
- -
- External Libraries or Applications - - - - libcurl. - - - - -
-
- -
- Exported Parameters -
- <varname>SSL</varname>(int) - - Whether or not to use SSL. - - If value is 1 the module will use https otherwise - it will use http. - - - Default value is 0 . - - - - Set <varname>SSL</varname> parameter - -... -modparam("db_http", "SSL",1) -... - - -
-
- <varname>cap_raw_query</varname>(int) - - Whether or not the server supports raw queries. - - - Default value is 0. - - - - Set <varname>cap_raw_query</varname> parameter - -... -modparam("db_http", "cap_raw_query", 1) -... - - -
-
- <varname>cap_replace</varname>(int) - - Whether or not the server supports replace capabilities. - - - Default value is 0. - - - - Set <varname>cap_replace</varname> parameter - -... -modparam("db_http", "cap_replace", 1) -... - - -
-
- <varname>cap_insert_update</varname>(int) - - Whether or not the server supports insert_update capabilities. - - - Default value is 0. - - - - Set <varname>cap_insert_update</varname> parameter - -... -modparam("db_http", "cap_insert_update", 1) -... - - -
-
- <varname>cap_last_inserted_id</varname>(int) - - Whether or not the server supports last_inserted_id capabilities. - - - Default value is 0. - - - - Set <varname>cap_last_inserted_id</varname> parameter - -... -modparam("db_http", "cap_last_inserted_id", 1) -... - - -
- -
- <varname>field_delimiter</varname> (str) - - Character to be used to delimit fields in the reply.Only - one char may be set. - - - Default value is ; - - - - Set <varname>field_delimiter</varname> parameter - -... -modparam("db_http", "field_delimiter",";") -... - - -
- -
- <varname>row_delimiter</varname> (str) - - Character to be used to delimit rows in the reply.Only - one char may be set. - - - Default value is \n - - - - Set <varname>row_delimiter</varname> parameter - -... -modparam("db_http", "row_delimiter","\n") -... - - -
- -
- <varname>quote_delimiter</varname> (str) - - Character to be used to quote fields that require quoting - in the reply.Only one char may be set. - - - Default value is | - - - - Set <varname>quote_delimiter</varname> parameter - -... -modparam("db_http", "quote_delimiter","|") -... - - -
- -
- <varname>value_delimiter</varname> (str) - - The delimiter used to separate multiple fields of a single - variable (see ). - Only one char may be set. - - - Default value is , - - - - Set <varname>value_delimiter</varname> parameter - -... -modparam("db_http", "value_delimiter",";") -... - - -
- -
- <varname>timeout</varname> (int) - - The maximum number of milliseconds that the HTTP ops are allowed to last - - - Default value is 30000 ( 30 seconds ) - - - - Set <varname>timeout</varname> parameter - -... -modparam("db_http", "timeout",5000) -... - - -
- -
- <varname>disable_expect</varname> (int) - - Disables automatic 'Expect: 100-continue' behavior in libcurl for requests over 1024 bytes in size. - This can help reduce latency by saving a network round-trip for large records. - For more information on this behavior please seee rfc2616 section 8.2.3. - - - Default value is 0 (off) - - - - Set <varname>disable_expect</varname> parameter - -... -modparam("db_http", "disable_expect",1) -... - - -
- - -
- -
- Exported Functions - - This module does not export any functions. - -
- - -
- Server specifications - -
- Queries - - The server must accept queries as HTTP queries. - - - The queries are of 2 types : GET and POST.Both - set variables that must be interpreted by the server. - All values are URL-encoded. - - - There are several types of queries and the server can tell - them apart by the query_type variable. Each type of query uses - specific variables simillar to those in the opensips db_api. - - - Example query. - -... -GET /presentity/?c=username,domain,event,expires HTTP/1.1 -... - - -
- - -
- Variables - - A description of all the variables. Each variable can have - either a single value or a comma-separated list of values. Each - variable has a special meaning and can be used only with - certain queries. - - - - The table on which operations will take place will be encoded - in the url as the end of the url ( www.some.com/users will point - to the users table). - - - - - - k= - - - - Describes the keys (columns) that will - be used for comparison.Can have multiple values. - - - - - - - op= - - - - Describes the operators that will - be used for comparison.Can have multiple values. - - - - - - - v= - - - - Describes the values that columns will be - compaired against. Can have multiple values. - - - - - - - c= - - - - Describes the columns that will be selected - from the result.Can have multiple values. - - - - - - - o= - - - - The column that the result will be ordered by. - Has a single value. - - - - - - - uk= - - - - The keys(columns) that will be updated. - Can have multiple values. - - - - - - - uv= - - - - The new values that will be put in the columns. - Can have multiple values. - - - - - - - q= - - - - Describes a raw query. Will only be used if - the server supports raw queries. Has a single - value. - - - - - - - query_type= - - - - Describes the type of the current query. - Can have a single value as described in the - Query Types section.Has a single value. - Will be present in all queries except the - "SELECT" (normal query). - - - - - - - - - - Example query with variables. - -... -GET /presentity/?c=username,domain,event,expires HTTP/1.1 -GET /version/?k=table_name&v=xcap&c=table_version HTTP/1.1 -... -... -POST /active_watchers HTTP/1.1 - -k=id&v=100&query_type=insert -... - - - -
- - -
- Query Types - - The types of the queries are described by the - query_type variable. The value of the variable - will be set to the exact name of the query. - - - Queries for "SELECT" use GET and the rest use POST - (insert, update, delete, replace, insert_update). - - - - - - normal query - - - Uses the k, op, v, c and o variables. - This will not set the query_type variable and - will use GET. - - - - - - delete - - - Uses the k, op and v variables. - - - - - - insert - - - Uses the k and v variables. - - - - - - - update - - - Uses the k,op,v,uk and uv variables. - - - - - - replace - - - Uses the k and v variables. This is an optional - type of query. If the module is not configured to use it - it will not. - - - - - - insert_update - - - Uses the k and v variables. This is an optional - type of query. If the module is not configured to use it - it will not. - - - - - - custom - - - Uses the q variable. This is an optional - type of query. If the module is not configured to use it - it will not. - - - - - - - - - More query examples. - - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=100&query_type=delete -... - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=100&uk=id&uv=101&query_type=update -... - - - -
- -
- NULL values in queries - - NULL values in queries are represented as a string of length 1 - containing a single character with value '\0'. - - - NULL query example. - - -... -POST /active_watchers HTTP/1.1 - -k=id&op=%3D&v=%00&query_type=delete -... - - - - - -
- - -
- Server Replies - - If the query is ok (even if the answer is empty) - the server must reply with a 200 OK HTTP reply with - a body containing the types and values of the columns. - - - The server must reply with a delimiter separated list of - values and columns. - - - Each element in the list must be seperated from the - one before it by a field delimiter that must be the same - as the one set as a parameter from the script for the module. - The last element of each line must not be followed by - a field delimiter, but by a row delimiter. - - - - The first line of the reply must contain a list of the types - of values of each column. The types can be any from the list: - integer, string, str, blob, date. - - - Each following line contains the values of each row from the result. - - - - If the query produced an error the server must reply with a - HTTP 500 reply, or with a corresponding error code (404, 401). - - - Example Reply. - -... -int;string;blob -6;something=something;1000 -100;mine;10002030 -... - - -
- - -
- Reply Quoting - - Because the values may contain delimiters inside, - the server must perform quoting when necessary (there is no - problem if it does it even when it is not necessary). - - - A quote delimiter must be defined and must be the same as - the one set from the script ( by default it is "|" ). - - - - If a value contains a field , row or a quote delimiter - it must be placed under quotes. A quote delimiter inside a value - must be preceeded by another quote delimiter. - - - - Quoting Example. - -... -int;string;blob -6;|ana;maria|;1000 -100;mine;10002030 -3;mine;|some||more;| -... - - -
- -
- Last inserted id - - This is an optional feature and may be enabled if one wants - to use it. - - - In order to use this feature the server must place the id - of the last insert in the 200 reply for each insert query. - - -
- -
- Authentication and SSL - - If the server supports authentication and SSL, the module - can be enabled to use SSL. Authentication will always be used - if needed. - - - The module will try to use the most secure type of - authentication that is provided by the server from: - Basic, Digest,GSSNEGOTIATE and NTLM. - - -
- - -
- -
- diff --git a/modules/db_mysql/README b/modules/db_mysql/README deleted file mode 100644 index fe48f16d653..00000000000 --- a/modules/db_mysql/README +++ /dev/null @@ -1,309 +0,0 @@ -mysql Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. exec_query_threshold (integer) - 1.3.2. timeout_interval (integer) - 1.3.3. max_db_queries (integer) - 1.3.4. max_db_retries (integer) - 1.3.5. ps_max_col_size (integer) - 1.3.6. use_tls (integer) - - 1.4. Exported Functions - 1.5. Installation - 1.6. Exported Events - - 1.6.1. E_MYSQL_CONNECTION - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set exec_query_threshold parameter - 1.2. Set timeout_interval parameter - 1.3. Set max_db_queries parameter - 1.4. Set max_db_retries parameter - 1.5. Set ps_max_col_size parameter - 1.6. Set the use_tls parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides MySQL connectivity for - OpenSIPS. It implements the DB API defined in OpenSIPS. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * If a use_tls is defined, the tls_mgm module will need to be - loaded as well. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libmysqlclient-dev - the development libraries of - mysql-client. - -1.3. Exported Parameters - -1.3.1. exec_query_threshold (integer) - - If queries take longer than 'exec_query_threshold' - microseconds, warning messages will be written to logging - facility. - - Default value is 0 - disabled. - - Example 1.1. Set exec_query_threshold parameter -... -modparam("db_mysql", "exec_query_threshold", 60000) -... - -1.3.2. timeout_interval (integer) - - Time interval after which a connection attempt (read or write - request) is aborted. The value counts three times, as several - retries are done from the driver before it gives up. - - The read timeout parameter is ignored on driver versions prior - to “5.1.12”, “5.0.25” and “4.1.22”. The write timeout parameter - is ignored on version prior to “5.1.12” and “5.0.25”, the “4.1” - release don't support it at all. - - Default value is 2 (6 sec). - - Example 1.2. Set timeout_interval parameter -... -modparam("db_mysql", "timeout_interval", 2) -... - -1.3.3. max_db_queries (integer) - - The maximum number of retries to execute a failed query due to - connections problems. If this parameter is set improperly, it - is set to default value. - - Default value is 2. - - Example 1.3. Set max_db_queries parameter -... -modparam("db_mysql", "max_db_queries", 2) -... - -1.3.4. max_db_retries (integer) - - The maximum number of database connection retries. If this - parameter is set improperly, it is set to default value. - - Default value is 3. - - Example 1.4. Set max_db_retries parameter -... -modparam("db_mysql", "max_db_retries", 2) -... - -1.3.5. ps_max_col_size (integer) - - The maximum size of a column's data, when fetched using - prepared statements. Particularly relevant for variable-length - data, such as CHAR, BLOB, etc. - - NOTE: Should a column's data exceed this limit, the value will - be silently truncated to fit the buffer, without reporting any - errors! - - Default value is 1024 (bytes). - - Example 1.5. Set ps_max_col_size parameter -... -modparam("db_mysql", "ps_max_col_size", 4096) -... - -1.3.6. use_tls (integer) - - Setting this parameter will allow you to use TLS for MySQL - connections. In order to enable TLS for a specific connection, - you can use the "tls_domain=dom_name" URL parameter in the - db_url of the respective OpenSIPS module. This should be placed - at the end of the URL after the '?' character. Additionally, - the query string may include the "tls_opts= - PKEY,CERT,CA,CA_DIR,CIPHERS" CSV parameter, in order to - control/limit the amount of TLS options passed to the TLS - library. - - When using this parameter, you must also ensure that tls_mgm is - loaded and properly configured. Refer to the the module for - additional info regarding TLS client domains. - - Note that if you want to use this feature, the TLS domain must - be provisioned in the configuration file, NOT in the database. - In case you are loading TLS certificates from the database, you - must at least define one domain in the configuration script, to - use for the initial connection to the DB. - - Also, you can NOT enable TLS for the connection to the database - of the tls_mgm module itself. - - Default value is 0 (not enabled) - - Example 1.6. Set the use_tls parameter -... -modparam("tls_mgm", "client_domain", "dom1") -modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pe -m") -modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips. -key") -modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") -... -modparam("db_mysql", "use_tls", 1) -... -modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_d -omain=dom1") -... -modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_d -omain=dom1&tls_opts=PKEY,CERT,CA,CA_DIR,CIPHERS") -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Installation - - Because it dependes on an external library, the mysql module is - not compiled and installed by default. You can use one of the - next options. - * - edit the "Makefile" and remove "db_mysql" from - "excluded_modules" list. Then follow the standard procedure - to install OpenSIPS: "make all; make install". - * - from command line use: 'make all - include_modules="db_mysql"; make install - include_modules="db_mysql"'. - -1.6. Exported Events - -1.6.1. E_MYSQL_CONNECTION - - This event is raised when a MySQL connection is lost or - recovered. - - Parameters: - * url - the URL of the connection as specified by the db_url - parameter. - * status - connected if the connection recovered, or - disconnected if the connection was lost. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jan Janak (@janakj) 151 53 5336 3190 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 101 73 1576 795 - 3. Henning Westerholt (@henningw) 57 30 693 1239 - 4. Liviu Chircu (@liviuchircu) 44 35 582 207 - 5. Razvan Crainea (@razvancrainea) 29 24 246 66 - 6. Daniel-Constantin Mierla (@miconda) 28 20 571 154 - 7. Andrei Pelinescu-Onciul 16 14 52 49 - 8. Vlad Paiu (@vladpaiu) 15 12 185 25 - 9. Vlad Patrascu (@rvlad-patrascu) 12 8 179 78 - 10. Jiri Kuthan (@jiriatipteldotorg) 11 6 393 2 - - All remaining contributors: Nils Ohlmeier, Norman Brandinger - (@NormB), Maksym Sobolyev (@sobomax), Peter Lemenkov - (@lemenkov), Eseanu Marius Cristian (@eseanucristian), Dan - Pascu (@danpascu), Walter Doekes (@wdoekes), Ionut Ionita - (@ionutrazvanionita), Ovidiu Sas (@ovidiusas), Konstantin - Bokarius, Andreas Heise, Razvan Pistolea, Ken Rice, Saúl Ibarra - Corretgé (@saghul), Sergio Gutierrez, Edson Gellert Schubert, - Augusto Caringi. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2002 - Nov 2025 - 2. Ken Rice Sep 2025 - Sep 2025 - 3. Norman Brandinger (@NormB) Aug 2006 - Jan 2025 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Dec 2024 - 5. Razvan Crainea (@razvancrainea) Oct 2011 - Nov 2024 - 6. Vlad Paiu (@vladpaiu) Feb 2011 - Jul 2023 - 7. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 8. Vlad Patrascu (@rvlad-patrascu) Apr 2017 - May 2021 - 9. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 10. Peter Lemenkov (@lemenkov) Nov 2017 - Jun 2018 - - All remaining contributors: Augusto Caringi, Ovidiu Sas - (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Eseanu Marius - Cristian (@eseanucristian), Saúl Ibarra Corretgé (@saghul), - Razvan Pistolea, Sergio Gutierrez, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Andreas Heise, Jan Janak - (@janakj), Andrei Pelinescu-Onciul, Dan Pascu (@danpascu), Jiri - Kuthan (@jiriatipteldotorg), Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter - Lemenkov (@lemenkov), Eseanu Marius Cristian (@eseanucristian), - Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Jan Janak - (@janakj). - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/db_mysql/README.md b/modules/db_mysql/README.md new file mode 100644 index 00000000000..948b7c95314 --- /dev/null +++ b/modules/db_mysql/README.md @@ -0,0 +1,226 @@ +--- +title: "mysql Module" +description: "This is a module which provides MySQL connectivity for OpenSIPS. It implements the DB API defined in OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides MySQL connectivity for OpenSIPS. +It implements the DB API defined in OpenSIPS. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *If a [use tls](#param_use_tls) is defined, the **tls_mgm** module will need to be loaded as well*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libmysqlclient-dev* - the development libraries of mysql-client. + + +### Exported Parameters + + +#### exec_query_threshold (integer) + + +If queries take longer than 'exec_query_threshold' microseconds, warning +messages will be written to logging facility. + + +*Default value is 0 - disabled.* + + +```opensips title="Set exec_query_threshold parameter" +... +modparam("db_mysql", "exec_query_threshold", 60000) +... +``` + + +#### timeout_interval (integer) + + +Time interval after which a connection attempt (read or write request) +is aborted. The value counts three times, as several retries are done +from the driver before it gives up. + + +The read timeout parameter is ignored on driver versions prior to +"5.1.12", "5.0.25" and "4.1.22". +The write timeout parameter is ignored on version prior to "5.1.12" +and "5.0.25", the "4.1" release don't support it at all. + + +*Default value is 2 (6 sec).* + + +```opensips title="Set timeout_interval parameter" +... +modparam("db_mysql", "timeout_interval", 2) +... +``` + + +#### max_db_queries (integer) + + +The maximum number of retries to execute a failed query due to connections problems. +If this parameter is set improperly, it is set to default value. + + +*Default value is 2.* + + +```opensips title="Set max_db_queries parameter" +... +modparam("db_mysql", "max_db_queries", 2) +... +``` + + +#### max_db_retries (integer) + + +The maximum number of database connection retries. If this parameter +is set improperly, it is set to default value. + + +*Default value is 3.* + + +```opensips title="Set max_db_retries parameter" +... +modparam("db_mysql", "max_db_retries", 2) +... +``` + + +#### ps_max_col_size (integer) + + +The maximum size of a column's data, when fetched using prepared +statements. Particularly relevant for variable-length data, such as +CHAR, BLOB, etc. + + +> [!NOTE] +> Should a column's data exceed this limit, the value will be +> silently truncated to fit the buffer, without reporting any errors! + + +*Default value is *1024 (bytes)*.* + + +```opensips title="Set ps_max_col_size parameter" +... +modparam("db_mysql", "ps_max_col_size", 4096) +... +``` + + +#### use_tls (integer) + + +Setting this parameter will allow you to use TLS for MySQL connections. +In order to enable TLS for a specific connection, you can use the +"**tls_domain=**dom_name" URL parameter in the db_url of +the respective OpenSIPS module. This should be placed at the end of the +URL after the **'?'** character. Additionally, +the query string may include the "**tls_opts=** +PKEY,CERT,CA,CA_DIR,CIPHERS" CSV parameter, in order to control/limit the +amount of TLS options passed to the TLS library. + + +When using this parameter, you must also ensure that +*tls_mgm* is loaded and properly configured. Refer to +the the module for additional info regarding TLS client domains. + + +Note that if you want to use this feature, the TLS domain must be +provisioned in the configuration file, *NOT* in +the database. In case you are loading TLS certificates from the +database, you must at least define one domain in the +configuration script, to use for the initial connection to the DB. + + +Also, you can *NOT* enable TLS for the connection +to the database of the *tls_mgm* module itself. + + +*Default value is **0** (not enabled)* + + +```opensips title="Set the use_tls parameter" +... +modparam("tls_mgm", "client_domain", "dom1") +modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pem") +modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips.key") +modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") +... +modparam("db_mysql", "use_tls", 1) +... +modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_domain=dom1") +... +modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_domain=dom1&tls_opts=PKEY,CERT,CA,CA_DIR,CIPHERS") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Installation + + +Because it dependes on an external library, the mysql module is not +compiled and installed by default. You can use one of the next options. + + +- edit the "Makefile" and remove "db_mysql" from "excluded_modules" +list. Then follow the standard procedure to install OpenSIPS: +"make all; make install". +- from command line use: 'make all include_modules="db_mysql"; +make install include_modules="db_mysql"'. + + +### Exported Events + + +#### E_MYSQL_CONNECTION + + +This event is raised when a MySQL connection is lost or recovered. + + +Parameters: + + +- *url* - the URL of the connection as specified by the *db_url* parameter. +- *status* - *connected* if the connection recovered, or +*disconnected* if the connection was lost. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_mysql/dbase.c b/modules/db_mysql/dbase.c index a124876b9a7..2c1085e55f5 100644 --- a/modules/db_mysql/dbase.c +++ b/modules/db_mysql/dbase.c @@ -164,6 +164,15 @@ static inline int wrapper_single_mysql_stmt_execute(const db_con_t *conn, * while MariaDB has it as ER_REFERENCED_TRG_DOES_NOT_EXIST */ case 4031: + /* The server-side prepared-statement cache no longer knows + * about our stmt handle - e.g. after a managed-DB transparent + * failover or a zero-downtime minor version upgrade (AWS Aurora), + * where the backing instance is replaced while the client TCP + * connection is preserved. libmysqlclient auto-reprepare (which + * handles the related ER_NEED_REPREPARE case) does not kick in + * here because the server has no record of the handle at all. + * Fall back to the existing reconnect + re-prepare path. */ + case ER_UNKNOWN_STMT_HANDLER: return -1; /* reconnection error -> <0 */ default: LM_CRIT("driver error (%i): %s\n", error, mysql_stmt_error(stmt)); diff --git a/modules/db_mysql/doc/contributors.xml b/modules/db_mysql/doc/contributors.xml deleted file mode 100644 index 8649bc2c24f..00000000000 --- a/modules/db_mysql/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jan Janak (@janakj) - 151 - 53 - 5336 - 3190 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 101 - 73 - 1576 - 795 - - - 3. - Henning Westerholt (@henningw) - 57 - 30 - 693 - 1239 - - - 4. - Liviu Chircu (@liviuchircu) - 44 - 35 - 582 - 207 - - - 5. - Razvan Crainea (@razvancrainea) - 29 - 24 - 246 - 66 - - - 6. - Daniel-Constantin Mierla (@miconda) - 28 - 20 - 571 - 154 - - - 7. - Andrei Pelinescu-Onciul - 16 - 14 - 52 - 49 - - - 8. - Vlad Paiu (@vladpaiu) - 15 - 12 - 185 - 25 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 12 - 8 - 179 - 78 - - - 10. - Jiri Kuthan (@jiriatipteldotorg) - 11 - 6 - 393 - 2 - - - -
-All remaining contributors: Nils Ohlmeier, Norman Brandinger (@NormB), Maksym Sobolyev (@sobomax), Peter Lemenkov (@lemenkov), Eseanu Marius Cristian (@eseanucristian), Dan Pascu (@danpascu), Walter Doekes (@wdoekes), Ionut Ionita (@ionutrazvanionita), Ovidiu Sas (@ovidiusas), Konstantin Bokarius, Andreas Heise, Razvan Pistolea, Ken Rice, Saúl Ibarra Corretgé (@saghul), Sergio Gutierrez, Edson Gellert Schubert, Augusto Caringi. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2002 - Nov 2025 - - - 2. - Ken Rice - Sep 2025 - Sep 2025 - - - 3. - Norman Brandinger (@NormB) - Aug 2006 - Jan 2025 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Dec 2024 - - - 5. - Razvan Crainea (@razvancrainea) - Oct 2011 - Nov 2024 - - - 6. - Vlad Paiu (@vladpaiu) - Feb 2011 - Jul 2023 - - - 7. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - Apr 2017 - May 2021 - - - 9. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 10. - Peter Lemenkov (@lemenkov) - Nov 2017 - Jun 2018 - - - -
-All remaining contributors: Augusto Caringi, Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Eseanu Marius Cristian (@eseanucristian), Saúl Ibarra Corretgé (@saghul), Razvan Pistolea, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Andreas Heise, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Dan Pascu (@danpascu), Jiri Kuthan (@jiriatipteldotorg), Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Eseanu Marius Cristian (@eseanucristian), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jan Janak (@janakj). -
- -
diff --git a/modules/db_mysql/doc/db_mysql.xml b/modules/db_mysql/doc/db_mysql.xml deleted file mode 100644 index 9a8c7bcc7e7..00000000000 --- a/modules/db_mysql/doc/db_mysql.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mysql Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - diff --git a/modules/db_mysql/doc/db_mysql_admin.xml b/modules/db_mysql/doc/db_mysql_admin.xml deleted file mode 100644 index 0ddbc6a101a..00000000000 --- a/modules/db_mysql/doc/db_mysql_admin.xml +++ /dev/null @@ -1,266 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module which provides MySQL connectivity for OpenSIPS. - It implements the DB API defined in OpenSIPS. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - If a is defined, the tls_mgm module will need to be loaded as well. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libmysqlclient-dev - the development libraries of mysql-client. - - - - -
-
-
- Exported Parameters -
- <varname>exec_query_threshold</varname> (integer) - - If queries take longer than 'exec_query_threshold' microseconds, warning - messages will be written to logging facility. - - - - Default value is 0 - disabled. - - - - Set <varname>exec_query_threshold</varname> parameter - -... -modparam("db_mysql", "exec_query_threshold", 60000) -... - - -
-
- <varname>timeout_interval</varname> (integer) - - Time interval after which a connection attempt (read or write request) - is aborted. The value counts three times, as several retries are done - from the driver before it gives up. - - - The read timeout parameter is ignored on driver versions prior to - 5.1.12, 5.0.25 and 4.1.22. - The write timeout parameter is ignored on version prior to 5.1.12 - and 5.0.25, the 4.1 release don't support it at all. - - - - Default value is 2 (6 sec). - - - - Set <varname>timeout_interval</varname> parameter - -... -modparam("db_mysql", "timeout_interval", 2) -... - - -
-
- <varname>max_db_queries</varname> (integer) - - The maximum number of retries to execute a failed query due to connections problems. - If this parameter is set improperly, it is set to default value. - - - - Default value is 2. - - - - Set <varname>max_db_queries</varname> parameter - -... -modparam("db_mysql", "max_db_queries", 2) -... - - -
- -
- <varname>max_db_retries</varname> (integer) - - The maximum number of database connection retries. If this parameter - is set improperly, it is set to default value. - - - - Default value is 3. - - - - Set <varname>max_db_retries</varname> parameter - -... -modparam("db_mysql", "max_db_retries", 2) -... - - -
- -
- <varname>ps_max_col_size</varname> (integer) - - The maximum size of a column's data, when fetched using prepared - statements. Particularly relevant for variable-length data, such as - CHAR, BLOB, etc. - - - NOTE: Should a column's data exceed this limit, the value will be - silently truncated to fit the buffer, without reporting any errors! - - - - Default value is 1024 (bytes). - - - - Set <varname>ps_max_col_size</varname> parameter - -... -modparam("db_mysql", "ps_max_col_size", 4096) -... - - -
- -
- <varname>use_tls</varname> (integer) - - Setting this parameter will allow you to use TLS for MySQL connections. - In order to enable TLS for a specific connection, you can use the - "tls_domain=dom_name" URL parameter in the db_url of - the respective OpenSIPS module. This should be placed at the end of the - URL after the '?' character. Additionally, - the query string may include the "tls_opts= - PKEY,CERT,CA,CA_DIR,CIPHERS" CSV parameter, in order to control/limit the - amount of TLS options passed to the TLS library. - - - When using this parameter, you must also ensure that - tls_mgm is loaded and properly configured. Refer to - the the module for additional info regarding TLS client domains. - - - Note that if you want to use this feature, the TLS domain must be - provisioned in the configuration file, NOT in - the database. In case you are loading TLS certificates from the - database, you must at least define one domain in the - configuration script, to use for the initial connection to the DB. - - - Also, you can NOT enable TLS for the connection - to the database of the tls_mgm module itself. - - - - Default value is 0 (not enabled) - - - - Set the <varname>use_tls</varname> parameter - -... -modparam("tls_mgm", "client_domain", "dom1") -modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pem") -modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips.key") -modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") -... -modparam("db_mysql", "use_tls", 1) -... -modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_domain=dom1") -... -modparam("usrloc", "db_url", "mysql://root:1234@localhost/opensips?tls_domain=dom1&tls_opts=PKEY,CERT,CA,CA_DIR,CIPHERS") -... - - -
-
-
- Exported Functions - - No function exported to be used from configuration file. - -
-
- Installation - - Because it dependes on an external library, the mysql module is not - compiled and installed by default. You can use one of the next options. - - - - - - edit the "Makefile" and remove "db_mysql" from "excluded_modules" - list. Then follow the standard procedure to install &osips;: - "make all; make install". - - - - - - from command line use: 'make all include_modules="db_mysql"; - make install include_modules="db_mysql"'. - - - -
- -
- Exported Events -
- - <function moreinfo="none">E_MYSQL_CONNECTION</function> - - - This event is raised when a MySQL connection is lost or recovered. - - Parameters: - - - url - the URL of the connection as specified by the db_url parameter. - - - status - connected if the connection recovered, or - disconnected if the connection was lost. - - -
-
- -
- diff --git a/modules/db_oracle/README b/modules/db_oracle/README deleted file mode 100644 index f4ed3198945..00000000000 --- a/modules/db_oracle/README +++ /dev/null @@ -1,206 +0,0 @@ -oracle Module - __________________________________________________________ - - Table of Contents - - 1. User's Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. timeout (fixedpoint) - 1.3.2. reconnect (fixedpoint) - - 1.4. Exported Functions - 1.5. Installation - 1.6. Utility opensips_orasel - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set timeout parameter - 1.2. Disable asynchronous mode - 1.3. Set reconnect parameter - -Chapter 1. User's Guide - -1.1. Overview - - This is a module which provides Oracle connectivity for - OpenSIPS. It implements the DB API defined in OpenSIPS. If you - want to use the nathelper module, or any other modules that - calls the get_all_ucontacts API export from usrloc, then you - need to set the DORACLE_USRLOC define in the Makefile.defs file - before compilation. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * instantclient-sdk-10.2.0.3 - the development headers and - libraries of OCI. - -1.3. Exported Parameters - -1.3.1. timeout (fixedpoint) - - Timeout value for any operation with BD. - - Possible values is from 0.1 to 10.0 seconds. - - Default value is 3.0 (3 second). - - If value of timeout parameter set to 0, module use synchronous - mode (without timeout). - - Example 1.1. Set timeout parameter -... -modparam("db_oracle", "timeout", 1.5) -... - - Example 1.2. Disable asynchronous mode -... -modparam("db_oracle", "timeout", 0) -... - -1.3.2. reconnect (fixedpoint) - - Timeout value for connect (create session) operation. - - Possible values is from 0.1 to 10.0 seconds. - - Default value is 0.2 (200 milliseconds). - - Example 1.3. Set reconnect parameter -... -modparam("db_oracle", "reconnect", 0.5) -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Installation - - Because it dependes on an external library, the oracle module - is not compiled and installed by default. You can use one of - the next options. - * - edit the "Makefile" and remove "db_oracle" from - "excluded_modules" list. Then follow the standard procedure - to install OpenSIPS: "make all; make install". - * - from command line use: 'make all - include_modules="db_oracle"; make install - include_modules="db_oracle"'. - -1.6. Utility opensips_orasel - - For working with opensips-cli tool, should be able to print the - 'query' results to the terminal in a user-readable form. The - standard command-line Oracle client (sqlplus) is not quite - suitable for this, as it cannot align row width to real - (received) data's (it always prints a cell width as described - in the db scheme). This problem has been solved by inclusion - the utility opensips_orasel, which formats printing - approximately in the same way as the 'mysql' client utility. In - addition, this utility known about the "agreements and types" - in DB that are used in OpenSIPS for the work with Oracle and - formats printing taking these into account. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Iouri Kharon 21 1 2363 0 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 14 11 64 68 - 3. Razvan Crainea (@razvancrainea) 12 10 115 41 - 4. Liviu Chircu (@liviuchircu) 12 9 23 83 - 5. dronord 8 6 29 18 - 6. Peter Lemenkov (@lemenkov) 7 5 41 5 - 7. Gang Zhuo 6 4 42 16 - 8. Henning Westerholt (@henningw) 5 3 19 7 - 9. Gang Zhuo 4 2 4 2 - 10. Vlad Patrascu (@rvlad-patrascu) 4 2 3 3 - - All remaining contributors: Maksym Sobolyev (@sobomax), - fabriziopicconi, Ovidiu Sas (@ovidiusas), Ken Rice, Sergio - Gutierrez, Julián Moreno Patiño, Razvan Pistolea. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Gang Zhuo Nov 2022 - Nov 2024 - 3. Razvan Crainea (@razvancrainea) Oct 2011 - Jul 2024 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Gang Zhuo Dec 2021 - Dec 2021 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2008 - Apr 2019 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Aug 2012 - Jun 2018 - 10. dronord Nov 2017 - Dec 2017 - - All remaining contributors: Julián Moreno Patiño, - fabriziopicconi, Ovidiu Sas (@ovidiusas), Razvan Pistolea, - Sergio Gutierrez, Henning Westerholt (@henningw), Iouri Kharon. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Henning - Westerholt (@henningw), Iouri Kharon. - - Documentation Copyrights: - - Copyright © 2007-2008 TRUNK MOBILE, INC. diff --git a/modules/db_oracle/README.md b/modules/db_oracle/README.md new file mode 100644 index 00000000000..27b76eb69ae --- /dev/null +++ b/modules/db_oracle/README.md @@ -0,0 +1,130 @@ +--- +title: "oracle Module" +description: "This is a module which provides Oracle connectivity for OpenSIPS." +--- + +## User's Guide + + +### Overview + + +This is a module which provides Oracle connectivity for OpenSIPS. +It implements the DB API defined in OpenSIPS. If you want to use +the nathelper module, or any other modules that calls the +get_all_ucontacts API export from usrloc, then you need to set +the *DORACLE_USRLOC* define in the Makefile.defs +file before compilation. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *instantclient-sdk-10.2.0.3* - the development headers and libraries of OCI. + + +### Exported Parameters + + +#### timeout (fixedpoint) + + +Timeout value for any operation with BD. + + +Possible values is from 0.1 to 10.0 seconds. + + +*Default value is 3.0 (3 second).* + + +If value of timeout parameter set to 0, module use synchronous +mode (without timeout). + + +```opensips title="Set timeout parameter" +... +modparam("db_oracle", "timeout", 1.5) +... +``` + + +```opensips title="Disable asynchronous mode" +... +modparam("db_oracle", "timeout", 0) +... +``` + + +#### reconnect (fixedpoint) + + +Timeout value for connect (create session) operation. + + +Possible values is from 0.1 to 10.0 seconds. + + +*Default value is 0.2 (200 milliseconds).* + + +```opensips title="Set reconnect parameter" +... +modparam("db_oracle", "reconnect", 0.5) +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Installation + + +Because it dependes on an external library, the oracle module is not +compiled and installed by default. You can use one of the next options. + + +- edit the "Makefile" and remove "db_oracle" from "excluded_modules" +list. Then follow the standard procedure to install OpenSIPS: +"make all; make install". +- from command line use: 'make all include_modules="db_oracle"; +make install include_modules="db_oracle"'. + + +### Utility opensips_orasel + + +For working with opensips-cli tool, should be able to print the 'query' +results to the terminal in a user-readable form. The standard command-line +Oracle client (sqlplus) is not quite suitable for this, as it cannot align +row width to real (received) data's (it always prints a cell width as +described in the db scheme). This problem has been solved by inclusion the +utility opensips_orasel, which formats printing approximately in the same +way as the 'mysql' client utility. In addition, this utility known about +the "agreements and types" in DB that are used in OpenSIPS for the work +with Oracle and formats printing taking these into account. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_oracle/doc/contributors.xml b/modules/db_oracle/doc/contributors.xml deleted file mode 100644 index 997d7627d67..00000000000 --- a/modules/db_oracle/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Iouri Kharon - 21 - 1 - 2363 - 0 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 14 - 11 - 64 - 68 - - - 3. - Razvan Crainea (@razvancrainea) - 12 - 10 - 115 - 41 - - - 4. - Liviu Chircu (@liviuchircu) - 12 - 9 - 23 - 83 - - - 5. - dronord - 8 - 6 - 29 - 18 - - - 6. - Peter Lemenkov (@lemenkov) - 7 - 5 - 41 - 5 - - - 7. - Gang Zhuo - 6 - 4 - 42 - 16 - - - 8. - Henning Westerholt (@henningw) - 5 - 3 - 19 - 7 - - - 9. - Gang Zhuo - 4 - 2 - 4 - 2 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 3 - 3 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), fabriziopicconi, Ovidiu Sas (@ovidiusas), Ken Rice, Sergio Gutierrez, Julián Moreno Patiño, Razvan Pistolea. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Gang Zhuo - Nov 2022 - Nov 2024 - - - 3. - Razvan Crainea (@razvancrainea) - Oct 2011 - Jul 2024 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Gang Zhuo - Dec 2021 - Dec 2021 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2008 - Apr 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Aug 2012 - Jun 2018 - - - 10. - dronord - Nov 2017 - Dec 2017 - - - -
-All remaining contributors: Julián Moreno Patiño, fabriziopicconi, Ovidiu Sas (@ovidiusas), Razvan Pistolea, Sergio Gutierrez, Henning Westerholt (@henningw), Iouri Kharon. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Henning Westerholt (@henningw), Iouri Kharon. -
- -
diff --git a/modules/db_oracle/doc/db_oracle.xml b/modules/db_oracle/doc/db_oracle.xml deleted file mode 100644 index 1d33929b932..00000000000 --- a/modules/db_oracle/doc/db_oracle.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - oracle Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007-2008 TRUNK MOBILE, INC. - - diff --git a/modules/db_oracle/doc/db_oracle_admin.xml b/modules/db_oracle/doc/db_oracle_admin.xml deleted file mode 100644 index 7da37ae1226..00000000000 --- a/modules/db_oracle/doc/db_oracle_admin.xml +++ /dev/null @@ -1,151 +0,0 @@ - - - - - User's Guide - -
- Overview - - This is a module which provides Oracle connectivity for OpenSIPS. - It implements the DB API defined in OpenSIPS. If you want to use - the nathelper module, or any other modules that calls the - get_all_ucontacts API export from usrloc, then you need to set - the DORACLE_USRLOC define in the Makefile.defs - file before compilation. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - instantclient-sdk-10.2.0.3 - the development headers and libraries of OCI. - - - - -
-
-
- Exported Parameters -
- <varname>timeout</varname> (fixedpoint) - - Timeout value for any operation with BD. - - - Possible values is from 0.1 to 10.0 seconds. - - - - Default value is 3.0 (3 second). - - - - If value of timeout parameter set to 0, module use synchronous - mode (without timeout). - - - Set <varname>timeout</varname> parameter - -... -modparam("db_oracle", "timeout", 1.5) -... - - - - Disable asynchronous mode - -... -modparam("db_oracle", "timeout", 0) -... - - -
-
- <varname>reconnect</varname> (fixedpoint) - - Timeout value for connect (create session) operation. - - - Possible values is from 0.1 to 10.0 seconds. - - - - Default value is 0.2 (200 milliseconds). - - - - Set <varname>reconnect</varname> parameter - -... -modparam("db_oracle", "reconnect", 0.5) -... - - -
-
-
- Exported Functions - - No function exported to be used from configuration file. - -
-
- Installation - - Because it dependes on an external library, the oracle module is not - compiled and installed by default. You can use one of the next options. - - - - - - edit the "Makefile" and remove "db_oracle" from "excluded_modules" - list. Then follow the standard procedure to install &osips;: - "make all; make install". - - - - - - from command line use: 'make all include_modules="db_oracle"; - make install include_modules="db_oracle"'. - - - -
-
- Utility opensips_orasel - - For working with opensips-cli tool, should be able to print the 'query' - results to the terminal in a user-readable form. The standard command-line - Oracle client (sqlplus) is not quite suitable for this, as it cannot align - row width to real (received) data's (it always prints a cell width as - described in the db scheme). This problem has been solved by inclusion the - utility opensips_orasel, which formats printing approximately in the same - way as the 'mysql' client utility. In addition, this utility known about - the "agreements and types" in DB that are used in OpenSIPS for the work - with Oracle and formats printing taking these into account. - -
-
- diff --git a/modules/db_perlvdb/README b/modules/db_perlvdb/README deleted file mode 100644 index 9b6db0990fe..00000000000 --- a/modules/db_perlvdb/README +++ /dev/null @@ -1,337 +0,0 @@ -Perl Virtual Database Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Functions - - 2. Developer Guide - - 2.1. Introduction - 2.2. Base class OpenSIPS::VDB - 2.3. Data types - - 2.3.1. OpenSIPS::VDB::Value - 2.3.2. OpenSIPS::VDB::Pair - 2.3.3. OpenSIPS::VDB::ReqCond - 2.3.4. OpenSIPS::VDB::Column - 2.3.5. OpenSIPS::VDB::Result - - 2.4. Adapters - - 2.4.1. Function parameters - - 2.5. VTabs - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - -Chapter 1. Admin Guide - -1.1. Overview - - The Perl Virtual Database (VDB) provides a virtualization - framework for OpenSIPS's database access. It does not handle a - particular database engine itself but lets the user relay - database requests to arbitrary Perl functions. - - This module cannot be used "out of the box". The user has to - supply functionality dedicated to the client module. See below - for options. - - The module can be used in all current OpenSIPS modules that - need database access. Relaying of insert, update, query and - delete operations is supported. - - Modules can be configured to use the db_perlvdb module as - database backend using the db_url_parameter: -modparam("acc", "db_url", "perlvdb:OpenSIPS::VDB::Adapter::AccountingSIP -trace") - - This configuration options tells acc module that it should use - the db_perlvdb module which will in turn use the Perl class - OpenSIPS::VDB::Adapter::AccountingSIPtrace to relay the - database requests. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * perl -- Perl module - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None (Besides the ones mentioned in the perl module - documentation). - -1.3. Exported Parameters - - None. - -1.4. Exported Functions - - None. - -Chapter 2. Developer Guide - -2.1. Introduction - - OpenSIPS uses a database API for requests of numerous different - types of data. Four primary operations are supported: - * query - * insert - * update - * delete - - This module relays these database requests to user implemented - Perl functions. - -2.2. Base class OpenSIPS::VDB - - A client module has to be configured to use the db_perlvdb - module in conjunction with a Perl class to provide the - functions. The configured class needs to inherit from the base - class OpenSIPS::VDB. - - Derived classes have to implement the necessary functions - "query", "insert", "update" and/or "delete". The client module - specifies the necessary functions. To find out which functions - are called from a module, its processes may be evaluated with - the OpenSIPS::VDB::Adapter::Describe class which will log - incoming requests (without actually providing any real - functionality). - - While users can directly implement their desired functionality - in a class derived from OpenSIPS::VDB, it is advisable to split - the implementation into an Adapter that transforms the - relational structured parameters into pure Perl function - arguments, and add a virtual table (VTab) to provide the - relaying to an underlying technology. - -2.3. Data types - - Before introducing the higher level concepts of this module, - the used datatypes will briefly be explained. The OpenSIPS Perl - library includes some data types that have to be used in this - module: - -2.3.1. OpenSIPS::VDB::Value - - A value includes a data type flag and a value. Valid data types - are DB_INT, DB_DOUBLE, DB_STRING, DB_STR, DB_DATETIME, DB_BLOB, - DB_BITMAP. A new variable may be created with -my $val = new OpenSIPS::VDB::Value(DB_STRING, "foobar"); - - Value objects contain the type() and data() methods to get or - set the type and data attributes. - -2.3.2. OpenSIPS::VDB::Pair - - The Pair class is derived from the Value class and additionally - contains a column name (key). A new variable may be created - with -my $pair = new OpenSIPS::VDB::Pair("foo", DB_STRING, "bar"); - - where foo is the key and bar is the value. Additonally to the - methods of the Value class, it contains a key() method to get - or set the key attribute. - -2.3.3. OpenSIPS::VDB::ReqCond - - The ReqCond class is used for select condition and is derived - from the Pair class. It contains an addtional operator - attribute. A new variable may be created with -my $cond = new OpenSIPS::VDB::ReqCond("foo", ">", DB_INT, 5); - - where foo is the key, "greater" is the operator and 5 is the - value to compare. Additonally to the methods of the Pair class, - it contains an op() method to get or set the operator - attribute. - -2.3.4. OpenSIPS::VDB::Column - - This class represents a column definition or database schema. - It contains an array for the column names and an array for the - column types. Both arrays need to have the same length. A new - variable may be created with -my @types = { DB_INT, DB_STRING }; -my @names = { "id", "vals" }; -my $cols = new OpenSIPS::VDB::Column(\@types, \@names); - - The class contains the methods type() and name() to get or set - the type and name arrays. - -2.3.5. OpenSIPS::VDB::Result - - The Result class represents a query result. It contains a - schema (class Column) and an array of rows, where each row is - an array of Values. The object methods coldefs() and rows() may - be used to get and set the object attributes. - -2.4. Adapters - - Adapters should be used to turn the relational structured - database request into pure Perl function arguments. The - alias_db function alias_db_lookup for example takes a user/host - pair, and turns it into another user/host pair. The Alias - adapter turns the ReqCond array into two separate scalars that - are used as parameters for a VTab call. - - Adapter classes have to inherit from the OpenSIPS::VDB base - class and may provide one or more functions with the names - insert, update, replace, query and/or delete, depending on the - module which is to be used with the adapter. While modules such - as alias_db only require a query function, others -- such as - siptrace -- depend on inserts only. - -2.4.1. Function parameters - - The implemented functions need to deal with the correct data - types. The parameter and return types are listed in this - section. - - insert() is passed an array of OpenSIPS::VDB::Pair objects. It - should return an integer value. - - replace() is passed an array of OpenSIPS::VDB::Pair objects. - This function is currently not used by any publicly available - modules. It should return an integer value. - - delete() is passed an array of OpenSIPS::VDB::ReqCond objects. - It should return an integer value. - - update() is passed an array of OpenSIPS::VDB::ReqCond objects - (which rows to update) and an array of OpenSIPS::VDB::Pair - objects (new data). It should return an integer value. - - query() is passed an array of OpenSIPS::VDB::ReqCond objects - (which rows to select), an array of strings (which column names - to return) and a single string by which column to sort. It - should return an object of type OpenSIPS::VDB::Result. - -2.5. VTabs - - VTabs (virtual tables) provide a particular implementation for - an adapter. The Alias adapter e.g. calls a function with two - parameters (user, host) and expects a hash to be returned with - the two elements username and domain, or undef (when no result - is found). A sample VTab implementation for the Alias adapter - demonstrates this technique with a Perl hash that contains the - alias data. - - The standard Adapter/VTab pattern lets the user choose between - three options on how to implement VTabs: - * Single function. When a function is used as a virtual - table, it is passed the operation name (insert, replace, - update, query, delete) as its first parameter. The function - may be implemented in the main namespace. - - * Package/class. The defined class needs to have an init() - function. It will be called during the first call of that - VTab. Addtionally, the package has to define the necessary - functions insert, replace, update, delete and/or query. - These functions will be called in a function context (first - parameter is the class name). - - * Object. The defined class needs to have a new() function - which will return a reference to the newly created object. - This object needs to define the necessary functions insert, - replace, update, delete and/or query. These functions will - be called in a method context (first parameter is a - reference to the object). - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 26 19 257 202 - 2. Bastian Friedrich 19 2 1820 18 - 3. Liviu Chircu (@liviuchircu) 14 12 25 57 - 4. Razvan Crainea (@razvancrainea) 11 9 27 14 - 5. Daniel-Constantin Mierla (@miconda) 9 7 27 25 - 6. Maksym Sobolyev (@sobomax) 5 3 5 21 - 7. Henning Westerholt (@henningw) 4 2 14 13 - 8. Vlad Patrascu (@rvlad-patrascu) 4 2 10 10 - 9. Ancuta Onofrei 3 1 13 20 - 10. Konstantin Bokarius 3 1 3 5 - - All remaining contributors: Alexandra Titoc, Julián Moreno - Patiño, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Aug 2023 - 4. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Apr 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Daniel-Constantin Mierla (@miconda) Oct 2007 - Mar 2008 - 10. Konstantin Bokarius Mar 2008 - Mar 2008 - - All remaining contributors: Edson Gellert Schubert, Henning - Westerholt (@henningw), Ancuta Onofrei, Bastian Friedrich. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Bastian Friedrich. - - Documentation Copyrights: - - Copyright © 2007 Collax GmbH diff --git a/modules/db_perlvdb/README.md b/modules/db_perlvdb/README.md new file mode 100644 index 00000000000..4a15a37c2c7 --- /dev/null +++ b/modules/db_perlvdb/README.md @@ -0,0 +1,299 @@ +--- +title: "Perl Virtual Database Module" +description: "The Perl Virtual Database (VDB) provides a virtualization framework for OpenSIPS's database access. It does not handle a particular database engine itself but lets the user relay database requests to arbitrary Perl functions." +--- + +## Admin Guide + + +### Overview + + +The Perl Virtual Database (VDB) provides a virtualization framework +for OpenSIPS's database access. It does not handle a particular +database engine itself but lets the user relay database requests +to arbitrary Perl functions. + + +This module cannot be used "out of the box". The user has to supply +functionality dedicated to the client module. See below for options. + + +The module can be used in all current OpenSIPS modules that need +database access. Relaying of insert, update, query and delete +operations is supported. + + +Modules can be configured to use the db_perlvdb module as +database backend using the db_url_parameter: + + +```opensips +modparam("acc", "db_url", "perlvdb:OpenSIPS::VDB::Adapter::AccountingSIPtrace") +``` + + +This configuration options tells acc module that it should use the +db_perlvdb module which will in turn use the Perl class +OpenSIPS::VDB::Adapter::AccountingSIPtrace +to relay the database requests. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *perl* -- Perl module + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None* (Besides the ones mentioned in the perl +module documentation). + + +### Exported Parameters + + +*None*. + + +### Exported Functions + + +*None*. + + +## Developer Guide + + +### Introduction + + +OpenSIPS uses a database API for requests of numerous different +types of data. Four primary operations are supported: + + +- query +- insert +- update +- delete + + +This module relays these database requests to user implemented +Perl functions. + + +### Base class OpenSIPS::VDB + + +A client module has to be configured to use the db_perlvdb module in conjunction +with a Perl class to provide the functions. The configured class needs to +inherit from the base class `OpenSIPS::VDB`. + + +Derived classes have to implement the necessary +functions "query", "insert", "update" and/or "delete". The client module +specifies the necessary functions. +To find out which functions are called from a module, its processes may +be evaluated with the `OpenSIPS::VDB::Adapter::Describe` class which will +log incoming requests (without actually providing any real functionality). + + +While users can directly implement their desired functionality in a class +derived from OpenSIPS::VDB, it is advisable to split the implementation into +an Adapter that transforms the relational structured parameters into pure +Perl function arguments, and add a virtual table (VTab) to provide the +relaying to an underlying technology. + + +### Data types + + +Before introducing the higher level concepts of this module, the used +datatypes will briefly be explained. +The OpenSIPS Perl library includes some data types that have to be used +in this module: + + +#### OpenSIPS::VDB::Value + + +A value includes a data type flag and a value. Valid data types are +DB_INT, DB_DOUBLE, DB_STRING, DB_STR, DB_DATETIME, DB_BLOB, DB_BITMAP. +A new variable may be created with + + +```perl +my $val = new OpenSIPS::VDB::Value(DB_STRING, "foobar"); +``` + + +Value objects contain the type() and data() methods to get or set the type +and data attributes. + + +#### OpenSIPS::VDB::Pair + + +The Pair class is derived from the Value class and additionally contains a +column name (key). +A new variable may be created with + + +```perl +my $pair = new OpenSIPS::VDB::Pair("foo", DB_STRING, "bar"); +``` + + +where foo is the key and bar is the value. +Additonally to the methods of the Value class, it contains a key() method to +get or set the key attribute. + + +#### OpenSIPS::VDB::ReqCond + + +The ReqCond class is used for select condition and is derived from the Pair +class. It contains an addtional operator attribute. +A new variable may be created with + + +```perl +my $cond = new OpenSIPS::VDB::ReqCond("foo", ">", DB_INT, 5); +``` + + +where foo is the key, "greater" is the operator and 5 is the value to compare. +Additonally to the methods of the Pair class, it contains an op() method to +get or set the operator attribute. + + +#### OpenSIPS::VDB::Column + + +This class represents a column definition or database schema. It contains an +array for the column names and an array for the column types. Both arrays need +to have the same length. +A new variable may be created with + + +```perl +my @types = { DB_INT, DB_STRING }; +my @names = { "id", "vals" }; +my $cols = new OpenSIPS::VDB::Column(\@types, \@names); +``` + + +The class contains the methods type() and name() to get or set the type and name +arrays. + + +#### OpenSIPS::VDB::Result + + +The Result class represents a query result. It contains a schema (class Column) +and an array of rows, where each row is an array of Values. The object methods +coldefs() and rows() may be used to get and set the object attributes. + + +### Adapters + + +Adapters should be used to turn the relational structured database request into +pure Perl function arguments. The alias_db function alias_db_lookup for example +takes a user/host pair, and turns it into another user/host pair. The Alias +adapter turns the ReqCond array into two separate scalars that are used as parameters +for a VTab call. + + +Adapter classes have to inherit from the OpenSIPS::VDB base class and may provide +one or more functions with the names insert, update, replace, query and/or delete, +depending on the module which is to be used with the adapter. While modules such as +alias_db only require a query function, others -- such as siptrace -- depend +on inserts only. + + +#### Function parameters + + +The implemented functions need to deal with the correct data types. The +parameter and return types are listed in this section. + + +- *insert()* is passed an array of OpenSIPS::VDB::Pair objects. +It should return an integer value. + + +- *replace()* is passed an array of OpenSIPS::VDB::Pair objects. +This function is currently not used by any publicly available modules. +It should return an integer value. + + +- *delete()* is passed an array of OpenSIPS::VDB::ReqCond objects. +It should return an integer value. + + +- *update()* is passed an array of OpenSIPS::VDB::ReqCond objects +(which rows to update) and an array of OpenSIPS::VDB::Pair objects +(new data). +It should return an integer value. + + +- *query()* is passed an array of OpenSIPS::VDB::ReqCond objects +(which rows to select), an array of strings (which column names to return) +and a single string by which column to sort. +It should return an object of type OpenSIPS::VDB::Result. + + +### VTabs + + +VTabs (virtual tables) provide a particular implementation for an adapter. The Alias +adapter e.g. calls a function with two parameters (user, host) and expects a hash to +be returned with the two elements username and domain, or undef (when no result +is found). +A sample VTab implementation for the Alias adapter demonstrates this technique with +a Perl hash that contains the alias data. + + +The standard Adapter/VTab pattern lets the user choose between three options on how to +implement VTabs: + + +- *Single function*. When a function is used +as a virtual table, it is passed the operation name (insert, replace, update, +query, delete) as its first parameter. The function may be implemented +in the main namespace. + + +- *Package/class*. The defined class needs +to have an init() function. It will be called during the first call of that +VTab. +Addtionally, the package has +to define the necessary functions insert, replace, update, delete and/or query. +These functions will be called in a function context (first parameter is the +class name). + + +- *Object*. The defined class needs +to have a new() function which will return a reference to the newly +created object. This object needs to define the necessary functions insert, +replace, update, delete and/or query. +These functions will be called in a method context (first parameter is +a reference to the object). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_perlvdb/doc/contributors.xml b/modules/db_perlvdb/doc/contributors.xml deleted file mode 100644 index 46557ecd668..00000000000 --- a/modules/db_perlvdb/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 26 - 19 - 257 - 202 - - - 2. - Bastian Friedrich - 19 - 2 - 1820 - 18 - - - 3. - Liviu Chircu (@liviuchircu) - 14 - 12 - 25 - 57 - - - 4. - Razvan Crainea (@razvancrainea) - 11 - 9 - 27 - 14 - - - 5. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 27 - 25 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 5 - 21 - - - 7. - Henning Westerholt (@henningw) - 4 - 2 - 14 - 13 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 10 - 10 - - - 9. - Ancuta Onofrei - 3 - 1 - 13 - 20 - - - 10. - Konstantin Bokarius - 3 - 1 - 3 - 5 - - - -
-All remaining contributors: Alexandra Titoc, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Aug 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Apr 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Daniel-Constantin Mierla (@miconda) - Oct 2007 - Mar 2008 - - - 10. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - -
-All remaining contributors: Edson Gellert Schubert, Henning Westerholt (@henningw), Ancuta Onofrei, Bastian Friedrich. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Bastian Friedrich. -
- -
diff --git a/modules/db_perlvdb/doc/db_perlvdb.xml b/modules/db_perlvdb/doc/db_perlvdb.xml deleted file mode 100644 index cee0735d4f4..00000000000 --- a/modules/db_perlvdb/doc/db_perlvdb.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Perl Virtual Database Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Collax GmbH - - diff --git a/modules/db_perlvdb/doc/db_perlvdb_admin.xml b/modules/db_perlvdb/doc/db_perlvdb_admin.xml deleted file mode 100644 index da3075aab5c..00000000000 --- a/modules/db_perlvdb/doc/db_perlvdb_admin.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Perl Virtual Database (VDB) provides a virtualization framework - for &osips;'s database access. It does not handle a particular - database engine itself but lets the user relay database requests - to arbitrary Perl functions. - - - This module cannot be used "out of the box". The user has to supply - functionality dedicated to the client module. See below for options. - - - The module can be used in all current &osips; modules that need - database access. Relaying of insert, update, query and delete - operations is supported. - - - Modules can be configured to use the db_perlvdb module as - database backend using the db_url_parameter: - - -modparam("acc", "db_url", "perlvdb:OpenSIPS::VDB::Adapter::AccountingSIPtrace") - - - This configuration options tells acc module that it should use the - db_perlvdb module which will in turn use the Perl class - OpenSIPS::VDB::Adapter::AccountingSIPtrace - to relay the database requests. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - perl -- Perl module - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None (Besides the ones mentioned in the perl - module documentation). - - - - -
-
- -
- Exported Parameters - - None. - -
- -
- Exported Functions - - None. - -
- -
- diff --git a/modules/db_perlvdb/doc/db_perlvdb_devel.xml b/modules/db_perlvdb/doc/db_perlvdb_devel.xml deleted file mode 100644 index c0f434ebf37..00000000000 --- a/modules/db_perlvdb/doc/db_perlvdb_devel.xml +++ /dev/null @@ -1,195 +0,0 @@ - - - - - &develguide; -
Introduction - - OpenSIPS uses a database API for requests of numerous different - types of data. Four primary operations are supported: - - query - insert - update - delete - - - - This module relays these database requests to user implemented - Perl functions. - -
-
Base class OpenSIPS::VDB - - A client module has to be configured to use the db_perlvdb module in conjunction - with a Perl class to provide the functions. The configured class needs to - inherit from the base class OpenSIPS::VDB. - - - Derived classes have to implement the necessary - functions "query", "insert", "update" and/or "delete". The client module - specifies the necessary functions. - To find out which functions are called from a module, its processes may - be evaluated with the OpenSIPS::VDB::Adapter::Describe class which will - log incoming requests (without actually providing any real functionality). - - - While users can directly implement their desired functionality in a class - derived from OpenSIPS::VDB, it is advisable to split the implementation into - an Adapter that transforms the relational structured parameters into pure - Perl function arguments, and add a virtual table (VTab) to provide the - relaying to an underlying technology. - -
-
Data types - - Before introducing the higher level concepts of this module, the used - datatypes will briefly be explained. - The OpenSIPS Perl library includes some data types that have to be used - in this module: - -
OpenSIPS::VDB::Value - - A value includes a data type flag and a value. Valid data types are - DB_INT, DB_DOUBLE, DB_STRING, DB_STR, DB_DATETIME, DB_BLOB, DB_BITMAP. - A new variable may be created with -my $val = new OpenSIPS::VDB::Value(DB_STRING, "foobar"); - - Value objects contain the type() and data() methods to get or set the type - and data attributes. - -
-
OpenSIPS::VDB::Pair - - The Pair class is derived from the Value class and additionally contains a - column name (key). - A new variable may be created with -my $pair = new OpenSIPS::VDB::Pair("foo", DB_STRING, "bar"); - - where foo is the key and bar is the value. - Additonally to the methods of the Value class, it contains a key() method to - get or set the key attribute. - -
-
OpenSIPS::VDB::ReqCond - - The ReqCond class is used for select condition and is derived from the Pair - class. It contains an addtional operator attribute. - A new variable may be created with -my $cond = new OpenSIPS::VDB::ReqCond("foo", ">", DB_INT, 5); - - where foo is the key, "greater" is the operator and 5 is the value to compare. - Additonally to the methods of the Pair class, it contains an op() method to - get or set the operator attribute. - -
-
OpenSIPS::VDB::Column - - This class represents a column definition or database schema. It contains an - array for the column names and an array for the column types. Both arrays need - to have the same length. - A new variable may be created with -my @types = { DB_INT, DB_STRING }; -my @names = { "id", "vals" }; -my $cols = new OpenSIPS::VDB::Column(\@types, \@names); - - The class contains the methods type() and name() to get or set the type and name - arrays. - -
-
OpenSIPS::VDB::Result - - The Result class represents a query result. It contains a schema (class Column) - and an array of rows, where each row is an array of Values. The object methods - coldefs() and rows() may be used to get and set the object attributes. - -
-
-
Adapters - - Adapters should be used to turn the relational structured database request into - pure Perl function arguments. The alias_db function alias_db_lookup for example - takes a user/host pair, and turns it into another user/host pair. The Alias - adapter turns the ReqCond array into two separate scalars that are used as parameters - for a VTab call. - - - Adapter classes have to inherit from the OpenSIPS::VDB base class and may provide - one or more functions with the names insert, update, replace, query and/or delete, - depending on the module which is to be used with the adapter. While modules such as - alias_db only require a query function, others -- such as siptrace -- depend - on inserts only. - -
Function parameters - - The implemented functions need to deal with the correct data types. The - parameter and return types are listed in this section. - - - insert() is passed an array of OpenSIPS::VDB::Pair objects. - It should return an integer value. - - - replace() is passed an array of OpenSIPS::VDB::Pair objects. - This function is currently not used by any publicly available modules. - It should return an integer value. - - - delete() is passed an array of OpenSIPS::VDB::ReqCond objects. - It should return an integer value. - - - update() is passed an array of OpenSIPS::VDB::ReqCond objects - (which rows to update) and an array of OpenSIPS::VDB::Pair objects - (new data). - It should return an integer value. - - - query() is passed an array of OpenSIPS::VDB::ReqCond objects - (which rows to select), an array of strings (which column names to return) - and a single string by which column to sort. - It should return an object of type OpenSIPS::VDB::Result. - -
-
-
VTabs - - VTabs (virtual tables) provide a particular implementation for an adapter. The Alias - adapter e.g. calls a function with two parameters (user, host) and expects a hash to - be returned with the two elements username and domain, or undef (when no result - is found). - A sample VTab implementation for the Alias adapter demonstrates this technique with - a Perl hash that contains the alias data. - - - The standard Adapter/VTab pattern lets the user choose between three options on how to - implement VTabs: - - Single function. When a function is used - as a virtual table, it is passed the operation name (insert, replace, update, - query, delete) as its first parameter. The function may be implemented - in the main namespace. - - - Package/class. The defined class needs - to have an init() function. It will be called during the first call of that - VTab. - Addtionally, the package has - to define the necessary functions insert, replace, update, delete and/or query. - These functions will be called in a function context (first parameter is the - class name). - - - - Object. The defined class needs - to have a new() function which will return a reference to the newly - created object. This object needs to define the necessary functions insert, - replace, update, delete and/or query. - These functions will be called in a method context (first parameter is - a reference to the object). - - - -
-
- diff --git a/modules/db_postgres/README b/modules/db_postgres/README deleted file mode 100644 index 5fd0e35dbeb..00000000000 --- a/modules/db_postgres/README +++ /dev/null @@ -1,258 +0,0 @@ -db_postgres Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. exec_query_threshold (integer) - 1.3.2. max_db_queries (integer) - 1.3.3. timeout (integer) - 1.3.4. use_tls (integer) - - 1.4. Exported Functions - 1.5. Installation and Running - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set exec_query_threshold parameter - 1.2. Set max_db_queries parameter - 1.3. Set timeout parameter - 1.4. Set the use_tls parameter - -Chapter 1. Admin Guide - -1.1. Overview - - Module description - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * PostgreSQL library - e.g., libpq5. - * PostgreSQL devel library - to compile the module (e.g., - libpq-dev). - -1.3. Exported Parameters - -1.3.1. exec_query_threshold (integer) - - If queries take longer than 'exec_query_threshold' - microseconds, warning messages will be written to logging - facility. - - Default value is 0 - disabled. - - Example 1.1. Set exec_query_threshold parameter -... -modparam("db_postgres", "exec_query_threshold", 60000) -... - -1.3.2. max_db_queries (integer) - - The maximum number of database queries to be executed. If this - parameter is set improperly, it is set to default value. - - Default value is 2. - - Example 1.2. Set max_db_queries parameter -... -modparam("db_postgres", "max_db_queries", 2) -... - -1.3.3. timeout (integer) - - The number of seconds the PostgreSQL library waits to connect - and query the server. If the connection does not succeed within - the given timeout, the connection fails. - - Note:If the timeout is a negative value and connection does not - succeed, OpenSIPS will block until the connection becomes back - available and gets successfully established. This is the - default behavior of the library and is the behavior prior to - the adition of this parameter. - - Default value is 5. - - Example 1.3. Set timeout parameter -... -modparam("db_postgres", "timeout", 2) -... - -1.3.4. use_tls (integer) - - Parameter to control the way the SSL support is used when - connecting to the Postgres server, as follows: - * use_tls=0 (default) - the SSL support is disabled and there - is no attempt to use it; - * use_tls=1 with "tls_domain" present in the DB URL - the SSL - support is enabled, either "require", either "verify-ca", - depending on the certificate settings; - * use_tls=1 with no "tls_domain" present in the DB URL - the - SSL support is enabled in best effort mode (or "prefer"); - if supported by the server, it will be used, otherwise it - will fall back to non-SSL. - - Warning: the tls_openssl module cannot be used when setting - this parameter. Use the tls_wolfssl module instead if a TLS/SSL - Library is required. - - Setting this parameter will allow you to use TLS for PostgreSQL - connections. In order to enable TLS for a specific connection, - you can use the "tls_domain=dom_name" URL parameter in the - db_url of the respective OpenSIPS module. This should be placed - at the end of the URL after the '?' character. - - When using this parameter, you must also ensure that tls_mgm is - loaded and properly configured. Refer to the the module for - additional info regarding TLS client domains. - - Note that if you want to use this feature, the TLS domain must - be provisioned in the configuration file, NOT in the database. - In case you are loading TLS certificates from the database, you - must at least define one domain in the configuration script, to - use for the initial connection to the DB. - - Also, you can NOT enable TLS for the connection to the database - of the tls_mgm module itself. - - Default value is 0 (not enabled) - - Example 1.4. Set the use_tls parameter -... -modparam("tls_mgm", "client_domain", "dom1") -modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pe -m") -modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips. -key") -modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") -... -modparam("db_postgres", "use_tls", 1) -... -modparam("usrloc", "db_url", "postgres://root:1234@localhost/opensips?tl -s_domain=dom1") -... - -1.4. Exported Functions - - NONE - -1.5. Installation and Running - - Notes about installation and running. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Henning Westerholt (@henningw) 67 29 554 1963 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 61 45 1088 349 - 3. Norman Brandinger (@NormB) 55 4 1449 2247 - 4. Greg Fausak 42 3 4472 2 - 5. Daniel-Constantin Mierla (@miconda) 27 20 350 203 - 6. Liviu Chircu (@liviuchircu) 18 15 45 87 - 7. Razvan Crainea (@razvancrainea) 15 12 210 27 - 8. Jan Janak (@janakj) 12 8 300 23 - 9. Klaus Darilion 10 6 139 67 - 10. Vlad Paiu (@vladpaiu) 9 7 102 34 - - All remaining contributors: Maksym Sobolyev (@sobomax), Vlad - Patrascu (@rvlad-patrascu), Ancuta Onofrei, Norman Brandinger, - Andrei Pelinescu-Onciul, Dusan Klinec (@ph4r05), Eseanu Marius - Cristian (@eseanucristian), Ruslan Bukin, Ryan Bullock - (@rrb3942), Konstantin Bokarius, Razvan Pistolea, Aron - Podrigal, Dan Pascu (@danpascu), Ken Rice, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Jarrod Baumann (@jarrodb). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Razvan Crainea (@razvancrainea) Oct 2011 - Jul 2024 - 3. Liviu Chircu (@liviuchircu) Sep 2012 - May 2024 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2005 - Feb 2024 - 5. Maksym Sobolyev (@sobomax) Apr 2004 - Feb 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Oct 2021 - 7. Norman Brandinger (@NormB) Aug 2006 - Oct 2021 - 8. Dan Pascu (@danpascu) May 2019 - May 2019 - 9. Ryan Bullock (@rrb3942) Mar 2019 - Mar 2019 - 10. Vlad Paiu (@vladpaiu) Jan 2011 - Feb 2019 - - All remaining contributors: Peter Lemenkov (@lemenkov), Jarrod - Baumann (@jarrodb), Dusan Klinec (@ph4r05), Aron Podrigal, - Eseanu Marius Cristian (@eseanucristian), Razvan Pistolea, - Ruslan Bukin, Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Ancuta Onofrei, Klaus Darilion, Norman Brandinger, Jan Janak - (@janakj), Greg Fausak, Andrei Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Norman Brandinger (@NormB), Liviu - Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter - Lemenkov (@lemenkov), Aron Podrigal, Eseanu Marius Cristian - (@eseanucristian), Vlad Paiu (@vladpaiu), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Henning Westerholt (@henningw), Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 Greg Fausak diff --git a/modules/db_postgres/README.md b/modules/db_postgres/README.md new file mode 100644 index 00000000000..0ef3dc51c87 --- /dev/null +++ b/modules/db_postgres/README.md @@ -0,0 +1,182 @@ +--- +title: "db_postgres Module" +description: "Module description" +--- + +## Admin Guide + + +### Overview + + +Module description + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *PostgreSQL library* - e.g., libpq5. +- *PostgreSQL devel library* - to compile +the module (e.g., libpq-dev). + + +### Exported Parameters + + +#### exec_query_threshold (integer) + + +If queries take longer than 'exec_query_threshold' microseconds, warning +messages will be written to logging facility. + + +*Default value is 0 - disabled.* + + +```opensips title="Set exec_query_threshold parameter" +... +modparam("db_postgres", "exec_query_threshold", 60000) +... +``` + + +#### max_db_queries (integer) + + +The maximum number of database queries to be executed. +If this parameter is set improperly, it is set to default value. + + +*Default value is 2.* + + +```opensips title="Set max_db_queries parameter" +... +modparam("db_postgres", "max_db_queries", 2) +... +``` + + +#### timeout (integer) + + +The number of seconds the PostgreSQL library waits to connect and query +the server. If the connection does not succeed within the given timeout, +the connection fails. + + +> [!NOTE] +> If the timeout is a negative value and +> connection does not succeed, OpenSIPS will block until the connection +> becomes back available and gets successfully established. This is the +> default behavior of the library and is the behavior prior to the +> addition of this parameter. + + +*Default value is 5.* + + +```opensips title="Set timeout parameter" +... +modparam("db_postgres", "timeout", 2) +... +``` + + +#### use_tls (integer) + + +Parameter to control the way the SSL support is used when connecting +to the Postgres server, as follows: + + +- *use_tls=0* (default) - the SSL support +is disabled and there is no attempt to use it; +- *use_tls=1* with "tls_domain" present +in the DB URL - the SSL support is enabled, either +"require", either "verify-ca", depending on the certificate +settings; +- *use_tls=1* with no "tls_domain" present +in the DB URL - the SSL support is enabled in best effort mode +(or "prefer"); if supported by the server, it will be used, +otherwise it will fall back to non-SSL. + + +> [!WARNING] +> The *tls_openssl* module cannot be used +> when setting this parameter. Use the *tls_wolfssl* +> module instead if a TLS/SSL Library is required. + + +Setting this parameter will allow you to use TLS for PostgreSQL connections. +In order to enable TLS for a specific connection, you can use the +"tls_domain=*dom_name*" URL parameter in the db_url of +the respective OpenSIPS module. This should be placed at the end of the +URL after the '?' character. + + +When using this parameter, you must also ensure that +*tls_mgm* is loaded and properly configured. Refer to +the the module for additional info regarding TLS client domains. + + +> [!NOTE] +> If you want to use this feature, the TLS domain must be +> provisioned in the configuration file, *NOT* in +> the database. In case you are loading TLS certificates from the +> database, you must at least define one domain in the +> configuration script, to use for the initial connection to the DB. + + +Also, you can *NOT* enable TLS for the connection +to the database of the *tls_mgm* module itself. + + +*Default value is **0** (not enabled)* + + +```opensips title="Set the use_tls parameter" +... +modparam("tls_mgm", "client_domain", "dom1") +modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pem") +modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips.key") +modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") +... +modparam("db_postgres", "use_tls", 1) +... +modparam("usrloc", "db_url", "postgres://root:1234@localhost/opensips?tls_domain=dom1") +... +``` + + +### Exported Functions + + +NONE + + +### Installation and Running + + +Notes about installation and running. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_postgres/doc/contributors.xml b/modules/db_postgres/doc/contributors.xml deleted file mode 100644 index 3b785b5c3d7..00000000000 --- a/modules/db_postgres/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Henning Westerholt (@henningw) - 67 - 29 - 554 - 1963 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 61 - 45 - 1088 - 349 - - - 3. - Norman Brandinger (@NormB) - 55 - 4 - 1449 - 2247 - - - 4. - Greg Fausak - 42 - 3 - 4472 - 2 - - - 5. - Daniel-Constantin Mierla (@miconda) - 27 - 20 - 350 - 203 - - - 6. - Liviu Chircu (@liviuchircu) - 18 - 15 - 45 - 87 - - - 7. - Razvan Crainea (@razvancrainea) - 15 - 12 - 210 - 27 - - - 8. - Jan Janak (@janakj) - 12 - 8 - 300 - 23 - - - 9. - Klaus Darilion - 10 - 6 - 139 - 67 - - - 10. - Vlad Paiu (@vladpaiu) - 9 - 7 - 102 - 34 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Vlad Patrascu (@rvlad-patrascu), Ancuta Onofrei, Norman Brandinger, Andrei Pelinescu-Onciul, Dusan Klinec (@ph4r05), Eseanu Marius Cristian (@eseanucristian), Ruslan Bukin, Ryan Bullock (@rrb3942), Konstantin Bokarius, Razvan Pistolea, Aron Podrigal, Dan Pascu (@danpascu), Ken Rice, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Jarrod Baumann (@jarrodb). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Oct 2011 - Jul 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Sep 2012 - May 2024 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2005 - Feb 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Apr 2004 - Feb 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Oct 2021 - - - 7. - Norman Brandinger (@NormB) - Aug 2006 - Oct 2021 - - - 8. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 9. - Ryan Bullock (@rrb3942) - Mar 2019 - Mar 2019 - - - 10. - Vlad Paiu (@vladpaiu) - Jan 2011 - Feb 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Jarrod Baumann (@jarrodb), Dusan Klinec (@ph4r05), Aron Podrigal, Eseanu Marius Cristian (@eseanucristian), Razvan Pistolea, Ruslan Bukin, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei, Klaus Darilion, Norman Brandinger, Jan Janak (@janakj), Greg Fausak, Andrei Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Norman Brandinger (@NormB), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Aron Podrigal, Eseanu Marius Cristian (@eseanucristian), Vlad Paiu (@vladpaiu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jan Janak (@janakj). -
- -
diff --git a/modules/db_postgres/doc/db_postgres.xml b/modules/db_postgres/doc/db_postgres.xml deleted file mode 100644 index ebbf2942108..00000000000 --- a/modules/db_postgres/doc/db_postgres.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - db_postgres Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 Greg Fausak - - diff --git a/modules/db_postgres/doc/db_postgres_admin.xml b/modules/db_postgres/doc/db_postgres_admin.xml deleted file mode 100644 index 1a5a047ff28..00000000000 --- a/modules/db_postgres/doc/db_postgres_admin.xml +++ /dev/null @@ -1,210 +0,0 @@ - - - - - &adminguide; - -
- Overview - Module description -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - PostgreSQL library - e.g., libpq5. - - - - - PostgreSQL devel library - to compile - the module (e.g., libpq-dev). - - - - -
-
- -
- Exported Parameters -
- <varname>exec_query_threshold</varname> (integer) - - If queries take longer than 'exec_query_threshold' microseconds, warning - messages will be written to logging facility. - - - - Default value is 0 - disabled. - - - - Set <varname>exec_query_threshold</varname> parameter - -... -modparam("db_postgres", "exec_query_threshold", 60000) -... - - -
-
- <varname>max_db_queries</varname> (integer) - - The maximum number of database queries to be executed. - If this parameter is set improperly, it is set to default value. - - - - Default value is 2. - - - - Set <varname>max_db_queries</varname> parameter - -... -modparam("db_postgres", "max_db_queries", 2) -... - - -
-
- <varname>timeout</varname> (integer) - - The number of seconds the PostgreSQL library waits to connect and query - the server. If the connection does not succeed within the given timeout, - the connection fails. - - - Note:If the timeout is a negative value and - connection does not succeed, &osips; will block until the connection - becomes back available and gets successfully established. This is the - default behavior of the library and is the behavior prior to the - adition of this parameter. - - - - Default value is 5. - - - - Set <varname>timeout</varname> parameter - -... -modparam("db_postgres", "timeout", 2) -... - - -
- -
- <varname>use_tls</varname> (integer) - - Parameter to control the way the SSL support is used when connecting - to the Postgres server, as follows: - - - - - use_tls=0 (default) - the SSL support - is disabled and there is no attempt to use it; - - - - - use_tls=1 with "tls_domain" present - in the DB URL - the SSL support is enabled, either - "require", either "verify-ca", depending on the certificate - settings; - - - - - use_tls=1 with no "tls_domain" present - in the DB URL - the SSL support is enabled in best effort mode - (or "prefer"); if supported by the server, it will be used, - otherwise it will fall back to non-SSL. - - - - - Warning: the tls_openssl module cannot be used - when setting this parameter. Use the tls_wolfssl - module instead if a TLS/SSL Library is required. - - - Setting this parameter will allow you to use TLS for PostgreSQL connections. - In order to enable TLS for a specific connection, you can use the - "tls_domain=dom_name" URL parameter in the db_url of - the respective OpenSIPS module. This should be placed at the end of the - URL after the '?' character. - - - When using this parameter, you must also ensure that - tls_mgm is loaded and properly configured. Refer to - the the module for additional info regarding TLS client domains. - - - Note that if you want to use this feature, the TLS domain must be - provisioned in the configuration file, NOT in - the database. In case you are loading TLS certificates from the - database, you must at least define one domain in the - configuration script, to use for the initial connection to the DB. - - - Also, you can NOT enable TLS for the connection - to the database of the tls_mgm module itself. - - - - Default value is 0 (not enabled) - - - - Set the <varname>use_tls</varname> parameter - -... -modparam("tls_mgm", "client_domain", "dom1") -modparam("tls_mgm", "certificate", "[dom1]/etc/pki/tls/certs/opensips.pem") -modparam("tls_mgm", "private_key", "[dom1]/etc/pki/tls/private/opensips.key") -modparam("tls_mgm", "ca_list", "[dom1]/etc/pki/tls/certs/ca.pem") -... -modparam("db_postgres", "use_tls", 1) -... -modparam("usrloc", "db_url", "postgres://root:1234@localhost/opensips?tls_domain=dom1") -... - - -
-
-
- Exported Functions - - NONE - -
-
- Installation and Running - Notes about installation and running. -
-
- diff --git a/modules/db_sqlite/README b/modules/db_sqlite/README deleted file mode 100644 index a3020f0d9bc..00000000000 --- a/modules/db_sqlite/README +++ /dev/null @@ -1,239 +0,0 @@ -db_sqlite Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. alloc_limit (integer) - 1.3.2. load_extension (string) - 1.3.3. busy_timeout (integer) - 1.3.4. exec_pragma (string) - - 1.4. Exported Functions - 1.5. Installation - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set alloc_limit parameter - 1.2. Set load_extension parameter - 1.3. Set busy_timeout parameter - 1.4. Set exec_pragma parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides SQLite support for OpenSIPS. It - implements the DB API defined in OpenSIPS. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - - Also this module provides two ways of creating the query. One - is to use sqlite3_bind_* functions after opensips creates the - prepared statement query. The second one directly uses only - sqlite3_snprintf function to print the values into the opensips - created query. In theory, the second one should be faster and - should allow you to make more queries to the database in the - same time, so by default this one will be active. You can use - the sqlite3_bind_* interface by simply uncommenting the - SQLITE_BIND line the Makefile. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libsqlite3-dev - the development libraries of sqlite. - -1.3. Exported Parameters - -1.3.1. alloc_limit (integer) - - Since the library does not support a function to return the - number of rows in a query, this number is obtained using - "count(*)" query. If we use multiple processes there is the - risk ,since "count(*)" query and the actual "select" query, the - number of rows in the result query to have changed, so realloc - will be needed if the number is bigger. Using alloc_limit - parameter you can specify the number with which the number of - allocated rows in the result is raised. - - Default value is 10. - - Example 1.1. Set alloc_limit parameter -... -modparam("db_sqlite", "alloc_limit", 25) -... - -1.3.2. load_extension (string) - - This parameter enables extension loading, similiar to ".load" - functionality in sqlite3, extenions like sqlite3-pcre which - enables REGEX function. In order to use this functionality you - must specify the library path (.so file) and the entry point - which represents the function to be called by the sqlite - library (read more at sqlite load_extension official - documentation), separated by ";" delimiter. The entry point - paramter can miss, so you won't need to use the delimitier in - this case. - - By default, no extension is loaded. - - Example 1.2. Set load_extension parameter -... -modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so") -modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so;sqlite -3_extension_init") -... - -1.3.3. busy_timeout (integer) - - This parameter sets the default busy_handler for the SQLite - library, that sleeps for a specified amount of time when a - table is locked. The handler will sleep multiple times until at - least the specified "busy_timeout" duration (in milliseconds) - has been reached. Setting this parameter to a value less than - or equal to zero turns off all busy handlers. (read more in the - SQLite official documentation) - - Default value is 500. - - Example 1.3. Set busy_timeout parameter -... -modparam("db_sqlite", "busy_timeout", 5000) -... - -1.3.4. exec_pragma (string) - - This parameter allows configuring an SQLite database with - "PRAGMA" statements, (read more in the SQLite official - documentation) To use this functionality you must specify the - exec_pragma parameter value as "pragma-name=pragma-value". - Multiple parameters with the same name can be specified, and - they will be executed one by one on every database connection. - If a parameter has an incorrect name or syntax, it will be - ignored by SQLite without any error messages. - - By default, no PRAGMA statements are executed. - - Example 1.4. Set exec_pragma parameter -... -modparam("db_sqlite", "exec_pragma", "journal_mode=wal") -modparam("db_sqlite", "exec_pragma", "synchronous=normal") -modparam("db_sqlite", "exec_pragma", "cache_size=-2000") -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Installation - - Because it dependes on an external library, the sqlite module - is not compiled and installed by default. You can use one of - the next options. - * - edit the "Makefile" and remove "db_sqlite" from - "excluded_modules" list. Then follow the standard procedure - to install OpenSIPS: "make all; make install". - * - from command line use: 'make all - include_modules="db_sqlite"; make install - include_modules="db_sqlite"'. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- -1. Ionut Ionita (@ionutrazvanionita) 82 28 3744 1276 -2. Razvan Crainea (@razvancrainea) 19 17 115 42 -3. Alexey Vasilyev (@vasilevalex) 13 9 165 96 -4. Liviu Chircu (@liviuchircu) 12 10 32 60 -5. Jarrod Baumann (@jarrodb) 5 3 7 4 -6. Vlad Patrascu (@rvlad-patrascu) 4 2 3 2 -7. Alexandra Titoc 4 2 2 3 -8. Aron Podrigal (@ar45) 3 1 10 1 -9. Daniel Fussia 3 1 4 22 -10. Maksym Sobolyev (@sobomax) 3 1 2 2 - - All remaining contributors: Bogdan-Andrei Iancu - (@bogdan-iancu), Eric Green, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2015 - Jan 2025 - 2. Alexey Vasilyev (@vasilevalex) Dec 2024 - Dec 2024 - 3. Liviu Chircu (@liviuchircu) May 2016 - Sep 2024 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Eric Green Aug 2020 - Aug 2020 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2019 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Ionut Ionita (@ionutrazvanionita) Apr 2015 - Feb 2017 - - All remaining contributors: Daniel Fussia, Jarrod Baumann - (@jarrodb), Aron Podrigal (@ar45). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Alexey Vasilyev (@vasilevalex), Liviu Chircu - (@liviuchircu), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/db_sqlite/README.md b/modules/db_sqlite/README.md new file mode 100644 index 00000000000..38a9a1da057 --- /dev/null +++ b/modules/db_sqlite/README.md @@ -0,0 +1,163 @@ +--- +title: "db_sqlite Module" +description: "This is a module which provides SQLite support for OpenSIPS. It implements the DB API defined in OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides SQLite support for OpenSIPS. +It implements the DB API defined in OpenSIPS. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +Also this module provides two ways of creating the query. One is to use +sqlite3_bind_* functions after opensips creates the prepared statement query. +The second one directly uses only sqlite3_snprintf function to print the +values into the opensips created query. In theory, the second one should +be faster and should allow you to make more queries to the database in +the same time, so by default this one will be active. You can use the +sqlite3_bind_* interface by simply uncommenting the SQLITE_BIND line +the Makefile. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libsqlite3-dev* - the development libraries of sqlite. + + +### Exported Parameters + + +#### alloc_limit (integer) + + +Since the library does not support a function to return the number of rows +in a query, this number is obtained using "count(*)" query. If we use multiple +processes there is the risk ,since "count(*)" query and the actual "select" +query, the number of rows in the result query to have changed, so realloc +will be needed if the number is bigger. Using *alloc_limit* +parameter you can specify the number with which the number of allocated rows in the +result is raised. + + +*Default value is 10.* + + +```opensips title="Set alloc_limit parameter" +... +modparam("db_sqlite", "alloc_limit", 25) +... +``` + + +#### load_extension (string) + + +This parameter enables extension loading, similiar to ".load" functionality in sqlite3, +extenions like sqlite3-pcre which enables REGEX function. In order to use this functionality +you must specify the library path (.so file) and the entry point which represents the function +to be called by the sqlite library (read more at sqlite +[load_extension](https://www.sqlite.org/capi3ref.html#sqlite3_load_extension) +official documentation), separated by ";" delimiter. The entry point paramter +can miss, so you won't need to use the delimitier in this case. + + +*By default, no extension is loaded.* + + +```opensips title="Set load_extension parameter" +... +modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so") +modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so;sqlite3_extension_init") +... +``` + + +#### busy_timeout (integer) + + +This parameter sets the default busy_handler for the SQLite library, that sleeps for +a specified amount of time when a table is locked. The handler will sleep multiple +times until at least the specified "busy_timeout" duration (in milliseconds) has been +reached. Setting this parameter to a value less than or equal to zero turns off all +busy handlers. (read more in the +[SQLite +official documentation](https://www.sqlite.org/capi3ref.html#sqlite3_busy_timeout)) + + +*Default value is 500.* + + +```opensips title="Set busy_timeout parameter" +... +modparam("db_sqlite", "busy_timeout", 5000) +... +``` + + +#### exec_pragma (string) + + +This parameter allows configuring an SQLite database with "PRAGMA" statements, (read +more in the [SQLite official documentation](https://sqlite.org/pragma.html)) +To use this functionality you must specify the exec_pragma parameter value as +"pragma-name=pragma-value". Multiple parameters with the same name can be specified, +and they will be executed one by one on every database connection. If a parameter has an +incorrect name or syntax, it will be ignored by SQLite without any error messages. + + +*By default, no PRAGMA statements are executed.* + + +```opensips title="Set exec_pragma parameter" +... +modparam("db_sqlite", "exec_pragma", "journal_mode=wal") +modparam("db_sqlite", "exec_pragma", "synchronous=normal") +modparam("db_sqlite", "exec_pragma", "cache_size=-2000") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Installation + + +Because it dependes on an external library, the sqlite module is not +compiled and installed by default. You can use one of the next options. + + +- edit the "Makefile" and remove "db_sqlite" from "excluded_modules" +list. Then follow the standard procedure to install OpenSIPS: +"make all; make install". +- from command line use: 'make all include_modules="db_sqlite"; +make install include_modules="db_sqlite"'. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_sqlite/dbase.c b/modules/db_sqlite/dbase.c index 7626c603d63..9fc588fe148 100644 --- a/modules/db_sqlite/dbase.c +++ b/modules/db_sqlite/dbase.c @@ -183,6 +183,7 @@ int db_sqlite_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op, if (db_sqlite_bind_values(CON_SQLITE_PS(_h), _v, _n) != SQLITE_OK) { LM_ERR("failed to bind values\n"); sqlite3_finalize(CON_SQLITE_PS(_h)); + CON_SQLITE_PS(_h) = NULL; return -1; } #endif @@ -192,10 +193,19 @@ int db_sqlite_query(const db_con_t* _h, const db_key_t* _k, const db_op_t* _op, } else { /* need to fetch now the total number of rows in query * because later won't have the query string */ - ret = CON_PS_ROWS(_h) = db_sqlite_get_query_rows(_h, &count_str, _v, _n); + ret = db_sqlite_get_query_rows(_h, &count_str, _v, _n); + if (ret >= 0) { + CON_PS_ROWS(_h) = ret; + ret = 0; + } } - if( ret < 0 && _r ){ - db_sqlite_free_result_internal(_h,*_r); + if( ret < 0 ) { + if (_r) { + db_sqlite_free_result_internal(_h,*_r); + } else if (CON_SQLITE_PS(_h)) { + sqlite3_finalize(CON_SQLITE_PS(_h)); + CON_SQLITE_PS(_h) = NULL; + } } return ret; @@ -384,10 +394,19 @@ int db_sqlite_raw_query(const db_con_t* _h, const str* _s, db_res_t** _r) } else { /* need to fetch now the total number of rows in query * because later won't have the query string */ - ret = CON_PS_ROWS(_h) = db_sqlite_get_query_rows(_h, &count_str, NULL, 0); + ret = db_sqlite_get_query_rows(_h, &count_str, NULL, 0); + if (ret >= 0) { + CON_PS_ROWS(_h) = ret; + ret = 0; + } } - if( ret < 0 && _r ){ - db_sqlite_free_result_internal(_h,*_r); + if( ret < 0 ){ + if (_r) { + db_sqlite_free_result_internal(_h,*_r); + } else if (CON_SQLITE_PS(_h)) { + sqlite3_finalize(CON_SQLITE_PS(_h)); + CON_SQLITE_PS(_h) = NULL; + } } return ret; diff --git a/modules/db_sqlite/doc/contributors.xml b/modules/db_sqlite/doc/contributors.xml deleted file mode 100644 index c76f6ca5cee..00000000000 --- a/modules/db_sqlite/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ionut Ionita (@ionutrazvanionita) - 82 - 28 - 3744 - 1276 - - - 2. - Razvan Crainea (@razvancrainea) - 19 - 17 - 115 - 42 - - - 3. - Alexey Vasilyev (@vasilevalex) - 13 - 9 - 165 - 96 - - - 4. - Liviu Chircu (@liviuchircu) - 12 - 10 - 32 - 60 - - - 5. - Jarrod Baumann (@jarrodb) - 5 - 3 - 7 - 4 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 3 - 2 - - - 7. - Alexandra Titoc - 4 - 2 - 2 - 3 - - - 8. - Aron Podrigal (@ar45) - 3 - 1 - 10 - 1 - - - 9. - Daniel Fussia - 3 - 1 - 4 - 22 - - - 10. - Maksym Sobolyev (@sobomax) - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: Bogdan-Andrei Iancu (@bogdan-iancu), Eric Green, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2015 - Jan 2025 - - - 2. - Alexey Vasilyev (@vasilevalex) - Dec 2024 - Dec 2024 - - - 3. - Liviu Chircu (@liviuchircu) - May 2016 - Sep 2024 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Eric Green - Aug 2020 - Aug 2020 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Apr 2015 - Feb 2017 - - - -
-All remaining contributors: Daniel Fussia, Jarrod Baumann (@jarrodb), Aron Podrigal (@ar45). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Alexey Vasilyev (@vasilevalex), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/db_sqlite/doc/db_sqlite.xml b/modules/db_sqlite/doc/db_sqlite.xml deleted file mode 100644 index bbe9060f684..00000000000 --- a/modules/db_sqlite/doc/db_sqlite.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - db_sqlite Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/db_sqlite/doc/db_sqlite_admin.xml b/modules/db_sqlite/doc/db_sqlite_admin.xml deleted file mode 100644 index aaa62f061b1..00000000000 --- a/modules/db_sqlite/doc/db_sqlite_admin.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module which provides SQLite support for OpenSIPS. - It implements the DB API defined in OpenSIPS. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - Also this module provides two ways of creating the query. One is to use - sqlite3_bind_* functions after opensips creates the prepared statement query. - The second one directly uses only sqlite3_snprintf function to print the - values into the opensips created query. In theory, the second one should - be faster and should allow you to make more queries to the database in - the same time, so by default this one will be active. You can use the - sqlite3_bind_* interface by simply uncommenting the SQLITE_BIND line - the Makefile. - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libsqlite3-dev - the development libraries of sqlite. - - - - -
-
-
- Exported Parameters -
- <varname>alloc_limit</varname> (integer) - - Since the library does not support a function to return the number of rows - in a query, this number is obtained using "count(*)" query. If we use multiple - processes there is the risk ,since "count(*)" query and the actual "select" - query, the number of rows in the result query to have changed, so realloc - will be needed if the number is bigger. Using alloc_limit - parameter you can specify the number with which the number of allocated rows in the - result is raised. - - - - Default value is 10. - - - - Set <varname>alloc_limit</varname> parameter - -... -modparam("db_sqlite", "alloc_limit", 25) -... - - -
-
- <varname>load_extension</varname> (string) - - This parameter enables extension loading, similiar to ".load" functionality in sqlite3, - extenions like sqlite3-pcre which enables REGEX function. In order to use this functionality - you must specify the library path (.so file) and the entry point which represents the function - to be called by the sqlite library (read more at sqlite - load_extension - official documentation), separated by ";" delimiter. The entry point paramter - can miss, so you won't need to use the delimitier in this case. - - - - By default, no extension is loaded. - - - - Set <varname>load_extension</varname> parameter - -... -modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so") -modparam("db_sqlite", "load_extension", "/usr/lib/sqlite3/pcre.so;sqlite3_extension_init") -... - - -
-
- <varname>busy_timeout</varname> (integer) - - This parameter sets the default busy_handler for the SQLite library, that sleeps for - a specified amount of time when a table is locked. The handler will sleep multiple - times until at least the specified "busy_timeout" duration (in milliseconds) has been - reached. Setting this parameter to a value less than or equal to zero turns off all - busy handlers. (read more in the - SQLite - official documentation) - - - - Default value is 500. - - - - Set <varname>busy_timeout</varname> parameter - -... -modparam("db_sqlite", "busy_timeout", 5000) -... - - -
-
- <varname>exec_pragma</varname> (string) - - This parameter allows configuring an SQLite database with "PRAGMA" statements, (read - more in the SQLite official documentation) - To use this functionality you must specify the exec_pragma parameter value as - "pragma-name=pragma-value". Multiple parameters with the same name can be specified, - and they will be executed one by one on every database connection. If a parameter has an - incorrect name or syntax, it will be ignored by SQLite without any error messages. - - - - By default, no PRAGMA statements are executed. - - - - Set <varname>exec_pragma</varname> parameter - -... -modparam("db_sqlite", "exec_pragma", "journal_mode=wal") -modparam("db_sqlite", "exec_pragma", "synchronous=normal") -modparam("db_sqlite", "exec_pragma", "cache_size=-2000") -... - - -
-
-
- Exported Functions - - No function exported to be used from configuration file. - -
-
- Installation - - Because it dependes on an external library, the sqlite module is not - compiled and installed by default. You can use one of the next options. - - - - - - edit the "Makefile" and remove "db_sqlite" from "excluded_modules" - list. Then follow the standard procedure to install &osips;: - "make all; make install". - - - - - - from command line use: 'make all include_modules="db_sqlite"; - make install include_modules="db_sqlite"'. - - - -
-
- diff --git a/modules/db_text/README b/modules/db_text/README deleted file mode 100644 index 26fd5a4bbcd..00000000000 --- a/modules/db_text/README +++ /dev/null @@ -1,517 +0,0 @@ -db_text Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Design of db_text engine - 1.1.2. Internal format of a db_text table - 1.1.3. Existing limitations - - 1.2. Dependencies - - 1.2.1. OpenSIPS modules - 1.2.2. External libraries or applications - - 1.3. Exported Parameters - - 1.3.1. db_mode (integer) - 1.3.2. buffer_size (integer) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. dbt_dump - 1.5.2. dbt_reload - - 1.6. Installation and Running - - 1.6.1. Using db_text with basic OpenSIPS - configuration - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Sample of a db_text table - 1.2. Minimal OpenSIPS location db_text table definition - 1.3. Minimal OpenSIPS subscriber db_text table example - 1.4. Set db_mode parameter - 1.5. Set buffer_size parameter - 1.6. Load the db_text module - 1.7. Definition of 'subscriber' table (one line) - 1.8. Definition of 'location' and 'aliases' tables (one line) - 1.9. Definition of 'version' table and sample records - 1.10. Configuration file - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements a simplified database engine based on - text files. It can be used by OpenSIPS DB interface instead of - other database module (like MySQL). - - The module is meant for use in demos or small devices that do - not support other DB modules. It keeps everything in memory and - if you deal with large amount of data you may run quickly out - of memory. Also, it has not implemented all standard database - facilities (like order by), it includes minimal functionality - to work properly with OpenSIPS - - NOTE: the timestamp is printed in an integer value from time_t - structure. If you use it in a system that cannot do this - conversion, it will fail (support for such situation is in - to-do list). - - NOTE: even when is in non-caching mode, the module does not - write back to hard drive after changes. In this mode, the - module checks if the corresponding file on disk has changed, - and reloads it. The write on disk happens at OpenSIPS shut - down. - -1.1.1. Design of db_text engine - - The db_text database system architecture: - * a database is represented by a directory in the local file - system. NOTE: when you use db_text in OpenSIPS, the - database URL for modules must be the path to the directory - where the table-files are located, prefixed by “text://”, - e.g., “text:///var/dbtext/opensips”. If there is no “/” - after “text://” then “CFG_DIR/” is inserted at the - beginning of the database path. So, either you provide an - absolute path to database directory or a relative one to - “CFG_DIR” directory. - * a table is represented by a text file inside database - directory. - -1.1.2. Internal format of a db_text table - - First line is the definition of the columns. Each column must - be declared as follows: - * the name of column must not include white spaces. - * the format of a column definition is: name(type,attr). - * between two column definitions must be a white space, e.g., - “first_name(str) last_name(str)”. - * the type of a column can be: - + int - integer numbers. - + double - real numbers with two decimals. - + str - strings with maximum size of 4KB. - * a column can have one of the attributes: - + auto - only for 'int' columns, the maximum value in - that column is incremented and stored in this field if - it is not provided in queries. - + null - accept null values in column fields. - + if no attribute is set, the fields of the column - cannot have null value. - * each other line is a row with data. The line ends with - “\n”. - * the fields are separated by “:”. - * no value between two ':' (or between ':' and start/end of a - row) means “null” value. - * next characters must be escaped in strings: “\n”, “\r”, - “\t”, “:”. - * 0 -- the zero value must be escaped too. - - Example 1.1. Sample of a db_text table -... -id(int,auto) name(str) flag(double) desc(str,null) -1:nick:0.34:a\tgood\: friend -2:cole:-3.75:colleague -3:bob:2.50: -... - - Example 1.2. Minimal OpenSIPS location db_text table definition -... -username(str) contact(str) expires(int) q(double) callid(str) cseq(int) -... - - Example 1.3. Minimal OpenSIPS subscriber db_text table example -... -username(str) password(str) ha1(str) domain(str) ha1b(str) -suser:supasswd:xxx:alpha.org:xxx -... - -1.1.3. Existing limitations - - This database interface don't support the data insertion with - default values. All such values specified in the database - template are ignored. So its advisable to specify all data for - a column at insertion operations. - -1.2. Dependencies - -1.2.1. OpenSIPS modules - - The next modules must be loaded before this module: - * none. - -1.2.2. External libraries or applications - - The next libraries or applications must be installed before - running OpenSIPS with this module: - * none. - -1.3. Exported Parameters - -1.3.1. db_mode (integer) - - Set caching mode (0) or non-caching mode (1). In caching mode, - data is loaded at startup. In non-caching mode, the module - check every time a table is requested whether the corresponding - file on disk has changed, and if yes, will re-load table from - file. - - Default value is “0”. - - Example 1.4. Set db_mode parameter -... -modparam("db_text", "db_mode", 1) -... - -1.3.2. buffer_size (integer) - - Size of the buffer used to read the text file. - - Default value is “4096”. - - Example 1.5. Set buffer_size parameter -... -modparam("db_text", "buffer_size", 8192) -... - -1.4. Exported Functions - - None. - -1.5. Exported MI Functions - -1.5.1. dbt_dump - - Write back to hard drive modified tables. - - Name: dbt_dump. - - Parameters: none - - MI FIFO Command Format: -opensips-cli -x mi dbt_dump - -1.5.2. dbt_reload - - Causes db_text module to reload cached tables from disk. - Depending on parameters it could be a whole cache or a - specified database or a single table. If any table cannot be - reloaded from disk - the old version preserved and error - reported. - - Name: dbt_reload. - - Parameters: - * db_name (optional) - database name to reload. - * table_name (optional, but cannot be present without the - db_name parameter) - specific table to reload. - - MI FIFO Command Format: -opensips-cli -x mi dbt_reload - -opensips-cli -x mi dbt_reload /path/to/dbtext/database - -opensips-cli -x mi dbt_reload /path/to/dbtext/database table_name - -1.6. Installation and Running - - Compile the module and load it instead of mysql or other DB - modules. - - REMINDER: when you use db_text in OpenSIPS, the database URL - for modules must be the path to the directory where the - table-files are located, prefixed by “text://”, e.g., - “text:///var/dbtext/opensips”. If there is no “/” after - “text://” then “CFG_DIR/” is inserted at the beginning of the - database path. So, either you provide an absolute path to - database directory or a relative one to “CFG_DIR” directory. - - Example 1.6. Load the db_text module -... -loadmodule "/path/to/opensips/modules/db_text.so" -... -modparam("module_name", "database_URL", "text:///path/to/dbtext/database -") -... - -1.6.1. Using db_text with basic OpenSIPS configuration - - Here are the definitions for most important table as well as a - basic configuration file to use db_text with OpenSIPS. The - table structures may change in time and you will have to adjust - next examples. - - You have to populate the table 'subscriber' by hand with user - profiles in order to have authentication. To use with the given - configuration file, the table files must be placed in the - '/tmp/opensipsdb' directory. - - Example 1.7. Definition of 'subscriber' table (one line) -... -username(str) domain(str) password(str) first_name(str) last_name(str) p -hone(str) email_address(str) datetime_created(int) datetime_modified(int -) confirmation(str) flag(str) sendnotification(str) greeting(str) ha1(st -r) ha1b(str) perms(str) allow_find(str) timezone(str,null) rpid(str,null -) -... - - Example 1.8. Definition of 'location' and 'aliases' tables (one - line) -... -username(str) domain(str,null) contact(str,null) received(str) expires(i -nt,null) q(double,null) callid(str,null) cseq(int,null) last_modified(st -r) flags(int) user_agent(str) socket(str) -... - - Example 1.9. Definition of 'version' table and sample records -... -table_name(str) table_version(int) -subscriber:3 -location:6 -aliases:6 -... - - Example 1.10. Configuration file -... -# -# simple quick-start config script with dbtext -# - -# ----------- global configuration parameters ------------------------ - -#debug_mode=yes -udp_workers=4 - -check_via=no # (cmd. line: -v) -dns=no # (cmd. line: -r) -rev_dns=no # (cmd. line: -R) - -socket=udp:10.100.100.1:5060 - -# ------------------ module loading ---------------------------------- - -# use dbtext database -loadmodule "modules/dbtext/dbtext.so" - -loadmodule "modules/sl/sl.so" -loadmodule "modules/tm/tm.so" -loadmodule "modules/rr/rr.so" -loadmodule "modules/maxfwd/maxfwd.so" -loadmodule "modules/usrloc/usrloc.so" -loadmodule "modules/registrar/registrar.so" -loadmodule "modules/textops/textops.so" -loadmodule "modules/textops/mi_fifo.so" - -# modules for digest authentication -loadmodule "modules/auth/auth.so" -loadmodule "modules/auth_db/auth_db.so" - -# ----------------- setting module-specific parameters --------------- - -# -- mi_fifo params -- - -modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") - -# -- usrloc params -- - -# use dbtext database for persistent storage -modparam("usrloc", "db_mode", 2) -modparam("usrloc|auth_db", "db_url", "text:///tmp/opensipsdb") - -# -- auth params -- -# -modparam("auth_db", "calculate_ha1", 1) -modparam("auth_db", "password_column", "password") -modparam("auth_db", "user_column", "username") -modparam("auth_db", "domain_column", "domain") - -# ------------------------- request routing logic ------------------- - -# main routing logic - -route{ - # initial sanity checks -- messages with - # max_forwards==0, or excessively long requests - if (!mf_process_maxfwd_header("10")) { - sl_send_reply(483,"Too Many Hops"); - exit; - }; - if ($ml >= 65535 ) { - sl_send_reply(513, "Message too big"); - exit; - }; - - # we record-route all messages -- to make sure that - # subsequent messages will go through our proxy; that's - # particularly good if upstream and downstream entities - # use different transport protocol - if (!$rm=="REGISTER") record_route(); - - # subsequent messages withing a dialog should take the - # path determined by record-routing - if (loose_route()) { - # mark routing logic in request - append_hf("P-hint: rr-enforced\r\n"); - route(1); - exit; - }; - - if (!is_myself("$rd")) { - # mark routing logic in request - append_hf("P-hint: outbound\r\n"); - route(1); - exit; - }; - - # if the request is for other domain use UsrLoc - # (in case, it does not work, use the following command - # with proper names and addresses in it) - if (is_myself("$rd")) { - if ($rm=="REGISTER") { - # digest authentication - if (!www_authorize("", "subscriber")) { - www_challenge("", "0"); - exit; - }; - - save("location"); - exit; - }; - - lookup("aliases"); - if (!is_myself("$rd")) { - append_hf("P-hint: outbound alias\r\n"); - route(1); - exit; - }; - - # native SIP destinations are handled using our USRLOC DB - if (!lookup("location")) { - sl_send_reply(404, "Not Found"); - exit; - }; - }; - append_hf("P-hint: usrloc applied\r\n"); - route(1); -} - -route[1] -{ - # send it out now; use stateful forwarding as it works reliably - # even for UDP2TCP - if (!t_relay()) { - sl_reply_error(); - }; -} - - -... - -Chapter 2. Developer Guide - - Once you have the module loaded, you can use the API specified - by OpenSIPS DB interface. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 135 59 6126 1441 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 41 32 310 309 - 3. Henning Westerholt (@henningw) 25 15 252 410 - 4. Razvan Crainea (@razvancrainea) 23 19 123 97 - 5. Liviu Chircu (@liviuchircu) 21 18 71 110 - 6. Jan Janak (@janakj) 11 7 124 106 - 7. Ovidiu Sas (@ovidiusas) 8 6 105 20 - 8. Vlad Patrascu (@rvlad-patrascu) 8 6 94 49 - 9. Alexandra Titoc 5 3 13 6 - 10. Sergey Khripchenko (@shripchenko) 5 2 185 2 - - All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), - Ionut Ionita (@ionutrazvanionita), Maksym Sobolyev (@sobomax), - Konstantin Bokarius, Razvan Pistolea, Chris Heiser, Norman - Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert - Schubert, Dusan Klinec (@ph4r05), Andrei Pelinescu-Onciul. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Razvan Crainea (@razvancrainea) Oct 2011 - Jul 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Ovidiu Sas (@ovidiusas) Dec 2012 - Mar 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Dec 2021 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Nov 2003 - Apr 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 10. Sergey Khripchenko (@shripchenko) Aug 2015 - Aug 2015 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Razvan Pistolea, Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Chris - Heiser, Edson Gellert Schubert, Norman Brandinger (@NormB), Jan - Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Andrei - Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Ovidiu Sas (@ovidiusas), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad - Patrascu (@rvlad-patrascu), Sergey Khripchenko (@shripchenko), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw). - - Documentation Copyrights: - - Copyright © 2003-2004 FhG FOKUS diff --git a/modules/db_text/README.md b/modules/db_text/README.md new file mode 100644 index 00000000000..37aa2a84561 --- /dev/null +++ b/modules/db_text/README.md @@ -0,0 +1,334 @@ +--- +title: "db_text Module" +description: "The module implements a simplified database engine based on text files. It can be used by OpenSIPS DB interface instead of other database module (like MySQL)." +--- + +## Admin Guide + + +### Overview + + +The module implements a simplified database engine based on text +files. It can be used by OpenSIPS DB interface instead of other +database module (like MySQL). + + +The module is meant for use in demos or small devices that do not +support other DB modules. It keeps everything in memory and if you deal +with large amount of data you may run quickly out of memory. Also, it +has not implemented all standard database facilities (like order by), +it includes minimal functionality to work properly with OpenSIPS + + +> [!NOTE] +> The timestamp is printed in an integer value from time_t +> structure. If you use it in a system that cannot do this conversion, +> it will fail (support for such situation is in to-do list). + + +> [!NOTE] +> Even when is in non-caching mode, the module does not write +> back to hard drive after changes. In this mode, the module checks if +> the corresponding file on disk has changed, and reloads it. The write +> on disk happens at OpenSIPS shut down. + + +#### Design of db_text engine + + +The db_text database system architecture: + + +- a database is represented by a directory in the local file +system. +> [!NOTE] +> When you use *db_text* in OpenSIPS, +> the database URL for modules must be the path to the directory +> where the table-files are located, prefixed by +> "text://", e.g., +> "text:///var/dbtext/opensips". If there is no +> "/" after "text://" then +> "CFG_DIR/" is inserted at the beginning of the +> database path. So, either you provide an absolute path to +> database directory or a relative one to "CFG_DIR" +> directory. +- a table is represented by a text file inside database directory. + + +#### Internal format of a db_text table + + +First line is the definition of the columns. Each column must be +declared as follows: + + +- the name of column must not include white spaces. +- the format of a column definition is: +*name(type,attr)*. +- between two column definitions must be a white space, e.g., +"first_name(str) last_name(str)". +- the type of a column can be: + - *int* - integer numbers. + - *double* - real numbers with two + decimals. + - *str* - strings with maximum size of 4KB. +- a column can have one of the attributes: + - *auto* - only for 'int' columns, + the maximum value in that column is incremented and stored + in this field if it is not provided in queries. + - *null* - accept null values in column + fields. + + if no attribute is set, the fields of the column cannot have + null value. +- each other line is a row with data. The line ends with +"\n". +- the fields are separated by ":". +- no value between two ':' (or between ':' and start/end of a row) +means "null" value. +- next characters must be escaped in strings: "\n", +"\r", "\t", ":". +- *0* -- the zero value must be escaped too. + + +```c title="Sample of a db_text table" +... +id(int,auto) name(str) flag(double) desc(str,null) +1:nick:0.34:a\tgood\: friend +2:cole:-3.75:colleague +3:bob:2.50: +... +``` + + +```c title="Minimal OpenSIPS location db_text table definition" +... +username(str) contact(str) expires(int) q(double) callid(str) cseq(int) +... +``` + + +```c title="Minimal OpenSIPS subscriber db_text table example" +... +username(str) password(str) ha1(str) domain(str) ha1b(str) +suser:supasswd:xxx:alpha.org:xxx +... +``` + + +#### Existing limitations + + +This database interface don't support the data insertion with +default values. All such values specified in the database template +are ignored. So its advisable to specify all data for a column at +insertion operations. + + +### Dependencies + + +#### OpenSIPS modules + + +The next modules must be loaded before this module: + + +- *none*. + + +#### External libraries or applications + + +The next libraries or applications must be installed before running +OpenSIPS with this module: + + +- *none*. + + +### Exported Parameters + + +#### db_mode (integer) + + +Set caching mode (0) or non-caching mode (1). In caching mode, data +is loaded at startup. In non-caching mode, the module check every time +a table is requested whether the corresponding file on disk has +changed, and if yes, will re-load table from file. + + +*Default value is "0".* + + +```opensips title="Set db_mode parameter" +... +modparam("db_text", "db_mode", 1) +... +``` + + +#### buffer_size (integer) + + +Size of the buffer used to read the text file. + + +*Default value is "4096".* + + +```opensips title="Set buffer_size parameter" +... +modparam("db_text", "buffer_size", 8192) +... +``` + + +### Exported Functions + + +*None*. + + +### Exported MI Functions + + +#### dbt_dump + + +Write back to hard drive modified tables. + + +Name: *dbt_dump*. + + +Parameters: none + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dbt_dump +``` + + +#### dbt_reload + + +Causes db_text module to reload cached tables from disk. +Depending on parameters it could be a whole cache or a specified +database or a single table. +If any table cannot be reloaded from disk - the old version +preserved and error reported. + + +Name: *dbt_reload*. + + +Parameters: + + +- *db_name* (optional) - database name to reload. +- *table_name* (optional, but cannot be present +without the db_name parameter) - specific table to reload. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dbt_reload +``` + + +```bash +opensips-cli -x mi dbt_reload /path/to/dbtext/database +``` + + +```bash +opensips-cli -x mi dbt_reload /path/to/dbtext/database table_name +``` + + +### Installation and Running + + +Compile the module and load it instead of mysql or other DB modules. + + +> [!WARNING] +> When you use *db_text* in OpenSIPS, +> the database URL for modules must be the path to the directory +> where the table-files are located, prefixed by +> "text://", e.g., +> "text:///var/dbtext/opensips". If there is no "/" +> after "text://" then "CFG_DIR/" is inserted +> at the beginning of the database path. So, either you provide an +> absolute path to database directory or a relative one to +> "CFG_DIR" directory. + + +```opensips title="Load the db_text module" +... +loadmodule "/path/to/opensips/modules/db_text.so" +... +modparam("module_name", "database_URL", "text:///path/to/dbtext/database") +... +``` + + +#### Using db_text with basic OpenSIPS configuration + + +Here are the definitions for most important table as well as a basic +configuration file to use db_text with OpenSIPS. The table structures +may change in time and you will have to adjust next examples. + + +You have to populate the table 'subscriber' by hand with user profiles +in order to have authentication. To use with the given configuration +file, the table files must be placed in the '/tmp/opensipsdb' directory. + + +```c title="Definition of 'subscriber' table (one line)" +... +username(str) domain(str) password(str) first_name(str) last_name(str) phone(str) email_address(str) datetime_created(int) datetime_modified(int) confirmation(str) flag(str) sendnotification(str) greeting(str) ha1(str) ha1b(str) perms(str) allow_find(str) timezone(str,null) rpid(str,null) +... +``` + + +```c title="Definition of 'location' and 'aliases' tables (one line)" +... +username(str) domain(str,null) contact(str,null) received(str) expires(int,null) q(double,null) callid(str,null) cseq(int,null) last_modified(str) flags(int) user_agent(str) socket(str) +... +``` + + +```c title="Definition of 'version' table and sample records" +... +table_name(str) table_version(int) +subscriber:3 +location:6 +aliases:6 +... +``` + +## Samples + +[samples](./samples/samples.md "include") + + +## Developer Guide + + +Once you have the module loaded, you can use the API specified by OpenSIPS DB +interface. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_text/doc/contributors.xml b/modules/db_text/doc/contributors.xml deleted file mode 100644 index 4e6831cc38b..00000000000 --- a/modules/db_text/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 135 - 59 - 6126 - 1441 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 41 - 32 - 310 - 309 - - - 3. - Henning Westerholt (@henningw) - 25 - 15 - 252 - 410 - - - 4. - Razvan Crainea (@razvancrainea) - 23 - 19 - 123 - 97 - - - 5. - Liviu Chircu (@liviuchircu) - 21 - 18 - 71 - 110 - - - 6. - Jan Janak (@janakj) - 11 - 7 - 124 - 106 - - - 7. - Ovidiu Sas (@ovidiusas) - 8 - 6 - 105 - 20 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 8 - 6 - 94 - 49 - - - 9. - Alexandra Titoc - 5 - 3 - 13 - 6 - - - 10. - Sergey Khripchenko (@shripchenko) - 5 - 2 - 185 - 2 - - - -
-All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), Ionut Ionita (@ionutrazvanionita), Maksym Sobolyev (@sobomax), Konstantin Bokarius, Razvan Pistolea, Chris Heiser, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Dusan Klinec (@ph4r05), Andrei Pelinescu-Onciul. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Oct 2011 - Jul 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Ovidiu Sas (@ovidiusas) - Dec 2012 - Mar 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Dec 2021 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Nov 2003 - Apr 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 10. - Sergey Khripchenko (@shripchenko) - Aug 2015 - Aug 2015 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Razvan Pistolea, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Chris Heiser, Edson Gellert Schubert, Norman Brandinger (@NormB), Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Andrei Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ovidiu Sas (@ovidiusas), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Sergey Khripchenko (@shripchenko), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw). -
- -
diff --git a/modules/db_text/doc/db_text.xml b/modules/db_text/doc/db_text.xml deleted file mode 100644 index f34b6f308be..00000000000 --- a/modules/db_text/doc/db_text.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - db_text Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003-2004 &fhg; - diff --git a/modules/db_text/doc/db_text_admin.xml b/modules/db_text/doc/db_text_admin.xml deleted file mode 100644 index fb894366a8d..00000000000 --- a/modules/db_text/doc/db_text_admin.xml +++ /dev/null @@ -1,411 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module implements a simplified database engine based on text - files. It can be used by &osips; DB interface instead of other - database module (like MySQL). - - - The module is meant for use in demos or small devices that do not - support other DB modules. It keeps everything in memory and if you deal - with large amount of data you may run quickly out of memory. Also, it - has not implemented all standard database facilities (like order by), - it includes minimal functionality to work properly with &osips; - - - NOTE: the timestamp is printed in an integer value from time_t - structure. If you use it in a system that cannot do this conversion, - it will fail (support for such situation is in to-do list). - - - NOTE: even when is in non-caching mode, the module does not write - back to hard drive after changes. In this mode, the module checks if - the corresponding file on disk has changed, and reloads it. The write - on disk happens at OpenSIPS shut down. - -
- Design of db_text engine - - The db_text database system architecture: - - - - a database is represented by a directory in the local file - system. - NOTE: when you use db_text in &osips;, - the database URL for modules must be the path to the directory - where the table-files are located, prefixed by - text://, e.g., - text:///var/dbtext/opensips. If there is no - / after text:// then - CFG_DIR/ is inserted at the beginning of the - database path. So, either you provide an absolute path to - database directory or a relative one to CFG_DIR - directory. - - - - - a table is represented by a text file inside database directory. - - - - -
-
- Internal format of a db_text table - - First line is the definition of the columns. Each column must be - declared as follows: - - - - the name of column must not include white spaces. - - - - - the format of a column definition is: - name(type,attr). - - - - - between two column definitions must be a white space, e.g., - first_name(str) last_name(str). - - - - - the type of a column can be: - - - - int - integer numbers. - - - - - double - real numbers with two - decimals. - - - - - str - strings with maximum size of 4KB. - - - - - - - - a column can have one of the attributes: - - - - auto - only for 'int' columns, - the maximum value in that column is incremented and stored - in this field if it is not provided in queries. - - - - - null - accept null values in column - fields. - - - - - if no attribute is set, the fields of the column cannot have - null value. - - - - - - - - each other line is a row with data. The line ends with - \n. - - - - - the fields are separated by :. - - - - - no value between two ':' (or between ':' and start/end of a row) - means null value. - - - - - next characters must be escaped in strings: \n, - \r, \t, :. - - - - - 0 -- the zero value must be escaped too. - - - - - - Sample of a db_text table - -... -id(int,auto) name(str) flag(double) desc(str,null) -1:nick:0.34:a\tgood\: friend -2:cole:-3.75:colleague -3:bob:2.50: -... - - - - Minimal &osips; location db_text table definition - -... -username(str) contact(str) expires(int) q(double) callid(str) cseq(int) -... - - - - Minimal &osips; subscriber db_text table example - -... -username(str) password(str) ha1(str) domain(str) ha1b(str) -suser:supasswd:xxx:alpha.org:xxx -... - - -
-
- Existing limitations - This database interface don't support the data insertion with - default values. All such values specified in the database template - are ignored. So its advisable to specify all data for a column at - insertion operations. - -
-
-
- Dependencies -
- &osips; modules - - The next modules must be loaded before this module: - - - - none. - - - - -
-
- External libraries or applications - - The next libraries or applications must be installed before running - &osips; with this module: - - - - none. - - - - -
-
-
- Exported Parameters -
- <varname>db_mode</varname> (integer) - - Set caching mode (0) or non-caching mode (1). In caching mode, data - is loaded at startup. In non-caching mode, the module check every time - a table is requested whether the corresponding file on disk has - changed, and if yes, will re-load table from file. - - - - Default value is 0. - - - - Set <varname>db_mode</varname> parameter - -... -modparam("db_text", "db_mode", 1) -... - - -
-
- <varname>buffer_size</varname> (integer) - - Size of the buffer used to read the text file. - - - - Default value is 4096. - - - - Set <varname>buffer_size</varname> parameter - -... -modparam("db_text", "buffer_size", 8192) -... - - -
-
-
- Exported Functions - - None. - -
-
- Exported MI Functions -
- <varname>dbt_dump</varname> - - Write back to hard drive modified tables. - - - Name: dbt_dump. - - Parameters: none - - MI FIFO Command Format: - - -opensips-cli -x mi dbt_dump - -
-
- <varname>dbt_reload</varname> - - Causes db_text module to reload cached tables from disk. - Depending on parameters it could be a whole cache or a specified - database or a single table. - If any table cannot be reloaded from disk - the old version - preserved and error reported. - - - Name: dbt_reload. - - Parameters: - - - db_name (optional) - database name to reload. - - - table_name (optional, but cannot be present - without the db_name parameter) - specific table to reload. - - - - MI FIFO Command Format: - - -opensips-cli -x mi dbt_reload - - -opensips-cli -x mi dbt_reload /path/to/dbtext/database - - -opensips-cli -x mi dbt_reload /path/to/dbtext/database table_name - -
-
-
- Installation and Running - - Compile the module and load it instead of mysql or other DB modules. - - - REMINDER: when you use db_text in &osips;, - the database URL for modules must be the path to the directory - where the table-files are located, prefixed by - text://, e.g., - text:///var/dbtext/opensips. If there is no / - after text:// then CFG_DIR/ is inserted - at the beginning of the database path. So, either you provide an - absolute path to database directory or a relative one to - CFG_DIR directory. - - - Load the db_text module - -... -loadmodule "/path/to/opensips/modules/db_text.so" -... -modparam("module_name", "database_URL", "text:///path/to/dbtext/database") -... - - -
- Using db_text with basic &osips; configuration - - Here are the definitions for most important table as well as a basic - configuration file to use db_text with &osips;. The table structures - may change in time and you will have to adjust next examples. - - - You have to populate the table 'subscriber' by hand with user profiles - in order to have authentication. To use with the given configuration - file, the table files must be placed in the '/tmp/opensipsdb' directory. - - - Definition of 'subscriber' table (one line) - -... -username(str) domain(str) password(str) first_name(str) last_name(str) phone(str) email_address(str) datetime_created(int) datetime_modified(int) confirmation(str) flag(str) sendnotification(str) greeting(str) ha1(str) ha1b(str) perms(str) allow_find(str) timezone(str,null) rpid(str,null) -... - - - - Definition of 'location' and 'aliases' tables (one line) - -... -username(str) domain(str,null) contact(str,null) received(str) expires(int,null) q(double,null) callid(str,null) cseq(int,null) last_modified(str) flags(int) user_agent(str) socket(str) -... - - - - Definition of 'version' table and sample records - -... -table_name(str) table_version(int) -subscriber:3 -location:6 -aliases:6 -... - - - - Configuration file - -... -&dbtextsercfg; -... - - -
-
-
- diff --git a/modules/db_text/doc/db_text_devel.xml b/modules/db_text/doc/db_text_devel.xml deleted file mode 100644 index 6f4933c7dc1..00000000000 --- a/modules/db_text/doc/db_text_devel.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - &develguide; - - Once you have the module loaded, you can use the API specified by &osips; DB - interface. - - - diff --git a/modules/db_text/doc/db_text.cfg b/modules/db_text/samples/db_text.cfg similarity index 100% rename from modules/db_text/doc/db_text.cfg rename to modules/db_text/samples/db_text.cfg diff --git a/modules/db_text/samples/samples.md b/modules/db_text/samples/samples.md new file mode 100644 index 00000000000..cae2869dfdc --- /dev/null +++ b/modules/db_text/samples/samples.md @@ -0,0 +1,4 @@ +### OpenSIPS Config Script - DB_TEXT Usage + +[db_text.cfg](./db_text.cfg "include") + diff --git a/modules/db_unixodbc/README b/modules/db_unixodbc/README deleted file mode 100644 index e38d43dc432..00000000000 --- a/modules/db_unixodbc/README +++ /dev/null @@ -1,229 +0,0 @@ -unixodbc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. auto_reconnect (int) - 1.3.2. use_escape_common (int) - - 1.4. Exported Functions - 1.5. Installation and Running - - 1.5.1. Installing - 1.5.2. Configuring and Running - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set the “auto_reconnect” parameter - 1.2. Set the “use_escape_common” parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module allows to use the unixodbc package with OpenSIPS. - It have been tested with mysql and the odbc connector, but it - should work also with other database. The auth_db module works. - - For more information, see the http://www.unixodbc.org/ project - web page. - - To see what DB engines can be used via unixodbc, look at - http://www.unixodbc.org/drivers.html. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. auto_reconnect (int) - - Turns on or off the auto_reconnect mode. - - Default value is “1”, this means it is enabled. - - Example 1.1. Set the “auto_reconnect” parameter -... -modparam("db_unixodbc", "auto_reconnect", 0) -... - -1.3.2. use_escape_common (int) - - Escape values in query using internal escape_common() function. - It escapes single quote ''', double quote '"', backslash '\', - and NULL characters. - - You should enable this parameter if you know that the ODBC - driver considers the above characters as special (for marking - begin and end of a value, escape other characters ...). It - prevents against SQL injection. - - Default value is “0” (0 = disabled; 1 = enabled). - - Example 1.2. Set the “use_escape_common” parameter -... -modparam("db_unixodbc", "use_escape_common", 1) -... - -1.4. Exported Functions - - NONE - -1.5. Installation and Running - -1.5.1. Installing - - Prerequirement: you should first install unixodbc (or another - program that implements the odbc standard, such iodbc), your - database, and the right connector. Set the DSN in the odbc.ini - file and the connector drivers in the odbcinst.ini file. - -1.5.2. Configuring and Running - - In the opensips.conf file, add the line: -.... -loadmodule "/usr/local/lib/opensips/modules/db_unixodbc.so" -.... - - You should also uncomment this: -.... -loadmodule "/usr/local/lib/opensips/modules/auth.so" -loadmodule "/usr/local/lib/opensips/modules/auth_db.so" -modparam("usrloc", "db_mode", 2) -modparam("auth_db", "calculate_ha1", yes) -modparam("auth_db", "password_column", "password") -.... - - and setting the DSN specified in the odbc.ini, inserting this - with the url adding this line: -.... -modparam("usrloc|auth_db", "db_url", - "unixodbc://opensips:opensipsrw@localhost/my_dsn") -.... - - replacing my_dsn with the correct value. - - HINT: if unixodbc don't want to connect to mysql server, try - restarting mysql server with: -shell>safe_mysqld --user=mysql --socket=/var/lib/mysql/mysql.sock - - The connector search the socket in /var/lib/mysql/mysql.sock - and not in /tmp/mysql.sock - -Chapter 2. Developer Guide - - The module implements the OpenSIPS DB API, in order to be used - by other modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Henning Westerholt (@henningw) 45 22 385 1129 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 44 31 617 418 - 3. Marco Lorrai 24 1 2660 0 - 4. Daniel-Constantin Mierla (@miconda) 20 15 221 140 - 5. Liviu Chircu (@liviuchircu) 19 11 136 315 - 6. Razvan Crainea (@razvancrainea) 11 9 64 26 - 7. Peter Lemenkov (@lemenkov) 4 2 8 7 - 8. Maksym Sobolyev (@sobomax) 4 2 4 4 - 9. Vlad Patrascu (@rvlad-patrascu) 4 2 3 3 - 10. Anca Vamanu 4 1 89 103 - - All remaining contributors: Elena-Ramona Modroiu, Anonymous, - Konstantin Bokarius, Alex Massover, Razvan Pistolea, Norman - Brandinger (@NormB), Edson Gellert Schubert, Vlad Paiu - (@vladpaiu), Carsten Bock. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Oct 2011 - Jul 2025 - 2. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2005 - Apr 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Vlad Paiu (@vladpaiu) Jul 2011 - Jul 2011 - 8. Razvan Pistolea Jul 2009 - Jul 2009 - 9. Alex Massover Mar 2009 - Mar 2009 - 10. Carsten Bock May 2008 - May 2008 - - All remaining contributors: Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Anca Vamanu, Elena-Ramona Modroiu, Norman - Brandinger (@NormB), Anonymous, Marco Lorrai. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona - Modroiu, Marco Lorrai. - - Documentation Copyrights: - - Copyright © 2005-2006 Marco Lorrai diff --git a/modules/db_unixodbc/README.md b/modules/db_unixodbc/README.md new file mode 100644 index 00000000000..00c39330bdb --- /dev/null +++ b/modules/db_unixodbc/README.md @@ -0,0 +1,172 @@ +--- +title: "unixodbc Module" +description: "This module allows to use the unixodbc package with OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module allows to use the unixodbc package with OpenSIPS. It have been +tested with mysql and the odbc connector, but it should work also with +other database. The auth_db module works. + + +For more information, see the [http://www.unixodbc.org/](http://www.unixodbc.org/) project web page. + + +To see what DB engines can be used via unixodbc, look at +[http://www.unixodbc.org/drivers.html](http://www.unixodbc.org/drivers.html). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### auto_reconnect (int) + + +Turns on or off the auto_reconnect mode. + + +*Default value is "1", this means it is enabled.* + + +```opensips title="Set the 'auto_reconnect' parameter" +... +modparam("db_unixodbc", "auto_reconnect", 0) +... +``` + + +#### use_escape_common (int) + + +Escape values in query using internal escape_common() function. +It escapes single quote ''', double quote '"', backslash '\', +and NULL characters. + + +You should enable this parameter if you know that the ODBC driver +considers the above characters as special (for marking begin and end +of a value, escape other characters ...). It prevents against SQL +injection. + + +*Default value is "0" (0 = disabled; 1 = enabled).* + + +```opensips title="Set the 'use_escape_common' parameter" +... +modparam("db_unixodbc", "use_escape_common", 1) +... +``` + + +### Exported Functions + + +NONE + + +### Installation and Running + + +#### Installing + + +Prerequirement: you should first install unixodbc (or another program that +implements the odbc standard, such iodbc), your database, and the right +connector. Set the DSN in the odbc.ini file and the connector drivers in +the odbcinst.ini file. + + +#### Configuring and Running + + +In the opensips.conf file, add the line: + + +```opensips +.... +loadmodule "/usr/local/lib/opensips/modules/db_unixodbc.so" +.... +``` + + +You should also uncomment this: + + +```opensips +.... +loadmodule "/usr/local/lib/opensips/modules/auth.so" +loadmodule "/usr/local/lib/opensips/modules/auth_db.so" +modparam("usrloc", "db_mode", 2) +modparam("auth_db", "calculate_ha1", yes) +modparam("auth_db", "password_column", "password") +.... +``` + + +and setting the DSN specified in the odbc.ini, inserting this with the +url adding this line: + + +```opensips +.... +modparam("usrloc|auth_db", "db_url", + "unixodbc://opensips:opensipsrw@localhost/my_dsn") +.... +``` + + +replacing my_dsn with the correct value. + + +> [!TIP] +> If unixodbc don't want to connect to mysql server, try restarting +> mysql server with: + + +```bash +shell>safe_mysqld --user=mysql --socket=/var/lib/mysql/mysql.sock +``` + + +The connector search the socket in /var/lib/mysql/mysql.sock and not +in /tmp/mysql.sock + + +## Developer Guide + + +The module implements the OpenSIPS DB API, in order to +be used by other modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_unixodbc/doc/contributors.xml b/modules/db_unixodbc/doc/contributors.xml deleted file mode 100644 index 7f558d7e678..00000000000 --- a/modules/db_unixodbc/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Henning Westerholt (@henningw) - 45 - 22 - 385 - 1129 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 44 - 31 - 617 - 418 - - - 3. - Marco Lorrai - 24 - 1 - 2660 - 0 - - - 4. - Daniel-Constantin Mierla (@miconda) - 20 - 15 - 221 - 140 - - - 5. - Liviu Chircu (@liviuchircu) - 19 - 11 - 136 - 315 - - - 6. - Razvan Crainea (@razvancrainea) - 11 - 9 - 64 - 26 - - - 7. - Peter Lemenkov (@lemenkov) - 4 - 2 - 8 - 7 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 4 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 3 - 3 - - - 10. - Anca Vamanu - 4 - 1 - 89 - 103 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Anonymous, Konstantin Bokarius, Alex Massover, Razvan Pistolea, Norman Brandinger (@NormB), Edson Gellert Schubert, Vlad Paiu (@vladpaiu), Carsten Bock. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Oct 2011 - Jul 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2005 - Apr 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Vlad Paiu (@vladpaiu) - Jul 2011 - Jul 2011 - - - 8. - Razvan Pistolea - Jul 2009 - Jul 2009 - - - 9. - Alex Massover - Mar 2009 - Mar 2009 - - - 10. - Carsten Bock - May 2008 - May 2008 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Anca Vamanu, Elena-Ramona Modroiu, Norman Brandinger (@NormB), Anonymous, Marco Lorrai. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona Modroiu, Marco Lorrai. -
- -
diff --git a/modules/db_unixodbc/doc/db_unixodbc.xml b/modules/db_unixodbc/doc/db_unixodbc.xml deleted file mode 100644 index 9fba33b817f..00000000000 --- a/modules/db_unixodbc/doc/db_unixodbc.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - unixodbc Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2006 Marco Lorrai - - diff --git a/modules/db_unixodbc/doc/db_unixodbc_admin.xml b/modules/db_unixodbc/doc/db_unixodbc_admin.xml deleted file mode 100644 index 5df38620ee0..00000000000 --- a/modules/db_unixodbc/doc/db_unixodbc_admin.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module allows to use the unixodbc package with &osips;. It have been - tested with mysql and the odbc connector, but it should work also with - other database. The auth_db module works. - - - For more information, see the - http://www.unixodbc.org/ project web page. - - - To see what DB engines can be used via unixodbc, look at - - http://www.unixodbc.org/drivers.html. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>auto_reconnect</varname> (int) - - Turns on or off the auto_reconnect mode. - - - - Default value is 1, this means it is enabled. - - - - Set the <quote>auto_reconnect</quote> parameter - -... -modparam("db_unixodbc", "auto_reconnect", 0) -... - - -
- -
- <varname>use_escape_common</varname> (int) - - Escape values in query using internal escape_common() function. - It escapes single quote ''', double quote '"', backslash '\', - and NULL characters. - - - You should enable this parameter if you know that the ODBC driver - considers the above characters as special (for marking begin and end - of a value, escape other characters ...). It prevents against SQL - injection. - - - - Default value is 0 (0 = disabled; 1 = enabled). - - - - Set the <quote>use_escape_common</quote> parameter - -... -modparam("db_unixodbc", "use_escape_common", 1) -... - - -
-
- -
- Exported Functions - - NONE - -
- -
- Installation and Running - -
- Installing - - Prerequirement: you should first install unixodbc (or another program that - implements the odbc standard, such iodbc), your database, and the right - connector. Set the DSN in the odbc.ini file and the connector drivers in - the odbcinst.ini file. - -
- -
- Configuring and Running - - In the opensips.conf file, add the line: - - -.... -loadmodule "/usr/local/lib/opensips/modules/db_unixodbc.so" -.... - - - You should also uncomment this: - - -.... -loadmodule "/usr/local/lib/opensips/modules/auth.so" -loadmodule "/usr/local/lib/opensips/modules/auth_db.so" -modparam("usrloc", "db_mode", 2) -modparam("auth_db", "calculate_ha1", yes) -modparam("auth_db", "password_column", "password") -.... - - - and setting the DSN specified in the odbc.ini, inserting this with the - url adding this line: - - -.... -modparam("usrloc|auth_db", "db_url", - "unixodbc://opensips:opensipsrw@localhost/my_dsn") -.... - - - replacing my_dsn with the correct value. - - - HINT: if unixodbc don't want to connect to mysql server, try restarting - mysql server with: - - -shell>safe_mysqld --user=mysql --socket=/var/lib/mysql/mysql.sock - - - The connector search the socket in /var/lib/mysql/mysql.sock and not - in /tmp/mysql.sock - -
- -
-
- diff --git a/modules/db_unixodbc/doc/db_unixodbc_devel.xml b/modules/db_unixodbc/doc/db_unixodbc_devel.xml deleted file mode 100644 index df1a82af8a4..00000000000 --- a/modules/db_unixodbc/doc/db_unixodbc_devel.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - &develguide; - - The module implements the &osips; DB API, in order to - be used by other modules. - - - diff --git a/modules/db_virtual/README b/modules/db_virtual/README deleted file mode 100644 index caac67a5ff4..00000000000 --- a/modules/db_virtual/README +++ /dev/null @@ -1,308 +0,0 @@ -db_virtual Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. The idea - 1.1.2. Modes - 1.1.3. Capabilities - 1.1.4. Failures - 1.1.5. The timer process - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_urls (str) - 1.3.2. db_probe_time (integer) - 1.3.3. db_max_consec_retrys (integer) - - 1.4. Exported MI Functions - - 1.4.1. db_get - 1.4.2. db_set - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_urls parameter - 1.2. Set db_probe_time parameter - 1.3. Set db_max_consec_retrys parameter - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. The idea - - A virtual DB will expose the same front DB api however, it will - backed by many real DB. This means that a virtual DB URL - translates to many real DB URLs. This virtual layer also - enables us to use the real dbs in multiple ways such as: - parallel, failover(hotswap) and round-robin. Therefore: each - virtual DB URL with associated real dbs and a way to use(mode) - it's real dbs must be specified. - -1.1.2. Modes - - The implemented modes are: - * FAILOVER - Use the first URL; if it fails, take the next URL and redo - the operation. - * PARALLEL - Use all the URLs in the virtual DB URL set. Fails if all - the URLs fail. - * ROUND (round-robin) - Use the next URL each time; if it fails, use the next one, - redo operation. - - When choosing the db virtual mode, be sure that there is a full - compatibility between the DB operations you want to do - (inserts, updates, deletes,...) and the relation (if any) - between the real DB URLs you have in the set - can be - completely independent, can be nodes of the same cluster, or - any other combination. - -1.1.3. Capabilities - - For each set (or new virtual DB URL), the capabilities are - automatically calculated based on the capabilities provided by - the real DB URLs from the set. A logical AND is done for each - cabability over all the URLs in the set. Shortly, in order for - the virtual URL to provide a certain capability, ALL its real - URLs must provide that capability. - - Note that starting with version 2.2 db_virtual supports - async_raw_query and async_raw_resume functions currently - implemented only by the mysql database engine. - -1.1.4. Failures - - When an operation from a process on a real DB fails: - it is marked (global and local CAN flag down) - its connection closed - - Later a timer process (probe): - foreach virtual db_url - foreach real db_url - if global CAN down - try to connect - if ok - global CAN up - close connection - - Later each process: - if local CAN down and global CAN up - if db_max_consec_retrys * - try to connect - if ok - local CAN up - - - Note *: there could be inconsistencies between the probe and - each process so a retry limit is in order. It is reset and - ignored by an MI command. - -1.1.5. The timer process - - The timer process(probe) is a process that tries to reconnect - to failed dbs from time to time. It is a separate process so - that when it blocks (for a timeout on the connection) it - doesn't matter. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * At least one real DB module. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_urls (str) - - Multiple value parameter used for virtual DB URLs declaration. - - Example 1.1. Set db_urls parameter -... - -modparam("group","db_url","virtual://set1") -modparam("presence|presence_xml", "db_url","virtual://set2") - -modparam("db_virtual", "db_urls", "define set1 PARALLEL") -modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost -/testa") -modparam("db_virtual", "db_urls", "postgres://opensips:opensipsrw@localh -ost/opensips") - -modparam("db_virtual", "db_urls", "define set2 FAILOVER") -modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost -/testa") -... - -1.3.2. db_probe_time (integer) - - Time interval after which a registered timer process attempts - to check failed(as reported by other processes) connections to - real dbs. The probe will connect and disconnect to the failed - real DB and announce others. - - Default value is 10 (10 sec). - - Example 1.2. Set db_probe_time parameter -... -modparam("db_virtual", "db_probe_time", 20) -... - -1.3.3. db_max_consec_retrys (integer) - - After the timer process has reported that it can connect to the - real db, other processes will try to reconnect to it. There are - cases where although the probe could connect some might fail. - This parameter represents the number of consecutive failed - retries that a process will do before it gives up. This value - is reset and suppressed by a MI function(db_set). - - Default value is 10 (10 consecutive times). - - Example 1.3. Set db_max_consec_retrys parameter -... -modparam("db_virtual", "db_max_consec_retrys", 20) -... - - -1.4. Exported MI Functions - -1.4.1. db_get - - Return information about global state of the real dbs. - - Name: db_get - - Parameters: - * None. - - MI FIFO Command Format: - opensips-cli -x mi db_get - -1.4.2. db_set - - Sets the permissions for real dbs access per set per db. - - Sets the reconnect reset flag. - - Name: db_set - - Parameters: - * set_index [int] - * db_url_index [int] - * may_use_db_flag [boolean] - * ignore_retries[boolean](optional) - - db_set 3 2 0 1 means: - * 3 - the fourth set (must exist) - * 2 - the third URL in the fourth set(must exist) - * 0 - processes are not allowed to use that URL - * 1 - reset and suppress db_max_consec_retrys - - MI FIFO Command Format: - opensips-cli -x mi db_set 3 2 0 1 - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Pistolea 31 7 2244 297 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 22 18 104 128 - 3. Liviu Chircu (@liviuchircu) 16 12 105 140 - 4. Razvan Crainea (@razvancrainea) 14 12 21 19 - 5. Vlad Patrascu (@rvlad-patrascu) 9 5 85 145 - 6. Ionut Ionita (@ionutrazvanionita) 6 3 232 9 - 7. Maksym Sobolyev (@sobomax) 4 2 4 5 - 8. Zero King (@l2dy) 3 1 5 5 - 9. Anca Vamanu 3 1 3 3 - 10. Walter Doekes (@wdoekes) 3 1 2 2 - - All remaining contributors: Julián Moreno Patiño, Peter - Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2009 - May 2022 - 3. Razvan Crainea (@razvancrainea) Sep 2011 - Jan 2021 - 4. Zero King (@l2dy) Mar 2020 - Mar 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Liviu Chircu (@liviuchircu) Oct 2013 - Jun 2018 - 8. Ionut Ionita (@ionutrazvanionita) Feb 2016 - Mar 2017 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Walter Doekes (@wdoekes) Jun 2014 - Jun 2014 - - All remaining contributors: Anca Vamanu, Razvan Pistolea. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián - Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Razvan - Pistolea. - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/db_virtual/README.md b/modules/db_virtual/README.md new file mode 100644 index 00000000000..43460662173 --- /dev/null +++ b/modules/db_virtual/README.md @@ -0,0 +1,253 @@ +--- +title: "db_virtual Module" +--- + +## Admin Guide + + +### Overview + + +#### The idea + + +A virtual DB will expose the same front DB api however, it will +backed by many real DB. This means that a virtual DB URL +translates to many real DB URLs. This virtual layer also +enables us to use the real dbs in multiple ways such as: +parallel, failover(hotswap) and round-robin. + +Therefore: +each virtual DB URL with associated real dbs and +a way to use(mode) it's real dbs must be specified. + + +#### Modes + + +The implemented modes are: + + +- FAILOVER - Use the first URL; if it fails, take the next URL and redo the operation. +- PARALLEL - Use all the URLs in the virtual DB URL set. Fails if all the URLs fail. +- ROUND (round-robin) - Use the next URL each time; if it fails, use the next one, redo operation. + + +When choosing the db virtual mode, be sure that there is a full +compatibility between the DB operations you want to do (inserts, +updates, deletes,...) and the relation (if any) between the real +DB URLs you have in the set - can be completely independent, can be +nodes of the same cluster, or any other combination. + + +#### Capabilities + + +For each set (or new virtual DB URL), the capabilities are +automatically calculated based on the capabilities provided by the +real DB URLs from the set. A logical AND is done for each +cabability over all the URLs in the set. Shortly, in order for the +virtual URL to provide a certain capability, ALL its real URLs +must provide that capability. + + +> [!NOTE] +> Starting with version 2.2 db_virtual supports +> async_raw_query and async_raw_resume functions currently +> implemented only by the mysql database engine. + + +#### Failures + + +```c +When an operation from a process on a real DB fails: + it is marked (global and local CAN flag down) + its connection closed + +Later a timer process (probe): +foreach virtual db_url + foreach real db_url + if global CAN down + try to connect + if ok + global CAN up + close connection + +Later each process: + if local CAN down and global CAN up + if db_max_consec_retrys * + try to connect + if ok + local CAN up + +``` + + +> [!NOTE] +> There could be inconsistencies between the probe and each process so a retry limit is in order. +> It is reset and ignored by an MI command. + + +#### The timer process + + +The timer process(probe) is a process that tries to reconnect to failed dbs from time to time. +It is a separate process so that when it blocks (for a timeout on the connection) it doesn't matter. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *At least one real DB module*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_urls (str) + + +Multiple value parameter used for virtual DB URLs declaration. + + +```opensips title="Set db_urls parameter" +... + +modparam("group","db_url","virtual://set1") +modparam("presence|presence_xml", "db_url","virtual://set2") + +modparam("db_virtual", "db_urls", "define set1 PARALLEL") +modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa") +modparam("db_virtual", "db_urls", "postgres://opensips:opensipsrw@localhost/opensips") + +modparam("db_virtual", "db_urls", "define set2 FAILOVER") +modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa") +... +``` + + +#### db_probe_time (integer) + + +Time interval after which a registered timer process attempts to check +failed(as reported by other processes) connections to real dbs. The probe will connect and +disconnect to the failed real DB and announce others. + + +*Default value is 10 (10 sec).* + + +```opensips title="Set db_probe_time parameter" +... +modparam("db_virtual", "db_probe_time", 20) +... +``` + + +#### db_max_consec_retrys (integer) + + +After the timer process has reported that it can connect to the real db, +other processes will try to reconnect to it. There are cases where although +the probe could connect some might fail. This parameter represents the number +of consecutive failed retries that a process will do before it gives up. +This value is reset and suppressed by a MI function(db_set). + + +*Default value is 10 (10 consecutive times).* + + +```opensips title="Set db_max_consec_retrys parameter" +... +modparam("db_virtual", "db_max_consec_retrys", 20) +... + +``` + + +### Exported MI Functions + + +#### db_get + + +Return information about global state of the real dbs. + + +Name: +*db_get* + + +Parameters: + + +- None. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi db_get +``` + + +#### db_set + + +Sets the permissions for real dbs access per set per db. + + +Sets the reconnect reset flag. + + +Name: +*db_set* + + +Parameters: + + +- set_index [int] +- db_url_index [int] +- may_use_db_flag [boolean] +- ignore_retries[boolean](optional) + + +db_set 3 2 0 1 means: + + +- 3 - the fourth set (must exist) +- 2 - the third URL in the fourth set(must exist) +- 0 - processes are not allowed to use that URL +- 1 - reset and suppress db_max_consec_retrys + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi db_set 3 2 0 1 +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/db_virtual/doc/contributors.xml b/modules/db_virtual/doc/contributors.xml deleted file mode 100644 index 2489471fd00..00000000000 --- a/modules/db_virtual/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Pistolea - 31 - 7 - 2244 - 297 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 22 - 18 - 104 - 128 - - - 3. - Liviu Chircu (@liviuchircu) - 16 - 12 - 105 - 140 - - - 4. - Razvan Crainea (@razvancrainea) - 14 - 12 - 21 - 19 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 9 - 5 - 85 - 145 - - - 6. - Ionut Ionita (@ionutrazvanionita) - 6 - 3 - 232 - 9 - - - 7. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 5 - - - 8. - Zero King (@l2dy) - 3 - 1 - 5 - 5 - - - 9. - Anca Vamanu - 3 - 1 - 3 - 3 - - - 10. - Walter Doekes (@wdoekes) - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: Julián Moreno Patiño, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2009 - May 2022 - - - 3. - Razvan Crainea (@razvancrainea) - Sep 2011 - Jan 2021 - - - 4. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Liviu Chircu (@liviuchircu) - Oct 2013 - Jun 2018 - - - 8. - Ionut Ionita (@ionutrazvanionita) - Feb 2016 - Mar 2017 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Walter Doekes (@wdoekes) - Jun 2014 - Jun 2014 - - - -
-All remaining contributors: Anca Vamanu, Razvan Pistolea. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Razvan Pistolea. -
- -
diff --git a/modules/db_virtual/doc/db_virtual.xml b/modules/db_virtual/doc/db_virtual.xml deleted file mode 100644 index 0fdee30c2de..00000000000 --- a/modules/db_virtual/doc/db_virtual.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - db_virtual Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - - diff --git a/modules/db_virtual/doc/db_virtual_admin.xml b/modules/db_virtual/doc/db_virtual_admin.xml deleted file mode 100644 index d1e41c0e6cf..00000000000 --- a/modules/db_virtual/doc/db_virtual_admin.xml +++ /dev/null @@ -1,306 +0,0 @@ - - - - - &adminguide; - -
- Overview - -
- The idea - - A virtual DB will expose the same front DB api however, it will - backed by many real DB. This means that a virtual DB URL - translates to many real DB URLs. This virtual layer also - enables us to use the real dbs in multiple ways such as: - parallel, failover(hotswap) and round-robin. - - Therefore: - each virtual DB URL with associated real dbs and - a way to use(mode) it's real dbs must be specified. - -
- - -
- Modes - - The implemented modes are: - - - FAILOVER - - Use the first URL; if it fails, take the next - URL and redo the operation. - - - - PARALLEL - - Use all the URLs in the virtual DB URL set. - Fails if all the URLs fail. - - - - ROUND (round-robin) - - Use the next URL each time; if it fails, - use the next one, redo operation. - - - - - - When choosing the db virtual mode, be sure that there is a full - compatibility between the DB operations you want to do (inserts, - updates, deletes,...) and the relation (if any) between the real - DB URLs you have in the set - can be completely independent, can be - nodes of the same cluster, or any other combination. - -
-
- Capabilities - - For each set (or new virtual DB URL), the capabilities are - automatically calculated based on the capabilities provided by the - real DB URLs from the set. A logical AND is done for each - cabability over all the URLs in the set. Shortly, in order for the - virtual URL to provide a certain capability, ALL its real URLs - must provide that capability. - - - Note that starting with version 2.2 db_virtual supports - async_raw_query and async_raw_resume functions currently - implemented only by the mysql database engine. - -
- -
- Failures - - - When an operation from a process on a real DB fails: - it is marked (global and local CAN flag down) - its connection closed - - Later a timer process (probe): - foreach virtual db_url - foreach real db_url - if global CAN down - try to connect - if ok - global CAN up - close connection - - Later each process: - if local CAN down and global CAN up - if db_max_consec_retrys * - try to connect - if ok - local CAN up - - - - - Note *: there could be inconsistencies between the probe and each process so a retry limit is in order. - It is reset and ignored by an MI command. - -
- -
- The timer process - - The timer process(probe) is a process that tries to reconnect to failed dbs from time to time. - It is a separate process so that when it blocks (for a timeout on the connection) it doesn't matter. - -
- -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - - At least one real DB module. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - None. - - - - -
-
-
- Exported Parameters -
- - <varname>db_urls</varname> (str) - - - Multiple value parameter used for virtual DB URLs declaration. - - - Set - <varname>db_urls</varname> parameter - - -... - -modparam("group","db_url","virtual://set1") -modparam("presence|presence_xml", "db_url","virtual://set2") - -modparam("db_virtual", "db_urls", "define set1 PARALLEL") -modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa") -modparam("db_virtual", "db_urls", "postgres://opensips:opensipsrw@localhost/opensips") - -modparam("db_virtual", "db_urls", "define set2 FAILOVER") -modparam("db_virtual", "db_urls", "mysql://opensips:opensipsrw@localhost/testa") -... - - - -
-
- - <varname>db_probe_time</varname> (integer) - - - Time interval after which a registered timer process attempts to check - failed(as reported by other processes) connections to real dbs. The probe will connect and - disconnect to the failed real DB and announce others. - - - - Default value is 10 (10 sec). - - - - Set - <varname>db_probe_time</varname> parameter - - -... -modparam("db_virtual", "db_probe_time", 20) -... - - -
- -
- - <varname>db_max_consec_retrys</varname> (integer) - - - After the timer process has reported that it can connect to the real db, - other processes will try to reconnect to it. There are cases where although - the probe could connect some might fail. This parameter represents the number - of consecutive failed retries that a process will do before it gives up. - This value is reset and suppressed by a MI function(db_set). - - - - Default value is 10 (10 consecutive times). - - - - Set - <varname>db_max_consec_retrys</varname> parameter - - -... -modparam("db_virtual", "db_max_consec_retrys", 20) -... - - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">db_get</function> - - - Return information about global state of the real dbs. - - - Name: - db_get - - Parameters: - - - None. - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi db_get - -
- - - -
- - <function moreinfo="none">db_set</function> - - Sets the permissions for real dbs access per set per db. - Sets the reconnect reset flag. - - Name: - db_set - - Parameters: - - set_index [int] - db_url_index [int] - may_use_db_flag [boolean] - ignore_retries[boolean](optional) - - - db_set 3 2 0 1 means: - - 3 - the fourth set (must exist) - 2 - the third URL in the fourth set(must exist) - 0 - processes are not allowed to use that URL - 1 - reset and suppress db_max_consec_retrys - - - - MI FIFO Command Format: - - - opensips-cli -x mi db_set 3 2 0 1 - -
-
- -
- diff --git a/modules/dialog/README b/modules/dialog/README deleted file mode 100644 index f51cbd45e03..00000000000 --- a/modules/dialog/README +++ /dev/null @@ -1,2742 +0,0 @@ -dialog Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Dialog profiling - 1.4. Dialog clustering - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. External Libraries or Applications - - 1.6. Exported Parameters - - 1.6.1. enable_stats (integer) - 1.6.2. hash_size (integer) - 1.6.3. log_profile_hash_size (integer) - 1.6.4. rr_param (string) - 1.6.5. default_timeout (integer) - 1.6.6. dlg_extra_hdrs (string) - 1.6.7. dlg_match_mode (integer) - 1.6.8. delete_delay (integer) - 1.6.9. db_url (string) - 1.6.10. db_mode (integer) - 1.6.11. db_update_period (integer) - 1.6.12. options_ping_interval (integer) - 1.6.13. reinvite_ping_interval (integer) - 1.6.14. table_name (string) - 1.6.15. call_id_column (string) - 1.6.16. from_uri_column (string) - 1.6.17. from_tag_column (string) - 1.6.18. to_uri_column (string) - 1.6.19. to_tag_column (string) - 1.6.20. from_cseq_column (string) - 1.6.21. to_cseq_column (string) - 1.6.22. from_route_column (string) - 1.6.23. to_route_column (string) - 1.6.24. from_contact_column (string) - 1.6.25. to_contact_column (string) - 1.6.26. from_sock_column (string) - 1.6.27. to_sock_column (string) - 1.6.28. dlg_id_column (string) - 1.6.29. state_column (string) - 1.6.30. start_time_column (string) - 1.6.31. timeout_column (string) - 1.6.32. profiles_column (string) - 1.6.33. vars_column (string) - 1.6.34. sflags_column (string) - 1.6.35. mflags_column (string) - 1.6.36. flags_column (string) - 1.6.37. profiles_with_value (string) - 1.6.38. profiles_no_value (string) - 1.6.39. db_flush_vals_profiles (int) - 1.6.40. timer_bulk_del_no (int) - 1.6.41. race_condition_timeout (int) - 1.6.42. cachedb_url (string) - 1.6.43. profile_value_prefix (string) - 1.6.44. profile_no_value_prefix (string) - 1.6.45. profile_size_prefix (string) - 1.6.46. profile_timeout (int) - 1.6.47. dialog_replication_cluster (int) - 1.6.48. profile_replication_cluster (int) - 1.6.49. replicate_profiles_buffer (string) - 1.6.50. replicate_profiles_check (string) - 1.6.51. replicate_profiles_timer (string) - 1.6.52. replicate_profiles_expire (string) - 1.6.53. cluster_auto_sync (string) - - 1.7. Exported Functions - - 1.7.1. create_dialog([flags]) - 1.7.2. match_dialog([dlg_match_mode]) - 1.7.3. validate_dialog() - 1.7.4. fix_route_dialog() - 1.7.5. get_dialog_info(attr,avp,key,key_val,no_dlgs) - - 1.7.6. get_dialog_vals(names,vals,callid) - 1.7.7. - get_dialogs_by_val(name,value,out_avp,out_dlg_ - no) - - 1.7.8. - get_dialogs_by_profile(name,value,out_avp,out_ - dlg_no) - - 1.7.9. load_dialog_ctx( dialog [, id_type]) - 1.7.10. unload_dialog_ctx() - 1.7.11. set_dlg_profile(profile, [value], - [clear_values]) - - 1.7.12. unset_dlg_profile(profile, [value]) - 1.7.13. is_in_profile(profile,[value]) - 1.7.14. get_profile_size(profile,[value],size) - 1.7.15. set_dlg_flag(flag) - 1.7.16. test_and_set_dlg_flag(flag, value) - 1.7.17. reset_dlg_flag(flag) - 1.7.18. is_dlg_flag_set(flag) - 1.7.19. store_dlg_value(name,val) - 1.7.20. fetch_dlg_value(name,val) - 1.7.21. set_dlg_sharing_tag(tag_name) - 1.7.22. dlg_on_answer([route_name]) - 1.7.23. dlg_on_timeout([route_name]) - 1.7.24. dlg_on_hangup([route_name]) - 1.7.25. dlg_send_sequential(method, leg, [, body] [, - content-type] [, headers]) - - 1.7.26. dlg_inc_cseq([tag, ][inc]) - - 1.8. Exported Statistics - - 1.8.1. active_dialogs - 1.8.2. early_dialogs - 1.8.3. processed_dialogs - 1.8.4. expired_dialogs - 1.8.5. failed_dialogs - 1.8.6. create_sent - 1.8.7. update_sent - 1.8.8. delete_sent - 1.8.9. create_recv - 1.8.10. update_recv - 1.8.11. delete_recv - - 1.9. Exported MI Functions - - 1.9.1. dlg_list - 1.9.2. dlg_list_ctx - 1.9.3. dlg_end_dlg - 1.9.4. profile_get_size - 1.9.5. profile_list_dlgs - 1.9.6. profile_get_values - 1.9.7. profile_end_dlgs - 1.9.8. dlg_db_sync - 1.9.9. dlg_cluster_sync - 1.9.10. dlg_restore_db - 1.9.11. list_all_profiles - 1.9.12. dlg_push_var - 1.9.13. dlg_send_sequential - 1.9.14. set_dlg_profile - 1.9.15. unset_dlg_profile - - 1.10. Exported Pseudo-Variables - - 1.10.1. $DLG_count - 1.10.2. $DLG_status - 1.10.3. $DLG_lifetime - 1.10.4. $DLG_flags - 1.10.5. $DLG_dir - 1.10.6. $DLG_did - 1.10.7. $DLG_end_reason - 1.10.8. $DLG_timeout - 1.10.9. $DLG_del_delay - 1.10.10. $DLG_json - 1.10.11. $DLG_ctx_json - 1.10.12. $dlg_val(name) - - 1.11. Exported Events - - 1.11.1. E_DLG_STATE_CHANGED - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. register_dlgcb (dialog, type, cb, param, - free_param_cb) - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set enable_stats parameter - 1.2. Set hash_size parameter - 1.3. Set hash_size parameter - 1.4. Set rr_param parameter - 1.5. Set default_timeout parameter - 1.6. Set dlf_extra_hdrs parameter - 1.7. Set dlg_match_mode parameter - 1.8. Set delete_delay parameter - 1.9. Set db_url parameter - 1.10. Set db_mode parameter - 1.11. Set db_update_period parameter - 1.12. Set options_ping_interval parameter - 1.13. Set reinvite_ping_interval parameter - 1.14. Set table_name parameter - 1.15. Set call_id_column parameter - 1.16. Set from_uri_column parameter - 1.17. Set from_tag_column parameter - 1.18. Set to_uri_column parameter - 1.19. Set to_tag_column parameter - 1.20. Set from_cseq_column parameter - 1.21. Set to_cseq_column parameter - 1.22. Set from_route_column parameter - 1.23. Set to_route_column parameter - 1.24. Set from_contact_column parameter - 1.25. Set to_contact_column parameter - 1.26. Set from_sock_column parameter - 1.27. Set to_sock_column parameter - 1.28. Set dlg_id_column parameter - 1.29. Set state_column parameter - 1.30. Set start_time_column parameter - 1.31. Set timeout_column parameter - 1.32. Set profiles_column parameter - 1.33. Set vars_column parameter - 1.34. Set sflags_column parameter - 1.35. Set mflags_column parameter - 1.36. Set flags_column parameter - 1.37. Set profiles_with_value parameter - 1.38. Set profiles_no_value parameter - 1.39. Set db_flush_vals_profiles parameter - 1.40. Set timer_bulk_del_no parameter - 1.41. Set race_condition_timeout parameter - 1.42. Set cachedb_url parameter - 1.43. Set profile_value_prefix parameter - 1.44. Set profile_no_value_prefix parameter - 1.45. Set profile_size_prefix parameter - 1.46. Set profile_timeout parameter - 1.47. Set dialog_replication_cluster parameter - 1.48. Set profile_replication_cluster parameter - 1.49. Set replicate_profiles_buffer parameter - 1.50. Set replicate_profiles_check parameter - 1.51. Set replicate_profiles_timer parameter - 1.52. Set replicate_profiles_expire parameter - 1.53. Set cluster_auto_sync parameter - 1.54. create_dialog() usage - 1.55. match_dialog() usage - 1.56. validate_dialog() usage - 1.57. fix_route_dialog() usage - 1.58. get_dialog_info usage - 1.59. get_dialog_vals usage - 1.60. get_dialog_vals usage - 1.61. get_dialog_vals usage - 1.62. load_dialog_ctx usage - 1.63. set_dlg_profile usage - 1.64. unset_dlg_profile usage - 1.65. is_in_profile usage - 1.66. get_profile_size usage - 1.67. set_dlg_flag usage - 1.68. test_and_set_dlg_flag usage - 1.69. reset_dlg_flag usage - 1.70. is_dlg_flag_set usage - 1.71. store_dlg_value usage - 1.72. fetch_dlg_value usage - 1.73. set_dlg_sharing_tag usage - 1.74. dlg_on_answer usage - 1.75. dlg_on_timeout usage - 1.76. dlg_on_hangup usage - 1.77. dlg_send_sequential usage to convert DTMF codes - 1.78. dlg_inc_cseq usage - -Chapter 1. Admin Guide - -1.1. Overview - - The dialog module provides dialog awareness to the OpenSIPS - proxy. Its functionality is to keep trace of the current - dialogs, to offer information about them (like how many dialogs - are active). - - Aside tracking, the dialog module offers functionalities like - flags and attributes per dialog (persistent data across - dialog), dialog profiling and dialog termination (on timeout - base or external triggered). - - The module, via an internal API, also provide the foundation to - build on top of it more complex dialog-based functionalities - via other OpenSIPS modules. - -1.2. How it works - - To create the dialog associated with an initial request, you - must call the create_dialog() function, with or without - parameter. - - The dialog is automatically terminated when a “BYE” is - received. In case of no “BYE”, the dialog lifetime is - controlled via the default timeout (see “default_timeout” - - default_timeout) and custom timeout (see “$DLG_timeout” - - $DLG_timeout). - - Once terminated, the in-memory dialog may be destroyed right - away or, depending on the “delete_delay” - delete_delay) - setting, it may be kept for a while in memory, in a read-only - state (no action, no changes, nothing). This delaying may be - used to help with the routing of late in-dialog request that - may be received after the dialog terminted (like late BYE's due - retransmissions, cross BYE requests, auth'ed BYE request, slow - ACK on re-INVITEs, etc). - -1.3. Dialog profiling - - Dialog profiling is a mechanism that helps in classifying, - sorting and keeping trace of certain types of dialogs, using - whatever properties of the dialog (like caller, destination, - type of calls, etc). Dialogs can be dynamically added in - different (and several) profile tables - logically, each - profile table can have a special meaning (like dialogs outside - the domain, dialogs terminated to PSTN, etc). - - There are two types of profiles: - * with no value - a dialog simply belongs to a profile. (like - outbound calls profile). There is no other additional - information to describe the dialog's belonging to the - profile; - * with value - a dialog belongs to a profile having a certain - value (like in caller profile, where the value is the - caller ID). The belonging of the dialog to the profile is - strictly related to the value. - - A dialog can be added to multiple profiles in the same time. - - Profiles are visible (at the moment) in the request route (for - initial and sequential requests) and in the branch, failure and - reply routes of the original request. - - Dialog profiles can also be used in distributed systems, using - the OpenSIPS CacheDB Interface or the clusterer module. This - feature allows you to share dialog profile information with - multiple OpenSIPS instaces that use the same CacheDB backend or - are part of an OpenSIPS cluster. In order to do that, the - cachedb_url or profile_replication_cluster parameters must be - defined. Also, the profile must be marked as shared, by adding - one of the '/s' or '/b' suffixes to the name of the profile in - the profiles_with_value or profiles_no_value parameters. - -1.4. Dialog clustering - - Dialog replication is a mechanism used to mirror all dialog - changes taking place in one OpenSIPS instance to one or - multiple other instances. The process is simplified by using - the clusterer module which facilitates the management of a - cluster of OpenSIPS nodes and the sending of - replication-related BIN packets (binary-encoded, using - proto_bin). This feature is useful in achieving High - Availability and/or Load Balancing for ongoing calls. - - Configuring both receival and sending of dialog replication - packets is trivial and can be done by using the - dialog_replication_cluster parameter. But in addition to just - sharing data, in order to properly cluster dialogs you will - need to manage which node in the cluster is doing certain - actions on certain dialogs using the sharing tags mechanism. - For details and configuration examples on how this would work - in different usage scenarios, see this article. - - The following actions will not be performed for a dialog marked - with a sharing tag that is in the "backup" state: - * sending Re-Invite or OPTIONS pings to end-points - * generating BYE requests or any other actions(like producing - CDRs) upon dialog expiration - * sending replication packets on dialog events(update, - delete) - * counting the dialog in the profiles that it belongs; only - if profile replication is also enabled - - In addition to the event-driven replication, an OpenSIPS - instance will first try to learn all the dialog information - from antoher node in the cluster at startup. The data - synchronization mechanism requires defining one of the nodes in - the cluster as a "seed" node. See the clusterer module for - details on how to do this and why is it needed. - - In the context of dialog replication, using a database as a - failsafe for obtaining restart persistency for dialog data is - useful in case all nodes in the cluster are down. This approach - makes the most sense if a separate, local DB is used for each - node in the cluster. Dialogs loaded from the database at - startup, which are not reconfirmed through syncing, are dropped - and also deleted from the database once the sync from cluster - is complete. - - Also configuring profile replication via the - profile_replication_cluster parameter is not necessary when - dialog replication is already configured. The profile - information is included in the dialog updates sent in the - dialog replication cluster. The profiles must still be marked - for sharing though in the profiles_with_value or - profiles_no_value parameters. - - A scenario were both profile and dialog replication should be - configured is when a platform has multiple POPs, where separate - dialog replication clusters are configured for HA purposes, and - a cluster for globally shared profiles is also required. In - this case, proper counting for dialogs is ensured by using the - sharing tags mechanism(in order to avoid counting each dialog - twice, both on the active and backup node for that dialog). - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction module - * RR - Record-Route module, optional, if Dialog ID matching - is used in non Topo Hiding cases - * clusterer - if replication_cluster parameter is set - (contact replication via clusterer module) - -1.5.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.6. Exported Parameters - -1.6.1. enable_stats (integer) - - If the statistics support should be enabled or not. Via - statistic variables, the module provide information about the - dialog processing. Set it to zero to disable or to non-zero to - enable it. - - Default value is “1 (enabled)”. - - Example 1.1. Set enable_stats parameter -... -modparam("dialog", "enable_stats", 0) -... - -1.6.2. hash_size (integer) - - The size of the hash table internally used to keep the dialogs. - A larger table is much faster but consumes more memory. The - hash size must be a power of 2 number. - - IMPORTANT: If dialogs' information should be stored in a - database, a constant hash_size should be used, otherwise the - restored process will not take place. If you really want to - modify the hash_size you must delete all table's rows before - restarting OpenSIPS. - - Default value is “4096”. - - Example 1.2. Set hash_size parameter -... -modparam("dialog", "hash_size", 1024) -... - -1.6.3. log_profile_hash_size (integer) - - The size of the hash table internally used to store - profile->dialog associations. A larger table can provide more - parallel operations but consumes more memory. The hash size is - provided as the base 2 logarithm(e.g. log_profile_hash_size =4 - means the table has 2^4 entries). - - Default value is “4”. - - Example 1.3. Set hash_size parameter -... -modparam("dialog", "log_profile_hash_size", 5) #set a table size of 32 -... - -1.6.4. rr_param (string) - - Name of the Record-Route parameter to be added with the dialog - cookie. It is used for fast dialog matching of the sequential - requests. - - Default value is “did”. - - Example 1.4. Set rr_param parameter -... -modparam("dialog", "rr_param", "xyz") -... - -1.6.5. default_timeout (integer) - - The default dialog timeout (in seconds) if no custom one is - set. - - Default value is “43200 (12 hours)”. - - Example 1.5. Set default_timeout parameter -... -modparam("dialog", "default_timeout", 21600) -... - -1.6.6. dlg_extra_hdrs (string) - - A string containing the extra headers (full format, with EOH) - to be added in the requests generated by the module (like - BYEs). - - Default value is “NULL”. - - Example 1.6. Set dlf_extra_hdrs parameter -... -modparam("dialog", "dlg_extra_hdrs", "Hint: credit expired\r\n") -... - -1.6.7. dlg_match_mode (integer) - - How the seqential requests should be matched against the known - dialogs. The modes are a combination between matching based on - a cookie (DID) stored as cookie in Record-Route header and the - matching based on SIP elements (as in RFC3261). - - The supported modes are: - * 0 - DID_ONLY - the match is done exclusively based on DID; - * 1 - DID_FALLBACK - the match is first tried based on DID - and if not present, it will fallback to SIP matching; - * 2 - DID_NONE - the match is done exclusively based on SIP - elements; no DID information is added in RR. - - Default value is “1 (DID_FALLBACK)”. - - NOTE that if you have call looping on your OpenSIPS server - (passing more than once through the same OpenSIPS instance), it - is strongly suggested to use only DID_ONLY mode, as the SIP - based matching will have an undefined behavior - from SIP - perspective, a sequential dialog will match all the loops of - the call, as the Call-ID, To and From TAGs are the same. - - Example 1.7. Set dlg_match_mode parameter -... -modparam("dialog", "dlg_match_mode", 0) -... - -1.6.8. delete_delay (integer) - - The interval (seconds) to delay a dialog deletion / removal - from memory AFTER its termination. Once terminated, the dialog - will be kept in a read only state (no action, no changes), but - it will still be able to match and route late in-dialog - requests. - - This global value may be per-call changed via the DLG_del_delay - “$DLG_del_delay” ($DLG_del_delay) script variable. - - Default value is “0” (disabled). - - Example 1.8. Set delete_delay parameter -... -modparam("dialog", "delete_delay", 10) -... - -1.6.9. db_url (string) - - If you want to store the information about the dialogs in a - database a database url must be specified. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.9. Set db_url parameter -... -modparam("dialog", "db_url", "dbdriver://username:password@dbhost/dbname -") -... - -1.6.10. db_mode (integer) - - Describe how to push into the DB the dialogs' information from - memory. - - The supported modes are: - * 0 - NO_DB - the memory content is not flushed into DB; - * 1 - REALTIME - any dialog information changes will be - reflected into the database immediately. - * 2 - DELAYED - the dialog information changes will be - flushed into the DB periodically, based on a timer routine. - * 3 - SHUTDOWN - the dialog information will be flushed into - DB only at shutdown - no runtime updates. - - Default value is “0”. - - Example 1.10. Set db_mode parameter -... -modparam("dialog", "db_mode", 1) -... - -1.6.11. db_update_period (integer) - - The interval (seconds) at which to update dialogs' information - if you chose to store the dialogs' info at a given interval. A - too short interval will generate intensive database operations, - a too large one will not notice short dialogs. - - Default value is “60”. - - Example 1.11. Set db_update_period parameter -... -modparam("dialog", "db_update_period", 120) -... - -1.6.12. options_ping_interval (integer) - - The interval (seconds) at which OpenSIPS will generate - in-dialog OPTIONS pings for one or both of the involved - parties. - - Default value is “30”. - - Example 1.12. Set options_ping_interval parameter -... -modparam("dialog", "options_ping_interval", 20) -... - -1.6.13. reinvite_ping_interval (integer) - - The interval (seconds) at which OpenSIPS will generate - in-dialog Re-INVITE pings for one or both of the involved - parties. - - Important: the ping timeout detection is performed every time - this interval ticks, not when the re-INVITE transaction times - out! Consequently, please make sure that the timeouts for - re-INVITE transactions (e.g. the "fr_timeout" modparam of the - "tm" module or its $T_fr_timeout variable) are always lower - than the value of this parameter! Failing to ensure this - ordering of timeouts may possibly lead to re-INVITE pings never - ending a disconnected dialog due to pings getting retried - before getting a chance to properly time out. - - Default value is “300”. - - Example 1.13. Set reinvite_ping_interval parameter -... -modparam("dialog", "reinvite_ping_interval", 600) -... - -1.6.14. table_name (string) - - If you want to store the information about the dialogs in a - database a table name must be specified. - - Default value is “dialog”. - - Example 1.14. Set table_name parameter -... -modparam("dialog", "table_name", "my_dialog") -... - -1.6.15. call_id_column (string) - - The column's name in the database to store the dialogs' callid. - - Default value is “callid”. - - Example 1.15. Set call_id_column parameter -... -modparam("dialog", "call_id_column", "callid_c_name") -... - -1.6.16. from_uri_column (string) - - The column's name in the database to store the caller's sip - address. - - Default value is “from_uri”. - - Example 1.16. Set from_uri_column parameter -... -modparam("dialog", "from_uri_column", "from_uri_c_name") -... - -1.6.17. from_tag_column (string) - - The column's name in the database to store the From tag from - the Invite request. - - Default value is “from_tag”. - - Example 1.17. Set from_tag_column parameter -... -modparam("dialog", "from_tag_column", "from_tag_c_name") -... - -1.6.18. to_uri_column (string) - - The column's name in the database to store the calee's sip - address. - - Default value is “to_uri”. - - Example 1.18. Set to_uri_column parameter -... -modparam("dialog", "to_uri_column", "to_uri_c_name") -... - -1.6.19. to_tag_column (string) - - The column's name in the database to store the To tag from the - 200 OK response to the Invite request, if present. - - Default value is “to_tag”. - - Example 1.19. Set to_tag_column parameter -... -modparam("dialog", "to_tag_column", "to_tag_c_name") -... - -1.6.20. from_cseq_column (string) - - The column's name in the database to store the cseq from caller - side. - - Default value is “caller_cseq”. - - Example 1.20. Set from_cseq_column parameter -... -modparam("dialog", "from_cseq_column", "from_cseq_c_name") -... - -1.6.21. to_cseq_column (string) - - The column's name in the database to store the cseq from callee - side. - - Default value is “callee_cseq”. - - Example 1.21. Set to_cseq_column parameter -... -modparam("dialog", "to_cseq_column", "to_cseq_c_name") -... - -1.6.22. from_route_column (string) - - The column's name in the database to store the route records - from caller side (proxy to caller). - - Default value is “caller_route_set”. - - Example 1.22. Set from_route_column parameter -... -modparam("dialog", "from_route_column", "from_route_c_name") -... - -1.6.23. to_route_column (string) - - The column's name in the database to store the route records - from callee side (proxy to callee). - - Default value is “callee_route_set”. - - Example 1.23. Set to_route_column parameter -... -modparam("dialog", "to_route_column", "to_route_c_name") -... - -1.6.24. from_contact_column (string) - - The column's name in the database to store the caller's contact - uri. - - Default value is “caller_contact”. - - Example 1.24. Set from_contact_column parameter -... -modparam("dialog", "from_contact_column", "from_contact_c_name") -... - -1.6.25. to_contact_column (string) - - The column's name in the database to store the callee's contact - uri. - - Default value is “callee_contact”. - - Example 1.25. Set to_contact_column parameter -... -modparam("dialog", "to_contact_column", "to_contact_c_name") -... - -1.6.26. from_sock_column (string) - - The column's name in the database to store the information - about the local interface receiving the traffic from caller. - - Default value is “caller_sock”. - - Example 1.26. Set from_sock_column parameter -... -modparam("dialog", "from_sock_column", "from_sock_c_name") -... - -1.6.27. to_sock_column (string) - - The column's name in the database to store information about - the local interface receiving the traffic from callee. - - Default value is “callee_sock”. - - Example 1.27. Set to_sock_column parameter -... -modparam("dialog", "to_sock_column", "to_sock_c_name") -... - -1.6.28. dlg_id_column (string) - - The column's name in the database to store the dialogs' id - information. - - Default value is “dlg_id”. - - Example 1.28. Set dlg_id_column parameter -... -modparam("dialog", "dlg_id_column", "dlg_id_c_name") -... - -1.6.29. state_column (string) - - The column's name in the database to store the dialogs' state - information. - - Default value is “state”. - - Example 1.29. Set state_column parameter -... -modparam("dialog", "state_column", "state_c_name") -... - -1.6.30. start_time_column (string) - - The column's name in the database to store the dialogs' start - time information. - - Default value is “start_time”. - - Example 1.30. Set start_time_column parameter -... -modparam("dialog", "start_time_column", "start_time_c_name") -... - -1.6.31. timeout_column (string) - - The column's name in the database to store the dialogs' - timeout. - - Default value is “timeout”. - - Example 1.31. Set timeout_column parameter -... -modparam("dialog", "timeout_column", "timeout_c_name") -... - -1.6.32. profiles_column (string) - - The column's name in the database to store the dialogs' - profiles. - - Default value is “profiles”. - - Example 1.32. Set profiles_column parameter -... -modparam("dialog", "profiles_column", "profiles_c_name") -... - -1.6.33. vars_column (string) - - The column's name in the database to store the dialogs' vars. - - Default value is “vars”. - - Example 1.33. Set vars_column parameter -... -modparam("dialog", "vars_column", "vars_c_name") -... - -1.6.34. sflags_column (string) - - The column's name in the database to store the dialogs' script - flags. - - Default value is “script_flags”. - - Example 1.34. Set sflags_column parameter -... -modparam("dialog", "sflags_column", "sflags_c_name") -... - -1.6.35. mflags_column (string) - - The column's name in the database to store the dialogs' module - flags. - - Default value is “module_flags”. - - Example 1.35. Set mflags_column parameter -... -modparam("dialog", "mflags_column", "mflags_c_name") -... - -1.6.36. flags_column (string) - - The column's name in the database to store the dialogs' flags. - - Default value is “flags”. - - Example 1.36. Set flags_column parameter -... -modparam("dialog", "flags_column", "flags_c_name") -... - -1.6.37. profiles_with_value (string) - - List of names (alphanumerical/-/_) for profiles with values. - Flags /b or /s allow sharing profiles between OpenSIPS - instances using the clusterer module or a CacheDB backend, - respectively. - - Default value is “empty”. - - Example 1.37. Set profiles_with_value parameter -... -modparam("dialog", "profiles_with_value", "callerCC; gatewayCC; clientCh -annels/s; codecUsed/b;") -... - -1.6.38. profiles_no_value (string) - - List of names (alphanumerical/-/_) for profiles without values. - Flags /b or /s allow sharing profiles between OpenSIPS - instances using the clusterer module or a CacheDB backend, - respectively. - - Default value is “empty”. - - Example 1.38. Set profiles_no_value parameter -... -modparam("dialog", "profiles_no_value", "inbound ; outbound ; shared/s; -repl/b;") -... - -1.6.39. db_flush_vals_profiles (int) - - Pushes dialog values, profiles and flags into the database - along with other dialog state information (see db_mode 1 and - 2). - - Default value is “empty”. - - Example 1.39. Set db_flush_vals_profiles parameter -... -modparam("dialog", "db_flush_vals_profiles", 1) -... - -1.6.40. timer_bulk_del_no (int) - - The number of dialogs that should be attempted to be deleted at - the same time ( a single query ) from the DB back-end. - - Default value is “1”. - - Example 1.40. Set timer_bulk_del_no parameter -... -modparam("dialog", "timer_bulk_del_no", 10) -... - -1.6.41. race_condition_timeout (int) - - If dialog is created using the 'E' flag, and a SIP Race - condition happens, then the dialog will be terminated after - 'race_condition_timeout' seconds. Currently, the only supported - race conditions are (200OK vs CANCEL) and (early BYE vs 200OK) - - Default value is “5” seconds. - - Example 1.41. Set race_condition_timeout parameter -... -modparam("dialog", "race_condition_timeout", 1) -... - -1.6.42. cachedb_url (string) - - Enables distributed dialog profiles and specifies the backend - that should be used by the CacheDB interface. - - Default value is “empty”. - - Example 1.42. Set cachedb_url parameter -... -modparam("dialog", "cachedb_url", "redis://127.0.0.1:6379") -... - -1.6.43. profile_value_prefix (string) - - Specifies what prefix should be added to the profiles with - value when they are inserted into CacheDB backed. This is only - used when distributed profiles are enabled. - - Default value is “dlg_val_”. - - Example 1.43. Set profile_value_prefix parameter -... -modparam("dialog", "profile_value_prefix", "dlgv_") -... - -1.6.44. profile_no_value_prefix (string) - - Specifies what prefix should be added to the profiles without - value when they are inserted into CacheDB backed. This is only - used when distributed profiles are enabled. - - Default value is “dlg_noval_”. - - Example 1.44. Set profile_no_value_prefix parameter -... -modparam("dialog", "profile_no_value_prefix", "dlgnv_") -... - -1.6.45. profile_size_prefix (string) - - Specifies what prefix should be added to the entity that holds - the profiles with value size in CacheDB backed. This is only - used when distributed profiles are enabled. - - Default value is “dlg_size_”. - - Example 1.45. Set profile_size_prefix parameter -... -modparam("dialog", "profile_size_prefix", "dlgs_") -... - -1.6.46. profile_timeout (int) - - Specifies how long a dialog profile should be kept in the - CacheDB until it expires. This is only used when distributed - profiles are enabled. - - Default value is “86400”. - - Example 1.46. Set profile_timeout parameter -... -modparam("dialog", "profile_timeout", "43200") -... - -1.6.47. dialog_replication_cluster (int) - - Specifies the cluster ID for dialog replication using the - clusterer module. This enables sending and receiving all the - dialog-related events (creation, update and deletion) in the - cluster. - - This OpenSIPS cluster exposes the "dialog-dlg-repl" capability - in order to mark nodes as eligible for becoming data donors - during an arbitrary sync request. Consequently, the cluster - must have at least one node marked with the "seed" value as the - clusterer.flags column/property in order to be fully - functional. Consult the clusterer - Capabilities chapter for - more details. - - Default value is “0” (no replication). - - Example 1.47. Set dialog_replication_cluster parameter -... -modparam("dialog", "dialog_replication_cluster", 1) -... - -1.6.48. profile_replication_cluster (int) - - Specifies the cluster ID for profile replication using the - clusterer module. This enables sending and receiving the - profile information (value, dialog count) in the cluster. - - Default value is “0” (no replication). - - Example 1.48. Set profile_replication_cluster parameter -... -modparam("dialog", "profile_replication_cluster", 1) -... - -1.6.49. replicate_profiles_buffer (string) - - Used to specify the length of the buffer used by the binary - replication, in bytes. Usually this should be big enough to - hold as much data as possible, but small enough to avoid UDP - fragmentation. The recommended value is the smallest MTU - between all the replication instances. - - Default value is 1400 bytes. - - Example 1.49. Set replicate_profiles_buffer parameter -... -modparam("dialog", "replicate_profiles_buffer", 500) -... - -1.6.50. replicate_profiles_check (string) - - Timer in seconds, used to specify how often the module should - check whether old, replicated profiles values are obsolete and - should be removed. should replicate its profiles to the other - instances. - - Default value is 10 s. - - Example 1.50. Set replicate_profiles_check parameter -... -modparam("dialog", "replicate_profiles_check", 100) -... - -1.6.51. replicate_profiles_timer (string) - - Timer in milliseconds, used to specify how often the module - should replicate its profiles to the other instances. - - Default value is 200 ms. - - Example 1.51. Set replicate_profiles_timer parameter -... -modparam("dialog", "replicate_profiles_timer", 100) -... - -1.6.52. replicate_profiles_expire (string) - - Timer in seconds, used to specify when the profiles counters - received from a different instance should no longer be taken - into account. This is used to prevent obsolete values, in case - an instance stops replicating its counters. - - Default value is 10 s. - - Example 1.52. Set replicate_profiles_expire parameter -... -modparam("dialog", "replicate_profiles_expire", 10) -... - -1.6.53. cluster_auto_sync (string) - - Specifies whether to automatically issue a sync request (for - dialogs marked with a sharing tag in backup state) when a node - becomes reachable. A value of 1 means enabled and 0 disabled. - - Default value is 1 (enabled). - - Example 1.53. Set cluster_auto_sync parameter -... -modparam("dialog", "cluster_auto_sync", 0) -... - -1.7. Exported Functions - -1.7.1. create_dialog([flags]) - - The function creats the dialog for the currently processed - request. The request must be an initial request. Optionally,the - function also receives a string parameter, which specifies - special behavior to be done for the current dialog. - - Parameters: - * flags (string, optional) Possible values here are : - + B - Upon reaching dialog lifetime, BYEs will be - triggered both ways - + P - Ping caller side with OPTIONS messages, once every - options_ping_interval seconds - + p - Ping callee side with OPTIONS messages, once every - options_ping_interval seconds - + R - Ping caller side with RE-INVITE messages, once - every reinvite_ping_interval seconds - + r - Ping callee side with RE-INVITE messages, once - every reinvite_ping_interval seconds - + E - Upon detecting a SIP Race condition (see RFC - 5407), end the call after race_condition_timeout - seconds - Multiple string flags can be used at the same time, ie. - passing "BPp" flags will enable all 3 flags. - - NOTE: both RE-INVITE and OPTIONS pinging cannot be enabled at - the same time for a single dialog leg. If both flags ("PR" or - "pr") are provided only RE-INVITE pinging will be used. - - The function returns true if the dialog was successfully - created or if the dialog was previously created. - - This function can be used from REQUEST_ROUTE. - - Example 1.54. create_dialog() usage -... -create_dialog(); -... -#ping caller -create_dialog("P"); -... -#ping caller and callee -create_dialog("Pp"); - -#bye on timeout -create_dialog("B"); -... - -1.7.2. match_dialog([dlg_match_mode]) - - This function is to be used to match a sequential (in-dialog) - request to an ongoing dialog. - - By default, dialog matching is performed according to the - dlg_match_mode module parameter. A specific matching mode may - be enforced by specifying the optional "dlg_match_mode" - parameter. Possible values for this parameter are "DID_ONLY", - "DID_FALLBACK" and "DID_NONE". - - As sequential requests are automatically matched to the dialog - when doing "loose_route()" from script, this function is - intended to: (A) control the place in your script where the - dialog matching is done and (B) to cope with bogus sequential - requests that do not have Route headers, so they are not - handled by loose_route(). - - Parameters: - * dlg_match_mode (string, optional) - - The function returns true if a dialog exists for the request. - - This function can be used from REQUEST_ROUTE. - - Example 1.55. match_dialog() usage -... - if (has_totag()) { - loose_route(); - - # example 1: match according to dlg_match_mode - if ($DLG_status == NULL && !match_dialog()) - xlog("cannot match request to a dialog\n"); - - # example 2: override dlg_match_mode - if ($DLG_status == NULL && !match_dialog("DID_FALLBACK")) - xlog("cannot match request to a dialog\n"); - } -... - -1.7.3. validate_dialog() - - The function checks the current received requests against the - dialog (internal data) it belongs to. Performing several tests, - the function will help to detect the bogus injected in-dialog - requests (like malicious BYEs). - - The performed tests are related to CSEQ sequence checking and - routing information checking (contact and route set). - - The function returns true if a dialog exists for the request - and if the request is valid (according to dialog data). If the - request is invalid, the following return codes are returned : - * -1 - invalid cseq - * -2 - invalid remote target - * -3 - invalid route set - * -4 - other errors ( parsing, no dlg, etc ) - - This function can be used from REQUEST_ROUTE. - - Example 1.56. validate_dialog() usage -... - if (has_totag()) { - loose_route(); - if ($DLG_status!=NULL && !validate_dialog() ) { - xlog(" in-dialog bogus request \n"); - } else { - xlog(" in-dialog valid request - $DLG_dir !\n"); - } - } -... - -1.7.4. fix_route_dialog() - - The function forces an in dialog SIP message to contain the - ruri, route headers and dst_uri, as specified by the internal - data of the dialog it belongs to. The function will prevent the - existence of bogus injected in-dialog requests ( like malicious - BYEs ) - - This function can be used from REQUEST_ROUTE. - - Example 1.57. fix_route_dialog() usage -... - if (has_totag()) { - loose_route(); - if ($DLG_status!=NULL) - if (!validate_dialog()) - fix_route_dialog(); - } -... - -1.7.5. get_dialog_info(attr,avp,key,key_val,no_dlgs) - - The function extracts a dialog value from another dialog. It - first searches through all existing (ongoing) dialogs for all - dialogs that have a dialog variable named "key" with the value - "key_val" (so a dialog where $dlg_val(key)=="key_val"). If - found, it returns the value of the dialog variable "attr" from - all the founds dialog in the "avp" pseudo-variable, otherwise - nothing is written in "avp", and a negative error code is - returned. - - NOTE: the function does not require to be called in the context - of a dialog - you can use it whenever / whereever for searching - for other dialogs. - - Meaning of the parameters is as follows: - * attr (string) - the name of the dialog variable (from the - found dialog) to be returned; - * avp (var) - an avp where to store the values of the "attr" - dialog variable. Since the function checks through all - dialogs, this needs to be an actual AVP in order to support - pushing values from all matched dialogs. - * key (string) - name of a dialog variable to be used a - search key (when looking after the target dialog) - * key_val (var) - the value of the dialog variable that is - used as key in searching the target dialog. - * no_dlgs (var) - the total number of dialogs containing the - key variable - - This function can be used from ALL ROUTES. - - Example 1.58. get_dialog_info usage -... -if ( get_dialog_info("callee",$avp(callee_array),"caller",$fu,$var(dlg_n -o)) ) { - xlog("caller $fu has $var(dlg_no) other ongoing calls, talking w -ith :"); - $var(it) = 0; - while ($var(it) < $var(dlg_no)) { - $var(current_callee) = $(avp(callee_array)[$var(it)]); - xlog(" $var(current_callee) "); - $var(it) = $var(it) + 1; - } - - xlog("\n"); -} - -# create dialog for current call and place the caller and callee attribu -tes -create_dialog(); -$dlg_val(caller) = $fu; -$dlg_val(callee) = $ru; -... - -1.7.6. get_dialog_vals(names,vals,callid) - - The function fetches all the dialog variables of another - dialog. It first searches through all existing (ongoing) - dialogs based on the given SIP CallID. If found, it returns all - the dialog variables as two parallel arrays of names and values - (using the given variables "names" and "vals"). As these - variables have to hold arrays, they must be AVPs. - - NOTE: the function does not require to be called in the context - of a dialog - you can use it whenever / whereever for searching - for other dialogs. - - Meaning of the parameters is as follows: - * names (var) - an AVP variable to hold all the names of the - variables from the found dialog. - * vals (var) - an AVP variable to hold all the values of the - variables from the found dialog. - * callid (string) - the callid of a dialog to be searched - (and have the variables fetched). - - This function can be used from any type of route. - - Example 1.59. get_dialog_vals usage -... -if ( get_dialog_vals($avp(d_names),$avp(d_vals),$var(callid)) ) { - xlog("the call $var(callid) has the variables:\n); - $var(i) = 0; - while ( $(avp(d_names)[$var(i)])!=NULL ) { - xlog("var $var(i) is $(avp(d_names)[$var(i)])='$(avp(d_v -als)[$var(i)])'\n"); - $var(i) = $var(i) + 1; - } -} -... - -1.7.7. get_dialogs_by_val(name,value,out_avp,out_dlg_no) - - The function looks up through the whole dialog table for - dialogs containing a $dlg_val with the provided name and value, - and returns all the $DLG_ctx_json variables for the matched - dialogs, storing them in the provided out_avp. The total number - of matched dialogs is returned in the out_dlgs_no variable - - NOTE: the function does not require to be called in the context - of a dialog - you can use it whenever / whereever for searching - for other dialogs. - - Meaning of the parameters is as follows: - * name (string) - the name of the dialog variable used for - the lookup - * value (var) - the value of the above dialog val - * out_avp (var) - the AVP which will be populated will the - dialog JSONs for all the matched calls - * dlg_no (var) - the out var which will contain the total - number of matched dialogs - - This function can be used from any type of route. - - Example 1.60. get_dialog_vals usage -... -if ( get_dialogs_by_val("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) { - xlog("Caller $fU has $avp(dlg_no) other calls \n); - $var(i) = 0; - while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { - $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); - # fetch any info for the above call and process it - $var(i) = $var(i) + 1; - } -} -... - -1.7.8. get_dialogs_by_profile(name,value,out_avp,out_dlg_no) - - The function looks up through the whole dialog table for - dialogs configured to be within the provided dialog profile - name, and optionally with the provided profile value. The - function returns all the $DLG_ctx_json variables for the - matched dialogs, storing them in the provided out_avp. The - total number of matched dialogs is returned in the out_dlgs_no - variable - - NOTE: the function does not require to be called in the context - of a dialog - you can use it whenever / whereever for searching - for other dialogs. - - Meaning of the parameters is as follows: - * name (string) - the name of the dialog profile used for the - lookup - * value (string) - the value of the above dialog profile ( - optional ) - * out_avp (var) - the AVP which will be populated will the - dialog JSONs for all the matched calls - * dlg_no (var) - the out var which will contain the total - number of matched dialogs - - This function can be used from any type of route. - - Example 1.61. get_dialog_vals usage -... -if ( get_dialogs_by_profile("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) - { - xlog("Caller $fU has $avp(dlg_no) other calls \n); - $var(i) = 0; - while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { - $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); - # fetch any info for the above call and process it - $var(i) = $var(i) + 1; - } -} -... - -1.7.9. load_dialog_ctx( dialog [, id_type]) - - The function loads and switches to the context of the given - dialog. The context of a dialog is given by the dialog flags, - variables, profiles and any other value/state related to the - dialog. By switching to the context of another dialog, you will - see at the script level, by default, all the data from the new - dialog. - - NOTE: you cannot perform a new load until doing an unload - no - nested loadings are possible. - - Meaning of the parameters is as follows: - * dialog (string) - the identifier of the dialog to be - loaded, it may be a SIP Call-ID or a Dialog ID. - * id_type (string,optional) - what kind of dialog identified - was used in the first parameter. It can be callid (SIP - Call-ID) or did (internal Dialog ID). By default callid - will be assumed. - - This function can be used from any type of route. - - Example 1.62. load_dialog_ctx usage -... -if (load_dialog_ctx("$var(callid)")) { - xlog("The dialog '$var(callid)' already has a duration " - "of $DLG_lifetime seconds\n"); - if (is_in_profile("inboundCall")) - xlog("this dialog is an inbound call\n"); - unload_dialog_ctx(); -} -... - -1.7.10. unload_dialog_ctx() - - The function off-loads the loaded context of another dialog, - exposing whatever dialog context was present before doing the - load. - - NOTE: you MUST perform from script an explicit unload for each - load you did, otherwise the loaded dialog will remain hanged - for ever. - - This function can be used from any type of route. - - For usage example, see the load_dialog_ctx() - -1.7.11. set_dlg_profile(profile, [value], [clear_values]) - - Inserts the current dialog into a profile. Note that if the - profile does not support values, this will be silently - discarded. A dialog may be inserted in the same profile - multiple times. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - Meaning of the parameters is as follows: - * profile (string) - name of the profile to be added to. - * value (string, optional) - string value to define the - belonging of the dialog to the profile - note that the - profile must support values. - * clear_values (boolean, optional) - if set to true (1), all - values of the profile will be cleared before setting the - given value. Default: false. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.63. set_dlg_profile usage -... -set_dlg_profile("inboundCall"); - -# Set a new value (all other values are kept intact) -set_dlg_profile("caller", $fu); - -# Set a new value while removing all previous values -set_dlg_profile("caller", $fu, true); -... - -1.7.12. unset_dlg_profile(profile, [value]) - - Removes the current dialog from a profile. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - Meaning of the parameters is as follows: - * profile (string) - name of the profile to be removed from. - * value (string, optional) - string value to define the - belonging of the dialog to the profile - note that the - profile must support values. - NEW in 3.4: for profiles with value, by omitting this - parameter you can now clear all values of the given - profile. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.64. unset_dlg_profile usage -... -unset_dlg_profile("inboundCall"); -unset_dlg_profile("caller", $fu); -... -# Remove all values in a profile -unset_dlg_profile("caller"); -... - -1.7.13. is_in_profile(profile,[value]) - - Checks if the current dialog belongs to a profile. If the - profile supports values, the check can be reinforced to take - into account a specific value - if the dialog was inserted into - the profile for a specific value. If no value is passed, only - simply belonging of the dialog to the profile is checked. Note - that if the profile does not support values, this will be - silently discarded. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - Meaning of the parameters is as follows: - * profile (string) - name of the profile to be checked - against. - * value (string. optional) - string value to toughen the - check. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.65. is_in_profile usage -... -if (is_in_profile("inboundCall")) { - log("this request belongs to a inbound call\n"); -} -... -if (is_in_profile("caller","XX")) { - log("this request belongs to a call of user XX\n"); -} -... - -1.7.14. get_profile_size(profile,[value],size) - - Returns the number of dialogs belonging to a profile. If the - profile supports values, the check can be reinforced to take - into account a specific value - how many dialogs were inserted - into the profile with a specific value. If not value is passed, - only simply belonging of the dialog to the profile is checked. - Note that the profile does not supports values, this will be - silently discarded. - - Meaning of the parameters is as follows: - * profile (string) - name of the profile to get the size for. - * value (string, optional) - string value to toughen the - check. - * size (var) - an AVP or script variable to return the - profile size in. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.66. get_profile_size usage -modparam("dialog", "profiles_no_value", "inboundCalls") -modparam("dialog", "profiles_with_value", "caller") -... -get_profile_size("inboundCalls",,$var(size)); -xlog("inboundCalls: $var(size)\n"); -... -get_profile_size("caller", $fu, $var(size)); -xlog("currently, the user $fu has $var(size) active outgoing calls\n"); -... - -1.7.15. set_dlg_flag(flag) - - Sets the dialog flag named flag to true. The dialog flags are - dialog persistent and they can be accessed (set and test) for - all requests belonging to the dialog. - - Parameters: - * flag (string, static) - The flag name. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.67. set_dlg_flag usage -... -set_dlg_flag("MY_DLG_FLAG"); -... - -1.7.16. test_and_set_dlg_flag(flag, value) - - Atomically checks if the dialog flag named flag is equal to - value. If true, changes the value with the opposite one. This - operation is done under the dialog lock. - * flag (string, static) - The flag name. - * value (int) - The value should be 0 (false) or 1 (true). - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.68. test_and_set_dlg_flag usage -... -test_and_set_dlg_flag("MY_DLG_FLAG", 0); -... - -1.7.17. reset_dlg_flag(flag) - - Resets the dialog flag named flag to false. The dialog flags - are dialog persistent and they can be accessed (set and test) - for all requests belonging to the dialog. - - Parameters: - * flag (string, static) - The flag name. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.69. reset_dlg_flag usage -... -reset_dlg_flag("MY_DLG_FLAG"); -... - -1.7.18. is_dlg_flag_set(flag) - - Returns true if the dialog flag named flag is set. The dialog - flags are dialog persistent and they can be accessed (set and - test) for all requests belonging to the dialog. - - Parameters: - * flag (string, static) - The flag name. - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.70. is_dlg_flag_set usage -... -if (is_dlg_flag_set("MY_DLG_FLAG")) { - xlog("dialog flag MY_DLG_FLAG is set\n"); -} -... - -1.7.19. store_dlg_value(name,val) - - Attaches to the dialog the value from the variable val under - the name name. The values attached to dialogs are dialog - persistent and they can be accessed (read and write) for all - requests belonging to the dialog. - - Parameters: - * name (string) - * val (var) - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - Same functionality may be obtain by assigning a value to pseudo - variable $dlg_val(name). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.71. store_dlg_value usage -... -store_dlg_value("inv_src_ip",$si); -store_dlg_value("account type",$var(account)); -# or -$dlg_val(account_type) = "prepaid"; -... - -1.7.20. fetch_dlg_value(name,val) - - Fetches from the dialog the value of attribute named name. The - values attached to dialogs are dialog persistent and they can - be accessed (read and write) for all requests belonging to the - dialog. - - Parameters: - * name (string) - * val (var) - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - Same functionality may be obtain by reading the pseudo variable - $dlg_val(name). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.72. fetch_dlg_value usage -... -fetch_dlg_value("inv_src_ip",$avp(2)); -fetch_dlg_value("account type",$var(account)); -# or -$var(account) = $dlg_val(account_type); -... - -1.7.21. set_dlg_sharing_tag(tag_name) - - Marks the current dialog with the sharing tag tag_name. From - this point on, actions like in-dialog pinging, BYEs on timeout - etc. will depend on the tag state(no action in "backup" state, - normal operation in "active" state). - - For more details see the Dialog clustering chapter. - - Parameters: - * tag_name (string) - - NOTE: the dialog must be created before using this function - (use create_dialog() function before). - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.73. set_dlg_sharing_tag usage -... -set_dlg_sharing_tag("vip1"); -... - -1.7.22. dlg_on_answer([route_name]) - - The function arms a script route to be executed when the - current dialog will be later answered. When the route will be - executed, the dialog context will be exposed, but with no valid - SIP message (just a phony one). - - You must use this function AFTER creating the dialog and before - the dialog being answered. - - If the parameter is missing, the function does a reset of any - route previously set; there will be no triggering. - - Parameters: - * route_name (string,optional) - the name of the script route - to be executed. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.74. dlg_on_answer usage -... -create_dialog(); -dlg_on_answer("dlg_answered"); -... -route[dlg_answered] { - xlog("The dialog $DLG_did was answered\n"); -} - -1.7.23. dlg_on_timeout([route_name]) - - The function arms a script route to be executed when (and if) - the current dialog will timeout (as duration). When the route - will be executed, the dialog context will be exposed, but with - no valid SIP message (just a phony one) - - When the route is executed, the dialog is not yet terminated, - just its lifetime reached the set limit. In the timeout route - you can increase the dialog expiration timeout (and the dialog - will continue) or you can let the dialog to be terminated - (after the end of this route). - - You must use this function AFTER creating the dialog and before - the dialog being answered. - - You must use this function AFTER creating the dialog and before - the dialog being answered. - - Parameters: - * route_name (string,optional) - the name of the script route - to be executed. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.75. dlg_on_timeout usage -... -create_dialog(); -$DLG_timeout=120; -dlg_on_timeout("dlg_timeout"); -... -route[dlg_timeout] { - xlog("The dialog $DLG_did timed out\n"); - if (_some_prolongation_condition) - $DLG_timeout = 60; # give it 1 min more -} - -1.7.24. dlg_on_hangup([route_name]) - - The function arms a script route to be executed when the - current dialog will be terminated. When the route will be - executed, the dialog context will be exposed, but with no valid - SIP message (just a phony one). Note that the dialog will be - already terminated and there is nothing you can do about it - besides reading data from its context. - - You must use this function AFTER creating the dialog and before - the dialog being answered. - - If the parameter is missing, the function does a reset of any - route previously set; there will be no triggering. - - Parameters: - * route_name (string,optional) - the name of the script route - to be executed. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - Example 1.76. dlg_on_hangup usage -... -create_dialog(); -dlg_on_hangup("dlg_hangup"); -... -route[dlg_hangup] { - xlog("The dialog $DLG_did terminated after $DLG_lifetime secs\n" -); -} - -1.7.25. dlg_send_sequential(method, leg, [, body] [, content-type] -[, headers]) - - Used to send an in-dialog request towards one if the dialog's - legs. The function assumes that is runs inside a dialog context - - if you are running it from a different context (such as an - event_route), make sure you first load the dialog context using - the load_dialog_ctx() function. - - Parameters: - * method (string) - the method of the request sent. - * leg (string) - the leg where the request is sent. Must be - either caller or callee. - * body (string, optional) - an optional body sent in the - request. If missing, no body is sent. - * content-type (string, optional) - the content type of the - body sent. Make sure you specify this every time you send a - request with a body, otherwise there are high changes that - your UAC will reject the request. - * headers (string, optional) - additional headers attached to - the request sent. - - This function can be used from ANY route. - - Example 1.77. dlg_send_sequential usage to convert DTMF codes -... -event_route[E_RTPPROXY_DTMF] { - if (load_dialog_ctx("$param(id)", "did")) { - if ($param(stream) == 0) { - $var(direction) = "callee"; - } else { - $var(direction) = "caller"; - } - dlg_send_sequential($var(direction), "INFO", - "Signal=$param(digit)\nDuration=160", - "application/dtmf-relay"); - unload_dialog_ctx(); - } -} -... - -1.7.26. dlg_inc_cseq([tag, ][inc]) - - Increments the dialog's generated CSeq associated to the leg - identified by the dialog's tag. - - Parameters: - * tag (string, optional) - the tag to increment the CSeq - value for. If missing, the message's To tag is used to - identify the leg to increment the CSeq for. - * inc (integer, optional) - the value used to - increment/decrement (if negative) the CSeq of the - identified leg. If not used, the value is incremented with - 1. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE routes. - - Example 1.78. dlg_inc_cseq usage -... -route { - ... - if (has_totag()) { - if (loose_route()) - dlg_inc_cseq(); # increment upstream CSeq after -each in-dialog request - } -} -... - -1.8. Exported Statistics - -1.8.1. active_dialogs - - Returns the number of current active dialogs (may be confirmed - or not). - -1.8.2. early_dialogs - - Returns the number of early dialogs. - -1.8.3. processed_dialogs - - Returns the total number of processed dialogs (terminated, - expired or active) from the startup. - -1.8.4. expired_dialogs - - Returns the total number of expired dialogs from the startup. - -1.8.5. failed_dialogs - - Returns the number of failed dialogs ( dialogs were never - established due to whatever reasons - internal error, negative - reply, cancelled, etc ) - -1.8.6. create_sent - - Returns the number of replicated dialog create requests send to - other OpenSIPS instances. - -1.8.7. update_sent - - Returns the number of replicated dialog update requests send to - other OpenSIPS instances. - -1.8.8. delete_sent - - Returns the number of replicated dialog delete requests send to - other OpenSIPS instances. - -1.8.9. create_recv - - Returns the number of dialog create events received from other - OpenSIPS instances. - -1.8.10. update_recv - - Returns the number of dialog update events received from other - OpenSIPS instances. - -1.8.11. delete_recv - - Returns the number of dialog delete events received from other - OpenSIPS instances. - -1.9. Exported MI Functions - -1.9.1. dlg_list - - Lists the description of the dialogs (calls). If no parameter - is given, all dialogs will be listed. If a dialog identifier is - passed as parameter (callid and fromtag), only that dialog will - be listed. If a index and conter parameter is passed, it will - list only a number of "counter" dialogs starting with index (as - offset) - this is used to get only section of dialogs. - - Name: dlg_list - - Parameters (with dialog idetification): - * callid (optional) - callid if a single dialog to be listed. - * from_tag (optional, but cannot be present without the - callid parameter) - fromtag (as per initial request) of the - dialog to be listed. entry - - Parameters (with dialog counting): - * index - offset where the dialog listing should start. - * counter - how many dialogs should be listed (starting from - the offset) - - MI FIFO Command Format: - ## list all ongoing dialogs - opensips-cli -x mi dlg_list - ## list the dialog by callid and From TAG - opensips-cli -x mi dlg_list callid=abcdrssfrs122444@192. -168.1.1 from_tag=AAdfeEFF33 - ## list 10 dialogs, starting from the position 40 - ## (in the list of all ongoing dialogs) - opensips-cli -x mi dlg_list index=40 counter=10 - -1.9.2. dlg_list_ctx - - The same as the “dlg_list” but including in the dialog - description the associated context from modules sitting on top - of the dialog module. This function also prints the dialog's - values. In case of binary values, the non-printable chars are - represented in hex (e.g. \x00) - - Name: dlg_list_ctx - - Parameters: see “dlg_list” - - MI FIFO Command Format: - opensips-cli -x mi dlg_list_ctx - -1.9.3. dlg_end_dlg - - Terminates an ongoing dialog. If dialog is established, BYEs - are sent in both directions. If dialog is in unconfirmed or - early state, a CANCEL will be sent to the callee side, that - will trigger a 487 from the callee, which, when relayed, will - also end the dialog on the caller's side. - - Name: dlg_end_dlg - - Parameters are: - * dialog_id - this is an identifier of the dialog - it can be - either (1) the unique ID of the dialog (as provided by - dlg_list), either (2) the SIP Call-ID of the dialog. - * extra_hdrs - (optional) string containg the extra headers - (full format) to be added to the BYE requests. - - The "dialog_id" value can be get via the "dlg_list" MI command. - - MI FIFO Command Format: - # terminate the dialog via the internal Dialog-ID - opensips-cli -x mi dlg_end_dlg 6ae.4b38d013 - # terminate the dialog via its SIP Call-ID - opensips-cli -x mi dlg_end_dlg Y2IwYjQ2YmE2ZDg5MWVkNDNkZ -GIwZjAzNGM1ZDY - -1.9.4. profile_get_size - - Returns the number of dialogs belonging to a profile. If the - profile supports values, the check can be reinforced to take - into account a specific value - how many dialogs were inserted - into the profile with a specific value. If not value is passed, - only simply belonging of the dialog to the profile is checked. - Note that the profile does not supports values, this will be - silently discarded. - - Name: profile_get_size - - Parameters: - * profile - name of the profile to get the value for. - * value (optional)- string value to toughen the check; - - MI FIFO Command Format: - opensips-cli -x mi profile_get_size inboundCalls - -1.9.5. profile_list_dlgs - - Lists all the dialogs belonging to a profile. If the profile - supports values, the check can be reinforced to take into - account a specific value - list only the dialogs that were - inserted into the profile with that specific value. If not - value is passed, all dialogs belonging to the profile will be - listed. Note that the profile does not supports values, this - will be silently discarded. Also, when using shared profiles - using the CacheDB interface, this command will only display the - local dialogs. - - Name: profile_list_dlgs - - Parameters: - * profile - name of the profile to list the dialog for. - * value (optional)- string value to toughen the check; - - MI FIFO Command Format: - opensips-cli -x mi profile_list_dlgs inboundCalls - -1.9.6. profile_get_values - - Lists all the values belonging to a profile along with their - count. If the profile does not support values a total count - will be returned. Note that this function does not work for - shared profiles over the CacheDB interface. - - Name: profile_get_values - - Parameters: - * profile - name of the profile to list the dialog for. - - MI FIFO Command Format: - opensips-cli -x mi profile_get_values inboundCalls - -1.9.7. profile_end_dlgs - - Terminate all ongoing dialogs from a specified profile, on a - single dialog it performs the same operations as the command - dlg_end_dlg - - Name: profile_end_dlgs - - Parameters: - * profile - name of the profile that will have its dialogs - termianted - * value - (optional) if the profile supports values terminate - only the dialogs with the specified value - - MI FIFO Command Format: - opensips-cli -x mi profile_end_dlgs inboundCalls - -1.9.8. dlg_db_sync - - Will load all the information about the dialogs from the - database in the OpenSIPS internal memory. If a dialog is - already found in memory and has the same/an older state, it - will be updated with the values from DB. Otherwise, the newer - in-memory version will not be changed. - - Name: dlg_db_sync - - It takes no parameters - - MI FIFO Command Format: - opensips-cli -x mi dlg_db_sync - -1.9.9. dlg_cluster_sync - - This command will only take effect if dialog replication is - enabled. - - Fully synchronize the dialog information in memory from a - suitable donor node within the dialog_replication_cluster. - Dialogs that already exist in memory which are not reconfirmed - through syncing will be discarded. A sharing tag can be - specified in order to sync only dialogs marked with that - sharing tag. - - Name: dlg_cluster_sync - - Parameters: - * sharing_tag - name of the sharing tag that dialogs have to - be marked with in order to be synced - - MI FIFO Command Format: - opensips-cli -x mi dlg_cluster_sync vip1 - -1.9.10. dlg_restore_db - - Restores the dialog table after a potential desynchronization - event. The table is truncated, then populated with CONFIRMED - dialogs from memory. - - Name: dlg_restore_db - - It takes no parameters - - MI FIFO Command Format: - opensips-cli -x mi dlg_restore_db - -1.9.11. list_all_profiles - - Lists all the dialog profiles, along with 1 or 0 if the given - profile has/does not have an associated value. - - Name: list_all_profiles - - Parameters: It takes no parameters - - MI FIFO Command Format: - opensips-cli -x mi list_all_profiles - -1.9.12. dlg_push_var - - Push or update a dialog value for the given list of dialog IDs - / Call-IDs. - - Name: dlg_push_var - - Parameters: It takes 3 or more parameters - * dlg_val_name - name of the dialog value that needs to be - inserted/updated - * dlg_val_value - value to be inserted/updated - * DID - dialog identifier. Can be either the $DLG_did or the - actual Call-ID. - - MI FIFO Command Format: - opensips-cli -x mi dlg_push_var var_name var_value DID1 -[ DID2 DID3 ... DIDN ] - -1.9.13. dlg_send_sequential - - Sends a sequential request within an ongoing dialog. - - Name: dlg_send_sequential - - Parameters: - * callid - the callid of the dialog you need to trigger the - sequential message for. - * method - (optional) the method used for the sequential - message. Default value is INVITE. - * mode - (optional) can be used to tune the behavior of the - sequential message. Possible values for the mode are: - + caller - (default) sends the sequential message to the - caller. This mode can be useful in high availability - scenarios when you want to update the upstream's - routing set, specifically the contact. - + callee - same as caller, but sends the sequential - message to the callee. - + challenge - sends a sequential INVITE (or UPDATE) to - the caller to challenge it for its advertised SDP - body. When the body is received, it is forwarded to - the callee. This mode is useful when trying to change - both endpoints (upstream and downstream) routing set. - It can also be useful when trying to trigger a - re-negotiation for SDP body. - + challenge-caller - same as challenge - + challenge-callee - same as challenge-caller, only that - it first challenges the callee, instead of the caller. - * body - (optional) can be used to specify a body for the - initial sequential message. Possible values for the body - parameter are: - + none - (default) no body added to the sequential - message. - + inbound - advertises in the body of the sequential - message generated the last body received from its - pair. For example, if the mode=challenge-caller, the - message will contain the body sent to OpenSIPS by the - callee. This is useful when you need to alter the body - previously sent to the caller, because you want to - re-negotiate a different media proxy for the call. - This can be achieved by catching the generated request - in local_route, and re-engage the Media proxy. - + outbound - advertises in the body of the sequential - message generated the last body sent to that UAC. For - example, if the mode=challenge-caller, the message - will contain the last body sent by OpenSIPS to the - caller. This is useful in a high availability scenario - when trying to re-negotiate the contact of the server, - but there is no need to alter the body sent earlier. - + custom:CONTENT_TYPE:BODY - this can be used to specify - a specific Content-Type ehader and body for the - sequential message generated. - * headers - (optional) can be used to specify some headers - for the initial sequential message. - - This functions runs asynchronously and returns the status code - and reason of the last reply received for either the challenge - or normal mode. - - MI Command Format: - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 - - MI Command used to trigger media re-negotiation: - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 \ - mode=challenge \ - body=inbound - - MI Command used to UPDATE the callee's remote Contact after a - server failover: - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 \ - mode=challenge-callee \ - body=outbound \ - method=UPDATE - - MI Command used to send REFER to the callee, and add Refer-To - header: - opensips-cli -x mi dlg_send_sequential \ - callid=usR8FlGOSMfCTAIHebHCOQ.. \ - method=REFER \ - body=none \ - mode=callee \ - headers='Refer-To: sip:user@domain:50060 -' - -1.9.14. set_dlg_profile - - Set the dialog identified by dialog ID / Call-ID into the given - profile ( with optional value and clearing of the old profile - values ) - - Name: set_dlg_profile - - Parameters: It takes 2-4 parameters - * dlg_id - dialog ID or Call-ID for the respective dialog - * profile - profile name to be set - * value - optional, the profile value to be set - * clear_values - optional, clear previous values in the - profile before setting the new one - - MI FIFO Command Format: - opensips-cli -x mi set_dlg_profile DID my_profile my_val -ue 1 - -1.9.15. unset_dlg_profile - - Unsets the dialog identified by dialog ID / Call-ID from the - given profile ( with optional value and clearing of the old - profile values ) - - Name: set_dlg_profile - - Parameters: It takes 2-3 parameters - * dlg_id - dialog ID or Call-ID for the respective dialog - * profile - profile name to be unset - * value - optional, the profile value to be unset. for - profiles with value, by omitting this parameter you can now - clear all values of the given profile. - - MI FIFO Command Format: - opensips-cli -x mi unset_dlg_profile DID my_profile my_v -alue - -1.10. Exported Pseudo-Variables - -1.10.1. $DLG_count - - Returns the number of current active dialogs (may be confirmed - or not). - -1.10.2. $DLG_status - - Returns the status of the dialog corresponding to the processed - sequential request. This PV will be available only for - sequential requests, after doing loose_route(). - - Value may be: - * NULL - Dialog not found. - * 1 - Dialog unconfirmed (created but no reply received at - all) - * 2 - Dialog in early state (created provisional reply - received, but no final reply received yet) - * 3 - Confirmed by a final reply but no ACK received yet. - * 4 - Confirmed by a final reply and ACK received. - * 5 - Dialog ended. - -1.10.3. $DLG_lifetime - - Returns the duration (in seconds) of the dialog corresponding - to the processed sequential request. The duration is calculated - from the dialog confirmation and the current moment. This PV - will be available only for sequential requests, after doing - loose_route(). - - NULL will be returned if there is no dialog for the request. - -1.10.4. $DLG_flags - - Returns the dialog flags (as a list of flag names separted by - space) of the dialog corresponding to the processed sequential - request. This PV will be available only for sequential - requests, after doing loose_route(). - - NULL will be returned if there is no dialog for the request. - -1.10.5. $DLG_dir - - Returns the direction of the request in dialog (as "upstream" - string if the request is generated by callee or "downstream" - string if the request is generated by caller) - to be used for - sequential request. This PV will be available only for - sequential requests (not for replies), after doing - loose_route(). - - NULL will be returned if there is no dialog for the request. - -1.10.6. $DLG_did - - Returns the id of the dialog corresponding to the processed - sequential request. The output format is a string identical to - the one returned by the dlg_list MI function. This PV will be - available only for sequential requests, after doing - loose_route(). - - NULL will be returned if there is no dialog for the request. - -1.10.7. $DLG_end_reason - - Returns the reason for the dialog termination. It can be one of - the following : - * Upstream BYE - Callee has sent a BYE - * Downstream BYE - Caller has sent a BYE - * Lifetime Timeout - Dialog lifetime expired - * MI Termination - Dialog ended via the MI interface - * Ping Timeout - Dialog ended because no reply to option - pings - * ReINVITE Ping Timeout - Dialog ended because no reply to - reinvite pings - * RTPProxy Timeout - Media timeout signaled by RTPProxy - * SIP Race Condition - SIP Race Condition occurred - - NULL will be returned if there is no dialog for the request, or - if the dialog is not ended in the current context. - -1.10.8. $DLG_timeout - - Used to set the dialog lifetime (in seconds). When read, the - variable returns the number of seconds until the dialog expires - and is destroyed. Note that reading the variable is only - possible after the dialog is created (for initial requests) or - after doing loose_route() (for sequential requests). Important - notice: using this variable with a REALTIME db_mode is very - inefficient, because every time the dialog value is changed, a - database update is done. - - NULL will be returned if there is no dialog for the request, - otherwise the number of seconds until the dialog expiration. - -1.10.9. $DLG_del_delay - - Used to set the dialog deletion delay (in seconds) for the - current dialog (in a per-call manner). When read, the variable - returns the number of seconds that were set for the call or the - default value ( see the “delete_delay” - delete_delay) module - param) for the delete delaying. - - The variable must be used when the context of a dialog is - available in script. - -1.10.10. $DLG_json - - The variable is read-only and exposes a JSON variable - containing all the information that the dlg_list MI function - contains - - NULL will be returned if there is no dialog for the request, - otherwise the JSON will be returned. - -1.10.11. $DLG_ctx_json - - The variable is read-only and exposes a JSON variable - containing all the information that the dlg_list_ctx MI - function contains ( on top of $DLG_json, this will expose the - full list of dialog vars and profile links for the current - dialog ) - - NULL will be returned if there is no dialog for the request, - otherwise the JSON will be returned. - -1.10.12. $dlg_val(name) - - This is a read/write variable that allows access to the dialog - attribute named name. It can hold a string or integer value. - - Be sure and use this variable only when having a dialog context - (like after create_dialog() or match_dialog() or equivalent). - - The variable accepts dynamic names, meaning the name may - contain other variables. - - NULL will be returned if there is no dialog for the request. - -1.11. Exported Events - -1.11.1. E_DLG_STATE_CHANGED - - This event is raised when the dialog state is changed. - - Parameters: - * id - the hex representation of the dialog id. - * db_id - the integer representation of the dialog id, as it - is stored in the database dlg_id field. - * callid - the callid. - * from_tag - the From tag. - * to_tag - the To tag. - * old_state - the old state of the dialog. - * new_state - the new state of the dialog. - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. register_dlgcb (dialog, type, cb, param, free_param_cb) - - Register a new callback to the dialog. - - Meaning of the parameters is as follows: - * struct dlg_cell* dlg - dialog to register callback to. If - maybe NULL only for DLG_CREATED callback type, which is not - a per dialog type. - * int type - types of callbacks; more types may be register - for the same callback function; only DLG_CREATED must be - register alone. Possible types: - + DLGCB_LOADED - called when a dialog is loaded from the - database, or received by a node using the cluster - replication. - + DLGCB_SAVED - + DLG_CREATED - called when a new dialog is created - - it's a global type (not associated to any dialog) - + DLG_FAILED - called when the dialog was negatively - replied (non-2xx) - it's a per dialog type. - + DLG_CONFIRMED - called when the dialog is confirmed - (2xx replied) - it's a per dialog type. - + DLG_REQ_WITHIN - called when the dialog matches a - sequential request - it's a per dialog type. - + DLG_TERMINATED - called when the dialog is terminated - via BYE, or by the mi dlg_end_dlg command - it's a per - dialog type. - + DLG_EXPIRED - called when the dialog expires without - receiving a BYE - it's a per dialog type. Note that - when using replication sharing tags, this callback is - only executed by the node that has the Active tag. - + DLGCB_EARLY - called when the dialog is created in an - early state (18x replied) - it's a per dialog type. - + DLGCB_RESPONSE_FWDED - called when the dialog matches - a reply to the initial INVITE request - it's a per - dialog type. - + DLGCB_RESPONSE_WITHIN - called when the dialog matches - a reply to a subsequent in dialog request - it's a per - dialog type. - + DLGCB_MI_CONTEXT - called when the mi dlg_list_ctx - command is invoked - it's a per dialog type. - + DLGCB_DESTROY - * dialog_cb cb - callback function to be called. Prototype - is: “void (dialog_cb) (struct dlg_cell* dlg, int type, - struct dlg_cb_params * params); ” - * void *param - parameter to be passed to the callback - function. - * param_free callback_param_free - callback function to be - called to free the param. Prototype is: “void - (param_free_cb) (void *param);” - -Chapter 3. Frequently Asked Questions - - 3.1. - - What happened with “topology_hiding()” function? - - The respective functionality was moved into the topology_hiding - module. Function prototype has remained the same. - - 3.2. - - What happened with “use_tight_match” parameter? - - The parameter was removed with version 1.3 as the option of - tight matching became mandatory and not configurable. Now, the - tight matching is done all the time (when using DID matching). - - 3.3. - - What happened with “bye_on_timeout_flag” parameter? - - The parameter was removed in a dialog module parameter - restructuring. To keep the bye on timeout behavior, you need to - provide a "B" string parameter to the create_dialog() function. - - 3.4. - - What happened with “dlg_flag” parameter? - - The parameter is considered obsolete. The only way to create a - dialog is to call the create_dialog() function - - 3.5. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 3.6. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 3.7. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 460 288 13367 3546 - 2. Razvan Crainea (@razvancrainea) 299 222 5499 1804 - 3. Vlad Paiu (@vladpaiu) 262 149 7467 3027 - 4. Vlad Patrascu (@rvlad-patrascu) 200 104 4330 3514 - 5. Liviu Chircu (@liviuchircu) 183 133 3128 1374 - 6. Ovidiu Sas (@ovidiusas) 35 26 601 161 - 7. Dan Pascu (@danpascu) 30 25 233 179 - 8. Eseanu Marius Cristian (@eseanucristian) 19 6 722 341 - 9. Daniel-Constantin Mierla (@miconda) 16 13 76 66 - 10. Henning Westerholt (@henningw) 16 10 172 187 - - All remaining contributors: Anca Vamanu, Walter Doekes - (@wdoekes), Ionut Ionita (@ionutrazvanionita), Maksym Sobolyev - (@sobomax), Ionel Cerghit (@ionel-cerghit), Andrei Dragus, - Alexandra Titoc, John Riordan, Hugues Mitonneau, Carsten Bock, - Peter Lemenkov (@lemenkov), Jerome Martin, Klaus Darilion, - Jarrod Baumann (@jarrodb), Nick Altmann (@nikbyte), Zero King - (@l2dy), Michel Bensoussan, Richard Revels, Tavis Paquette, - Elena-Ramona Modroiu, Ryan Bullock, Andrei Datcu - (@andrei-datcu), Jeffrey Magder, Stefan-Cristian Mititelu, Ron - Winacott, Andy Pyles, Julián Moreno Patiño, Konstantin - Bokarius, sergei lavrov, Alex Massover, Damien Sandras - (@dsandras), Alex Hermann, Dusan Klinec (@ph4r05), Norman - Brandinger (@NormB), UnixDev, Eliot Gable, Ryan Bullock - (@rrb3942), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2010 - Sep 2025 - 2. Vlad Paiu (@vladpaiu) Oct 2010 - Jan 2025 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2006 - Jun 2024 - 5. Stefan-Cristian Mititelu Jan 2024 - Jan 2024 - 6. Maksym Sobolyev (@sobomax) Nov 2020 - Nov 2023 - 7. Vlad Patrascu (@rvlad-patrascu) Jul 2016 - Jun 2023 - 8. Ovidiu Sas (@ovidiusas) Feb 2008 - Jun 2023 - 9. Ryan Bullock May 2023 - May 2023 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Sep 2022 - - All remaining contributors: Nick Altmann (@nikbyte), Walter - Doekes (@wdoekes), Liviu Chircu (@liviuchircu), sergei lavrov, - Zero King (@l2dy), Dan Pascu (@danpascu), Ionel Cerghit - (@ionel-cerghit), Jarrod Baumann (@jarrodb), Ionut Ionita - (@ionutrazvanionita), Julián Moreno Patiño, Dusan Klinec - (@ph4r05), Eseanu Marius Cristian (@eseanucristian), Andrei - Datcu (@andrei-datcu), Norman Brandinger (@NormB), Damien - Sandras (@dsandras), Ryan Bullock (@rrb3942), Anca Vamanu, Alex - Massover, Andrei Dragus, John Riordan, Hugues Mitonneau, - Richard Revels, UnixDev, Alex Hermann, Henning Westerholt - (@henningw), Carsten Bock, Klaus Darilion, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Jerome Martin, Tavis Paquette, Michel Bensoussan, Eliot Gable, - Andy Pyles, Elena-Ramona Modroiu, Jeffrey Magder, Ron Winacott. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu - (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Stefan-Cristian Mititelu, Ryan Bullock, - Vlad Patrascu (@rvlad-patrascu), Zero King (@l2dy), Dan Pascu - (@danpascu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, - Ionut Ionita (@ionutrazvanionita), Ionel Cerghit - (@ionel-cerghit), Walter Doekes (@wdoekes), Eseanu Marius - Cristian (@eseanucristian), Norman Brandinger (@NormB), Anca - Vamanu, Andrei Dragus, Hugues Mitonneau, Klaus Darilion, - Henning Westerholt (@henningw), Ovidiu Sas (@ovidiusas), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Michel Bensoussan, Andy Pyles, Elena-Ramona - Modroiu. - - Documentation Copyrights: - - Copyright © 2006-2009 Voice Sistem SRL diff --git a/modules/dialog/README.md b/modules/dialog/README.md new file mode 100644 index 00000000000..2a8e097f964 --- /dev/null +++ b/modules/dialog/README.md @@ -0,0 +1,3126 @@ +--- +title: "dialog Module" +description: "The dialog module provides dialog awareness to the OpenSIPS proxy." +--- + +## Admin Guide + + +### Overview + + +The dialog module provides dialog awareness to the OpenSIPS proxy. Its +functionality is to keep trace of the current dialogs, to offer information +about them (like how many dialogs are active). + + +Aside tracking, the dialog module offers functionalities like flags and +attributes per dialog (persistent data across dialog), dialog profiling +and dialog termination (on timeout base or external triggered). + + +The module, via an internal API, also provide the foundation to build on +top of it more complex dialog-based functionalities via other OpenSIPS +modules. + + +### How it works + + +To create the dialog associated with an initial request, you must call +the create_dialog() function, with or without parameter. + + +The dialog is automatically terminated when a "BYE" is +received. In case of no "BYE", the dialog lifetime is +controlled via the default timeout (see "default_timeout" + - [default timeout](#param_default_timeout)) and custom timeout (see +"$DLG_timeout" - [DLG timeout](#pv_DLG_timeout)). + + +Once terminated, the in-memory dialog may be destroyed right away or, +depending on the "delete_delay" + - [delete delay](#param_delete_delay)) setting, it may be kept for a +while in memory, in a read-only state (no action, no changes, nothing). +This delaying may be used to help with the routing of late in-dialog +request that may be received after the dialog terminted (like late BYE's +due retransmissions, cross BYE requests, auth'ed BYE request, slow ACK on +re-INVITEs, etc). + + +### Dialog profiling + + +Dialog profiling is a mechanism that helps in classifying, sorting and +keeping trace of certain types of dialogs, using whatever properties of +the dialog (like caller, destination, type of calls, etc). +Dialogs can be dynamically added in different (and several) profile +tables - logically, each profile table can have a special meaning (like +dialogs outside the domain, dialogs terminated to PSTN, etc). + + +There are two types of profiles: + + +- *with no value* - a dialog simply belongs +to a profile. (like outbound calls profile). There is no other +additional information to describe the dialog's belonging to the +profile; +- *with value* - a dialog belongs to a profile +having a certain value (like in caller profile, where the value +is the caller ID). The belonging of the dialog to the profile is +strictly related to the value. + + +A dialog can be added to multiple profiles in the same time. + + +Profiles are visible (at the moment) in the request route (for initial +and sequential requests) and in the branch, failure and reply routes of +the original request. + + +Dialog profiles can also be used in distributed systems, using the OpenSIPS +CacheDB Interface or the *clusterer* module. This feature +allows you to share dialog profile information with multiple OpenSIPS instaces +that use the same CacheDB backend or are part of an OpenSIPS cluster. In order +to do that, the **cachedb_url** or +**profile_replication_cluster** parameters must be defined. +Also, the profile must be marked as shared, by adding one of the +*'/s'* or *'/b'* suffixes to the name of +the profile in the *profiles_with_value* or +*profiles_no_value* parameters. + + +### Dialog clustering + + +**Dialog replication** is a mechanism used to +mirror all dialog changes taking place in one OpenSIPS instance to one or +multiple other instances. The process is simplified by using the +*clusterer* module which facilitates the management of a +cluster of OpenSIPS nodes and the sending of replication-related BIN packets +(binary-encoded, using *proto_bin*). This feature +is useful in achieving High Availability and/or Load Balancing for ongoing calls. + + +Configuring both receival and sending of dialog replication packets is trivial +and can be done by using the +**dialog_replication_cluster** parameter. But in +addition to just sharing data, in order to properly cluster dialogs you will +need to manage which node in the cluster is doing certain actions on certain +dialogs using the **sharing tags** mechanism. +For details and configuration examples on how this would work +in different usage scenarios, see +[this article](https://blog.opensips.org/2018/03/23/clustering-ongoing-calls-with-opensips-2-4/). + + +The following actions will **not** be performed for a dialog +marked with a sharing tag that is in the "**backup**" state: + + +- sending Re-Invite or OPTIONS pings to end-points +- generating BYE requests or any other actions(like producing CDRs) +upon dialog expiration +- sending replication packets on dialog events(update, delete) +- counting the dialog in the profiles that it belongs; only if profile replication +is also enabled + + +In addition to the event-driven replication, an OpenSIPS instance will first +try to learn all the dialog information from antoher node in the cluster at startup. +The data synchronization mechanism requires defining one of the nodes in the cluster +as a "**seed**" node. +See the [clusterer](../clusterer#capabilities) +module for details on how to do this and why is it needed. + + +In the context of dialog replication, using a database as a failsafe for obtaining +restart persistency for dialog data is useful in case all nodes in the cluster are down. +This approach makes the most sense if a separate, local DB is used for each node in the +cluster. Dialogs loaded from the database at startup, which are not reconfirmed through +syncing, are dropped and also deleted from the database once the sync from cluster is complete. + + +Also configuring profile replication via the *profile_replication_cluster* +parameter is not necessary when dialog replication is already configured. The profile information +is included in the dialog updates sent in the dialog replication cluster. The profiles must still +be marked for sharing though in the *profiles_with_value* or +*profiles_no_value* parameters. + + +A scenario were both profile and dialog replication should be configured is when a platform has +multiple POPs, where separate dialog replication clusters are configured for HA purposes, and a +cluster for globally shared profiles is also required. In this case, proper counting for dialogs +is ensured by using the sharing tags mechanism(in order to avoid counting each dialog twice, +both on the active and backup node for that dialog). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM* - Transaction module +- *RR* - Record-Route module, optional, +if Dialog ID matching is used in non Topo Hiding cases +- *clusterer* - if *replication_cluster* +parameter is set (contact replication via clusterer +module) + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### enable_stats (integer) + + +If the statistics support should be enabled or not. Via statistic +variables, the module provide information about the dialog processing. +Set it to zero to disable or to non-zero to enable it. + + +*Default value is "1 (enabled)".* + + +```opensips title="Set enable_stats parameter" +... +modparam("dialog", "enable_stats", 0) +... +``` + + +#### hash_size (integer) + + +The size of the hash table internally used to keep the dialogs. A +larger table is much faster but consumes more memory. The hash size +must be a power of 2 number. + + +IMPORTANT: If dialogs' information should be stored in a database, +a constant hash_size should be used, otherwise the restored process +will not take place. If you really want to modify the hash_size you +must delete all table's rows before restarting OpenSIPS. + + +*Default value is "4096".* + + +```opensips title="Set hash_size parameter" +... +modparam("dialog", "hash_size", 1024) +... +``` + + +#### log_profile_hash_size (integer) + + +The size of the hash table internally used to store profile->dialog +associations. A larger table can provide more +parallel operations but consumes more memory. The hash size +is provided as the base 2 logarithm(e.g. log_profile_hash_size =4 +means the table has 2^4 entries). + + +*Default value is "4".* + + +```opensips title="Set hash_size parameter" +... +modparam("dialog", "log_profile_hash_size", 5) #set a table size of 32 +... +``` + + +#### rr_param (string) + + +Name of the Record-Route parameter to be added with the dialog cookie. +It is used for fast dialog matching of the sequential requests. + + +*Default value is "did".* + + +```opensips title="Set rr_param parameter" +... +modparam("dialog", "rr_param", "xyz") +... +``` + + +#### default_timeout (integer) + + +The default dialog timeout (in seconds) if no custom one is set. + + +*Default value is "43200 (12 hours)".* + + +```opensips title="Set default_timeout parameter" +... +modparam("dialog", "default_timeout", 21600) +... +``` + + +#### dlg_extra_hdrs (string) + + +A string containing the extra headers (full format, with EOH) +to be added in the requests generated by the module (like BYEs). + + +*Default value is "NULL".* + + +```opensips title="Set dlf_extra_hdrs parameter" +... +modparam("dialog", "dlg_extra_hdrs", "Hint: credit expired\r\n") +... +``` + + +#### dlg_match_mode (integer) + + +How the seqential requests should be matched against the known dialogs. +The modes are a combination between matching based on a cookie (DID) +stored as cookie in Record-Route header and the matching based on SIP +elements (as in RFC3261). + + +The supported modes are: + + +- *0 - DID_ONLY* - the match is done +exclusively based on DID; +- *1 - DID_FALLBACK* - the match is first +tried based on DID and if not present, it will fallback to +SIP matching; +- *2 - DID_NONE* - the match is done +exclusively based on SIP elements; no DID information is added +in RR. + + +*Default value is "1 (DID_FALLBACK)".* + + +NOTE that if you have call looping on your OpenSIPS server (passing +more than once through the same OpenSIPS instance), it is strongly +suggested to use only DID_ONLY mode, as the SIP based matching will +have an undefined behavior - from SIP perspective, a sequential +dialog will match all the loops of the call, as the Call-ID, To and +From TAGs are the same. + + +```opensips title="Set dlg_match_mode parameter" +... +modparam("dialog", "dlg_match_mode", 0) +... +``` + + +#### delete_delay (integer) + + +The interval (seconds) to delay a dialog deletion / removal from +memory AFTER its termination. Once terminated, the dialog will +be kept in a read only state (no action, no changes), but it will +still be able to match and route late in-dialog requests. + + +This global value may be per-call changed via the DLG_del_delay +"$DLG_del_delay" ([DLG del delay](#pv_DLG_del_delay)) +script variable. + + +*Default value is "0" (disabled).* + + +```opensips title="Set delete_delay parameter" +... +modparam("dialog", "delete_delay", 10) +... +``` + + +#### db_url (string) + + +If you want to store the information about the dialogs in a database +a database url must be specified. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("dialog", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### db_mode (integer) + + +Describe how to push into the DB the dialogs' information from memory. + + +The supported modes are: + + +- *0 - NO_DB* - the memory content is not +flushed into DB; +- *1 - REALTIME* - any dialog information +changes will be reflected into the database immediately. +- *2 - DELAYED* - the dialog information +changes will be flushed into the DB periodically, based on a +timer routine. +- *3 - SHUTDOWN* - the dialog information +will be flushed into DB only at shutdown - no runtime updates. + + +*Default value is "0".* + + +```opensips title="Set db_mode parameter" +... +modparam("dialog", "db_mode", 1) +... +``` + + +#### db_update_period (integer) + + +The interval (seconds) at which to update dialogs' information if you chose to store the dialogs' info at a given interval. +A too short interval will generate intensive database operations, a too large one will not notice short dialogs. + + +*Default value is "60".* + + +```opensips title="Set db_update_period parameter" +... +modparam("dialog", "db_update_period", 120) +... +``` + + +#### options_ping_interval (integer) + + +The interval (seconds) at which OpenSIPS will generate in-dialog +OPTIONS pings for one or both of the involved parties. + + +*Default value is "30".* + + +```opensips title="Set options_ping_interval parameter" +... +modparam("dialog", "options_ping_interval", 20) +... +``` + + +#### reinvite_ping_interval (integer) + + +The interval (seconds) at which OpenSIPS will generate in-dialog +Re-INVITE pings for one or both of the involved parties. + + +**Important:** the ping timeout detection +is performed every time this interval ticks, not when the re-INVITE +transaction times out! Consequently, please make sure that the +timeouts for re-INVITE transactions (e.g. the "fr_timeout" +modparam of the "tm" module or its $T_fr_timeout variable) are +always **lower** than the value of this +parameter! Failing to ensure this ordering of timeouts may possibly +lead to re-INVITE pings never ending a disconnected dialog due to pings +getting retried before getting a chance to properly time out. + + +*Default value is "300".* + + +```opensips title="Set reinvite_ping_interval parameter" +... +modparam("dialog", "reinvite_ping_interval", 600) +... +``` + + +#### table_name (string) + + +If you want to store the information about the dialogs in a +database a table name must be specified. + + +*Default value is "dialog".* + + +```opensips title="Set table_name parameter" +... +modparam("dialog", "table_name", "my_dialog") +... +``` + + +#### call_id_column (string) + + +The column's name in the database to store the dialogs' callid. + + +*Default value is "callid".* + + +```opensips title="Set call_id_column parameter" +... +modparam("dialog", "call_id_column", "callid_c_name") +... +``` + + +#### from_uri_column (string) + + +The column's name in the database to store the caller's +sip address. + + +*Default value is "from_uri".* + + +```opensips title="Set from_uri_column parameter" +... +modparam("dialog", "from_uri_column", "from_uri_c_name") +... +``` + + +#### from_tag_column (string) + + +The column's name in the database to store the From tag from +the Invite request. + + +*Default value is "from_tag".* + + +```opensips title="Set from_tag_column parameter" +... +modparam("dialog", "from_tag_column", "from_tag_c_name") +... +``` + + +#### to_uri_column (string) + + +The column's name in the database to store the calee's sip address. + + +*Default value is "to_uri".* + + +```opensips title="Set to_uri_column parameter" +... +modparam("dialog", "to_uri_column", "to_uri_c_name") +... +``` + + +#### to_tag_column (string) + + +The column's name in the database to store the To tag from +the 200 OK response to the Invite request, if present. + + +*Default value is "to_tag".* + + +```opensips title="Set to_tag_column parameter" +... +modparam("dialog", "to_tag_column", "to_tag_c_name") +... +``` + + +#### from_cseq_column (string) + + +The column's name in the database to store the cseq from caller +side. + + +*Default value is "caller_cseq".* + + +```opensips title="Set from_cseq_column parameter" +... +modparam("dialog", "from_cseq_column", "from_cseq_c_name") +... +``` + + +#### to_cseq_column (string) + + +The column's name in the database to store the cseq from callee +side. + + +*Default value is "callee_cseq".* + + +```opensips title="Set to_cseq_column parameter" +... +modparam("dialog", "to_cseq_column", "to_cseq_c_name") +... +``` + + +#### from_route_column (string) + + +The column's name in the database to store the route records from +caller side (proxy to caller). + + +*Default value is "caller_route_set".* + + +```opensips title="Set from_route_column parameter" +... +modparam("dialog", "from_route_column", "from_route_c_name") +... +``` + + +#### to_route_column (string) + + +The column's name in the database to store the route records from +callee side (proxy to callee). + + +*Default value is "callee_route_set".* + + +```opensips title="Set to_route_column parameter" +... +modparam("dialog", "to_route_column", "to_route_c_name") +... +``` + + +#### from_contact_column (string) + + +The column's name in the database to store the caller's contact +uri. + + +*Default value is "caller_contact".* + + +```opensips title="Set from_contact_column parameter" +... +modparam("dialog", "from_contact_column", "from_contact_c_name") +... +``` + + +#### to_contact_column (string) + + +The column's name in the database to store the callee's contact +uri. + + +*Default value is "callee_contact".* + + +```opensips title="Set to_contact_column parameter" +... +modparam("dialog", "to_contact_column", "to_contact_c_name") +... +``` + + +#### from_sock_column (string) + + +The column's name in the database to store the information about +the local interface receiving the traffic from caller. + + +*Default value is "caller_sock".* + + +```opensips title="Set from_sock_column parameter" +... +modparam("dialog", "from_sock_column", "from_sock_c_name") +... +``` + + +#### to_sock_column (string) + + +The column's name in the database to store information about the +local interface receiving the traffic from callee. + + +*Default value is "callee_sock".* + + +```opensips title="Set to_sock_column parameter" +... +modparam("dialog", "to_sock_column", "to_sock_c_name") +... +``` + + +#### dlg_id_column (string) + + +The column's name in the database to store the dialogs' +id information. + + +*Default value is "dlg_id".* + + +```opensips title="Set dlg_id_column parameter" +... +modparam("dialog", "dlg_id_column", "dlg_id_c_name") +... +``` + + +#### state_column (string) + + +The column's name in the database to store the +dialogs' state information. + + +*Default value is "state".* + + +```opensips title="Set state_column parameter" +... +modparam("dialog", "state_column", "state_c_name") +... +``` + + +#### start_time_column (string) + + +The column's name in the database to store the +dialogs' start time information. + + +*Default value is "start_time".* + + +```opensips title="Set start_time_column parameter" +... +modparam("dialog", "start_time_column", "start_time_c_name") +... +``` + + +#### timeout_column (string) + + +The column's name in the database to store the dialogs' timeout. + + +*Default value is "timeout".* + + +```opensips title="Set timeout_column parameter" +... +modparam("dialog", "timeout_column", "timeout_c_name") +... +``` + + +#### profiles_column (string) + + +The column's name in the database to store the dialogs' profiles. + + +*Default value is "profiles".* + + +```opensips title="Set profiles_column parameter" +... +modparam("dialog", "profiles_column", "profiles_c_name") +... +``` + + +#### vars_column (string) + + +The column's name in the database to store the dialogs' vars. + + +*Default value is "vars".* + + +```opensips title="Set vars_column parameter" +... +modparam("dialog", "vars_column", "vars_c_name") +... +``` + + +#### sflags_column (string) + + +The column's name in the database to store the dialogs' script flags. + + +*Default value is "script_flags".* + + +```opensips title="Set sflags_column parameter" +... +modparam("dialog", "sflags_column", "sflags_c_name") +... +``` + + +#### mflags_column (string) + + +The column's name in the database to store the dialogs' module flags. + + +*Default value is "module_flags".* + + +```opensips title="Set mflags_column parameter" +... +modparam("dialog", "mflags_column", "mflags_c_name") +... +``` + + +#### flags_column (string) + + +The column's name in the database to store the dialogs' flags. + + +*Default value is "flags".* + + +```opensips title="Set flags_column parameter" +... +modparam("dialog", "flags_column", "flags_c_name") +... +``` + + +#### profiles_with_value (string) + + +List of names (alphanumerical/-/_) for profiles with values. Flags +*/b* or */s* allow sharing +profiles between OpenSIPS instances using the clusterer module or a +CacheDB backend, respectively. + + +*Default value is "empty".* + + +```opensips title="Set profiles_with_value parameter" +... +modparam("dialog", "profiles_with_value", "callerCC; gatewayCC; clientChannels/s; codecUsed/b;") +... +``` + + +#### profiles_no_value (string) + + +List of names (alphanumerical/-/_) for profiles without values. Flags +*/b* or */s* allow sharing +profiles between OpenSIPS instances using the clusterer module or a +CacheDB backend, respectively. + + +*Default value is "empty".* + + +```opensips title="Set profiles_no_value parameter" +... +modparam("dialog", "profiles_no_value", "inbound ; outbound ; shared/s; repl/b;") +... +``` + + +#### db_flush_vals_profiles (int) + + +Pushes dialog values, profiles and flags into the database +along with other dialog state information (see db_mode 1 and 2). + + +*Default value is "empty".* + + +```opensips title="Set db_flush_vals_profiles parameter" +... +modparam("dialog", "db_flush_vals_profiles", 1) +... +``` + + +#### timer_bulk_del_no (int) + + +The number of dialogs that should be attempted to be +deleted at the same time ( a single query ) from the +DB back-end. + + +*Default value is "1".* + + +```opensips title="Set timer_bulk_del_no parameter" +... +modparam("dialog", "timer_bulk_del_no", 10) +... +``` + + +#### race_condition_timeout (int) + + +If dialog is created using the 'E' flag, and a SIP Race condition happens, then the dialog will be terminated after 'race_condition_timeout' seconds. +Currently, the only supported race conditions are (200OK vs CANCEL) and (early BYE vs 200OK) + + +*Default value is "5" seconds.* + + +```opensips title="Set race_condition_timeout parameter" +... +modparam("dialog", "race_condition_timeout", 1) +... +``` + + +#### cachedb_url (string) + + +Enables distributed dialog profiles and specifies the +backend that should be used by the CacheDB interface. + + +*Default value is "empty".* + + +```opensips title="Set cachedb_url parameter" +... +modparam("dialog", "cachedb_url", "redis://127.0.0.1:6379") +... +``` + + +#### profile_value_prefix (string) + + +Specifies what prefix should be added to the profiles with +value when they are inserted into CacheDB backed. This is +only used when distributed profiles are enabled. + + +*Default value is "dlg_val_".* + + +```opensips title="Set profile_value_prefix parameter" +... +modparam("dialog", "profile_value_prefix", "dlgv_") +... +``` + + +#### profile_no_value_prefix (string) + + +Specifies what prefix should be added to the profiles without +value when they are inserted into CacheDB backed. This is +only used when distributed profiles are enabled. + + +*Default value is "dlg_noval_".* + + +```opensips title="Set profile_no_value_prefix parameter" +... +modparam("dialog", "profile_no_value_prefix", "dlgnv_") +... +``` + + +#### profile_size_prefix (string) + + +Specifies what prefix should be added to the entity that holds +the profiles with value size in CacheDB backed. This is +only used when distributed profiles are enabled. + + +*Default value is "dlg_size_".* + + +```opensips title="Set profile_size_prefix parameter" +... +modparam("dialog", "profile_size_prefix", "dlgs_") +... +``` + + +#### profile_timeout (int) + + +Specifies how long a dialog profile should be kept in the CacheDB +until it expires. This is only used when distributed profiles are +enabled. + + +*Default value is "86400".* + + +```opensips title="Set profile_timeout parameter" +... +modparam("dialog", "profile_timeout", "43200") +... +``` + + +#### dialog_replication_cluster (int) + + +Specifies the cluster ID for dialog replication using the +*clusterer* module. This enables sending +and receiving all the dialog-related events (creation, update and +deletion) in the cluster. + + +This OpenSIPS cluster exposes the **"dialog-dlg-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +*Default value is "0" (no replication).* + + +```opensips title="Set dialog_replication_cluster parameter" +... +modparam("dialog", "dialog_replication_cluster", 1) +... +``` + + +#### profile_replication_cluster (int) + + +Specifies the cluster ID for profile replication using the +*clusterer* module. This enables sending +and receiving the profile information (value, dialog count) +in the cluster. + + +*Default value is "0" (no replication).* + + +```opensips title="Set profile_replication_cluster parameter" +... +modparam("dialog", "profile_replication_cluster", 1) +... +``` + + +#### replicate_profiles_buffer (string) + + +Used to specify the length of the buffer used by the binary +replication, in bytes. Usually this should be big enough to hold +as much data as possible, but small enough to avoid UDP +fragmentation. The recommended value is the smallest MTU between +all the replication instances. + + +*Default value is 1400 bytes.* + + +```opensips title="Set replicate_profiles_buffer parameter" +... +modparam("dialog", "replicate_profiles_buffer", 500) +... +``` + + +#### replicate_profiles_check (string) + + +Timer in seconds, used to specify how often the module should check +whether old, replicated profiles values are obsolete and should be removed. +should replicate its profiles to the other instances. + + +*Default value is 10 s.* + + +```opensips title="Set replicate_profiles_check parameter" +... +modparam("dialog", "replicate_profiles_check", 100) +... +``` + + +#### replicate_profiles_timer (string) + + +Timer in milliseconds, used to specify how often the module +should replicate its profiles to the other instances. + + +*Default value is 200 ms.* + + +```opensips title="Set replicate_profiles_timer parameter" +... +modparam("dialog", "replicate_profiles_timer", 100) +... +``` + + +#### replicate_profiles_expire (string) + + +Timer in seconds, used to specify when the profiles counters received +from a different instance should no longer be taken into account. +This is used to prevent obsolete values, in case an instance stops +replicating its counters. + + +*Default value is 10 s.* + + +```opensips title="Set replicate_profiles_expire parameter" +... +modparam("dialog", "replicate_profiles_expire", 10) +... +``` + + +#### cluster_auto_sync (string) + + +Specifies whether to automatically issue a sync request (for dialogs +marked with a sharing tag in backup state) when a node becomes reachable. +A value of *1* means enabled and *0* +disabled. + + +*Default value is 1 (enabled).* + + +```opensips title="Set cluster_auto_sync parameter" +... +modparam("dialog", "cluster_auto_sync", 0) +... +``` + + +### Exported Functions + + +#### create_dialog([flags]) + + +The function creats the dialog for the currently processed request. The +request must be an initial request. + +Optionally,the function also receives a string parameter, which specifies +special behavior to be done for the current dialog. + + +Parameters: + + +- *flags (string, optional)* +Possible values here are : + - B - Upon reaching dialog lifetime, BYEs will be triggered + both ways + - P - Ping caller side with OPTIONS messages, once every + options_ping_interval seconds + - p - Ping callee side with OPTIONS messages, once every + options_ping_interval seconds + - R - Ping caller side with RE-INVITE messages, once every + reinvite_ping_interval seconds + - r - Ping callee side with RE-INVITE messages, once every + reinvite_ping_interval seconds + - E - Upon detecting a SIP Race condition (see RFC 5407), + end the call after race_condition_timeout seconds + + Multiple string flags can be used at the same time, + ie. passing "BPp" flags will enable all 3 flags. + + +> [!NOTE] +> Both RE-INVITE and OPTIONS pinging cannot be enabled at the same time +> for a single dialog leg. If both flags ("*PR*" or +> "*pr*") are provided only RE-INVITE pinging will be used. + + +The function returns true if the dialog was successfully created or +if the dialog was previously created. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="create_dialog() usage" +... +create_dialog(); +... +#ping caller +create_dialog("P"); +... +#ping caller and callee +create_dialog("Pp"); + +#bye on timeout +create_dialog("B"); +... +``` + + +#### match_dialog([dlg_match_mode]) + + +This function is to be used to match a sequential (in-dialog) request +to an ongoing dialog. + + +By default, dialog matching is performed according to the +[dlg match mode](#param_dlg_match_mode) module parameter. A specific +matching mode may be enforced by specifying the optional +"dlg_match_mode" parameter. Possible values for this parameter are +"DID_ONLY", "DID_FALLBACK" and "DID_NONE". + + +As sequential requests are automatically matched to the dialog when +doing "loose_route()" from script, this function is intended to: +(A) control the place in your script where the dialog matching is done +and (B) to cope with bogus sequential requests that do not have Route +headers, so they are not handled by loose_route(). + + +Parameters: + + +- *dlg_match_mode (string, optional)* + + +The function returns true if a dialog exists for the request. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="match_dialog() usage" +... + if (has_totag()) { + loose_route(); + + # example 1: match according to dlg_match_mode + if ($DLG_status == NULL && !match_dialog()) + xlog("cannot match request to a dialog\n"); + + # example 2: override dlg_match_mode + if ($DLG_status == NULL && !match_dialog("DID_FALLBACK")) + xlog("cannot match request to a dialog\n"); + } +... +``` + + +#### validate_dialog() + + +The function checks the current received requests against the dialog +(internal data) it belongs to. +Performing several tests, the function will help to detect the bogus +injected in-dialog requests (like malicious BYEs). + + +The performed tests are related to CSEQ sequence checking and routing +information checking (contact and route set). + + +The function returns true if a dialog exists for the request and if +the request is valid (according to dialog data). If the request is invalid, +the following return codes are returned : + + +- *-1* - invalid cseq +- *-2* - invalid remote target +- *-3* - invalid route set +- *-4* - other errors ( parsing, no dlg, etc ) + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="validate_dialog() usage" +... + if (has_totag()) { + loose_route(); + if ($DLG_status!=NULL && !validate_dialog() ) { + xlog(" in-dialog bogus request \n"); + } else { + xlog(" in-dialog valid request - $DLG_dir !\n"); + } + } +... +``` + + +#### fix_route_dialog() + + +The function forces an in dialog SIP message to contain the ruri, route headers and +dst_uri, as specified by the internal data of the dialog it belongs to. +The function will prevent the existence of bogus injected in-dialog +requests ( like malicious BYEs ) + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="fix_route_dialog() usage" +... + if (has_totag()) { + loose_route(); + if ($DLG_status!=NULL) + if (!validate_dialog()) + fix_route_dialog(); + } +... +``` + + +#### get_dialog_info(attr,avp,key,key_val,no_dlgs) + + +The function extracts a dialog value from another dialog. It first searches +through all existing (ongoing) dialogs for all dialogs that have a dialog +variable named "key" with the value "key_val" +(so a dialog where $dlg_val(key)=="key_val"). If found, it returns +the value of the dialog variable "attr" from all the +founds dialog in the "avp" pseudo-variable, otherwise nothing is written +in "avp", and a negative error code is returned. + + +> [!NOTE] +> The function does not require to be called in the context of +> a dialog - you can use it whenever / whereever for searching for other +> dialogs. + + +Meaning of the parameters is as follows: + + +- *attr (string)* - the name of the dialog variable +(from the found dialog) to be returned; +- *avp (var)* - an avp where to store the values of +the "attr" dialog variable. +Since the function checks through all dialogs, this needs to be an actual +AVP in order to support pushing values from all matched dialogs. +- *key (string)* - name of a dialog variable to be +used a search key (when looking after the target dialog) +- *key_val (var)* - the value of the dialog +variable that is used as key in searching the target dialog. +- *no_dlgs (var)* - the total number of dialogs +containing the key variable + + +This function can be used from ALL ROUTES. + + +```opensips title="get_dialog_info usage" +... +if ( get_dialog_info("callee",$avp(callee_array),"caller",$fu,$var(dlg_no)) ) { + xlog("caller $fu has $var(dlg_no) other ongoing calls, talking with :"); + $var(it) = 0; + while ($var(it) < $var(dlg_no)) { + $var(current_callee) = $(avp(callee_array)[$var(it)]); + xlog(" $var(current_callee) "); + $var(it) = $var(it) + 1; + } + + xlog("\n"); +} + +# create dialog for current call and place the caller and callee attributes +create_dialog(); +$dlg_val(caller) = $fu; +$dlg_val(callee) = $ru; +... +``` + + +#### get_dialog_vals(names,vals,callid) + + +The function fetches all the dialog variables of another dialog. +It first searches through all existing (ongoing) dialogs based on the +given SIP CallID. If found, it returns all the dialog variables as +two parallel arrays of names and values (using the given variables +"names" and "vals"). As these variables have to hold arrays, they must +be AVPs. + + +> [!NOTE] +> The function does not require to be called in the context of +> a dialog - you can use it whenever / whereever for searching for other +> dialogs. + + +Meaning of the parameters is as follows: + + +- *names (var)* - an AVP variable to +hold all the names of the variables from the found dialog. +- *vals (var)* - an AVP variable to +hold all the values of the variables from the found dialog. +- *callid (string)* - the callid of a dialog +to be searched (and have the variables fetched). + + +This function can be used from any type of route. + + +```opensips title="get_dialog_vals usage" +... +if ( get_dialog_vals($avp(d_names),$avp(d_vals),$var(callid)) ) { + xlog("the call $var(callid) has the variables:\n); + $var(i) = 0; + while ( $(avp(d_names)[$var(i)])!=NULL ) { + xlog("var $var(i) is $(avp(d_names)[$var(i)])='$(avp(d_vals)[$var(i)])'\n"); + $var(i) = $var(i) + 1; + } +} +... +``` + + +#### get_dialogs_by_val(name,value,out_avp,out_dlg_no) + + +The function looks up through the whole dialog table for dialogs containing a $dlg_val with the provided name and value, and returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable + + +> [!NOTE] +> The function does not require to be called in the context of +> a dialog - you can use it whenever / whereever for searching for other +> dialogs. + + +Meaning of the parameters is as follows: + + +- *name (string)* - the name of the dialog variable used for the lookup +- *value (var)* - the value of the above dialog val +- *out_avp (var)* - the AVP which will be populated will the dialog JSONs for all the matched calls +- *dlg_no (var)* - the out var which will contain the total number of matched dialogs + + +This function can be used from any type of route. + + +```opensips title="get_dialog_vals usage" +... +if ( get_dialogs_by_val("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) { + xlog("Caller $fU has $avp(dlg_no) other calls \n); + $var(i) = 0; + while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { + $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); + # fetch any info for the above call and process it + $var(i) = $var(i) + 1; + } +} +... +``` + + +#### get_dialogs_by_profile(name,value,out_avp,out_dlg_no) + + +The function looks up through the whole dialog table for dialogs configured to be within the provided dialog profile name, and optionally with the provided profile value. The function returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable + + +> [!NOTE] +> The function does not require to be called in the context of +> a dialog - you can use it whenever / whereever for searching for other +> dialogs. + + +Meaning of the parameters is as follows: + + +- *name (string)* - the name of the dialog profile used for the lookup +- *value (string)* - the value of the above dialog profile ( optional ) +- *out_avp (var)* - the AVP which will be populated will the dialog JSONs for all the matched calls +- *dlg_no (var)* - the out var which will contain the total number of matched dialogs + + +This function can be used from any type of route. + + +```opensips title="get_dialog_vals usage" +... +if ( get_dialogs_by_profile("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) { + xlog("Caller $fU has $avp(dlg_no) other calls \n); + $var(i) = 0; + while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { + $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); + # fetch any info for the above call and process it + $var(i) = $var(i) + 1; + } +} +... +``` + + +#### load_dialog_ctx( dialog [, id_type]) + + +The function loads and switches to the context of the given dialog. +The context of a dialog is given by the dialog flags, variables, +profiles and any other value/state related to the dialog. By +switching to the context of another dialog, you will see at the script +level, by default, all the data from the new dialog. + + +> [!NOTE] +> You cannot perform a new load until doing an unload - no nested +> loadings are possible. + + +Meaning of the parameters is as follows: + + +- *dialog (string)* - the identifier of the +dialog to be loaded, it may be a SIP Call-ID or a Dialog ID. +- *id_type (string,optional)* - what kind of +dialog identified was used in the first parameter. It can be +*callid* (SIP Call-ID) or +*did* (internal Dialog ID). By default callid +will be assumed. + + +This function can be used from any type of route. + + +```opensips title="load_dialog_ctx usage" +... +if (load_dialog_ctx("$var(callid)")) { + xlog("The dialog '$var(callid)' already has a duration " + "of $DLG_lifetime seconds\n"); + if (is_in_profile("inboundCall")) + xlog("this dialog is an inbound call\n"); + unload_dialog_ctx(); +} +... +``` + + +#### unload_dialog_ctx() + + +The function off-loads the loaded context of another dialog, exposing +whatever dialog context was present before doing the load. + + +> [!NOTE] +> You MUST perform from script an explicit unload for each load +> you did, otherwise the loaded dialog will remain hanged for ever. + + +This function can be used from any type of route. + + +For usage example, see the [load dialog ctx](#func_load_dialog_ctx) + + +#### set_dlg_profile(profile, [value], [clear_values]) + + +Inserts the current dialog into a profile. Note that if the profile does +not support values, this will be silently discarded. A dialog may be +inserted in the same profile multiple times. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +Meaning of the parameters is as follows: + + +- *profile (string)* - name of the profile to be +added to. +- *value (string, optional)* - string value to +define the belonging of the dialog to the profile - note that the +profile must support values. +- *clear_values (boolean, optional)* - if set to +*true* (1), all values of the profile will be cleared +before setting the given value. Default: *false*. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="set_dlg_profile usage" +... +set_dlg_profile("inboundCall"); + +# Set a new value (all other values are kept intact) +set_dlg_profile("caller", $fu); + +# Set a new value while removing all previous values +set_dlg_profile("caller", $fu, true); +... +``` + + +#### unset_dlg_profile(profile, [value]) + + +Removes the current dialog from a profile. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +Meaning of the parameters is as follows: + + +- *profile (string)* - name of the profile to be +removed from. +- *value (string, optional)* - string value to +define the belonging of the dialog to the profile - note that the +profile must support values. +NEW in 3.4: for profiles with value, by omitting this parameter +you can now clear all values of the given profile. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="unset_dlg_profile usage" +... +unset_dlg_profile("inboundCall"); +unset_dlg_profile("caller", $fu); +... +# Remove all values in a profile +unset_dlg_profile("caller"); +... +``` + + +#### is_in_profile(profile,[value]) + + +Checks if the current dialog belongs to a profile. If the profile +supports values, the check can be reinforced to take into account a +specific value - if the dialog was inserted into the profile for a +specific value. If no value is passed, only simply belonging of the +dialog to the profile is checked. Note that if the profile does not +support values, this will be silently discarded. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +Meaning of the parameters is as follows: + + +- *profile (string)* - name of the profile to be +checked against. +- *value (string. optional)* - string value to +toughen the check. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="is_in_profile usage" +... +if (is_in_profile("inboundCall")) { + log("this request belongs to a inbound call\n"); +} +... +if (is_in_profile("caller","XX")) { + log("this request belongs to a call of user XX\n"); +} +... +``` + + +#### get_profile_size(profile,[value],size) + + +Returns the number of dialogs belonging to a profile. If the profile +supports values, the check can be reinforced to take into account a +specific value - how many dialogs were inserted into the profile with +a specific value. If not value is passed, only simply belonging of the +dialog to the profile is checked. Note that the profile does not +supports values, this will be silently discarded. + + +Meaning of the parameters is as follows: + + +- *profile (string)* - name of the profile to get +the size for. +- *value (string, optional)* - string value to +toughen the check. +- *size (var)* - an AVP or script variable to +return the profile size in. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="get_profile_size usage" +modparam("dialog", "profiles_no_value", "inboundCalls") +modparam("dialog", "profiles_with_value", "caller") +... +get_profile_size("inboundCalls",,$var(size)); +xlog("inboundCalls: $var(size)\n"); +... +get_profile_size("caller", $fu, $var(size)); +xlog("currently, the user $fu has $var(size) active outgoing calls\n"); +... +``` + + +#### set_dlg_flag(flag) + + +Sets the dialog flag named *flag* to true. The dialog +flags are dialog persistent and they can be accessed (set and test) +for all requests belonging to the dialog. + + +Parameters: + + +- *flag (string, static)* - The flag name. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="set_dlg_flag usage" +... +set_dlg_flag("MY_DLG_FLAG"); +... +``` + + +#### test_and_set_dlg_flag(flag, value) + + +Atomically checks if the dialog flag named *flag* is +equal to *value*. If true, changes the value with the +opposite one. This operation is done under the dialog lock. + + +- *flag (string, static)* - The flag name. +- *value (int)* - The value should be 0 (false) or 1 (true). + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="test_and_set_dlg_flag usage" +... +test_and_set_dlg_flag("MY_DLG_FLAG", 0); +... +``` + + +#### reset_dlg_flag(flag) + + +Resets the dialog flag named *flag* to false. +The dialog flags are dialog persistent and they can be accessed +(set and test) for all requests belonging to the dialog. + + +Parameters: + + +- *flag (string, static)* - The flag name. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="reset_dlg_flag usage" +... +reset_dlg_flag("MY_DLG_FLAG"); +... +``` + + +#### is_dlg_flag_set(flag) + + +Returns true if the dialog flag named *flag* is set. +The dialog flags are dialog persistent and they can be accessed +(set and test) for all requests belonging to the dialog. + + +Parameters: + + +- *flag (string, static)* - The flag name. + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="is_dlg_flag_set usage" +... +if (is_dlg_flag_set("MY_DLG_FLAG")) { + xlog("dialog flag MY_DLG_FLAG is set\n"); +} +... +``` + + +#### store_dlg_value(name,val) + + +Attaches to the dialog the value from the variable *val* +under the name *name*. The values attached to dialogs are +dialog persistent and they can be accessed (read and write) for all +requests belonging to the dialog. + + +Parameters: + + +- *name (string)* +- *val (var)* + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +Same functionality may be obtain by assigning a value to pseudo +variable *$dlg_val(name)*. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="store_dlg_value usage" +... +store_dlg_value("inv_src_ip",$si); +store_dlg_value("account type",$var(account)); +# or +$dlg_val(account_type) = "prepaid"; +... +``` + + +#### fetch_dlg_value(name,val) + + +Fetches from the dialog the value of attribute named +*name*. The values attached to dialogs are +dialog persistent and they can be accessed (read and write) for all +requests belonging to the dialog. + + +Parameters: + + +- *name (string)* +- *val (var)* + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +Same functionality may be obtain by reading the pseudo +variable *$dlg_val(name)*. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="fetch_dlg_value usage" +... +fetch_dlg_value("inv_src_ip",$avp(2)); +fetch_dlg_value("account type",$var(account)); +# or +$var(account) = $dlg_val(account_type); +... +``` + + +#### set_dlg_sharing_tag(tag_name) + + +Marks the current dialog with the sharing tag *tag_name*. +From this point on, actions like in-dialog pinging, BYEs on timeout etc. +will depend on the tag state(no action in "backup" state, normal operation +in "active" state). + + +For more details see the [dialog clustering](#dialog_clustering) chapter. + + +Parameters: + + +- *tag_name (string)* + + +> [!NOTE] +> The dialog must be created before using this function (use +> create_dialog() function before). + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="set_dlg_sharing_tag usage" +... +set_dlg_sharing_tag("vip1"); +... +``` + + +#### dlg_on_answer([route_name]) + + +The function arms a script route to be executed when the current +dialog will be later answered. When the route will be executed, the +dialog context will be exposed, but with no valid SIP message (just +a phony one). + + +You must use this function AFTER creating the dialog and before the +dialog being answered. + + +If the parameter is missing, the function does a reset of any route +previously set; there will be no triggering. + + +Parameters: + + +- *route_name (string,optional)* - the name +of the script route to be executed. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="dlg_on_answer usage" +... +create_dialog(); +dlg_on_answer("dlg_answered"); +... +route[dlg_answered] { + xlog("The dialog $DLG_did was answered\n"); +} +``` + + +#### dlg_on_timeout([route_name]) + + +The function arms a script route to be executed when (and if) the +current dialog will timeout (as duration). When the route will be +executed, the dialog context will be exposed, but with no valid SIP +message (just a phony one) + + +When the route is executed, the dialog is not yet terminated, just its +lifetime reached the set limit. In the timeout route you can increase +the dialog expiration timeout (and the dialog will continue) or you +can let the dialog to be terminated (after the end of this route). + + +You must use this function AFTER creating the dialog and before the +dialog being answered. + + +You must use this function AFTER creating the dialog and before the +dialog being answered. + + +Parameters: + + +- *route_name (string,optional)* - the name +of the script route to be executed. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="dlg_on_timeout usage" +... +create_dialog(); +$DLG_timeout=120; +dlg_on_timeout("dlg_timeout"); +... +route[dlg_timeout] { + xlog("The dialog $DLG_did timed out\n"); + if (_some_prolongation_condition) + $DLG_timeout = 60; # give it 1 min more +} +``` + + +#### dlg_on_hangup([route_name]) + + +The function arms a script route to be executed when the current +dialog will be terminated. When the route will be executed, the +dialog context will be exposed, but with no valid SIP message (just +a phony one). Note that the dialog will be already terminated and there +is nothing you can do about it besides reading data from its context. + + +You must use this function AFTER creating the dialog and before the +dialog being answered. + +If the parameter is missing, the function does a reset of any route +previously set; there will be no triggering. + + +Parameters: + + +- *route_name (string,optional)* - the name +of the script route to be executed. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +REPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="dlg_on_hangup usage" +... +create_dialog(); +dlg_on_hangup("dlg_hangup"); +... +route[dlg_hangup] { + xlog("The dialog $DLG_did terminated after $DLG_lifetime secs\n"); +} +``` + + +#### dlg_send_sequential(method, leg, [, body] [, content-type] [, headers]) + + +Used to send an in-dialog request towards one if the dialog's legs. +The function assumes that is runs inside a dialog context - if you +are running it from a different context (such as an event_route), +make sure you first load the dialog context using the +[load dialog ctx](#func_load_dialog_ctx) function. + + +Parameters: + + +- *method (string)* - +the method of the request sent. +- *leg (string)* - the leg +where the request is sent. Must be either +*caller* or *callee*. +- *body (string, optional)* - an +optional body sent in the request. If missing, no body is sent. +- *content-type (string, optional)* - +the content type of the body sent. Make sure you specify this +every time you send a request with a body, otherwise there are high +changes that your UAC will reject the request. +- *headers (string, optional)* - +additional headers attached to the request sent. + + +This function can be used from ANY route. + + +```opensips title="dlg_send_sequential usage to convert DTMF codes" +... +event_route[E_RTPPROXY_DTMF] { + if (load_dialog_ctx("$param(id)", "did")) { + if ($param(stream) == 0) { + $var(direction) = "callee"; + } else { + $var(direction) = "caller"; + } + dlg_send_sequential($var(direction), "INFO", + "Signal=$param(digit)\nDuration=160", + "application/dtmf-relay"); + unload_dialog_ctx(); + } +} +... +``` + + +#### dlg_inc_cseq([tag, ][inc]) + + +Increments the dialog's generated CSeq associated to the leg +identified by the dialog's tag. + + +Parameters: + + +- *tag (string, optional)* - +the tag to increment the CSeq value for. If missing, the +message's *To* tag is used to identify +the leg to increment the CSeq for. +- *inc (integer, optional)* - the +value used to increment/decrement (if negative) the CSeq of +the identified leg. If not used, the value is incremented with +*1*. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE routes. + + +```opensips title="dlg_inc_cseq usage" +... +route { + ... + if (has_totag()) { + if (loose_route()) + dlg_inc_cseq(); # increment upstream CSeq after each in-dialog request + } +} +... +``` + + +### Exported Statistics + + +#### active_dialogs + + +Returns the number of current active dialogs (may be confirmed or +not). + + +#### early_dialogs + + +Returns the number of early dialogs. + + +#### processed_dialogs + + +Returns the total number of processed dialogs (terminated, +expired or active) from the startup. + + +#### expired_dialogs + + +Returns the total number of expired dialogs from the startup. + + +#### failed_dialogs + + +Returns the number of failed dialogs ( dialogs were +never established due to whatever reasons - internal error, +negative reply, cancelled, etc ) + + +#### create_sent + + +Returns the number of replicated dialog +**create** requests send to other OpenSIPS +instances. + + +#### update_sent + + +Returns the number of replicated dialog +**update** requests send to other OpenSIPS +instances. + + +#### delete_sent + + +Returns the number of replicated dialog +**delete** requests send to other OpenSIPS +instances. + + +#### create_recv + + +Returns the number of dialog +**create** events received from other +OpenSIPS instances. + + +#### update_recv + + +Returns the number of dialog +**update** events received from other +OpenSIPS instances. + + +#### delete_recv + + +Returns the number of dialog +**delete** events received from other +OpenSIPS instances. + + +### Exported MI Functions + + +#### dlg_list + + +Lists the description of the dialogs (calls). If no parameter is given, +all dialogs will be listed. If a dialog identifier is passed +as parameter (callid and fromtag), only that dialog will be listed. If +a index and conter parameter is passed, it will list only a number of +"counter" dialogs starting with index (as offset) - this is used to +get only section of dialogs. + + +Name: *dlg_list* + + +Parameters (with dialog idetification): + + +- *callid* (optional) - callid if a single +dialog to be listed. +- *from_tag* (optional, but cannot be present +without the callid parameter) - fromtag (as per initial request) +of the dialog to be listed. +entry + + +Parameters (with dialog counting): + + +- *index* - offset where the dialog listing +should start. +- *counter* - how many dialogs should be +listed (starting from the offset) + + +MI FIFO Command Format: + + +```bash +## list all ongoing dialogs +opensips-cli -x mi dlg_list +## list the dialog by callid and From TAG +opensips-cli -x mi dlg_list callid=abcdrssfrs122444@192.168.1.1 from_tag=AAdfeEFF33 +## list 10 dialogs, starting from the position 40 +## (in the list of all ongoing dialogs) +opensips-cli -x mi dlg_list index=40 counter=10 +``` + + +#### dlg_list_ctx + + +The same as the "dlg_list" but including in the +dialog description +the associated context from modules sitting on top of +the dialog module. +This function also prints the dialog's values. In case of +binary values, the non-printable chars are represented in hex +(e.g. \x00) + + +Name: *dlg_list_ctx* + + +Parameters: *see "dlg_list"* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dlg_list_ctx +``` + + +#### dlg_end_dlg + + +Terminates an ongoing dialog. +If dialog is established, BYEs are sent in both directions. +If dialog is in unconfirmed or early state, a CANCEL will be +sent to the callee side, that will trigger a 487 from the +callee, which, when relayed, will also end the dialog on +the caller's side. + + +Name: *dlg_end_dlg* + + +Parameters are: + + +- *dialog_id* - this is an identifier +of the dialog - it can be either (1) the unique ID +of the dialog (as provided by dlg_list), either (2) the +SIP Call-ID of the dialog. +- *extra_hdrs* - (optional) string containg +the extra headers (full format) to be added to the BYE +requests. + + +The "dialog_id" value can be get via the "dlg_list" MI command. + + +MI FIFO Command Format: + + +```bash +# terminate the dialog via the internal Dialog-ID +opensips-cli -x mi dlg_end_dlg 6ae.4b38d013 +# terminate the dialog via its SIP Call-ID +opensips-cli -x mi dlg_end_dlg Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY +``` + + +#### profile_get_size + + +Returns the number of dialogs belonging to a profile. If the profile +supports values, the check can be reinforced to take into account a +specific value - how many dialogs were inserted into the profile with +a specific value. If not value is passed, only simply belonging of the +dialog to the profile is checked. Note that the profile does not +supports values, this will be silently discarded. + + +Name: *profile_get_size* + + +Parameters: + + +- *profile* - name of the profile to get the +value for. +- *value* (optional)- string value to +toughen the check; + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi profile_get_size inboundCalls +``` + + +#### profile_list_dlgs + + +Lists all the dialogs belonging to a profile. If the profile +supports values, the check can be reinforced to take into account a +specific value - list only the dialogs that were inserted into the +profile with that specific value. If not value is passed, all dialogs +belonging to the profile will be listed. Note that the profile does +not supports values, this will be silently discarded. Also, when using +shared profiles using the CacheDB interface, this command will only +display the local dialogs. + + +Name: *profile_list_dlgs* + + +Parameters: + + +- *profile* - name of the profile to list the +dialog for. +- *value* (optional)- string value to +toughen the check; + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi profile_list_dlgs inboundCalls +``` + + +#### profile_get_values + + +Lists all the values belonging to a profile along with their +count. If the profile does not support values a total count +will be returned. Note that this function does not work for shared +profiles over the CacheDB interface. + + +Name: *profile_get_values* + + +Parameters: + + +- *profile* - name of the profile to list the +dialog for. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi profile_get_values inboundCalls +``` + + +#### profile_end_dlgs + + +Terminate all ongoing dialogs from a specified profile, on a single dialog it +performs the same operations as the command **[mi dlg end dlg](#mi_dlg_end_dlg)** + + +Name: *profile_end_dlgs* + + +Parameters: + + +- *profile* - name of the profile that will have its dialogs termianted +- *value* - (optional) if the profile supports values terminate only the dialogs +with the specified value + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi profile_end_dlgs inboundCalls +``` + + +#### dlg_db_sync + + +Will load all the information about the dialogs from the database +in the OpenSIPS internal memory. If a dialog is already found in memory +and has the same/an older state, it will be updated with the values from +DB. Otherwise, the newer in-memory version will not be changed. + + +Name: *dlg_db_sync* + + +It takes no parameters + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dlg_db_sync +``` + + +#### dlg_cluster_sync + + +This command will only take effect if dialog replication is enabled. + + +Fully synchronize the dialog information in memory from a suitable donor +node within the [dialog replication cluster](#param_dialog_replication_cluster). Dialogs +that already exist in memory which are not reconfirmed through syncing will +be discarded. A sharing tag can be specified in order to sync only dialogs +marked with that sharing tag. + + +Name: *dlg_cluster_sync* + + +Parameters: + + +- *sharing_tag* - name of the sharing tag that +dialogs have to be marked with in order to be synced + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dlg_cluster_sync vip1 +``` + + +#### dlg_restore_db + + +Restores the dialog table after a potential desynchronization event. +The table is truncated, then populated with CONFIRMED dialogs from memory. + + +Name: *dlg_restore_db* + + +It takes no parameters + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi dlg_restore_db +``` + + +#### list_all_profiles + + +Lists all the dialog profiles, along with 1 or 0 if +the given profile has/does not have an associated value. + + +Name: *list_all_profiles* + + +Parameters: *It takes no parameters* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi list_all_profiles +``` + + +#### dlg_push_var + + +Push or update a dialog value for the given list of dialog IDs / Call-IDs. + + +Name: *dlg_push_var* + + +Parameters: *It takes 3 or more parameters* + + +- *dlg_val_name* - name of the dialog value that needs to be inserted/updated +- *dlg_val_value* - value to be inserted/updated +- *DID* - dialog identifier. Can be either the $DLG_did or the actual Call-ID. + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi dlg_push_var var_name var_value DID1 [ DID2 DID3 ... DIDN ] + +``` + + +#### dlg_send_sequential + + +Sends a sequential request within an ongoing dialog. + + +Name: *dlg_send_sequential* + + +Parameters: + + +- *callid* - the callid of the dialog you need to trigger +the sequential message for. +- *method* - (optional) the method used for the sequential +message. Default value is *INVITE*. +- *mode* - (optional) can be used to tune the behavior of +the sequential message. Possible values for the *mode* are: + - *caller* - (default) sends the sequential message + to the caller. This mode can be useful in high availability scenarios + when you want to update the upstream's routing set, specifically the contact. + - *callee* - same as caller, but sends the sequential + message to the callee. + - *challenge* - sends a sequential INVITE (or UPDATE) + to the caller to challenge it for its advertised SDP body. When the + body is received, it is forwarded to the callee. This mode is useful + when trying to change both endpoints (upstream and downstream) routing + set. It can also be useful when trying to trigger a re-negotiation for + SDP body. + - *challenge-caller* - same as *challenge* + - *challenge-callee* - same as + *challenge-caller*, only that it first challenges + the callee, instead of the caller. +- *body* - (optional) can be used to specify a body for +the initial sequential message. Possible values for the *body* parameter are: + - *none* - (default) no body added to the sequential message. + - *inbound* - advertises in the body of the sequential + message generated the last body received from its pair. For example, + if the *mode=challenge-caller*, the message will + contain the body sent to OpenSIPS by the callee. This is useful when + you need to alter the body previously sent to the caller, because you + want to re-negotiate a different media proxy for the call. This can + be achieved by catching the generated request in + *local_route*, and re-engage the Media proxy. + - *outbound* - advertises in the body of the sequential + message generated the last body sent to that UAC. For example, + if the *mode=challenge-caller*, the message will + contain the last body sent by OpenSIPS to the caller. This is useful + in a high availability scenario when trying to re-negotiate the + contact of the server, but there is no need to alter the body sent + earlier. + - *custom:CONTENT_TYPE:BODY* - this can be used to + specify a specific Content-Type ehader and body for the + sequential message generated. +- *headers* - (optional) can be used to specify some headers for +the initial sequential message. + + +This functions runs asynchronously and returns the status code and reason +of the last reply received for either the *challenge* or normal mode. + + +MI Command Format: + + +```bash +opensips-cli -x mi dlg_send_sequential \ + callid=5291231-testing@127.0.0.1 +``` + + +MI Command used to trigger media re-negotiation: + + +```bash +opensips-cli -x mi dlg_send_sequential \ + callid=5291231-testing@127.0.0.1 \ + mode=challenge \ + body=inbound +``` + + +MI Command used to UPDATE the callee's remote Contact after a server failover: + + +```bash +opensips-cli -x mi dlg_send_sequential \ + callid=5291231-testing@127.0.0.1 \ + mode=challenge-callee \ + body=outbound \ + method=UPDATE +``` + + +MI Command used to send REFER to the callee, and add Refer-To header: + + +```bash +opensips-cli -x mi dlg_send_sequential \ + callid=usR8FlGOSMfCTAIHebHCOQ.. \ + method=REFER \ + body=none \ + mode=callee \ + headers='Refer-To: sip:user@domain:50060' +``` + + +#### set_dlg_profile + + +Set the dialog identified by dialog ID / Call-ID into the given profile ( with optional value and clearing of the old profile values ) + + +Name: *set_dlg_profile* + + +Parameters: *It takes 2-4 parameters* + + +- *dlg_id* - dialog ID or Call-ID for the respective dialog +- *profile* - profile name to be set +- *value* - optional, the profile value to be set +- *clear_values* - optional, clear previous values in the profile before setting the new one + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi set_dlg_profile DID my_profile my_value 1 +``` + + +#### unset_dlg_profile + + +Unsets the dialog identified by dialog ID / Call-ID from the given profile ( with optional value and clearing of the old profile values ) + + +Name: *set_dlg_profile* + + +Parameters: *It takes 2-3 parameters* + + +- *dlg_id* - dialog ID or Call-ID for the respective dialog +- *profile* - profile name to be unset +- *value* - optional, the profile value to be unset. for profiles with value, by omitting this parameter you can now clear all values of the given profile. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi unset_dlg_profile DID my_profile my_value +``` + + +### Exported Pseudo-Variables + + +#### $DLG_count + + +Returns the number of current active dialogs (may be confirmed or +not). + + +#### $DLG_status + + +Returns the status of the dialog corresponding to the processed +sequential request. This PV will be available only for sequential +requests, after doing loose_route(). + + +Value may be: + + +- *NULL* - Dialog not found. +- *1* - Dialog unconfirmed (created +but no reply received at all) +- *2* - Dialog in early state (created +provisional reply received, but no final reply received +yet) +- *3* - Confirmed by a final reply but +no ACK received yet. +- *4* - Confirmed by a final reply and +ACK received. +- *5* - Dialog ended. + + +#### $DLG_lifetime + + +Returns the duration (in seconds) of the dialog corresponding to +the processed sequential request. The duration is calculated from +the dialog confirmation and the current moment. This PV will be +available only for sequential requests, after doing loose_route(). + + +NULL will be returned if there is no dialog for the request. + + +#### $DLG_flags + + +Returns the dialog flags (as a list of flag names separted by space) +of the dialog corresponding to the processed sequential request. +This PV will be available only for sequential requests, +after doing loose_route(). + + +NULL will be returned if there is no dialog for the request. + + +#### $DLG_dir + + +Returns the direction of the request in dialog (as "upstream" string +if the request is generated by callee or "downstream" string if the +request is generated by caller) - to be used for sequential request. +This PV will be available only for sequential requests (not for +replies), after doing loose_route(). + + +NULL will be returned if there is no dialog for the request. + + +#### $DLG_did + + +Returns the id of the dialog corresponding to +the processed sequential request. The output format is a string +identical to the one returned by the dlg_list MI function. This PV will be +available only for sequential requests, after doing loose_route(). + + +NULL will be returned if there is no dialog for the request. + + +#### $DLG_end_reason + + +Returns the reason for the dialog termination. It can be +one of the following : + + +- *Upstream BYE* - Callee has sent a BYE +- *Downstream BYE* - Caller has sent a BYE +- *Lifetime Timeout* - Dialog lifetime expired +- *MI Termination* - Dialog ended via the MI interface +- *Ping Timeout* - Dialog ended because no reply to option pings +- *ReINVITE Ping Timeout* - Dialog ended because no reply to reinvite pings +- *RTPProxy Timeout* - Media timeout signaled by RTPProxy +- *SIP Race Condition* - SIP Race Condition occurred + + +NULL will be returned if there is no dialog for the request, +or if the dialog is not ended in the current context. + + +#### $DLG_timeout + + +Used to set the dialog lifetime (in seconds). When read, the variable +returns the number of seconds until the dialog expires and is destroyed. +Note that reading the variable is only possible after the dialog is created +(for initial requests) or after doing loose_route() (for sequential requests). +Important notice: using this variable with a REALTIME db_mode is very inefficient, +because every time the dialog value is changed, a database update is done. + + +NULL will be returned if there is no dialog for the request, otherwise the +number of seconds until the dialog expiration. + + +#### $DLG_del_delay + + +Used to set the dialog deletion delay (in seconds) for the +current dialog (in a per-call manner). When read, the variable +returns the number of seconds that were set for the call or +the default value ( see the +"delete_delay" - [delete delay](#param_delete_delay)) +module param) for the delete delaying. + + +The variable must be used when the context of a dialog is +available in script. + + +#### $DLG_json + + +The variable is read-only and exposes a JSON variable containing all the information that the dlg_list MI function contains + + +NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned. + + +#### $DLG_ctx_json + + +The variable is read-only and exposes a JSON variable containing all the information that the dlg_list_ctx MI function contains ( on top of $DLG_json, this will expose the full list of dialog vars and profile links for the current dialog ) + + +NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned. + + +#### $dlg_val(name) + + +This is a read/write variable that allows access to the dialog +attribute named *name*. It can hold a string or +integer value. + + +Be sure and use this variable only when having a dialog context +(like after create_dialog() or match_dialog() or equivalent). + + +The variable accepts dynamic names, meaning the name may contain +other variables. + + +NULL will be returned if there is no dialog for the request. + + +### Exported Events + + +#### E_DLG_STATE_CHANGED + + +This event is raised when the dialog state is changed. + + +Parameters: + + +- *id* - the hex representation of the dialog id. +- *db_id* - the integer representation of the dialog id, +as it is stored in the database *dlg_id* field. +- *callid* - the callid. +- *from_tag* - the From tag. +- *to_tag* - the To tag. +- *old_state* - the old state of the dialog. +- *new_state* - the new state of the dialog. + + +## Developer Guide + + +### Available Functions + + +#### register_dlgcb (dialog, type, cb, param, free_param_cb) + + +Register a new callback to the dialog. + + +Meaning of the parameters is as follows: + + +- *struct dlg_cell* dlg* - dialog to +register callback to. If maybe NULL only for DLG_CREATED callback +type, which is not a per dialog type. +- *int type* - types of callbacks; more +types may be register for the same callback function; only +DLG_CREATED must be register alone. Possible types: + - *DLGCB_LOADED* - called when a dialog + is loaded from the database, or received by a node using the + cluster replication. + - *DLGCB_SAVED* + - *DLG_CREATED* - called when a new + dialog is created - it's a global type (not associated to + any dialog) + - *DLG_FAILED* - called when the dialog + was negatively replied (non-2xx) - it's a per dialog type. + - *DLG_CONFIRMED* - called when the + dialog is confirmed (2xx replied) - it's a per dialog type. + - *DLG_REQ_WITHIN* - called when the + dialog matches a sequential request - it's a per dialog type. + - *DLG_TERMINATED* - called when the + dialog is terminated via BYE, or by the mi dlg_end_dlg command - it's a per dialog type. + - *DLG_EXPIRED* - called when the + dialog expires without receiving a BYE - it's a per dialog + type. Note that when using replication sharing tags, this + callback is only executed by the node that has the Active tag. + - *DLGCB_EARLY* - called when the + dialog is created in an early state (18x replied) - it's + a per dialog type. + - *DLGCB_RESPONSE_FWDED* - called when + the dialog matches a reply to the initial INVITE request - it's + a per dialog type. + - *DLGCB_RESPONSE_WITHIN* - called when + the dialog matches a reply to a subsequent in dialog request - it's a per dialog type. + - *DLGCB_MI_CONTEXT* - called when the + mi dlg_list_ctx command is invoked - it's a per dialog type. + - *DLGCB_DESTROY* +- *dialog_cb cb* - callback function to be +called. Prototype is: "void (dialog_cb) +(struct dlg_cell* dlg, int type, struct dlg_cb_params * params); +" +- *void *param* - parameter to be passed to +the callback function. +- *param_free callback_param_free* - +callback function to be called to free the param. +Prototype is: "void (param_free_cb) (void *param);" + + +## Frequently Asked Questions + + +**Q: What happened with "topology_hiding()" +function?** + + +The respective functionality was moved into the topology_hiding module. +Function prototype has remained the same. + + +**Q: What happened with "use_tight_match" +parameter?** + + +The parameter was removed with version 1.3 as the option of tight +matching became mandatory and not configurable. Now, the tight +matching is done all the time (when using DID matching). + + +**Q: What happened with "bye_on_timeout_flag" +parameter?** + + +The parameter was removed in a dialog module parameter restructuring. +To keep the bye on timeout behavior, you need to provide a "B" +string parameter to the create_dialog() function. + + +**Q: What happened with "dlg_flag" +parameter?** + + +The parameter is considered obsolete. The only way to +create a dialog is to call the create_dialog() function + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/dialog/dlg_db_handler.c b/modules/dialog/dlg_db_handler.c index 6abfc00b7cb..31db33f0fa4 100644 --- a/modules/dialog/dlg_db_handler.c +++ b/modules/dialog/dlg_db_handler.c @@ -322,7 +322,7 @@ static inline void strip_esc(str *s) int len = s->len; for ( ; len > 0; len--, c++) { - if (*c == '\\' && + if (*c == '\\' && len > 1 && (*(c+1)=='\\' || *(c+1)=='#' || *(c+1)=='|')) { memmove(c, c + 1, len - 1); s->len--; @@ -1323,14 +1323,14 @@ str* write_dialog_vars( struct dlg_cell *dlg) o_l = l; } - lock_stop_read(dlg->vals_lock); - - /* write the stuff into it */ + /* write the stuff into it (still under read lock) */ o.len = l; p = o.s; for ( v=dlg->vals ; v ; v=v->next) { p += write_pair( p, &v->name,NULL, &v->val, v->type); } + lock_stop_read(dlg->vals_lock); + if (o.len!=p-o.s) { LM_CRIT("BUG - buffer overflow allocated %d, written %d\n", o.len,(int)(p-o.s)); @@ -1639,7 +1639,7 @@ void dialog_update_db(unsigned int ticks, void *do_lock) struct dlg_entry *entry; struct dlg_cell * cell,*next_cell; unsigned char on_shutdown; - int callee_leg,ins_done=0; + int callee_leg, ins_done=0, reset_locked_by; static query_list_t *ins_list = NULL; db_key_t insert_keys[DIALOG_TABLE_TOTAL_COL_NO] = { @@ -1697,9 +1697,11 @@ void dialog_update_db(unsigned int ticks, void *do_lock) /* mark it as deleted so as we don't deal with it later */ cell->flags |= DLG_FLAG_DB_DELETED; /* timer is done with this dialog */ + reset_locked_by = (cell->ref > 1); cell->locked_by = process_no; unref_dlg_unsafe(cell,1,entry); - cell->locked_by = 0; + if (reset_locked_by) + cell->locked_by = 0; cell=next_cell; continue; } @@ -2514,4 +2516,3 @@ mi_response_t *mi_restore_dlg_db(const mi_params_t *params, else return init_mi_result_ok(); } - diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c index 0e792e1b7e4..273f18ca207 100644 --- a/modules/dialog/dlg_handlers.c +++ b/modules/dialog/dlg_handlers.c @@ -968,6 +968,7 @@ static void dlg_update_req_info(str *buffer, struct dlg_cell *dlg, int leg, if (t && is_invite(t)) dlg_leg_push_cseq_map(dlg, t, DLG_CALLER_LEG, &msg); dlg_update_out_sdp(dlg, leg, other_leg(dlg, leg), &msg, + msg.first_line.type == SIP_REQUEST && msg.REQ_METHOD != METHOD_ACK); free_sip_msg(&msg); } @@ -2169,7 +2170,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) return; } - if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK) + if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK || event==DLG_EVENT_REQPRACK) && (new_state==DLG_STATE_CONFIRMED || new_state==DLG_STATE_CONFIRMED_NA) ) { LM_DBG("sequential request successfully processed (dst_leg=%d)\n", dst_leg); diff --git a/modules/dialog/dlg_replication.c b/modules/dialog/dlg_replication.c index 4bc7e869401..414ea2c377f 100644 --- a/modules/dialog/dlg_replication.c +++ b/modules/dialog/dlg_replication.c @@ -300,24 +300,24 @@ int dlg_replicated_create(bin_packet_t *packet, struct dlg_cell *cell, /* link the dialog into the hash */ _link_dlg_unsafe(d_entry, dlg); - DLG_BIN_POP(str, packet, vars, pre_linking_error); - DLG_BIN_POP(str, packet, profiles, pre_linking_error); - DLG_BIN_POP(int, packet, dlg->user_flags, pre_linking_error); - DLG_BIN_POP(int, packet, dlg->mod_flags, pre_linking_error); + DLG_BIN_POP(str, packet, vars, post_linking_error); + DLG_BIN_POP(str, packet, profiles, post_linking_error); + DLG_BIN_POP(int, packet, dlg->user_flags, post_linking_error); + DLG_BIN_POP(int, packet, dlg->mod_flags, post_linking_error); - DLG_BIN_POP(int, packet, dlg->flags, pre_linking_error); + DLG_BIN_POP(int, packet, dlg->flags, post_linking_error); /* also save the dialog into the DB on this instance */ dlg->flags |= DLG_FLAG_NEW; - DLG_BIN_POP(int, packet, dlg->tl.timeout, pre_linking_error); + DLG_BIN_POP(int, packet, dlg->tl.timeout, post_linking_error); DLG_BIN_POP(int, packet, dlg->legs[DLG_CALLER_LEG].last_gen_cseq, - pre_linking_error); + post_linking_error); DLG_BIN_POP(int, packet, dlg->legs[callee_idx(dlg)].last_gen_cseq, - pre_linking_error); + post_linking_error); - DLG_BIN_POP_ROUTE( packet, dlg, on_answer, pre_linking_error); - DLG_BIN_POP_ROUTE( packet, dlg, on_timeout, pre_linking_error); - DLG_BIN_POP_ROUTE( packet, dlg, on_hangup, pre_linking_error); + DLG_BIN_POP_ROUTE( packet, dlg, on_answer, post_linking_error); + DLG_BIN_POP_ROUTE( packet, dlg, on_timeout, post_linking_error); + DLG_BIN_POP_ROUTE( packet, dlg, on_hangup, post_linking_error); if (dlg->tl.timeout <= (unsigned int)(unsigned long) time(0)) dlg->tl.timeout = 0; @@ -411,6 +411,10 @@ int dlg_replicated_create(bin_packet_t *packet, struct dlg_cell *cell, unref_dlg(dlg, 1); return 0; + +post_linking_error: + /* dialog was linked but not yet timer-inserted or ref-bumped */ + unlink_unsafe_dlg(d_entry, dlg); pre_linking_error: dlg_unlock(d_table, d_entry); if (dlg) @@ -439,7 +443,9 @@ int dlg_replicated_update(bin_packet_t *packet) struct dlg_entry *d_entry; int rcv_flags, save_new_flag, save_sync_flag; unsigned int h_id; + unsigned int new_state; short pkg_ver = get_bin_pkg_version(packet); + int state; bin_pop_str(packet, &call_id); bin_pop_str(packet, &from_tag); @@ -482,7 +488,18 @@ int dlg_replicated_update(bin_packet_t *packet) } bin_skip_int(packet, 1); - bin_pop_int(packet, &dlg->state); + state = dlg->state; + bin_pop_int(packet, &new_state); + /* Update stats when the dialog moves between confirmed, early, and other states. */ + if ((state == DLG_STATE_CONFIRMED_NA || state == DLG_STATE_CONFIRMED) != + (new_state == DLG_STATE_CONFIRMED_NA || new_state == DLG_STATE_CONFIRMED) || + (state == DLG_STATE_EARLY) != (new_state == DLG_STATE_EARLY)) { + update_dlg_stats(dlg, -1); + dlg->state = new_state; + update_dlg_stats(dlg, 1); + } else { + dlg->state = new_state; + } /* sockets */ bin_skip_str(packet, 2); diff --git a/modules/dialog/doc/contributors.xml b/modules/dialog/doc/contributors.xml deleted file mode 100644 index cd8a833f03a..00000000000 --- a/modules/dialog/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 460 - 288 - 13367 - 3546 - - - 2. - Razvan Crainea (@razvancrainea) - 299 - 222 - 5499 - 1804 - - - 3. - Vlad Paiu (@vladpaiu) - 262 - 149 - 7467 - 3027 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 200 - 104 - 4330 - 3514 - - - 5. - Liviu Chircu (@liviuchircu) - 183 - 133 - 3128 - 1374 - - - 6. - Ovidiu Sas (@ovidiusas) - 35 - 26 - 601 - 161 - - - 7. - Dan Pascu (@danpascu) - 30 - 25 - 233 - 179 - - - 8. - Eseanu Marius Cristian (@eseanucristian) - 19 - 6 - 722 - 341 - - - 9. - Daniel-Constantin Mierla (@miconda) - 16 - 13 - 76 - 66 - - - 10. - Henning Westerholt (@henningw) - 16 - 10 - 172 - 187 - - - -
-All remaining contributors: Anca Vamanu, Walter Doekes (@wdoekes), Ionut Ionita (@ionutrazvanionita), Maksym Sobolyev (@sobomax), Ionel Cerghit (@ionel-cerghit), Andrei Dragus, Alexandra Titoc, John Riordan, Hugues Mitonneau, Carsten Bock, Peter Lemenkov (@lemenkov), Jerome Martin, Klaus Darilion, Jarrod Baumann (@jarrodb), Nick Altmann (@nikbyte), Zero King (@l2dy), Michel Bensoussan, Richard Revels, Tavis Paquette, Elena-Ramona Modroiu, Ryan Bullock, Andrei Datcu (@andrei-datcu), Jeffrey Magder, Stefan-Cristian Mititelu, Ron Winacott, Andy Pyles, Julián Moreno Patiño, Konstantin Bokarius, sergei lavrov, Alex Massover, Damien Sandras (@dsandras), Alex Hermann, Dusan Klinec (@ph4r05), Norman Brandinger (@NormB), UnixDev, Eliot Gable, Ryan Bullock (@rrb3942), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2010 - Sep 2025 - - - 2. - Vlad Paiu (@vladpaiu) - Oct 2010 - Jan 2025 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2006 - Jun 2024 - - - 5. - Stefan-Cristian Mititelu - Jan 2024 - Jan 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Nov 2020 - Nov 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - Jul 2016 - Jun 2023 - - - 8. - Ovidiu Sas (@ovidiusas) - Feb 2008 - Jun 2023 - - - 9. - Ryan Bullock - May 2023 - May 2023 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Sep 2022 - - - -
-All remaining contributors: Nick Altmann (@nikbyte), Walter Doekes (@wdoekes), Liviu Chircu (@liviuchircu), sergei lavrov, Zero King (@l2dy), Dan Pascu (@danpascu), Ionel Cerghit (@ionel-cerghit), Jarrod Baumann (@jarrodb), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Dusan Klinec (@ph4r05), Eseanu Marius Cristian (@eseanucristian), Andrei Datcu (@andrei-datcu), Norman Brandinger (@NormB), Damien Sandras (@dsandras), Ryan Bullock (@rrb3942), Anca Vamanu, Alex Massover, Andrei Dragus, John Riordan, Hugues Mitonneau, Richard Revels, UnixDev, Alex Hermann, Henning Westerholt (@henningw), Carsten Bock, Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jerome Martin, Tavis Paquette, Michel Bensoussan, Eliot Gable, Andy Pyles, Elena-Ramona Modroiu, Jeffrey Magder, Ron Winacott. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Stefan-Cristian Mititelu, Ryan Bullock, Vlad Patrascu (@rvlad-patrascu), Zero King (@l2dy), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Ionel Cerghit (@ionel-cerghit), Walter Doekes (@wdoekes), Eseanu Marius Cristian (@eseanucristian), Norman Brandinger (@NormB), Anca Vamanu, Andrei Dragus, Hugues Mitonneau, Klaus Darilion, Henning Westerholt (@henningw), Ovidiu Sas (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Michel Bensoussan, Andy Pyles, Elena-Ramona Modroiu. -
- -
diff --git a/modules/dialog/doc/dialog.xml b/modules/dialog/doc/dialog.xml deleted file mode 100644 index 1a494919c17..00000000000 --- a/modules/dialog/doc/dialog.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - dialog Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006-2009 &voicesystem; - diff --git a/modules/dialog/doc/dialog_admin.xml b/modules/dialog/doc/dialog_admin.xml deleted file mode 100644 index 00f1a44149d..00000000000 --- a/modules/dialog/doc/dialog_admin.xml +++ /dev/null @@ -1,3552 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The dialog module provides dialog awareness to the &osips; proxy. Its - functionality is to keep trace of the current dialogs, to offer information - about them (like how many dialogs are active). - - - Aside tracking, the dialog module offers functionalities like flags and - attributes per dialog (persistent data across dialog), dialog profiling - and dialog termination (on timeout base or external triggered). - - - The module, via an internal API, also provide the foundation to build on - top of it more complex dialog-based functionalities via other &osips; - modules. - -
- -
- How it works - - To create the dialog associated with an initial request, you must call - the create_dialog() function, with or without parameter. - - - The dialog is automatically terminated when a BYE is - received. In case of no BYE, the dialog lifetime is - controlled via the default timeout (see default_timeout - - ) and custom timeout (see - $DLG_timeout - ). - - - Once terminated, the in-memory dialog may be destroyed right away or, - depending on the delete_delay - - ) setting, it may be kept for a - while in memory, in a read-only state (no action, no changes, nothing). - This delaying may be used to help with the routing of late in-dialog - request that may be received after the dialog terminted (like late BYE's - due retransmissions, cross BYE requests, auth'ed BYE request, slow ACK on - re-INVITEs, etc). - -
- -
- Dialog profiling - - Dialog profiling is a mechanism that helps in classifying, sorting and - keeping trace of certain types of dialogs, using whatever properties of - the dialog (like caller, destination, type of calls, etc). - Dialogs can be dynamically added in different (and several) profile - tables - logically, each profile table can have a special meaning (like - dialogs outside the domain, dialogs terminated to PSTN, etc). - - - There are two types of profiles: - - - - with no value - a dialog simply belongs - to a profile. (like outbound calls profile). There is no other - additional information to describe the dialog's belonging to the - profile; - - - - - with value - a dialog belongs to a profile - having a certain value (like in caller profile, where the value - is the caller ID). The belonging of the dialog to the profile is - strictly related to the value. - - - - - - A dialog can be added to multiple profiles in the same time. - - - Profiles are visible (at the moment) in the request route (for initial - and sequential requests) and in the branch, failure and reply routes of - the original request. - - - Dialog profiles can also be used in distributed systems, using the &osips; - CacheDB Interface or the clusterer module. This feature - allows you to share dialog profile information with multiple &osips; instaces - that use the same CacheDB backend or are part of an &osips; cluster. In order - to do that, the cachedb_url or - profile_replication_cluster parameters must be defined. - Also, the profile must be marked as shared, by adding one of the - '/s' or '/b' suffixes to the name of - the profile in the profiles_with_value or - profiles_no_value parameters. - -
- -
- Dialog clustering - - Dialog replication is a mechanism used to - mirror all dialog changes taking place in one OpenSIPS instance to one or - multiple other instances. The process is simplified by using the - clusterer module which facilitates the management of a - cluster of OpenSIPS nodes and the sending of replication-related BIN packets - (binary-encoded, using proto_bin). This feature - is useful in achieving High Availability and/or Load Balancing for ongoing calls. - - - Configuring both receival and sending of dialog replication packets is trivial - and can be done by using the - dialog_replication_cluster parameter. But in - addition to just sharing data, in order to properly cluster dialogs you will - need to manage which node in the cluster is doing certain actions on certain - dialogs using the sharing tags mechanism. - For details and configuration examples on how this would work - in different usage scenarios, see - this article. - - - The following actions will not be performed for a dialog - marked with a sharing tag that is in the "backup" state: - - sending Re-Invite or OPTIONS pings to end-points - generating BYE requests or any other actions(like producing CDRs) - upon dialog expiration - sending replication packets on dialog events(update, delete) - counting the dialog in the profiles that it belongs; only if profile replication - is also enabled - - - - In addition to the event-driven replication, an OpenSIPS instance will first - try to learn all the dialog information from antoher node in the cluster at startup. - The data synchronization mechanism requires defining one of the nodes in the cluster - as a "seed" node. - See the clusterer - module for details on how to do this and why is it needed. - - - In the context of dialog replication, using a database as a failsafe for obtaining - restart persistency for dialog data is useful in case all nodes in the cluster are down. - This approach makes the most sense if a separate, local DB is used for each node in the - cluster. Dialogs loaded from the database at startup, which are not reconfirmed through - syncing, are dropped and also deleted from the database once the sync from cluster is complete. - - - Also configuring profile replication via the profile_replication_cluster - parameter is not necessary when dialog replication is already configured. The profile information - is included in the dialog updates sent in the dialog replication cluster. The profiles must still - be marked for sharing though in the profiles_with_value or - profiles_no_value parameters. - - - A scenario were both profile and dialog replication should be configured is when a platform has - multiple POPs, where separate dialog replication clusters are configured for HA purposes, and a - cluster for globally shared profiles is also required. In this case, proper counting for dialogs - is ensured by using the sharing tags mechanism(in order to avoid counting each dialog twice, - both on the active and backup node for that dialog). - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction module - - - - - RR - Record-Route module, optional, - if Dialog ID matching is used in non Topo Hiding cases - - - - - clusterer - if replication_cluster - parameter is set (contact replication via clusterer - module) - - - - -
- - -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Parameters -
- <varname>enable_stats</varname> (integer) - - If the statistics support should be enabled or not. Via statistic - variables, the module provide information about the dialog processing. - Set it to zero to disable or to non-zero to enable it. - - - - Default value is 1 (enabled). - - - - Set <varname>enable_stats</varname> parameter - -... -modparam("dialog", "enable_stats", 0) -... - - -
- -
- <varname>hash_size</varname> (integer) - - The size of the hash table internally used to keep the dialogs. A - larger table is much faster but consumes more memory. The hash size - must be a power of 2 number. - - - IMPORTANT: If dialogs' information should be stored in a database, - a constant hash_size should be used, otherwise the restored process - will not take place. If you really want to modify the hash_size you - must delete all table's rows before restarting &osips;. - - - - Default value is 4096. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("dialog", "hash_size", 1024) -... - - -
- -
- <varname>log_profile_hash_size</varname> (integer) - - The size of the hash table internally used to store profile->dialog - associations. A larger table can provide more - parallel operations but consumes more memory. The hash size - is provided as the base 2 logarithm(e.g. log_profile_hash_size =4 - means the table has 2^4 entries). - - - - - Default value is 4. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("dialog", "log_profile_hash_size", 5) #set a table size of 32 -... - - -
- -
- <varname>rr_param</varname> (string) - - Name of the Record-Route parameter to be added with the dialog cookie. - It is used for fast dialog matching of the sequential requests. - - - - Default value is did. - - - - Set <varname>rr_param</varname> parameter - -... -modparam("dialog", "rr_param", "xyz") -... - - -
- -
- <varname>default_timeout</varname> (integer) - - The default dialog timeout (in seconds) if no custom one is set. - - - - Default value is 43200 (12 hours). - - - - Set <varname>default_timeout</varname> parameter - -... -modparam("dialog", "default_timeout", 21600) -... - - -
- -
- <varname>dlg_extra_hdrs</varname> (string) - - A string containing the extra headers (full format, with EOH) - to be added in the requests generated by the module (like BYEs). - - - - Default value is NULL. - - - - Set <varname>dlf_extra_hdrs</varname> parameter - -... -modparam("dialog", "dlg_extra_hdrs", "Hint: credit expired\r\n") -... - - -
- -
- <varname>dlg_match_mode</varname> (integer) - - How the seqential requests should be matched against the known dialogs. - The modes are a combination between matching based on a cookie (DID) - stored as cookie in Record-Route header and the matching based on SIP - elements (as in RFC3261). - - - The supported modes are: - - - - 0 - DID_ONLY - the match is done - exclusively based on DID; - - - 1 - DID_FALLBACK - the match is first - tried based on DID and if not present, it will fallback to - SIP matching; - - - 2 - DID_NONE - the match is done - exclusively based on SIP elements; no DID information is added - in RR. - - - - - Default value is 1 (DID_FALLBACK). - - - - NOTE that if you have call looping on your OpenSIPS server (passing - more than once through the same OpenSIPS instance), it is strongly - suggested to use only DID_ONLY mode, as the SIP based matching will - have an undefined behavior - from SIP perspective, a sequential - dialog will match all the loops of the call, as the Call-ID, To and - From TAGs are the same. - - - Set <varname>dlg_match_mode</varname> parameter - -... -modparam("dialog", "dlg_match_mode", 0) -... - - -
- -
- <varname>delete_delay</varname> (integer) - - The interval (seconds) to delay a dialog deletion / removal from - memory AFTER its termination. Once terminated, the dialog will - be kept in a read only state (no action, no changes), but it will - still be able to match and route late in-dialog requests. - - - This global value may be per-call changed via the DLG_del_delay - $DLG_del_delay () - script variable. - - - - Default value is 0 (disabled). - - - - Set <varname>delete_delay</varname> parameter - -... -modparam("dialog", "delete_delay", 10) -... - - -
- -
- <varname>db_url</varname> (string) - - If you want to store the information about the dialogs in a database - a database url must be specified. - - - - Default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("dialog", "db_url", "&exampledb;") -... - - -
- -
- <varname>db_mode</varname> (integer) - - Describe how to push into the DB the dialogs' information from memory. - - - The supported modes are: - - - - 0 - NO_DB - the memory content is not - flushed into DB; - - - 1 - REALTIME - any dialog information - changes will be reflected into the database immediately. - - - 2 - DELAYED - the dialog information - changes will be flushed into the DB periodically, based on a - timer routine. - - - 3 - SHUTDOWN - the dialog information - will be flushed into DB only at shutdown - no runtime updates. - - - - - Default value is 0. - - - - Set <varname>db_mode</varname> parameter - -... -modparam("dialog", "db_mode", 1) -... - - -
- -
- <varname>db_update_period</varname> (integer) - - The interval (seconds) at which to update dialogs' information if you chose to store the dialogs' info at a given interval. - A too short interval will generate intensive database operations, a too large one will not notice short dialogs. - - - - Default value is 60. - - - - Set <varname>db_update_period</varname> parameter - -... -modparam("dialog", "db_update_period", 120) -... - - -
- -
- <varname>options_ping_interval</varname> (integer) - - The interval (seconds) at which OpenSIPS will generate in-dialog - OPTIONS pings for one or both of the involved parties. - - - - Default value is 30. - - - - Set <varname>options_ping_interval</varname> parameter - -... -modparam("dialog", "options_ping_interval", 20) -... - - -
- -
- <varname>reinvite_ping_interval</varname> (integer) - - The interval (seconds) at which OpenSIPS will generate in-dialog - Re-INVITE pings for one or both of the involved parties. - - - Important: the ping timeout detection - is performed every time this interval ticks, not when the re-INVITE - transaction times out! Consequently, please make sure that the - timeouts for re-INVITE transactions (e.g. the "fr_timeout" - modparam of the "tm" module or its $T_fr_timeout variable) are - always lower than the value of this - parameter! Failing to ensure this ordering of timeouts may possibly - lead to re-INVITE pings never ending a disconnected dialog due to pings - getting retried before getting a chance to properly time out. - - - - Default value is 300. - - - - Set <varname>reinvite_ping_interval</varname> parameter - -... -modparam("dialog", "reinvite_ping_interval", 600) -... - - -
- -
- <varname>table_name</varname> (string) - - If you want to store the information about the dialogs in a - database a table name must be specified. - - - - Default value is dialog. - - - - Set <varname>table_name</varname> parameter - -... -modparam("dialog", "table_name", "my_dialog") -... - - -
- -
- <varname>call_id_column</varname> (string) - - The column's name in the database to store the dialogs' callid. - - - - Default value is callid. - - - - Set <varname>call_id_column</varname> parameter - -... -modparam("dialog", "call_id_column", "callid_c_name") -... - - -
- -
- <varname>from_uri_column</varname> (string) - - The column's name in the database to store the caller's - sip address. - - - - Default value is from_uri. - - - - Set <varname>from_uri_column</varname> parameter - -... -modparam("dialog", "from_uri_column", "from_uri_c_name") -... - - -
- -
- <varname>from_tag_column</varname> (string) - - The column's name in the database to store the From tag from - the Invite request. - - - - Default value is from_tag. - - - - Set <varname>from_tag_column</varname> parameter - -... -modparam("dialog", "from_tag_column", "from_tag_c_name") -... - - -
- -
- <varname>to_uri_column</varname> (string) - - The column's name in the database to store the calee's sip address. - - - - Default value is to_uri. - - - - Set <varname>to_uri_column</varname> parameter - -... -modparam("dialog", "to_uri_column", "to_uri_c_name") -... - - -
- - -
- <varname>to_tag_column</varname> (string) - - The column's name in the database to store the To tag from - the 200 OK response to the Invite request, if present. - - - - Default value is to_tag. - - - - Set <varname>to_tag_column</varname> parameter - -... -modparam("dialog", "to_tag_column", "to_tag_c_name") -... - - -
- -
- <varname>from_cseq_column</varname> (string) - - The column's name in the database to store the cseq from caller - side. - - - - Default value is caller_cseq. - - - - Set <varname>from_cseq_column</varname> parameter - -... -modparam("dialog", "from_cseq_column", "from_cseq_c_name") -... - - -
- -
- <varname>to_cseq_column</varname> (string) - - The column's name in the database to store the cseq from callee - side. - - - - Default value is callee_cseq. - - - - Set <varname>to_cseq_column</varname> parameter - -... -modparam("dialog", "to_cseq_column", "to_cseq_c_name") -... - - -
- -
- <varname>from_route_column</varname> (string) - - The column's name in the database to store the route records from - caller side (proxy to caller). - - - - Default value is caller_route_set. - - - - Set <varname>from_route_column</varname> parameter - -... -modparam("dialog", "from_route_column", "from_route_c_name") -... - - -
- -
- <varname>to_route_column</varname> (string) - - The column's name in the database to store the route records from - callee side (proxy to callee). - - - - Default value is callee_route_set. - - - - Set <varname>to_route_column</varname> parameter - -... -modparam("dialog", "to_route_column", "to_route_c_name") -... - - -
- -
- <varname>from_contact_column</varname> (string) - - The column's name in the database to store the caller's contact - uri. - - - - Default value is caller_contact. - - - - Set <varname>from_contact_column</varname> parameter - -... -modparam("dialog", "from_contact_column", "from_contact_c_name") -... - - -
- -
- <varname>to_contact_column</varname> (string) - - The column's name in the database to store the callee's contact - uri. - - - - Default value is callee_contact. - - - - Set <varname>to_contact_column</varname> parameter - -... -modparam("dialog", "to_contact_column", "to_contact_c_name") -... - - -
- -
- <varname>from_sock_column</varname> (string) - - The column's name in the database to store the information about - the local interface receiving the traffic from caller. - - - - Default value is caller_sock. - - - - Set <varname>from_sock_column</varname> parameter - -... -modparam("dialog", "from_sock_column", "from_sock_c_name") -... - - -
- -
- <varname>to_sock_column</varname> (string) - - The column's name in the database to store information about the - local interface receiving the traffic from callee. - - - - Default value is callee_sock. - - - - Set <varname>to_sock_column</varname> parameter - -... -modparam("dialog", "to_sock_column", "to_sock_c_name") -... - - -
- -
- <varname>dlg_id_column</varname> (string) - - The column's name in the database to store the dialogs' - id information. - - - - Default value is dlg_id. - - - - Set <varname>dlg_id_column</varname> parameter - -... -modparam("dialog", "dlg_id_column", "dlg_id_c_name") -... - - -
- -
- <varname>state_column</varname> (string) - - The column's name in the database to store the - dialogs' state information. - - - - Default value is state. - - - - Set <varname>state_column</varname> parameter - -... -modparam("dialog", "state_column", "state_c_name") -... - - -
- -
- <varname>start_time_column</varname> (string) - - The column's name in the database to store the - dialogs' start time information. - - - - Default value is start_time. - - - - Set <varname>start_time_column</varname> parameter - -... -modparam("dialog", "start_time_column", "start_time_c_name") -... - - -
- -
- <varname>timeout_column</varname> (string) - - The column's name in the database to store the dialogs' timeout. - - - - Default value is timeout. - - - - Set <varname>timeout_column</varname> parameter - -... -modparam("dialog", "timeout_column", "timeout_c_name") -... - - -
- -
- <varname>profiles_column</varname> (string) - - The column's name in the database to store the dialogs' profiles. - - - - Default value is profiles. - - - - Set <varname>profiles_column</varname> parameter - -... -modparam("dialog", "profiles_column", "profiles_c_name") -... - - -
- -
- <varname>vars_column</varname> (string) - - The column's name in the database to store the dialogs' vars. - - - - Default value is vars. - - - - Set <varname>vars_column</varname> parameter - -... -modparam("dialog", "vars_column", "vars_c_name") -... - - -
- -
- <varname>sflags_column</varname> (string) - - The column's name in the database to store the dialogs' script flags. - - - - Default value is script_flags. - - - - Set <varname>sflags_column</varname> parameter - -... -modparam("dialog", "sflags_column", "sflags_c_name") -... - - -
- -
- <varname>mflags_column</varname> (string) - - The column's name in the database to store the dialogs' module flags. - - - - Default value is module_flags. - - - - Set <varname>mflags_column</varname> parameter - -... -modparam("dialog", "mflags_column", "mflags_c_name") -... - - -
- -
- <varname>flags_column</varname> (string) - - The column's name in the database to store the dialogs' flags. - - - - Default value is flags. - - - - Set <varname>flags_column</varname> parameter - -... -modparam("dialog", "flags_column", "flags_c_name") -... - - -
- -
- <varname>profiles_with_value</varname> (string) - - List of names (alphanumerical/-/_) for profiles with values. Flags - /b or /s allow sharing - profiles between &osips; instances using the clusterer module or a - CacheDB backend, respectively. - - - - Default value is empty. - - - - Set <varname>profiles_with_value</varname> parameter - -... -modparam("dialog", "profiles_with_value", "callerCC; gatewayCC; clientChannels/s; codecUsed/b;") -... - - -
- -
- <varname>profiles_no_value</varname> (string) - - List of names (alphanumerical/-/_) for profiles without values. Flags - /b or /s allow sharing - profiles between &osips; instances using the clusterer module or a - CacheDB backend, respectively. - - - - Default value is empty. - - - - Set <varname>profiles_no_value</varname> parameter - -... -modparam("dialog", "profiles_no_value", "inbound ; outbound ; shared/s; repl/b;") -... - - -
- -
- <varname>db_flush_vals_profiles</varname> (int) - - Pushes dialog values, profiles and flags into the database - along with other dialog state information (see db_mode 1 and 2). - - - - Default value is empty. - - - - Set <varname>db_flush_vals_profiles</varname> parameter - -... -modparam("dialog", "db_flush_vals_profiles", 1) -... - - -
- -
- <varname>timer_bulk_del_no</varname> (int) - - The number of dialogs that should be attempted to be - deleted at the same time ( a single query ) from the - DB back-end. - - - - Default value is 1. - - - - Set <varname>timer_bulk_del_no</varname> parameter - -... -modparam("dialog", "timer_bulk_del_no", 10) -... - - -
- -
- <varname>race_condition_timeout</varname> (int) - - If dialog is created using the 'E' flag, and a SIP Race condition happens, then the dialog will be terminated after 'race_condition_timeout' seconds. - Currently, the only supported race conditions are (200OK vs CANCEL) and (early BYE vs 200OK) - - - - Default value is 5 seconds. - - - - Set <varname>race_condition_timeout</varname> parameter - -... -modparam("dialog", "race_condition_timeout", 1) -... - - -
- -
- <varname>cachedb_url</varname> (string) - - Enables distributed dialog profiles and specifies the - backend that should be used by the CacheDB interface. - - - - Default value is empty. - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("dialog", "cachedb_url", "redis://127.0.0.1:6379") -... - - -
- -
- <varname>profile_value_prefix</varname> (string) - - Specifies what prefix should be added to the profiles with - value when they are inserted into CacheDB backed. This is - only used when distributed profiles are enabled. - - - - Default value is dlg_val_. - - - - Set <varname>profile_value_prefix</varname> parameter - -... -modparam("dialog", "profile_value_prefix", "dlgv_") -... - - -
- -
- <varname>profile_no_value_prefix</varname> (string) - - Specifies what prefix should be added to the profiles without - value when they are inserted into CacheDB backed. This is - only used when distributed profiles are enabled. - - - - Default value is dlg_noval_. - - - - Set <varname>profile_no_value_prefix</varname> parameter - -... -modparam("dialog", "profile_no_value_prefix", "dlgnv_") -... - - -
- -
- <varname>profile_size_prefix</varname> (string) - - Specifies what prefix should be added to the entity that holds - the profiles with value size in CacheDB backed. This is - only used when distributed profiles are enabled. - - - - Default value is dlg_size_. - - - - Set <varname>profile_size_prefix</varname> parameter - -... -modparam("dialog", "profile_size_prefix", "dlgs_") -... - - -
- -
- <varname>profile_timeout</varname> (int) - - Specifies how long a dialog profile should be kept in the CacheDB - until it expires. This is only used when distributed profiles are - enabled. - - - - Default value is 86400. - - - - Set <varname>profile_timeout</varname> parameter - -... -modparam("dialog", "profile_timeout", "43200") -... - - -
- -
- <varname>dialog_replication_cluster</varname> (int) - - Specifies the cluster ID for dialog replication using the - clusterer module. This enables sending - and receiving all the dialog-related events (creation, update and - deletion) in the cluster. - - - &clusterer_sync_cap_para; - - - - Default value is 0 (no replication). - - - - Set <varname>dialog_replication_cluster</varname> parameter - -... -modparam("dialog", "dialog_replication_cluster", 1) -... - - -
- -
- <varname>profile_replication_cluster</varname> (int) - - Specifies the cluster ID for profile replication using the - clusterer module. This enables sending - and receiving the profile information (value, dialog count) - in the cluster. - - - - Default value is 0 (no replication). - - - - Set <varname>profile_replication_cluster</varname> parameter - -... -modparam("dialog", "profile_replication_cluster", 1) -... - - -
- -
- <varname>replicate_profiles_buffer</varname> (string) - - Used to specify the length of the buffer used by the binary - replication, in bytes. Usually this should be big enough to hold - as much data as possible, but small enough to avoid UDP - fragmentation. The recommended value is the smallest MTU between - all the replication instances. - - - - Default value is 1400 bytes. - - - - Set <varname>replicate_profiles_buffer</varname> parameter - -... -modparam("dialog", "replicate_profiles_buffer", 500) -... - - -
-
- <varname>replicate_profiles_check</varname> (string) - - Timer in seconds, used to specify how often the module should check - whether old, replicated profiles values are obsolete and should be removed. - should replicate its profiles to the other instances. - - - - Default value is 10 s. - - - - Set <varname>replicate_profiles_check</varname> parameter - -... -modparam("dialog", "replicate_profiles_check", 100) -... - - -
-
- <varname>replicate_profiles_timer</varname> (string) - - Timer in milliseconds, used to specify how often the module - should replicate its profiles to the other instances. - - - - Default value is 200 ms. - - - - Set <varname>replicate_profiles_timer</varname> parameter - -... -modparam("dialog", "replicate_profiles_timer", 100) -... - - -
-
- <varname>replicate_profiles_expire</varname> (string) - - Timer in seconds, used to specify when the profiles counters received - from a different instance should no longer be taken into account. - This is used to prevent obsolete values, in case an instance stops - replicating its counters. - - - - Default value is 10 s. - - - - Set <varname>replicate_profiles_expire</varname> parameter - -... -modparam("dialog", "replicate_profiles_expire", 10) -... - - -
-
- <varname>cluster_auto_sync</varname> (string) - - Specifies whether to automatically issue a sync request (for dialogs - marked with a sharing tag in backup state) when a node becomes reachable. - A value of 1 means enabled and 0 - disabled. - - - Default value is 1 (enabled). - - - Set <varname>cluster_auto_sync</varname> parameter - -... -modparam("dialog", "cluster_auto_sync", 0) -... - - -
-
- - -
- Exported Functions - -
- - <function moreinfo="none">create_dialog([flags])</function> - - - The function creats the dialog for the currently processed request. The - request must be an initial request. - - Optionally,the function also receives a string parameter, which specifies - special behavior to be done for the current dialog. - - - Parameters: - - - flags (string, optional) - Possible values here are : - - - B - Upon reaching dialog lifetime, BYEs will be triggered - both ways - - - P - Ping caller side with OPTIONS messages, once every - options_ping_interval seconds - - - p - Ping callee side with OPTIONS messages, once every - options_ping_interval seconds - - - R - Ping caller side with RE-INVITE messages, once every - reinvite_ping_interval seconds - - - r - Ping callee side with RE-INVITE messages, once every - reinvite_ping_interval seconds - - - E - Upon detecting a SIP Race condition (see RFC 5407), - end the call after race_condition_timeout seconds - - - Multiple string flags can be used at the same time, - ie. passing "BPp" flags will enable all 3 flags. - - - - NOTE: both RE-INVITE and OPTIONS pinging cannot be enabled at the same time - for a single dialog leg. If both flags ("PR" or - "pr") are provided only RE-INVITE pinging will be used. - - - The function returns true if the dialog was successfully created or - if the dialog was previously created. - - - This function can be used from REQUEST_ROUTE. - - - <function>create_dialog()</function> usage - -... -create_dialog(); -... -#ping caller -create_dialog("P"); -... -#ping caller and callee -create_dialog("Pp"); - -#bye on timeout -create_dialog("B"); -... - - -
- -
- - <function moreinfo="none">match_dialog([dlg_match_mode])</function> - - - This function is to be used to match a sequential (in-dialog) request - to an ongoing dialog. - - - By default, dialog matching is performed according to the - module parameter. A specific - matching mode may be enforced by specifying the optional - "dlg_match_mode" parameter. Possible values for this parameter are - "DID_ONLY", "DID_FALLBACK" and "DID_NONE". - - - As sequential requests are automatically matched to the dialog when - doing "loose_route()" from script, this function is intended to: - (A) control the place in your script where the dialog matching is done - and (B) to cope with bogus sequential requests that do not have Route - headers, so they are not handled by loose_route(). - - Parameters: - - - dlg_match_mode (string, optional) - - - - The function returns true if a dialog exists for the request. - - - This function can be used from REQUEST_ROUTE. - - - <function>match_dialog()</function> usage - -... - if (has_totag()) { - loose_route(); - - # example 1: match according to - if ($DLG_status == NULL && !match_dialog()) - xlog("cannot match request to a dialog\n"); - - # example 2: override - if ($DLG_status == NULL && !match_dialog("DID_FALLBACK")) - xlog("cannot match request to a dialog\n"); - } -... - - -
- - -
- - <function moreinfo="none">validate_dialog()</function> - - - The function checks the current received requests against the dialog - (internal data) it belongs to. - Performing several tests, the function will help to detect the bogus - injected in-dialog requests (like malicious BYEs). - - - The performed tests are related to CSEQ sequence checking and routing - information checking (contact and route set). - - - The function returns true if a dialog exists for the request and if - the request is valid (according to dialog data). If the request is invalid, - the following return codes are returned : - - - -1 - invalid cseq - - - - -2 - invalid remote target - - - - -3 - invalid route set - - - - -4 - other errors ( parsing, no dlg, etc ) - - - - - - - This function can be used from REQUEST_ROUTE. - - - <function>validate_dialog()</function> usage - -... - if (has_totag()) { - loose_route(); - if ($DLG_status!=NULL && !validate_dialog() ) { - xlog(" in-dialog bogus request \n"); - } else { - xlog(" in-dialog valid request - $DLG_dir !\n"); - } - } -... - - -
- -
- - <function moreinfo="none">fix_route_dialog()</function> - - - The function forces an in dialog SIP message to contain the ruri, route headers and - dst_uri, as specified by the internal data of the dialog it belongs to. - The function will prevent the existence of bogus injected in-dialog - requests ( like malicious BYEs ) - - - This function can be used from REQUEST_ROUTE. - - - <function>fix_route_dialog()</function> usage - -... - if (has_totag()) { - loose_route(); - if ($DLG_status!=NULL) - if (!validate_dialog()) - fix_route_dialog(); - } -... - - -
- - -
- - <function moreinfo="none">get_dialog_info(attr,avp,key,key_val,no_dlgs)</function> - - - The function extracts a dialog value from another dialog. It first searches - through all existing (ongoing) dialogs for all dialogs that have a dialog - variable named "key" with the value "key_val" - (so a dialog where $dlg_val(key)=="key_val"). If found, it returns - the value of the dialog variable "attr" from all the - founds dialog in the "avp" pseudo-variable, otherwise nothing is written - in "avp", and a negative error code is returned. - - - NOTE: the function does not require to be called in the context of - a dialog - you can use it whenever / whereever for searching for other - dialogs. - - Meaning of the parameters is as follows: - - - attr (string) - the name of the dialog variable - (from the found dialog) to be returned; - - - - avp (var) - an avp where to store the values of - the "attr" dialog variable. - Since the function checks through all dialogs, this needs to be an actual - AVP in order to support pushing values from all matched dialogs. - - - - key (string) - name of a dialog variable to be - used a search key (when looking after the target dialog) - - - - key_val (var) - the value of the dialog - variable that is used as key in searching the target dialog. - - - - no_dlgs (var) - the total number of dialogs - containing the key variable - - - - - This function can be used from ALL ROUTES. - - - <function>get_dialog_info</function> usage - -... -if ( get_dialog_info("callee",$avp(callee_array),"caller",$fu,$var(dlg_no)) ) { - xlog("caller $fu has $var(dlg_no) other ongoing calls, talking with :"); - $var(it) = 0; - while ($var(it) < $var(dlg_no)) { - $var(current_callee) = $(avp(callee_array)[$var(it)]); - xlog(" $var(current_callee) "); - $var(it) = $var(it) + 1; - } - - xlog("\n"); -} - -# create dialog for current call and place the caller and callee attributes -create_dialog(); -$dlg_val(caller) = $fu; -$dlg_val(callee) = $ru; -... - - -
- - -
- - <function moreinfo="none">get_dialog_vals(names,vals,callid)</function> - - - The function fetches all the dialog variables of another dialog. - It first searches through all existing (ongoing) dialogs based on the - given SIP CallID. If found, it returns all the dialog variables as - two parallel arrays of names and values (using the given variables - "names" and "vals"). As these variables have to hold arrays, they must - be AVPs. - - - NOTE: the function does not require to be called in the context of - a dialog - you can use it whenever / whereever for searching for other - dialogs. - - Meaning of the parameters is as follows: - - - names (var) - an AVP variable to - hold all the names of the variables from the found dialog. - - - - vals (var) - an AVP variable to - hold all the values of the variables from the found dialog. - - - - callid (string) - the callid of a dialog - to be searched (and have the variables fetched). - - - - - This function can be used from any type of route. - - - <function>get_dialog_vals</function> usage - -... -if ( get_dialog_vals($avp(d_names),$avp(d_vals),$var(callid)) ) { - xlog("the call $var(callid) has the variables:\n); - $var(i) = 0; - while ( $(avp(d_names)[$var(i)])!=NULL ) { - xlog("var $var(i) is $(avp(d_names)[$var(i)])='$(avp(d_vals)[$var(i)])'\n"); - $var(i) = $var(i) + 1; - } -} -... - - -
- -
- - <function moreinfo="none">get_dialogs_by_val(name,value,out_avp,out_dlg_no)</function> - - - The function looks up through the whole dialog table for dialogs containing a $dlg_val with the provided name and value, and returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable - - - NOTE: the function does not require to be called in the context of - a dialog - you can use it whenever / whereever for searching for other - dialogs. - - Meaning of the parameters is as follows: - - - name (string) - the name of the dialog variable used for the lookup - - - - value (var) - the value of the above dialog val - - - - out_avp (var) - the AVP which will be populated will the dialog JSONs for all the matched calls - - - - dlg_no (var) - the out var which will contain the total number of matched dialogs - - - - - This function can be used from any type of route. - - - <function>get_dialog_vals</function> usage - -... -if ( get_dialogs_by_val("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) { - xlog("Caller $fU has $avp(dlg_no) other calls \n); - $var(i) = 0; - while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { - $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); - # fetch any info for the above call and process it - $var(i) = $var(i) + 1; - } -} -... - - -
- -
- - <function moreinfo="none">get_dialogs_by_profile(name,value,out_avp,out_dlg_no)</function> - - - The function looks up through the whole dialog table for dialogs configured to be within the provided dialog profile name, and optionally with the provided profile value. The function returns all the $DLG_ctx_json variables for the matched dialogs, storing them in the provided out_avp. The total number of matched dialogs is returned in the out_dlgs_no variable - - - NOTE: the function does not require to be called in the context of - a dialog - you can use it whenever / whereever for searching for other - dialogs. - - Meaning of the parameters is as follows: - - - name (string) - the name of the dialog profile used for the lookup - - - - value (string) - the value of the above dialog profile ( optional ) - - - - out_avp (var) - the AVP which will be populated will the dialog JSONs for all the matched calls - - - - dlg_no (var) - the out var which will contain the total number of matched dialogs - - - - - This function can be used from any type of route. - - - <function>get_dialog_vals</function> usage - -... -if ( get_dialogs_by_profile("caller",$fU,$avp(dlg_jsons),$avp(dlg_no)) ) { - xlog("Caller $fU has $avp(dlg_no) other calls \n); - $var(i) = 0; - while ( $(avp(dlg_jsons)[$var(i)])!=NULL ) { - $json(dlg_info) := $(avp(dlg_jsons)[$var(i)]); - # fetch any info for the above call and process it - $var(i) = $var(i) + 1; - } -} -... - - -
- - -
- - <function moreinfo="none">load_dialog_ctx( dialog [, id_type])</function> - - - The function loads and switches to the context of the given dialog. - The context of a dialog is given by the dialog flags, variables, - profiles and any other value/state related to the dialog. By - switching to the context of another dialog, you will see at the script - level, by default, all the data from the new dialog. - - - NOTE: you cannot perform a new load until doing an unload - no nested - loadings are possible. - - Meaning of the parameters is as follows: - - - dialog (string) - the identifier of the - dialog to be loaded, it may be a SIP Call-ID or a Dialog ID. - - - - id_type (string,optional) - what kind of - dialog identified was used in the first parameter. It can be - callid (SIP Call-ID) or - did (internal Dialog ID). By default callid - will be assumed. - - - - - This function can be used from any type of route. - - - <function>load_dialog_ctx</function> usage - -... -if (load_dialog_ctx("$var(callid)")) { - xlog("The dialog '$var(callid)' already has a duration " - "of $DLG_lifetime seconds\n"); - if (is_in_profile("inboundCall")) - xlog("this dialog is an inbound call\n"); - unload_dialog_ctx(); -} -... - - -
- - -
- - <function moreinfo="none">unload_dialog_ctx()</function> - - - The function off-loads the loaded context of another dialog, exposing - whatever dialog context was present before doing the load. - - - NOTE: you MUST perform from script an explicit unload for each load - you did, otherwise the loaded dialog will remain hanged for ever. - - - This function can be used from any type of route. - - - For usage example, see the - -
- - -
- - <function moreinfo="none">set_dlg_profile(profile, [value], [clear_values])</function> - - - Inserts the current dialog into a profile. Note that if the profile does - not support values, this will be silently discarded. A dialog may be - inserted in the same profile multiple times. - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - Meaning of the parameters is as follows: - - - profile (string) - name of the profile to be - added to. - - - - value (string, optional) - string value to - define the belonging of the dialog to the profile - note that the - profile must support values. - - - - clear_values (boolean, optional) - if set to - true (1), all values of the profile will be cleared - before setting the given value. Default: false. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>set_dlg_profile</function> usage - -... -set_dlg_profile("inboundCall"); - -# Set a new value (all other values are kept intact) -set_dlg_profile("caller", $fu); - -# Set a new value while removing all previous values -set_dlg_profile("caller", $fu, true); -... - - -
- - -
- - <function moreinfo="none">unset_dlg_profile(profile, [value])</function> - - - Removes the current dialog from a profile. - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - Meaning of the parameters is as follows: - - - profile (string) - name of the profile to be - removed from. - - - - value (string, optional) - string value to - define the belonging of the dialog to the profile - note that the - profile must support values. - - NEW in 3.4: for profiles with value, by omitting this parameter - you can now clear all values of the given profile. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>unset_dlg_profile</function> usage - -... -unset_dlg_profile("inboundCall"); -unset_dlg_profile("caller", $fu); -... -# Remove all values in a profile -unset_dlg_profile("caller"); -... - - -
- - -
- - <function moreinfo="none">is_in_profile(profile,[value])</function> - - - Checks if the current dialog belongs to a profile. If the profile - supports values, the check can be reinforced to take into account a - specific value - if the dialog was inserted into the profile for a - specific value. If no value is passed, only simply belonging of the - dialog to the profile is checked. Note that if the profile does not - support values, this will be silently discarded. - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - Meaning of the parameters is as follows: - - - profile (string) - name of the profile to be - checked against. - - - - value (string. optional) - string value to - toughen the check. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>is_in_profile</function> usage - -... -if (is_in_profile("inboundCall")) { - log("this request belongs to a inbound call\n"); -} -... -if (is_in_profile("caller","XX")) { - log("this request belongs to a call of user XX\n"); -} -... - - -
- -
- - <function moreinfo="none">get_profile_size(profile,[value],size)</function> - - - Returns the number of dialogs belonging to a profile. If the profile - supports values, the check can be reinforced to take into account a - specific value - how many dialogs were inserted into the profile with - a specific value. If not value is passed, only simply belonging of the - dialog to the profile is checked. Note that the profile does not - supports values, this will be silently discarded. - - Meaning of the parameters is as follows: - - - profile (string) - name of the profile to get - the size for. - - - - value (string, optional) - string value to - toughen the check. - - - - size (var) - an AVP or script variable to - return the profile size in. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>get_profile_size</function> usage - -modparam("dialog", "profiles_no_value", "inboundCalls") -modparam("dialog", "profiles_with_value", "caller") -... -get_profile_size("inboundCalls",,$var(size)); -xlog("inboundCalls: $var(size)\n"); -... -get_profile_size("caller", $fu, $var(size)); -xlog("currently, the user $fu has $var(size) active outgoing calls\n"); -... - - -
- -
- - <function moreinfo="none">set_dlg_flag(flag)</function> - - - Sets the dialog flag named flag to true. The dialog - flags are dialog persistent and they can be accessed (set and test) - for all requests belonging to the dialog. - - Parameters: - - - flag (string, static) - The flag name. - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>set_dlg_flag</function> usage - -... -set_dlg_flag("MY_DLG_FLAG"); -... - - -
- -
- - <function moreinfo="none">test_and_set_dlg_flag(flag, value)</function> - - - Atomically checks if the dialog flag named flag is - equal to value. If true, changes the value with the - opposite one. This operation is done under the dialog lock. - - - - flag (string, static) - The flag name. - - - value (int) - The value should be 0 (false) or 1 (true). - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>test_and_set_dlg_flag</function> usage - -... -test_and_set_dlg_flag("MY_DLG_FLAG", 0); -... - - -
- -
- - <function moreinfo="none">reset_dlg_flag(flag)</function> - - - Resets the dialog flag named flag to false. - The dialog flags are dialog persistent and they can be accessed - (set and test) for all requests belonging to the dialog. - - Parameters: - - - flag (string, static) - The flag name. - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>reset_dlg_flag</function> usage - -... -reset_dlg_flag("MY_DLG_FLAG"); -... - - -
- -
- - <function moreinfo="none">is_dlg_flag_set(flag)</function> - - - Returns true if the dialog flag named flag is set. - The dialog flags are dialog persistent and they can be accessed - (set and test) for all requests belonging to the dialog. - - Parameters: - - - flag (string, static) - The flag name. - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>is_dlg_flag_set</function> usage - -... -if (is_dlg_flag_set("MY_DLG_FLAG")) { - xlog("dialog flag MY_DLG_FLAG is set\n"); -} -... - - -
- -
- - <function moreinfo="none">store_dlg_value(name,val)</function> - - - Attaches to the dialog the value from the variable val - under the name name. The values attached to dialogs are - dialog persistent and they can be accessed (read and write) for all - requests belonging to the dialog. - - Parameters: - - - name (string) - - - val (var) - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - Same functionality may be obtain by assigning a value to pseudo - variable $dlg_val(name). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>store_dlg_value</function> usage - -... -store_dlg_value("inv_src_ip",$si); -store_dlg_value("account type",$var(account)); -# or -$dlg_val(account_type) = "prepaid"; -... - - -
- -
- - <function moreinfo="none">fetch_dlg_value(name,val)</function> - - - Fetches from the dialog the value of attribute named - name. The values attached to dialogs are - dialog persistent and they can be accessed (read and write) for all - requests belonging to the dialog. - - Parameters: - - - name (string) - - - val (var) - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - Same functionality may be obtain by reading the pseudo - variable $dlg_val(name). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>fetch_dlg_value</function> usage - -... -fetch_dlg_value("inv_src_ip",$avp(2)); -fetch_dlg_value("account type",$var(account)); -# or -$var(account) = $dlg_val(account_type); -... - - -
- -
- - <function moreinfo="none">set_dlg_sharing_tag(tag_name)</function> - - - Marks the current dialog with the sharing tag tag_name. - From this point on, actions like in-dialog pinging, BYEs on timeout etc. - will depend on the tag state(no action in "backup" state, normal operation - in "active" state). - - - For more details see the chapter. - - Parameters: - - - tag_name (string) - - - - NOTE: the dialog must be created before using this function (use - create_dialog() function before). - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>set_dlg_sharing_tag</function> usage - -... -set_dlg_sharing_tag("vip1"); -... - - -
- -
- - <function moreinfo="none">dlg_on_answer([route_name])</function> - - - The function arms a script route to be executed when the current - dialog will be later answered. When the route will be executed, the - dialog context will be exposed, but with no valid SIP message (just - a phony one). - - - You must use this function AFTER creating the dialog and before the - dialog being answered. - - - If the parameter is missing, the function does a reset of any route - previously set; there will be no triggering. - - Parameters: - - - route_name (string,optional) - the name - of the script route to be executed. - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>dlg_on_answer</function> usage - -... -create_dialog(); -dlg_on_answer("dlg_answered"); -... -route[dlg_answered] { - xlog("The dialog $DLG_did was answered\n"); -} - - -
- -
- - <function moreinfo="none">dlg_on_timeout([route_name])</function> - - - The function arms a script route to be executed when (and if) the - current dialog will timeout (as duration). When the route will be - executed, the dialog context will be exposed, but with no valid SIP - message (just a phony one) - - - When the route is executed, the dialog is not yet terminated, just its - lifetime reached the set limit. In the timeout route you can increase - the dialog expiration timeout (and the dialog will continue) or you - can let the dialog to be terminated (after the end of this route). - - - You must use this function AFTER creating the dialog and before the - dialog being answered. - - - You must use this function AFTER creating the dialog and before the - dialog being answered. - - Parameters: - - - route_name (string,optional) - the name - of the script route to be executed. - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>dlg_on_timeout</function> usage - -... -create_dialog(); -$DLG_timeout=120; -dlg_on_timeout("dlg_timeout"); -... -route[dlg_timeout] { - xlog("The dialog $DLG_did timed out\n"); - if (_some_prolongation_condition) - $DLG_timeout = 60; # give it 1 min more -} - - -
- -
- - <function moreinfo="none">dlg_on_hangup([route_name])</function> - - - The function arms a script route to be executed when the current - dialog will be terminated. When the route will be executed, the - dialog context will be exposed, but with no valid SIP message (just - a phony one). Note that the dialog will be already terminated and there - is nothing you can do about it besides reading data from its context. - - - You must use this function AFTER creating the dialog and before the - dialog being answered. - - - If the parameter is missing, the function does a reset of any route - previously set; there will be no triggering. - - Parameters: - - - route_name (string,optional) - the name - of the script route to be executed. - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - REPLY_ROUTE and FAILURE_ROUTE. - - - <function>dlg_on_hangup</function> usage - -... -create_dialog(); -dlg_on_hangup("dlg_hangup"); -... -route[dlg_hangup] { - xlog("The dialog $DLG_did terminated after $DLG_lifetime secs\n"); -} - - -
- -
- - <function moreinfo="none">dlg_send_sequential(method, leg, [, body] [, content-type] [, headers])</function> - - - Used to send an in-dialog request towards one if the dialog's legs. - The function assumes that is runs inside a dialog context - if you - are running it from a different context (such as an event_route), - make sure you first load the dialog context using the - function. - - Parameters: - - method (string) - - the method of the request sent. - - leg (string) - the leg - where the request is sent. Must be either - caller or callee. - - body (string, optional) - an - optional body sent in the request. If missing, no body is sent. - - content-type (string, optional) - - the content type of the body sent. Make sure you specify this - every time you send a request with a body, otherwise there are high - changes that your UAC will reject the request. - - headers (string, optional) - - additional headers attached to the request sent. - - - - This function can be used from ANY route. - - - <function>dlg_send_sequential</function> usage to convert DTMF codes - -... -event_route[E_RTPPROXY_DTMF] { - if (load_dialog_ctx("$param(id)", "did")) { - if ($param(stream) == 0) { - $var(direction) = "callee"; - } else { - $var(direction) = "caller"; - } - dlg_send_sequential($var(direction), "INFO", - "Signal=$param(digit)\nDuration=160", - "application/dtmf-relay"); - unload_dialog_ctx(); - } -} -... - - -
-
- - <function moreinfo="none">dlg_inc_cseq([tag, ][inc])</function> - - Increments the dialog's generated CSeq associated to the leg - identified by the dialog's tag. - - Parameters: - - tag (string, optional) - - the tag to increment the CSeq value for. If missing, the - message's To tag is used to identify - the leg to increment the CSeq for. - - inc (integer, optional) - the - value used to increment/decrement (if negative) the CSeq of - the identified leg. If not used, the value is incremented with - 1. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE routes. - - - <function>dlg_inc_cseq</function> usage - -... -route { - ... - if (has_totag()) { - if (loose_route()) - dlg_inc_cseq(); # increment upstream CSeq after each in-dialog request - } -} -... - - -
- -
- - -
- Exported Statistics -
- <varname>active_dialogs</varname> - - Returns the number of current active dialogs (may be confirmed or - not). - -
-
- <varname>early_dialogs</varname> - - Returns the number of early dialogs. - -
-
- <varname>processed_dialogs</varname> - - Returns the total number of processed dialogs (terminated, - expired or active) from the startup. - -
-
- <varname>expired_dialogs</varname> - - Returns the total number of expired dialogs from the startup. - -
-
- <varname>failed_dialogs</varname> - - Returns the number of failed dialogs ( dialogs were - never established due to whatever reasons - internal error, - negative reply, cancelled, etc ) - -
-
- <varname>create_sent</varname> - - Returns the number of replicated dialog - create requests send to other OpenSIPS - instances. - -
-
- <varname>update_sent</varname> - - Returns the number of replicated dialog - update requests send to other OpenSIPS - instances. - -
-
- <varname>delete_sent</varname> - - Returns the number of replicated dialog - delete requests send to other OpenSIPS - instances. - -
-
- <varname>create_recv</varname> - - Returns the number of dialog - create events received from other - OpenSIPS instances. - -
-
- <varname>update_recv</varname> - - Returns the number of dialog - update events received from other - OpenSIPS instances. - -
-
- <varname>delete_recv</varname> - - Returns the number of dialog - delete events received from other - OpenSIPS instances. - -
-
- -
- Exported MI Functions - -
- - <function moreinfo="none">dlg_list</function> - - - Lists the description of the dialogs (calls). If no parameter is given, - all dialogs will be listed. If a dialog identifier is passed - as parameter (callid and fromtag), only that dialog will be listed. If - a index and conter parameter is passed, it will list only a number of - "counter" dialogs starting with index (as offset) - this is used to - get only section of dialogs. - - - Name: dlg_list - - Parameters (with dialog idetification): - - - callid (optional) - callid if a single - dialog to be listed. - - - from_tag (optional, but cannot be present - without the callid parameter) - fromtag (as per initial request) - of the dialog to be listed. - entry - - - Parameters (with dialog counting): - - - index - offset where the dialog listing - should start. - - - counter - how many dialogs should be - listed (starting from the offset) - - - - MI FIFO Command Format: - - - ## list all ongoing dialogs - opensips-cli -x mi dlg_list - ## list the dialog by callid and From TAG - opensips-cli -x mi dlg_list callid=abcdrssfrs122444@192.168.1.1 from_tag=AAdfeEFF33 - ## list 10 dialogs, starting from the position 40 - ## (in the list of all ongoing dialogs) - opensips-cli -x mi dlg_list index=40 counter=10 - -
- -
- <function moreinfo="none">dlg_list_ctx</function> - - The same as the dlg_list but including in the - dialog description - the associated context from modules sitting on top of - the dialog module. - This function also prints the dialog's values. In case of - binary values, the non-printable chars are represented in hex - (e.g. \x00) - - - Name: dlg_list_ctx - - Parameters: see dlg_list - - - MI FIFO Command Format: - - - opensips-cli -x mi dlg_list_ctx - -
- -
- <function moreinfo="none">dlg_end_dlg</function> - - Terminates an ongoing dialog. - If dialog is established, BYEs are sent in both directions. - If dialog is in unconfirmed or early state, a CANCEL will be - sent to the callee side, that will trigger a 487 from the - callee, which, when relayed, will also end the dialog on - the caller's side. - - - Name: dlg_end_dlg - - Parameters are: - - - dialog_id - this is an identifier - of the dialog - it can be either (1) the unique ID - of the dialog (as provided by dlg_list), either (2) the - SIP Call-ID of the dialog. - - - extra_hdrs - (optional) string containg - the extra headers (full format) to be added to the BYE - requests. - - - - The "dialog_id" value can be get via the "dlg_list" MI command. - - - MI FIFO Command Format: - - - # terminate the dialog via the internal Dialog-ID - opensips-cli -x mi dlg_end_dlg 6ae.4b38d013 - # terminate the dialog via its SIP Call-ID - opensips-cli -x mi dlg_end_dlg Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY - -
- -
- <function moreinfo="none">profile_get_size</function> - - Returns the number of dialogs belonging to a profile. If the profile - supports values, the check can be reinforced to take into account a - specific value - how many dialogs were inserted into the profile with - a specific value. If not value is passed, only simply belonging of the - dialog to the profile is checked. Note that the profile does not - supports values, this will be silently discarded. - - - Name: profile_get_size - - Parameters: - - - profile - name of the profile to get the - value for. - - - value (optional)- string value to - toughen the check; - - - - MI FIFO Command Format: - - - opensips-cli -x mi profile_get_size inboundCalls - -
- -
- <function moreinfo="none">profile_list_dlgs</function> - - Lists all the dialogs belonging to a profile. If the profile - supports values, the check can be reinforced to take into account a - specific value - list only the dialogs that were inserted into the - profile with that specific value. If not value is passed, all dialogs - belonging to the profile will be listed. Note that the profile does - not supports values, this will be silently discarded. Also, when using - shared profiles using the CacheDB interface, this command will only - display the local dialogs. - - - Name: profile_list_dlgs - - Parameters: - - - profile - name of the profile to list the - dialog for. - - - value (optional)- string value to - toughen the check; - - - - MI FIFO Command Format: - - - opensips-cli -x mi profile_list_dlgs inboundCalls - -
- -
- <function moreinfo="none">profile_get_values</function> - - Lists all the values belonging to a profile along with their - count. If the profile does not support values a total count - will be returned. Note that this function does not work for shared - profiles over the CacheDB interface. - - - Name: profile_get_values - - Parameters: - - - profile - name of the profile to list the - dialog for. - - - - MI FIFO Command Format: - - - opensips-cli -x mi profile_get_values inboundCalls - -
-
- <function moreinfo="none">profile_end_dlgs</function> - - Terminate all ongoing dialogs from a specified profile, on a single dialog it - performs the same operations as the command - - - Name: profile_end_dlgs - - Parameters: - - - profile - name of the profile that will have its dialogs termianted - - - value - (optional) if the profile supports values terminate only the dialogs - with the specified value - - - - MI FIFO Command Format: - - - opensips-cli -x mi profile_end_dlgs inboundCalls - -
-
- <function moreinfo="none">dlg_db_sync</function> - - Will load all the information about the dialogs from the database - in the OpenSIPS internal memory. If a dialog is already found in memory - and has the same/an older state, it will be updated with the values from - DB. Otherwise, the newer in-memory version will not be changed. - - - Name: dlg_db_sync - - It takes no parameters - - MI FIFO Command Format: - - - opensips-cli -x mi dlg_db_sync - -
- -
- <function moreinfo="none">dlg_cluster_sync</function> - - This command will only take effect if dialog replication is enabled. - - - Fully synchronize the dialog information in memory from a suitable donor - node within the . Dialogs - that already exist in memory which are not reconfirmed through syncing will - be discarded. A sharing tag can be specified in order to sync only dialogs - marked with that sharing tag. - - - Name: dlg_cluster_sync - - Parameters: - - - sharing_tag - name of the sharing tag that - dialogs have to be marked with in order to be synced - - - - MI FIFO Command Format: - - - opensips-cli -x mi dlg_cluster_sync vip1 - -
- -
- <function moreinfo="none">dlg_restore_db</function> - - Restores the dialog table after a potential desynchronization event. - The table is truncated, then populated with CONFIRMED dialogs from memory. - - - Name: dlg_restore_db - - It takes no parameters - - MI FIFO Command Format: - - - opensips-cli -x mi dlg_restore_db - -
- -
- <function moreinfo="none">list_all_profiles</function> - - Lists all the dialog profiles, along with 1 or 0 if - the given profile has/does not have an associated value. - - - Name: list_all_profiles - - Parameters: It takes no parameters - - - MI FIFO Command Format: - - - opensips-cli -x mi list_all_profiles - -
- -
- <function moreinfo="none">dlg_push_var</function> - - Push or update a dialog value for the given list of dialog IDs / Call-IDs. - - - Name: dlg_push_var - - Parameters: It takes 3 or more parameters - - - - dlg_val_name - name of the dialog value that needs to be inserted/updated - - - dlg_val_value - value to be inserted/updated - - - DID - dialog identifier. Can be either the $DLG_did or the actual Call-ID. - - - - MI FIFO Command Format: - - - opensips-cli -x mi dlg_push_var var_name var_value DID1 [ DID2 DID3 ... DIDN ] - -
- -
- <function moreinfo="none">dlg_send_sequential</function> - - Sends a sequential request within an ongoing dialog. - - - Name: dlg_send_sequential - - Parameters: - - - callid - the callid of the dialog you need to trigger - the sequential message for. - - - method - (optional) the method used for the sequential - message. Default value is INVITE. - - - mode - (optional) can be used to tune the behavior of - the sequential message. Possible values for the mode are: - - - caller - (default) sends the sequential message - to the caller. This mode can be useful in high availability scenarios - when you want to update the upstream's routing set, specifically the contact. - - - callee - same as caller, but sends the sequential - message to the callee. - - - challenge - sends a sequential INVITE (or UPDATE) - to the caller to challenge it for its advertised SDP body. When the - body is received, it is forwarded to the callee. This mode is useful - when trying to change both endpoints (upstream and downstream) routing - set. It can also be useful when trying to trigger a re-negotiation for - SDP body. - - - challenge-caller - same as challenge - - - challenge-callee - same as - challenge-caller, only that it first challenges - the callee, instead of the caller. - - - - - body - (optional) can be used to specify a body for - the initial sequential message. Possible values for the body - parameter are: - - - none - (default) no body added to the sequential message. - - - inbound - advertises in the body of the sequential - message generated the last body received from its pair. For example, - if the mode=challenge-caller, the message will - contain the body sent to &osips; by the callee. This is useful when - you need to alter the body previously sent to the caller, because you - want to re-negotiate a different media proxy for the call. This can - be achieved by catching the generated request in - local_route, and re-engage the Media proxy. - - - outbound - advertises in the body of the sequential - message generated the last body sent to that UAC. For example, - if the mode=challenge-caller, the message will - contain the last body sent by &osips; to the caller. This is useful - in a high availability scenario when trying to re-negotiate the - contact of the server, but there is no need to alter the body sent - earlier. - - - custom:CONTENT_TYPE:BODY - this can be used to - specify a specific Content-Type ehader and body for the - sequential message generated. - - - - - headers - (optional) can be used to specify some headers for - the initial sequential message. - - - - This functions runs asynchronously and returns the status code and reason - of the last reply received for either the challenge or normal mode. - - - MI Command Format: - - - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 - - - - MI Command used to trigger media re-negotiation: - - - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 \ - mode=challenge \ - body=inbound - - - - MI Command used to UPDATE the callee's remote Contact after a server failover: - - - opensips-cli -x mi dlg_send_sequential \ - callid=5291231-testing@127.0.0.1 \ - mode=challenge-callee \ - body=outbound \ - method=UPDATE - - - - MI Command used to send REFER to the callee, and add Refer-To header: - - - opensips-cli -x mi dlg_send_sequential \ - callid=usR8FlGOSMfCTAIHebHCOQ.. \ - method=REFER \ - body=none \ - mode=callee \ - headers='Refer-To: sip:user@domain:50060' - - -
- -
- <function moreinfo="none">set_dlg_profile</function> - - Set the dialog identified by dialog ID / Call-ID into the given profile ( with optional value and clearing of the old profile values ) - - - Name: set_dlg_profile - - Parameters: It takes 2-4 parameters - - - - dlg_id - dialog ID or Call-ID for the respective dialog - - - profile - profile name to be set - - - value - optional, the profile value to be set - - - clear_values - optional, clear previous values in the profile before setting the new one - - - - MI FIFO Command Format: - - - opensips-cli -x mi set_dlg_profile DID my_profile my_value 1 - -
- -
- <function moreinfo="none">unset_dlg_profile</function> - - Unsets the dialog identified by dialog ID / Call-ID from the given profile ( with optional value and clearing of the old profile values ) - - - Name: set_dlg_profile - - Parameters: It takes 2-3 parameters - - - - dlg_id - dialog ID or Call-ID for the respective dialog - - - profile - profile name to be unset - - - value - optional, the profile value to be unset. for profiles with value, by omitting this parameter you can now clear all values of the given profile. - - - - MI FIFO Command Format: - - - opensips-cli -x mi unset_dlg_profile DID my_profile my_value - -
-
- -
- Exported Pseudo-Variables -
- <varname>$DLG_count</varname> - - Returns the number of current active dialogs (may be confirmed or - not). - -
- -
- <varname>$DLG_status</varname> - - Returns the status of the dialog corresponding to the processed - sequential request. This PV will be available only for sequential - requests, after doing loose_route(). - - - Value may be: - - - - NULL - Dialog not found. - - - 1 - Dialog unconfirmed (created - but no reply received at all) - - - 2 - Dialog in early state (created - provisional reply received, but no final reply received - yet) - - - 3 - Confirmed by a final reply but - no ACK received yet. - - - 4 - Confirmed by a final reply and - ACK received. - - - 5 - Dialog ended. - - -
- -
- <varname>$DLG_lifetime</varname> - - Returns the duration (in seconds) of the dialog corresponding to - the processed sequential request. The duration is calculated from - the dialog confirmation and the current moment. This PV will be - available only for sequential requests, after doing loose_route(). - - - NULL will be returned if there is no dialog for the request. - -
- -
- <varname>$DLG_flags</varname> - - Returns the dialog flags (as a list of flag names separted by space) - of the dialog corresponding to the processed sequential request. - This PV will be available only for sequential requests, - after doing loose_route(). - - - NULL will be returned if there is no dialog for the request. - -
- -
- <varname>$DLG_dir</varname> - - Returns the direction of the request in dialog (as "upstream" string - if the request is generated by callee or "downstream" string if the - request is generated by caller) - to be used for sequential request. - This PV will be available only for sequential requests (not for - replies), after doing loose_route(). - - - NULL will be returned if there is no dialog for the request. - -
- -
- <varname>$DLG_did</varname> - - Returns the id of the dialog corresponding to - the processed sequential request. The output format is a string - identical to the one returned by the dlg_list MI function. This PV will be - available only for sequential requests, after doing loose_route(). - - - NULL will be returned if there is no dialog for the request. - -
- -
- <varname>$DLG_end_reason</varname> - - Returns the reason for the dialog termination. It can be - one of the following : - - - - Upstream BYE - Callee has sent a BYE - - - - Downstream BYE - Caller has sent a BYE - - - - Lifetime Timeout - Dialog lifetime expired - - - - MI Termination - Dialog ended via the MI interface - - - - Ping Timeout - Dialog ended because no reply to option pings - - - - ReINVITE Ping Timeout - Dialog ended because no reply to reinvite pings - - - - RTPProxy Timeout - Media timeout signaled by RTPProxy - - - - SIP Race Condition - SIP Race Condition occurred - - - - - - NULL will be returned if there is no dialog for the request, - or if the dialog is not ended in the current context. - -
- -
- <varname>$DLG_timeout</varname> - - Used to set the dialog lifetime (in seconds). When read, the variable - returns the number of seconds until the dialog expires and is destroyed. - Note that reading the variable is only possible after the dialog is created - (for initial requests) or after doing loose_route() (for sequential requests). - Important notice: using this variable with a REALTIME db_mode is very inefficient, - because every time the dialog value is changed, a database update is done. - - - NULL will be returned if there is no dialog for the request, otherwise the - number of seconds until the dialog expiration. - -
- -
- <varname>$DLG_del_delay</varname> - - Used to set the dialog deletion delay (in seconds) for the - current dialog (in a per-call manner). When read, the variable - returns the number of seconds that were set for the call or - the default value ( see the - delete_delay - ) - module param) for the delete delaying. - - - The variable must be used when the context of a dialog is - available in script. - -
- - -
- <varname>$DLG_json</varname> - - The variable is read-only and exposes a JSON variable containing all the information that the dlg_list MI function contains - - - NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned. - -
- -
- <varname>$DLG_ctx_json</varname> - - The variable is read-only and exposes a JSON variable containing all the information that the dlg_list_ctx MI function contains ( on top of $DLG_json, this will expose the full list of dialog vars and profile links for the current dialog ) - - - NULL will be returned if there is no dialog for the request, otherwise the JSON will be returned. - -
- -
- <varname>$dlg_val(name)</varname> - - This is a read/write variable that allows access to the dialog - attribute named name. It can hold a string or - integer value. - - - Be sure and use this variable only when having a dialog context - (like after create_dialog() or match_dialog() or equivalent). - - - The variable accepts dynamic names, meaning the name may contain - other variables. - - - NULL will be returned if there is no dialog for the request. - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_DLG_STATE_CHANGED</function> - - - This event is raised when the dialog state is changed. - - Parameters: - - - id - the hex representation of the dialog id. - - - db_id - the integer representation of the dialog id, - as it is stored in the database dlg_id field. - - - callid - the callid. - - - from_tag - the From tag. - - - to_tag - the To tag. - - - old_state - the old state of the dialog. - - - new_state - the new state of the dialog. - - -
-
- - -
- diff --git a/modules/dialog/doc/dialog_devel.xml b/modules/dialog/doc/dialog_devel.xml deleted file mode 100644 index 1106795d400..00000000000 --- a/modules/dialog/doc/dialog_devel.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - - &develguide; -
- Available Functions - -
- - <function moreinfo="none">register_dlgcb (dialog, type, cb, param, free_param_cb)</function> - - - Register a new callback to the dialog. - - Meaning of the parameters is as follows: - - - struct dlg_cell* dlg - dialog to - register callback to. If maybe NULL only for DLG_CREATED callback - type, which is not a per dialog type. - - - - int type - types of callbacks; more - types may be register for the same callback function; only - DLG_CREATED must be register alone. Possible types: - - - DLGCB_LOADED - called when a dialog - is loaded from the database, or received by a node using the - cluster replication. - - - - DLGCB_SAVED - - - - DLG_CREATED - called when a new - dialog is created - it's a global type (not associated to - any dialog) - - - - DLG_FAILED - called when the dialog - was negatively replied (non-2xx) - it's a per dialog type. - - - - DLG_CONFIRMED - called when the - dialog is confirmed (2xx replied) - it's a per dialog type. - - - - DLG_REQ_WITHIN - called when the - dialog matches a sequential request - it's a per dialog type. - - - - DLG_TERMINATED - called when the - dialog is terminated via BYE, or by the mi dlg_end_dlg command - - it's a per dialog type. - - - - DLG_EXPIRED - called when the - dialog expires without receiving a BYE - it's a per dialog - type. Note that when using replication sharing tags, this - callback is only executed by the node that has the Active tag. - - - - DLGCB_EARLY - called when the - dialog is created in an early state (18x replied) - it's - a per dialog type. - - - - DLGCB_RESPONSE_FWDED - called when - the dialog matches a reply to the initial INVITE request - it's - a per dialog type. - - - - DLGCB_RESPONSE_WITHIN - called when - the dialog matches a reply to a subsequent in dialog request - - it's a per dialog type. - - - - DLGCB_MI_CONTEXT - called when the - mi dlg_list_ctx command is invoked - it's a per dialog type. - - - - DLGCB_DESTROY - - - - - - - dialog_cb cb - callback function to be - called. Prototype is: void (dialog_cb) - (struct dlg_cell* dlg, int type, struct dlg_cb_params * params); - - - - - void *param - parameter to be passed to - the callback function. - - - - param_free callback_param_free - - callback function to be called to free the param. - Prototype is: void (param_free_cb) (void *param); - - - - -
- -
- -
- diff --git a/modules/dialog/doc/dialog_faq.xml b/modules/dialog/doc/dialog_faq.xml deleted file mode 100644 index 92b709861f1..00000000000 --- a/modules/dialog/doc/dialog_faq.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - &faqguide; - - - - What happened with topology_hiding() - function? - - - - The respective functionality was moved into the topology_hiding module. - Function prototype has remained the same. - - - - - - What happened with use_tight_match - parameter? - - - - The parameter was removed with version 1.3 as the option of tight - matching became mandatory and not configurable. Now, the tight - matching is done all the time (when using DID matching). - - - - - - What happened with bye_on_timeout_flag - parameter? - - - - The parameter was removed in a dialog module parameter restructuring. - To keep the bye on timeout behavior, you need to provide a "B" - string parameter to the create_dialog() function. - - - - - - What happened with dlg_flag - parameter? - - - - The parameter is considered obsolete. The only way to - create a dialog is to call the create_dialog() function - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/dialplan/Makefile b/modules/dialplan/Makefile index a7c6a0a91a6..a937d32859e 100644 --- a/modules/dialplan/Makefile +++ b/modules/dialplan/Makefile @@ -8,12 +8,16 @@ NAME=dialplan.so # the autodetection # CROSS_COMPILE=true +PCRE_LIB ?= pcre2-8 +PCRE_VERSION ?= $(word 1,$(subst -, , $(PCRE_LIB))) +PCRE_CONFIG ?= $(PCRE_VERSION)-config + ifeq ($(CROSS_COMPILE),) PCRE_BUILDER := $(shell \ - if which pcre-config >/dev/null 2>/dev/null; then \ - echo 'pcre-config'; \ - elif pkg-config --exists libcre; then \ - echo 'pkg-config libpcre'; \ + if which $(PCRE_CONFIG) >/dev/null 2>/dev/null; then \ + echo '$(PCRE_CONFIG)'; \ + elif pkg-config --exists lib$(PCRE_LIB); then \ + echo 'pkg-config lib$(PCRE_LIB)'; \ fi) endif @@ -21,10 +25,12 @@ ifeq ($(PCRE_BUILDER),) DEFS += -I$(SYSBASE)/include \ -I$(LOCALBASE)/include LIBS += -L$(SYSBASE)/lib \ - -L$(LOCALBASE)/lib -lpcre + -L$(LOCALBASE)/lib -l$(PCRE_LIB) else DEFS += $(shell $(PCRE_BUILDER) --cflags) - LIBS += $(shell $(PCRE_BUILDER) --libs) + LIBS += $(shell $(PCRE_BUILDER) --libs 2>/dev/null) \ + $(shell $(PCRE_BUILDER) --libs$(word 2,$(subst -, ,$(PCRE_LIB))) 2>/dev/null) endif +DEFS += -D$(shell echo $(PCRE_VERSION) | tr 'a-z' 'A-Z')_LIB include ../../Makefile.modules diff --git a/modules/dialplan/README b/modules/dialplan/README deleted file mode 100644 index fe720ede921..00000000000 --- a/modules/dialplan/README +++ /dev/null @@ -1,684 +0,0 @@ -dialplan Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Usage cases - 1.4. Database structure and usage - - 1.4.1. What to place in table - - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. External Libraries or Applications - - 1.6. Exported Parameters - - 1.6.1. partition (string) - 1.6.2. db_url (string) - 1.6.3. table_name (string) - 1.6.4. dpid_col (string) - 1.6.5. pr_col (string) - 1.6.6. match_op_col (string) - 1.6.7. match_exp_col (string) - 1.6.8. match_flags_col (string) - 1.6.9. subst_exp_col (string) - 1.6.10. repl_exp_col (string) - 1.6.11. timerec_col (integer) - 1.6.12. disabled_col (integer) - 1.6.13. attrs_col (string) - - 1.7. Exported Functions - - 1.7.1. dp_translate(id, input, [out_var], - [attrs_var], [partition]) - - 1.8. Exported MI Functions - - 1.8.1. dp_reload - 1.8.2. dp_translate - 1.8.3. dp_show_partiton - - 1.9. Exported Status/Report Identifiers - - 1.9.1. [partition_name] - - 1.10. Installation - - 2. Developer's Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Defining the 'pstn' partition - 1.2. Define the 'pstn' partition and make it the 'default' - partition, so we avoid loading the 'dialplan' table - - 1.3. Set db_url parameter - 1.4. Set table_name parameter - 1.5. Set dpid_col parameter - 1.6. Set pr_col parameter - 1.7. Set match_op_col parameter - 1.8. Set match_exp_col parameter - 1.9. Set match_flags_col parameter - 1.10. Set subs_exp_col parameter - 1.11. Set repl_exp_col parameter - 1.12. Set timerec_col parameter - 1.13. Set disabled_col parameter - 1.14. Set attrs_col parameter - 1.15. dp_translate usage - 1.16. dp_translate usage - 1.17. dp_translate usage - 1.18. dp_translate usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements generic string translations based on - matching and replacement rules. It can be used to manipulate - R-URI or a PV and to translated to a new format/value. - -1.2. How it works - - At startup, the module will load all transformation rules from - one or more dialplan-compatible tables. The data of each table - will be stored in a partition (data source), which is defined - by the "db_url" and "table_name" properties. Every table row - will be stored in memory as a translation rule. Each rule will - describe how the matching should be made, how the input value - should be modified and which attributes should be set for the - matching transformation. - - A dialplan rule can be of two types: - * "String matching" rule - performs a string equality test - against the input string. The case of the characters can be - ignored by enabling bit 1 of the rule's "match_flags" - bitmask column (i.e. set the column value to 1 or 0, for - insensitive or sensitive) - * "Regex matching" rule - uses Perl Compatible Regular - Expressions, and will attempt to match the rule's - expression against an input string. The regex maching can - be done in a caseless manner by enabling bit 1 of the - rule's "match_flags" bitmask column (i.e. set the column - value to 1 or 0, for insensitive or sensitive) - - The module provides the dp_translate() script function, which - expects an input string value that will be matched, at worst, - against all rules of a partition. - - Internally, the module groups a partition's rules into two - sets, "string" and "regex". The matching logic will attempt to - find the first match within each of these two sets of rules. - Each set will be iterated in ascending order of priority. If an - input string happens to match a rule in each of the two sets, - the rule with the smallest priority will be chosen. - Furthermore, should these two matching rules also have equal - priorities, the one with the smallest "id" field (the unique - key) will be chosen. - - Once a single rule is decided upon, the defined transformation - (if any) is applied and the result is returned as output value. - Also, if any string attribute is associated to the rule, this - will be returned to the script along with the output value. - -1.3. Usage cases - - The module can be used to implement dialplans - to do auto - completion of the dialed numbers (e.g. national to - international), to convert generic numbers to specific numbers - (e.g. for emergency numbers). - - Also the module can be used for detecting ranges or sets of - numbers mapped on a service/case - the "attributes" string - column can be used here to store extra information about the - service/case. - - Non-SIP string translation can also be implemented - like - converting country names from all possible formats to a - canonical format: (UK, England, United Kingdom) -> GB. - - Any other string-based translation or detection for whatever - other purposes. - -1.4. Database structure and usage - - Depending what kind of operation (translation, matching, etc) - you want to do with the module, you need to populate the - appropriate DB records. - - The definition of the tables used by the dialplan module can be - found at - https://opensips.org/docs/db/db-schema-devel.html#AEN1501 - -1.4.1. What to place in table - -1.4.1.1. String translation (regexp detection, subst translation) - - Recognize a number block in all forms (international, national) - and convert it to a canonical format (E.164) - * match_op = 1 (regexp) - * match_exp = "^(0040|\+40|0|40)21[0-9]+" ; regular - expression that will be used to match with this rule (if - the rule should be applied for the input string) - * match_flags = 0 (0 - case sensitive, 1 - case insensitive - matching) - * subst_exp = "^(0040|\+40|0|40)(.+)" ; regular expression - used to do the transformation (first part of the subst - operation) - * repl_exp = "40\2" ; second part of the subst (output) - - linked to the subst_exp field; when both defined, they work - as a subst() - -1.4.1.2. String translation (regexp detection, replacement) - - Recognize the name of a country (multiple languages) and - convert it to a single, fixed value - * match_op = 1 (regexp) - * match_exp = "^((Germany)|(Germania)|(Deutschland)|(DE))" ; - regular expression that will be used to match with this - rule (if the rule should be applied for the input string) - * match_flags = 0 (0 - case sensitive, 1 - case insensitive - matching) - * subst_exp = NULL ; when translation is actually a - replacement, this field must be NULL. - * repl_exp = "DE" ; static string to replace the input - - whenever this rule will match, it will return this string - as output. - -1.4.1.3. Number detection (regexp detection, no replacement) - - Recognize a block of numbers as belong to a single service and - signalize this via an attribute. - * match_op = 1 (regexp) - * match_exp = "^021456[0-9]{5}" ; regular expression that - will be used to match with this rule (if the rule should be - applied for the input string) - * match_flags = 0 (0 - case sensitive, 1 - case insensitive - matching) - * subst_exp = NULL ; no translation - * repl_exp = NULL ; no translation - * attrs = "serviceX" ; whatever string you will get into - OpenSIPS script and it will provide you more information - (totally custom) - -1.4.1.4. String conversion (equal detection, replacement) - - Recognize a fixed string/number and replace it with something - fixed. - * match_op = 0 (equal) - * match_exp = "SIP server" ; string to be matched - * match_flags = 0 (0 - case sensitive, 1 - case insensitive - matching) - * subst_exp = NULL ; no subst translation - * repl_exp = "OpenSIPS" ; output string - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None - -1.5.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libpcre-dev - the development libraries of PCRE. - -1.6. Exported Parameters - -1.6.1. partition (string) - - Specify a new dialplan partition (data source). This parameter - may be set multiple times. Each partition may have a specific - "db_url" and "table_name". If not specified, these values will - be inherited from db_url, db_default_url or table_name, - respectively. The name of the default partition is 'default'. - - Note: OpenSIPS will validate each partition, so make sure to - add any required entries in the "version" table of each - database defined through the 'db_url' property. - - Example 1.1. Defining the 'pstn' partition -... -modparam("dialplan", "partition", " - pstn: - table_name = dialplan; - db_url = mysql://opensips:opensipsrw@127.0.0.1/opensips" -) -... - - Example 1.2. Define the 'pstn' partition and make it the - 'default' partition, so we avoid loading the 'dialplan' table -... -db_default_url = "mysql://opensips:opensipsrw@localhost/opensips" - -loadmodule "dialplan.so" -modparam("dialplan", "partition", " - pstn: - table_name = dialplan_pstn") -modparam("dialplan", "partition", "default: pstn") -... - -1.6.2. db_url (string) - - The default DB connection of the module, overriding the global - 'db_default_url' setting. Once specified, partitions which are - missing the 'db_url' property will inherit their URL from this - value. - - Default value is NULL (not set). - - Example 1.3. Set db_url parameter -... -modparam("dialplan", "db_url", "mysql://user:passwd@localhost/db") -... - -1.6.3. table_name (string) - - The default name of the table from which to load translation - rules. Partitions which are missing the 'table_name' property - will inherit their table name from this value. - - Default value is “dialplan”. - - Example 1.4. Set table_name parameter -... -modparam("dialplan", "table_name", "my_table") -... - -1.6.4. dpid_col (string) - - The column name to store the dialplan ID group. - - Default value is “dpid”. - - Example 1.5. Set dpid_col parameter -... -modparam("dialplan", "dpid_col", "column_name") -... - -1.6.5. pr_col (string) - - The column name to store the priority of the corresponding rule - from the table row. Smaller priority values have higher - precedence. - - Default value is “pr”. - - Example 1.6. Set pr_col parameter -... -modparam("dialplan", "pr_col", "column_name") -... - -1.6.6. match_op_col (string) - - The column name to store the type of matching of the rule. - - Default value is “match_op”. - - Example 1.7. Set match_op_col parameter -... -modparam("dialplan", "match_op_col", "column_name") -... - -1.6.7. match_exp_col (string) - - The column name to store the rule match expression. - - Default value is “match_exp”. - - Example 1.8. Set match_exp_col parameter -... -modparam("dialplan", "match_exp_col", "column_name") -... - -1.6.8. match_flags_col (string) - - The column name to store various matching flags. Currently 0 - - case sensitive matching, 1 - case insensitive matching. - - Default value is “match_flags”. - - Example 1.9. Set match_flags_col parameter -... -modparam("dialplan", "match_flags_col", "column_name") -... - -1.6.9. subst_exp_col (string) - - The column name to store the rule's substitution expression. - - Default value is “subst_exp”. - - Example 1.10. Set subs_exp_col parameter -... -modparam("dialplan", "subst_exp_col", "column_name") -... - -1.6.10. repl_exp_col (string) - - The column name to store the rule's replacement expression. - - Default value is “repl_exp”. - - Example 1.11. Set repl_exp_col parameter -... -modparam("dialplan", "repl_exp_col", "column_name") -... - -1.6.11. timerec_col (integer) - - The column name that indicates an additional time recurrence - check within the rule (column values are RFC 2445-compatible - strings). The value format is identical to the input of the - check_time_rec() function of the cfgutils module, including the - optional use of logical operators linking multiple such strings - into a larger expression. - - Default value is “timerec”. - - Example 1.12. Set timerec_col parameter -... -modparam("dialplan", "timerec_col", "month_match") -... - -1.6.12. disabled_col (integer) - - The column name that indicates if the dialplan rule is - disabled. - - Default value is “disabled”. - - Example 1.13. Set disabled_col parameter -... -modparam("dialplan", "disabled_col", "disabled_column") -... - -1.6.13. attrs_col (string) - - The column name to store rule-specific attributes. - - Default value is “attrs”. - - Example 1.14. Set attrs_col parameter -... -modparam("dialplan", "attrs_col", "column_name") -... - -1.7. Exported Functions - -1.7.1. dp_translate(id, input, [out_var], [attrs_var], [partition]) - - Will try to translate the src string into dest string according - to the translation rules with dialplan ID equal to id. - - Meaning of the parameters is as follows: - * id (int) - the dialplan id to be used for matching rules - * input (string) - input string to be used for rule matching - and for computing the output string. - * out_var (var, optional) - variable to be populated/written - with the output string (if provided by the translation - rule), on a successful translation. - * attrs_var (var, optional) - variable to be - populated/written with the "attributes" field of the - translation rule, on a successful translation. If the field - is NULL or empty-string, the variable will be set to - empty-string. - * partition (string, optional) - the name of the partition - (set of data) to be used for locating the DP ID. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE and - EVENT_ROUTE. - - Example 1.15. dp_translate usage -... -dp_translate(240, $ru, $var(out)); -xlog("translated into '$var(out)' \n"); -... - - Example 1.16. dp_translate usage -... -$avp(src) = $ruri.user; -dp_translate($var(x), $avp(src), $var(y), $var(attrs)); -xlog("translated to var $var(y) with attributes: '$var(attrs)'\n"); -... - - Example 1.17. dp_translate usage -... -$var(id) = 10; -dp_translate($var(id), $avp(in), , $avp(attrs), "example_partition"); -xlog("matched with attributes '$avp(attrs) against example_partition'\n" -); -... - - Example 1.18. dp_translate usage -... -dp_translate(10, $var(in), , , $var(part)); -xlog("'$var(in)' matched against partition '$var(part)'\n") -... - -1.8. Exported MI Functions - -1.8.1. dp_reload - - It will update the translation rules, loading the database - info. - - Name: dp_reload - - Parameters: 1 - * partition (optional) - Partition to be reloaded. If not - specified, all partitions will be reloaded. - - MI DATAGRAM Command Format: - opensips-cli -x mi dp_reload - -1.8.2. dp_translate - - It will apply a translation rule identified by a dialplan id on - an input string. - - Name: dp_translate - - Parameters: 3 - * dpid - the dpid of the rule set used for match the input - string - * input - the input string - * partition - (optional) the name of the partition when the - dpid is located - - MI DATAGRAM Command Format: - opensips-cli -x mi dp_translate 10 +40123456789 - -1.8.3. dp_show_partiton - - Display partition(s) details. - - Name: dp_show_partiton - - Parameters: 2 - * partition (optional) - The partition name. If no partition - is specified, all known partitions will be listed. - - MI DATAGRAM Command Format: - opensips-cli -x mi dp_translate default - -1.9. Exported Status/Report Identifiers - - The module provides the "dialplan" Status/Report group, where - each dialplan partition is defined as a separate SR identifier. - -1.9.1. [partition_name] - - The status of these identifiers reflects the readiness/status - of the cached data (if available or not when being loaded from - DB): - * -2 - no data at all (initial status) - * -1 - no data, initial loading in progress - * 1 - data loaded, partition ready - * 2 - data available, a reload in progress - - In terms of reports/logs, the following events will be - reported: - * starting DB data loading - * DB data loading failed, discarding - * DB data loading successfully completed - * N rules loaded (N discarded) - - { - "Name": "default", - "Reports": [ - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "5 rules loaded (0 discarded)" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "5 rules loaded (0 discarded)" - } - ] - } - - For how to access and use the Status/Report information, please - see - https://www.opensips.org/Documentation/Interface-StatusReport-3 - -3. - -1.10. Installation - - The modules requires one table in OpenSIPS database: - dialplan.The SQL syntax to create them can be found in - dialplan-create.sql script in the database directories in the - opensips/scripts folder. You can also find the complete - database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer's Guide - - Revision History - Revision $Revision: 5895 $ $Date$ - - The module does not provide any API to use in other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 73 48 986 949 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 71 46 910 983 - 3. Ionut Ionita (@ionutrazvanionita) 40 20 1149 579 - 4. Anca Vamanu 34 5 3263 19 - 5. Andrei Dragus 24 3 382 1029 - 6. Razvan Crainea (@razvancrainea) 23 19 98 162 - 7. Ovidiu Sas (@ovidiusas) 16 13 144 37 - 8. Vlad Patrascu (@rvlad-patrascu) 10 6 157 115 - 9. Maksym Sobolyev (@sobomax) 6 4 10 10 - 10. Eseanu Marius Cristian (@eseanucristian) 5 3 114 47 - - All remaining contributors: Henning Westerholt (@henningw), - Zero King (@l2dy), Parantido Julius De Rica (@Parantido), Paul - Wise, Sergio Gutierrez, Vlad Paiu (@vladpaiu), Rudy Pedraza, - Juha Heinanen (@juha-h), Ken Rice, Peter Lemenkov (@lemenkov), - UnixDev, David Sanders. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Jul 2012 - Feb 2025 - 3. Razvan Crainea (@razvancrainea) Dec 2010 - Sep 2024 - 4. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2008 - Sep 2022 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2022 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ovidiu Sas (@ovidiusas) Sep 2008 - Nov 2015 - 10. Ionut Ionita (@ionutrazvanionita) Jul 2014 - Nov 2015 - - All remaining contributors: David Sanders, Eseanu Marius - Cristian (@eseanucristian), Parantido Julius De Rica - (@Parantido), Vlad Paiu (@vladpaiu), Rudy Pedraza, Sergio - Gutierrez, Paul Wise, Anca Vamanu, Andrei Dragus, UnixDev, Juha - Heinanen (@juha-h), Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Zero King - (@l2dy), Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Ovidiu Sas (@ovidiusas), Ionut Ionita - (@ionutrazvanionita), Andrei Dragus, Anca Vamanu. - - Documentation Copyrights: - - Copyright © 2007-2008 Voice Sistem SRL diff --git a/modules/dialplan/README.md b/modules/dialplan/README.md new file mode 100644 index 00000000000..e417e23f8d1 --- /dev/null +++ b/modules/dialplan/README.md @@ -0,0 +1,704 @@ +--- +title: "dialplan Module" +description: "This module implements generic string translations based on matching and replacement rules." +--- + +## Admin Guide + + +### Overview + + +This module implements generic string translations based on matching and +replacement rules. It can be used to manipulate R-URI or a PV and to +translated to a new format/value. + + +### How it works + + +At startup, the module will load all transformation rules from one or more +dialplan-compatible tables. The data of each table will be stored in a +*partition* (data source), which is defined by the +"db_url" and "table_name" properties. Every table row will be stored in +memory as a translation rule. Each rule will describe how the matching +should be made, how the input value should be modified and which attributes +should be set for the matching transformation. + + +A dialplan rule can be of two types: + + +- *"String matching" rule* - performs a +string equality test against the input string. The case of the +characters can be ignored by enabling bit 1 of the rule's "match_flags" +bitmask column +(i.e. set the column value to 1 or 0, for insensitive or sensitive) +- *"Regex matching" rule* - uses Perl +Compatible Regular Expressions, and will attempt to match the rule's +expression against an input string. The regex +maching can be done in a caseless manner by enabling bit 1 of the +rule's "match_flags" bitmask column +(i.e. set the column value to 1 or 0, for insensitive or sensitive) + + +The module provides the *dp_translate()* script function, +which expects an input **string** value that +will be matched, at worst, against all rules of a partition. + + +Internally, the module groups a partition's rules into two sets, "string" and "regex". +The matching logic will attempt to find the first match within each of +these two sets of rules. Each set will be iterated in +**ascending** order of priority. If an input +string happens to match a rule in each of the two sets, the rule with the +smallest priority will be chosen. Furthermore, should these two matching +rules also have equal priorities, the one with the smallest "id" field +(the unique key) will be chosen. + + +Once a single rule is decided upon, the defined transformation (if any) is +applied and the result is returned as output value. Also, if any string +attribute is associated to the rule, this will be returned to the script +along with the output value. + + +### Usage cases + + +The module can be used to implement dialplans - to do auto completion of +the dialed numbers (e.g. national to international), to convert generic +numbers to specific numbers (e.g. for emergency numbers). + + +Also the module can be used for detecting ranges or sets of numbers mapped +on a service/case - the "attributes" string column can be used here to +store extra information about the service/case. + + +Non-SIP string translation can also be implemented - like converting country +names from all possible formats to a canonical format: +(UK, England, United Kingdom) -> GB. + + +Any other string-based translation or detection for whatever other purposes. + + +### Database structure and usage + + +Depending what kind of operation (translation, matching, etc) you want +to do with the module, you need to populate the appropriate DB records. + + +The definition of the tables used by the dialplan module can be found +at [dialplan table documentation](https://docs.opensips.org/manual/3-6/install-dbschema/#table-dialplan) + + +#### What to place in table + + +##### String translation (regexp detection, subst translation) + + +Recognize a number block in all forms (international, national) +and convert it to a canonical format (E.164) + + +- *match_op* = 1 (regexp) +- *match_exp* = "^(0040|\+40|0|40)21[0-9]+" ; +regular expression that will be used to match with this rule (if +the rule should be applied for the input string) +- *match_flags* = 0 (0 - case sensitive, +1 - case insensitive matching) +- *subst_exp* = "^(0040|\+40|0|40)(.+)" ; +regular expression used to do the transformation (first part +of the subst operation) +- *repl_exp* = "40\2" ; second part of the +subst (output) - linked to the subst_exp field; when both +defined, they work as a subst() + + +##### String translation (regexp detection, replacement) + + +Recognize the name of a country (multiple languages) and convert +it to a single, fixed value + + +- *match_op* = 1 (regexp) +- *match_exp* = "^((Germany)|(Germania)|(Deutschland)|(DE))" ; +regular expression that will be used to match with this rule (if +the rule should be applied for the input string) +- *match_flags* = 0 (0 - case sensitive, +1 - case insensitive matching) +- *subst_exp* = NULL ; +when translation is actually a replacement, this field must +be NULL. +- *repl_exp* = "DE" ; static string to +replace the input - whenever this rule will match, it will +return this string as output. + + +##### Number detection (regexp detection, no replacement) + + +Recognize a block of numbers as belong to a single service and +signalize this via an attribute. + + +- *match_op* = 1 (regexp) +- *match_exp* = "^021456[0-9]{5}" ; +regular expression that will be used to match with this rule (if +the rule should be applied for the input string) +- *match_flags* = 0 (0 - case sensitive, +1 - case insensitive matching) +- *subst_exp* = NULL ; +no translation +- *repl_exp* = NULL ; +no translation +- *attrs* = "serviceX" ; +whatever string you will get into OpenSIPS script and it will +provide you more information (totally custom) + + +##### String conversion (equal detection, replacement) + + +Recognize a fixed string/number and replace it with something fixed. + + +- *match_op* = 0 (equal) +- *match_exp* = "SIP server" ; +string to be matched +- *match_flags* = 0 (0 - case sensitive, +1 - case insensitive matching) +- *subst_exp* = NULL ; +no subst translation +- *repl_exp* = "OpenSIPS" ; +output string + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libpcre-dev - the development libraries of [PCRE](http://www.pcre.org/)*. + + +### Exported Parameters + + +#### partition (string) + + +Specify a new dialplan partition (data source). This parameter may +be set multiple times. Each partition may have a specific "db_url" and +"table_name". If not specified, these values will be inherited from +[db url](#param_db_url), db_default_url or +[table name](#param_table_name), respectively. The name of +the default partition is 'default'. + + +> [!NOTE] +> OpenSIPS will validate each partition, so make sure to add any +> required entries in the "version" table of each database defined +> through the 'db_url' property. + + +```opensips title="Defining the 'pstn' partition" +... +modparam("dialplan", "partition", " + pstn: + table_name = dialplan; + db_url = mysql://opensips:opensipsrw@127.0.0.1/opensips") +... + +``` + + +```opensips title="Define the 'pstn' partition and make it the 'default' partition, so we avoid loading the 'dialplan' table" +... +db_default_url = "mysql://opensips:opensipsrw@localhost/opensips" + +loadmodule "dialplan.so" +modparam("dialplan", "partition", " + pstn: + table_name = dialplan_pstn") +modparam("dialplan", "partition", "default: pstn") +... + +``` + + +#### db_url (string) + + +The default DB connection of the module, overriding the global +'db_default_url' setting. Once specified, partitions which are missing +the 'db_url' property will inherit their URL from this value. + + +*Default value is NULL (not set).* + + +```opensips title="Set db_url parameter" +... +modparam("dialplan", "db_url", "mysql://user:passwd@localhost/db") +... + +``` + + +#### table_name (string) + + +The default name of the table from which to load translation rules. +Partitions which are missing the 'table_name' property will inherit +their table name from this value. + + +*Default value is "dialplan".* + + +```opensips title="Set table_name parameter" +... +modparam("dialplan", "table_name", "my_table") +... + +``` + + +#### dpid_col (string) + + +The column name to store the dialplan ID group. + + +*Default value is "dpid".* + + +```opensips title="Set dpid_col parameter" +... +modparam("dialplan", "dpid_col", "column_name") +... + +``` + + +#### pr_col (string) + + +The column name to store the priority of the corresponding rule from +the table row. Smaller priority values have higher precedence. + + +*Default value is "pr".* + + +```opensips title="Set pr_col parameter" +... +modparam("dialplan", "pr_col", "column_name") +... + +``` + + +#### match_op_col (string) + + +The column name to store the type of matching of the rule. + + +*Default value is "match_op".* + + +```opensips title="Set match_op_col parameter" +... +modparam("dialplan", "match_op_col", "column_name") +... + +``` + + +#### match_exp_col (string) + + +The column name to store the rule match expression. + + +*Default value is "match_exp".* + + +```opensips title="Set match_exp_col parameter" +... +modparam("dialplan", "match_exp_col", "column_name") +... + +``` + + +#### match_flags_col (string) + + +The column name to store various matching flags. Currently +0 - case sensitive matching, 1 - case insensitive matching. + + +*Default value is "match_flags".* + + +```opensips title="Set match_flags_col parameter" +... +modparam("dialplan", "match_flags_col", "column_name") +... + +``` + + +#### subst_exp_col (string) + + +The column name to store the rule's substitution expression. + + +*Default value is "subst_exp".* + + +```opensips title="Set subs_exp_col parameter" +... +modparam("dialplan", "subst_exp_col", "column_name") +... + +``` + + +#### repl_exp_col (string) + + +The column name to store the rule's replacement expression. + + +*Default value is "repl_exp".* + + +```opensips title="Set repl_exp_col parameter" +... +modparam("dialplan", "repl_exp_col", "column_name") +... + +``` + + +#### timerec_col (integer) + + +The column name that indicates an additional time recurrence check +within the rule (column values are RFC 2445-compatible strings). The +value format is identical to the input of the +[check_time_rec()](../cfgutils#func_check_time_rec) +function of the *cfgutils* module, including the +optional use of logical operators linking multiple such strings into a +larger expression. + + +*Default value is "timerec".* + + +```opensips title="Set timerec_col parameter" +... +modparam("dialplan", "timerec_col", "month_match") +... + +``` + + +#### disabled_col (integer) + + +The column name that indicates if the dialplan rule is disabled. + + +*Default value is "disabled".* + + +```opensips title="Set disabled_col parameter" +... +modparam("dialplan", "disabled_col", "disabled_column") +... + +``` + + +#### attrs_col (string) + + +The column name to store rule-specific attributes. + + +*Default value is "attrs".* + + +```opensips title="Set attrs_col parameter" +... +modparam("dialplan", "attrs_col", "column_name") +... + +``` + + +### Exported Functions + + +#### dp_translate(id, input, [out_var], [attrs_var], [partition]) + + +Will try to translate the src string into dest string according to +the translation rules with dialplan ID equal to id. + + +Meaning of the parameters is as follows: + + +- *id* (int) - the dialplan id to be used for matching rules +- *input* (string) - input string to be used for rule matching +and for computing the output string. +- *out_var* (var, optional) - variable to be populated/written with +the output string (if provided by the translation rule), on a successful translation. +- *attrs_var* (var, optional) - variable to be populated/written +with the "attributes" field of the translation rule, on a successful translation. +If the field is NULL or empty-string, the variable will be set to empty-string. +- *partition* (string, optional) - the name of the partition +(set of data) to be used for locating the DP ID. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, LOCAL_ROUTE, +BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE and EVENT_ROUTE. + + +```opensips title="dp_translate usage" +... +dp_translate(240, $ru, $var(out)); +xlog("translated into '$var(out)' \n"); +... + +``` + + +```opensips title="dp_translate usage" +... +$avp(src) = $ruri.user; +dp_translate($var(x), $avp(src), $var(y), $var(attrs)); +xlog("translated to var $var(y) with attributes: '$var(attrs)'\n"); +... + +``` + + +```opensips title="dp_translate usage" +... +$var(id) = 10; +dp_translate($var(id), $avp(in), , $avp(attrs), "example_partition"); +xlog("matched with attributes '$avp(attrs) against example_partition'\n"); +... + +``` + + +```opensips title="dp_translate usage" +... +dp_translate(10, $var(in), , , $var(part)); +xlog("'$var(in)' matched against partition '$var(part)'\n") +... + +``` + + +### Exported MI Functions + + +#### dp_reload + + +It will update the translation rules, loading the database info. + + +Name: *dp_reload* + + +Parameters: *1* + + +- *partition* (optional) - Partition +to be reloaded. If not specified, all partitions will be +reloaded. + + +MI DATAGRAM Command Format: + + +```bash +opensips-cli -x mi dp_reload +``` + + +#### dp_translate + + +It will apply a translation rule identified by a dialplan +id on an input string. + + +Name: *dp_translate* + + +Parameters: *3* + + +- *dpid* - the dpid of the rule set used for +match the input string +- *input* - the input string +- *partition* - (optional) the name of the +partition when the dpid is located + + +MI DATAGRAM Command Format: + + +```bash +opensips-cli -x mi dp_translate 10 +40123456789 +``` + + +#### dp_show_partiton + + +Display partition(s) details. + + +Name: *dp_show_partiton* + + +Parameters: *2* + + +- *partition* (optional) - The +partition name. If no partition is specified, all known +partitions will be listed. + + +MI DATAGRAM Command Format: + + +```bash +opensips-cli -x mi dp_translate default +``` + + +### Exported Status/Report Identifiers + + +The module provides the "dialplan" Status/Report group, where each +dialplan partition is defined as a separate SR identifier. + + +#### [partition_name] + + +The status of these identifiers reflects the readiness/status of the +cached data (if available or not when being loaded from DB): + + +- *-2* - no data at all (initial status) +- *-1* - no data, initial loading in progress +- *1* - data loaded, partition ready +- *2* - data available, a reload in progress + + +In terms of reports/logs, the following events will be reported: + + +- starting DB data loading +- DB data loading failed, discarding +- DB data loading successfully completed +- N rules loaded (N discarded) + + +```json +{ + "Name": "default", + "Reports": [ + { + "Timestamp": 1652778355, + "Date": "Tue May 17 12:05:55 2022", + "Log": "starting DB data loading" + }, + { + "Timestamp": 1652778355, + "Date": "Tue May 17 12:05:55 2022", + "Log": "DB data loading successfully completed" + }, + { + "Timestamp": 1652778355, + "Date": "Tue May 17 12:05:55 2022", + "Log": "5 rules loaded (0 discarded)" + }, + { + "Timestamp": 1652778405, + "Date": "Tue May 17 12:06:45 2022", + "Log": "starting DB data loading" + }, + { + "Timestamp": 1652778405, + "Date": "Tue May 17 12:06:45 2022", + "Log": "DB data loading successfully completed" + }, + { + "Timestamp": 1652778405, + "Date": "Tue May 17 12:06:45 2022", + "Log": "5 rules loaded (0 discarded)" + } + ] +} + +``` + + +For how to access and use the Status/Report information, please see +[Status/Report Interface documentation](https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +### Installation + + +The modules requires one table in OpenSIPS database: dialplan.The SQL +syntax to create them can be found in dialplan-create.sql +script in the database directories in the opensips/scripts folder. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +## Developer Guide + + +The module does not provide any API to use in other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/dialplan/dialplan.c b/modules/dialplan/dialplan.c index 454f9a6caea..d62ad80e93f 100644 --- a/modules/dialplan/dialplan.c +++ b/modules/dialplan/dialplan.c @@ -86,6 +86,32 @@ static str database_url = {NULL, 0}; void *dp_srg = NULL; +#ifdef PCRE2_LIB +pcre2_general_context *dp_gcontext = NULL; +pcre2_compile_context *dp_ccontext = NULL; + +void * wrap_shm_malloc(PCRE2_SIZE size, void * memory_data) +{ + UNUSED(memory_data); + return shm_malloc(size); +} + +void wrap_shm_free(void * p, void * memory_data) +{ + UNUSED(memory_data); + shm_free(p); +} +#else +void * wrap_shm_malloc(size_t size) +{ + return shm_malloc(size); +} + +void wrap_shm_free(void * p ) +{ + shm_free(p); +} +#endif static const param_export_t mod_params[]={ { "partition", STR_PARAM|USE_FUNC_PARAM, @@ -398,6 +424,21 @@ static int mod_init(void) return -1; } +#ifdef PCRE2_LIB + dp_gcontext = pcre2_general_context_create(wrap_shm_malloc, wrap_shm_free, NULL); + if (!dp_gcontext) { + LM_ERR("Unable to create pcre general context\n"); + return -1; + } + + dp_ccontext = pcre2_compile_context_create(dp_gcontext); + if (!dp_ccontext) { + LM_ERR("Unable to create pcre compile context\n"); + return -1; + } +#endif + + return 0; } @@ -452,6 +493,19 @@ static void mod_destroy(void) } destroy_data(); +#ifdef PCRE2_LIB + if (dp_ccontext) + { + pcre2_compile_context_free(dp_ccontext); + dp_ccontext = NULL; + } + + if (dp_gcontext) + { + pcre2_general_context_free(dp_gcontext); + dp_gcontext = NULL; + } +#endif } @@ -869,51 +923,43 @@ static mi_response_t *mi_translate3(const mi_params_t *params, } -void * wrap_shm_malloc(size_t size) -{ - return shm_malloc(size); -} - -void wrap_shm_free(void * p ) +pcre2_code * wrap_pcre_compile(char * pattern, int flags) { - shm_free(p); + pcre2_code * ret ; + PCRE2_ERR error; + PCRE2_SIZE erroffset; + int pcre_flags = 0; + +#ifndef PCRE2_LIB + void *(*old_malloc)(size_t) = pcre_malloc; + void (*old_free)(void *) = pcre_free; + + pcre_malloc = wrap_shm_malloc; + pcre_free = wrap_shm_free; +#endif + + if (flags & DP_CASE_INSENSITIVE) + pcre_flags |= PCRE2_CASELESS; + + ret = pcre2_compile( + (PCRE2_SPTR)pattern, /* the pattern */ + PCRE2_ZERO_TERMINATED, + pcre_flags, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + dp_ccontext); /* compile context, to allocate memory in shm */ + +#ifndef PCRE2_LIB + pcre_malloc = old_malloc; + pcre_free = old_free; +#endif + + return ret; } - -pcre * wrap_pcre_compile(char * pattern, int flags) -{ - pcre * ret ; - func_malloc old_malloc ; - func_free old_free; - const char * error; - int erroffset; - int pcre_flags = 0; - - - old_malloc = pcre_malloc; - old_free = pcre_free; - - pcre_malloc = wrap_shm_malloc; - pcre_free = wrap_shm_free; - - if (flags & DP_CASE_INSENSITIVE) - pcre_flags |= PCRE_CASELESS; - - ret = pcre_compile( - pattern, /* the pattern */ - pcre_flags, /* default options */ - &error, /* for error message */ - &erroffset, /* for error offset */ - NULL); - - pcre_malloc = old_malloc; - pcre_free = old_free; - - return ret; -} - -void wrap_pcre_free( pcre* re) +void wrap_pcre_free( pcre2_code* re) { + // *not* pcre2_code_free + // shm_free is used because pcre2_general_context_create overrides malloc with wrap_shm_malloc shm_free(re); - } diff --git a/modules/dialplan/dialplan.h b/modules/dialplan/dialplan.h index 954359a7af8..7d1578e7953 100644 --- a/modules/dialplan/dialplan.h +++ b/modules/dialplan/dialplan.h @@ -31,7 +31,25 @@ #include "../../db/db.h" #include "../../re.h" + +#ifdef PCRE2_LIB +#define PCRE2_CODE_UNIT_WIDTH 8 +#define PCRE2_ERR int +#include +#else +/* backwards compatibility */ +#define pcre2_code pcre +#define PCRE2_CASELESS PCRE_CASELESS +#define PCRE2_SIZE int +#define PCRE2_ERR const char * +#define pcre2_pattern_info(subst_comp, flag, ret) \ + pcre_fullinfo(subst_comp, NULL, PCRE_INFO_CAPTURECOUNT, ret); +#define PCRE2_SPTR char * +#define pcre2_compile(pattern, _, flags, error, erroffset, ctx) \ + pcre_compile(pattern, flags, error, erroffset, NULL) #include +#endif + #define REGEX_OP 1 #define EQUAL_OP 0 @@ -48,7 +66,7 @@ typedef struct dpl_node{ int matchop; int match_flags; str match_exp, subst_exp, repl_exp; /*keeping the original strings*/ - pcre * match_comp, * subst_comp; /*compiled patterns*/ + pcre2_code * match_comp, * subst_comp; /*compiled patterns*/ struct subst_expr * repl_comp; str attrs; str timerec; @@ -121,19 +139,11 @@ struct subst_expr* repl_exp_parse(str subst); void repl_expr_free(struct subst_expr *se); int translate(struct sip_msg *msg, str user_name, str* repl_user, dpl_id_p idp, str *); int rule_translate(struct sip_msg *msg, str , dpl_node_t * rule, str *); -int test_match(str string, pcre * exp, int * out, int out_max); - - -typedef void * (*func_malloc)(size_t ); -typedef void (*func_free)(void * ); - -void * wrap_shm_malloc(size_t size); -void wrap_shm_free(void *); - +int test_match(str string, pcre2_code * exp, int * out, int out_max); -pcre * wrap_pcre_compile(char * pattern, int flags); -void wrap_pcre_free( pcre*); +pcre2_code * wrap_pcre_compile(char * pattern, int flags); +void wrap_pcre_free( pcre2_code*); extern rw_lock_t *ref_lock; extern str dp_df_part; diff --git a/modules/dialplan/doc/contributors.xml b/modules/dialplan/doc/contributors.xml deleted file mode 100644 index f65d7c80666..00000000000 --- a/modules/dialplan/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 73 - 48 - 986 - 949 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 71 - 46 - 910 - 983 - - - 3. - Ionut Ionita (@ionutrazvanionita) - 40 - 20 - 1149 - 579 - - - 4. - Anca Vamanu - 34 - 5 - 3263 - 19 - - - 5. - Andrei Dragus - 24 - 3 - 382 - 1029 - - - 6. - Razvan Crainea (@razvancrainea) - 23 - 19 - 98 - 162 - - - 7. - Ovidiu Sas (@ovidiusas) - 16 - 13 - 144 - 37 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 10 - 6 - 157 - 115 - - - 9. - Maksym Sobolyev (@sobomax) - 6 - 4 - 10 - 10 - - - 10. - Eseanu Marius Cristian (@eseanucristian) - 5 - 3 - 114 - 47 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Zero King (@l2dy), Parantido Julius De Rica (@Parantido), Paul Wise, Sergio Gutierrez, Vlad Paiu (@vladpaiu), Rudy Pedraza, Juha Heinanen (@juha-h), Ken Rice, Peter Lemenkov (@lemenkov), UnixDev, David Sanders. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jul 2012 - Feb 2025 - - - 3. - Razvan Crainea (@razvancrainea) - Dec 2010 - Sep 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2008 - Sep 2022 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2022 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ovidiu Sas (@ovidiusas) - Sep 2008 - Nov 2015 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Jul 2014 - Nov 2015 - - - -
-All remaining contributors: David Sanders, Eseanu Marius Cristian (@eseanucristian), Parantido Julius De Rica (@Parantido), Vlad Paiu (@vladpaiu), Rudy Pedraza, Sergio Gutierrez, Paul Wise, Anca Vamanu, Andrei Dragus, UnixDev, Juha Heinanen (@juha-h), Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Zero King (@l2dy), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Andrei Dragus, Anca Vamanu. -
- -
diff --git a/modules/dialplan/doc/dialplan.xml b/modules/dialplan/doc/dialplan.xml deleted file mode 100644 index a450110144e..00000000000 --- a/modules/dialplan/doc/dialplan.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - dialplan Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2007-2008 &voicesystem; - - diff --git a/modules/dialplan/doc/dialplan_admin.xml b/modules/dialplan/doc/dialplan_admin.xml deleted file mode 100644 index 8c1127446f7..00000000000 --- a/modules/dialplan/doc/dialplan_admin.xml +++ /dev/null @@ -1,903 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module implements generic string translations based on matching and - replacement rules. It can be used to manipulate R-URI or a PV and to - translated to a new format/value. - -
- -
- How it works - - At startup, the module will load all transformation rules from one or more - dialplan-compatible tables. The data of each table will be stored in a - partition (data source), which is defined by the - "db_url" and "table_name" properties. Every table row will be stored in - memory as a translation rule. Each rule will describe how the matching - should be made, how the input value should be modified and which attributes - should be set for the matching transformation. - - - A dialplan rule can be of two types: - - - - "String matching" rule - performs a - string equality test against the input string. The case of the - characters can be ignored by enabling bit 1 of the rule's "match_flags" - bitmask column - (i.e. set the column value to 1 or 0, for insensitive or sensitive) - - - - - "Regex matching" rule - uses Perl - Compatible Regular Expressions, and will attempt to match the rule's - expression against an input string. The regex - maching can be done in a caseless manner by enabling bit 1 of the - rule's "match_flags" bitmask column - (i.e. set the column value to 1 or 0, for insensitive or sensitive) - - - - - - The module provides the dp_translate() script function, - which expects an input string value that - will be matched, at worst, against all rules of a partition. - - - Internally, the module groups a partition's rules into two sets, "string" and "regex". - The matching logic will attempt to find the first match within each of - these two sets of rules. Each set will be iterated in - ascending order of priority. If an input - string happens to match a rule in each of the two sets, the rule with the - smallest priority will be chosen. Furthermore, should these two matching - rules also have equal priorities, the one with the smallest "id" field - (the unique key) will be chosen. - - - Once a single rule is decided upon, the defined transformation (if any) is - applied and the result is returned as output value. Also, if any string - attribute is associated to the rule, this will be returned to the script - along with the output value. - -
- -
- Usage cases - - The module can be used to implement dialplans - to do auto completion of - the dialed numbers (e.g. national to international), to convert generic - numbers to specific numbers (e.g. for emergency numbers). - - - Also the module can be used for detecting ranges or sets of numbers mapped - on a service/case - the "attributes" string column can be used here to - store extra information about the service/case. - - - Non-SIP string translation can also be implemented - like converting country - names from all possible formats to a canonical format: - (UK, England, United Kingdom) -> GB. - - - Any other string-based translation or detection for whatever other purposes. - -
- -
- Database structure and usage - - Depending what kind of operation (translation, matching, etc) you want - to do with the module, you need to populate the appropriate DB records. - - - The definition of the tables used by the dialplan module can be found - at &osipsdbdocslink;#AEN1501 - -
- What to place in table - -
- String translation (regexp detection, subst translation) - - Recognize a number block in all forms (international, national) - and convert it to a canonical format (E.164) - - - - - match_op = 1 (regexp) - - - - - match_exp = "^(0040|\+40|0|40)21[0-9]+" ; - regular expression that will be used to match with this rule (if - the rule should be applied for the input string) - - - - - match_flags = 0 (0 - case sensitive, - 1 - case insensitive matching) - - - - - subst_exp = "^(0040|\+40|0|40)(.+)" ; - regular expression used to do the transformation (first part - of the subst operation) - - - - - repl_exp = "40\2" ; second part of the - subst (output) - linked to the subst_exp field; when both - defined, they work as a subst() - - - -
- -
- String translation (regexp detection, replacement) - - Recognize the name of a country (multiple languages) and convert - it to a single, fixed value - - - - - match_op = 1 (regexp) - - - - - match_exp = "^((Germany)|(Germania)|(Deutschland)|(DE))" ; - regular expression that will be used to match with this rule (if - the rule should be applied for the input string) - - - - - match_flags = 0 (0 - case sensitive, - 1 - case insensitive matching) - - - - - subst_exp = NULL ; - when translation is actually a replacement, this field must - be NULL. - - - - - repl_exp = "DE" ; static string to - replace the input - whenever this rule will match, it will - return this string as output. - - - -
- -
- Number detection (regexp detection, no replacement) - - Recognize a block of numbers as belong to a single service and - signalize this via an attribute. - - - - - match_op = 1 (regexp) - - - - - match_exp = "^021456[0-9]{5}" ; - regular expression that will be used to match with this rule (if - the rule should be applied for the input string) - - - - - match_flags = 0 (0 - case sensitive, - 1 - case insensitive matching) - - - - - subst_exp = NULL ; - no translation - - - - - repl_exp = NULL ; - no translation - - - - - attrs = "serviceX" ; - whatever string you will get into OpenSIPS script and it will - provide you more information (totally custom) - - - -
- -
- String conversion (equal detection, replacement) - - Recognize a fixed string/number and replace it with something fixed. - - - - - match_op = 0 (equal) - - - - - match_exp = "SIP server" ; - string to be matched - - - - - match_flags = 0 (0 - case sensitive, - 1 - case insensitive matching) - - - - - subst_exp = NULL ; - no subst translation - - - - - repl_exp = "OpenSIPS" ; - output string - - - -
- -
- -
- - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None - - - - -
- - -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libpcre-dev - the development libraries of PCRE. - - - - -
-
- - -
- Exported Parameters - -
- <varname>partition</varname> (string) - - Specify a new dialplan partition (data source). This parameter may - be set multiple times. Each partition may have a specific "db_url" and - "table_name". If not specified, these values will be inherited from - , db_default_url or - , respectively. The name of - the default partition is 'default'. - - - Note: OpenSIPS will validate each partition, so make sure to add any - required entries in the "version" table of each database defined - through the 'db_url' property. - - - - Defining the <varname>'pstn'</varname> partition - -... -modparam("dialplan", "partition", " - pstn: - table_name = dialplan; - db_url = mysql://opensips:opensipsrw@127.0.0.1/opensips") -... - - - - - Define the 'pstn' partition and make it the 'default' partition, so we avoid loading the 'dialplan' table - -... -db_default_url = "mysql://opensips:opensipsrw@localhost/opensips" - -loadmodule "dialplan.so" -modparam("dialplan", "partition", " - pstn: - table_name = dialplan_pstn") -modparam("dialplan", "partition", "default: pstn") -... - - -
- -
- <varname>db_url</varname> (string) - - The default DB connection of the module, overriding the global - 'db_default_url' setting. Once specified, partitions which are missing - the 'db_url' property will inherit their URL from this value. - - - - Default value is NULL (not set). - - - - Set <varname>db_url</varname> parameter - -... -modparam("dialplan", "db_url", "mysql://user:passwd@localhost/db") -... - - -
- -
- <varname>table_name</varname> (string) - - The default name of the table from which to load translation rules. - Partitions which are missing the 'table_name' property will inherit - their table name from this value. - - - - Default value is dialplan. - - - - Set <varname>table_name</varname> parameter - -... -modparam("dialplan", "table_name", "my_table") -... - - -
- -
- <varname>dpid_col</varname> (string) - - The column name to store the dialplan ID group. - - - - Default value is dpid. - - - - Set <varname>dpid_col</varname> parameter - -... -modparam("dialplan", "dpid_col", "column_name") -... - - -
- -
- <varname>pr_col</varname> (string) - - The column name to store the priority of the corresponding rule from - the table row. Smaller priority values have higher precedence. - - - - Default value is pr. - - - - Set <varname>pr_col</varname> parameter - -... -modparam("dialplan", "pr_col", "column_name") -... - - -
- -
- <varname>match_op_col</varname> (string) - - The column name to store the type of matching of the rule. - - - - Default value is match_op. - - - - Set <varname>match_op_col</varname> parameter - -... -modparam("dialplan", "match_op_col", "column_name") -... - - -
- -
- <varname>match_exp_col</varname> (string) - - The column name to store the rule match expression. - - - - Default value is match_exp. - - - - Set <varname>match_exp_col</varname> parameter - -... -modparam("dialplan", "match_exp_col", "column_name") -... - - -
- -
- <varname>match_flags_col</varname> (string) - - The column name to store various matching flags. Currently - 0 - case sensitive matching, 1 - case insensitive matching. - - - - Default value is match_flags. - - - - Set <varname>match_flags_col</varname> parameter - -... -modparam("dialplan", "match_flags_col", "column_name") -... - - -
- -
- <varname>subst_exp_col</varname> (string) - - The column name to store the rule's substitution expression. - - - - Default value is subst_exp. - - - - Set <varname>subs_exp_col</varname> parameter - -... -modparam("dialplan", "subst_exp_col", "column_name") -... - - -
- -
- <varname>repl_exp_col</varname> (string) - - The column name to store the rule's replacement expression. - - - - Default value is repl_exp. - - - - Set <varname>repl_exp_col</varname> parameter - -... -modparam("dialplan", "repl_exp_col", "column_name") -... - - -
- -
- <varname>timerec_col</varname> (integer) - - The column name that indicates an additional time recurrence check - within the rule (column values are RFC 2445-compatible strings). The - value format is identical to the input of the - check_time_rec() - function of the cfgutils module, including the - optional use of logical operators linking multiple such strings into a - larger expression. - - - - Default value is timerec. - - - - Set <varname>timerec_col</varname> parameter - -... -modparam("dialplan", "timerec_col", "month_match") -... - - -
- -
- <varname>disabled_col</varname> (integer) - - The column name that indicates if the dialplan rule is disabled. - - - - Default value is disabled. - - - - Set <varname>disabled_col</varname> parameter - -... -modparam("dialplan", "disabled_col", "disabled_column") -... - - -
- -
- <varname>attrs_col</varname> (string) - - The column name to store rule-specific attributes. - - - - Default value is attrs. - - - - Set <varname>attrs_col</varname> parameter - -... -modparam("dialplan", "attrs_col", "column_name") -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">dp_translate(id, input, [out_var], [attrs_var], [partition])</function> - - - Will try to translate the src string into dest string according to - the translation rules with dialplan ID equal to id. - - Meaning of the parameters is as follows: - - - - id (int) - the dialplan id to be used for matching rules - - - - - - input (string) - input string to be used for rule matching - and for computing the output string. - - - - - - out_var (var, optional) - variable to be populated/written with - the output string (if provided by the translation rule), on a successful translation. - - - - - - attrs_var (var, optional) - variable to be populated/written - with the "attributes" field of the translation rule, on a successful translation. - If the field is NULL or empty-string, the variable will be set to empty-string. - - - - - - partition (string, optional) - the name of the partition - (set of data) to be used for locating the DP ID. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, LOCAL_ROUTE, - BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE and EVENT_ROUTE. - - - <function>dp_translate</function> usage - -... -dp_translate(240, $ru, $var(out)); -xlog("translated into '$var(out)' \n"); -... - - - - <function>dp_translate</function> usage - -... -$avp(src) = $ruri.user; -dp_translate($var(x), $avp(src), $var(y), $var(attrs)); -xlog("translated to var $var(y) with attributes: '$var(attrs)'\n"); -... - - - - <function>dp_translate</function> usage - -... -$var(id) = 10; -dp_translate($var(id), $avp(in), , $avp(attrs), "example_partition"); -xlog("matched with attributes '$avp(attrs) against example_partition'\n"); -... - - - - <function>dp_translate</function> usage - -... -dp_translate(10, $var(in), , , $var(part)); -xlog("'$var(in)' matched against partition '$var(part)'\n") -... - - - -
- -
- - -
- Exported MI Functions - -
- <function moreinfo="none">dp_reload</function> - - It will update the translation rules, loading the database info. - - - Name: dp_reload - - Parameters: 1 - - - partition (optional) - Partition - to be reloaded. If not specified, all partitions will be - reloaded. - - - - MI DATAGRAM Command Format: - - - opensips-cli -x mi dp_reload - -
- -
- <function moreinfo="none">dp_translate</function> - - It will apply a translation rule identified by a dialplan - id on an input string. - - - Name: dp_translate - - Parameters: 3 - - - dpid - the dpid of the rule set used for - match the input string - - - input - the input string - - - partition - (optional) the name of the - partition when the dpid is located - - - - MI DATAGRAM Command Format: - - - opensips-cli -x mi dp_translate 10 +40123456789 - -
- -
- <function moreinfo="none">dp_show_partiton</function> - - Display partition(s) details. - - - Name: dp_show_partiton - - Parameters: 2 - - - partition (optional) - The - partition name. If no partition is specified, all known - partitions will be listed. - - - - MI DATAGRAM Command Format: - - - opensips-cli -x mi dp_translate default - -
-
- - -
- Exported Status/Report Identifiers - - - The module provides the "dialplan" Status/Report group, where each - dialplan partition is defined as a separate SR identifier. - -
- <varname>[partition_name]</varname> - - The status of these identifiers reflects the readiness/status of the - cached data (if available or not when being loaded from DB): - - - - -2 - no data at all (initial status) - - - -1 - no data, initial loading in progress - - - 1 - data loaded, partition ready - - - 2 - data available, a reload in progress - - - - - In terms of reports/logs, the following events will be reported: - - - - starting DB data loading - - - DB data loading failed, discarding - - - DB data loading successfully completed - - - N rules loaded (N discarded) - - - - { - "Name": "default", - "Reports": [ - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652778355, - "Date": "Tue May 17 12:05:55 2022", - "Log": "5 rules loaded (0 discarded)" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652778405, - "Date": "Tue May 17 12:06:45 2022", - "Log": "5 rules loaded (0 discarded)" - } - ] - } - -
- - - For how to access and use the Status/Report information, please see - https://www.opensips.org/Documentation/Interface-StatusReport-3-3. - - -
- - -
- Installation - - The modules requires one table in OpenSIPS database: dialplan.The SQL - syntax to create them can be found in dialplan-create.sql - script in the database directories in the opensips/scripts folder. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- - - -
diff --git a/modules/dialplan/doc/dialplan_devel.xml b/modules/dialplan/doc/dialplan_devel.xml deleted file mode 100644 index 0e6fda7493d..00000000000 --- a/modules/dialplan/doc/dialplan_devel.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - $Revision: 5895 $ - $Date$ - - - - Developer's Guide - - The module does not provide any API to use in other &osips; modules. - - diff --git a/modules/dialplan/dp_db.c b/modules/dialplan/dp_db.c index e88682a5fdd..cacac30183f 100644 --- a/modules/dialplan/dp_db.c +++ b/modules/dialplan/dp_db.c @@ -467,12 +467,12 @@ int str_to_shm(str src, str * dest) dpl_node_t * build_rule(db_val_t * values) { tmrec_expr *parsed_timerec; - pcre * match_comp, *subst_comp; + pcre2_code * match_comp, *subst_comp; struct subst_expr * repl_comp; dpl_node_t * new_rule; str match_exp, subst_exp, repl_exp, attrs, timerec; int matchop; - int namecount; + uint32_t namecount; matchop = VAL_INT(values+2); @@ -524,10 +524,9 @@ dpl_node_t * build_rule(db_val_t * values) } } - pcre_fullinfo( + pcre2_pattern_info( subst_comp, /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - PCRE_INFO_CAPTURECOUNT, /* number of named substrings */ + PCRE2_INFO_CAPTURECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ LM_DBG("references:%d , max:%d\n",namecount, diff --git a/modules/dialplan/dp_repl.c b/modules/dialplan/dp_repl.c index 6ff94dd03f2..c6b97c23e3c 100644 --- a/modules/dialplan/dp_repl.c +++ b/modules/dialplan/dp_repl.c @@ -110,11 +110,11 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule, { int repl_nb, offset, match_nb; struct replace_with token; - pcre * subst_comp; + pcre2_code * subst_comp; struct subst_expr * repl_comp; pv_value_t sv; str* uri; - int capturecount; + uint32_t capturecount; char *match_begin; int match_len; @@ -133,11 +133,10 @@ int rule_translate(struct sip_msg *msg, str string, dpl_node_t * rule, if(subst_comp){ - pcre_fullinfo( - subst_comp, /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - PCRE_INFO_CAPTURECOUNT , /* number of named substrings */ - &capturecount); /* where to put the answer */ + pcre2_pattern_info( + subst_comp, /* the compiled pattern */ + PCRE2_INFO_CAPTURECOUNT, /* number of named substrings */ + &capturecount); /* where to put the answer */ /*just in case something went wrong at load time*/ @@ -397,19 +396,22 @@ int translate(struct sip_msg *msg, str input, str * output, dpl_id_p idp, str * } -int test_match(str string, pcre * exp, int * out, int out_max) +int test_match(str string, pcre2_code * exp, int * out, int out_max) { int i, result_count; char *substring_start; int substring_length; - UNUSED(substring_start); - UNUSED(substring_length); +#ifdef PCRE2_LIB + pcre2_match_data *match_data; + PCRE2_SIZE *ovector; +#endif if(!exp){ LM_ERR("invalid compiled expression\n"); return -1; } +#ifndef PCRE2_LIB result_count = pcre_exec( exp, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ @@ -428,6 +430,44 @@ int test_match(str string, pcre * exp, int * out, int out_max) LM_ERR("Not enough space for mathing\n"); return result_count; } +#else + match_data = pcre2_match_data_create_from_pattern(exp, NULL); + if (!match_data) { + LM_ERR("failed to allocate match data\n"); + return -1; + } + + result_count = pcre2_match( + exp, /* the compiled pattern */ + (PCRE2_SPTR)string.s, /* the subject string */ + (PCRE2_SIZE)string.len, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + match_data, /* match data block */ + NULL); /* match context */ + + if (result_count < 0) + { + pcre2_match_data_free(match_data); + return result_count; + } + + if (result_count == 0) + { + LM_ERR("Not enough space for matching\n"); + pcre2_match_data_free(match_data); + return result_count; + } + + ovector = pcre2_get_ovector_pointer(match_data); + if (2 * result_count >= out_max) + result_count = out_max / 2; + + // ovector is freed by pcre2_match_data_free, copy offsets to out[] + for (i = 0; i < result_count * 2; i++) + out[i] = ovector[i]; + pcre2_match_data_free(match_data); +#endif for (i = 0; i < result_count; i++) @@ -437,7 +477,6 @@ int test_match(str string, pcre * exp, int * out, int out_max) LM_DBG("test_match:[%d] %.*s\n",i, substring_length, substring_start); } - return result_count; } diff --git a/modules/dispatcher/README b/modules/dispatcher/README deleted file mode 100644 index a1deb9350e2..00000000000 --- a/modules/dispatcher/README +++ /dev/null @@ -1,1608 +0,0 @@ -dispatcher Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS modules - 1.2.2. External libraries or applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. attrs_avp (str) - 1.3.3. script_attrs_avp (str) - 1.3.4. algo_route (str) - 1.3.5. hash_pvar (str) - 1.3.6. setid_pvar (str) - 1.3.7. ds_ping_method (string) - 1.3.8. ds_ping_from (string) - 1.3.9. ds_ping_interval (int) - 1.3.10. ds_ping_maxfwd (int) - 1.3.11. ds_probing_sock (str) - 1.3.12. ds_probing_threshold (int) - 1.3.13. ds_probing_mode (int) - 1.3.14. ds_probing_list (str) - 1.3.15. ds_define_blacklist (str) - 1.3.16. options_reply_codes (str) - 1.3.17. dst_avp (str) - 1.3.18. grp_avp (str) - 1.3.19. cnt_avp (str) - 1.3.20. sock_avp (str) - 1.3.21. pvar_algo_pattern (str) - 1.3.22. persistent_state (int) - 1.3.23. cluster_id (integer) - 1.3.24. cluster_sharing_tag (string) - 1.3.25. cluster_probing_mode (string) - 1.3.26. partition (string) - 1.3.27. table_name (string) - 1.3.28. setid_col (string) - 1.3.29. destination_col (string) - 1.3.30. state_col (string) - 1.3.31. weight_col (string) - 1.3.32. priority_col (string) - 1.3.33. attrs_col (string) - 1.3.34. socket_col (string) - 1.3.35. probe_mode_col (string) - 1.3.36. fetch_freeswitch_stats (integer) - 1.3.37. max_freeswitch_weight (integer) - - 1.4. Exported Functions - - 1.4.1. ds_select_dst(set, alg, [flags], [partition], - [max_res]) - - 1.4.2. ds_select_domain(set, alg, [flags], - [partition], [max_res]) - - 1.4.3. ds_next_dst([partition]) - 1.4.4. ds_next_domain([partition]) - 1.4.5. ds_mark_dst([state], [partition]) - 1.4.6. ds_count(set, state_filter, res_var, - [partition]) - - 1.4.7. ds_is_in_list(ip, port, [set], [partition], - [active_only], [pattern]) - - 1.4.8. ds_push_script_attrs(script_attr, ip, port, - set, [partition]) - - 1.4.9. ds_get_script_attrs(uri, set, [partition], - out_attrs) - - 1.5. Exported MI Functions - - 1.5.1. ds_set_state - 1.5.2. ds_list - 1.5.3. ds_reload - 1.5.4. ds_push_script_attrs - - 1.6. Exported Events - - 1.6.1. E_DISPATCHER_STATUS - - 1.7. Exported Status/Report Identifiers - - 1.7.1. [partition_name] - 1.7.2. [partition_name];events - - 1.8. Installation and Running - - 1.8.1. OpenSIPS config file - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the default database URL for dispatcher - 1.2. Set the 'default' partition's “attrs_avp” parameter - 1.3. Set the 'default' partition's “script_attrs_avp” parameter - 1.4. Use algo_route for hashing: - 1.5. Use $avp(273) for hashing: - 1.6. Use combination of PVs for hashing: - 1.7. Set the “setid_pvar” parameter - 1.8. Set the “ds_ping_method” parameter - 1.9. Set the “ds_ping_from” parameter - 1.10. Set the “ds_ping_interval” parameter - 1.11. Set the “ds_ping_maxfwd” parameter - 1.12. Set the “ds_probing_sock” parameter - 1.13. Set the “ds_probing_threshold” parameter - 1.14. Set the “ds_probing_mode” parameter - 1.15. Set the “ds_probing_list” parameter - 1.16. Set the 'default' partition's “ds_define_blacklist” - parameter - - 1.17. Set the “options_reply_codes” parameter - 1.18. Set the 'default' partition's “dst_avp” parameter - 1.19. Set the 'default' partition's “grp_avp” parameter - 1.20. Set the 'default' partition's “cnt_avp” parameter - 1.21. Set the 'default' partition's “sock_avp” parameter - 1.22. Set the “pvar_algo_pattern” parameter - 1.23. Set the persistent_state parameter - 1.24. Set cluster_id parameter - 1.25. Set cluster_sharing_tag parameter - 1.26. Set cluster_probing_mode parameter - 1.27. Define a new partition called 'voicemail' - 1.28. Define the 'trunks' partition and make it the 'default' - partition, so we avoid loading the 'dispatcher' table - - 1.29. Set the default table name - 1.30. Set “setid_col” parameter - 1.31. Set “destination_col” parameter - 1.32. Set “state_col” parameter - 1.33. Set “weight_col” parameter - 1.34. Set “priority_col” parameter - 1.35. Set “attrs_col” parameter - 1.36. Set “socket_col” parameter - 1.37. Set “probe_mode_col” parameter - 1.38. Set the fetch_freeswitch_load parameter - 1.39. Set the max_freeswitch_weight parameter - 1.40. ds_select_dst usage - 1.41. ds_count usage - 1.42. ds_is_in_list usage - 1.43. ds_count usage - 1.44. ds_count usage - 1.45. OpenSIPS config script - sample dispatcher usage - -Chapter 1. Admin Guide - -1.1. Overview - - This modules implements a dispatcher for destination addresses. - It computes hashes over various parts of the request and - selects an address from a destination set. The selected address - may then either overwrite the R-URI of a SIP request or be used - as an outbound proxy. - - The module can be used as a stateless load balancer, having no - guarantee of fair distribution. - - For the distribution algorithm, the module allows the - definition of weights for the destination. This is useful in - order to get a different ratio of traffic between destinations. - - Starting with version 2.1, the dispatcher module keeps its - destination sets into different partitions. Each partition is - described by its own "db_url", "table_name", "dst_avp", - "grp_avp", "cnt_avp", "sock_avp", "attr_avp", "blacklists", - "ping_from", "ping_method" and "persistent_state" set of - attributes. Setting any of these module parameters will only - alter the "default" partition's properties. - - In order to create a new partition, the partition parameter can - be used. If none of the 8 partition specific parameters are - defined for the "default" partition, then this partition will - not be created. Once the "default" partition is created, any - undefined parameter from other partitions will inherit the - value of the corresponding parameter of the "default" - partition. If there is no "default" partition, the default - value specified in the parameter's description will be used. - Finally, note that each dispatcher table specified using the - "table_name" partition attribute requires a corresponding - "version" table record within the partition's database, - specified through "db_url". - - Since version 2.1, the "flags" parameter has been moved to - ds_select_dst() and ds_select_domain() along with "force_dst" - and "use_default" flags. - -1.2. Dependencies - -1.2.1. OpenSIPS modules - - The following modules must be loaded before this module: - * TM - only if active recovery of failed hosts is required. - * clusterer - only if "cluster_id" option is enabled. - * database - one of the DB SQL modules - * freeswitch - only if "fetch_freeswitch_stats" is enabled.. - -1.2.2. External libraries or applications - - The following libraries or applications must be installed - before running OpenSIPS with this module: - * none. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - The default DB connection of the module, overriding the global - 'db_default_url' setting. Once specified, partitions which are - missing the 'db_url' property will inherit their URL from this - value. - - Default value is “NULL”. - - Example 1.1. Setting the default database URL for dispatcher -... -modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database -") -... - -1.3.2. attrs_avp (str) - - The name of the avp to contain the attributes string of the - current destination. When a destination is selected, - automatically, this AVP will provide the attributes string - - this is an opaque string (from OpenSIPS point of view) : it is - loaded from destination definition ( via DB) and blindly - provided in the script. Setting this parameter will only change - the default partition's attrs_avp. Use the partition parameter - to create and alter other partitions. - -Note - - Default value is “null” - don't provide ATTRIBUTEs. - - Example 1.2. Set the 'default' partition's “attrs_avp” - parameter -... -modparam("dispatcher", "attrs_avp", "$avp(272)") -... - -1.3.3. script_attrs_avp (str) - - Name of the avp to contain the script attributes string of the - current destination. When a destination is selected, - automatically, this AVP will provide the attributes string - - this is an opaque string (from OpenSIPS point of view) : it is - provided via the ds_push_script_attrs MI or SCRIPT function. - -Note - - Default value is “null” - don't provide SCRIPT ATTRIBUTEs. - - Example 1.3. Set the 'default' partition's “script_attrs_avp” - parameter -... -modparam("dispatcher", "attrs_avp", "$avp(script_attrs)") -... - -1.3.4. algo_route (str) - - Name of the route to be called when using algo 10. The route - will get as param the dst_uri, attrs and script_attrs for the - dispatcher entry that currently needs to be evaluated ( - available via $param(1), $param(2) and $param(3) or via - $param(dst_uri), $param(attrs) and $param(script_attrs) when - the route gets called ). The return value of the route is - considered by the dispatcher module to be the current weight of - the dispatcher entry, and when using the 10 algo, the - dispatcher entries are sorted in ascending weight order. If the - returned value from the algo route is negative, the current - dispatcher entry will be automatically skipped from usage - - Default value is “null” - disabled. - - Example 1.4. Use algo_route for hashing: -... -modparam("dispatcher", "algo_route", "my_dispatcher_logic)") -... -route[my_dispatcher_logic] { - $var(curent_score) = 0; - xlog("DISPATCHER - Running logic for $param(dst_uri) with attrs -$param(attrs) and script attrs $param(script_attrs) \n"); - - # decide to penalize current dispatcher entry, based on your log -ic - if (my_condition_here) - $var(current_score) = $var(current_score) + 10; - - return $var(rc); -} - - -1.3.5. hash_pvar (str) - - String with PVs used for the hashing algorithm 7. - -Note - - You must set this parameter if you want do hashing over custom - message parts. - - Default value is “null” - disabled. - - Example 1.5. Use $avp(273) for hashing: -... -modparam("dispatcher", "hash_pvar", "$avp(273)") -... - - Example 1.6. Use combination of PVs for hashing: -... -modparam("dispatcher", "hash_pvar", "hash the $fU@$ci") -... - -1.3.6. setid_pvar (str) - - The name of the PV where to store the set ID (group ID) when - calling ds_is_in_list() without group parameter (third - parameter). - - Default value is “null” - don't set PV. - - Example 1.7. Set the “setid_pvar” parameter -... -modparam("dispatcher", "setid_pvar", "$var(setid)") -... - -1.3.7. ds_ping_method (string) - - With this Method you can define, with which method you want to - probe the failed gateways. This method is only available, if - compiled with the probing of failed gateways enabled. - - Use the 'partition' parameter if you want to define the ping - method other partitions. - - Default value is “OPTIONS”. - - Example 1.8. Set the “ds_ping_method” parameter -... -modparam("dispatcher", "ds_ping_method", "INFO") -... - -1.3.8. ds_ping_from (string) - - With this Method you can define the "From:"-Line for the - request, sent to the failed gateways. This method is only - available, if compiled with the probing of failed gateways - enabled. - - Use the 'partition' parameter if you want to define the "From:" - ping header of other partitions. - - Default value is “sip:dispatcher@localhost”. - - Example 1.9. Set the “ds_ping_from” parameter -... -modparam("dispatcher", "ds_ping_from", "sip:proxy@sip.somehost.com") -... - -1.3.9. ds_ping_interval (int) - - With this Method you can define the interval for sending a - request to a failed gateway. This parameter is only used, when - the TM-Module is loaded. If set to “0”, the pinging of failed - requests is disabled. - - Default value is “0” (disabled). - - Example 1.10. Set the “ds_ping_interval” parameter -... -modparam("dispatcher", "ds_ping_interval", 30) -... - -1.3.10. ds_ping_maxfwd (int) - - This parameter allows you to enforce a specific Max-Forward - value for the SIP pinging requests generated by the Dispatcher - modules. If not explicitly set, no value will be enforced and - it let the Transaction Layer (TM module) to set a default - Max-Forward value. - - The accepted values are any positive integer values, including - the “0” value. - - Example 1.11. Set the “ds_ping_maxfwd” parameter -... -modparam("dispatcher", "ds_ping_maxfwd", 2) -... - -1.3.11. ds_probing_sock (str) - - A socket description [proto:]host[:port] of the local socket - (which is used by OpenSIPS for SIP traffic) to be used (if - multiple) for sending the probing messages from. - - Default value is “NULL(none)”. - - Example 1.12. Set the “ds_probing_sock” parameter -... -modparam("dispatcher", "ds_probing_sock", "udp:192.168.1.100:5077") -... - -1.3.12. ds_probing_threshold (int) - - If you want to set a gateway into probing mode, you will need a - specific number of requests until it will change from "active" - to probing. The number of attempts can be set with this - parameter. - - Default value is “3”. - - Example 1.13. Set the “ds_probing_threshold” parameter -... -modparam("dispatcher", "ds_probing_threshold", 10) -... - -1.3.13. ds_probing_mode (int) - - Controls what gateways are tested to see if they are reachable. - If set to 0, only the gateways with state PROBING are tested, - if set to 1, all gateways are tested. If set to 1 and the - response is 408 (timeout), an active gateway is set to PROBING - state. - - Default value is “0”. - - Example 1.14. Set the “ds_probing_mode” parameter -... -modparam("dispatcher", "ds_probing_mode", 1) -... - -1.3.14. ds_probing_list (str) - - Defines a list of one or more setids that limits which - destinations are probed if probing is active. This is useful - when multiple proxies share the same dispatcher table, but you - want to limit which ones are responsible for probing specific - destinations. - - Default value is “NULL (probe all sets)”. - - Example 1.15. Set the “ds_probing_list” parameter -... -modparam("dispatcher", "ds_probing_list", "1,2,3") -... - -1.3.15. ds_define_blacklist (str) - - Defines a blacklist based on a dispatching setid from the - 'default' partition. This list will contain the IPs (no port, - all protocols) of the destinations matching the given setid. - Use the 'partition' parameter if you want to define blacklists - based on other partitions' sets. - - Multiple instances of this param are allowed. - - Default value is “NULL”. - - Example 1.16. Set the 'default' partition's - “ds_define_blacklist” parameter -... -modparam("dispatcher", "ds_define_blacklist", "list= 1,4,3") -modparam("dispatcher", "ds_define_blacklist", "blist2= 2,10,6") -... - -1.3.16. options_reply_codes (str) - - This parameter must contain a list of SIP reply codes separated - by comma. The codes defined here will be considered as valid - reply codes for OPTIONS messages used for pinging, apart for - 200. - - Default value is “NULL”. - - Example 1.17. Set the “options_reply_codes” parameter -... -modparam("dispatcher", "options_reply_codes", "501, 403") -... - -1.3.17. dst_avp (str) - - This is mainly for internal usage and represents the name of - the avp which will hold the list with addresses, in the order - they have been selected by the chosen algorithm. If use_default - is 1, the value of last dst_avp_id is the last address in - destination set. The first dst_avp_id is the selected - destinations. All the other addresses from the destination set - will be added in the avp list to be able to implement serial - forking. Setting this parameter will only change the default - partition's dst_avp. Use the partition parameter to create and - alter other partitions. - - For the 'default' partition the default value is - “$avp(ds_dst_failover)”. For any other partition, the default - value is “$avp(ds_dst_failover_partitionname)”. - - Example 1.18. Set the 'default' partition's “dst_avp” parameter -... -modparam("dispatcher", "dst_avp", "$avp(271)") -... - -1.3.18. grp_avp (str) - - This is mainly for internal usage and represents the name of - the avp storing the group id of the destination set. Good to - have it for later usage or checks. Setting this parameter will - only change the default partition's grp_avp. Use the partition - parameter to create and alter other partitions. - - For the 'default' partition the default value is - “$avp(ds_grp_failover)”. For any other partition, the default - value is “$avp(ds_grp_failover_partitionname)”. - - Example 1.19. Set the 'default' partition's “grp_avp” parameter -... -modparam("dispatcher", "grp_avp", "$avp(273)") -... - -1.3.19. cnt_avp (str) - - This is mainly for internal usage and represents the name of - the avp storing the number of destination addresses kept in - dst_avp avps. Setting this parameter will only change the - default partition's cnt_avp. Use the partition parameter to - create and alter other partitions. - - For the 'default' partition the default value is - “$avp(ds_cnt_failover)”. For any other partition, the default - value is “$avp(ds_cnt_failover_partitionname)”. - - Example 1.20. Set the 'default' partition's “cnt_avp” parameter -... -modparam("dispatcher", "cnt_avp", "$avp(274)") -... - -1.3.20. sock_avp (str) - - This is mainly for internal usage and represents the name of - the avp storing the sockets to be used for the destination - addresses kept in dst_avp avps. Setting this parameter will - only change the default partition's sock_avp. Use the partition - parameter to create and alter other partitions. - - For the 'default' partition the default value is - “$avp(ds_sock_failover)”. For any other partition, the default - value is “$avp(ds_sock_failover_partitionname)”. - - Example 1.21. Set the 'default' partition's “sock_avp” - parameter -... -modparam("dispatcher", "sock_avp", "$avp(275)") -... - -1.3.21. pvar_algo_pattern (str) - - This parameter is used by the PVAR(9) algorithm to specify the - pseudovariable pattern used to detect the load of each - destination. The name of the pseudovariable should contain the - string “%u”, which will be internally replaced by the module - with the uri of the destination. The string “%i” can also be - used and will be replaced with the set ID of the destination - (useful in cases where same uri exists in multiple sets). - - Default value is “none”. - - Example 1.22. Set the “pvar_algo_pattern” parameter -... -modparam("dispatcher", "pvar_algo_pattern", "$stat(load_%u)") -... - -1.3.22. persistent_state (int) - - Specifies whether the state column should be loaded at startup - and flushed during runtime or not for the "default" partition. - - Use the 'partition' parameter if you want to define the - persistent state of other partitions. - - Default value is “1” (enabled). - - Example 1.23. Set the persistent_state parameter -... -# disable all DB operations with the state of a destination -modparam("dispatcher", "persistent_state", 0) -... - -1.3.23. cluster_id (integer) - - The ID of the cluster the module is part of. The clustering - support is used in dispatcher module for two purposes: for - sharing the status of the destinations and for controlling the - pinging to destinations. - - If clustering enbled, the module will automatically share - changes over the status of the destinations with the other - OpenSIPS instances that are part of a cluster. Whenever such a - status changes (following an MI command, a probing result, a - script command), the module will replicate this status change - to all the nodes in this given cluster. - - The clustering with sharing tag support may be used to control - which node in the cluster will perform the pinging/probing to - destinations. See the cluster_sharing_tag option. - - This OpenSIPS cluster exposes the "dispatcher-status-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - For more info on how to define and populate a cluster (with - OpenSIPS nodes) see the clusterer module. - - Default value is “0 (none)”. - - Example 1.24. Set cluster_id parameter -... -# replicate destination status with all OpenSIPS in cluster ID 9 -modparam("dispatcher", "cluster_id", 9) -... - -1.3.24. cluster_sharing_tag (string) - - The name of the sharing tag (as defined per clusterer modules) - to control which node is responsible for perform the - self-triggered actions in the module. Such actions may be the - destination probing (see also the cluster_probing_mode - parameter) or sharing the changes in the destination status. If - defined, only the node with active status of this tag will - perform the actions (pinging and sharing status). - - The cluster_id must be defined for this option to work. - - This is an optional parameter. If not set, all the nodes in the - cluster will share the status changes. - - Default value is “empty (none)”. - - Example 1.25. Set cluster_sharing_tag parameter -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_sharing_tag", "vip") -... - -1.3.25. cluster_probing_mode (string) - - This paramter controls how the probing/pinging should be done - when using the clustering support. It is about which node in - the cluster pings which gateway/destination. - - The cluster_id must be defined for this option to work. - - The supported probing modes are: - * "all" - all the nodes in the cluster will independetly ping - all the defined destinations, an "all" pings "all" mode. - * "by-shtag" - all the destinations are pinged by only one - node in the cluster, the node having the - cluster_sharing_tag active. By activating the sharing tag - on a different node, the pinging duty will be transfered to - another node in the cluster. - * "distributed" - the pinging effort is distributed across - all the nodes in the cluster, so each node will ping a - sub-set of the overall set of destinations. Still all the - destinations will get pinged (and only once per pinging - cycle). The re-partitioning of the pinging effort over the - available nodes in the cluster is automatically done when - new nodes are joining or nodes are dropping out. Still - there is no guaratee on which node will be responsible for - pinging which destination. - - Default value is “"all"”. - - Example 1.26. Set cluster_probing_mode parameter -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_sharing_tag", "vip") -modparam("dispatcher", "cluster_probing_mode", "by-shtag") -... -# the pinging effort is distributed across all the nodes -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_probing_mode", "distributed") -... - -1.3.26. partition (string) - - Define a new partition (data source) with the following - properties: "db_url", "table_name", "dst_avp", "grp_avp", - "cnt_avp", "sock_avp", "attrs_avp", "script_attrs", - "ds_define_blacklist". All these properties are optional, - having appropriate default values. - - The syntax is: "partition_name: param1 = value1; param2 = - value2". Each value format is the same as the one used to - define a specific parameter using modparam. - - This parameter may be set multiple times, thus defining as many - partitions as needed. The 'default' partition may also be - defined using this parameter. - - Example 1.27. Define a new partition called 'voicemail' -... -modparam("dispatcher", "partition", - "voicemail: - db_url = mysql://user:passwd@localhost/database; - table_name = dispatcher; - attrs_avp = $avp(ds_attr_vm); - ds_define_blacklist = list2 = 4,6") -... - - Example 1.28. Define the 'trunks' partition and make it the - 'default' partition, so we avoid loading the 'dispatcher' table -... -modparam("dispatcher", "partition", - "trunks: - db_url = mysql://user:passwd@localhost/database; - table_name = dispatcher_trunks; - attrs_avp = $avp(ds_attr_trunks)") -modparam("dispatcher", "partition", "default: trunks") -... - -1.3.27. table_name (string) - - The default name of the table from which to load dispatcher - destinations. Partitions which are missing the 'table_name' - property will inherit their table name from this value. - - Default value is “dispatcher”. - - Example 1.29. Set the default table name -... -modparam("dispatcher", "table_name", "my_dispatcher") -... - -1.3.28. setid_col (string) - - The column's name in the database storing the gateway's group - id. - - Default value is “setid”. - - Example 1.30. Set “setid_col” parameter -... -modparam("dispatcher", "setid_col", "groupid") -... - -1.3.29. destination_col (string) - - The column's name in the database storing the destination's sip - uri. - - Default value is “destination”. - - Example 1.31. Set “destination_col” parameter -... -modparam("dispatcher", "destination_col", "uri") -... - -1.3.30. state_col (string) - - The column's name in the database storing the state of the - destination uri. - - Default value is “state”. - - Example 1.32. Set “state_col” parameter -... -modparam("dispatcher", "state_col", "dststate") -... - -1.3.31. weight_col (string) - - The column's name in the database storing the weight for - destination uri. - - Default value is “weight”. - - Example 1.33. Set “weight_col” parameter -... -modparam("dispatcher", "weight_col", "dstweight") -... - -1.3.32. priority_col (string) - - The column's name in the database storing the priority for - destination uri. - - Default value is “priority”. - - Example 1.34. Set “priority_col” parameter -... -modparam("dispatcher", "priority_col", "dstprio") -... - -1.3.33. attrs_col (string) - - The column's name in the database storing the attributes - (opaque string) for destination uri. - - Default value is “attrs”. - - Example 1.35. Set “attrs_col” parameter -... -modparam("dispatcher", "attrs_col", "dstattrs") -... - -1.3.34. socket_col (string) - - The column's name in the database storing the socket (as - string) for destination uri. - - Default value is “socket”. - - Example 1.36. Set “socket_col” parameter -... -modparam("dispatcher", "socket_col", "my_sock") -... - -1.3.35. probe_mode_col (string) - - The column's name in the database storing the probe_mode (as - string) for destination. - - Default value is “probe_mode”. - - Example 1.37. Set “probe_mode_col” parameter -... -modparam("dispatcher", "probe_mode_col", "probing") -... - -1.3.36. fetch_freeswitch_stats (integer) - - If enabled, FreeSWITCH destinations may have dynamic - dispatching weights, refreshed at runtime, using the FreeSWITCH - Event Socket Layer. For these destinations, an Event Socket - Layer URL must be provisioned into the "weight" column, instead - of an integer string. Some example values: - "fs://:password@freeswitch.example.com" or - "fs://user:password@127.0.0.1:8021". The default ESL port is - 8021. - - OpenSIPS will establish a connection with the given socket and - periodically calculate/update the weights of these destinations - using statistics pushed by the FreeSWITCH box. - - The value for an automatically calculated weight ranges between - 0 - 100. This is helpful when grouping normal destinations with - FreeSWITCH ones. - - The dynamic weights are recalculated every - event_heartbeat_interval seconds (see the "freeswitch" OpenSIPS - module for more details regarding this setting), as the stats - from FreeSWITCH are expected to arrive. The update formula is - shown below (FreeSWITCH stats are highlighted in bold): - - weight = 100 * (Idle-CPU / 100) * (1 - Session-Count / - Max-Sessions) - - Default value is 0 (disabled). - - Example 1.38. Set the fetch_freeswitch_load parameter -... -modparam("dispatcher", "fetch_freeswitch_stats", 1) -... - -1.3.37. max_freeswitch_weight (integer) - - The maximum weight of a FreeSWITCH ESL-enabled destination. - This value is also used during startup/reload, when no stats - from FreeSWITCH are available yet. - - Important: When mixing normal destinations with - FreeSWITCH-enabled ones in the same dispatching set, OpenSIPS - will truncate any weight values that are larger than - max_freeswitch_weight to the value of this parameter! - - NOTE: OpenSIPS internally rounds weights to nearest integer, so - larger max weight values will more accurately represent the - current load on the FreeSWITCH boxes! For example, if you set - this parameter to 1, the box will receive no traffic whenever - either its CPU or session usage goes past 50%! - - Default value is 100. - - Example 1.39. Set the max_freeswitch_weight parameter -... -modparam("dispatcher", "max_freeswitch_weight", 1000) -... - -1.4. Exported Functions - -1.4.1. ds_select_dst(set, alg, [flags], [partition], [max_res]) - - The method selects a destination from the given set of - addresses. It will overwrite the destination URI ($du) of a SIP - request. - - Meaning of the parameters is as follows: - * set (int) - a set identifier from which to select - destinations - * alg (int) - the algorithm used to select the destination - address - + “0” - hash over callid - + “1” - hash over from uri. - + “2” - hash over to uri. - + “3” - hash over request-uri. - + “4” - weighted round-robin (next destination). the - destination's weight determines how many times it is - chosen before going to the next one - + “5” - hash over authorization-username - (Proxy-Authorization or "normal" authorization). If no - username is found, weighted round-robin is used. - + “6” - random (using rand()). - + “7” - hash over the content of PVs string. Note: This - works only when the parameter hash_pvar is set. - + “8” - the first entry in set is chosen. - + “9” - The pvar_algo_pattern parameter is used to - determine the load on each server. If the parameter is - not specified, then the first entry in the set is - chosen. - + “10” - The algo_route OpenSIPS route is called for - each dispatcher entry in the setid, in order to decide - the routing order. See the algo_route parameter for - usage examples - + “X” - if the algorithm is not implemented, the first - entry in set is chosen. - * flags (string, optional) - a string of flag-settings which - tweak the function's behavior: - + 'f' (failover support): causes the remaining addresses - from the destination set to be stored within an - internally managed AVP. You may then use ds_next_dst() - to switch to the next address, thus achieving serial - forking to all possible destinations - + 'u' (user only): will specify that only the URI user - part will be used for hashing - + 'd' (use default): use the last address in destination - set as last option to send the message - + 'a' (append destinations): append any new destinations - to the current destination list, rather than rewriting - the list - The flags are being kept per partition. - * partition (string, optional) - name of a DB partition - * max_res (int, optional) - signifies that only a maximum - number of destinations shall be included in the specified - failover AVP. This allows having multiple destinations - while also preventing excessive failover attempts in case a - number is bound to fail globally. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.40. ds_select_dst usage -... -if (!ds_select_dst(1, 0)) { - xlog("ERROR: no active destinations found!\n"); - send_reply(503, "Service Unavailable"); - exit; -} -... -ds_select_dst(1, 0, , "fs_boxes", 5); -... -ds_select_dst(1, 0, "fUD", "ask_boxes"); -... -ds_select_dst(2, 0, "fud", "pstn_gws", 5); -ds_select_dst(3, 1, "fua", "pstn_gws", 2); -... -# using variables -$var(part) = "pstn_gws" -$var(setid) = 1; -$var(alg) = 4; -$var(flags) = "fdu"; -$var(max_res) = 2; -ds_select_dst($var(setid), $var(alg), $var(flags), $var(part), $var(max_ -res)); -... - -1.4.2. ds_select_domain(set, alg, [flags], [partition], [max_res]) - - The method selects a destination from addresses set and - rewrites the hostname and port parts of the Request-URI ($ru). - Its parameters have same meaning as in ds_select_dst(). - - If the "f" (failover support) flag is present, the rest of the - addresses from the destination set will be stored in an - internally managed AVP. You may then use ds_next_domain() to - switch to the next address in the list, thus achieving serial - forking to all possible destinations. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - -1.4.3. ds_next_dst([partition]) - - Takes the next destination address from the AVPs with id - partition.'dst_avp_id' and sets the dst_uri (outbound proxy - address). If "partition" is omitted, the default partition will - be used.This function is using the flags set in ds_select_dst - or ds_select_domain. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -1.4.4. ds_next_domain([partition]) - - Takes the next destination address from the AVPs with id - partition.'dst_avp_id' and sets the domain part of the request - uri. If "partition" is omitted, the default partition will be - used.This function is using the flags set in ds_select_dst or - ds_select_domain. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -1.4.5. ds_mark_dst([state], [partition]) - - Mark the last used address from partition's destination set as - inactive ("i"/"I"/"0"), active ("a"/"A"/"1") or probing - ("p"/"P"/"2"). With this function, an automatic detection of - failed gateways can be implemented. When an address is marked - as inactive or probing, it will be ignored by ds_select_dst() - and ds_select_domain(). If "partition" is omitted, the default - partition will be used. This function is using the flags set in - ds_select_dst() or ds_select_domain(). - - Possible parameters: - * state (string, optional) - new state for the last attempted - destination. Possible values: - + "i", "I" or "0" (default) - the last destination - should be set to inactive and will be ignored in - future requests. - + "a", "A" or "1" - the last destination should be set - to active. - + "p", "P" or "2" - the last destination will be set to - probing. Note: You will need to call this function - "threshold"-times, before it will be actually set to - probing. - * partition (string, optional) - name of a DB partition, - otherwise the default one will be used - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -1.4.6. ds_count(set, state_filter, res_var, [partition]) - - Returns the number of active, inactive or probing destinations - in a partition's set, or combinations between these properties. - - Meaning of the parameters: - * set (int) - a set of dispatching destinations - * state_filter (string) - which destinations should be - counted. Either active ("a", "A" or "1"), inactive ("i", - "I" or "0"), probing ("p", "P" or "2") destinations or - different combinations between these flags, such as "pI", - "1i", "ipA"... - * res_var (variable) - a variable which will hold the integer - result - * partition (string, optional) - name of a DB partition. If - omitted, the "default" partition will be used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - Example 1.41. ds_count usage -... -if (ds_count(1, "a", $avp(result))) { - ... -} -... -if (ds_count($avp(set), "ip", $avp(result), $avp(partition))) { - ... -} -... - -1.4.7. ds_is_in_list(ip, port, [set], [partition], [active_only], -[pattern]) - - This function returns true only if "ip" and "port" point to a - host from the given dispatcher "set". - - Meaning of the parameters: - * ip (string) - an IPv4 or IPv6 address to test against the - dispatcher "set" - * port (int) - a port to test against the dispatcher list. - Use a 0 value in order to match any port - * set (int, optional) - a dispatcher set identifier to test - against. If missing, all sets will be checked. The -1 set - is a special value, acting as a "check all sets" wildcard. - * partition (string, optional) - name of a DB partition - * active_only (int, optional) - specify a non-zero value in - order to only search through the active destinations - (ignore the ones in probing and inactive states) - * pattern (string, optional) - a glob pattern used to match - destination attributes. If the destination ip and port - matches but the pattern does not match the destination's - attribute, the function will fail. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ONREPLY_ROUTE. - - Example 1.42. ds_is_in_list usage -... -if (ds_is_in_list($si, $sp)) { - # source IP:PORT is in a dispatcher list -} -... -if (ds_is_in_list($rd, $rp, 2)) { - # the R-URI (IP and port) is in the dispatcher set 2 of the "def -ault" partition -} -... -if (ds_is_in_list($rd, $rp, 2, "part2")) { - # the R-URI (IP and port) is in the dispatcher set 2 of the "par -t2" partition -} -... - -1.4.8. ds_push_script_attrs(script_attr, ip, port, set, [partition]) - - Set the script attrs for the dispatcher entry defined by IP, - Port, setid and partition. - - Meaning of the parameters: - * script_attr (str or pvar) - The new script attributes - * IP (string) - IP address for which we are pushing script - attributes - * port (int) Port for which we are pushing script attributes - * setid (int) Setid for which we are pushing script - attributes - * partition (string, optional) - name of a DB partition. If - omitted, the "default" partition will be used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - Example 1.43. ds_count usage -... -if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition -')) { - ... -} -... - -1.4.9. ds_get_script_attrs(uri, set, [partition], out_attrs) - - Get the script attrs for the dispatcher entry defined by the - URI, setid and partition. - - Meaning of the parameters: - * URI (string) - URI address for which we are getting script - attributes - * setid (int) Setid for which we are pushing script - attributes - * partition (string, optional) - name of a DB partition. If - omitted, the "default" partition will be used. - * out_atrs (pvar) - name of a variable where we will store - the script attrs. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - Example 1.44. ds_count usage -... -if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition -')) { - ... -} -... - -1.5. Exported MI Functions - -1.5.1. ds_set_state - - Sets the status for a destination address (can be use to mark - the destination as active or inactive). - - Name: ds_set_state - - Parameters: - * state : state of the destination address - + “a”: active - + “i”: inactive - + “p”: probing - * group: partition name followed by colon and destination - group id. If the partition name is omitted, the default - partition will be used - * address: address of the destination in the group - - MI FIFO Command Format: -opensips-cli -x mi ds_set_state a 2 sip:10.0.0.202 - -1.5.2. ds_list - - It lists the groups and included destinations of all the - partitions. - - Name: ds_list - - Parameters: - * full (optional) - adds the weight, priority and description - fields to the listing - * partition (optional) - return only destinations and sets in - the provided partition. - - MI FIFO Command Format: -opensips-cli -x mi ds_list - -1.5.3. ds_reload - - It reloads the groups and included destinations for a specified - partition or all partitions. - - Name: ds_reload - - Parameters: - * partition (optional) - name of the partition to be - reloaded. default partition is "default". - * inherit_state (optional) : whether inherit old state of the - destination , default is y. - + “n”: no inherit state - + “y”: inherit state - - MI FIFO Command Format: -opensips-cli -x mi ds_reload -opensips-cli -x mi ds_reload inherit_state=n - -1.5.4. ds_push_script_attrs - - Pushes script attrs for the dispatcher entry defined by IP, - Port, setid, and optionally partition. - - Name: ds_push_script_attrs - - Parameters: - * attrs : new attributes to be pushed - * ip: IP for which we are pushing script attributes - * port: Port for which we are pushing script attributes - * setid: Setid for which we are pushing script attributes - * partition ( optional ): Partition for which we are pushing - script attributes - - MI FIFO Command Format: -#opensips-cli -x mi ds_push_script_attrs '{"ping":"30000","load":"50"}' -'192.168.0.107' 5091 1 main - -1.6. Exported Events - -1.6.1. E_DISPATCHER_STATUS - - This event is raised when the dispatcher module marks a - destination as activated or deactivated. - - Parameters: - * partition - the partition name of the destination. - * group - the group of the destination. - * address - the address of the destination. - * status - active if the destination gets activated or - inactive if the destination is detected unresponsive. - -1.7. Exported Status/Report Identifiers - - The module provides the "dispatcher" Status/Report group, where - each partition is defined as a separate SR identifier. - -1.7.1. [partition_name] - - The status of these identifiers reflects the readiness/status - of the cached data (if available or not when being loaded from - DB): - * -2 - no data at all (initial status) - * -1 - no data, initial loading in progress - * 1 - data loaded, partition ready - * 2 - data available, a reload in progress - - Reload reporting: - - In terms of date reloading, the following events will be - reported: - * starting DB data loading - * DB data loading failed, discarding - * DB data loading successfully completed - * N destination loaded (N discarded) - - { - "Name": "default", - "Reports": [ - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "2 destinations loaded (0 discarded)" - } - ] - } - - -1.7.2. [partition_name];events - - Destination switching reporting: - - For reporting events related to the state changes of the - destinations, the module provides separate identifiers (still - one per partition). Why separate ones? The reports on state - changing may be verbose and there is the risk of loose/discard - important reports on reloads due to the high number of logs on - state changes; - - So, each partition will provide the identified - "partition_name;events" for reporting state changes of - destinations, along with the reason of the change. This - identifiers have a 200 records history before discarding the - old ones. - { - "Name": "default;events", - "Reports": [ - { - "Timestamp": 1652373308, - "Date": "Thu May 12 19:35:08 2022", - "Log": "DESTINATION , set 1 switched -to [inactive] due to negative probing reply\n" - }, - { - "Timestamp": 1652373308, - "Date": "Thu May 12 19:35:08 2022", - "Log": "DESTINATION , set 1 switched -to [inactive] due to negative probing reply\n" - } - ] - }, - - - For how to access and use the Status/Report information, please - see - https://www.opensips.org/Documentation/Interface-StatusReport-3 - -3. - -1.8. Installation and Running - -1.8.1. OpenSIPS config file - - Next picture displays a sample usage of dispatcher. - - Example 1.45. OpenSIPS config script - sample dispatcher usage -... -# -# sample config file for dispatcher module -# - -socket= udp:*:5060 - -udp_workers = 2 -check_via = off # (cmd. line: -v) -dns = off # (cmd. line: -r) -rev_dns = off # (cmd. line: -R) - -# for more info: opensips -h - -# ------------------ module loading ---------------------------------- -mpath = "/usr/lib/x86_64-linux-gnu/opensips/modules" - -loadmodule "maxfwd.so" -loadmodule "signaling.so" -loadmodule "sl.so" -loadmodule "tm.so" -loadmodule "db_mysql.so" -loadmodule "dispatcher.so" - -loadmodule "proto_udp.so" - -# ----------------- setting module-specific parameters --------------- -modparam("dispatcher", "db_url", "mysql://opensips:opensipsrw@localhost/ -opensips") - -route { - if (!mf_process_maxfwd_header(10)) { - send_reply(483, "Too Many Hops"); - exit; - } - - if (!ds_select_dst(2, 0)) { - send_reply(503, "Service Unavailable"); - exit; - } - - t_relay(); -} - -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - Does dispatcher provide a fair distribution? - - There is no guarantee of that. You should do some measurements - to decide what distribution algorithm fits better in your - environment. - - 2.2. - - Is dispatcher dialog stateful? - - No. Dispatcher is stateless, although some distribution - algorithms are designed to select same destination for - subsequent requests of the same dialog (e.g., hashing the - call-id). - - 2.3. - - What happened with the ds_is_from_list() function? - - The function was replaced by the more generic ds_is_in_list() - function that takes as parameters the IP and PORT to test - against the dispatcher list. - - ds_is_from_list() == ds_is_in_list("$si", "$sp") - - 2.4. - - How is weight and priority used by the dispatcher in selecting - a destination? - - The weight of a destination is currently used in the hashing - algorithms and it increases the probability of it to be - chosen(if we have two destinations with weights 1 respectively - 4 than the second one is 4 times more likely to be selected - than the other). The sum of all weights does not need to add up - to a specific number. Weights are now used in the round-robin - algorithm, a destination is chosen a number of times equal to - its weight consecutively before going to the next destination. - - The priority field is used at ordering the destinations from a - set. It does not affect the overall probability of a - destination to be chosen. It is reflected when listing the - destination, the field can definetly be used in further - selecting algorithms. - - 2.5. - - What happened with the list_file module parameter ? - - The support for text file (for provisioning destinations) was - dropped. Only the DB support (provisioning via a DB table) is - now available - if you still want to use a text file for - provisioning, use db_text DB driver (DB emulated via text - files) - - 2.6. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.7. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable version should be sent to - and e-mail regarding development - versions or SVN snapshots should be send to - . - - If you want to keep the mail private, send it to - . - - 2.8. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 172 109 3360 2030 - 2. Liviu Chircu (@liviuchircu) 111 72 1711 1441 - 3. Daniel-Constantin Mierla (@miconda) 82 39 3372 844 - 4. Andrei Datcu (@andrei-datcu) 48 15 2153 846 - 5. Razvan Crainea (@razvancrainea) 46 37 602 175 - 6. Ionut Ionita (@ionutrazvanionita) 43 17 1145 969 - 7. Ovidiu Sas (@ovidiusas) 31 17 705 434 - 8. Vlad Patrascu (@rvlad-patrascu) 19 11 378 236 - 9. Vlad Paiu (@vladpaiu) 17 10 681 33 - 10. Henning Westerholt (@henningw) 11 7 93 125 - - All remaining contributors: Carsten Bock, Ionel Cerghit - (@ionel-cerghit), Elena-Ramona Modroiu, Maksym Sobolyev - (@sobomax), John Burke (@john08burke), Norman Brandinger - (@NormB), Klaus Darilion, Anca Vamanu, Jarrod Baumann - (@jarrodb), wangdd, Walter Doekes (@wdoekes), Nick Altmann - (@nikbyte), Jan Janak (@janakj), Andrei Pelinescu-Onciul, Peter - Lemenkov (@lemenkov), Stanislaw Pitucha, Babak Yakhchali, - Federico Cabiddu, Konstantin Bokarius, Alexandra Titoc, Andreas - Granig, John Riordan, Aron Podrigal (@ar45), Julián Moreno - Patiño, Kevin McAllister, Roman Sevko, UnixDev, David Sanders, - Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - Jun 2025 - 2. Liviu Chircu (@liviuchircu) Aug 2012 - May 2025 - 3. Babak Yakhchali Feb 2025 - Feb 2025 - 4. Norman Brandinger (@NormB) Nov 2024 - Nov 2024 - 5. Alexandra Titoc Sep 2024 - Sep 2024 - 6. Vlad Paiu (@vladpaiu) Mar 2012 - Dec 2023 - 7. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 8. Razvan Crainea (@razvancrainea) May 2011 - Nov 2023 - 9. wangdd Apr 2023 - May 2023 - 10. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2022 - - All remaining contributors: John Burke (@john08burke), Peter - Lemenkov (@lemenkov), Roman Sevko, Nick Altmann (@nikbyte), - Ionel Cerghit (@ionel-cerghit), Ionut Ionita - (@ionutrazvanionita), Julián Moreno Patiño, Jarrod Baumann - (@jarrodb), Ovidiu Sas (@ovidiusas), David Sanders, Aron - Podrigal (@ar45), Andrei Datcu (@andrei-datcu), Walter Doekes - (@wdoekes), Stanislaw Pitucha, Anca Vamanu, John Riordan, - UnixDev, Kevin McAllister, Klaus Darilion, Carsten Bock, - Daniel-Constantin Mierla (@miconda), Henning Westerholt - (@henningw), Konstantin Bokarius, Edson Gellert Schubert, - Federico Cabiddu, Elena-Ramona Modroiu, Andreas Granig, Andrei - Pelinescu-Onciul, Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu - (@vladpaiu), Razvan Crainea (@razvancrainea), wangdd, Vlad - Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu - (@bogdan-iancu), John Burke (@john08burke), Roman Sevko, Peter - Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Ionel Cerghit - (@ionel-cerghit), Jarrod Baumann (@jarrodb), Ovidiu Sas - (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Andrei Datcu - (@andrei-datcu), Walter Doekes (@wdoekes), Stanislaw Pitucha, - Anca Vamanu, Klaus Darilion, Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Carsten Bock, Edson Gellert - Schubert, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2005-2010 Voice Sistem SRL - - Copyright © 2004 FhG FOKUS diff --git a/modules/dispatcher/README.md b/modules/dispatcher/README.md new file mode 100644 index 00000000000..efe50573924 --- /dev/null +++ b/modules/dispatcher/README.md @@ -0,0 +1,1618 @@ +--- +title: "dispatcher Module" +description: "This modules implements a dispatcher for destination addresses." +--- + +## Admin Guide + + +### Overview + + +This modules implements a dispatcher for destination addresses. It +computes hashes over various parts of the request and selects an +address from a destination set. The selected address may then either +overwrite the R-URI of a SIP request or be used as an outbound proxy. + + +The module can be used as a stateless load balancer, having no +guarantee of fair distribution. + + +For the distribution algorithm, the module allows the definition of +weights for the destination. This is useful in order to get a different +ratio of traffic between destinations. + + +Starting with version 2.1, the dispatcher module keeps its destination sets +into different partitions. Each partition is described by its own +"db_url", "table_name", "dst_avp", "grp_avp", "cnt_avp", "sock_avp", +"attr_avp", "blacklists", "ping_from", "ping_method" and +"persistent_state" set of attributes. Setting any of these +module parameters will only alter the "default" partition's properties. + + +In order to create a new partition, the [partition](#param_partition) +parameter can be used. If none of the 8 partition specific parameters +are defined for the "default" partition, then this partition will not +be created. Once the "default" partition is created, any undefined +parameter from other partitions will inherit the value of the +corresponding parameter of the "default" partition. If there is no +"default" partition, the default value specified in the parameter's +description will be used. Finally, note that each dispatcher table +specified using the "table_name" partition attribute requires a +corresponding "version" table record within the partition's database, +specified through "db_url". + + +Since version 2.1, the "flags" parameter has been moved to +ds_select_dst() and ds_select_domain() along with "force_dst" and +"use_default" flags. + + +### Dependencies + + +#### OpenSIPS modules + + +The following modules must be loaded before this module: + + +- *TM - only if active recovery of failed hosts is required*. +- *clusterer* - only if "cluster_id" +option is enabled. +- *database* - one of the DB SQL modules +- *freeswitch - only if "fetch_freeswitch_stats" is enabled.*. + + +#### External libraries or applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module: + + +- *none*. + + +### Exported Parameters + + +#### db_url (string) + + +The default DB connection of the module, overriding the global +'db_default_url' setting. Once specified, partitions which are missing +the 'db_url' property will inherit their URL from this value. + + +*Default value is "NULL".* + + +```opensips title="Setting the default database URL for dispatcher" +... +modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database") +... +``` + + +#### attrs_avp (str) + + +The name of the avp to contain the attributes string of the current +destination. When a destination is selected, automatically, this AVP +will provide the attributes string - this is an opaque string (from +OpenSIPS point of view) : it is loaded from destination definition ( +via DB) and blindly provided in the script. +Setting this parameter will only change the default partition's +attrs_avp. Use the partition parameter to create and alter +other partitions. + + +*Default value is "null" - don't provide ATTRIBUTEs.* + + +```opensips title="Set the 'default' partition's 'attrs_avp' parameter" +... +modparam("dispatcher", "attrs_avp", "$avp(272)") +... +``` + + +#### script_attrs_avp (str) + + +Name of the avp to contain the script attributes string of the current +destination. When a destination is selected, automatically, this AVP +will provide the attributes string - this is an opaque string (from +OpenSIPS point of view) : it is provided via the ds_push_script_attrs +MI or SCRIPT function. + + +*Default value is "null" - don't provide SCRIPT ATTRIBUTEs.* + + +```opensips title="Set the 'default' partition's 'script_attrs_avp' parameter" +... +modparam("dispatcher", "attrs_avp", "$avp(script_attrs)") +... +``` + + +#### algo_route (str) + + +Name of the route to be called when using algo 10. +The route will get as param the dst_uri, attrs and script_attrs for the +dispatcher entry that currently needs to be evaluated ( available via +$param(1), $param(2) and $param(3) or via $param(dst_uri), $param(attrs) and $param(script_attrs) when the route gets called ). +The return value of the route is considered by the dispatcher module to +be the current weight of the dispatcher entry, and when using the 10 +algo, the dispatcher entries are sorted in ascending weight order. + +If the returned value from the algo route is negative, the current dispatcher entry will be automatically skipped from usage + + +*Default value is "null" - disabled.* + + +```opensips title="Use algo_route for hashing:" +... +modparam("dispatcher", "algo_route", "my_dispatcher_logic)") +... +route[my_dispatcher_logic] { + $var(curent_score) = 0; + xlog("DISPATCHER - Running logic for $param(dst_uri) with attrs $param(attrs) and script attrs $param(script_attrs) \n"); + + # decide to penalize current dispatcher entry, based on your logic + if (my_condition_here) + $var(current_score) = $var(current_score) + 10; + + return $var(rc); +} +``` + + +#### hash_pvar (str) + + +String with PVs used for the hashing algorithm 7. + + +> [!NOTE] +> You must set this parameter if you want do hashing over custom message +parts. + + +*Default value is "null" - disabled.* + + +```opensips title="Use $avp(273) for hashing:" +... +modparam("dispatcher", "hash_pvar", "$avp(273)") +... +``` + + +```opensips title="Use combination of PVs for hashing:" +... +modparam("dispatcher", "hash_pvar", "hash the $fU@$ci") +... +``` + + +#### setid_pvar (str) + + +The name of the PV where to store the set ID (group ID) when calling +ds_is_in_list() without group parameter (third parameter). + + +*Default value is "null" - don't set PV.* + + +```opensips title="Set the 'setid_pvar' parameter" +... +modparam("dispatcher", "setid_pvar", "$var(setid)") +... +``` + + +#### ds_ping_method (string) + + +With this Method you can define, with which method you want to probe +the failed gateways. This method is only available, if compiled with +the probing of failed gateways enabled. + + +Use the 'partition' parameter if you want to define the ping method +other partitions. + + +*Default value is "OPTIONS".* + + +```opensips title="Set the 'ds_ping_method' parameter" +... +modparam("dispatcher", "ds_ping_method", "INFO") +... +``` + + +#### ds_ping_from (string) + + +With this Method you can define the "From:"-Line for the request, +sent to the failed gateways. This method is only available, if +compiled with the probing of failed gateways enabled. + + +Use the 'partition' parameter if you want to define the "From:" +ping header of other partitions. + + +*Default value is "sip:dispatcher@localhost".* + + +```opensips title="Set the 'ds_ping_from' parameter" +... +modparam("dispatcher", "ds_ping_from", "sip:proxy@sip.somehost.com") +... +``` + + +#### ds_ping_interval (int) + + +With this Method you can define the interval for sending a request to +a failed gateway. This parameter is only used, when the TM-Module is +loaded. If set to "0", the pinging of failed requests +is disabled. + + +*Default value is "0" (disabled).* + + +```opensips title="Set the 'ds_ping_interval' parameter" +... +modparam("dispatcher", "ds_ping_interval", 30) +... +``` + + +#### ds_ping_maxfwd (int) + + +This parameter allows you to enforce a specific Max-Forward value +for the SIP pinging requests generated by the Dispatcher modules. +If not explicitly set, no value will be enforced and it let the +Transaction Layer (TM module) to set a default Max-Forward value. + + +The accepted values are any positive integer values, including the +"0" value. + + +```opensips title="Set the 'ds_ping_maxfwd' parameter" +... +modparam("dispatcher", "ds_ping_maxfwd", 2) +... +``` + + +#### ds_probing_sock (str) + + +A socket description [proto:]host[:port] of the local socket (which +is used by OpenSIPS for SIP traffic) to be used (if multiple) for +sending the probing messages from. + + +*Default value is "NULL(none)".* + + +```opensips title="Set the 'ds_probing_sock' parameter" +... +modparam("dispatcher", "ds_probing_sock", "udp:192.168.1.100:5077") +... +``` + + +#### ds_probing_threshold (int) + + +If you want to set a gateway into probing mode, you will need a +specific number of requests until it will change from "active" to +probing. The number of attempts can be set with this parameter. + + +*Default value is "3".* + + +```opensips title="Set the 'ds_probing_threshold' parameter" +... +modparam("dispatcher", "ds_probing_threshold", 10) +... +``` + + +#### ds_probing_mode (int) + + +Controls what gateways are tested to see if they are reachable. If set +to 0, only the gateways with state PROBING are tested, if set to 1, all +gateways are tested. If set to 1 and the response is 408 (timeout), +an active gateway is set to PROBING state. + + +*Default value is "0".* + + +```opensips title="Set the 'ds_probing_mode' parameter" +... +modparam("dispatcher", "ds_probing_mode", 1) +... +``` + + +#### ds_probing_list (str) + + +Defines a list of one or more setids that limits which +destinations are probed if probing is active. This is useful +when multiple proxies share the same dispatcher table, but you +want to limit which ones are responsible for probing specific +destinations. + + +*Default value is "NULL (probe all sets)".* + + +```opensips title="Set the 'ds_probing_list' parameter" +... +modparam("dispatcher", "ds_probing_list", "1,2,3") +... +``` + + +#### ds_define_blacklist (str) + + +Defines a blacklist based on a dispatching setid from the 'default' +partition. +This list will contain the IPs (no port, all protocols) of the +destinations matching the given setid. +Use the 'partition' parameter if you want to define blacklists +based on other partitions' sets. + + +Multiple instances of this param are allowed. + + +*Default value is "NULL".* + + +```opensips title="Set the 'default' partition's 'ds_define_blacklist' parameter" +... +modparam("dispatcher", "ds_define_blacklist", "list= 1,4,3") +modparam("dispatcher", "ds_define_blacklist", "blist2= 2,10,6") +... +``` + + +#### options_reply_codes (str) + + +This parameter must contain a list of SIP reply codes separated by +comma. The codes defined here will be considered as valid reply codes +for OPTIONS messages used for pinging, apart for 200. + + +*Default value is "NULL".* + + +```opensips title="Set the 'options_reply_codes' parameter" +... +modparam("dispatcher", "options_reply_codes", "501, 403") +... +``` + + +#### dst_avp (str) + + +This is mainly for internal usage and represents the name of the avp +which will hold the list with addresses, in the order +they have been selected by the chosen algorithm. If use_default is 1, +the value of last dst_avp_id is the last address in destination set. The +first dst_avp_id is the selected destinations. All the other addresses +from the destination set will be added in the avp list to be able to +implement serial forking. +Setting this parameter will only change the default partition's +dst_avp. Use the partition parameter to create and alter +other partitions. + + +*For the 'default' partition the default value +is "$avp(ds_dst_failover)". For any other partition, +the default value is "$avp(ds_dst_failover_partitionname)".* + + +```opensips title="Set the 'default' partition's 'dst_avp' parameter" +... +modparam("dispatcher", "dst_avp", "$avp(271)") +... +``` + + +#### grp_avp (str) + + +This is mainly for internal usage and represents the name of the avp +storing the group id of the destination set. Good +to have it for later usage or checks. +Setting this parameter will only change the default partition's +grp_avp. Use the partition parameter to create and alter +other partitions. + + +*For the 'default' partition the default value +is "$avp(ds_grp_failover)". For any other partition, +the default value is "$avp(ds_grp_failover_partitionname)".* + + +```opensips title="Set the 'default' partition's 'grp_avp' parameter" +... +modparam("dispatcher", "grp_avp", "$avp(273)") +... +``` + + +#### cnt_avp (str) + + +This is mainly for internal usage and represents the name of the avp +storing the number of destination addresses kept in dst_avp avps. +Setting this parameter will only change the default partition's +cnt_avp. Use the partition parameter to create and alter +other partitions. + + +*For the 'default' partition the default value +is "$avp(ds_cnt_failover)". For any other partition, +the default value is "$avp(ds_cnt_failover_partitionname)".* + + +```opensips title="Set the 'default' partition's 'cnt_avp' parameter" +... +modparam("dispatcher", "cnt_avp", "$avp(274)") +... +``` + + +#### sock_avp (str) + + +This is mainly for internal usage and represents the name of the avp +storing the sockets to be used for the destination addresses kept in +dst_avp avps. +Setting this parameter will only change the default partition's +sock_avp. Use the partition parameter to create and alter +other partitions. + + +*For the 'default' partition the default value +is "$avp(ds_sock_failover)". For any other partition, +the default value is "$avp(ds_sock_failover_partitionname)".* + + +```opensips title="Set the 'default' partition's 'sock_avp' parameter" +... +modparam("dispatcher", "sock_avp", "$avp(275)") +... +``` + + +#### pvar_algo_pattern (str) + + +This parameter is used by the PVAR(9) algorithm to specify the +pseudovariable pattern used to detect the load of each destination. The +name of the pseudovariable should contain the string "%u", +which will be internally replaced by the module with the uri of the +destination. The string "%i" can also be used and will be +replaced with the set ID of the destination (useful in cases where same +uri exists in multiple sets). + + +*Default value is "none".* + + +```opensips title="Set the 'pvar_algo_pattern' parameter" +... +modparam("dispatcher", "pvar_algo_pattern", "$stat(load_%u)") +... +``` + + +#### persistent_state (int) + + +Specifies whether the *state* column +should be loaded at startup and flushed during runtime or not +for the "default" partition. + + +Use the 'partition' parameter if you want to define the persistent +state of other partitions. + + +*Default value is "1" (enabled).* + + +```opensips title="Set the persistent_state parameter" +... +# disable all DB operations with the state of a destination +modparam("dispatcher", "persistent_state", 0) +... +``` + + +#### cluster_id (integer) + + +The ID of the cluster the module is part of. The clustering support is +used in dispatcher module for two purposes: for sharing the status +of the destinations and for controlling the pinging to destinations. + + +If clustering enbled, the module will automatically share changes +over the status of the destinations with the other +OpenSIPS instances that are part of a cluster. Whenever such a status +changes (following an MI command, a probing result, a script command), +the module will replicate this status change to all the nodes in this +given cluster. + + +The clustering with sharing tag support may be used to control which +node in the cluster will perform the pinging/probing to +destinations. See the +[cluster sharing tag](#param_cluster_sharing_tag) option. + + +This OpenSIPS cluster exposes the **"dispatcher-status-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +For more info on how to define and populate a cluster (with OpenSIPS +nodes) see the [clusterer](../clusterer) module. + + +*Default value is "0 (none)".* + + +```opensips title="Set cluster_id parameter" +... +# replicate destination status with all OpenSIPS in cluster ID 9 +modparam("dispatcher", "cluster_id", 9) +... +``` + + +#### cluster_sharing_tag (string) + + +The name of the sharing tag (as defined per clusterer modules) to +control which node is responsible for perform the self-triggered +actions in the module. Such actions may be the destination probing +(see also the [cluster probing mode](#param_cluster_probing_mode) parameter) +or sharing the changes in the destination status. +If defined, only the node with active status of this tag will +perform the actions (pinging and sharing status). + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +This is an optional parameter. If not set, all the nodes in the cluster +will share the status changes. + + +*Default value is "empty (none)".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +# and broadcast the status changes +modparam("dispatcher", "cluster_id", 9) +modparam("dispatcher", "cluster_sharing_tag", "vip") +... +``` + + +#### cluster_probing_mode (string) + + +This paramter controls how the probing/pinging should be done when +using the clustering support. It is about which node in the cluster +pings which gateway/destination. + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +The supported probing modes are: + + +- **"all"** - all the nodes in the +cluster will independetly ping all the defined destinations, +an "all" pings "all" mode. +- **"by-shtag"** - all the destinations +are pinged by only one node in the cluster, the node having the +[cluster sharing tag](#param_cluster_sharing_tag) active. By +activating the sharing tag on a different node, the pinging +duty will be transfered to another node in the cluster. +- **"distributed"** - the pinging +effort is distributed across all the nodes in the cluster, so each +node will ping a sub-set of the overall set of destinations. Still +all the destinations will get pinged (and only once per pinging +cycle). +The re-partitioning of the pinging effort over the available nodes +in the cluster is automatically done when new nodes are joining or +nodes are dropping out. Still there is no guaratee on which node +will be responsible for pinging which destination. + + +*Default value is ""all"".* + + +```opensips title="Set cluster_probing_mode parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +modparam("dispatcher", "cluster_id", 9) +modparam("dispatcher", "cluster_sharing_tag", "vip") +modparam("dispatcher", "cluster_probing_mode", "by-shtag") +... +# the pinging effort is distributed across all the nodes +modparam("dispatcher", "cluster_id", 9) +modparam("dispatcher", "cluster_probing_mode", "distributed") +... +``` + + +#### partition (string) + + +Define a new partition (data source) with the following properties: +"db_url", "table_name", "dst_avp", "grp_avp", "cnt_avp", "sock_avp", +"attrs_avp", "script_attrs", "ds_define_blacklist". All these +properties are optional, having appropriate default values. + + +The syntax is: "partition_name: param1 = value1; param2 = value2". +Each value format is the same as the one used to define a specific +parameter using modparam. + + +This parameter may be set multiple times, thus defining as many +partitions as needed. The 'default' partition may also be defined +using this parameter. + + +```opensips title="Define a new partition called 'voicemail'" +... +modparam("dispatcher", "partition", + "voicemail: + db_url = mysql://user:passwd@localhost/database; + table_name = dispatcher; + attrs_avp = $avp(ds_attr_vm); + ds_define_blacklist = list2 = 4,6") +... +``` + + +```opensips title="Define the 'trunks' partition and make it the 'default' partition, so we avoid loading the 'dispatcher' table" +... +modparam("dispatcher", "partition", + "trunks: + db_url = mysql://user:passwd@localhost/database; + table_name = dispatcher_trunks; + attrs_avp = $avp(ds_attr_trunks)") +modparam("dispatcher", "partition", "default: trunks") +... +``` + + +#### table_name (string) + + +The default name of the table from which to load dispatcher +destinations. Partitions which are missing the 'table_name' property +will inherit their table name from this value. + + +*Default value is "dispatcher".* + + +```opensips title="Set the default table name" +... +modparam("dispatcher", "table_name", "my_dispatcher") +... +``` + + +#### setid_col (string) + + +The column's name in the database storing the gateway's group id. + + +*Default value is "setid".* + + +```opensips title="Set 'setid_col' parameter" +... +modparam("dispatcher", "setid_col", "groupid") +... +``` + + +#### destination_col (string) + + +The column's name in the database storing the destination's +sip uri. + + +*Default value is "destination".* + + +```opensips title="Set 'destination_col' parameter" +... +modparam("dispatcher", "destination_col", "uri") +... +``` + + +#### state_col (string) + + +The column's name in the database storing the state of the +destination uri. + + +*Default value is "state".* + + +```opensips title="Set 'state_col' parameter" +... +modparam("dispatcher", "state_col", "dststate") +... +``` + + +#### weight_col (string) + + +The column's name in the database storing the weight for +destination uri. + + +*Default value is "weight".* + + +```opensips title="Set 'weight_col' parameter" +... +modparam("dispatcher", "weight_col", "dstweight") +... +``` + + +#### priority_col (string) + + +The column's name in the database storing the priority for +destination uri. + + +*Default value is "priority".* + + +```opensips title="Set 'priority_col' parameter" +... +modparam("dispatcher", "priority_col", "dstprio") +... +``` + + +#### attrs_col (string) + + +The column's name in the database storing the attributes (opaque +string) for destination uri. + + +*Default value is "attrs".* + + +```opensips title="Set 'attrs_col' parameter" +... +modparam("dispatcher", "attrs_col", "dstattrs") +... +``` + + +#### socket_col (string) + + +The column's name in the database storing the socket (as +string) for destination uri. + + +*Default value is "socket".* + + +```opensips title="Set 'socket_col' parameter" +... +modparam("dispatcher", "socket_col", "my_sock") +... +``` + + +#### probe_mode_col (string) + + +The column's name in the database storing the probe_mode (as +string) for destination. + + +*Default value is "probe_mode".* + + +```opensips title="Set 'probe_mode_col' parameter" +... +modparam("dispatcher", "probe_mode_col", "probing") +... +``` + + +#### fetch_freeswitch_stats (integer) + + +If enabled, FreeSWITCH destinations may have dynamic dispatching weights, +refreshed at runtime, using the FreeSWITCH Event Socket Layer. +For these destinations, an Event Socket Layer URL must be provisioned +into the "weight" column, instead of an integer string. Some example values: +*"fs://:password@freeswitch.example.com"* +or *"fs://user:password@127.0.0.1:8021"*. +The default ESL port is 8021. + + +OpenSIPS will establish a connection with the given socket and +periodically calculate/update the weights of these destinations +using statistics pushed by the FreeSWITCH box. + + +The value for an automatically calculated weight ranges between +**0 - 100**. +This is helpful when grouping normal destinations with +FreeSWITCH ones. + + +The dynamic weights are recalculated every +*event_heartbeat_interval* seconds (see the +"freeswitch" OpenSIPS module for more details regarding this setting), +as the stats from FreeSWITCH are expected to arrive. The update formula +is shown below (FreeSWITCH stats are highlighted in bold): + + +*weight = 100 * (**Idle-CPU** / 100) * (1 - **Session-Count** / **Max-Sessions**)* + + +*Default value is **0** (disabled).* + + +```opensips title="Set the fetch_freeswitch_load parameter" +... +modparam("dispatcher", "fetch_freeswitch_stats", 1) +... +``` + + +#### max_freeswitch_weight (integer) + + +The maximum weight of a FreeSWITCH ESL-enabled destination. This value +is also used during startup/reload, when no stats from FreeSWITCH are +available yet. + + +Important: When mixing normal destinations with FreeSWITCH-enabled ones in +the same dispatching set, OpenSIPS will truncate any weight values that +are larger than **max_freeswitch_weight** +to the value of this parameter! + + +NOTE: OpenSIPS internally rounds weights to nearest integer, so larger +max weight values will more accurately represent the current load on the +FreeSWITCH boxes! For example, if you set this parameter to 1, the box +will receive no traffic whenever either its CPU or session usage goes +past 50%! + + +*Default value is **100**.* + + +```opensips title="Set the max_freeswitch_weight parameter" +... +modparam("dispatcher", "max_freeswitch_weight", 1000) +... +``` + + +### Exported Functions + + +#### ds_select_dst(set, alg, [flags], [partition], [max_res]) + + +The method selects a destination from the given set of addresses. It will +overwrite the destination URI (*$du*) of a SIP request. + + +Meaning of the parameters is as follows: + + +- *set (int)* - a set identifier from which to select destinations +- *alg (int)* - the algorithm used to select the +destination address + + - "0" - hash over callid + - "1" - hash over from uri. + - "2" - hash over to uri. + - "3" - hash over request-uri. + - "4" - weighted round-robin (next destination). +the destination's weight determines how many times it is chosen +before going to the next one + - "5" - hash over authorization-username +(Proxy-Authorization or "normal" authorization). +If no username is found, weighted round-robin is used. + - "6" - random (using rand()). + - "7" - hash over the content of PVs string. +Note: This works only when the parameter hash_pvar is set. + - "8" - the first entry in set is chosen. + - "9" - The *pvar_algo_pattern* +parameter is used to determine the load on each server. If the +parameter is not specified, then the first entry in the set is +chosen. + - "10" - The *algo_route* +OpenSIPS route is called for each dispatcher entry in +the setid, in order to decide the routing order. +See the algo_route parameter for usage examples + - "X" - if the algorithm is not implemented, the +first entry in set is chosen. +- *flags (string, optional)* - a string of flag-settings +which tweak the function's behavior: + + - 'f' (failover support): causes the remaining +addresses from the destination set to be stored within an +internally managed AVP. You may then use +[ds next dst](#func_ds_next_dst) to switch to the next +address, thus achieving serial forking to all possible destinations + - 'u' (user only): will specify that only the URI user part +will be used for hashing + - 'd' (use default): use the last address in destination +set as last option to send the message + - 'a' (append destinations): append any new destinations to +the current destination list, rather than rewriting the list +The flags are being kept per partition. +- *partition (string, optional)* - name of a DB partition +- *max_res (int, optional)* - signifies that only a maximum +number of destinations shall be included in the specified failover AVP. +This allows having multiple destinations while +also preventing excessive failover attempts in case a number is +bound to fail globally. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. + + +```opensips title="ds_select_dst usage" +... +if (!ds_select_dst(1, 0)) { + xlog("ERROR: no active destinations found!\n"); + send_reply(503, "Service Unavailable"); + exit; +} +... +ds_select_dst(1, 0, , "fs_boxes", 5); +... +ds_select_dst(1, 0, "fUD", "ask_boxes"); +... +ds_select_dst(2, 0, "fud", "pstn_gws", 5); +ds_select_dst(3, 1, "fua", "pstn_gws", 2); +... +# using variables +$var(part) = "pstn_gws" +$var(setid) = 1; +$var(alg) = 4; +$var(flags) = "fdu"; +$var(max_res) = 2; +ds_select_dst($var(setid), $var(alg), $var(flags), $var(part), $var(max_res)); +... +``` + + +#### ds_select_domain(set, alg, [flags], [partition], [max_res]) + + +The method selects a destination from addresses set and rewrites the +hostname and port parts of the Request-URI (*$ru*). +Its parameters have same meaning as in [ds select dst](#func_ds_select_dst). + + +If the "f" (failover support) flag is present, the rest of the +addresses from the destination set will be stored in an internally +managed AVP. You may then use [ds next domain](#func_ds_next_domain) to +switch to the next address in the list, thus achieving serial forking +to all possible destinations. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. + + +#### ds_next_dst([partition]) + + +Takes the next destination address from the AVPs with id +partition.'dst_avp_id' and sets the dst_uri (outbound proxy address). +If "partition" is omitted, the default partition will be used.This +function is using the flags set in ds_select_dst or ds_select_domain. + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +#### ds_next_domain([partition]) + + +Takes the next destination address from the AVPs with id +partition.'dst_avp_id' and sets the domain part of the request uri. +If "partition" is omitted, the default partition will be used.This +function is using the flags set in ds_select_dst or ds_select_domain. + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +#### ds_mark_dst([state], [partition]) + + +Mark the last used address from partition's destination set as +inactive ("i"/"I"/"0"), active ("a"/"A"/"1") or probing ("p"/"P"/"2"). +With this function, an automatic detection of failed gateways can be implemented. +When an address is marked as inactive or probing, it will be ignored by +[ds select dst](#func_ds_select_dst) and [ds select domain](#func_ds_select_domain). +If "partition" is omitted, the default partition will be used. This function +is using the flags set in [ds select dst](#func_ds_select_dst) or +[ds select domain](#func_ds_select_domain). + + +Possible parameters: + + +- state (string, optional) - new state for the last attempted +destination. Possible values: + + - *"i", "I" or "0" (default)* - the last +destination should be set to inactive and will be ignored +in future requests. + - *"a", "A" or "1"* - the last +destination should be set to active. + - *"p", "P" or "2"* - the last +destination will be set to probing. Note: You will need to +call this function "threshold"-times, before it will be +actually set to probing. +- partition (string, optional) - name of a DB partition, +otherwise the default one will be used + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +#### ds_count(set, state_filter, res_var, [partition]) + + +Returns the number of active, inactive or probing destinations in a +partition's set, or combinations between these properties. + + +Meaning of the parameters: + + +- *set (int)* - a set of dispatching destinations +- *state_filter (string)* - which destinations should be +counted. Either active ("a", "A" or "1"), inactive +("i", "I" or "0"), probing ("p", "P" or "2") destinations or +different combinations between these flags, such as +"pI", "1i", "ipA"... +- *res_var (variable)* - a variable +which will hold the integer result +- *partition (string, optional)* - name of a +DB partition. If omitted, the "default" partition +will be used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, +LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE + + +```opensips title="ds_count usage" +... +if (ds_count(1, "a", $avp(result))) { + ... +} +... +if (ds_count($avp(set), "ip", $avp(result), $avp(partition))) { + ... +} +... +``` + + +#### ds_is_in_list(ip, port, [set], [partition], [active_only], [pattern]) + + +This function returns *true* only if "ip" and "port" point to a +host from the given dispatcher "set". + + +Meaning of the parameters: + + +- *ip (string)* - an IPv4 or IPv6 address to +test against the dispatcher "set" +- *port (int)* - a port to test against the +dispatcher list. Use a *0* value in order to +match any port +- *set (int, optional)* - a dispatcher set +identifier to test against. If missing, all sets will be checked. +The *-1* set is a special value, acting as a +"check all sets" wildcard. +- *partition (string, optional)* - name of +a DB partition +- *active_only (int, optional)* - specify +a non-zero value in order to only search through the active +destinations (ignore the ones in probing and inactive states) +- *pattern (string, optional)* - a glob +pattern used to match destination attributes. If the destination +ip and port matches but the pattern does not match the destination's +attribute, the function will fail. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and ONREPLY_ROUTE. + + +```opensips title="ds_is_in_list usage" +... +if (ds_is_in_list($si, $sp)) { + # source IP:PORT is in a dispatcher list +} +... +if (ds_is_in_list($rd, $rp, 2)) { + # the R-URI (IP and port) is in the dispatcher set 2 of the "default" partition +} +... +if (ds_is_in_list($rd, $rp, 2, "part2")) { + # the R-URI (IP and port) is in the dispatcher set 2 of the "part2" partition +} +... +``` + + +#### ds_push_script_attrs(script_attr, ip, port, set, [partition]) + + +Set the script attrs for the dispatcher entry defined by IP, Port, setid and partition. + + +Meaning of the parameters: + + +- *script_attr (str or pvar)* - The new script attributes +- *IP (string)* - +IP address for which we are pushing script attributes +- *port (int)* Port for which we are pushing script attributes +- *setid (int)* Setid for which we are pushing script attributes +- *partition (string, optional)* - name of a +DB partition. If omitted, the "default" partition +will be used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, +LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE + + +```opensips title="ds_count usage" +... +if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition')) { + ... +} +... +``` + + +#### ds_get_script_attrs(uri, set, [partition], out_attrs) + + +Get the script attrs for the dispatcher entry defined by the URI, setid and partition. + + +Meaning of the parameters: + + +- *URI (string)* - +URI address for which we are getting script attributes +- *setid (int)* Setid for which we are pushing script attributes +- *partition (string, optional)* - name of a +DB partition. If omitted, the "default" partition +will be used. +- *out_atrs (pvar)* - name of a +variable where we will store the script attrs. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, +LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE + + +```opensips title="ds_count usage" +... +if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition')) { + ... +} +... +``` + + +### Exported MI Functions + + +#### ds_set_state + + +Sets the status for a destination address (can be use to mark the destination +as active or inactive). + + +Name: *ds_set_state* + + +Parameters: + + +- *state* : state of the destination address + + - "a": active + - "i": inactive + - "p": probing +- *group*: partition name followed by colon +and destination group id. If the partition name is omitted, +the default partition will be used +- *address*: address of the destination in the group + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi ds_set_state a 2 sip:10.0.0.202 +``` + + +#### ds_list + + +It lists the groups and included destinations of all the partitions. + + +Name: *ds_list* + + +Parameters: + + +- *full* (optional) - adds the weight, +priority and description fields to the listing +- *partition* (optional) - return only +destinations and sets in the provided partition. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi ds_list +``` + + +#### ds_reload + + +It reloads the groups and included destinations for a +specified partition or all partitions. + + +Name: *ds_reload* + + +Parameters: + + +- *partition* (optional) - name of +the partition to be reloaded. default partition is "default". +- *inherit_state* (optional) : whether inherit old state of the destination , default is y. + + - "n": no inherit state + - "y": inherit state + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi ds_reload +opensips-cli -x mi ds_reload inherit_state=n +``` + + +#### ds_push_script_attrs + + +Pushes script attrs for the dispatcher entry defined by IP, Port, setid, and optionally partition. + + +Name: *ds_push_script_attrs* + + +Parameters: + + +- *attrs* : new attributes to be pushed +- *ip*: IP for which we are pushing script attributes +- *port*: Port for which we are pushing script attributes +- *setid*: Setid for which we are pushing script attributes +- *partition ( optional )*: Partition for which we are pushing script attributes + + +MI FIFO Command Format: + + +```bash +$opensips-cli -x mi ds_push_script_attrs '{"ping":"30000","load":"50"}' '192.168.0.107' 5091 1 main +``` + + +### Exported Events + + +#### E_DISPATCHER_STATUS + + +This event is raised when the dispatcher module marks a destination as +activated or deactivated. + + +Parameters: + + +- *partition* - the partition name of the destination. +- *group* - the group of the destination. +- *address* - the address of the destination. +- *status* - *active* if +the destination gets activated or *inactive* if the +destination is detected unresponsive. + + +### Exported Status/Report Identifiers + + +The module provides the "dispatcher" Status/Report group, where each +partition is defined as a separate SR identifier. + + +#### [partition_name] + + +The status of these identifiers reflects the readiness/status of the +cached data (if available or not when being loaded from DB): + + +- *-2* - no data at all (initial status) +- *-1* - no data, initial loading in progress +- *1* - data loaded, partition ready +- *2* - data available, a reload in progress + + +Reload reporting: + + +In terms of date reloading, the following events will be reported: + + +- starting DB data loading +- DB data loading failed, discarding +- DB data loading successfully completed +- N destination loaded (N discarded) + + +```json +{ + "Name": "default", + "Reports": [ + { + "Timestamp": 1652373212, + "Date": "Thu May 12 19:33:32 2022", + "Log": "starting DB data loading" + }, + { + "Timestamp": 1652373212, + "Date": "Thu May 12 19:33:32 2022", + "Log": "DB data loading successfully completed" + }, + { + "Timestamp": 1652373212, + "Date": "Thu May 12 19:33:32 2022", + "Log": "2 destinations loaded (0 discarded)" + } + ] +} +``` + + +#### [partition_name];events + + +Destination switching reporting: + + +For reporting events related to the state changes of the +destinations, the module provides separate identifiers (still +one per partition). +Why separate ones? The reports on state changing may be verbose and there +is the risk of loose/discard important reports on reloads due to the high +number of logs on state changes; + + +So, each partition will provide the identified "partition_name;events" for +reporting state changes of destinations, along with the reason +of the change. This identifiers have a 200 records history before +discarding the old ones. + + +```json +{ + "Name": "default;events", + "Reports": [ + { + "Timestamp": 1652373308, + "Date": "Thu May 12 19:35:08 2022", + "Log": "DESTINATION , set 1 switched to [inactive] due to negative probing reply\n" + }, + { + "Timestamp": 1652373308, + "Date": "Thu May 12 19:35:08 2022", + "Log": "DESTINATION , set 1 switched to [inactive] due to negative probing reply\n" + } + ] +}, +``` + + +For how to access and use the Status/Report information, please see +[Status/Report Interface documentation](https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +## Samples + +[samples](./samples/samples.md "include") + + +## Frequently Asked Questions + + +**Q: Does *dispatcher* provide a fair distribution?** + + +There is no guarantee of that. You should do some measurements +to decide what distribution algorithm fits better in your +environment. + + +**Q: Is *dispatcher* dialog stateful?** + + +No. Dispatcher is stateless, although some distribution algorithms +are designed to select same destination for subsequent requests of +the same dialog (e.g., hashing the call-id). + + +**Q: What happened with the *ds_is_from_list()* +function?** + + +The function was replaced by the more generic +*ds_is_in_list()* function that takes as +parameters the IP and PORT to test against the dispatcher list. + +ds_is_from_list() == ds_is_in_list("$si", "$sp") + + +**Q: How is weight and priority used by the dispatcher in selecting +a destination?** + + +The *weight* of a destination is currently used in +the hashing algorithms and it increases the probability of it to be +chosen(if we have two destinations with weights 1 respectively +4 than the second one is 4 times more likely to be selected than the +other). The sum of all weights does not need to add up to a specific +number. +Weights are now used in the round-robin algorithm, a destination is +chosen a number of times equal to its weight consecutively before going +to the next destination. + +The *priority* field is used at ordering the +destinations from a set. It does not affect the overall probability +of a destination to be chosen. It is reflected when listing the +destination, the field can definetly be used in further selecting algorithms. + + +**Q: What happened with the *list_file* +module parameter ?** + + +The support for text file (for provisioning destinations) was dropped. +Only the DB support (provisioning via a DB table) is now available - if +you still want to use a text file for provisioning, use db_text DB driver +(DB emulated via text files) + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable version should be sent to +users@lists.opensips.org and e-mail regarding development versions or SVN +snapshots should be send to devel@lists.opensips.org. + +If you want to keep the mail private, send it to users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: [https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues) + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/dispatcher/doc/contributors.xml b/modules/dispatcher/doc/contributors.xml deleted file mode 100644 index 2ac6d18deb9..00000000000 --- a/modules/dispatcher/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 172 - 109 - 3360 - 2030 - - - 2. - Liviu Chircu (@liviuchircu) - 111 - 72 - 1711 - 1441 - - - 3. - Daniel-Constantin Mierla (@miconda) - 82 - 39 - 3372 - 844 - - - 4. - Andrei Datcu (@andrei-datcu) - 48 - 15 - 2153 - 846 - - - 5. - Razvan Crainea (@razvancrainea) - 46 - 37 - 602 - 175 - - - 6. - Ionut Ionita (@ionutrazvanionita) - 43 - 17 - 1145 - 969 - - - 7. - Ovidiu Sas (@ovidiusas) - 31 - 17 - 705 - 434 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 19 - 11 - 378 - 236 - - - 9. - Vlad Paiu (@vladpaiu) - 17 - 10 - 681 - 33 - - - 10. - Henning Westerholt (@henningw) - 11 - 7 - 93 - 125 - - - -
-All remaining contributors: Carsten Bock, Ionel Cerghit (@ionel-cerghit), Elena-Ramona Modroiu, Maksym Sobolyev (@sobomax), John Burke (@john08burke), Norman Brandinger (@NormB), Klaus Darilion, Anca Vamanu, Jarrod Baumann (@jarrodb), wangdd, Walter Doekes (@wdoekes), Nick Altmann (@nikbyte), Jan Janak (@janakj), Andrei Pelinescu-Onciul, Peter Lemenkov (@lemenkov), Stanislaw Pitucha, Babak Yakhchali, Federico Cabiddu, Konstantin Bokarius, Alexandra Titoc, Andreas Granig, John Riordan, Aron Podrigal (@ar45), Julián Moreno Patiño, Kevin McAllister, Roman Sevko, UnixDev, David Sanders, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - Jun 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Aug 2012 - May 2025 - - - 3. - Babak Yakhchali - Feb 2025 - Feb 2025 - - - 4. - Norman Brandinger (@NormB) - Nov 2024 - Nov 2024 - - - 5. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 6. - Vlad Paiu (@vladpaiu) - Mar 2012 - Dec 2023 - - - 7. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 8. - Razvan Crainea (@razvancrainea) - May 2011 - Nov 2023 - - - 9. - wangdd - Apr 2023 - May 2023 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2022 - - - -
-All remaining contributors: John Burke (@john08burke), Peter Lemenkov (@lemenkov), Roman Sevko, Nick Altmann (@nikbyte), Ionel Cerghit (@ionel-cerghit), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Jarrod Baumann (@jarrodb), Ovidiu Sas (@ovidiusas), David Sanders, Aron Podrigal (@ar45), Andrei Datcu (@andrei-datcu), Walter Doekes (@wdoekes), Stanislaw Pitucha, Anca Vamanu, John Riordan, UnixDev, Kevin McAllister, Klaus Darilion, Carsten Bock, Daniel-Constantin Mierla (@miconda), Henning Westerholt (@henningw), Konstantin Bokarius, Edson Gellert Schubert, Federico Cabiddu, Elena-Ramona Modroiu, Andreas Granig, Andrei Pelinescu-Onciul, Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu (@vladpaiu), Razvan Crainea (@razvancrainea), wangdd, Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), John Burke (@john08burke), Roman Sevko, Peter Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Ionel Cerghit (@ionel-cerghit), Jarrod Baumann (@jarrodb), Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Andrei Datcu (@andrei-datcu), Walter Doekes (@wdoekes), Stanislaw Pitucha, Anca Vamanu, Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Carsten Bock, Edson Gellert Schubert, Elena-Ramona Modroiu. -
- -
diff --git a/modules/dispatcher/doc/dispatcher.list b/modules/dispatcher/doc/dispatcher.list deleted file mode 100644 index 55a8cf476ac..00000000000 --- a/modules/dispatcher/doc/dispatcher.list +++ /dev/null @@ -1,14 +0,0 @@ -# dispatcher destination sets -# - -# line format -# setit(integer) destination(sip uri) flags (integer, optional) - -# proxies -2 sip:127.0.0.1:5080 -2 sip:127.0.0.1:5082 - -# gateways -1 sip:127.0.0.1:7070 -1 sip:127.0.0.1:7072 -1 sip:127.0.0.1:7074 diff --git a/modules/dispatcher/doc/dispatcher.xml b/modules/dispatcher/doc/dispatcher.xml deleted file mode 100644 index 57412aecf88..00000000000 --- a/modules/dispatcher/doc/dispatcher.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - -%docentities; - -]> - - - - dispatcher Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2010 &voicesystem; - ©right; 2004 &fhg; - - diff --git a/modules/dispatcher/doc/dispatcher_admin.xml b/modules/dispatcher/doc/dispatcher_admin.xml deleted file mode 100644 index 08be88e02a7..00000000000 --- a/modules/dispatcher/doc/dispatcher_admin.xml +++ /dev/null @@ -1,1943 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This modules implements a dispatcher for destination addresses. It - computes hashes over various parts of the request and selects an - address from a destination set. The selected address may then either - overwrite the R-URI of a SIP request or be used as an outbound proxy. - - - The module can be used as a stateless load balancer, having no - guarantee of fair distribution. - - - For the distribution algorithm, the module allows the definition of - weights for the destination. This is useful in order to get a different - ratio of traffic between destinations. - - - Starting with version 2.1, the dispatcher module keeps its destination sets - into different partitions. Each partition is described by its own - "db_url", "table_name", "dst_avp", "grp_avp", "cnt_avp", "sock_avp", - "attr_avp", "blacklists", "ping_from", "ping_method" and - "persistent_state" set of attributes. Setting any of these - module parameters will only alter the "default" partition's properties. - - - In order to create a new partition, the - parameter can be used. If none of the 8 partition specific parameters - are defined for the "default" partition, then this partition will not - be created. Once the "default" partition is created, any undefined - parameter from other partitions will inherit the value of the - corresponding parameter of the "default" partition. If there is no - "default" partition, the default value specified in the parameter's - description will be used. Finally, note that each dispatcher table - specified using the "table_name" partition attribute requires a - corresponding "version" table record within the partition's database, - specified through "db_url". - - - Since version 2.1, the "flags" parameter has been moved to - ds_select_dst() and ds_select_domain() along with "force_dst" and - "use_default" flags. - -
-
- Dependencies -
- &osips; modules - - The following modules must be loaded before this module: - - - - TM - only if active recovery of failed hosts is required. - - - - - clusterer - only if "cluster_id" - option is enabled. - - - - - database - one of the DB SQL modules - - - - - freeswitch - only if "fetch_freeswitch_stats" is enabled.. - - - - -
-
- External libraries or applications - - The following libraries or applications must be installed before - running &osips; with this module: - - - - none. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - The default DB connection of the module, overriding the global - 'db_default_url' setting. Once specified, partitions which are missing - the 'db_url' property will inherit their URL from this value. - - - - Default value is NULL. - - - - Setting the default database URL for dispatcher - -... -modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database") -... - - -
- -
- <varname>attrs_avp</varname> (str) - - The name of the avp to contain the attributes string of the current - destination. When a destination is selected, automatically, this AVP - will provide the attributes string - this is an opaque string (from - OpenSIPS point of view) : it is loaded from destination definition ( - via DB) and blindly provided in the script. - Setting this parameter will only change the default partition's - attrs_avp. Use the partition parameter to create and alter - other partitions. - - - - - - Default value is null - don't provide ATTRIBUTEs. - - - - Set the 'default' partition's <quote>attrs_avp</quote> parameter - -... -modparam("dispatcher", "attrs_avp", "$avp(272)") -... - - -
- -
- <varname>script_attrs_avp</varname> (str) - - Name of the avp to contain the script attributes string of the current - destination. When a destination is selected, automatically, this AVP - will provide the attributes string - this is an opaque string (from - OpenSIPS point of view) : it is provided via the ds_push_script_attrs - MI or SCRIPT function. - - - - - - Default value is null - don't provide SCRIPT ATTRIBUTEs. - - - - Set the 'default' partition's <quote>script_attrs_avp</quote> parameter - -... -modparam("dispatcher", "attrs_avp", "$avp(script_attrs)") -... - - -
- -
- <varname>algo_route</varname> (str) - - Name of the route to be called when using algo 10. - The route will get as param the dst_uri, attrs and script_attrs for the - dispatcher entry that currently needs to be evaluated ( available via - $param(1), $param(2) and $param(3) or via $param(dst_uri), $param(attrs) and $param(script_attrs) when the route gets called ). - The return value of the route is considered by the dispatcher module to - be the current weight of the dispatcher entry, and when using the 10 - algo, the dispatcher entries are sorted in ascending weight order. - - If the returned value from the algo route is negative, the current dispatcher entry will be automatically skipped from usage - - - - Default value is null - disabled. - - - - Use algo_route for hashing: - -... -modparam("dispatcher", "algo_route", "my_dispatcher_logic)") -... -route[my_dispatcher_logic] { - $var(curent_score) = 0; - xlog("DISPATCHER - Running logic for $param(dst_uri) with attrs $param(attrs) and script attrs $param(script_attrs) \n"); - - # decide to penalize current dispatcher entry, based on your logic - if (my_condition_here) - $var(current_score) = $var(current_score) + 10; - - return $var(rc); -} - - - -
- - -
- <varname>hash_pvar</varname> (str) - - String with PVs used for the hashing algorithm 7. - - - - You must set this parameter if you want do hashing over custom message - parts. - - - - - Default value is null - disabled. - - - - Use $avp(273) for hashing: - -... -modparam("dispatcher", "hash_pvar", "$avp(273)") -... - - - - Use combination of PVs for hashing: - -... -modparam("dispatcher", "hash_pvar", "hash the $fU@$ci") -... - - -
- -
- <varname>setid_pvar</varname> (str) - - The name of the PV where to store the set ID (group ID) when calling - ds_is_in_list() without group parameter (third parameter). - - - - Default value is null - don't set PV. - - - - Set the <quote>setid_pvar</quote> parameter - -... -modparam("dispatcher", "setid_pvar", "$var(setid)") -... - - -
- -
- <varname>ds_ping_method</varname> (string) - - With this Method you can define, with which method you want to probe - the failed gateways. This method is only available, if compiled with - the probing of failed gateways enabled. - - - Use the 'partition' parameter if you want to define the ping method - other partitions. - - - - Default value is OPTIONS. - - - - Set the <quote>ds_ping_method</quote> parameter - -... -modparam("dispatcher", "ds_ping_method", "INFO") -... - - -
- -
- <varname>ds_ping_from</varname> (string) - - With this Method you can define the "From:"-Line for the request, - sent to the failed gateways. This method is only available, if - compiled with the probing of failed gateways enabled. - - - Use the 'partition' parameter if you want to define the "From:" - ping header of other partitions. - - - - Default value is sip:dispatcher@localhost. - - - - Set the <quote>ds_ping_from</quote> parameter - -... -modparam("dispatcher", "ds_ping_from", "sip:proxy@sip.somehost.com") -... - - -
- -
- <varname>ds_ping_interval</varname> (int) - - With this Method you can define the interval for sending a request to - a failed gateway. This parameter is only used, when the TM-Module is - loaded. If set to 0, the pinging of failed requests - is disabled. - - - - Default value is 0 (disabled). - - - - Set the <quote>ds_ping_interval</quote> parameter - -... -modparam("dispatcher", "ds_ping_interval", 30) -... - - -
- -
- <varname>ds_ping_maxfwd</varname> (int) - - This parameter allows you to enforce a specific Max-Forward value - for the SIP pinging requests generated by the Dispatcher modules. - If not explicitly set, no value will be enforced and it let the - Transaction Layer (TM module) to set a default Max-Forward value. - - - The accepted values are any positive integer values, including the - 0 value. - - - Set the <quote>ds_ping_maxfwd</quote> parameter - -... -modparam("dispatcher", "ds_ping_maxfwd", 2) -... - - -
- - -
- <varname>ds_probing_sock</varname> (str) - - A socket description [proto:]host[:port] of the local socket (which - is used by OpenSIPS for SIP traffic) to be used (if multiple) for - sending the probing messages from. - - - - Default value is NULL(none). - - - - Set the <quote>ds_probing_sock</quote> parameter - -... -modparam("dispatcher", "ds_probing_sock", "udp:192.168.1.100:5077") -... - - -
- -
- <varname>ds_probing_threshold</varname> (int) - - If you want to set a gateway into probing mode, you will need a - specific number of requests until it will change from "active" to - probing. The number of attempts can be set with this parameter. - - - - Default value is 3. - - - - Set the <quote>ds_probing_threshold</quote> parameter - -... -modparam("dispatcher", "ds_probing_threshold", 10) -... - - -
- -
- <varname>ds_probing_mode</varname> (int) - - Controls what gateways are tested to see if they are reachable. If set - to 0, only the gateways with state PROBING are tested, if set to 1, all - gateways are tested. If set to 1 and the response is 408 (timeout), - an active gateway is set to PROBING state. - - - - Default value is 0. - - - - Set the <quote>ds_probing_mode</quote> parameter - -... -modparam("dispatcher", "ds_probing_mode", 1) -... - - -
- -
- <varname>ds_probing_list</varname> (str) - - Defines a list of one or more setids that limits which - destinations are probed if probing is active. This is useful - when multiple proxies share the same dispatcher table, but you - want to limit which ones are responsible for probing specific - destinations. - - - - Default value is NULL (probe all sets). - - - - Set the <quote>ds_probing_list</quote> parameter - -... -modparam("dispatcher", "ds_probing_list", "1,2,3") -... - - -
- -
- <varname>ds_define_blacklist</varname> (str) - - Defines a blacklist based on a dispatching setid from the 'default' - partition. - This list will contain the IPs (no port, all protocols) of the - destinations matching the given setid. - Use the 'partition' parameter if you want to define blacklists - based on other partitions' sets. - - - Multiple instances of this param are allowed. - - - - Default value is NULL. - - - - Set the 'default' partition's <quote>ds_define_blacklist</quote> - parameter - -... -modparam("dispatcher", "ds_define_blacklist", "list= 1,4,3") -modparam("dispatcher", "ds_define_blacklist", "blist2= 2,10,6") -... - - -
- -
- <varname>options_reply_codes</varname> (str) - - This parameter must contain a list of SIP reply codes separated by - comma. The codes defined here will be considered as valid reply codes - for OPTIONS messages used for pinging, apart for 200. - - - - Default value is NULL. - - - - Set the <quote>options_reply_codes</quote> parameter - -... -modparam("dispatcher", "options_reply_codes", "501, 403") -... - - -
- -
- <varname>dst_avp</varname> (str) - - This is mainly for internal usage and represents the name of the avp - which will hold the list with addresses, in the order - they have been selected by the chosen algorithm. If use_default is 1, - the value of last dst_avp_id is the last address in destination set. The - first dst_avp_id is the selected destinations. All the other addresses - from the destination set will be added in the avp list to be able to - implement serial forking. - Setting this parameter will only change the default partition's - dst_avp. Use the partition parameter to create and alter - other partitions. - - - - For the 'default' partition the default value - is $avp(ds_dst_failover). For any other partition, - the default value is $avp(ds_dst_failover_partitionname). - - - - Set the 'default' partition's <quote>dst_avp</quote> parameter - -... -modparam("dispatcher", "dst_avp", "$avp(271)") -... - - -
- -
- <varname>grp_avp</varname> (str) - - This is mainly for internal usage and represents the name of the avp - storing the group id of the destination set. Good - to have it for later usage or checks. - Setting this parameter will only change the default partition's - grp_avp. Use the partition parameter to create and alter - other partitions. - - - - For the 'default' partition the default value - is $avp(ds_grp_failover). For any other partition, - the default value is $avp(ds_grp_failover_partitionname). - - - - Set the 'default' partition's <quote>grp_avp</quote> parameter - -... -modparam("dispatcher", "grp_avp", "$avp(273)") -... - - -
- -
- <varname>cnt_avp</varname> (str) - - This is mainly for internal usage and represents the name of the avp - storing the number of destination addresses kept in dst_avp avps. - Setting this parameter will only change the default partition's - cnt_avp. Use the partition parameter to create and alter - other partitions. - - - - For the 'default' partition the default value - is $avp(ds_cnt_failover). For any other partition, - the default value is $avp(ds_cnt_failover_partitionname). - - - - Set the 'default' partition's <quote>cnt_avp</quote> parameter - -... -modparam("dispatcher", "cnt_avp", "$avp(274)") -... - - -
- -
- <varname>sock_avp</varname> (str) - - This is mainly for internal usage and represents the name of the avp - storing the sockets to be used for the destination addresses kept in - dst_avp avps. - Setting this parameter will only change the default partition's - sock_avp. Use the partition parameter to create and alter - other partitions. - - - - For the 'default' partition the default value - is $avp(ds_sock_failover). For any other partition, - the default value is $avp(ds_sock_failover_partitionname). - - - - Set the 'default' partition's <quote>sock_avp</quote> parameter - -... -modparam("dispatcher", "sock_avp", "$avp(275)") -... - - -
- -
- <varname>pvar_algo_pattern</varname> (str) - - This parameter is used by the PVAR(9) algorithm to specify the - pseudovariable pattern used to detect the load of each destination. The - name of the pseudovariable should contain the string %u, - which will be internally replaced by the module with the uri of the - destination. The string %i can also be used and will be - replaced with the set ID of the destination (useful in cases where same - uri exists in multiple sets). - - - - - - Default value is none. - - - - Set the <quote>pvar_algo_pattern</quote> parameter - -... -modparam("dispatcher", "pvar_algo_pattern", "$stat(load_%u)") -... - - -
- -
- <varname>persistent_state</varname> (int) - - Specifies whether the state column - should be loaded at startup and flushed during runtime or not - for the "default" partition. - - - Use the 'partition' parameter if you want to define the persistent - state of other partitions. - - - Default value is 1 (enabled). - - - - Set the <varname>persistent_state</varname> parameter - -... -# disable all DB operations with the state of a destination -modparam("dispatcher", "persistent_state", 0) -... - - -
- -
- <varname>cluster_id</varname> (integer) - - The ID of the cluster the module is part of. The clustering support is - used in dispatcher module for two purposes: for sharing the status - of the destinations and for controlling the pinging to destinations. - - - If clustering enbled, the module will automatically share changes - over the status of the destinations with the other - OpenSIPS instances that are part of a cluster. Whenever such a status - changes (following an MI command, a probing result, a script command), - the module will replicate this status change to all the nodes in this - given cluster. - - - The clustering with sharing tag support may be used to control which - node in the cluster will perform the pinging/probing to - destinations. See the - option. - - - &clusterer_sync_cap_para; - - - For more info on how to define and populate a cluster (with OpenSIPS - nodes) see the clusterer module. - - - - Default value is 0 (none). - - - - Set <varname>cluster_id</varname> parameter - -... -# replicate destination status with all OpenSIPS in cluster ID 9 -modparam("dispatcher", "cluster_id", 9) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (string) - - The name of the sharing tag (as defined per clusterer modules) to - control which node is responsible for perform the self-triggered - actions in the module. Such actions may be the destination probing - (see also the parameter) - or sharing the changes in the destination status. - If defined, only the node with active status of this tag will - perform the actions (pinging and sharing status). - - - The must be defined for this option - to work. - - - This is an optional parameter. If not set, all the nodes in the cluster - will share the status changes. - - - - Default value is empty (none). - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_sharing_tag", "vip") -... - - -
- -
- <varname>cluster_probing_mode</varname> (string) - - This paramter controls how the probing/pinging should be done when - using the clustering support. It is about which node in the cluster - pings which gateway/destination. - - - The must be defined for this option - to work. - - - The supported probing modes are: - - - - - "all" - all the nodes in the - cluster will independetly ping all the defined destinations, - an "all" pings "all" mode. - - - - - "by-shtag" - all the destinations - are pinged by only one node in the cluster, the node having the - active. By - activating the sharing tag on a different node, the pinging - duty will be transfered to another node in the cluster. - - - - - "distributed" - the pinging - effort is distributed across all the nodes in the cluster, so each - node will ping a sub-set of the overall set of destinations. Still - all the destinations will get pinged (and only once per pinging - cycle). - The re-partitioning of the pinging effort over the available nodes - in the cluster is automatically done when new nodes are joining or - nodes are dropping out. Still there is no guaratee on which node - will be responsible for pinging which destination. - - - - - - Default value is "all". - - - - Set <varname>cluster_probing_mode</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_sharing_tag", "vip") -modparam("dispatcher", "cluster_probing_mode", "by-shtag") -... -# the pinging effort is distributed across all the nodes -modparam("dispatcher", "cluster_id", 9) -modparam("dispatcher", "cluster_probing_mode", "distributed") -... - - -
- -
- <varname>partition</varname> (string) - - Define a new partition (data source) with the following properties: - "db_url", "table_name", "dst_avp", "grp_avp", "cnt_avp", "sock_avp", - "attrs_avp", "script_attrs", "ds_define_blacklist". All these - properties are optional, having appropriate default values. - - - The syntax is: "partition_name: param1 = value1; param2 = value2". - Each value format is the same as the one used to define a specific - parameter using modparam. - - - This parameter may be set multiple times, thus defining as many - partitions as needed. The 'default' partition may also be defined - using this parameter. - - - - Define a new partition called 'voicemail' - -... -modparam("dispatcher", "partition", - "voicemail: - db_url = mysql://user:passwd@localhost/database; - table_name = dispatcher; - attrs_avp = $avp(ds_attr_vm); - ds_define_blacklist = list2 = 4,6") -... - - - - - Define the 'trunks' partition and make it the 'default' - partition, so we avoid loading the 'dispatcher' table - - -... -modparam("dispatcher", "partition", - "trunks: - db_url = mysql://user:passwd@localhost/database; - table_name = dispatcher_trunks; - attrs_avp = $avp(ds_attr_trunks)") -modparam("dispatcher", "partition", "default: trunks") -... - - -
- -
- <varname>table_name</varname> (string) - - The default name of the table from which to load dispatcher - destinations. Partitions which are missing the 'table_name' property - will inherit their table name from this value. - - - - Default value is dispatcher. - - - - Set the default table name - -... -modparam("dispatcher", "table_name", "my_dispatcher") -... - - -
- -
- <varname>setid_col</varname> (string) - - The column's name in the database storing the gateway's group id. - - - - Default value is setid. - - - - Set <quote>setid_col</quote> parameter - -... -modparam("dispatcher", "setid_col", "groupid") -... - - -
- -
- <varname>destination_col</varname> (string) - - The column's name in the database storing the destination's - sip uri. - - - - Default value is destination. - - - - Set <quote>destination_col</quote> parameter - -... -modparam("dispatcher", "destination_col", "uri") -... - - -
- -
- <varname>state_col</varname> (string) - - The column's name in the database storing the state of the - destination uri. - - - - Default value is state. - - - - Set <quote>state_col</quote> parameter - -... -modparam("dispatcher", "state_col", "dststate") -... - - -
- -
- <varname>weight_col</varname> (string) - - The column's name in the database storing the weight for - destination uri. - - - - Default value is weight. - - - - Set <quote>weight_col</quote> parameter - -... -modparam("dispatcher", "weight_col", "dstweight") -... - - -
- -
- <varname>priority_col</varname> (string) - - The column's name in the database storing the priority for - destination uri. - - - - Default value is priority. - - - - Set <quote>priority_col</quote> parameter - -... -modparam("dispatcher", "priority_col", "dstprio") -... - - -
- -
- <varname>attrs_col</varname> (string) - - The column's name in the database storing the attributes (opaque - string) for destination uri. - - - - Default value is attrs. - - - - Set <quote>attrs_col</quote> parameter - -... -modparam("dispatcher", "attrs_col", "dstattrs") -... - - -
- -
- <varname>socket_col</varname> (string) - - The column's name in the database storing the socket (as - string) for destination uri. - - - - Default value is socket. - - - - Set <quote>socket_col</quote> parameter - -... -modparam("dispatcher", "socket_col", "my_sock") -... - - -
- -
- <varname>probe_mode_col</varname> (string) - - The column's name in the database storing the probe_mode (as - string) for destination. - - - - Default value is probe_mode. - - - - Set <quote>probe_mode_col</quote> parameter - -... -modparam("dispatcher", "probe_mode_col", "probing") -... - - -
- -
- <varname>fetch_freeswitch_stats</varname> (integer) - - If enabled, FreeSWITCH destinations may have dynamic dispatching weights, - refreshed at runtime, using the FreeSWITCH Event Socket Layer. - For these destinations, an Event Socket Layer URL must be provisioned - into the "weight" column, instead of an integer string. Some example values: - "fs://:password@freeswitch.example.com" - or "fs://user:password@127.0.0.1:8021". - The default ESL port is 8021. - - - OpenSIPS will establish a connection with the given socket and - periodically calculate/update the weights of these destinations - using statistics pushed by the FreeSWITCH box. - - - The value for an automatically calculated weight ranges between - 0 - 100. - This is helpful when grouping normal destinations with - FreeSWITCH ones. - - - The dynamic weights are recalculated every - event_heartbeat_interval seconds (see the - "freeswitch" OpenSIPS module for more details regarding this setting), - as the stats from FreeSWITCH are expected to arrive. The update formula - is shown below (FreeSWITCH stats are highlighted in bold): - - - weight = 100 * (Idle-CPU / 100) * (1 - Session-Count / Max-Sessions) - - - - Default value is 0 (disabled). - - - - Set the <varname>fetch_freeswitch_load</varname> parameter - -... -modparam("dispatcher", "fetch_freeswitch_stats", 1) -... - - -
- -
- <varname>max_freeswitch_weight</varname> (integer) - - The maximum weight of a FreeSWITCH ESL-enabled destination. This value - is also used during startup/reload, when no stats from FreeSWITCH are - available yet. - - - Important: When mixing normal destinations with FreeSWITCH-enabled ones in - the same dispatching set, OpenSIPS will truncate any weight values that - are larger than max_freeswitch_weight - to the value of this parameter! - - - NOTE: OpenSIPS internally rounds weights to nearest integer, so larger - max weight values will more accurately represent the current load on the - FreeSWITCH boxes! For example, if you set this parameter to 1, the box - will receive no traffic whenever either its CPU or session usage goes - past 50%! - - - - Default value is 100. - - - - Set the <varname>max_freeswitch_weight</varname> parameter - -... -modparam("dispatcher", "max_freeswitch_weight", 1000) -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">ds_select_dst(set, alg, [flags], [partition], [max_res])</function> - - - The method selects a destination from the given set of addresses. It will - overwrite the destination URI ($du) of a SIP request. - - Meaning of the parameters is as follows: - - - - set (int) - a set identifier from which to select destinations - - - - - alg (int) - the algorithm used to select the - destination address - - - - - 0 - hash over callid - - - - - 1 - hash over from uri. - - - - - 2 - hash over to uri. - - - - - 3 - hash over request-uri. - - - - - 4 - weighted round-robin (next destination). - the destination's weight determines how many times it is chosen - before going to the next one - - - - - 5 - hash over authorization-username - (Proxy-Authorization or "normal" authorization). - If no username is found, weighted round-robin is used. - - - - - 6 - random (using rand()). - - - - - 7 - hash over the content of PVs string. - Note: This works only when the parameter hash_pvar is set. - - - - - 8 - the first entry in set is chosen. - - - - - 9 - The pvar_algo_pattern - parameter is used to determine the load on each server. If the - parameter is not specified, then the first entry in the set is - chosen. - - - - - 10 - The algo_route - OpenSIPS route is called for each dispatcher entry in - the setid, in order to decide the routing order. - See the algo_route parameter for usage examples - - - - - - X - if the algorithm is not implemented, the - first entry in set is chosen. - - - - - - - flags (string, optional) - a string of flag-settings - which tweak the function's behavior: - - - - 'f' (failover support): causes the remaining - addresses from the destination set to be stored within an - internally managed AVP. You may then use - to switch to the next - address, thus achieving serial forking to all possible destinations - - - - - 'u' (user only): will specify that only the URI user part - will be used for hashing - - - - - 'd' (use default): use the last address in destination - set as last option to send the message - - - - 'a' (append destinations): append any new destinations to - the current destination list, rather than rewriting the list - - - - The flags are being kept per partition. - - - - - partition (string, optional) - name of a DB partition - - - - - max_res (int, optional) - signifies that only a maximum - number of destinations shall be included in the specified failover AVP. - This allows having multiple destinations while - also preventing excessive failover attempts in case a number is - bound to fail globally. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. - - - <function>ds_select_dst</function> usage - -... -if (!ds_select_dst(1, 0)) { - xlog("ERROR: no active destinations found!\n"); - send_reply(503, "Service Unavailable"); - exit; -} -... -ds_select_dst(1, 0, , "fs_boxes", 5); -... -ds_select_dst(1, 0, "fUD", "ask_boxes"); -... -ds_select_dst(2, 0, "fud", "pstn_gws", 5); -ds_select_dst(3, 1, "fua", "pstn_gws", 2); -... -# using variables -$var(part) = "pstn_gws" -$var(setid) = 1; -$var(alg) = 4; -$var(flags) = "fdu"; -$var(max_res) = 2; -ds_select_dst($var(setid), $var(alg), $var(flags), $var(part), $var(max_res)); -... - - -
-
- - <function moreinfo="none">ds_select_domain(set, alg, [flags], [partition], [max_res])</function> - - - The method selects a destination from addresses set and rewrites the - hostname and port parts of the Request-URI ($ru). - Its parameters have same meaning as in . - - - If the "f" (failover support) flag is present, the rest of the - addresses from the destination set will be stored in an internally - managed AVP. You may then use to - switch to the next address in the list, thus achieving serial forking - to all possible destinations. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. - -
-
- - <function moreinfo="none">ds_next_dst([partition])</function> - - - Takes the next destination address from the AVPs with id - partition.'dst_avp_id' and sets the dst_uri (outbound proxy address). - If "partition" is omitted, the default partition will be used.This - function is using the flags set in ds_select_dst or ds_select_domain. - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -
-
- - <function moreinfo="none">ds_next_domain([partition])</function> - - - Takes the next destination address from the AVPs with id - partition.'dst_avp_id' and sets the domain part of the request uri. - If "partition" is omitted, the default partition will be used.This - function is using the flags set in ds_select_dst or ds_select_domain. - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -
-
- - <function moreinfo="none">ds_mark_dst([state], [partition])</function> - - - Mark the last used address from partition's destination set as - inactive ("i"/"I"/"0"), active ("a"/"A"/"1") or probing ("p"/"P"/"2"). - With this function, an automatic detection of failed gateways can be implemented. - When an address is marked as inactive or probing, it will be ignored by - and . - If "partition" is omitted, the default partition will be used. This function - is using the flags set in or - . - - Possible parameters: - - - state (string, optional) - new state for the last attempted - destination. Possible values: - - - "i", "I" or "0" (default) - the last - destination should be set to inactive and will be ignored - in future requests. - - - "a", "A" or "1" - the last - destination should be set to active. - - - "p", "P" or "2" - the last - destination will be set to probing. Note: You will need to - call this function "threshold"-times, before it will be - actually set to probing. - - - - - partition (string, optional) - name of a DB partition, - otherwise the default one will be used - - - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - -
-
- - <function moreinfo="none">ds_count(set, state_filter, res_var, [partition])</function> - - - Returns the number of active, inactive or probing destinations in a - partition's set, or combinations between these properties. - - Meaning of the parameters: - - - - set (int) - a set of dispatching destinations - - - - - state_filter (string) - which destinations should be - counted. Either active ("a", "A" or "1"), inactive - ("i", "I" or "0"), probing ("p", "P" or "2") destinations or - different combinations between these flags, such as - "pI", "1i", "ipA"... - - - - res_var (variable) - a variable - which will hold the integer result - - - - partition (string, optional) - name of a - DB partition. If omitted, the "default" partition - will be used. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, - LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - - <function>ds_count</function> usage - -... -if (ds_count(1, "a", $avp(result))) { - ... -} -... -if (ds_count($avp(set), "ip", $avp(result), $avp(partition))) { - ... -} -... - - -
- -
- - <function moreinfo="none">ds_is_in_list(ip, port, [set], [partition], [active_only], [pattern])</function> - - - This function returns true only if "ip" and "port" point to a - host from the given dispatcher "set". - - - Meaning of the parameters: - - - - ip (string) - an IPv4 or IPv6 address to - test against the dispatcher "set" - - - port (int) - a port to test against the - dispatcher list. Use a 0 value in order to - match any port - - - set (int, optional) - a dispatcher set - identifier to test against. If missing, all sets will be checked. - The -1 set is a special value, acting as a - "check all sets" wildcard. - - - - partition (string, optional) - name of - a DB partition - - - active_only (int, optional) - specify - a non-zero value in order to only search through the active - destinations (ignore the ones in probing and inactive states) - - - pattern (string, optional) - a glob - pattern used to match destination attributes. If the destination - ip and port matches but the pattern does not match the destination's - attribute, the function will fail. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ONREPLY_ROUTE. - - - <function>ds_is_in_list</function> usage - -... -if (ds_is_in_list($si, $sp)) { - # source IP:PORT is in a dispatcher list -} -... -if (ds_is_in_list($rd, $rp, 2)) { - # the R-URI (IP and port) is in the dispatcher set 2 of the "default" partition -} -... -if (ds_is_in_list($rd, $rp, 2, "part2")) { - # the R-URI (IP and port) is in the dispatcher set 2 of the "part2" partition -} -... - - - -
- -
- - <function moreinfo="none">ds_push_script_attrs(script_attr, ip, port, set, [partition])</function> - - - Set the script attrs for the dispatcher entry defined by IP, Port, setid and partition. - - Meaning of the parameters: - - - - script_attr (str or pvar) - The new script attributes - - - - - IP (string) - - IP address for which we are pushing script attributes - - - - port (int) Port for which we are pushing script attributes - - - - setid (int) Setid for which we are pushing script attributes - - - - partition (string, optional) - name of a - DB partition. If omitted, the "default" partition - will be used. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, - LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - - <function>ds_count</function> usage - -... -if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition')) { - ... -} -... - - -
- -
- - <function moreinfo="none">ds_get_script_attrs(uri, set, [partition], out_attrs)</function> - - - Get the script attrs for the dispatcher entry defined by the URI, setid and partition. - - Meaning of the parameters: - - - URI (string) - - URI address for which we are getting script attributes - - - - setid (int) Setid for which we are pushing script attributes - - - - partition (string, optional) - name of a - DB partition. If omitted, the "default" partition - will be used. - - - out_atrs (pvar) - name of a - variable where we will store the script attrs. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, - LOCAL_ROUTE, TIMER_ROUTE, EVENT_ROUTE - - - <function>ds_count</function> usage - -... -if (ds_push_script_attrs($var(my_attributes),$si , $sp, 1, 'my_partition')) { - ... -} -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">ds_set_state</function> - - - Sets the status for a destination address (can be use to mark the destination - as active or inactive). - - - Name: ds_set_state - - Parameters: - - state : state of the destination address - - a: active - i: inactive - p: probing - - - - group: partition name followed by colon - and destination group id. If the partition name is omitted, - the default partition will be used - - address: address of the destination in the group - - - MI FIFO Command Format: - - -opensips-cli -x mi ds_set_state a 2 sip:10.0.0.202 - -
-
- - <function moreinfo="none">ds_list</function> - - - It lists the groups and included destinations of all the partitions. - - - Name: ds_list - - Parameters: - - - full (optional) - adds the weight, - priority and description fields to the listing - - - partition (optional) - return only - destinations and sets in the provided partition. - - - - MI FIFO Command Format: - - -opensips-cli -x mi ds_list - -
-
- - <function moreinfo="none">ds_reload</function> - - - It reloads the groups and included destinations for a - specified partition or all partitions. - - - Name: ds_reload - - Parameters: - - - partition (optional) - name of - the partition to be reloaded. default partition is "default". - - - inherit_state (optional) : whether inherit old state of the destination , default is y. - - n: no inherit state - y: inherit state - - - - - - MI FIFO Command Format: - - -opensips-cli -x mi ds_reload -opensips-cli -x mi ds_reload inherit_state=n - -
- -
- - <function moreinfo="none">ds_push_script_attrs</function> - - - Pushes script attrs for the dispatcher entry defined by IP, Port, setid, and optionally partition. - - - Name: ds_push_script_attrs - - Parameters: - - attrs : new attributes to be pushed - - - ip: IP for which we are pushing script attributes - - port: Port for which we are pushing script attributes - - setid: Setid for which we are pushing script attributes - partition ( optional ): Partition for which we are pushing script attributes - - - MI FIFO Command Format: - - -#opensips-cli -x mi ds_push_script_attrs '{"ping":"30000","load":"50"}' '192.168.0.107' 5091 1 main - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_DISPATCHER_STATUS</function> - - - This event is raised when the dispatcher module marks a destination as - activated or deactivated. - - Parameters: - - - partition - the partition name of the destination. - - - group - the group of the destination. - - - address - the address of the destination. - - - status - active if - the destination gets activated or inactive if the - destination is detected unresponsive. - - -
-
- - -
- Exported Status/Report Identifiers - - - The module provides the "dispatcher" Status/Report group, where each - partition is defined as a separate SR identifier. - -
- <varname>[partition_name]</varname> - - The status of these identifiers reflects the readiness/status of the - cached data (if available or not when being loaded from DB): - - - - -2 - no data at all (initial status) - - - -1 - no data, initial loading in progress - - - 1 - data loaded, partition ready - - - 2 - data available, a reload in progress - - - - - Reload reporting: - - - In terms of date reloading, the following events will be reported: - - - - starting DB data loading - - - DB data loading failed, discarding - - - DB data loading successfully completed - - - N destination loaded (N discarded) - - - - { - "Name": "default", - "Reports": [ - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652373212, - "Date": "Thu May 12 19:33:32 2022", - "Log": "2 destinations loaded (0 discarded)" - } - ] - } - - -
- -
- <varname>[partition_name];events</varname> - - Destination switching reporting: - - - - For reporting events related to the state changes of the - destinations, the module provides separate identifiers (still - one per partition). - Why separate ones? The reports on state changing may be verbose and there - is the risk of loose/discard important reports on reloads due to the high - number of logs on state changes; - - - So, each partition will provide the identified "partition_name;events" for - reporting state changes of destinations, along with the reason - of the change. This identifiers have a 200 records history before - discarding the old ones. - - - { - "Name": "default;events", - "Reports": [ - { - "Timestamp": 1652373308, - "Date": "Thu May 12 19:35:08 2022", - "Log": "DESTINATION <sip:127.0.1.1>, set 1 switched to [inactive] due to negative probing reply\n" - }, - { - "Timestamp": 1652373308, - "Date": "Thu May 12 19:35:08 2022", - "Log": "DESTINATION <sip:127.0.1.2>, set 1 switched to [inactive] due to negative probing reply\n" - } - ] - }, - - -
- - - For how to access and use the Status/Report information, please see - https://www.opensips.org/Documentation/Interface-StatusReport-3-3. - - -
- - -
- Installation and Running -
- &osips; config file - - Next picture displays a sample usage of dispatcher. - - - &osips; config script - sample dispatcher usage - -... -&dispatchercfg; -... - - -
-
-
diff --git a/modules/dispatcher/doc/dispatcher_faq.xml b/modules/dispatcher/doc/dispatcher_faq.xml deleted file mode 100644 index 36d651c4732..00000000000 --- a/modules/dispatcher/doc/dispatcher_faq.xml +++ /dev/null @@ -1,143 +0,0 @@ - - - - - &faqguide; - - - - - - Does dispatcher provide a fair distribution? - - - - - There is no guarantee of that. You should do some measurements - to decide what distribution algorithm fits better in your - environment. - - - - - - - Is dispatcher dialog stateful? - - - - No. Dispatcher is stateless, although some distribution algorithms - are designed to select same destination for subsequent requests of - the same dialog (e.g., hashing the call-id). - - - - - - - What happened with the ds_is_from_list() - function? - - - - The function was replaced by the more generic - ds_is_in_list() function that takes as - parameters the IP and PORT to test against the dispatcher list. - - - ds_is_from_list() == ds_is_in_list("$si", "$sp") - - - - - - - How is weight and priority used by the dispatcher in selecting - a destination? - - - - The weight of a destination is currently used in - the hashing algorithms and it increases the probability of it to be - chosen(if we have two destinations with weights 1 respectively - 4 than the second one is 4 times more likely to be selected than the - other). The sum of all weights does not need to add up to a specific - number. - Weights are now used in the round-robin algorithm, a destination is - chosen a number of times equal to its weight consecutively before going - to the next destination. - - - The priority field is used at ordering the - destinations from a set. It does not affect the overall probability - of a destination to be chosen. It is reflected when listing the - destination, the field can definetly be used in further selecting algorithms. - - - - - - - What happened with the list_file - module parameter ? - - - - The support for text file (for provisioning destinations) was dropped. - Only the DB support (provisioning via a DB table) is now available - if - you still want to use a text file for provisioning, use db_text DB driver - (DB emulated via text files) - - - - - - - Where can I find more about &osips;? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable version should be sent to - &osipsusersmail; and e-mail regarding development versions or SVN - snapshots should be send to &osipsdevmail;. - - - If you want to keep the mail private, send it to &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: &osipsbugslink; - - - - - - diff --git a/modules/dispatcher/doc/dispatcher.cfg b/modules/dispatcher/samples/dispatcher.cfg similarity index 100% rename from modules/dispatcher/doc/dispatcher.cfg rename to modules/dispatcher/samples/dispatcher.cfg diff --git a/modules/dispatcher/samples/samples.md b/modules/dispatcher/samples/samples.md new file mode 100644 index 00000000000..7c0d0a48d19 --- /dev/null +++ b/modules/dispatcher/samples/samples.md @@ -0,0 +1,4 @@ +### OpenSIPS Config Script - Dispatcher Usage + +[dispatcher.cfg](./dispatcher.cfg "include") + diff --git a/modules/diversion/README b/modules/diversion/README deleted file mode 100644 index 8a195d9eae0..00000000000 --- a/modules/diversion/README +++ /dev/null @@ -1,251 +0,0 @@ -Diversion Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. suffix (string) - - 1.4. Exported Functions - - 1.4.1. add_diversion(reason, [uri], [counter]) - - 1.5. Diversion Example - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. suffix usage - 1.2. add_diversion usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements the Diversion extensions as per - draft-levy-sip-diversion-08. The diversion extensions are - useful in various scenarios involving call forwarding. - Typically one needs to communicate the original recipient of - the call to the PSTN gateway and this is what the diversion - extensions can be used for. - -Warning - - The draft-levy-sip-diversion-08 is expired!! See IETF I-D - tracker. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. suffix (string) - - The suffix to be appended to the end of the header field. You - can use the parameter to specify additional parameters to be - added to the header field, see the example. - - Default value is “” (empty string). - - Example 1.1. suffix usage -modparam("diversion", "suffix", ";privacy=full") - -1.4. Exported Functions - -1.4.1. add_diversion(reason, [uri], [counter]) - - The function adds a new diversion header field before any other - existing Diversion header field in the message (the newly added - Diversion header field will become the topmost Diversion header - field). The inbound (without any modifications done by the - proxy server) Request-URI will be used as the Diversion URI. - - Meaning of the parameters is as follows: - * reason (string) - The reason string to be added as the - reason parameter - * uri (string, optional) - The URI to be added in the header. - If missing the unchanged RURI from the original message - will be used. - * counter (int, optional) - Diversion counter to be added to - the header, as defined by the standard. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.2. add_diversion usage -... -add_diversion("user-busy"); -... - -1.5. Diversion Example - - The following example shows a Diversion header field added to - INVITE message. The original INVITE received by the user agent - of sip:bob@sip.org is: -INVITE sip:bob@sip.org SIP/2.0 -Via: SIP/2.0/UDP 1.2.3.4:5060 -From: "mark" ;tag=ldgheoihege -To: "Bob" -Call-ID: adgasdkgjhkjha@1.2.3.4 -CSeq: 3 INVITE -Contact: -Content-Length: 0 - - The INVITE message is diverted by the user agent of - sip:bob@sip.org because the user was talking to someone else - and the new destination is sip:alice@sip.org : -INVITE sip:alice@sip.org SIP/2.0 -Via: SIP/2.0/UDP 5.6.7.8:5060 -Via: SIP/2.0/UDP 1.2.3.4:5060 -From: "mark" ;tag=ldgheoihege -To: "Bob" -Call-ID: adgasdkgjhkjha@1.2.3.4 -CSeq: 3 INVITE -Diversion: ;reason=user-busy -Contact: -Content-Length: 0 - -Chapter 2. Developer Guide - - According to the specification new Diversion header field - should be inserted as the topmost Diversion header field in the - message, that means before any other existing Diversion header - field in the message. In addition to that, add_diversion - function can be called several times and each time it should - insert the new Diversion header field as the topmost one. - - In order to implement this, add_diversion function creates the - anchor in data_lump lists as a static variable to ensure that - the next call of the function will use the same anchor and - would insert new Diversion headers before the one created in - the previous execution. To my knowledge this is the only way of - inserting the diversion header field before any other created - in previous runs of the function. - - The anchor kept this way is only valid for a single message and - we have to invalidate it when another message is being - processed. For this reason, the function also stores the id of - the message in another static variable and compares the value - of that variable with the id of the SIP message being - processed. If they differ then the anchor will be invalidated - and the function creates a new one. - - The following code snippet shows the code that invalidates the - anchor, new anchor will be created when the anchor variable is - set to 0. -static inline int add_diversion_helper(struct sip_msg* msg, str* s) -{ - static struct lump* anchor = 0; - static int msg_id = 0; - - if (msg_id != msg->id) { - msg_id = msg->id; - anchor = 0; - } -... -} - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 17 15 62 32 - 2. Daniel-Constantin Mierla (@miconda) 15 13 28 20 - 3. Liviu Chircu (@liviuchircu) 11 9 16 47 - 4. Jan Janak (@janakj) 10 4 528 13 - 5. Razvan Crainea (@razvancrainea) 6 4 4 2 - 6. Vlad Patrascu (@rvlad-patrascu) 5 3 20 42 - 7. Henning Westerholt (@henningw) 5 3 3 27 - 8. Saúl Ibarra Corretgé (@saghul) 4 2 74 11 - 9. Maksym Sobolyev (@sobomax) 4 2 2 3 - 10. Konstantin Bokarius 3 1 3 5 - - All remaining contributors: Peter Lemenkov (@lemenkov), Edson - Gellert Schubert, Andreas Heise, Vlad Paiu (@vladpaiu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2005 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Vlad Paiu (@vladpaiu) Jun 2012 - Jun 2012 - 8. Saúl Ibarra Corretgé (@saghul) May 2012 - Jun 2012 - 9. Henning Westerholt (@henningw) Apr 2007 - May 2008 - 10. Daniel-Constantin Mierla (@miconda) Oct 2005 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Andreas Heise, Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2004 FhG FOKUS diff --git a/modules/diversion/README.md b/modules/diversion/README.md new file mode 100644 index 00000000000..5e51e313249 --- /dev/null +++ b/modules/diversion/README.md @@ -0,0 +1,179 @@ +--- +title: "Diversion Module" +description: "The module implements the Diversion extensions as per draft-levy-sip-diversion-08." +--- + +## Admin Guide + + +### Overview + + +The module implements the Diversion extensions as per +draft-levy-sip-diversion-08. The +diversion extensions are useful in various scenarios involving call +forwarding. Typically one needs to communicate the original recipient +of the call to the PSTN gateway and this is what the diversion +extensions can be used for. + + +> [!WARNING] +> The draft-levy-sip-diversion-08 is expired!! See +> [IETF I-D tracker](https://datatracker.ietf.org/public/idindex.cgi?command=id_detail∧id=6002). + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### suffix (string) + + +The suffix to be appended to the end of the header field. You can use +the parameter to specify additional parameters to be added to the +header field, see the example. + + +*Default value is "" (empty string).* + + +```opensips title="suffix usage" +modparam("diversion", "suffix", ";privacy=full") +``` + + +### Exported Functions + + +#### add_diversion(reason, [uri], [counter]) + + +The function adds a new diversion header field before any other +existing Diversion header field in the message (the newly added +Diversion header field will become the topmost Diversion header field). +The inbound (without any modifications done by the +proxy server) Request-URI will be used as the Diversion URI. + + +Meaning of the parameters is as follows: + + +- *reason* (string) - The reason string to be added +as the reason parameter +- *uri* (string, optional) - The URI to be added in the header. If missing +the unchanged RURI from the original message will be used. +- *counter* (int, optional) - Diversion counter to be added to the header, as defined by the standard. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="add_diversion usage" +... +add_diversion("user-busy"); +... +``` + + +### Diversion Example + + +The following example shows a Diversion header field added to +INVITE message. The original INVITE received by the user agent +of sip:bob@sip.org is: + + +```c +INVITE sip:bob@sip.org SIP/2.0 +Via: SIP/2.0/UDP 1.2.3.4:5060 +From: "mark" ;tag=ldgheoihege +To: "Bob" +Call-ID: adgasdkgjhkjha@1.2.3.4 +CSeq: 3 INVITE +Contact: +Content-Length: 0 +``` + + +The INVITE message is diverted by the user agent +of sip:bob@sip.org because the user was talking to someone else +and the new destination is sip:alice@sip.org : + + +```c +INVITE sip:alice@sip.org SIP/2.0 +Via: SIP/2.0/UDP 5.6.7.8:5060 +Via: SIP/2.0/UDP 1.2.3.4:5060 +From: "mark" ;tag=ldgheoihege +To: "Bob" +Call-ID: adgasdkgjhkjha@1.2.3.4 +CSeq: 3 INVITE +Diversion: ;reason=user-busy +Contact: +Content-Length: 0 +``` + + +## Developer Guide + + +According to the specification new Diversion header field should be inserted as the topmost +Diversion header field in the message, that means before any other existing Diversion header +field in the message. In addition to that, `add_diversion` function can be called several times and each time +it should insert the new Diversion header field as the topmost one. + + +In order to implement this, add_diversion function creates the anchor in data_lump lists as +a static variable to ensure that the next call of the function will use the same anchor and +would insert new Diversion headers before the one created in the previous execution. To my +knowledge this is the only way of inserting the diversion header field before any other +created in previous runs of the function. + + +The anchor kept this way is only valid for a single message and we have to invalidate it +when another message is being processed. For this reason, the function also stores the id of +the message in another static variable and compares the value of that variable with the id +of the SIP message being processed. If they differ then the anchor will be invalidated and +the function creates a new one. + + +The following code snippet shows the code that invalidates the anchor, new anchor will be +created when the `anchor` variable is set to 0. + + +```c +static inline int add_diversion_helper(struct sip_msg* msg, str* s) +{ + static struct lump* anchor = 0; + static int msg_id = 0; + + if (msg_id != msg->id) { + msg_id = msg->id; + anchor = 0; + } +... +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/diversion/doc/contributors.xml b/modules/diversion/doc/contributors.xml deleted file mode 100644 index b20804c2b1f..00000000000 --- a/modules/diversion/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 17 - 15 - 62 - 32 - - - 2. - Daniel-Constantin Mierla (@miconda) - 15 - 13 - 28 - 20 - - - 3. - Liviu Chircu (@liviuchircu) - 11 - 9 - 16 - 47 - - - 4. - Jan Janak (@janakj) - 10 - 4 - 528 - 13 - - - 5. - Razvan Crainea (@razvancrainea) - 6 - 4 - 4 - 2 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 20 - 42 - - - 7. - Henning Westerholt (@henningw) - 5 - 3 - 3 - 27 - - - 8. - Saúl Ibarra Corretgé (@saghul) - 4 - 2 - 74 - 11 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - 10. - Konstantin Bokarius - 3 - 1 - 3 - 5 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Andreas Heise, Vlad Paiu (@vladpaiu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2005 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Vlad Paiu (@vladpaiu) - Jun 2012 - Jun 2012 - - - 8. - Saúl Ibarra Corretgé (@saghul) - May 2012 - Jun 2012 - - - 9. - Henning Westerholt (@henningw) - Apr 2007 - May 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Oct 2005 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Andreas Heise, Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jan Janak (@janakj). -
- -
diff --git a/modules/diversion/doc/diversion.xml b/modules/diversion/doc/diversion.xml deleted file mode 100644 index b65f0390da8..00000000000 --- a/modules/diversion/doc/diversion.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Diversion Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2004 &fhg; - - diff --git a/modules/diversion/doc/diversion_admin.xml b/modules/diversion/doc/diversion_admin.xml deleted file mode 100644 index 2febd085b55..00000000000 --- a/modules/diversion/doc/diversion_admin.xml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module implements the Diversion extensions as per - draft-levy-sip-diversion-08. The - diversion extensions are useful in various scenarios involving call - forwarding. Typically one needs to communicate the original recipient - of the call to the PSTN gateway and this is what the diversion - extensions can be used for. - - - The draft-levy-sip-diversion-08 is expired!! See - IETF I-D tracker. - -
- -
- Dependencies -
- &osips; Modules - None. -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>suffix</varname> (string) - - The suffix to be appended to the end of the header field. You can use - the parameter to specify additional parameters to be added to the - header field, see the example. - - - Default value is (empty string). - - - <varname>suffix</varname> usage - -modparam("diversion", "suffix", ";privacy=full") - - -
-
-
- Exported Functions -
- <function moreinfo="none">add_diversion(reason, [uri], [counter])</function> - - The function adds a new diversion header field before any other - existing Diversion header field in the message (the newly added - Diversion header field will become the topmost Diversion header field). - The inbound (without any modifications done by the - proxy server) Request-URI will be used as the Diversion URI. - - Meaning of the parameters is as follows: - - - reason (string) - The reason string to be added - as the reason parameter - - - - uri (string, optional) - The URI to be added in the header. If missing - the unchanged RURI from the original message will be used. - - - - counter (int, optional) - Diversion counter to be added to the header, as defined by the standard. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function moreinfo="none">add_diversion</function> usage - -... -add_diversion("user-busy"); -... - - -
-
- -
- Diversion Example - - The following example shows a Diversion header field added to - INVITE message. The original INVITE received by the user agent - of sip:bob@sip.org is: - - -INVITE sip:bob@sip.org SIP/2.0 -Via: SIP/2.0/UDP 1.2.3.4:5060 -From: "mark" <sip:mark@sip.org>;tag=ldgheoihege -To: "Bob" <sip:bob@sip.org> -Call-ID: adgasdkgjhkjha@1.2.3.4 -CSeq: 3 INVITE -Contact: <sip:mark@1.2.3.4> -Content-Length: 0 - - - The INVITE message is diverted by the user agent - of sip:bob@sip.org because the user was talking to someone else - and the new destination is sip:alice@sip.org : - - -INVITE sip:alice@sip.org SIP/2.0 -Via: SIP/2.0/UDP 5.6.7.8:5060 -Via: SIP/2.0/UDP 1.2.3.4:5060 -From: "mark" <sip:mark@sip.org>;tag=ldgheoihege -To: "Bob" <sip:bob@sip.org> -Call-ID: adgasdkgjhkjha@1.2.3.4 -CSeq: 3 INVITE -Diversion: <sip:bob@sip.org>;reason=user-busy -Contact: <sip:mark@1.2.3.4> -Content-Length: 0 - -
-
- diff --git a/modules/diversion/doc/diversion_devel.xml b/modules/diversion/doc/diversion_devel.xml deleted file mode 100644 index 33b82bd9ae5..00000000000 --- a/modules/diversion/doc/diversion_devel.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - &develguide; - - According to the specification new Diversion header field should be inserted as the topmost - Diversion header field in the message, that means before any other existing Diversion header - field in the message. In addition to that, add_diversion function can be called several times and each time - it should insert the new Diversion header field as the topmost one. - - - In order to implement this, add_diversion function creates the anchor in data_lump lists as - a static variable to ensure that the next call of the function will use the same anchor and - would insert new Diversion headers before the one created in the previous execution. To my - knowledge this is the only way of inserting the diversion header field before any other - created in previous runs of the function. - - - The anchor kept this way is only valid for a single message and we have to invalidate it - when another message is being processed. For this reason, the function also stores the id of - the message in another static variable and compares the value of that variable with the id - of the SIP message being processed. If they differ then the anchor will be invalidated and - the function creates a new one. - - - The following code snippet shows the code that invalidates the anchor, new anchor will be - created when the anchor variable is set to 0. - - -static inline int add_diversion_helper(struct sip_msg* msg, str* s) -{ - static struct lump* anchor = 0; - static int msg_id = 0; - - if (msg_id != msg->id) { - msg_id = msg->id; - anchor = 0; - } -... -} - - - diff --git a/modules/dns_cache/README b/modules/dns_cache/README deleted file mode 100644 index 86ecce98aa4..00000000000 --- a/modules/dns_cache/README +++ /dev/null @@ -1,165 +0,0 @@ -dns_cache Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. cachedb_url (string) - 1.3.2. blacklist_timeout (int) - 1.3.3. min_ttl (int) - - 1.4. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set cachedb_url parameter - 1.2. Set blacklist_timeout parameter - 1.3. Set min_ttl parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of a cache system designed for - DNS records. For successful DNS queries of all types, the - module will store in a cache/db backend the mappings, for TTL - number of seconds received in the DNS answer. Failed DNS - queries will also be stored in the back-end, with a TTL that - can be specified by the user. The module uses the Key-Value - interface exported from the core. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - A cachedb_* type module must be loaded before loading the - dns_cache module. - -1.3. Exported Parameters - -1.3.1. cachedb_url (string) - - The url of the key-value back-end that will be used for storing - the DNS records. - - Example 1.1. Set cachedb_url parameter -... -#use internal cachedb_local module -modparam("dns_cache", "cachedb_url","local://") -#use cachedb_memcached module with memcached server at 192.168.2.130 -modparam("dns_cache", "cachedb_url","memcached://192.168.2.130:8888/") -... - -1.3.2. blacklist_timeout (int) - - The number of seconds that a failed DNS query will be kept in - cache. Default is 3600. - - Example 1.2. Set blacklist_timeout parameter -... -modparam("dns_cache", "blacklist_timeout",7200) # 2 hours -... - -1.3.3. min_ttl (int) - - The minimum number of seconds that a DNS record will be kept in - cache. If the TTL received in the DNS answer is lower than this - value, the record will be cached for min_ttl seconds. - - Default value is 0 seconds (no minimum TTL is enforced). - - Example 1.3. Set min_ttl parameter -... -modparam("dns_cache", "min_ttl",300) # 5 minutes -... - -1.4. Exported Functions - - The module does not export functions to be used in - configuration script. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 15 5 1006 3 - 2. Liviu Chircu (@liviuchircu) 13 11 50 48 - 3. Razvan Crainea (@razvancrainea) 11 9 12 14 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 9 7 22 13 - 5. Leo Smith 8 6 32 2 - 6. Maksym Sobolyev (@sobomax) 3 1 2 2 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - 8. Alexandra Titoc 2 1 2 0 - 9. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Leo Smith Mar 2025 - Mar 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2012 - Dec 2024 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 6. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 9. Vlad Paiu (@vladpaiu) Feb 2012 - Oct 2012 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Leo Smith, Razvan Crainea (@razvancrainea), - Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), - Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2012 www.opensips-solutions.com diff --git a/modules/dns_cache/README.md b/modules/dns_cache/README.md new file mode 100644 index 00000000000..63f8ad32cdb --- /dev/null +++ b/modules/dns_cache/README.md @@ -0,0 +1,94 @@ +--- +title: "dns_cache Module" +description: "This module is an implementation of a cache system designed for DNS records." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of a cache system designed for DNS records. +For successful DNS queries of all types, the module will store in a cache/db +backend the mappings, for TTL number of seconds received in the DNS answer. +Failed DNS queries will also be stored in the back-end, with a TTL that can be +specified by the user. +The module uses the Key-Value interface exported from the core. + + +### Dependencies + + +#### OpenSIPS Modules + + +A cachedb_* type module must be loaded before loading +the dns_cache module. + + +### Exported Parameters + + +#### cachedb_url (string) + + +The url of the key-value back-end that will be used +for storing the DNS records. + + +```opensips title="Set cachedb_url parameter" +... +#use internal cachedb_local module +modparam("dns_cache", "cachedb_url","local://") +#use cachedb_memcached module with memcached server at 192.168.2.130 +modparam("dns_cache", "cachedb_url","memcached://192.168.2.130:8888/") +... + +``` + + +#### blacklist_timeout (int) + + +The number of seconds that a failed DNS query will be kept in cache. +Default is 3600. + + +```opensips title="Set blacklist_timeout parameter" +... +modparam("dns_cache", "blacklist_timeout",7200) # 2 hours +... + +``` + + +#### min_ttl (int) + + +The minimum number of seconds that a DNS record will be kept in +cache. If the TTL received in the DNS answer is lower than this +value, the record will be cached for min_ttl seconds. + + +*Default value is **0** seconds (no minimum TTL is enforced).* + + +```opensips title="Set min_ttl parameter" +... +modparam("dns_cache", "min_ttl",300) # 5 minutes +... + +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/dns_cache/doc/contributors.xml b/modules/dns_cache/doc/contributors.xml deleted file mode 100644 index 78cfade2a53..00000000000 --- a/modules/dns_cache/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 15 - 5 - 1006 - 3 - - - 2. - Liviu Chircu (@liviuchircu) - 13 - 11 - 50 - 48 - - - 3. - Razvan Crainea (@razvancrainea) - 11 - 9 - 12 - 14 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 7 - 22 - 13 - - - 5. - Leo Smith - 8 - 6 - 32 - 2 - - - 6. - Maksym Sobolyev (@sobomax) - 3 - 1 - 2 - 2 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 8. - Alexandra Titoc - 2 - 1 - 2 - 0 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Leo Smith - Mar 2025 - Mar 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2012 - Dec 2024 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 6. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 9. - Vlad Paiu (@vladpaiu) - Feb 2012 - Oct 2012 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Leo Smith, Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/dns_cache/doc/dns_cache.xml b/modules/dns_cache/doc/dns_cache.xml deleted file mode 100644 index 98559592fea..00000000000 --- a/modules/dns_cache/doc/dns_cache.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -%docentities; - -]> - - - - dns_cache Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2012 &osipssol; - - - diff --git a/modules/dns_cache/doc/dns_cache_admin.xml b/modules/dns_cache/doc/dns_cache_admin.xml deleted file mode 100644 index e665872d61d..00000000000 --- a/modules/dns_cache/doc/dns_cache_admin.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of a cache system designed for DNS records. - For successful DNS queries of all types, the module will store in a cache/db - backend the mappings, for TTL number of seconds received in the DNS answer. - Failed DNS queries will also be stored in the back-end, with a TTL that can be - specified by the user. - The module uses the Key-Value interface exported from the core. - - - -
- -
- Dependencies -
- &osips; Modules - - A cachedb_* type module must be loaded before loading - the dns_cache module. - -
- -
- -
- Exported Parameters -
- <varname>cachedb_url</varname> (string) - - The url of the key-value back-end that will be used - for storing the DNS records. - - - - Set <varname>cachedb_url</varname> parameter - -... -#use internal cachedb_local module -modparam("dns_cache", "cachedb_url","local://") -#use cachedb_memcached module with memcached server at 192.168.2.130 -modparam("dns_cache", "cachedb_url","memcached://192.168.2.130:8888/") -... - - - -
- -
- <varname>blacklist_timeout</varname> (int) - - The number of seconds that a failed DNS query will be kept in cache. - Default is 3600. - - - - Set <varname>blacklist_timeout</varname> parameter - -... -modparam("dns_cache", "blacklist_timeout",7200) # 2 hours -... - - - -
- -
- <varname>min_ttl</varname> (int) - - The minimum number of seconds that a DNS record will be kept in - cache. If the TTL received in the DNS answer is lower than this - value, the record will be cached for min_ttl seconds. - - - - Default value is 0 seconds (no minimum TTL is enforced). - - - - - Set <varname>min_ttl</varname> parameter - -... -modparam("dns_cache", "min_ttl",300) # 5 minutes -... - - - -
-
- - -
- Exported Functions - The module does not export functions to be used - in configuration script. -
- -
- diff --git a/modules/domain/README b/modules/domain/README deleted file mode 100644 index 100057d79dc..00000000000 --- a/modules/domain/README +++ /dev/null @@ -1,375 +0,0 @@ -domain Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_mode (integer) - 1.3.3. domain_table (string) - 1.3.4. domain_col (string) - 1.3.5. attrs_col (string) - 1.3.6. subdomain_col (int) - - 1.4. Exported Functions - - 1.4.1. is_from_local([attrs_var]) - 1.4.2. is_uri_host_local([attrs_var]) - 1.4.3. is_domain_local(domain, [attrs_var]) - - 1.5. Exported MI Functions - - 1.5.1. domain_reload - 1.5.2. domain_dump - - 1.6. Known Limitations - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. is_domain_local(domain) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting db_url parameter - 1.2. db_mode example - 1.3. Setting domain_table parameter - 1.4. Setting domain_col parameter - 1.5. Setting attrs_col parameter - 1.6. Setting subdomain_col parameter - 1.7. is_from_local usage - 1.8. is_uri_host_local usage - 1.9. is_domain_local usage - -Chapter 1. Admin Guide - -1.1. Overview - - Domain module implements checks that based on domain table - determine if a host part of an URI is “local” or not. A “local” - domain is one that the proxy is responsible for. - - Domain module operates in caching or non-caching mode depending - on value of module parameter db_mode. In caching mode domain - module reads the contents of domain table into cache memory - when the module is loaded. After that domain table is re-read - only when module is given domain_reload fifo command. Any - changes in domain table must thus be followed by - “domain_reload” command in order to reflect them in module - behavior. In non-caching mode domain module always queries - domain table in the database. - - Caching is implemented using a hash table. The size of the hash - table is given by HASH_SIZE constant defined in domain_mod.h. - Its “factory default” value is 128. - -1.2. Dependencies - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * database -- Any database module - -1.3. Exported Parameters - -1.3.1. db_url (string) - - This is URL of the database to be used. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips” - - Example 1.1. Setting db_url parameter -modparam("domain", "db_url", "mysql://ser:pass@db_host/ser") - -1.3.2. db_mode (integer) - - Database mode: 0 means non-caching, 1 means caching. - - Default value is 0 (non-caching). - - Example 1.2. db_mode example -modparam("domain", "db_mode", 1) # Use caching - -1.3.3. domain_table (string) - - Name of table containing names of local domains that the proxy - is responsible for. Local users must have in their sip uri a - host part that is equal to one of these domains. - - Default value is “domain”. - - Example 1.3. Setting domain_table parameter -modparam("domain", "domain_table", "new_name") - -1.3.4. domain_col (string) - - Name of column containing domains in domain table. - - Default value is “domain”. - - Example 1.4. Setting domain_col parameter -modparam("domain", "domain_col", "domain_name") - -1.3.5. attrs_col (string) - - Name of column containing attributes in domain table. - - Default value is “attrs”. - - Example 1.5. Setting attrs_col parameter -modparam("domain", "attrs_col", "attributes") - -1.3.6. subdomain_col (int) - - Name of the "accept_subdomain" column in the domain table. A - positive value for the column means the domain accepts - subdomains. A 0 value means it does not. - - Default value is “accept_subdomain”. - - Example 1.6. Setting subdomain_col parameter -modparam("domain", "subdomain_col", "has_subdomain") - -1.4. Exported Functions - -1.4.1. is_from_local([attrs_var]) - - Checks based on domain table if host part of From header uri is - one of the local domains that the proxy is responsible for. The - argument is optional and if present it should contain a - writable variable that will be populated with the attributes - from the database. - - This function can be used from REQUEST_ROUTE. - - Example 1.7. is_from_local usage -... -if (is_from_local()) { - ... -}; -... -if (is_from_local($var(attrs))) { - xlog("Domain attributes are $var(attrs)\n"); - ... -}; -... - -1.4.2. is_uri_host_local([attrs_var]) - - If called from route or failure route block, checks based on - domain table if host part of Request-URI is one of the local - domains that the proxy is responsible for. If called from - branch route, the test is made on host part of URI of first - branch, which thus must have been appended to the transaction - before is_uri_host_local() is called. The argument is optional - and if present it should contain a writable variable that will - be populated with the attributes from the database. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.8. is_uri_host_local usage -... -if (is_uri_host_local()) { - ... -}; -... -if (is_uri_host_local($var(attrs))) { - xlog("Domain attributes are $var(attrs)\n"); - ... -}; - -1.4.3. is_domain_local(domain, [attrs_var]) - - This function checks if the domain contained in the first - parameter is local. - - This function is a generalized form of the is_from_local() and - is_uri_host_local() functions, being able to completely replace - them and also extends them by allowing the domain to be taken - from any of the above mentioned sources. The following - equivalences exist: - * is_domain_local($rd) is same as is_uri_host_local() - * is_domain_local($fd) is same as is_from_local() - - Parameters: - * domain (string) - * attrs_var (var, optional) - a writable variable that will - be populated with the attributes from the database. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.9. is_domain_local usage -... -if (is_domain_local($rd)) { - ... -}; -if (is_domain_local($fd)) { - ... -}; -if (is_domain_local($avp(some_avp_alias))) { - ... -}; -if (is_domain_local($avp(850))) { - ... -}; -if (is_domain_local($avp(some_avp))) { - ... -}; -if (is_domain_local($avp(some_avp), $avp(attrs))) { - xlog("Domain attributes are $avp(attrs)\n"); - ... -}; -... - -1.5. Exported MI Functions - -1.5.1. domain_reload - - Causes domain module to re-read the contents of domain table - into cache memory. - - Name: domain_reload - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi domain_reload - -1.5.2. domain_dump - - Causes domain module to dump hash indexes and domain names in - its cache memory. - - Name: domain_dump - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi domain_dump - -1.6. Known Limitations - - There is an unlikely race condition on domain list update. If a - process uses a table, which is reloaded at the same time twice - through FIFO, the second reload will delete the original table - still in use by the process. - -Chapter 2. Developer Guide - - The module provides is_domain_local API function for use by - other OpenSIPS modules. - -2.1. Available Functions - -2.1.1. is_domain_local(domain) - - Checks if domain given in str* parameter is local. - - The function returns 1 if domain is local and -1 if domain is - not local or if an error occurred. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 58 44 446 561 - 2. Jan Janak (@janakj) 32 21 999 113 - 3. Juha Heinanen (@juha-h) 30 20 700 233 - 4. Razvan Crainea (@razvancrainea) 22 15 290 226 - 5. Daniel-Constantin Mierla (@miconda) 19 16 92 79 - 6. Liviu Chircu (@liviuchircu) 12 9 46 110 - 7. Vlad Patrascu (@rvlad-patrascu) 9 5 96 123 - 8. Dan Pascu (@danpascu) 8 4 232 101 - 9. Andrei Pelinescu-Onciul 8 4 186 121 - 10. Henning Westerholt (@henningw) 7 5 44 48 - - All remaining contributors: Edson Gellert Schubert, David - Trihy, Elena-Ramona Modroiu, Maksym Sobolyev (@sobomax), Jiri - Kuthan (@jiriatipteldotorg), @coxx, Konstantin Bokarius, Klaus - Darilion, Anca Vamanu, Norman Brandinger (@NormB), Peter - Lemenkov (@lemenkov), Stefan Darius, UnixDev, Andreas Granig, - John Burke (@john08burke). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - Aug 2025 - 2. Razvan Crainea (@razvancrainea) Jun 2011 - May 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2025 - 4. David Trihy May 2025 - May 2025 - 5. Stefan Darius Jul 2024 - Jul 2024 - 6. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 7. John Burke (@john08burke) Jan 2022 - Jan 2022 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. @coxx Mar 2010 - Mar 2010 - - All remaining contributors: Anca Vamanu, UnixDev, Juha Heinanen - (@juha-h), Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Dan Pascu (@danpascu), Norman Brandinger - (@NormB), Andreas Granig, Klaus Darilion, Jan Janak (@janakj), - Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), - Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Juha Heinanen (@juha-h), Elena-Ramona - Modroiu, Dan Pascu (@danpascu), Klaus Darilion, Jan Janak - (@janakj). - - Documentation Copyrights: - - Copyright © 2002-2008 Juha Heinanen diff --git a/modules/domain/README.md b/modules/domain/README.md new file mode 100644 index 00000000000..42c8a789596 --- /dev/null +++ b/modules/domain/README.md @@ -0,0 +1,332 @@ +--- +title: "domain Module" +description: "Domain module implements checks that based on domain table determine if a host part of an URI is local or not." +--- + +## Admin Guide + + +### Overview + + +Domain module implements checks that based on domain table determine +if a host part of an URI is "local" or +not. A "local" domain is one that the proxy is responsible +for. + + +Domain module operates in caching or non-caching mode depending on +value of module parameter `db_mode`. +In caching mode domain module reads the contents of domain table into +cache memory when the module is loaded. After that domain table is +re-read only when module is given domain_reload fifo command. Any +changes in domain table must thus be followed by +"domain_reload" command in order to reflect them in +module behavior. In non-caching mode domain module always queries domain +table in the database. + + +Caching is implemented using a hash table. The size of the hash table +is given by HASH_SIZE constant defined in domain_mod.h. +Its "factory default" value is 128. + + +### Dependencies + + +The module depends on the following modules (in the other words the +listed modules must be loaded before this module): + + +- *database* -- Any database module + + +### Exported Parameters + + +#### db_url (string) + + +This is URL of the database to be used. + + +Default value is +"mysql://opensipsro:opensipsro@localhost/opensips" + + +```opensips title="Setting db_url parameter" +modparam("domain", "db_url", "mysql://ser:pass@db_host/ser") +``` + + +#### db_mode (integer) + + +Database mode: 0 means non-caching, 1 means caching. + + +Default value is 0 (non-caching). + + +```opensips title="db_mode example" +modparam("domain", "db_mode", 1) # Use caching +``` + + +#### domain_table (string) + + +Name of table containing names of local domains that the proxy is +responsible for. Local users must have in their sip uri a host part +that is equal to one of these domains. + + +Default value is "domain". + + +```opensips title="Setting domain_table parameter" +modparam("domain", "domain_table", "new_name") +``` + + +#### domain_col (string) + + +Name of column containing domains in domain table. + + +Default value is "domain". + + +```opensips title="Setting domain_col parameter" +modparam("domain", "domain_col", "domain_name") +``` + + +#### attrs_col (string) + + +Name of column containing attributes in domain table. + + +Default value is "attrs". + + +```opensips title="Setting attrs_col parameter" +modparam("domain", "attrs_col", "attributes") +``` + + +#### subdomain_col (int) + + +Name of the "accept_subdomain" column in the domain table. +A positive value for the column means the domain accepts subdomains. +A 0 value means it does not. + + +Default value is "accept_subdomain". + + +```opensips title="Setting subdomain_col parameter" +modparam("domain", "subdomain_col", "has_subdomain") +``` + + +### Exported Functions + + +#### is_from_local([attrs_var]) + + +Checks based on domain table if host part of From header uri is +one of the local domains that the proxy is responsible for. +The argument is optional and if present it should contain a writable +variable that will be populated with the attributes from the +database. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="is_from_local usage" +... +if (is_from_local()) { + ... +}; +... +if (is_from_local($var(attrs))) { + xlog("Domain attributes are $var(attrs)\n"); + ... +}; +... + +``` + + +#### is_uri_host_local([attrs_var]) + + +If called from route or failure route block, checks +based on domain table if host part of Request-URI is one +of the local domains that the proxy is responsible for. +If called from branch route, the test is made on host +part of URI of first branch, which thus must have been +appended to the transaction before is_uri_host_local() +is called. +The argument is optional and if present it should contain a writable +variable that will be populated with the attributes from the +database. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE. + + +```opensips title="is_uri_host_local usage" +... +if (is_uri_host_local()) { + ... +}; +... +if (is_uri_host_local($var(attrs))) { + xlog("Domain attributes are $var(attrs)\n"); + ... +}; + +``` + + +#### is_domain_local(domain, [attrs_var]) + + +This function checks if the domain contained in the first parameter is local. + + +This function is a generalized form of the is_from_local() +and is_uri_host_local() functions, being able to completely +replace them and also extends them by allowing the domain to +be taken from any of the above mentioned sources. +The following equivalences exist: + + +- is_domain_local($rd) is same as is_uri_host_local() +- is_domain_local($fd) is same as is_from_local() + + +Parameters: + + +- *domain* (string) +- *attrs_var* (var, optional) - a writable +variable that will be populated with the attributes from the +database. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE. + + +```opensips title="is_domain_local usage" +... +if (is_domain_local($rd)) { + ... +}; +if (is_domain_local($fd)) { + ... +}; +if (is_domain_local($avp(some_avp_alias))) { + ... +}; +if (is_domain_local($avp(850))) { + ... +}; +if (is_domain_local($avp(some_avp))) { + ... +}; +if (is_domain_local($avp(some_avp), $avp(attrs))) { + xlog("Domain attributes are $avp(attrs)\n"); + ... +}; +... + +``` + + +### Exported MI Functions + + +#### domain_reload + + +Causes domain module to re-read the contents of domain table +into cache memory. + + +Name: *domain_reload* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi domain_reload +``` + + +#### domain_dump + + +Causes domain module to dump hash indexes and domain names in +its cache memory. + + +Name: *domain_dump* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi domain_dump +``` + + +### Known Limitations + + +There is an unlikely race condition on domain list update. If a +process uses a table, which is reloaded at the same time twice +through FIFO, the second reload will delete the +original table still in use by the process. + + +## Developer Guide + + +The module provides is_domain_local API +function for use by other OpenSIPS modules. + + +### Available Functions + + +#### is_domain_local(domain) + + +Checks if domain given in str* parameter is local. + + +The function returns 1 if domain is local and -1 if +domain is not local or if an error occurred. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/domain/doc/contributors.xml b/modules/domain/doc/contributors.xml deleted file mode 100644 index a0d707d2d7a..00000000000 --- a/modules/domain/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 58 - 44 - 446 - 561 - - - 2. - Jan Janak (@janakj) - 32 - 21 - 999 - 113 - - - 3. - Juha Heinanen (@juha-h) - 30 - 20 - 700 - 233 - - - 4. - Razvan Crainea (@razvancrainea) - 22 - 15 - 290 - 226 - - - 5. - Daniel-Constantin Mierla (@miconda) - 19 - 16 - 92 - 79 - - - 6. - Liviu Chircu (@liviuchircu) - 12 - 9 - 46 - 110 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 9 - 5 - 96 - 123 - - - 8. - Dan Pascu (@danpascu) - 8 - 4 - 232 - 101 - - - 9. - Andrei Pelinescu-Onciul - 8 - 4 - 186 - 121 - - - 10. - Henning Westerholt (@henningw) - 7 - 5 - 44 - 48 - - - -
-All remaining contributors: Edson Gellert Schubert, David Trihy, Elena-Ramona Modroiu, Maksym Sobolyev (@sobomax), Jiri Kuthan (@jiriatipteldotorg), @coxx, Konstantin Bokarius, Klaus Darilion, Anca Vamanu, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Stefan Darius, UnixDev, Andreas Granig, John Burke (@john08burke). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - Aug 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jun 2011 - May 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2025 - - - 4. - David Trihy - May 2025 - May 2025 - - - 5. - Stefan Darius - Jul 2024 - Jul 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 7. - John Burke (@john08burke) - Jan 2022 - Jan 2022 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - @coxx - Mar 2010 - Mar 2010 - - - -
-All remaining contributors: Anca Vamanu, UnixDev, Juha Heinanen (@juha-h), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Dan Pascu (@danpascu), Norman Brandinger (@NormB), Andreas Granig, Klaus Darilion, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Dan Pascu (@danpascu), Klaus Darilion, Jan Janak (@janakj). -
- -
diff --git a/modules/domain/doc/domain.xml b/modules/domain/doc/domain.xml deleted file mode 100644 index 20960059ea8..00000000000 --- a/modules/domain/doc/domain.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - domain Module - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2002-2008 Juha Heinanen - - diff --git a/modules/domain/doc/domain_admin.xml b/modules/domain/doc/domain_admin.xml deleted file mode 100644 index 5437f0aed73..00000000000 --- a/modules/domain/doc/domain_admin.xml +++ /dev/null @@ -1,319 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Domain module implements checks that based on domain table determine - if a host part of an URI is local or - not. A local domain is one that the proxy is responsible - for. - - - Domain module operates in caching or non-caching mode depending on - value of module parameter db_mode. - In caching mode domain module reads the contents of domain table into - cache memory when the module is loaded. After that domain table is - re-read only when module is given domain_reload fifo command. Any - changes in domain table must thus be followed by - domain_reload command in order to reflect them in - module behavior. In non-caching mode domain module always queries domain - table in the database. - - - Caching is implemented using a hash table. The size of the hash table - is given by HASH_SIZE constant defined in domain_mod.h. - Its factory default value is 128. - -
- -
- Dependencies - - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): - - - database -- Any database module - - - -
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - This is URL of the database to be used. - - - Default value is - mysql://opensipsro:opensipsro@localhost/opensips - - - Setting db_url parameter - -modparam("domain", "db_url", "mysql://ser:pass@db_host/ser") - - -
-
- <varname>db_mode</varname> (integer) - - Database mode: 0 means non-caching, 1 means caching. - - - Default value is 0 (non-caching). - - - db_mode example - -modparam("domain", "db_mode", 1) # Use caching - - -
-
- <varname>domain_table</varname> (string) - - Name of table containing names of local domains that the proxy is - responsible for. Local users must have in their sip uri a host part - that is equal to one of these domains. - - - Default value is domain. - - - Setting domain_table parameter - -modparam("domain", "domain_table", "new_name") - - -
-
- <varname>domain_col</varname> (string) - - Name of column containing domains in domain table. - - - Default value is domain. - - - Setting domain_col parameter - -modparam("domain", "domain_col", "domain_name") - - -
-
- <varname>attrs_col</varname> (string) - - Name of column containing attributes in domain table. - - - Default value is attrs. - - - Setting attrs_col parameter - -modparam("domain", "attrs_col", "attributes") - - -
-
- <varname>subdomain_col</varname> (int) - - Name of the "accept_subdomain" column in the domain table. - A positive value for the column means the domain accepts subdomains. - A 0 value means it does not. - - - Default value is accept_subdomain. - - - Setting subdomain_col parameter - -modparam("domain", "subdomain_col", "has_subdomain") - - -
- -
-
- Exported Functions -
- <function moreinfo="none">is_from_local([attrs_var])</function> - - Checks based on domain table if host part of From header uri is - one of the local domains that the proxy is responsible for. - The argument is optional and if present it should contain a writable - variable that will be populated with the attributes from the - database. - - - This function can be used from REQUEST_ROUTE. - - - is_from_local usage - -... -if (is_from_local()) { - ... -}; -... -if (is_from_local($var(attrs))) { - xlog("Domain attributes are $var(attrs)\n"); - ... -}; -... - - -
-
- <function moreinfo="none">is_uri_host_local([attrs_var])</function> - - If called from route or failure route block, checks - based on domain table if host part of Request-URI is one - of the local domains that the proxy is responsible for. - If called from branch route, the test is made on host - part of URI of first branch, which thus must have been - appended to the transaction before is_uri_host_local() - is called. - The argument is optional and if present it should contain a writable - variable that will be populated with the attributes from the - database. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - - is_uri_host_local usage - -... -if (is_uri_host_local()) { - ... -}; -... -if (is_uri_host_local($var(attrs))) { - xlog("Domain attributes are $var(attrs)\n"); - ... -}; - - -
-
- <function moreinfo="none">is_domain_local(domain, [attrs_var])</function> - - This function checks if the domain contained in the first parameter is local. - - - This function is a generalized form of the is_from_local() - and is_uri_host_local() functions, being able to completely - replace them and also extends them by allowing the domain to - be taken from any of the above mentioned sources. - The following equivalences exist: - - - - is_domain_local($rd) is same as is_uri_host_local() - - - is_domain_local($fd) is same as is_from_local() - - - Parameters: - - - domain (string) - - - attrs_var (var, optional) - a writable - variable that will be populated with the attributes from the - database. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - - is_domain_local usage - -... -if (is_domain_local($rd)) { - ... -}; -if (is_domain_local($fd)) { - ... -}; -if (is_domain_local($avp(some_avp_alias))) { - ... -}; -if (is_domain_local($avp(850))) { - ... -}; -if (is_domain_local($avp(some_avp))) { - ... -}; -if (is_domain_local($avp(some_avp), $avp(attrs))) { - xlog("Domain attributes are $avp(attrs)\n"); - ... -}; -... - - -
-
-
- Exported MI Functions -
- <function moreinfo="none">domain_reload</function> - - Causes domain module to re-read the contents of domain table - into cache memory. - - - Name: domain_reload - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi domain_reload - - -
-
- <function moreinfo="none">domain_dump</function> - - Causes domain module to dump hash indexes and domain names in - its cache memory. - - - Name: domain_dump - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi domain_dump - -
-
-
- Known Limitations - - There is an unlikely race condition on domain list update. If a - process uses a table, which is reloaded at the same time twice - through FIFO, the second reload will delete the - original table still in use by the process. - -
-
- diff --git a/modules/domain/doc/domain_devel.xml b/modules/domain/doc/domain_devel.xml deleted file mode 100644 index a8866399ddb..00000000000 --- a/modules/domain/doc/domain_devel.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - &develguide; - - The module provides is_domain_local API - function for use by other &osips; modules. - -
- Available Functions -
- - <function moreinfo="none">is_domain_local(domain)</function> - - - Checks if domain given in str* parameter is local. - - - The function returns 1 if domain is local and -1 if - domain is not local or if an error occurred. - -
-
-
- diff --git a/modules/domainpolicy/README b/modules/domainpolicy/README deleted file mode 100644 index 81181321f75..00000000000 --- a/modules/domainpolicy/README +++ /dev/null @@ -1,574 +0,0 @@ -Domain Policy Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. dp_table (string) - 1.3.3. dp_col_rule (string) - 1.3.4. dp_col_type (string) - 1.3.5. dp_col_att (string) - 1.3.6. dp_col_val (string) - 1.3.7. port_override_avp (string) - 1.3.8. transport_override_avp (string) - 1.3.9. domain_replacement_avp (string) - 1.3.10. domain_prefix_avp (string) - 1.3.11. domain_suffix_avp (string) - 1.3.12. send_socket_avp (string) - - 1.4. Exported Functions - - 1.4.1. dp_can_connect() - 1.4.2. dp_apply_policy() - - 1.5. FIFO Commands - 1.6. Usage Scenarios - - 1.6.1. TLS Based Federation - 1.6.2. SIP Hub based Federation - 1.6.3. Walled Garden Federation - - 1.7. Known Limitations - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting db_url parameter - 1.2. Setting dp_table parameter - 1.3. Setting dp_col_rule parameter - 1.4. Setting dp_col_rule parameter - 1.5. Setting dp_col_att parameter - 1.6. Setting dp_col_val parameter - 1.7. Setting port_override_avp parameter - 1.8. Setting transport_override_avp parameter - 1.9. Setting domain_replacement_avp parameter - 1.10. Setting domain_prefix_avp parameter - 1.11. Setting domain_suffix_avp parameter - 1.12. Setting send_socket_avp parameter - 1.13. dp_can_connect usage - 1.14. dp_apply_policy usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Domain Policy module implements - draft-lendl-domain-policy-ddds-02 in combination with - draft-lendl-speermint-federations-02 and - draft-lendl-speermint-technical-policy-00. These drafts define - DNS records with which a domain can announce its federation - memberships. A local database can be used to map policy rules - to routing policy decisions. This database can also contain - rules concerning destination domains independently of - draft-lendl-domain-policy-ddds-02. - - This module requires a database. No caching is implemented. - -1.2. Dependencies - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * database -- Any database module - -1.3. Exported Parameters - -1.3.1. db_url (string) - - This is URL of the database to be used. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips” - - Example 1.1. Setting db_url parameter -modparam("domainpolicy", "db_url", "postgresql://user:pass@db_host/opens -ips") - -1.3.2. dp_table (string) - - Name of table containing the local support domain policy setup. - - Default value is “domainpolicy”. - - Example 1.2. Setting dp_table parameter -modparam("domainpolicy", "dp_table", "supportedpolicies") - -1.3.3. dp_col_rule (string) - - Name of column containing the domain policy rule name which is - equal to the URI as published in the domain policy NAPTRs. - - Default value is “rule”. - - Example 1.3. Setting dp_col_rule parameter -modparam("domainpolicy", "dp_col_rule", "rules") - -1.3.4. dp_col_type (string) - - Name of column containing the domain policy rule type. In the - case of federation names, this is "fed". For standard referrals - according to draft-lendl-speermint-technical-policy-00, this is - "std". For direct domain lookups, this is "dom". - - Default value is “type”. - - Example 1.4. Setting dp_col_rule parameter -modparam("domainpolicy", "dp_col_type", "type") - -1.3.5. dp_col_att (string) - - Name of column containing the AVP's name. If the rule stored in - this row triggers, than dp_can_connect() will add an AVP with - that name. - - Default value is “att”. - - Example 1.5. Setting dp_col_att parameter -modparam("domainpolicy", "dp_col_att", "attribute") - -1.3.6. dp_col_val (string) - - Name of column containing the value for AVPs created by - dp_can_connect(). - - Default value is “val”. - - Example 1.6. Setting dp_col_val parameter -modparam("domainpolicy", "dp_col_val", "values") - -1.3.7. port_override_avp (string) - - This parameter defines the name of the AVP where - dp_apply_policy() will look for an override port number. - - Default value is “portoverride”. - - Example 1.7. Setting port_override_avp parameter -# string named AVP -modparam("domainpolicy", "port_override_avp", "portoverride") - -1.3.8. transport_override_avp (string) - - Name of the AVP which contains the override transport setting. - - Default value is “transportoverride”. - - Example 1.8. Setting transport_override_avp parameter -# string named AVP -modparam("domainpolicy", "transport_override_avp", "transportoverride") - -1.3.9. domain_replacement_avp (string) - - Name of the AVP which contains a domain replacement. - - Default value is “domainreplacement”. - - Example 1.9. Setting domain_replacement_avp parameter -# string named AVP -modparam("domainpolicy", "domain_replacement_avp", "domainreplacement") - -1.3.10. domain_prefix_avp (string) - - Name of the AVP which contains a domain prefix. - - Default value is “domainprefix”. - - Example 1.10. Setting domain_prefix_avp parameter -# string named AVP -modparam("domainpolicy", "domain_prefix_avp", "domainprefix") - -1.3.11. domain_suffix_avp (string) - - Name of the AVP which contains a domain suffix. - - Default value is “domainsuffix”. - - Example 1.11. Setting domain_suffix_avp parameter -# string named AVP -modparam("domainpolicy", "domain_suffix_avp", "domainsuffix") - -1.3.12. send_socket_avp (string) - - Name of the AVP which contains a send_socket. The format of the - send socket (the payload of this AVP) must be in the format - [proto:]ip_address[:port]. The function dp_apply_policy will - look for this AVP and if defined, it will force the send socket - to its value (smilar to the force_send_socket core function). - - Default value is “sendsocket”. - - Example 1.12. Setting send_socket_avp parameter -# string named AVP -modparam("domainpolicy", "send_socket_avp", "sendsocket") - -1.4. Exported Functions - -1.4.1. dp_can_connect() - - Checks the interconnection policy of the caller. It uses the - domain in the request URI to perform the DP-DDDS algorithm - according to draft-lendl-domain-policy-ddds-02 to retrieve the - domain's policy announcements. As of this version, only records - conforming to draft-lendl-speermint-federations-02 and - draft-lendl-speermint-technical-policy-00 are supported. - - Non-terminal NAPTR records will cause recursion to the - replacement domain. dp_can_connect() will thus look for policy - rules in the referenced domain. Furthermore, an AVP for - "domainreplacement" (containing the new domain) will be added - to the call. This will redirect SRV/A record lookups to the new - domain. - - In order to simplify direct domain-based peerings all - destination domains are treated as if they contain a top - priority "D2P+SIP:dom" rule with the domain itself as the value - of the rule. Thus any database row with type = 'dom' and rule = - 'example.com' will override any dynamic DNS-discovered rules. - - For NAPTRs with service-type "D2P+SIP:fed", the federation IDs - (as extracted from the regexp field) are used to retrieve - policy records from a local local database (basically: "SELECT - dp_col_att, dp_col_val FROM dp_table WHERE dp_col_rule = - '[federationID]' AND type = 'fed'). If records are found (and - all other records with the same order value are fulfillable) - then AVPs will be created from the dp_col_att and dp_col_val - columns. - - For NAPTRs with service-type "D2P+SIP:std", the same procedure - is performed. This time, the database lookup searched for type - = 'std', though. - - "D2P+SIP:fed" and "D2P+SIP:std" can be mixed freely. If two - rules with the same "order" match and try to set the same AVP, - then the behaviour is undefined. - - The dp_col_att column specifies the AVP's name. If the AVP - start with "s:" or "i:", the corresponding AVP type (string - named or integer named) will be generated. If the excat - specifier is omited, the AVP type will be guessed. - - The dp_col_val column will always be interpreted as string. - Thus, the AVP's value is always string based. - - dp_can_connect returns: - * -2: on errors during the evaluation. (DNS, DB, ...) - * -1: D2P+SIP records were found, but the policy is not - fullfillable. - * 1: D2P+SIP records were found and a call is possible - * 2: No D2P+SIP records were found. The destination domain - does not announce a policy for incoming SIP calls. - - This function can be used from REQUEST_ROUTE. - - Example 1.13. dp_can_connect usage -... -dp_can_connect(); -switch(retcode) { - case -2: - xlog("L_INFO","Errors during the DP evaluation\n"); - sl_send_reply(404, "We can't connect you."); - break; - case -1: - xlog("L_INFO","We can't connect to that domain\n"); - sl_send_reply(404, "We can't connect you."); - break; - case 1: - xlog("L_INFO","We found matching policy records\n"); - avp_print(); - dp_apply_policy(); - t_relay(); - break; - case 2: - xlog("L_INFO","No DP records found\n"); - t_relay(); - break; -} -... - -1.4.2. dp_apply_policy() - - This function sets the destination URI according to the policy - returned from the dp_can_connect() function. Parameter exchange - between dp_can_connect() and dp_apply_policy() is done via - AVPs. The AVPs can be configured in the module's parameter - section. - - Note: The name of the AVPs must correspond with the names in - the att column in the domainpolicy table. - - Setting the following AVPs in dp_can_connect() (or by any other - means) cause the following actions in dp_apply_policy(): - * port_override_avp: If this AVP is set, the port in the - destination URI is set to this port. Setting an override - port disables NAPTR and SRV lookups according to RFC 3263. - - * transport_override_avp: If this AVP is set, the transport - parameter in the destination URI is set to the specified - transport ("udp", "tcp", "tls"). Setting an override - transport also disables NAPTR lookups, but retains an SRV - lookup according to RFC 3263. - - * domain_replacement_avp: If this AVP is set, the domain in - the destination URI will be replaced by this domain. - A non-terminal NAPTR and thus a referral to a new domain - implicitly sets domain_replacement_avp to the new domain. - - * domain_prefix_avp: If this AVP is set, the domain in the - destination URI will be prefixed with this "subdomain". - E.g. if the domain in the request URI is "example.com" and - the domain_prefix_avp contains "inbound", the domain in the - destinaton URI is set to "inbound.example.com". - - * domain_suffix_avp: If this AVP is set, the domain in the - destination URI will have the content of the AVP appended - to it. E.g. if the domain in the request URI is - "example.com" and the domain_suffix_avp contains - "myroot.com", the domain in the destination URI is set to - "example.com.myroot.com". - - * send_socket_avp: If this AVP is set, the sending socket - will be forced to the socket in the AVP. The payload format - of this AVP must be [proto:]ip_address[:port]. - - If both prefix/suffix and domain replacements are used, then - the replacement is performed first and the prefix/suffix are - applied to the new domain. - - This function can be used from REQUEST_ROUTE. - - Example 1.14. dp_apply_policy usage -... -if (dp_apply_policy()) { - t_relay(); -} -... - -1.5. FIFO Commands - -1.6. Usage Scenarios - - This section describes how this module can be use to implement - selective VoIP peerings. - -1.6.1. TLS Based Federation - - This example shows how a secure peering fabric can be - configured based on TLS and Domain Policies. - - Let's assume that an organization called "TLSFED.org" acts as - an umbrella for VoIP providers who want to peer with each other - but don't want to run open SIP proxies. TLSFED.org's secretary - acts as an X.509 Certification Authority that signs the TLS - keys of all member's SIP proxies. Each member should - automatically allow incoming calls from other members. On the - other hand, the configuration for this federation must not - interfere with a member's participation in other VoIP peering - fabrics. All this can be achieved by the following - configuration for a participating VoIP operation called - example.com: - * Incoming SIP configuration - Calls from other members are expected to use TLS and - authenticate using a client-CERT. To implement this, we - cannot share a TCP/TLS port with other incoming connection. - Thus we need to use tls_server_domain[] to dedicate a TCP - port for this federation. - -tls_server_domain[1.2.3.4:5066] { - tls_certificate = "/path/to/tlsfed/example-com.key" - tls_private_key = "/path/to/tlsfed/example-com.crt" - tls_ca_list = "/path/to/tlsfed/ca.pem" - tls_method = tlsv1 - tls_verify_client = 1 - tls_require_cleint_certificate = 1 -} - - - * Outgoing SIP configuration - Calls to other members also must use the proper client - cert. Therefore, a TLS client domain must be configured. We - use the federation name as TLS client domain identifier. - Therefore, the content of the "tls_client_domain_avp" must - be set to this identifier (e.g. by putting it as rule into - the domainpolicy table). - -tls_client_domain["tlsfed"] { - tls_certificate = "/path/to/tlsfed/example-com.key" - tls_private_key = "/path/to/tlsfed/example-com.crt" - tls_ca_list = "/path/to/tlsfed/ca.pem" - tls_method = tlsv1 - tls_verify_server = 1 -} - -1.6.2. SIP Hub based Federation - - This example shows how a peering fabric based on a central SIP - hub can be configured. - - Let's assume that an organization called "HUBFED.org" acts as - an umbrella for VoIP providers who want to peer with each other - but don't want to run open SIP proxies. Instead, HUBFED.org - operates a central SIP proxy which will relay calls between all - participating members. Each member thus only needs to allow - incoming calls from that central hub (which could be done by - firewalling). All this can be achieved by the following - configuration for a participating VoIP operation called - example.com: - * DNS configuration - The destination network announces its membership in this - federation. - -$ORIGIN destination.example.org -@ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( - "!^.*$!http://HUBFED.org/!" . ) - - - * Outgoing SIP configuration - Calls to other members need to be redirected to the central - proxy. The domainpolicy table just needs to list the - federation and link it to the central proxy's domain name: - -mysql> select * from domainpolicy; -+----+--------------------+------+-------------------+----------------+ -| id | rule | type | att | val | -+----+--------------------+------+-------------------+----------------+ -| 1 | http://HUBFED.org/ | fed | domainreplacement | sip.HUBFED.org | -+----+--------------------+------+-------------------+----------------+ - - -1.6.3. Walled Garden Federation - - This example assumes that a set of SIP providers have - established a secure Layer 3 network between their proxies. It - does not matter whether this network is build by means of - IPsec, a private Layer 2 network, or by simple firewalling. We - will use the 10.x network (for the walled garden net) and - "http://l3fed.org/" (as federation identifier) in this example. - - A member of this federation (e.g. example.com) can not announce - its SIP proxy's 10.x address in the standard SRV / A records of - his domain, as this address is only meaningful for other - members of this federation. In order to facilite different IP - address resolution paths within the federation vs. outside the - federation, all members of "http://l3fed.org/" agree to prefix - the destination domains with "l3fed" before the SRV (or A) - lookup. - - Here is the configuration for example.com: - * DNS configuration - The destination network announces its membership in this - federation. - -$ORIGIN example.com -@ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( - "!^.*$!http://l3fed.org/!" . ) -_sip._udp IN SRV 10 10 5060 publicsip.example.com. -_sip._udp.l3fe IN SRV 10 10 5060 l3fedsip.example.com. - -publicsip IN A 193.XXX.YYY.ZZZ -l3fedsip IN A 10.0.0.42 - - - * Outgoing SIP configuration - The domainpolicy table just needs to link the federation - identifier to the agreed apon prefix: - -mysql> select * from domainpolicy; -+----+-------------------+------+--------------+-------+ -| id | rule | type | att | val | -+----+-------------------+------+--------------+-------+ -| 1 | http://l3fed.org/ | fed | domainprefix | l3fed | -+----+-------------------+------+--------------+-------+ - - -1.7. Known Limitations - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 22 16 178 217 - 2. Klaus Darilion 22 1 2456 0 - 3. Razvan Crainea (@razvancrainea) 13 9 60 180 - 4. Liviu Chircu (@liviuchircu) 12 9 39 64 - 5. Daniel-Constantin Mierla (@miconda) 10 8 19 21 - 6. Henning Westerholt (@henningw) 6 4 25 25 - 7. Maksym Sobolyev (@sobomax) 5 3 4 5 - 8. Vlad Patrascu (@rvlad-patrascu) 4 2 6 4 - 9. Konstantin Bokarius 3 1 2 5 - 10. Peter Lemenkov (@lemenkov) 3 1 1 1 - - All remaining contributors: UnixDev, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2023 - 3. Razvan Crainea (@razvancrainea) Jun 2011 - Nov 2021 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2006 - Mar 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. UnixDev Feb 2009 - Feb 2009 - 8. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - 9. Konstantin Bokarius Mar 2008 - Mar 2008 - 10. Edson Gellert Schubert Feb 2008 - Feb 2008 - - All remaining contributors: Henning Westerholt (@henningw), - Klaus Darilion. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Klaus Darilion. - - Documentation Copyrights: - - Copyright © 2002,2003,2006 Juha Heinanen, Otmar Lendl, Klaus - Darilion diff --git a/modules/domainpolicy/README.md b/modules/domainpolicy/README.md new file mode 100644 index 00000000000..788836a2198 --- /dev/null +++ b/modules/domainpolicy/README.md @@ -0,0 +1,541 @@ +--- +title: "Domain Policy Module" +description: "The Domain Policy module implements draft-lendl-domain-policy-ddds-02 in combination with draft-lendl-speermint-federations-02 and draft-lendl-speermint-technical-policy-00." +--- + +## Admin Guide + + +### Overview + + +The Domain Policy module implements draft-lendl-domain-policy-ddds-02 in +combination with draft-lendl-speermint-federations-02 and +draft-lendl-speermint-technical-policy-00. These drafts +define DNS records with which a domain can +announce its federation memberships. A local database can be +used to map policy rules to routing policy decisions. +This database can also contain rules concerning destination +domains independently of draft-lendl-domain-policy-ddds-02. + + +This module requires a database. No caching is implemented. + + +### Dependencies + + +The module depends on the following modules (in the other words the +listed modules must be loaded before this module): + + +- *database* -- Any database module + + +### Exported Parameters + + +#### db_url (string) + + +This is URL of the database to be used. + + +*Default value is +"mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="Setting db_url parameter" +modparam("domainpolicy", "db_url", "postgresql://user:pass@db_host/opensips") +``` + + +#### dp_table (string) + + +Name of table containing the local support domain policy setup. + + +*Default value is "domainpolicy".* + + +```opensips title="Setting dp_table parameter" +modparam("domainpolicy", "dp_table", "supportedpolicies") +``` + + +#### dp_col_rule (string) + + +Name of column containing the domain policy rule name which is equal +to the URI as published in the domain policy NAPTRs. + + +*Default value is "rule".* + + +```opensips title="Setting dp_col_rule parameter" +modparam("domainpolicy", "dp_col_rule", "rules") +``` + + +#### dp_col_type (string) + + +Name of column containing the domain policy rule type. +In the case of federation names, this is "fed". For standard +referrals according to draft-lendl-speermint-technical-policy-00, +this is "std". For direct domain lookups, this is "dom". + + +*Default value is "type".* + + +```opensips title="Setting dp_col_rule parameter" +modparam("domainpolicy", "dp_col_type", "type") +``` + + +#### dp_col_att (string) + + +Name of column containing the AVP's name. If the rule stored in this +row triggers, than dp_can_connect() will add an AVP with that name. + + +*Default value is "att".* + + +```opensips title="Setting dp_col_att parameter" +modparam("domainpolicy", "dp_col_att", "attribute") +``` + + +#### dp_col_val (string) + + +Name of column containing the value for AVPs created by dp_can_connect(). + + +*Default value is "val".* + + +```opensips title="Setting dp_col_val parameter" +modparam("domainpolicy", "dp_col_val", "values") +``` + + +#### port_override_avp (string) + + +This parameter defines the name of the AVP where dp_apply_policy() will look +for an override port number. + + +*Default value is "portoverride".* + + +```opensips title="Setting port_override_avp parameter" +# string named AVP +modparam("domainpolicy", "port_override_avp", "portoverride") +``` + + +#### transport_override_avp (string) + + +Name of the AVP which contains the override transport setting. + + +*Default value is "transportoverride".* + + +```opensips title="Setting transport_override_avp parameter" +# string named AVP +modparam("domainpolicy", "transport_override_avp", "transportoverride") +``` + + +#### domain_replacement_avp (string) + + +Name of the AVP which contains a domain replacement. + + +*Default value is "domainreplacement".* + + +```opensips title="Setting domain_replacement_avp parameter" +# string named AVP +modparam("domainpolicy", "domain_replacement_avp", "domainreplacement") +``` + + +#### domain_prefix_avp (string) + + +Name of the AVP which contains a domain prefix. + + +*Default value is "domainprefix".* + + +```opensips title="Setting domain_prefix_avp parameter" +# string named AVP +modparam("domainpolicy", "domain_prefix_avp", "domainprefix") +``` + + +#### domain_suffix_avp (string) + + +Name of the AVP which contains a domain suffix. + + +*Default value is "domainsuffix".* + + +```opensips title="Setting domain_suffix_avp parameter" +# string named AVP +modparam("domainpolicy", "domain_suffix_avp", "domainsuffix") +``` + + +#### send_socket_avp (string) + + +Name of the AVP which contains a send_socket. The format of the +send socket (the payload of this AVP) must be in the format +[proto:]ip_address[:port]. The function dp_apply_policy will +look for this AVP and if defined, it will force the send socket +to its value (smilar to the force_send_socket core function). + + +*Default value is "sendsocket".* + + +```opensips title="Setting send_socket_avp parameter" +# string named AVP +modparam("domainpolicy", "send_socket_avp", "sendsocket") +``` + + +### Exported Functions + + +#### dp_can_connect() + + +Checks the interconnection policy of the caller. It uses the domain in the +request URI to perform the DP-DDDS algorithm according to draft-lendl-domain-policy-ddds-02 +to retrieve the domain's policy announcements. +As of this version, only records conforming to draft-lendl-speermint-federations-02 +and draft-lendl-speermint-technical-policy-00 are supported. + + +Non-terminal NAPTR records will cause recursion to the replacement domain. dp_can_connect() +will thus look for policy rules in the referenced domain. Furthermore, an AVP for +"domainreplacement" (containing the new domain) will be added to the call. This +will redirect SRV/A record lookups to the new domain. + + +In order to simplify direct domain-based peerings all destination domains are +treated as if they contain a top priority "D2P+SIP:dom" rule with the domain itself as the +value of the rule. Thus any database row with type = 'dom' and rule = 'example.com' +will override any dynamic DNS-discovered rules. + + +For NAPTRs with service-type "D2P+SIP:fed", the federation IDs +(as extracted from the regexp field) are used to retrieve +policy records from a local local database (basically: "SELECT dp_col_att, dp_col_val FROM +dp_table WHERE dp_col_rule = '[federationID]' AND type = 'fed'). If records are found (and all other +records with the same order value are fulfillable) then AVPs will be created from +the dp_col_att and dp_col_val columns. + + +For NAPTRs with service-type "D2P+SIP:std", the same procedure is performed. This time, +the database lookup searched for type = 'std', though. + + +"D2P+SIP:fed" and "D2P+SIP:std" can be mixed freely. If two rules with the same +"order" match and try to set the same AVP, then the behaviour is undefined. + + +The dp_col_att column specifies the AVP's name. If the AVP start with "s:" or "i:", the +corresponding AVP type (string named or integer named) will be generated. If the excat specifier +is omited, the AVP type will be guessed. + + +The dp_col_val column will always be interpreted as string. Thus, the AVP's value +is always string based. + + +dp_can_connect returns: + + +- *-2*: on errors during the evaluation. (DNS, DB, ...) +- *-1*: D2P+SIP records were found, but the policy is not fullfillable. +- *1*: D2P+SIP records were found and a call is possible +- *2*: No D2P+SIP records were found. The destination domain does +not announce a policy for incoming SIP calls. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="dp_can_connect usage" +... +dp_can_connect(); +switch(retcode) { + case -2: + xlog("L_INFO","Errors during the DP evaluation\n"); + sl_send_reply(404, "We can't connect you."); + break; + case -1: + xlog("L_INFO","We can't connect to that domain\n"); + sl_send_reply(404, "We can't connect you."); + break; + case 1: + xlog("L_INFO","We found matching policy records\n"); + avp_print(); + dp_apply_policy(); + t_relay(); + break; + case 2: + xlog("L_INFO","No DP records found\n"); + t_relay(); + break; +} +... + +``` + + +#### dp_apply_policy() + + +This function sets the destination URI according to the policy returned +from the `dp_can_connect()` function. +Parameter exchange between `dp_can_connect()` +and `dp_apply_policy()` is done via AVPs. +The AVPs can be configured in the module's parameter section. + + +> [!NOTE] +> The name of the AVPs must correspond with the names in the +> *att* column in the domainpolicy table. + + +Setting the following AVPs in `dp_can_connect()` +(or by any other means) +cause the following actions in `dp_apply_policy()`: + + +- *port_override_avp*: If this AVP is set, the port +in the destination URI is set to this port. +Setting an override port disables NAPTR and +SRV lookups according to RFC 3263. +- *transport_override_avp*: If this AVP is set, the transport +parameter in the destination URI is set to the specified transport ("udp", "tcp", +"tls"). +Setting an override transport also disables NAPTR lookups, but retains +an SRV lookup according to RFC 3263. +- *domain_replacement_avp*: If this AVP is set, the domain +in the destination URI will be replaced by this domain. +A non-terminal NAPTR and thus a referral to a new domain implicitly +sets *domain_replacement_avp* to the new domain. +- *domain_prefix_avp*: If this AVP is set, the domain +in the destination URI will be prefixed with this "subdomain". +E.g. if the domain in the request URI is +"example.com" and the domain_prefix_avp contains "inbound", the domain +in the destinaton URI is set to "inbound.example.com". +- *domain_suffix_avp*: If this AVP is set, the domain +in the destination URI will have the content of the AVP appended to it. +E.g. if the domain in the request URI is +"example.com" and the domain_suffix_avp contains "myroot.com", the domain +in the destination URI is set to "example.com.myroot.com". +- *send_socket_avp*: If this AVP is set, the sending socket +will be forced to the socket in the AVP. The payload format of this AVP must +be [proto:]ip_address[:port]. + + +If both prefix/suffix and domain replacements are used, then the replacement is +performed first and the prefix/suffix are applied to the new domain. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="dp_apply_policy usage" +... +if (dp_apply_policy()) { + t_relay(); +} +... + +``` + + +### FIFO Commands + + +### Usage Scenarios + + +This section describes how this module can be use to implement +selective VoIP peerings. + + +#### TLS Based Federation + + +This example shows how a secure peering fabric can be configured based on +TLS and Domain Policies. + + +Let's assume that an organization called "TLSFED.org" acts as an umbrella for +VoIP providers who want to peer with each other but don't want to run +open SIP proxies. TLSFED.org's secretary acts as an X.509 Certification Authority +that signs the TLS keys of all member's SIP proxies. Each member should automatically +allow incoming calls from other members. On the other hand, the configuration for +this federation must not interfere with a member's participation in other VoIP +peering fabrics. All this can be achieved by the following configuration for +a participating VoIP operation called example.com: + + +- *Incoming SIP configuration* +Calls from other members are expected to use TLS and authenticate +using a client-CERT. To implement this, we cannot share a TCP/TLS port +with other incoming connection. Thus we need to use tls_server_domain[] to +dedicate a TCP port for this federation. + + ``` + tls_server_domain[1.2.3.4:5066] { + tls_certificate = "/path/to/tlsfed/example-com.key" + tls_private_key = "/path/to/tlsfed/example-com.crt" + tls_ca_list = "/path/to/tlsfed/ca.pem" + tls_method = tlsv1 + tls_verify_client = 1 + tls_require_cleint_certificate = 1 + } + + ``` +- *Outgoing SIP configuration* +Calls to other members also must use the proper client cert. +Therefore, a TLS client domain must be configured. We use the +federation name as TLS client domain identifier. Therefore, the +content of the "tls_client_domain_avp" must be set to this identifier +(e.g. by putting it as rule into the domainpolicy table). + + ``` + tls_client_domain["tlsfed"] { + tls_certificate = "/path/to/tlsfed/example-com.key" + tls_private_key = "/path/to/tlsfed/example-com.crt" + tls_ca_list = "/path/to/tlsfed/ca.pem" + tls_method = tlsv1 + tls_verify_server = 1 + } + + ``` + + +#### SIP Hub based Federation + + +This example shows how a peering fabric based on a central SIP hub can be configured. + + +Let's assume that an organization called "HUBFED.org" acts as an umbrella for +VoIP providers who want to peer with each other but don't want to run +open SIP proxies. Instead, HUBFED.org operates a central SIP proxy which will +relay calls between all participating members. Each member thus only needs to +allow incoming calls from that central hub (which could be done by firewalling). +All this can be achieved by the following configuration for +a participating VoIP operation called example.com: + + +- *DNS configuration* +The destination network announces its membership in this +federation. + + ``` + $ORIGIN destination.example.org + @ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( + "!^.*$!http://HUBFED.org/!" . ) + + ``` +- *Outgoing SIP configuration* +Calls to other members need to be redirected to the central proxy. +The domainpolicy table just needs to list the federation and link +it to the central proxy's domain name: + + ``` + mysql> select * from domainpolicy; + +----+--------------------+------+-------------------+----------------+ + | id | rule | type | att | val | + +----+--------------------+------+-------------------+----------------+ + | 1 | http://HUBFED.org/ | fed | domainreplacement | sip.HUBFED.org | + +----+--------------------+------+-------------------+----------------+ + + ``` + + +#### Walled Garden Federation + + +This example assumes that a set of SIP providers have established +a secure Layer 3 network between their proxies. It does not +matter whether this network is build by means of IPsec, a private +Layer 2 network, or by simple firewalling. We will use the 10.x +network (for the walled garden net) and "http://l3fed.org/" +(as federation identifier) in this example. + + +A member of this federation (e.g. example.com) can not announce its +SIP proxy's 10.x address in the standard SRV / A records of his domain, +as this address is only meaningful for other members of this federation. +In order to facilite different IP address resolution paths within the +federation vs. outside the federation, all members of "http://l3fed.org/" +agree to prefix the destination domains with "l3fed" before the +SRV (or A) lookup. + + +Here is the configuration for example.com: + + +- *DNS configuration* +The destination network announces its membership in this +federation. + + ``` + $ORIGIN example.com + @ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( + "!^.*$!http://l3fed.org/!" . ) + _sip._udp IN SRV 10 10 5060 publicsip.example.com. + _sip._udp.l3fe IN SRV 10 10 5060 l3fedsip.example.com. + + publicsip IN A 193.XXX.YYY.ZZZ + l3fedsip IN A 10.0.0.42 + + ``` +- *Outgoing SIP configuration* +The domainpolicy table just needs to link the federation identifier +to the agreed apon prefix: + + ``` + mysql> select * from domainpolicy; + +----+-------------------+------+--------------+-------+ + | id | rule | type | att | val | + +----+-------------------+------+--------------+-------+ + | 1 | http://l3fed.org/ | fed | domainprefix | l3fed | + +----+-------------------+------+--------------+-------+ + + ``` + + +### Known Limitations + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/domainpolicy/doc/contributors.xml b/modules/domainpolicy/doc/contributors.xml deleted file mode 100644 index b4530818978..00000000000 --- a/modules/domainpolicy/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 22 - 16 - 178 - 217 - - - 2. - Klaus Darilion - 22 - 1 - 2456 - 0 - - - 3. - Razvan Crainea (@razvancrainea) - 13 - 9 - 60 - 180 - - - 4. - Liviu Chircu (@liviuchircu) - 12 - 9 - 39 - 64 - - - 5. - Daniel-Constantin Mierla (@miconda) - 10 - 8 - 19 - 21 - - - 6. - Henning Westerholt (@henningw) - 6 - 4 - 25 - 25 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 4 - 5 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 6 - 4 - - - 9. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: UnixDev, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Jun 2011 - Nov 2021 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2006 - Mar 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - UnixDev - Feb 2009 - Feb 2009 - - - 8. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - 9. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 10. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Klaus Darilion. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Klaus Darilion. -
- -
diff --git a/modules/domainpolicy/doc/domainpolicy.xml b/modules/domainpolicy/doc/domainpolicy.xml deleted file mode 100644 index 82c22c0707f..00000000000 --- a/modules/domainpolicy/doc/domainpolicy.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Domain Policy Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2002,2003,2006 Juha Heinanen, Otmar Lendl, Klaus Darilion - - diff --git a/modules/domainpolicy/doc/domainpolicy_admin.xml b/modules/domainpolicy/doc/domainpolicy_admin.xml deleted file mode 100644 index e539cb6c15e..00000000000 --- a/modules/domainpolicy/doc/domainpolicy_admin.xml +++ /dev/null @@ -1,687 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Domain Policy module implements draft-lendl-domain-policy-ddds-02 in - combination with draft-lendl-speermint-federations-02 and - draft-lendl-speermint-technical-policy-00. These drafts - define DNS records with which a domain can - announce its federation memberships. A local database can be - used to map policy rules to routing policy decisions. - This database can also contain rules concerning destination - domains independently of draft-lendl-domain-policy-ddds-02. - - - This module requires a database. No caching is implemented. - -
- -
- Dependencies - - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): - - - database -- Any database module - - - -
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - This is URL of the database to be used. - - - Default value is - &defaultrodb; - - - Setting db_url parameter - -modparam("domainpolicy", "db_url", "postgresql://user:pass@db_host/opensips") - - -
-
- <varname>dp_table</varname> (string) - - Name of table containing the local support domain policy setup. - - - Default value is domainpolicy. - - - Setting dp_table parameter - -modparam("domainpolicy", "dp_table", "supportedpolicies") - - -
-
- <varname>dp_col_rule</varname> (string) - - Name of column containing the domain policy rule name which is equal - to the URI as published in the domain policy NAPTRs. - - - Default value is rule. - - - Setting dp_col_rule parameter - -modparam("domainpolicy", "dp_col_rule", "rules") - - -
-
- <varname>dp_col_type</varname> (string) - - Name of column containing the domain policy rule type. - In the case of federation names, this is "fed". For standard - referrals according to draft-lendl-speermint-technical-policy-00, - this is "std". For direct domain lookups, this is "dom". - - - Default value is type. - - - Setting dp_col_rule parameter - -modparam("domainpolicy", "dp_col_type", "type") - - -
- - -
- <varname>dp_col_att</varname> (string) - - Name of column containing the AVP's name. If the rule stored in this - row triggers, than dp_can_connect() will add an AVP with that name. - - - Default value is att. - - - Setting dp_col_att parameter - -modparam("domainpolicy", "dp_col_att", "attribute") - - -
-
- <varname>dp_col_val</varname> (string) - - Name of column containing the value for AVPs created by dp_can_connect(). - - - Default value is val. - - - Setting dp_col_val parameter - -modparam("domainpolicy", "dp_col_val", "values") - - -
-
- <varname>port_override_avp</varname> (string) - - This parameter defines the name of the AVP where dp_apply_policy() will look - for an override port number. - - - Default value is portoverride. - - - Setting port_override_avp parameter - -# string named AVP -modparam("domainpolicy", "port_override_avp", "portoverride") - - -
-
- <varname>transport_override_avp</varname> (string) - - Name of the AVP which contains the override transport setting. - - - Default value is transportoverride. - - - Setting transport_override_avp parameter - -# string named AVP -modparam("domainpolicy", "transport_override_avp", "transportoverride") - - -
- -
- <varname>domain_replacement_avp</varname> (string) - - Name of the AVP which contains a domain replacement. - - - Default value is domainreplacement. - - - Setting domain_replacement_avp parameter - -# string named AVP -modparam("domainpolicy", "domain_replacement_avp", "domainreplacement") - - -
- -
- <varname>domain_prefix_avp</varname> (string) - - Name of the AVP which contains a domain prefix. - - - Default value is domainprefix. - - - Setting domain_prefix_avp parameter - -# string named AVP -modparam("domainpolicy", "domain_prefix_avp", "domainprefix") - - -
- -
- <varname>domain_suffix_avp</varname> (string) - - Name of the AVP which contains a domain suffix. - - - Default value is domainsuffix. - - - Setting domain_suffix_avp parameter - -# string named AVP -modparam("domainpolicy", "domain_suffix_avp", "domainsuffix") - - -
-
- <varname>send_socket_avp</varname> (string) - - Name of the AVP which contains a send_socket. The format of the - send socket (the payload of this AVP) must be in the format - [proto:]ip_address[:port]. The function dp_apply_policy will - look for this AVP and if defined, it will force the send socket - to its value (smilar to the force_send_socket core function). - - - Default value is sendsocket. - - - Setting send_socket_avp parameter - -# string named AVP -modparam("domainpolicy", "send_socket_avp", "sendsocket") - - -
- -
- - - -
- Exported Functions -
- <function moreinfo="none">dp_can_connect()</function> - - Checks the interconnection policy of the caller. It uses the domain in the - request URI to perform the DP-DDDS algorithm according to draft-lendl-domain-policy-ddds-02 - to retrieve the domain's policy announcements. - As of this version, only records conforming to draft-lendl-speermint-federations-02 - and draft-lendl-speermint-technical-policy-00 are supported. - - - Non-terminal NAPTR records will cause recursion to the replacement domain. dp_can_connect() - will thus look for policy rules in the referenced domain. Furthermore, an AVP for - "domainreplacement" (containing the new domain) will be added to the call. This - will redirect SRV/A record lookups to the new domain. - - - In order to simplify direct domain-based peerings all destination domains are - treated as if they contain a top priority "D2P+SIP:dom" rule with the domain itself as the - value of the rule. Thus any database row with type = 'dom' and rule = 'example.com' - will override any dynamic DNS-discovered rules. - - - For NAPTRs with service-type "D2P+SIP:fed", the federation IDs - (as extracted from the regexp field) are used to retrieve - policy records from a local local database (basically: "SELECT dp_col_att, dp_col_val FROM - dp_table WHERE dp_col_rule = '[federationID]' AND type = 'fed'). If records are found (and all other - records with the same order value are fulfillable) then AVPs will be created from - the dp_col_att and dp_col_val columns. - - - For NAPTRs with service-type "D2P+SIP:std", the same procedure is performed. This time, - the database lookup searched for type = 'std', though. - - - "D2P+SIP:fed" and "D2P+SIP:std" can be mixed freely. If two rules with the same - "order" match and try to set the same AVP, then the behaviour is undefined. - - - The dp_col_att column specifies the AVP's name. If the AVP start with "s:" or "i:", the - corresponding AVP type (string named or integer named) will be generated. If the excat specifier - is omited, the AVP type will be guessed. - - - The dp_col_val column will always be interpreted as string. Thus, the AVP's value - is always string based. - - - dp_can_connect returns: - - - - - -2: on errors during the evaluation. (DNS, DB, ...) - - - - - -1: D2P+SIP records were found, but the policy is not fullfillable. - - - - - 1: D2P+SIP records were found and a call is possible - - - - - 2: No D2P+SIP records were found. The destination domain does - not announce a policy for incoming SIP calls. - - - - - This function can be used from REQUEST_ROUTE. - - - dp_can_connect usage - -... -dp_can_connect(); -switch(retcode) { - case -2: - xlog("L_INFO","Errors during the DP evaluation\n"); - sl_send_reply(404, "We can't connect you."); - break; - case -1: - xlog("L_INFO","We can't connect to that domain\n"); - sl_send_reply(404, "We can't connect you."); - break; - case 1: - xlog("L_INFO","We found matching policy records\n"); - avp_print(); - dp_apply_policy(); - t_relay(); - break; - case 2: - xlog("L_INFO","No DP records found\n"); - t_relay(); - break; -} -... - - -
-
- <function moreinfo="none">dp_apply_policy()</function> - - This function sets the destination URI according to the policy returned - from the dp_can_connect() function. - Parameter exchange between dp_can_connect() - and dp_apply_policy() is done via AVPs. - The AVPs can be configured in the module's parameter section. - - - Note: The name of the AVPs must correspond with the names in the - att column in the domainpolicy table. - - - Setting the following AVPs in dp_can_connect() - (or by any other means) - cause the following actions in dp_apply_policy(): - - - - port_override_avp: If this AVP is set, the port - in the destination URI is set to this port. - Setting an override port disables NAPTR and - SRV lookups according to RFC 3263. - - -   - - - - - transport_override_avp: If this AVP is set, the transport - parameter in the destination URI is set to the specified transport ("udp", "tcp", - "tls"). - Setting an override transport also disables NAPTR lookups, but retains - an SRV lookup according to RFC 3263. - - -   - - - - - domain_replacement_avp: If this AVP is set, the domain - in the destination URI will be replaced by this domain. - - - A non-terminal NAPTR and thus a referral to a new domain implicitly - sets domain_replacement_avp to the new domain. - - -   - - - - - domain_prefix_avp: If this AVP is set, the domain - in the destination URI will be prefixed with this "subdomain". - E.g. if the domain in the request URI is - "example.com" and the domain_prefix_avp contains "inbound", the domain - in the destinaton URI is set to "inbound.example.com". - - -   - - - - - domain_suffix_avp: If this AVP is set, the domain - in the destination URI will have the content of the AVP appended to it. - E.g. if the domain in the request URI is - "example.com" and the domain_suffix_avp contains "myroot.com", the domain - in the destination URI is set to "example.com.myroot.com". - - -   - - - - - send_socket_avp: If this AVP is set, the sending socket - will be forced to the socket in the AVP. The payload format of this AVP must - be [proto:]ip_address[:port]. - - - - - - - If both prefix/suffix and domain replacements are used, then the replacement is - performed first and the prefix/suffix are applied to the new domain. - - - This function can be used from REQUEST_ROUTE. - - - dp_apply_policy usage - -... -if (dp_apply_policy()) { - t_relay(); -} -... - - -
-
- -
- <acronym>FIFO</acronym> Commands - - -
- -
- Usage Scenarios - - This section describes how this module can be use to implement - selective VoIP peerings. - - -
- TLS Based Federation - - This example shows how a secure peering fabric can be configured based on - TLS and Domain Policies. - - - Let's assume that an organization called "TLSFED.org" acts as an umbrella for - VoIP providers who want to peer with each other but don't want to run - open SIP proxies. TLSFED.org's secretary acts as an X.509 Certification Authority - that signs the TLS keys of all member's SIP proxies. Each member should automatically - allow incoming calls from other members. On the other hand, the configuration for - this federation must not interfere with a member's participation in other VoIP - peering fabrics. All this can be achieved by the following configuration for - a participating VoIP operation called example.com: - - - - Incoming SIP configuration - - Calls from other members are expected to use TLS and authenticate - using a client-CERT. To implement this, we cannot share a TCP/TLS port - with other incoming connection. Thus we need to use tls_server_domain[] to - dedicate a TCP port for this federation. - - -   - - -tls_server_domain[1.2.3.4:5066] { - tls_certificate = "/path/to/tlsfed/example-com.key" - tls_private_key = "/path/to/tlsfed/example-com.crt" - tls_ca_list = "/path/to/tlsfed/ca.pem" - tls_method = tlsv1 - tls_verify_client = 1 - tls_require_cleint_certificate = 1 -} - - -   - - - - - Outgoing SIP configuration - - Calls to other members also must use the proper client cert. - Therefore, a TLS client domain must be configured. We use the - federation name as TLS client domain identifier. Therefore, the - content of the "tls_client_domain_avp" must be set to this identifier - (e.g. by putting it as rule into the domainpolicy table). - - -   - - -tls_client_domain["tlsfed"] { - tls_certificate = "/path/to/tlsfed/example-com.key" - tls_private_key = "/path/to/tlsfed/example-com.crt" - tls_ca_list = "/path/to/tlsfed/ca.pem" - tls_method = tlsv1 - tls_verify_server = 1 -} - - - - -
- -
- SIP Hub based Federation - - This example shows how a peering fabric based on a central SIP hub can be configured. - - - Let's assume that an organization called "HUBFED.org" acts as an umbrella for - VoIP providers who want to peer with each other but don't want to run - open SIP proxies. Instead, HUBFED.org operates a central SIP proxy which will - relay calls between all participating members. Each member thus only needs to - allow incoming calls from that central hub (which could be done by firewalling). - All this can be achieved by the following configuration for - a participating VoIP operation called example.com: - - - - DNS configuration - - The destination network announces its membership in this - federation. - - -   - - -$ORIGIN destination.example.org -@ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( - "!^.*$!http://HUBFED.org/!" . ) - - -   - - - - - - Outgoing SIP configuration - - Calls to other members need to be redirected to the central proxy. - The domainpolicy table just needs to list the federation and link - it to the central proxy's domain name: - - -   - - -mysql> select * from domainpolicy; -+----+--------------------+------+-------------------+----------------+ -| id | rule | type | att | val | -+----+--------------------+------+-------------------+----------------+ -| 1 | http://HUBFED.org/ | fed | domainreplacement | sip.HUBFED.org | -+----+--------------------+------+-------------------+----------------+ - - -   - - - -
- - - - -
- Walled Garden Federation - - This example assumes that a set of SIP providers have established - a secure Layer 3 network between their proxies. It does not - matter whether this network is build by means of IPsec, a private - Layer 2 network, or by simple firewalling. We will use the 10.x - network (for the walled garden net) and "http://l3fed.org/" - (as federation identifier) in this example. - - - A member of this federation (e.g. example.com) can not announce its - SIP proxy's 10.x address in the standard SRV / A records of his domain, - as this address is only meaningful for other members of this federation. - In order to facilite different IP address resolution paths within the - federation vs. outside the federation, all members of "http://l3fed.org/" - agree to prefix the destination domains with "l3fed" before the - SRV (or A) lookup. - - - Here is the configuration for example.com: - - - - DNS configuration - - The destination network announces its membership in this - federation. - - -   - - -$ORIGIN example.com -@ IN NAPTR 10 50 "U" "D2P+SIP:fed" ( - "!^.*$!http://l3fed.org/!" . ) -_sip._udp IN SRV 10 10 5060 publicsip.example.com. -_sip._udp.l3fe IN SRV 10 10 5060 l3fedsip.example.com. - -publicsip IN A 193.XXX.YYY.ZZZ -l3fedsip IN A 10.0.0.42 - - -   - - - - - - Outgoing SIP configuration - - The domainpolicy table just needs to link the federation identifier - to the agreed apon prefix: - - -   - - -mysql> select * from domainpolicy; -+----+-------------------+------+--------------+-------+ -| id | rule | type | att | val | -+----+-------------------+------+--------------+-------+ -| 1 | http://l3fed.org/ | fed | domainprefix | l3fed | -+----+-------------------+------+--------------+-------+ - - -   - - - -
- - -
- -
- Known Limitations - - -
- -
- diff --git a/modules/drouting/README b/modules/drouting/README deleted file mode 100644 index 6552947977f..00000000000 --- a/modules/drouting/README +++ /dev/null @@ -1,1982 +0,0 @@ -Dynamic Routing Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Introduction - 1.1.2. Features - 1.1.3. Performance - 1.1.4. Dynamic Routing Concepts - 1.1.5. Routing Rule Processing - 1.1.6. Probing and Disabling destinations - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url(str) - 1.3.2. drd_table(str) - 1.3.3. drr_table(str) - 1.3.4. drg_table(str) - 1.3.5. drc_table(str) - 1.3.6. ruri_avp (str) - 1.3.7. gw_id_avp (str) - 1.3.8. gw_priprefix_avp (str) - 1.3.9. rule_id_avp (str) - 1.3.10. rule_prefix_avp (str) - 1.3.11. carrier_id_avp (str) - 1.3.12. gw_sock_avp (str) - 1.3.13. define_blacklist (str) - 1.3.14. default_group (int) - 1.3.15. force_dns (int) - 1.3.16. persistent_state (int) - 1.3.17. no_concurrent_reload (int) - 1.3.18. probing_interval (integer) - 1.3.19. probing_method (string) - 1.3.20. probing_from (string) - 1.3.21. probing_reply_codes (string) - 1.3.22. probing_socket (string) - 1.3.23. gw_socket_filter_mode (string) - 1.3.24. cluster_id (integer) - 1.3.25. cluster_sharing_tag (string) - 1.3.26. cluster_probing_mode (string) - 1.3.27. use_domain (int) - 1.3.28. drg_user_col (str) - 1.3.29. drg_domain_col (str) - 1.3.30. drg_grpid_col (str) - 1.3.31. use_partitions (int) - 1.3.32. db_partitions_url (str) - 1.3.33. db_partitions_table (str) - 1.3.34. partition_id_pvar (pvar) - 1.3.35. enable_restart_persistency (int) - 1.3.36. extra_prefix_chars (str) - 1.3.37. extra_id_chars (str) - 1.3.38. rule_tables_query (str) - 1.3.39. generate_data_checksum (int) - - 1.4. Exported Functions - - 1.4.1. do_routing([groupID], [flags], - [gw_whitelist], [rule_attrs_pvar], - [gw_attrs_pvar], [carrier_attrs_pvar], - [partition]) - - 1.4.2. route_to_carrier( carriers, [gw_attrs_pvar], - [carrier_attrs_pvar], [partition]) - - 1.4.3. route_to_gw(gw_id, [gw_attrs_var], - [carrier_attrs_var], [partition]) - - 1.4.4. use_next_gw( [rule_attrs_pvar], - [gw_attrs_pvar], [carrier_attrs_pvar], - [partition]) - - 1.4.5. goes_to_gw( [type], [flags], [gw_attrs_pvar], - [carrier_attrs_pvar], [partition]) - - 1.4.6. is_from_gw([type], [flags], [gw_attrs_pvar], - [carrier_attrs_pvar], [partition]) - - 1.4.7. dr_is_gw( sip_uri, [type], [flags], - [gw_attrs_pvar], [carrier_attrs_pvar], - [partition]) - - 1.4.8. dr_disable([partition]) - 1.4.9. dr_match(groupID, [flags], number, - [rule_attrs_pvar], [partition]) - - 1.5. Exported MI Functions - - 1.5.1. dr_reload - 1.5.2. dr_gw_status - 1.5.3. dr_carrier_status - 1.5.4. dr_reload_status - 1.5.5. dr_number_routing - 1.5.6. dr_enable_probing - - 1.6. Exported Events - - 1.6.1. E_DROUTING_STATUS - - 1.7. Exported Status/Report Identifiers - - 1.7.1. [partition_name] - 1.7.2. [partition_name];events - - 1.8. Installation - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set drd_table parameter - 1.3. Set drr_table parameter - 1.4. Set drg_table parameter - 1.5. Set drc_table parameter - 1.6. Set ruri_avp parameter - 1.7. Set gw_id_avp parameter - 1.8. Set gw_priprefix_avp parameter - 1.9. Set rule_id_avp parameter - 1.10. Set rule_prefix_avp parameter - 1.11. Set carrier_id_avp parameter - 1.12. Set gw_sock_avp parameter - 1.13. Set define_blacklist parameter - 1.14. Set default_group parameter - 1.15. Set force_dns parameter - 1.16. Set the persistent_state parameter - 1.17. Set no_concurrent_reload parameter - 1.18. Set probing_interval parameter - 1.19. Set probing_method parameter - 1.20. Set probing_from parameter - 1.21. Set probing_reply_codes parameter - 1.22. Set probing_socket parameter - 1.23. Set gw_socket_filter_mode parameter - 1.24. Set cluster_id parameter - 1.25. Set cluster_sharing_tag parameter - 1.26. Set cluster_probing_mode parameter - 1.27. Set use_domain parameter - 1.28. Set drg_user_col parameter - 1.29. Set drg_domain_col parameter - 1.30. Set drg_grpid_col parameter - 1.31. Set use_partitions parameter - 1.32. Set db_partitions_url parameter - 1.33. Set db_partitions_table parameter - 1.34. Set partition_id_pvar parameter - 1.35. Set enable_restart_persistency parameter - 1.36. Set extra_prefix_chars parameter - 1.37. Set extra_id_chars parameter - 1.38. Set the rule_tables_query parameter - 1.39. Set the generate_data_checksum parameter - 1.40. do_routing usage - 1.41. route_to_carrier usage - 1.42. route_to_gw usage - 1.43. use_next_gw usage - 1.44. goes_to_gw usage - 1.45. is_from_gw usage - 1.46. dr_is_gw usage - 1.47. dr_disable() usage - 1.48. dr_match usage - 1.49. dr_gw_status usage when use_partitions is set to 0 - 1.50. dr_gw_status usage when use_partitionsis set to 1 - 1.51. dr_carrier_status usage when use_partitions is 0 - 1.52. dr_carrier_status usage when use_partitions is 1 - 1.53. dr_reload_status usage when use_partitions is 0 - 1.54. dr_reload_status usage when use_partitions is 1 - 1.55. dr_enable_probing usage - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. Introduction - - Dynamic Routing is a module for selecting (based on multiple - criteria) the best gateway/destination to be used for - delivering a certain call. Least Cost Routing (LCR) is a - special case of dynamic routing - when the rules are ordered - based on costs. Dynamic Routing comes with many features - regarding routing rule selection: - * prefix based - * caller/group based - * time based - * priority based - - , processing : - * stripping and prefixing - * default rules - * inbound and outbound processing - * script route triggering - - and failure handling: - * serial forking - * weight based GW selection - * random GW selection - * GW probing for crashes - -1.1.2. Features - - The dynamic routing implementation for OpenSIPS is designed - with the following properties: - * The routing info (destinations, carriers, rules, groups) is - stored in a database and loaded into memory at start up - time; reload at runtime via a Management Interface command. - * weight-based or random selection of the destinations (from - a rule or from a carrier), failure detection of gateways - (with switching to next available gateway). - * able to handle large volume of routing info (10M of rules) - with minimal speed/time and memory consumption penalties - * script integration - Pseudo-variable support in functions; - scripting route triggering when rules are matched - * bidirectional behavior - inbound and outbound processing - (strip and prefixing when sending and receiving from a - destination/GW) - * blacklisting - the module allows definition of blacklists - based on the destination IPs. This blacklists are to be - used to prevent malicious forwarding to GWs (based on DNS - lookups) when the script logic does none-GE forwarding - (like foreign domains). - * loading routing information from multiple databases - the - gateways, rules, groups and carriers can be grouped by - partitions, and each partition may be loaded from different - databases/tables. This makes the routing process partition - based. In order to be able to use a table from a partition, - its name must be found in the "version" table belonging to - the database defined in the partition's db_url. - -1.1.3. Performance - - There were several tests performed regarding the performance of - the module when dealing with a large number of routing rules. - - The tests were performed with a set of 383000 rules and - measured: - * time to load from DB - * used shared memory - - The time to load was varying between 4 seconds and 8 seconds, - depending of the caching of the DB client - the first load was - the slowest (as the DB query hits the disk drive); the - following are faster as data is already cached in the DB - client. So technically speaking, the time to load (without the - time to query which is DB type dependent) is ~4 seconds - - After loading the data into shared memory ~ 96M of memory were - used exclusively for the DR data. - -1.1.4. Dynamic Routing Concepts - - DR engine uses several concepts in order to define how the - routing should be done (describing all the dependencies between - destinations and routing rules). - -1.1.4.1. Destination/Gateways - - These are the end SIP entities where actually the traffic needs - to be sent after routing. They are stored in a table called - “dr_gateways”. Gateway addresses are stored in a separate table - because of the need to access them independent of Dynamic - Routing processing (e.g., adding/ removing gateway PRI prefix - before/after performing other operation -- receiving/relaying - to gateway). - - In DR, a gateway is defined by: - * id (string) - * SIP address (SIP URI) - * type (integer which allows GWs to be grouped by purpose, - e.g. inbound, outbound, etc.) - * strip value (number of digits) from dialled number - * prefix (string) to be added to dialled number - * attributes (not used by DR engine, but only pushed to - script level when routing to this GW) - * probing mode (how the GW should be probed at SIP level - - see the probing chapter) - - The Gateways are to be used from the routing rule or from the - carrier definition. They are all the time referred by their ID. - -1.1.4.2. Carriers - - The carrier concept is used if you need to group gateways in - order to have a better control on how the GWs will be used by - DR rules; like in what order the GWs will be used. - - Basically, a carrier is a set of gateways which have its own - sorting algorithm and its own attribute string. They are by - default defined in the “dr_carriers” table. - - In DR, a carrier is defined by: - * id (string) - * list of gateways with/without weights (string) - (Ex:“gw1=10,gw4=10” or “gw1,gw2” - * flags : 0x1 - use only the first gateway from the carrier - (depending on the sorting); 0x2 - disable the usage of this - carrier - * sort algorithm : how the list of the gateways should be - sorted before being used, NULL - use the DB given order, W - - do weight based re-ordering, Q - do quality based sorting - (requires the qrouting module) - * attributes (not used by DR engine, but only pushed to - script level when routing to this carrier) - - The Carriers are to be used only from the routing rule - definition. They are all the time referred by their ID. - -1.1.4.3. Routing Rules - - These are the actual rules which control the routing. Using - different criterias (prefix, time, priority, etc), they will - decide to which gateways the call will be sent. - - Default name for the table storing rule definitions is - “dr_rules”. - - In DR, a routing rule is defined by: - * group (list of numbers) - rules can be grouped (a rule may - belong to multiple groups in the same time ) and you can - use only a certain group at a point; like having a - “premium” or “standard” or “interstate” or “intrastate” - groups of rules to be used in different cases - * prefix (string with digits only) - prefix to be used for - matching this rule (longest prefix matching) - * time validity (time recurrence string) - when this rule is - valid from time point of view (see RFC 2445) - * priority (number) - priority of the rule - higher value, - higher priority (see rule section alg) - * script route ID (string) - if defined, then execute the - route with the specified ID when this rule is matched. - That's it, a route which can be used to perform custom - operations on message. NOTE that no modification is - performed at signaling level and you must NOT do any - signaling operations in that script route - * list of GWs/carriers (string) - a comma separated list of - gateways or carriers (defined by IDs) to be used for this - rule; the carrier IDs are prefixed with “#” sign. For each - ID (GW or carrier) you may specify a weight. For how this - list will be interpreted (as order) see the rule selection - section. Example of list: “gw1,gw4,#cr3” or - “gw1=10,gw4=10,#cr3=80” - * attributes (not used by DR engine, but only pushed to - script level when this rule matched and been used) - - More on time recurrence: - * A date-time expression that defines the time recurrence to - be matched for current rule. Time recurrences are based - closely on the recurring time intervals from the Internet - Calendaring and Scheduling Core Object Specification - (calendar COS), RFC 2445. The set of attributes used in a - routing rule specification is a subset of time recurrence - attributes. - * The value stored in database has the basic format of: - ||||||||||| , identical to the input of the check_time_rec() function - of the cfgutils module, including the optional use of - logical operators linking multiple such strings into a - larger expression. - * When an attribute is not specified, the corresponding place - must be left empty, whenever another attribute that follows - in the list has to be specified. - -1.1.5. Routing Rule Processing - - The module can be used to find out which is the best gateway to - use for new calls terminated to PSTN. The algorithm to select - the rule is as follows: - * the module discovers the routing group of the originating - user. This step is skipped if a routing group is passed - from the script as parameter. - * once the group is known, in the subset of the rules for - this group the module looks for the one that matches the - destination based on "prefix" column. The set of rules with - the longest prefix is chosen. If no digit from the prefix - matches, the default rules are used (rules with no prefix) - * within the set of rules is applied the time criteria, and - the rule which has the highest priority and matches the - time criteria is selected to drive the routing. - * Once found the rule, it may contain a route ID to execute. - If a certain flag is set, then the processing is stopped - after executing the route block. - * The rule must contain a chain of gateways and carriers. The - module will execute serial forking for each address in the - chain (ordering is either done by simply using the - definition order or it may weight-based - weight selection - must be enabled). The next address in chain is used only if - the previously has failed. - * With the right gateway address found, the prefix (PRI) of - the gateway is added to the request URI and then the - request is forwarded. - - If no rule is found to match the selection criteria an default - action must be taken (e.g., error response sent back). If the - gateway in the chain has no prefix the request is forwarded - without adding any prefix to the request URI. - -1.1.6. Probing and Disabling destinations - - The module has the capability to monitor the status of the - destinations by doing SIP probing (sending SIP requests like - OPTIONS). - - For each destination, you can configure what kind of probing - should be done (probe_mode column): - * (0) - no probing at all; - * (1) - probing only when the destination is in disabled mode - (disabling via MI command will completely stop the probing - also). The destination will be automatically re-enabled - when the probing will succeed next time; - * (2) - probing all the time. If disabled, the destination - will be automatically re-enabled when the probing will - succeed next time; - - A destination can become disabled in two ways: - * script detection - by calling from script the dr_disable() - function after trying the destination. In this case, if - probing mode for the destination is (1) or (2), the - destination will be automatically re-enabled when the - probing will succeed. - * MI command - by calling the dr_gw_status MI command for - disabling (on demand) the destination. If so, the probing - and re-enabling of this destination will be completly - disabled until you re-enable it again via MI command - this - is designed to allow controlled and complete disabling of - some destination during maintenance. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - - * tm module. - * clusterer - only if "cluster_id" option is enabled. - -1.2.2. External Libraries or Applications - - * none. - -1.3. Exported Parameters - -1.3.1. db_url(str) - - The database url. - - Default value is “NULL”. - - Example 1.1. Set db_url parameter -... -modparam("drouting", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - -1.3.2. drd_table(str) - - The name of the db table storing gateway addresses. - - Default value is “dr_gateways”. - - Example 1.2. Set drd_table parameter -... -modparam("drouting", "drd_table", "dr_gateways") -... - -1.3.3. drr_table(str) - - The name of the db table storing routing rules. - - Default value is “dr_rules”. - - Example 1.3. Set drr_table parameter -... -modparam("drouting", "drr_table", "rules") -... - -1.3.4. drg_table(str) - - The name of the db table storing groups. - - Default value is “dr_groups”. - - Example 1.4. Set drg_table parameter -... -modparam("drouting", "drg_table", "groups") -... - -1.3.5. drc_table(str) - - The name of the db table storing definitions of the carriers - that will be used directly by the routing rules. - - Default value is “dr_carriers”. - - Example 1.5. Set drc_table parameter -... -modparam("drouting", "drc_table", "my_dr_carriers") -... - -1.3.6. ruri_avp (str) - - The name of the avp for storing Request URIs to be later used - (alternative destiantions for the current one). - - Default value is “$avp(___dr_ruri__)” if use_partitions - parameter is 0 or “$avp(___dr_ruri__partition_name)” where - partition_name is the name of the partition containing the AVP - (as fetched from the database) if use_partitions parameter is - 1. - - Example 1.6. Set ruri_avp parameter -... -modparam("drouting", "ruri_avp", '$avp(dr_ruri)') -modparam("drouting", "ruri_avp", '$avp(33)') -... - -1.3.7. gw_id_avp (str) - - The name of the avp for storing the id of the current selected - gateway/destination - once a new destination is selected (via - the use_next_gw() function), the AVP will be updated with the - ID of the new selected gateway/destination. - - Default value is “$avp(___dr_gw_id__)” if use_partitions - parameter is 0 or “$avp(___dr_gw_id__partition_name)” where - partition_name is the name of the partition containing the AVP - (as fetched from the database) if use_partitions parameter is - 1. - - Example 1.7. Set gw_id_avp parameter -... -modparam("drouting", "gw_id_avp", '$avp(gw_id)') -modparam("drouting", "gw_id_avp", '$avp(334)') -... - -1.3.8. gw_priprefix_avp (str) - - The name of the avp for storing the PRI prefix of the current - selected destination/gateway - once a new destination is - selected (via the use_next_gw() function), the AVP will be - updated with the PRI prefix of the new used destination. - - Default value is “NULL”. - - Example 1.8. Set gw_priprefix_avp parameter -... -modparam("drouting", "gw_priprefix_avp", '$avp(gw_priprefix)') -... - -1.3.9. rule_id_avp (str) - - The name of the avp for storing the id of the current matched - routing rule (see dr_rules table). - - Default value is “NULL”. - - Example 1.9. Set rule_id_avp parameter -... -modparam("drouting", "rule_id_avp", '$avp(rule_id)') -modparam("drouting", "rule_id_avp", '$avp(335)') -... - -1.3.10. rule_prefix_avp (str) - - The actual prefix that matched the routing rule (the part from - RURI username that matched the routing rule). - - Default value is “NULL”. - - Example 1.10. Set rule_prefix_avp parameter -... -modparam("drouting", "rule_prefix_avp", '$avp(dr_prefix)') -... - -1.3.11. carrier_id_avp (str) - - AVP to be populate with the ID string for the carrier the - current GW belongs to. - - Default value is “NULL”. - - Example 1.11. Set carrier_id_avp parameter -... -modparam("drouting", "carrier_id_avp", '$avp(carrier_id)') -... - -1.3.12. gw_sock_avp (str) - - The name of the avp for storing sockets for alternative - destinations defined by ruri_avp. - - Default value is “$avp(___dr_sock__)” if use_partitions - parameter is 0 or “$avp(___dr_sock__partition_name)” where - partition_name is the name of the partition containing the AVP - (as fetched from the database) if use_partitions parameter is - 1. - - Example 1.12. Set gw_sock_avp parameter -... -modparam("drouting", "gw_sock_avp", '$avp(dr_sock)') -modparam("drouting", "gw_sock_avp", '$avp(77)') -... - -1.3.13. define_blacklist (str) - - Defines a blacklist based on a list of GW types - the blacklist - will be populated with the IPs (no port, all protocols) of the - GWs having the specified types. - - If partitions are used, prefix the blacklist definition string - with the name of the partition followed by ":" separator. - - Multiple instances of this param are allowed. - - Default value is “NULL”. - - Example 1.13. Set define_blacklist parameter -... -modparam("drouting", "define_blacklist", 'bl_name= 3,5,25,23') -modparam("drouting", "define_blacklist", 'list= 4,2') -modparam("drouting", "define_blacklist", 'pstn:list2 = 5,6') -modparam("drouting", "define_blacklist", 'pstn:list3 = 7,8') -... - -1.3.14. default_group (int) - - Group to be used if the caller (FROM user) is not found in the - GROUP table. - - Default value is “NONE”. - - Example 1.14. Set default_group parameter -... -modparam("drouting", "default_group", 4) -... - -1.3.15. force_dns (int) - - Force DNS resolving of GW/destination names (if not IPs) during - startup. If not enabled, the GW name will be blindly used - during routing. - - Default value is “1 (enabled)”. - - Example 1.15. Set force_dns parameter -... -modparam("drouting", "force_dns", 0) -... - -1.3.16. persistent_state (int) - - Specifies whether the state column should be loaded at startup - and flushed during runtime or not. - - Default value is “1” (enabled). - - Example 1.16. Set the persistent_state parameter -... -# disable all DB operations with the state of a gateway -modparam("drouting", "persistent_state", 0) -... - -1.3.17. no_concurrent_reload (int) - - If enabled, the module will not allow do run multiple dr_reload - MI commands in parallel (with overlapping) Any new reload will - be rejected (and discarded) while an existing reload is in - progress. - - If you have a large routing set (millions of rules/prefixes), - you should consider disabling concurrent reload as they will - exhaust the shared memory (by reloading into memory, in the - same time, multiple instances of routing data). - - Default value is “0 (disabled)”. - - Example 1.17. Set no_concurrent_reload parameter -... -# do not allow parallel reload operations -modparam("drouting", "no_concurrent_reload", 1) -... - -1.3.18. probing_interval (integer) - - How often (in seconds) the probing of a destination should be - done. If set to 0, the probing will be disabled as - functionality (for all destinations) - - Default value is “30”. - - Example 1.18. Set probing_interval parameter -... -modparam("drouting", "probing_interval", 60) -... - -1.3.19. probing_method (string) - - The SIP method to be used for the probing requests. - - Default value is “"OPTIONS"”. - - Example 1.19. Set probing_method parameter -... -modparam("drouting", "probing_method", "INFO") -... - -1.3.20. probing_from (string) - - The FROM SIP URI to be advertised in the SIP probing requests. - - Default value is “"sip:prober@localhost"”. - - Example 1.20. Set probing_from parameter -... -modparam("drouting", "probing_from", "sip:pinger@192.168.2.10") -... - -1.3.21. probing_reply_codes (string) - - A comma separted list of SIP reply codes. The codes defined - here will be considered as valid reply codes for probing - messages, apart for 200. - - Default value is “NULL”. - - Example 1.21. Set probing_reply_codes parameter -... -modparam("drouting", "probing_reply_codes", "501, 403") -... - -1.3.22. probing_socket (string) - - A socket description [proto:]host[:port] of the local socket - (which is used by OpenSIPS for SIP traffic) to be used (if - multiple) for sending the probing messages from. - - For probing gateway the highest priority has socket from - gateway configuration in dr_gateways table. Then socket from - global probing_socket parameter and the lowest priority is - default behaviour with auto selected socket wich OpenSIPS - listens on. - - Default value is “NULL”. - - Example 1.22. Set probing_socket parameter -... -modparam("drouting", "probing_socket", "udp:192.168.1.100:5060") -... - -1.3.23. gw_socket_filter_mode (string) - - This parameter controls the gateway filtering during DB - loading, or which gateways are loaded or not into memory - depending on the configured socket they have. - - The supported filtering modes are: - * "all" - all the gateways defined in DB are loaded into - memory, disregarding what socket value they have. NOTE: for - the gw sockets not matching any OpenSIPS listeners/sockets, - the GW will be loaded with NULL/no socket. - * "ignore" - all the gateways defined in DB are loaded into - memory, but ignoring the socket value they have (the socket - will be set to NULL/NONE with no attempt to check it - against the OpenSIPS listeners/sockets). - * "matched-only" - in this mode the module will load from DB - only the gateways that have a configured a socket matching - any of the the OpenSIPS listeners/sockets. If the gateways - socket does not match, it will be discards, not loaded into - memory at all. - - Default value is “"all"”. - - Example 1.23. Set gw_socket_filter_mode parameter -... -# multiple OpenSIPS instances sharing a DR setting, so each should -# load only the GWs they have sockets for. -modparam("drouting", "gw_socket_filter_mode", "matched-only") -... -# an OpenSIPs instance not doing routing, but needing to be -# aware of all the gws, so load them all ignoring the sockets -modparam("drouting", "gw_socket_filter_mode", "ignore") -... - -1.3.24. cluster_id (integer) - - The ID of the cluster the module is part of. The clustering - support is used in drouting module for two purposes: for - sharing the status of the gateways/carriers and for controlling - the pinging to gateways. - - If clustering enbled, the module will automatically share - changes over the status of the gateways/destinations/carriers - with the other OpenSIPS instances that are part of a cluster. - Whenever such a status changes (following an MI command, a - probing result, a script command), the module will replicate - this status change to all the nodes in this given cluster. - - The clustering with sharing tag support may be used to control - which node in the cluster will perform the pinging/probing to - gateways. See the cluster_sharing_tag option. - - This OpenSIPS cluster exposes the "drouting-status-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - For more info on how to define and populate a cluster (with - OpenSIPS nodes) see the clusterer module. - - Default value is “0 (none)”. - - Example 1.24. Set cluster_id parameter -... -# replicate gw/carrier status with all OpenSIPS in cluster ID 9 -modparam("drouting", "cluster_id", 9) -... - -1.3.25. cluster_sharing_tag (string) - - The name of the sharing tag (as defined per clusterer modules) - to control which node is responsible for perform the - self-triggered actions in the module. Such actions may be the - gateway probing (see also the cluster_probing_mode parameter) - or sharing the gateway/carrier status changes. If defined, only - the node with active status of this tag will perform the - actions (pinging and sharing status). - - The cluster_id must be defined for this option to work. - - This is an optional parameter. If not set, all the nodes in the - cluster will share the status changes. - - Default value is “empty (none)”. - - Example 1.25. Set cluster_sharing_tag parameter -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_sharing_tag", "vip") -... - -1.3.26. cluster_probing_mode (string) - - This paramter controls how the probing/pinging should be done - when using the clustering support. It is about which node in - the cluster pings which gateway/destination. - - The cluster_id must be defined for this option to work. - - The supported probing modes are: - * "all" - all the nodes in the cluster will independetly ping - all the defined gateways, an "all" pings "all" mode. - * "by-shtag" - all the gateways are pinged by only one node - in the cluster, the node having the cluster_sharing_tag - active. By activating the sharing tag on a different node, - the pinging duty will be transfered to another node in the - cluster. - * "distributed" - the pinging effort is distributed across - all the nodes in the cluster, so each node will ping a - sub-set of the overall set of gateway. Still all the - gateways will get pinged (and only once per pinging cycle). - The re-partitioning of the pinging effort over the - available nodes in the cluster is automatically done when - new nodes are joining or nodes are dropping out. Still - there is no guaratee on which node will be responsible for - pinging which gateway. - - Default value is “"all"”. - - Example 1.26. Set cluster_probing_mode parameter -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_sharing_tag", "vip") -modparam("drouting", "cluster_probing_mode", "by-shtag") -... -# the pinging effort is distributed across all the nodes -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_probing_mode", "distributed") -... - -1.3.27. use_domain (int) - - Flag to configure whether to use domain match when querying - database for user's routing group. - - Default value is “1”. - - Example 1.27. Set use_domain parameter -... -modparam("drouting", "use_domain", 0) -... - -1.3.28. drg_user_col (str) - - The name of the column in group db table where the username is - stored. - - Default value is “username”. - - Example 1.28. Set drg_user_col parameter -... -modparam("drouting", "drg_user_col", "user") -... - -1.3.29. drg_domain_col (str) - - The name of the column in group db table where the domain is - stored. - - Default value is “domain”. - - Example 1.29. Set drg_domain_col parameter -... -modparam("drouting", "drg_domain_col", "host") -... - -1.3.30. drg_grpid_col (str) - - The name of the column in group db table where the group id is - stored. - - Default value is “groupid”. - - Example 1.30. Set drg_grpid_col parameter -... -modparam("drouting", "drg_grpid_col", "grpid") -... - -1.3.31. use_partitions (int) - - Flag to configure whether to use partitions for routing. If - this flag is set then the db_partitions_url and - db_partitions_table variables become mandatory. - - Default value is “0”. - - Example 1.31. Set use_partitions parameter -... -modparam("drouting", "use_partitions", 1) -... - -1.3.32. db_partitions_url (str) - - The url to the database containing partition-specific - information. (partition-specific information includes partition - name, url to the database where information about the partition - is preserved, the names of the tables in which it is preserved - and the AVPs that can be accessed using the .cfg script). The - use_partitions parameter must be set to 1. - - Default value is “"NULL"”. - - Example 1.32. Set db_partitions_url parameter -... -modparam("drouting", "db_partitions_url", "mysql://user:password@localho -st/opensips_partitions") -... - -1.3.33. db_partitions_table (str) - - The name of the table containing partition definitions. To be - used with use_partitions and db_partitions_url. - - Default value is “dr_partitions”. - - Example 1.33. Set db_partitions_table parameter -... -modparam("drouting", "db_partitions_table", "partition_defs") -... - -1.3.34. partition_id_pvar (pvar) - - Variable which will store the name of the name partition when - wildcard(*) operatior is used. Use_partitions must be set in - order to use this parameter. - - NOTE: The variable must be WRITABLE! - - Default value is “null(not used)”. - - Example 1.34. Set partition_id_pvar parameter -... -modparam("drouting", "partition_id_pvar", "$var(matched_partition)") -... - -1.3.35. enable_restart_persistency (int) - - Parameter set to enable restart persistency for the Dynamic - Routing module. When this parameter is set, the drouting module - no longer loads the data from the database after restart, but - uses the persistent storage file, and loads data from it “on - demand”, improving the startup performance. - - NOTE: If the restart persistent cache is not populated from a - previous run, then the data will be loaded from database at - startup! - - NOTE: A reload will update the cached data. - - Default value is “0 (disabled)”. - - Example 1.35. Set enable_restart_persistency parameter -... -modparam("drouting", "enable_restart_persistency", yes) -... - -1.3.36. extra_prefix_chars (str) - - List of ASCII (0-127) characters to be additionally accepted in - the prefixes. By default only '0' - '9' chars (digits) are - accepted. - - Default value is “NULL”. - - Example 1.36. Set extra_prefix_chars parameter -... -modparam("drouting", "extra_prefix_chars", "#-%") -... - -1.3.37. extra_id_chars (str) - - A set of extra characters to be allowed in both Gateway and - Carrier unique string identifiers, on top of alphanumeric - characters. - - Default value is “_-.”. - - Example 1.37. Set extra_id_chars parameter -... -modparam("drouting", "extra_id_chars", ":_-.") -... - -1.3.38. rule_tables_query (str) - - This parameter offers a dynamic, SQL-based way of building a - set of dr_rules-compatible table names, to be each loaded and - then merged into a single "dr_rules" table, for any given - partition. - - The syntax of the parameter is: "token : query", where token is - a special name given to a "dr_rules" table, so OpenSIPS can - match it against the custom queries defined using this - parameter. - - This parameter may be set multiple times (each definition - creates a new mapping). - - Example 1.38. Set the rule_tables_query parameter -... -# first, set the "dr_rules" table name to the name of your query -modparam("drouting", "drr_table", "MY_RULES_QUERY") - -# next, instruct drouting to load both 'dr_rules_a' and 'dr_rules_b', -# then merge all of their rules -modparam("drouting", "rule_tables_query", " - MY_RULES_QUERY: - SELECT 'dr_rules_a' UNION SELECT 'dr_rules_b'") -... - -1.3.39. generate_data_checksum (int) - - If enabled, it will generate a checksum ( MD5 ) for drouting - loaded data, attach that to the reload_status MI command output - and to the reload generated status reports - - Example 1.39. Set the generate_data_checksum parameter -... -modparam("drouting", "generate_data_checksum", 1) -... - -1.4. Exported Functions - -1.4.1. do_routing([groupID], [flags], [gw_whitelist], -[rule_attrs_pvar], [gw_attrs_pvar], [carrier_attrs_pvar], -[partition]) - - Function to trigger routing of the message according to the - rules in the database table and the configured parameters. - - This function can be used from all routes. - - If you set use_partitions to 1 the partition last parameter - becomes mandatory. - - All parameters are optional. Any of them may be ignored, - provided the necessary separation marks "," are properly - placed. - * groupID (int, optional) - number to specify the group of - the caller for routing purposes. If none specified the - function will automatically try to query the dr_group table - to get this - * flags (string, optional) - a list of letter-like flags for - controlling the routing behavior. Possible flags are: - + F - Enable rule fallback; normally the engine is using - a single rule for routing a call; by setting this - flag, the engine will fallback and use rules with less - priority or shorter prefix when all the destination - from the current rules failed. - + L - Do strict length matching over the prefix - - actually DR engine will do full number matching and - not prefix matching anymore. - + C - Only check if the dialed number matches any - routing rule, without loading / applying any routing - info (no GW is set, the RURI is not altered) - * gw_whitelist (string, optional) - a comma separated white - list of gateways. This will force routing over, at most, - this list of carriers or gateways (in other words, the - whitelist will be intersected with the results of the - search through the rules). - * rule_attrs_pvar (var, optional) - a writable variable which - will be populated with the attributes of the matched - dynamic routing rule. - * gw_attrs_pvar (var, optional) - a writable variable which - will be populated with the attributes of the matched - gateway. - * carrier_attrs_pvar (var, optional) - a a writable variable - which will be populated with the attributes of the matched - carrier. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Besides - specifing the name of one partition, you can use the "*" - wildcard sign to force routing over all partitions. - - Example 1.40. do_routing usage -... -# all groups, sort on order, use_partitions is 0 -do_routing(); -... -# all groups, sort on order, use_partitions is 1, route by partition nam -ed "part" -do_routing( , , , , , ,"part"); -... -# group id 0, sort on order, use_partitions is 0 -do_routing(0); -... -# group id 0, sort on order, use_partitions is 1, route by partition nam -ed "part" -do_routing(0, , , , , , "part"); -... -# group id from $var(id), sort on order, use_partitions is 0 -do_routing($var(id)); -... -# all groups, sort on weights, use_partitions is 0 -do_routing(, "W"); -... -# use_partitions is 1, partition and group supplied by AVPs, do strict l -ength matching -do_routing( $avp(grp),"L", , , , ,$avp(partition)) -... -# group id 2, sort on order, fallback rule and also return the gateway a -ttributes -do_routing(2, "F", , , $var(gw_attributes)); -... - -1.4.2. route_to_carrier( carriers, [gw_attrs_pvar], -[carrier_attrs_pvar], [partition]) - - Function to trigger the direct routing to a given set carriers - (one or more). So, the routing is not done prefix based, but - carrier based (call will be sent to the GWs of that carrier, - based on carrier policy). - - This function can be used from all routes. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter also (where the carrier are to be found). - - * carriers (string) - comma separated carrier IDs (names) - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the - currently matched gateway of this carrier. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of - this carrier. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is not accepted by the function. - - Example 1.41. route_to_carrier usage -... -# use_partitions is not set -if ( route_to_carrier("my_top_carrier, def_carrier", , $var(carrier_att) -) ) { - xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_carrier("my_top_carrier", , $var(carrier_att), "part") ) { - xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_carrier($var(carrierId), , , $var(my_partition)) ) { - xlog("Routing to \"my_top_carrier\"\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... - -1.4.3. route_to_gw(gw_id, [gw_attrs_var], [carrier_attrs_var], -[partition]) - - Function to trigger the direct routing to a given gateway (or - list of gateways). Attributes and per-gw processing will be - available. - - This function can be used from all routes. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - * gw_id (string) - comma separated list of gateway IDs to be - used. - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the - currently matched gateway. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of - this carrier. NOTE: the first carrier pointing to the GW(s) - will be considered! - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is not accepted by the function. - - Example 1.42. route_to_gw usage -... -# use_partitions is not set -if ( route_to_gw("gw_europe") ) { - t_relay(); - exit; -} -... -# use_partitions is not set -if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs)) ) { - xlog("Relaying to first gateway from our list - $var(gw_attrs)\n -"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_gw("gw_europe", , , "my_partition") ) { - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs), , "my_partition") ) { - xlog("Relaying to first gateway from our list - $var(gw_attrs)\n -"); - t_relay(); - exit; -} -... - -1.4.4. use_next_gw( [rule_attrs_pvar], [gw_attrs_pvar], -[carrier_attrs_pvar], [partition]) - - The function takes the next available destination (set by - do_routing, as alternative destinations) and pushes it into the - RURI. Note that the function just sets the RURI (nothing more). - - If a new RURI is set, the used destination is removed from the - pending set of alternative destinations. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - The function returns true only if a new RURI was set. False is - returned is no other alternative destinations are found or in - case of an internal processing error. It may take the following - optional parameters: - * rule_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of the - matched dynamic routing rule. - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the matched - gateway. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of the - matched carrier. - * partition (optinal, string) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is not accepted by the function. - - Example 1.43. use_next_gw usage -... -# use_partitions is not set -if (use_next_gw()) { - t_relay(); - exit; -} -... -# Also fetch the carrier attributes, if any -if (use_next_gw(, , $var(carrier_attrs))) { - xlog("Carrier attributes of current gateway: $var(carrier_attrs) -\n"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if (use_next_gw( , , ,"my_partition")) { - t_relay(); - exit; -} -... -# Also fetch the carrier attributes, if any -if (use_next_gw( , ,$var(carrier_attrs), "my_partition")) { - xlog("Carrier attributes of current gateway: $var(carrier_attrs) -\n"); - t_relay(); - exit; -} -... - -1.4.5. goes_to_gw( [type], [flags], [gw_attrs_pvar], -[carrier_attrs_pvar], [partition]) - - Function returns true if the destination of the current request - (destination URI or Request URI) points (as IP) to one of the - gateways. There no DNS lookups done if the domain part of the - URI is not an IP. - - This function does not change anything in the message. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - It may take the following optional parameters: - * type (int, optional) - number for the GW/destination type - to be checked; when omitting this parameter or specifying - the special value -1, matching will be done against all - types. - * flags (string, optional) - letter like flags for - controlling what operations should be performed when a GW - matches: - + 's' (Strip) - apply to the username of RURI the strip - defined by the GW - + 'p' (Prefix) - apply to the username of RURI the - prefix defined by the GW - + 'i' (Gateway ID) - return the gateway id into - gw_id_avp AVP - + 'n' (Ignore port) - ignores port number during - matching - + 'c' (Carrier ID) - return the carrier id into - carrier_id_avp AVP - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the matched - gateway. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of the - matched carrier. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is accepted by this function. - - Example 1.44. goes_to_gw usage -... -# use_partitions is not set -if (goes_to_gw( 1, , $var(gw_attrs))) { - sl_send_reply(403,"Forbidden"); - exit; -} -... -# use_partitions is enabledt -if (goes_to_gw(1, , $var(gw_attrs), , "my_partition")) { - sl_send_reply(403,"Forbidden"); - exit; -} -... - -1.4.6. is_from_gw([type], [flags], [gw_attrs_pvar], -[carrier_attrs_pvar], [partition]) - - The function checks if the sender of the message (source IP + - source port) is a gateway from a certain group. - - This function does not change anything in the message. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ONREPLY_ROUTE. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - It may take the following optional parameters: - * type (int, optional) - number for the GW/destination type - to be checked; when omitting this parameter or specifying - the special value -1, matching will be done against all - types. - * flags (string, optional) - letter like flags for - controlling what operations should be performed when a GW - matches: - + 's' (Strip) - apply to the username of RURI the strip - defined by the GW - + 'p' (Prefix) - apply to the username of RURI the - prefix defined by the GW - + 'i' (Gateway ID) - return the gateway id into - gw_id_avp AVP - + 'n' (Ignore port) - ignores port number during - matching - + 'r' (Check protocol) - check protocol - + 'c' (Carrier ID) - return the carrier id into - carrier_id_avp AVP - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the matched - gateway. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of the - matched carrier. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is accepted by this function. - - Example 1.45. is_from_gw usage -# use_partitions is not set -# match the source IP (only) against all gateways -if (is_from_gw(-1, "n")) { - ... -} - -# use_partitions is enabled -# match the source IP and port against all gateways from the "outbound" -# partition and return the matched gateway's carrier -if (is_from_gw(, "c", , , "outbound")) { - ... -} - -1.4.7. dr_is_gw( sip_uri, [type], [flags], [gw_attrs_pvar], -[carrier_attrs_pvar], [partition]) - - The function checks if the SIP URI hostname part stored inside - the "src_pv" pseudo-variable is a gateway from a certain group. - - This function does not change anything in the message. - - This function can be used from all routes. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - It may take the following optional parameters: - * sip_uri (string) - SIP URI. If the URI hostname part is a - FQDN, it will be resolved prior to matching. - * type (int, optional) - number for the GW/destination type - to be checked; when omitting this parameter or specifying - the special value -1, matching will be done against all - types. - * flags (string, optional) - letter like flags for - controlling what operations should be performed when a GW - matches: - + 's' (Strip) - apply to the username of RURI the strip - defined by the GW - + 'p' (Prefix) - apply to the username of RURI the - prefix defined by the GW - + 'i' (Gateway ID) - return the gateway id into - gw_id_avp AVP - + 'n' (Ignore port) - ignores port number during - matching - + 'c' (Carrier ID) - return the carrier id into - carrier_id_avp AVP - * gw_attrs_pvar (var, optional) - an output writable variable - which will be populated with the attributes of the matched - gateway. - * carrier_attrs_pvar (var, optional) - an output writable - variable which will be populated with the attributes of the - matched carrier. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is accepted by this function. - - Example 1.46. dr_is_gw usage -# match the SIP URI host within $var(uac) against all gateways -if (dr_is_gw( $var(uac), , "n")) { - ... -} - - -# match the SIP URI host within $var(uac) against -# all gws in "outbound" partition -if (dr_is_gw( $avp(uac), , "n", , , "partition")) { - ... -} - -1.4.8. dr_disable([partition]) - - Marks as disabled the last destination that was used for the - current call. The disabling done via this function will prevent - the destination to be used for usage from now on. The probing - mechanism can re-enable this peer (see the probing section in - the beginning) - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - If you set use_partitions parameter to 1 you must supply the - "partition" parameter to instruct on the partition where the - gateway has been defined. - - It may take the following parameters: - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. Wildcard - sign is accepted by this function. - - Example 1.47. dr_disable() usage -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - dr_disable(); - -} -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - dr_disable("my_partition"); - -} -... - -1.4.9. dr_match(groupID, [flags], number, [rule_attrs_pvar], -[partition]) - - The function tries to match/check the given number against the - rules from the database. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - If you set use_partitions to 1 the partition last parameter - becomes mandatory. - - The parameters are: - * groupID (int) - number to specify the dr group (set of - rules) to perform the check against - * flags (string, optional) - a list of letter-like flags for - controlling the checking/matching behavior. Possible flags - are: - + L - Do strict length matching over the prefix - - actually DR engine will do full number matching and - not prefix matching anymore. - * number (string) - the number to check - * rule_attrs_pvar (var, optional) - a writable variable which - will be populated with the attributes of the matched - dynamic routing rule. - * partition (string, optional) - the name of the DR partition - to be used. This parameter is to be defined ONLY if the - "use_partition" module parameter is turned on. - - Example 1.48. dr_match usage -... -if ( dr_match( 1, "L" , $fU, ,"dids") ) - xlog("Full From Username $fU found in group 1 partition DIDS\n") -; -... -if ( dr_match( 1, , $var(did) ) ) - xlog("DID $var(did) matches rules in group 1\n"); -... - -1.5. Exported MI Functions - -1.5.1. dr_reload - - Command to reload routing rules from database. - * if use_partition is set to 0 - all routing rules will be - reloaded. - + inherit_state (optional) : whether inherit old state - of the gateway , default is y. - o “n”: no inherit state - o “y”: inherit state - * if use_partition is set to 1, the parameters are: - + partition_name (optional) - if not provided all the - partitions will be reloaded, otherwise just the - partition given as parameter will be reloaded. - + inherit_state (optional) : whether inherit old state - of the gateway , default is y. - o “n”: no inherit state - o “y”: inherit state - - MI FIFO Command Format: - opensips-cli -x mi dr_reload part_1 - -1.5.2. dr_gw_status - - Gets the status (enabled or disabled) of one or multiple - gateways. The function can also be used to set the status of a - single gateway. - * if use_partitions is set to 0, the parameters are: - + gw_id (optional) - the id of a gateway. If provided, - the function will return/set (depnding if the second - parameter is given) the status of that gateway, - otherwise it will list all gateways along with their - statuses. - + status (optional) - the new status to be forced for a - GW (0 - disable, 1 - enable). Only makes sense if - gw_id is provided. - * if use_partitions is set to 1, the parameters are: - + partition_name - + gw_id (optional) - the id of a gateway. If provided, - the function will return/set (depnding if the third - parameter is given) the status of that gateway, - otherwise it will list all gateways in the given - partition along with their statuses. - + status (optional) - the new status to be forced for a - GW (0 - disable, 1 - enable). Only makes sense if - gw_id is provided. - - Example 1.49. dr_gw_status usage when use_partitions is set to - 0 -$ opensips-cli -x mi dr_gw_status gw_id=2 -State:: Active -$ opensips-cli -x mi dr_gw_status gw_id=2 status=0 -$ opensips-cli -x mi dr_gw_status gw_id=2 -Enabled:: Disabled MI -$ opensips-cli -x mi dr_gw_status gw_id=3 -Enabled:: Inactive - - Example 1.50. dr_gw_status usage when use_partitionsis set to 1 -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw -State:: Active -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw stat -us=0 -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw -enabled:: disabled mi -$ opensips-cli -x mi dr_gw_status partition_name=partition8 status=3 -enabled:: inactive - -1.5.3. dr_carrier_status - - Gets the status (enabled or disabled) of one or multiple - carriers. The function can also be used to set the status of a - single carrier. - * if use_partitions is set to 0, the parameters are: - + carrier_id (optional) - the id of a carrier. If - provided, the function will return/set (depnding if - the second parameter is given) the status of that - carrier, otherwise it will list all carriers along - with their statuses. - + status (optional) - the new status to be forced for a - carrier (0 - disable, 1 - enable). Only makes sense if - carrier_id is provided. - * if use_partitions is set to 1, the parameters are: - + partition_name - + carrier_id (optional) - the id of a carrier. If - provided, the function will return/set (depnding if - the third parameter is given) the status of that - carrier, otherwise it will list all carriers contained - in the given partition along with their statuses. - + status (optional) - the new status to be forced for a - carrier (0 - disable, 1 - enable). Only makes sense if - carrier_id is provided. - - Example 1.51. dr_carrier_status usage when use_partitions is 0 -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 -Enabled:: no -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 status=1 -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 -Enabled:: yes - - Example 1.52. dr_carrier_status usage when use_partitions is 1 -$ opensips-cli -x mi dr_carrier_status partition_name=my_partition carri -er_id=CR1 -Enabled:: no -$ opensips-cli -x mi dr_carrier_status partition_name=partition_1 carrie -r_id=CR1 status=1 -$ opensips-cli -x mi dr_carrier_status partition_name=partition_3 carrie -r_id=CR1 -Enabled:: yes - -1.5.4. dr_reload_status - - Gets the time of the last reload for any partition. - * if use_partition is set to 0 - the function doesn't receive - any parameter. It will list the date of the last reload for - the default (and only) partition. - * if use_partition is set to 1, the parameters are: - + partition_name (optional) - if not provided the - function will list the time of the last update for - every partition. Otherwise, the function will list the - time of the last reload for the given partition. - - Example 1.53. dr_reload_status usage when use_partitions is 0 -$ opensips-cli -x mi dr_reload_status -Date:: Tue Aug 12 12:26:00 2014 - - Example 1.54. dr_reload_status usage when use_partitions is 1 -$ opensips-cli -x mi dr_reload_status -Partition:: part_test Date=Tue Aug 12 12:24:13 2014 -Partition:: part_2 Date=Tue Aug 12 12:24:13 2014 -$ opensips-cli -x mi dr_reload_status part_test -Partition:: part_test Date=Tue Aug 12 12:24:13 2014 - -1.5.5. dr_number_routing - - Gets the matched prefix along with the list of the gateways / - carriers to which a number would be routed when using the - do_routing function. - * if use_partition is set to 1 the function will have 3 - parameters: - + partition_name - + group_id (optional) - the group id of the rules to - check against - + number - the number to test against - * if use_partition is set to 0 the function will have 2 - parameters: - + group_id (optional) - the group id of the rules to - check against - + number - the number to test against - - MI FIFO Command Format: - opensips-cli -x mi dr_number_routing partition_name=part -1 group_id=3 number=012340987 - -1.5.6. dr_enable_probing - - Enables/disables gateway probing or returns the current gateway - probing status. - - Parameters: - * status (optional) - 1 - enable, 0 - disable gateway probing - - Example 1.55. dr_enable_probing usage -$ opensips-cli -x mi dr_enable_probing -Status:: 1 -$ opensips-cli -x mi dr_enable_probing 0 -$ opensips-cli -x mi dr_enable_probing -Status:: 0 - -1.6. Exported Events - -1.6.1. E_DROUTING_STATUS - - This event is raised when the module changes the state of a - gateway, either through an MI command, probing or script - function. - - Parameters: - * partition - the name of the partition. - * gwid - the gateway identifier. - * address - the address of the gateway. - * status - disabled MI if the gateway was disabled using MI - commands, probing if the gateway is being pinged, inactive - if it was disabled from the script or active if the gateway - is enabled. - -1.7. Exported Status/Report Identifiers - - The module provides the "drouting" Status/Report group, where - each routing partition is defined as a separate SR identifier. - -1.7.1. [partition_name] - - The status of these identifiers reflects the readiness/status - of the cached data (if available or not when being loaded from - DB): - * -2 - no data at all (initial status) - * -1 - no data, initial loading in progress - * 1 - data loaded, partition ready - * 2 - data available, a reload in progress - - Reload reporting: - - In terms of data reloading, the following logs will be - reported: - * starting DB data loading - * DB data loading failed, discarding - * DB data loading successfully completed - * N gateways loaded (N discarded), N carriers loaded (N - discarded), N rules loaded (N discarded) - - { - "Name": "Default", - "Reports": [ - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "2 gateways loaded (0 discarded), 2 carriers load -ed (0 discarded), 1 rules loaded (0 discarded)" - } - ] - } - -1.7.2. [partition_name];events - - GW/Carrier switching reporting: - - For reporting events related to the state changes of the - gateways and carriers, the module provides separate identifiers - (still one per partition). Why separate ones? The reports on - state changing may be verbose and there is the risk of - loose/discard important reports on reloads due to the high - number of logs on state changes; - - So, each partition will provide the identified - "partition_name;events" for reporting state changes of gateways - and carriers, along with the reason of the change. This - identifiers have a 200 records history before discarding the - old ones. - { - "Name": "Default;events", - "Reports": [ - { - "Timestamp": 1652353976, - "Date": "Thu May 12 14:12:56 2022", - "Log": "GW /127.0.1.1 switched to [inactive] due -probing reply\n" - }, - { - "Timestamp": 1652353976, - "Date": "Thu May 12 14:12:56 2022", - "Log": "GW /127.0.1.2 switched to [inactive] due -probing reply\n" - } - ] - } - - For how to access and use the Status/Report information, please - see - https://www.opensips.org/Documentation/Interface-StatusReport-3 - -3. - -1.8. Installation - - The module requires 4 tables in the OpenSIPS database: - dr_groups, dr_gateways, dr_carriers, dr_rules. The SQL syntax - to create them can be found in the drouting-create.sql script, - located in the database directories of the opensips/scripts - folder. You can also find the complete database documentation - on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer Guide - - The module provides no function to be used by other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 416 202 13810 5824 - 2. Liviu Chircu (@liviuchircu) 163 97 2515 2613 - 3. Razvan Crainea (@razvancrainea) 100 53 1171 2226 - 4. Mihai Tiganus (@tallicamike) 73 20 4301 910 - 5. Vlad Patrascu (@rvlad-patrascu) 43 20 1100 735 - 6. Vlad Paiu (@vladpaiu) 28 22 421 65 - 7. Andrei Datcu (@andrei-datcu) 20 12 551 134 - 8. Ovidiu Sas (@ovidiusas) 15 11 132 70 - 9. Ionut Ionita (@ionutrazvanionita) 15 9 370 108 - 10. Maksym Sobolyev (@sobomax) 10 8 30 29 - - All remaining contributors: Andrei Dragus, Anca Vamanu, Nick - Altmann (@nikbyte), Jeremy Martinez (@JeremyMartinez51), - wangdd, nexbridge, Dusan Klinec (@ph4r05), Walter Doekes - (@wdoekes), MayamaTakeshi, Matt Lehner, Julián Moreno Patiño, - Sergio Gutierrez, Le Roy Christophe, Peter Lemenkov - (@lemenkov), Alexey Vasilyev (@vasilevalex), Ozzyboshi, Aron - Podrigal (@ar45). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2008 - Nov 2024 - 2. Vlad Paiu (@vladpaiu) Aug 2011 - Feb 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2020 - Nov 2023 - 4. Razvan Crainea (@razvancrainea) Sep 2010 - Oct 2023 - 5. wangdd May 2023 - May 2023 - 6. MayamaTakeshi Apr 2023 - Apr 2023 - 7. nexbridge Feb 2023 - Mar 2023 - 8. Vlad Patrascu (@rvlad-patrascu) Mar 2017 - Jul 2022 - 9. Nick Altmann (@nikbyte) Mar 2013 - May 2021 - 10. Walter Doekes (@wdoekes) May 2014 - Apr 2021 - - All remaining contributors: Liviu Chircu (@liviuchircu), Aron - Podrigal (@ar45), Alexey Vasilyev (@vasilevalex), Peter - Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Jeremy Martinez - (@JeremyMartinez51), Le Roy Christophe, Ionut Ionita - (@ionutrazvanionita), Ozzyboshi, Julián Moreno Patiño, Dusan - Klinec (@ph4r05), Mihai Tiganus (@tallicamike), Andrei Datcu - (@andrei-datcu), Matt Lehner, Anca Vamanu, Andrei Dragus, - Sergio Gutierrez. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu - (@vladpaiu), Razvan Crainea (@razvancrainea), wangdd, Vlad - Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu - (@bogdan-iancu), Nick Altmann (@nikbyte), Alexey Vasilyev - (@vasilevalex), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), Mihai Tiganus (@tallicamike), Andrei - Datcu (@andrei-datcu), Matt Lehner, Anca Vamanu, Andrei Dragus, - Sergio Gutierrez. - - Documentation Copyrights: - - Copyright © 2009-2012 www.opensips-solutions.com - - Copyright © 2005-2008 Voice Sistem SRL diff --git a/modules/drouting/README.md b/modules/drouting/README.md new file mode 100644 index 00000000000..51394140519 --- /dev/null +++ b/modules/drouting/README.md @@ -0,0 +1,2064 @@ +--- +title: "Dynamic Routing Module" +description: "Dynamic Routing is a module for selecting (based on multiple criteria) the best gateway/destination to be used for delivering a certain call." +--- + +## Admin Guide + + +### Overview + + +#### Introduction + + +Dynamic Routing is a module for selecting (based on multiple +criteria) the best gateway/destination to be used for delivering a +certain call. Least Cost Routing (LCR) is a special case of dynamic +routing - when the rules are ordered based on costs. Dynamic Routing +comes with many features regarding routing rule selection: + + +- prefix based +- caller/group based +- time based +- priority based + + +, processing : + + +- stripping and prefixing +- default rules +- inbound and outbound processing +- script route triggering + + +and failure handling: + + +- serial forking +- weight based GW selection +- random GW selection +- GW probing for crashes + + +#### Features + + +The dynamic routing implementation for OpenSIPS is designed with the +following properties: + + +- The routing info (destinations, carriers, rules, groups) is stored in a +database and loaded into memory at start up time; reload at runtime via +a Management Interface command. +- weight-based or random selection of the destinations (from a rule or +from a carrier), failure detection of gateways (with switching to next +available gateway). +- able to handle large volume of routing info (10M of rules) with minimal +speed/time and memory consumption penalties +- script integration - Pseudo-variable support in functions; scripting +route triggering when rules are matched +- bidirectional behavior - inbound and outbound processing (strip and +prefixing when sending and receiving from a destination/GW) +- blacklisting - the module allows definition of blacklists based on the +destination IPs. This blacklists are to be used to prevent malicious +forwarding to GWs (based on DNS lookups) when the script logic does +none-GE forwarding (like foreign domains). +- loading routing information from multiple databases - the gateways, rules, groups and +carriers can be grouped by partitions, and each partition may be loaded +from different databases/tables. This makes the routing process partition +based. In order to be able to use a table from a partition, its name must +be found in the "version" table belonging to the database defined in the +partition's db_url. + + +#### Performance + + +There were several tests performed regarding the performance of the module +when dealing with a large number of routing rules. + + +The tests were performed with a set of 383000 rules and measured: + + +- time to load from DB +- used shared memory + + +The time to load was varying between 4 seconds and 8 seconds, depending of +the caching of the DB client - the first load was the slowest (as the DB +query hits the disk drive); the following are faster as data is already +cached in the DB client. So technically speaking, the time to load (without +the time to query which is DB type dependent) is ~4 seconds + + +After loading the data into shared memory ~ 96M of memory were used +exclusively for the DR data. + + +#### Dynamic Routing Concepts + + +DR engine uses several concepts in order to define how the routing +should be done (describing all the dependencies between destinations +and routing rules). + + +##### Destination/Gateways + + +These are the end SIP entities where actually the traffic needs to be sent +after routing. They are stored in a table called "dr_gateways". +Gateway addresses are stored in a separate table because of the need to access them +independent of Dynamic Routing processing (e.g., adding/ removing gateway PRI +prefix before/after performing other operation -- receiving/relaying to gateway). + + +In DR, a gateway is defined by: + + +- id (string) +- SIP address (SIP URI) +- type (integer which allows GWs to be grouped by purpose, +e.g. inbound, outbound, etc.) +- strip value (number of digits) from dialled +number +- prefix (string) to be added to dialled +number +- attributes (not used by DR engine, but only pushed +to script level when routing to this GW) +- probing mode (how the GW should be probed at SIP level - see the probing chapter) + + +The Gateways are to be used from the routing rule or from the carrier +definition. They are all the time referred by their ID. + + +##### Carriers + + +The carrier concept is used if you need to group gateways in order to +have a better control on how the GWs will be used by DR rules; like +in what order the GWs will be used. + + +Basically, a carrier is a set of gateways which have its own sorting +algorithm and its own attribute string. They are by default defined +in the "dr_carriers" table. + + +In DR, a carrier is defined by: + + +- id (string) +- list of gateways with/without weights (string) +(Ex:"gw1=10,gw4=10" or "gw1,gw2" +- flags : 0x1 - use only the first gateway from the carrier +(depending on the sorting); 0x2 - disable the usage of this +carrier +- sort algorithm : how the list of the gateways should be +sorted before being used, NULL - use the DB given order, W - do weight +based re-ordering, Q - do quality based sorting (requires the qrouting +module) +- attributes (not used by DR engine, but only pushed +to script level when routing to this carrier) + + +The Carriers are to be used only from the routing rule definition. +They are all the time referred by their ID. + + +##### Routing Rules + + +These are the actual rules which control the routing. Using +different criterias (prefix, time, priority, etc), they will decide +to which gateways the call will be sent. + + +Default name for the table storing rule definitions is +"dr_rules". + + +In DR, a routing rule is defined by: + + +- group (list of numbers) - rules can be grouped (a rule may +belong to multiple groups in the same time ) and you can +use only a certain group at a point; like having a "premium" or +"standard" or "interstate" or +"intrastate" groups of rules to be used in different +cases +- prefix (string with digits only) - prefix to be used for +matching this rule (longest prefix matching) +- time validity (time recurrence string) - when this rule is +valid from time point of view (see RFC 2445) +- priority (number) - priority of the rule - higher value, +higher priority (see rule section alg) +- script route ID (string) - if defined, then execute the +route with the specified ID when this rule is matched. That's it, a route +which can be used to perform custom operations on message. NOTE that no +modification is performed at signaling level and you must NOT do +any signaling operations in that script route +- list of GWs/carriers (string) - a comma separated list +of gateways or carriers (defined by IDs) to be used for this rule; the +carrier IDs are prefixed with "#" sign. For each ID (GW or +carrier) you may specify a weight. For how this list will be interpreted +(as order) see the rule selection section. Example of list: +"gw1,gw4,#cr3" or "gw1=10,gw4=10,#cr3=80" +- attributes (not used by DR engine, but only pushed +to script level when this rule matched and been used) + + +More on time recurrence: + + +- A date-time expression that defines the time recurrence to be matched for +current rule. Time recurrences are based closely on the recurring time +intervals from the Internet Calendaring and Scheduling Core Object +Specification (calendar COS), RFC 2445. The set of attributes used in +a routing rule specification is a subset of time recurrence attributes. +- The value stored in database has the basic format of: + +``` + ||||||||||| +``` + +, identical to the input of the [check_time_rec()](../cfgutils#func_check_time_rec) +function of the *cfgutils* module, including the optional +use of logical operators linking multiple such strings into a larger expression. +- When an attribute is not specified, the corresponding place must be left +empty, whenever another attribute that follows in the list has to be +specified. + + +#### Routing Rule Processing + + +The module can be used to find out which is the best gateway to use for new +calls terminated to PSTN. The algorithm to select the rule is as follows: + + +- the module discovers the routing group of the originating user. This +step is skipped if a routing group is passed from the script as parameter. +- once the group is known, in the subset of the rules for this group the +module looks for the one that matches the destination based on "prefix" +column. The set of rules with the longest prefix is chosen. If no digit +from the prefix matches, the default rules are used (rules with no prefix) +- within the set of rules is applied the time criteria, and the rule which +has the highest priority and matches the time criteria is selected to drive +the routing. +- Once found the rule, it may contain a route ID to execute. If a certain +flag is set, then the processing is stopped after executing the route +block. +- The rule must contain a chain of gateways and carriers. The module will +execute serial forking for each address in the chain (ordering is either done +by simply using the definition order or it may weight-based - weight selection must be +enabled). The next address in chain is used only if the previously has failed. +- With the right gateway address found, the prefix (PRI) of the gateway is +added to the request URI and then the request is forwarded. + + +If no rule is found to match the selection criteria an default action must +be taken (e.g., error response sent back). If the gateway in the chain has +no prefix the request is forwarded without adding any prefix to the request +URI. + + +#### Probing and Disabling destinations + + +The module has the capability to monitor the status of the destinations by +doing SIP probing (sending SIP requests like OPTIONS). + + +For each destination, you can configure what kind of probing should be +done (probe_mode column): + + +- *(0)* - no probing at all; +- *(1)* - probing only when the destination is +in disabled mode (disabling via MI command will completely stop the +probing also). The destination will be automatically re-enabled +when the probing will succeed next time; +- *(2)* - probing all the time. If disabled, +the destination will be automatically re-enabled when the probing +will succeed next time; + + +A destination can become disabled in two ways: + + +- script detection +- MI command + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. + + +- *tm module*. +- *clusterer* - only if "cluster_id" +option is enabled. + + +#### External Libraries or Applications + + +- *none*. + + +### Exported Parameters + + +#### db_url(str) + + +The database url. + + +*Default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("drouting", "db_url", + "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### drd_table(str) + + +The name of the db table storing gateway addresses. + + +*Default value is "dr_gateways".* + + +```opensips title="Set drd_table parameter" +... +modparam("drouting", "drd_table", "dr_gateways") +... +``` + + +#### drr_table(str) + + +The name of the db table storing routing rules. + + +*Default value is "dr_rules".* + + +```opensips title="Set drr_table parameter" +... +modparam("drouting", "drr_table", "rules") +... +``` + + +#### drg_table(str) + + +The name of the db table storing groups. + + +*Default value is "dr_groups".* + + +```opensips title="Set drg_table parameter" +... +modparam("drouting", "drg_table", "groups") +... +``` + + +#### drc_table(str) + + +The name of the db table storing definitions of the carriers that will +be used directly by the routing rules. + + +*Default value is "dr_carriers".* + + +```opensips title="Set drc_table parameter" +... +modparam("drouting", "drc_table", "my_dr_carriers") +... +``` + + +#### ruri_avp (str) + + +The name of the avp for storing Request URIs to be later used +(alternative destiantions for the current one). + + +*Default value is "$avp(___dr_ruri__)" if `use_partitions` parameter is 0 +or "$avp(___dr_ruri__partition_name)" where partition_name is the name of the partition +containing the AVP (as fetched from the database) if `use_partitions` parameter is 1.* + + +```opensips title="Set ruri_avp parameter" +... +modparam("drouting", "ruri_avp", '$avp(dr_ruri)') +modparam("drouting", "ruri_avp", '$avp(33)') +... + +``` + + +#### gw_id_avp (str) + + +The name of the avp for storing the id of the current selected +gateway/destination - once a new destination is selected (via the +use_next_gw() function), the AVP will be updated with the ID of the +new selected gateway/destination. + + +*Default value is "$avp(___dr_gw_id__)" if `use_partitions` parameter is 0 +or "$avp(___dr_gw_id__partition_name)" where partition_name is the name of the partition +containing the AVP (as fetched from the database) if `use_partitions` parameter is 1.* + + +```opensips title="Set gw_id_avp parameter" +... +modparam("drouting", "gw_id_avp", '$avp(gw_id)') +modparam("drouting", "gw_id_avp", '$avp(334)') +... + +``` + + +#### gw_priprefix_avp (str) + + +The name of the avp for storing the PRI prefix of the current selected +destination/gateway - once a new destination is selected (via the +use_next_gw() function), the AVP will be updated with the PRI prefix of the +new used destination. + + +*Default value is "NULL".* + + +```opensips title="Set gw_priprefix_avp parameter" +... +modparam("drouting", "gw_priprefix_avp", '$avp(gw_priprefix)') +... + +``` + + +#### rule_id_avp (str) + + +The name of the avp for storing the id of the current matched +routing rule (see dr_rules table). + + +*Default value is "NULL".* + + +```opensips title="Set rule_id_avp parameter" +... +modparam("drouting", "rule_id_avp", '$avp(rule_id)') +modparam("drouting", "rule_id_avp", '$avp(335)') +... + +``` + + +#### rule_prefix_avp (str) + + +The actual prefix that matched the routing rule (the part from RURI +username that matched the routing rule). + + +*Default value is "NULL".* + + +```opensips title="Set rule_prefix_avp parameter" +... +modparam("drouting", "rule_prefix_avp", '$avp(dr_prefix)') +... + +``` + + +#### carrier_id_avp (str) + + +AVP to be populate with the ID string for the carrier the +current GW belongs to. + + +*Default value is "NULL".* + + +```opensips title="Set carrier_id_avp parameter" +... +modparam("drouting", "carrier_id_avp", '$avp(carrier_id)') +... + +``` + + +#### gw_sock_avp (str) + + +The name of the avp for storing sockets for alternative destinations +defined by ruri_avp. + + +*Default value is "$avp(___dr_sock__)" if `use_partitions` parameter is 0 +or "$avp(___dr_sock__partition_name)" where partition_name is the name of the partition +containing the AVP (as fetched from the database) if `use_partitions` parameter is 1.* + + +```opensips title="Set gw_sock_avp parameter" +... +modparam("drouting", "gw_sock_avp", '$avp(dr_sock)') +modparam("drouting", "gw_sock_avp", '$avp(77)') +... + +``` + + +#### define_blacklist (str) + + +Defines a blacklist based on a list of GW types - the blacklist will +be populated with the IPs (no port, all protocols) of the GWs having +the specified types. + + +If partitions are used, prefix the blacklist definition string with +the name of the partition followed by ":" separator. + + +Multiple instances of this param are allowed. + + +*Default value is "NULL".* + + +```opensips title="Set define_blacklist parameter" +... +modparam("drouting", "define_blacklist", 'bl_name= 3,5,25,23') +modparam("drouting", "define_blacklist", 'list= 4,2') +modparam("drouting", "define_blacklist", 'pstn:list2 = 5,6') +modparam("drouting", "define_blacklist", 'pstn:list3 = 7,8') +... + +``` + + +#### default_group (int) + + +Group to be used if the caller (FROM user) is not found in the GROUP +table. + + +*Default value is "NONE".* + + +```opensips title="Set default_group parameter" +... +modparam("drouting", "default_group", 4) +... +``` + + +#### force_dns (int) + + +Force DNS resolving of GW/destination names (if not IPs) during +startup. If not enabled, the GW name will be blindly used during +routing. + + +*Default value is "1 (enabled)".* + + +```opensips title="Set force_dns parameter" +... +modparam("drouting", "force_dns", 0) +... + +``` + + +#### persistent_state (int) + + +Specifies whether the *state* column +should be loaded at startup and flushed during runtime or not. + + +*Default value is "1" (enabled).* + + +```opensips title="Set the persistent_state parameter" +... +# disable all DB operations with the state of a gateway +modparam("drouting", "persistent_state", 0) +... +``` + + +#### no_concurrent_reload (int) + + +If enabled, the module will not allow do run multiple dr_reload +MI commands in parallel (with overlapping) Any new reload will +be rejected (and discarded) while an existing reload is in +progress. + + +If you have a large routing set (millions of rules/prefixes), you +should consider disabling concurrent reload as they will exhaust +the shared memory (by reloading into memory, in the same time, +multiple instances of routing data). + + +*Default value is "0 (disabled)".* + + +```opensips title="Set no_concurrent_reload parameter" +... +# do not allow parallel reload operations +modparam("drouting", "no_concurrent_reload", 1) +... +``` + + +#### probing_interval (integer) + + +How often (in seconds) the probing of a destination should be done. If +set to 0, the probing will be disabled as functionality (for all +destinations) + + +*Default value is "30".* + + +```opensips title="Set probing_interval parameter" +... +modparam("drouting", "probing_interval", 60) +... +``` + + +#### probing_method (string) + + +The SIP method to be used for the probing requests. + + +*Default value is ""OPTIONS"".* + + +```opensips title="Set probing_method parameter" +... +modparam("drouting", "probing_method", "INFO") +... +``` + + +#### probing_from (string) + + +The FROM SIP URI to be advertised in the SIP probing requests. + + +*Default value is ""sip:prober@localhost"".* + + +```opensips title="Set probing_from parameter" +... +modparam("drouting", "probing_from", "sip:pinger@192.168.2.10") +... +``` + + +#### probing_reply_codes (string) + + +A comma separted list of SIP reply codes. The codes defined here +will be considered as valid reply codes for probing messages, +apart for 200. + + +*Default value is "NULL".* + + +```opensips title="Set probing_reply_codes parameter" +... +modparam("drouting", "probing_reply_codes", "501, 403") +... +``` + + +#### probing_socket (string) + + +A socket description [proto:]host[:port] of the local socket +(which is used by OpenSIPS for SIP traffic) to be used +(if multiple) for sending the probing messages from. + + +For probing gateway the highest priority has socket from gateway +configuration in dr_gateways table. Then socket from global +`probing_socket` parameter and the lowest +priority is default behaviour with auto selected socket wich +OpenSIPS listens on. + + +*Default value is "NULL".* + + +```opensips title="Set probing_socket parameter" +... +modparam("drouting", "probing_socket", "udp:192.168.1.100:5060") +... +``` + + +#### gw_socket_filter_mode (string) + + +This parameter controls the gateway filtering during DB loading, or which +gateways are loaded or not into memory depending on the configured +socket they have. + + +The supported filtering modes are: + + +- **"all"** - all the gateways +defined in DB are loaded into memory, disregarding what socket +value they have. NOTE: for the gw sockets not matching any OpenSIPS +listeners/sockets, the GW will be loaded with NULL/no socket. +- **"ignore"** - all the gateways +defined in DB are loaded into memory, but ignoring the socket +value they have (the socket will be set to NULL/NONE with no +attempt to check it against the OpenSIPS listeners/sockets). +- **"matched-only"** - in this mode +the module will load from DB only the gateways that have a +configured a socket matching any of the the OpenSIPS +listeners/sockets. If the gateways socket does not match, it will +be discards, not loaded into memory at all. + + +*Default value is ""all"".* + + +```opensips title="Set gw_socket_filter_mode parameter" +... +# multiple OpenSIPS instances sharing a DR setting, so each should +# load only the GWs they have sockets for. +modparam("drouting", "gw_socket_filter_mode", "matched-only") +... +# an OpenSIPs instance not doing routing, but needing to be +# aware of all the gws, so load them all ignoring the sockets +modparam("drouting", "gw_socket_filter_mode", "ignore") +... +``` + + +#### cluster_id (integer) + + +The ID of the cluster the module is part of. The clustering support is +used in drouting module for two purposes: for sharing the status of +the gateways/carriers and for controlling the pinging to gateways. + + +If clustering enbled, the module will automatically share changes +over the status of the gateways/destinations/carriers with the other +OpenSIPS instances that are part of a cluster. Whenever such a status +changes (following an MI command, a probing result, a script command), +the module will replicate this status change to all the nodes in this +given cluster. + + +The clustering with sharing tag support may be used to control which +node in the cluster will perform the pinging/probing to +gateways. See the +[cluster sharing tag](#param_cluster_sharing_tag) option. + + +This OpenSIPS cluster exposes the **"drouting-status-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +For more info on how to define and populate a cluster (with OpenSIPS +nodes) see the [clusterer](../clusterer) module. + + +*Default value is "0 (none)".* + + +```opensips title="Set cluster_id parameter" +... +# replicate gw/carrier status with all OpenSIPS in cluster ID 9 +modparam("drouting", "cluster_id", 9) +... +``` + + +#### cluster_sharing_tag (string) + + +The name of the sharing tag (as defined per clusterer modules) to +control which node is responsible for perform the self-triggered +actions in the module. Such actions may be the gateway probing (see +also the [cluster probing mode](#param_cluster_probing_mode) parameter) or +sharing the gateway/carrier status changes. +If defined, only the node with active status of this tag will +perform the actions (pinging and sharing status). + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +This is an optional parameter. If not set, all the nodes in the cluster +will share the status changes. + + +*Default value is "empty (none)".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +# and broadcast the status changes +modparam("drouting", "cluster_id", 9) +modparam("drouting", "cluster_sharing_tag", "vip") +... +``` + + +#### cluster_probing_mode (string) + + +This paramter controls how the probing/pinging should be done when +using the clustering support. It is about which node in the cluster +pings which gateway/destination. + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +The supported probing modes are: + + +- **"all"** - all the nodes in the +cluster will independetly ping all the defined gateways, +an "all" pings "all" mode. +- **"by-shtag"** - all the gateways +are pinged by only one node in the cluster, the node having the +[cluster sharing tag](#param_cluster_sharing_tag) active. By +activating the sharing tag on a different node, the pinging +duty will be transfered to another node in the cluster. +- **"distributed"** - the pinging +effort is distributed across all the nodes in the cluster, so each +node will ping a sub-set of the overall set of gateway. Still all +the gateways will get pinged (and only once per pinging cycle). +The re-partitioning of the pinging effort over the available nodes +in the cluster is automatically done when new nodes are joining or +nodes are dropping out. Still there is no guaratee on which node +will be responsible for pinging which gateway. + + +*Default value is ""all"".* + + +```opensips title="Set cluster_probing_mode parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +modparam("drouting", "cluster_id", 9) +modparam("drouting", "cluster_sharing_tag", "vip") +modparam("drouting", "cluster_probing_mode", "by-shtag") +... +# the pinging effort is distributed across all the nodes +modparam("drouting", "cluster_id", 9) +modparam("drouting", "cluster_probing_mode", "distributed") +... +``` + + +#### use_domain (int) + + +Flag to configure whether to use domain match when querying +database for user's routing group. + + +*Default value is "1".* + + +```opensips title="Set use_domain parameter" +... +modparam("drouting", "use_domain", 0) +... +``` + + +#### drg_user_col (str) + + +The name of the column in group db table where the username is stored. + + +*Default value is "username".* + + +```opensips title="Set drg_user_col parameter" +... +modparam("drouting", "drg_user_col", "user") +... +``` + + +#### drg_domain_col (str) + + +The name of the column in group db table where the domain is stored. + + +*Default value is "domain".* + + +```opensips title="Set drg_domain_col parameter" +... +modparam("drouting", "drg_domain_col", "host") +... +``` + + +#### drg_grpid_col (str) + + +The name of the column in group db table where the +group id is stored. + + +*Default value is "groupid".* + + +```opensips title="Set drg_grpid_col parameter" +... +modparam("drouting", "drg_grpid_col", "grpid") +... +``` + + +#### use_partitions (int) + + +Flag to configure whether to use partitions for routing. If this +flag is set then the `db_partitions_url` and +`db_partitions_table` +variables become mandatory. + + +*Default value is "0".* + + +```opensips title="Set use_partitions parameter" +... +modparam("drouting", "use_partitions", 1) +... +``` + + +#### db_partitions_url (str) + + +The url to the database containing partition-specific +information. (partition-specific information includes +partition name, url to the database where information about +the partition is preserved, the names of the tables in which it +is preserved and the AVPs that can be accessed using the .cfg +script). The `use_partitions` parameter +must be set to 1. + + +*Default value is ""NULL"".* + + +```opensips title="Set db_partitions_url parameter" +... +modparam("drouting", "db_partitions_url", "mysql://user:password@localhost/opensips_partitions") +... +``` + + +#### db_partitions_table (str) + + +The name of the table containing partition definitions. To be +used with `use_partitions` and `db_partitions_url`. + + +*Default value is "dr_partitions".* + + +```opensips title="Set db_partitions_table parameter" +... +modparam("drouting", "db_partitions_table", "partition_defs") +... +``` + + +#### partition_id_pvar (pvar) + + +Variable which will store the name of the name partition when +*wildcard(*)* operatior is used. +*Use_partitions* must be set in order to +use this parameter. + + +> [!NOTE] +> The variable must be WRITABLE! + + +*Default value is "null(not used)".* + + +```opensips title="Set partition_id_pvar parameter" +... +modparam("drouting", "partition_id_pvar", "$var(matched_partition)") +... +``` + + +#### enable_restart_persistency (int) + + +Parameter set to enable restart persistency for the Dynamic Routing module. +When this parameter is set, the drouting module no longer loads the data +from the database after restart, but uses the persistent storage file, and loads +data from it "on demand", improving the startup performance. + + +> [!NOTE] +> If the restart persistent cache is not populated from a previous run, +> then the data will be loaded from database at startup! + + +> [!NOTE] +> A reload will update the cached data. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set enable_restart_persistency parameter" +... +modparam("drouting", "enable_restart_persistency", yes) +... +``` + + +#### extra_prefix_chars (str) + + +List of ASCII (0-127) characters to be additionally accepted in +the prefixes. By default only '0' - '9' chars (digits) are +accepted. + + +*Default value is "NULL".* + + +```opensips title="Set extra_prefix_chars parameter" +... +modparam("drouting", "extra_prefix_chars", "#-%") +... +``` + + +#### extra_id_chars (str) + + +A set of extra characters to be allowed in both Gateway and Carrier +unique string identifiers, on top of alphanumeric characters. + + +*Default value is "_-.".* + + +```opensips title="Set extra_id_chars parameter" +... +modparam("drouting", "extra_id_chars", ":_-.") +... +``` + + +#### rule_tables_query (str) + + +This parameter offers a dynamic, SQL-based way of building a set of +*dr_rules*-compatible table names, to be +each loaded and then merged into a single "dr_rules" table, +for any given partition. + + +The syntax of the parameter is: +"**token** : **query**", +where **token** is a special name +given to a "dr_rules" table, so OpenSIPS can match it against +the custom queries defined using this parameter. + + +This parameter may be set multiple times (each definition creates +a new mapping). + + +```opensips title="Set the rule_tables_query parameter" +... +# first, set the "dr_rules" table name to the name of your query +modparam("drouting", "drr_table", "MY_RULES_QUERY") + +# next, instruct drouting to load both 'dr_rules_a' and 'dr_rules_b', +# then merge all of their rules +modparam("drouting", "rule_tables_query", " + MY_RULES_QUERY: + SELECT 'dr_rules_a' UNION SELECT 'dr_rules_b'") +... +``` + + +#### generate_data_checksum (int) + + +If enabled, it will generate a checksum ( MD5 ) for drouting loaded data, attach that to the reload_status MI command output and to the reload generated status reports + + +```opensips title="Set the generate_data_checksum parameter" +... +modparam("drouting", "generate_data_checksum", 1) +... + +``` + + +### Exported Functions + + +#### do_routing([groupID], [flags], [gw_whitelist], [rule_attrs_pvar], [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +Function to trigger routing of the message according to the +rules in the database table and the configured parameters. + + +This function can be used from all routes. + + +If you set `use_partitions` to 1 the +**partition** last parameter becomes +mandatory. + + +All parameters are optional. Any of them may be ignored, provided +the necessary separation marks "," are properly placed. + + +- **groupID** (int, optional) - number to +specify the group of the caller for routing purposes. +If none specified the function will automatically try to query +the dr_group table to get this +- **flags** (string, optional) - a list +of letter-like flags for controlling the routing behavior. +Possible flags are: + + - **F** - Enable rule fallback; +normally the engine is using a single rule for routing a call; +by setting this flag, the engine will fallback and use +rules with less priority or shorter prefix when all the +destination from the current rules failed. + - **L** - Do strict length matching +over the prefix - actually DR engine will do full number +matching and not prefix matching anymore. + - **C** - Only check if the dialed +number matches any routing rule, without loading / applying any +routing info (no GW is set, the RURI is not altered) +- **gw_whitelist** (string, optional) - a +comma separated white list of gateways. This will force routing over, +at most, this list of carriers or gateways (in other words, +the whitelist will be intersected with the results of the search +through the rules). +- **rule_attrs_pvar** (var, optional) - a +writable variable which will be populated with the attributes of the +matched dynamic routing rule. +- **gw_attrs_pvar** (var, optional) - a +writable variable which will be +populated with the attributes of the matched gateway. +- **carrier_attrs_pvar** (var, optional) - a +a writable variable which will be +populated with the attributes of the matched carrier. +- **partition** (string, optional) - the name +of the DR partition to be used. This parameter is to be defined +ONLY if the "use_partition" module parameter is turned on. +Besides specifing the name of one partition, you can use the "*" +wildcard sign to force routing over all partitions. + + +```c title="do_routing usage" +... +# all groups, sort on order, +``` + + +#### route_to_carrier( carriers, [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +Function to trigger the direct routing to a given set carriers (one +or more). So, the routing is not done prefix based, but carrier based +(call will be sent to the GWs of that carrier, based on carrier +policy). + + +This function can be used from all routes. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter also (where the carrier are to be +found). + + +- **carriers** (string) - comma separated +carrier IDs (names) +- **gw_attrs_pvar** (var, optional) - +an output writable variable which will be populated +with the attributes of the currently matched gateway of +this carrier. +- **carrier_attrs_pvar** (var, +optional) - an output writable variable which will be populated +with the attributes of this carrier. +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is not accepted by the +function. + + +```opensips title="route_to_carrier usage" +... +# use_partitions is not set +if ( route_to_carrier("my_top_carrier, def_carrier", , $var(carrier_att)) ) { + xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); + t_on_failure("next_gw"); + t_relay(); + exit; +} +... +# use_partitions is enabled +if ( route_to_carrier("my_top_carrier", , $var(carrier_att), "part") ) { + xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); + t_on_failure("next_gw"); + t_relay(); + exit; +} +... +# use_partitions is enabled +if ( route_to_carrier($var(carrierId), , , $var(my_partition)) ) { + xlog("Routing to \"my_top_carrier\"\n"); + t_on_failure("next_gw"); + t_relay(); + exit; +} +... +``` + + +#### route_to_gw(gw_id, [gw_attrs_var], [carrier_attrs_var], [partition]) + + +Function to trigger the direct routing to a given gateway (or list of +gateways). Attributes and per-gw processing will be available. + + +This function can be used from all routes. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +- **gw_id** (string) - comma +separated list of gateway IDs to be used. +- **gw_attrs_pvar** (var, optional) + - an output writable variable which will be populated +with the attributes of the currently matched gateway. +- **carrier_attrs_pvar** (var, +optional) - an output writable variable which will be +populated with the attributes of this carrier. NOTE: the +first carrier pointing to the GW(s) will be considered! +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is not accepted by the +function. + + +```opensips title="route_to_gw usage" +... +# use_partitions is not set +if ( route_to_gw("gw_europe") ) { + t_relay(); + exit; +} +... +# use_partitions is not set +if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs)) ) { + xlog("Relaying to first gateway from our list - $var(gw_attrs)\n"); + t_relay(); + exit; +} +... +# use_partitions is enabled +if ( route_to_gw("gw_europe", , , "my_partition") ) { + t_relay(); + exit; +} +... +# use_partitions is enabled +if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs), , "my_partition") ) { + xlog("Relaying to first gateway from our list - $var(gw_attrs)\n"); + t_relay(); + exit; +} +... +``` + + +#### use_next_gw( [rule_attrs_pvar], [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +The function takes the next available destination (set by do_routing, +as alternative destinations) and pushes it into the RURI. Note that the +function just sets the RURI (nothing more). + + +If a new RURI is set, the used destination is removed from the +pending set of alternative destinations. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +The function returns true only if a new RURI was set. False +is returned is no other alternative destinations are found or in case +of an internal processing error. It may take the following optional +parameters: + + +- **rule_attrs_pvar** (var, optional) + - an output writable variable which will be populated +with the attributes of the matched dynamic routing rule. +- **gw_attrs_pvar** (var, optional) - an +output writable variable which will be populated +with the attributes of the matched gateway. +- **carrier_attrs_pvar** (var, optional) + - an output writable variable which will be populated +with the attributes of the matched carrier. +- **partition** (optinal, string) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is not accepted by the +function. + + +```opensips title="use_next_gw usage" +... +# use_partitions is not set +if (use_next_gw()) { + t_relay(); + exit; +} +... +# Also fetch the carrier attributes, if any +if (use_next_gw(, , $var(carrier_attrs))) { + xlog("Carrier attributes of current gateway: $var(carrier_attrs)\n"); + t_relay(); + exit; +} +... +# use_partitions is enabled +if (use_next_gw( , , ,"my_partition")) { + t_relay(); + exit; +} +... +# Also fetch the carrier attributes, if any +if (use_next_gw( , ,$var(carrier_attrs), "my_partition")) { + xlog("Carrier attributes of current gateway: $var(carrier_attrs)\n"); + t_relay(); + exit; +} +... +``` + + +#### goes_to_gw( [type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +Function returns true if the destination of the current request +(destination URI or Request URI) points (as IP) to one of the gateways. +There no DNS lookups done if the domain part of the URI is not an IP. + + +This function does not change anything in the message. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +It may take the following optional parameters: + + +- **type** (int, optional) - number for +the GW/destination type to be checked; when omitting this +parameter or specifying the special value *-1*, matching will +be done against all types. +- **flags** (string, optional) - +letter like flags for controlling what operations should be +performed when a GW matches: + + - **'s'** (Strip) - apply +to the username of RURI the strip defined by the GW + - **'p'** (Prefix) - apply +to the username of RURI the prefix defined by the GW + - **'i'** (Gateway ID) - +return the gateway id into gw_id_avp AVP + - **'n'** (Ignore port) - +ignores port number during matching + - **'c'** (Carrier ID) - +return the carrier id into carrier_id_avp AVP +- **gw_attrs_pvar** (var, optional) - +an output writable variable which will be populated with +the attributes of the matched gateway. +- **carrier_attrs_pvar** (var, optional) - an +output writable variable which will be populated with +the attributes of the matched carrier. +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is accepted by this +function. + + +```opensips title="goes_to_gw usage" +... +# use_partitions is not set +if (goes_to_gw( 1, , $var(gw_attrs))) { + sl_send_reply(403,"Forbidden"); + exit; +} +... +# use_partitions is enabledt +if (goes_to_gw(1, , $var(gw_attrs), , "my_partition")) { + sl_send_reply(403,"Forbidden"); + exit; +} +... +``` + + +#### is_from_gw([type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +The function checks if the sender of the message (source IP + source +port) is a gateway from a certain group. + + +This function does not change anything in the message. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and ONREPLY_ROUTE. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +It may take the following optional parameters: + + +- **type** (int, optional) - number for +the GW/destination type to be checked; when omitting this +parameter or specifying the special value *-1*, matching will +be done against all types. +- **flags** (string, optional) - +letter like flags for controlling what operations should be +performed when a GW matches: + + - **'s'** (Strip) - apply +to the username of RURI the strip defined by the GW + - **'p'** (Prefix) - apply +to the username of RURI the prefix defined by the GW + - **'i'** (Gateway ID) - +return the gateway id into gw_id_avp AVP + - **'n'** (Ignore port) - +ignores port number during matching + - **'r'** (Check protocol) - check protocol + - **'c'** (Carrier ID) - +return the carrier id into carrier_id_avp AVP +- **gw_attrs_pvar** (var, optional) - an +output writable variable which will be populated with +the attributes of the matched gateway. +- **carrier_attrs_pvar** (var, optional) - an +output writable variable which will be populated with +the attributes of the matched carrier. +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is accepted by this +function. + + +```opensips title="is_from_gw usage" +# use_partitions is not set +# match the source IP (only) against all gateways +if (is_from_gw(-1, "n")) { + ... +} + +# use_partitions is enabled +# match the source IP and port against all gateways from the "outbound" +# partition and return the matched gateway's carrier +if (is_from_gw(, "c", , , "outbound")) { + ... +} +``` + + +#### dr_is_gw( sip_uri, [type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition]) + + +The function checks if the SIP URI hostname part stored inside the +"src_pv" pseudo-variable is a gateway from a certain group. + + +This function does not change anything in the message. + + +This function can be used from all routes. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +It may take the following optional parameters: + + +- **sip_uri** (string) - SIP URI. +If the URI hostname part is a FQDN, +it will be resolved prior to matching. +- **type** (int, optional) - number for +the GW/destination type to be checked; when omitting this +parameter or specifying the special value *-1*, matching will +be done against all types. +- **flags** (string, optional) - +letter like flags for controlling what operations should be +performed when a GW matches: + + - **'s'** (Strip) - apply +to the username of RURI the strip defined by the GW + - **'p'** (Prefix) - apply +to the username of RURI the prefix defined by the GW + - **'i'** (Gateway ID) - +return the gateway id into gw_id_avp AVP + - **'n'** (Ignore port) - +ignores port number during matching + - **'c'** (Carrier ID) - +return the carrier id into carrier_id_avp AVP +- **gw_attrs_pvar** (var, optional) - an +output writable variable which will be populated with +the attributes of the matched gateway. +- **carrier_attrs_pvar** (var, optional) - an +output writable variable which will be populated with +the attributes of the matched carrier. +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is accepted by this +function. + + +```opensips title="dr_is_gw usage" +# match the SIP URI host within $var(uac) against all gateways +if (dr_is_gw( $var(uac), , "n")) { + ... +} + + +# match the SIP URI host within $var(uac) against +# all gws in "outbound" partition +if (dr_is_gw( $avp(uac), , "n", , , "partition")) { + ... +} +``` + + +#### dr_disable([partition]) + + +Marks as disabled the last destination that was used for the current +call. The disabling done via this function will prevent the +destination to be used for usage from now on. The probing mechanism +can re-enable this peer (see the probing section in the beginning) + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. + + +If you set `use_partitions` parameter to 1 you must +supply the "partition" parameter to instruct on the partition where the +gateway has been defined. + + +It may take the following parameters: + + +- **partition** (string, optional) - +the name of the DR partition to be used. This parameter is +to be defined ONLY if the "use_partition" module parameter +is turned on. Wildcard sign is accepted by this +function. + + +```opensips title="dr_disable() usage" +... +if (t_check_status("(408)|(5[0-9][0-9])")) { + dr_disable(); + +} +... +if (t_check_status("(408)|(5[0-9][0-9])")) { + dr_disable("my_partition"); + +} +... +``` + + +#### dr_match(groupID, [flags], number, [rule_attrs_pvar], [partition]) + + +The function tries to match/check the given number against the +rules from the database. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. + + +If you set `use_partitions` to 1 the +**partition** last parameter becomes +mandatory. + + +The parameters are: + + +- **groupID** (int) - number to +specify the dr group (set of rules) to perform the check against +- **flags** (string, optional) - a list +of letter-like flags for controlling the checking/matching behavior. +Possible flags are: + + - **L** - Do strict length matching +over the prefix - actually DR engine will do full number +matching and not prefix matching anymore. +- **number** (string) - the number to check +- **rule_attrs_pvar** (var, optional) - a +writable variable which will be populated with the attributes of the +matched dynamic routing rule. +- **partition** (string, optional) - the name +of the DR partition to be used. This parameter is to be defined +ONLY if the "use_partition" module parameter is turned on. + + +```opensips title="dr_match usage" +... +if ( dr_match( 1, "L" , $fU, ,"dids") ) + xlog("Full From Username $fU found in group 1 partition DIDS\n"); +... +if ( dr_match( 1, , $var(did) ) ) + xlog("DID $var(did) matches rules in group 1\n"); +... +``` + + +### Exported MI Functions + + +#### dr_reload + + +Command to reload routing rules from database. + + +- if `use_partition` is set to 0 - all routing rules will be reloaded. + * *inherit_state* (optional) : whether inherit old state of the gateway , default is y. +"n": no inherit state +"y": inherit state +- if `use_partition` is set to 1, the parameters are: + * *partition_name* (optional) - if not provided all the partitions will be reloaded, otherwise just the partition given as parameter will be reloaded. + * *inherit_state* (optional) : whether inherit old state of the gateway , default is y. + - "n": no inherit state + - "y": inherit state + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi dr_reload part_1 + +``` + + +#### dr_gw_status + + +Gets the status (enabled or disabled) of one or multiple gateways. The function +can also be used to set the status of a single gateway. + + +- if `use_partitions` is set to 0, the parameters are: + * *gw_id* (optional) - the id of a gateway. If provided, the function will return/set (depending if the second parameter is given) the status of that gateway, otherwise it will list all gateways along with their statuses. + * *status* (optional) - the new status to be forced for a GW (0 - disable, 1 - enable). Only makes sense if *gw_id* is provided. +- if `use_partitions` is set to 1, the parameters are: + * *partition_name* + * *gw_id* (optional) - the id of a gateway. If provided, the function will return/set (depending if the third parameter is given) the status of that gateway, otherwise it will list all gateways in the given partition along with their statuses. + * *status* (optional) - the new status to be forced for a GW (0 - disable, 1 - enable). Only makes sense if *gw_id* is provided. + + +```bash title="dr_gw_status usage when use_partitions is set to 0" +$ opensips-cli -x mi dr_gw_status gw_id=2 +State:: Active +$ opensips-cli -x mi dr_gw_status gw_id=2 status=0 +$ opensips-cli -x mi dr_gw_status gw_id=2 +Enabled:: Disabled MI +$ opensips-cli -x mi dr_gw_status gw_id=3 +Enabled:: Inactive +``` + + +```bash title="dr_gw_status usage when use_partitionsis set to 1" +$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw +State:: Active +$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw status=0 +$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw +enabled:: disabled mi +$ opensips-cli -x mi dr_gw_status partition_name=partition8 status=3 +enabled:: inactive +``` + + +#### dr_carrier_status + + +Gets the status (enabled or disabled) of one or multiple carriers. The function +can also be used to set the status of a single carrier. + + +- if `use_partitions` is set to 0, the parameters are: + * *carrier_id* (optional) - the id of a carrier. If provided, the function will return/set (depending if the second parameter is given) the status of that carrier, otherwise it will list all carriers along with their statuses. + * *status* (optional) - the new status to be forced for a carrier (0 - disable, 1 - enable). Only makes sense if *carrier_id* is provided. +- if `use_partitions` is set to 1, the parameters are: + * *partition_name* + * *carrier_id* (optional) - the id of a carrier. If provided, the function will return/set (depending if the third parameter is given) the status of that carrier, otherwise it will list all carriers contained in the given partition along with their statuses. + * *status* (optional) - the new status to be forced for a carrier (0 - disable, 1 - enable). Only makes sense if *carrier_id* is provided. + + +```bash title="dr_carrier_status usage when use_partitions is 0" +$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 +Enabled:: no +$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 status=1 +$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 +Enabled:: yes +``` + + +```bash title="dr_carrier_status usage when use_partitions is 1" +$ opensips-cli -x mi dr_carrier_status partition_name=my_partition carrier_id=CR1 +Enabled:: no +$ opensips-cli -x mi dr_carrier_status partition_name=partition_1 carrier_id=CR1 status=1 +$ opensips-cli -x mi dr_carrier_status partition_name=partition_3 carrier_id=CR1 +Enabled:: yes +``` + + +#### dr_reload_status + + +Gets the time of the last reload for any partition. + + +- if `use_partition` is set to 0 - the function doesn't receive any parameter. It will list the date of the last reload for the default (and only) partition. +- if `use_partition` is set to 1, the parameters are: + * *partition_name* (optional) - if not provided the function will list the time of the last update for every partition. Otherwise, the function will list the time of the last reload for the given partition. + + +```bash title="dr_reload_status usage when use_partitions is 0" +$ opensips-cli -x mi dr_reload_status +Date:: Tue Aug 12 12:26:00 2014 +``` + + +```bash title="dr_reload_status usage when use_partitions is 1" +$ opensips-cli -x mi dr_reload_status +Partition:: part_test Date=Tue Aug 12 12:24:13 2014 +Partition:: part_2 Date=Tue Aug 12 12:24:13 2014 +$ opensips-cli -x mi dr_reload_status part_test +Partition:: part_test Date=Tue Aug 12 12:24:13 2014 +``` + + +#### dr_number_routing + + +Gets the matched prefix along with the list of the gateways / carriers to which a number +would be routed when using the do_routing function. + + +- if `use_partition` is set to 1 the function will have 3 parameters: + * *partition_name* + * *group_id* (optional) - the group id of the rules to check against + * *number* - the number to test against +- if `use_partition` is set to 0 the function will have 2 parameters: + * *group_id* (optional) - the group id of the rules to check against + * *number* - the number to test against + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi dr_number_routing partition_name=part1 group_id=3 number=012340987 + +``` + + +#### dr_enable_probing + + +Enables/disables gateway probing or returns the current gateway +probing status. + + +Parameters: + + +- *status* (optional) - 1 - enable, 0 - disable gateway probing + + +```bash title="dr_enable_probing usage" +$ opensips-cli -x mi dr_enable_probing +Status:: 1 +$ opensips-cli -x mi dr_enable_probing 0 +$ opensips-cli -x mi dr_enable_probing +Status:: 0 + +``` + + +### Exported Events + + +#### E_DROUTING_STATUS + + +This event is raised when the module changes the state of a gateway, +either through an MI command, probing or script function. + + +Parameters: + + +- *partition* - the name of the partition. +- *gwid* - the gateway identifier. +- *address* - the address of the gateway. +- *status* - *disabled MI* if +the gateway was disabled using MI commands, +*probing* if the gateway is being pinged, +*inactive* if it was disabled from the script or +*active* if the gateway is enabled. + + +### Exported Status/Report Identifiers + + +The module provides the "drouting" Status/Report group, where each +routing partition is defined as a separate SR identifier. + + +#### [partition_name] + + +The status of these identifiers reflects the readiness/status of the +cached data (if available or not when being loaded from DB): + + +- *-2* - no data at all (initial status) +- *-1* - no data, initial loading in progress +- *1* - data loaded, partition ready +- *2* - data available, a reload in progress + + +Reload reporting: + + +In terms of data reloading, the following logs will be reported: + + +- starting DB data loading +- DB data loading failed, discarding +- DB data loading successfully completed +- N gateways loaded (N discarded), N carriers loaded (N discarded), N rules loaded (N discarded) + + +```json +{ + "Name": "Default", + "Reports": [ + { + "Timestamp": 1652353940, + "Date": "Thu May 12 14:12:20 2022", + "Log": "starting DB data loading" + }, + { + "Timestamp": 1652353940, + "Date": "Thu May 12 14:12:20 2022", + "Log": "DB data loading successfully completed" + }, + { + "Timestamp": 1652353940, + "Date": "Thu May 12 14:12:20 2022", + "Log": "2 gateways loaded (0 discarded), 2 carriers loaded (0 discarded), 1 rules loaded (0 discarded)" + } + ] +} + +``` + + +#### [partition_name];events + + +GW/Carrier switching reporting: + + +For reporting events related to the state changes of the +gateways and carriers, the module provides separate identifiers (still +one per partition). +Why separate ones? The reports on state changing may be verbose and there +is the risk of loose/discard important reports on reloads due to the high +number of logs on state changes; + + +So, each partition will provide the identified "partition_name;events" for +reporting state changes of gateways and carriers, along with the reason +of the change. This identifiers have a 200 records history before +discarding the old ones. + + +```json +{ + "Name": "Default;events", + "Reports": [ + { + "Timestamp": 1652353976, + "Date": "Thu May 12 14:12:56 2022", + "Log": "GW /127.0.1.1 switched to [inactive] due probing reply\n" + }, + { + "Timestamp": 1652353976, + "Date": "Thu May 12 14:12:56 2022", + "Log": "GW /127.0.1.2 switched to [inactive] due probing reply\n" + } + ] +} + +``` + + +For how to access and use the Status/Report information, please see +[https://docs.opensips.org/manual/3-6/interface-statusreport/](>https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +### Installation + + +The module requires 4 tables in the OpenSIPS database: dr_groups, +dr_gateways, dr_carriers, dr_rules. The SQL syntax to create them can be +found in the drouting-create.sql script, located in the database directories +of the opensips/scripts folder. You can also find the complete +database documentation on the project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +## Developer Guide + + +The module provides no function to be used +by other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/drouting/doc/contributors.xml b/modules/drouting/doc/contributors.xml deleted file mode 100644 index ecb8cb46471..00000000000 --- a/modules/drouting/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 416 - 202 - 13810 - 5824 - - - 2. - Liviu Chircu (@liviuchircu) - 163 - 97 - 2515 - 2613 - - - 3. - Razvan Crainea (@razvancrainea) - 100 - 53 - 1171 - 2226 - - - 4. - Mihai Tiganus (@tallicamike) - 73 - 20 - 4301 - 910 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 43 - 20 - 1100 - 735 - - - 6. - Vlad Paiu (@vladpaiu) - 28 - 22 - 421 - 65 - - - 7. - Andrei Datcu (@andrei-datcu) - 20 - 12 - 551 - 134 - - - 8. - Ovidiu Sas (@ovidiusas) - 15 - 11 - 132 - 70 - - - 9. - Ionut Ionita (@ionutrazvanionita) - 15 - 9 - 370 - 108 - - - 10. - Maksym Sobolyev (@sobomax) - 10 - 8 - 30 - 29 - - - -
-All remaining contributors: Andrei Dragus, Anca Vamanu, Nick Altmann (@nikbyte), Jeremy Martinez (@JeremyMartinez51), wangdd, nexbridge, Dusan Klinec (@ph4r05), Walter Doekes (@wdoekes), MayamaTakeshi, Matt Lehner, Julián Moreno Patiño, Sergio Gutierrez, Le Roy Christophe, Peter Lemenkov (@lemenkov), Alexey Vasilyev (@vasilevalex), Ozzyboshi, Aron Podrigal (@ar45). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2008 - Nov 2024 - - - 2. - Vlad Paiu (@vladpaiu) - Aug 2011 - Feb 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2020 - Nov 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Sep 2010 - Oct 2023 - - - 5. - wangdd - May 2023 - May 2023 - - - 6. - MayamaTakeshi - Apr 2023 - Apr 2023 - - - 7. - nexbridge - Feb 2023 - Mar 2023 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - Mar 2017 - Jul 2022 - - - 9. - Nick Altmann (@nikbyte) - Mar 2013 - May 2021 - - - 10. - Walter Doekes (@wdoekes) - May 2014 - Apr 2021 - - - -
-All remaining contributors: Liviu Chircu (@liviuchircu), Aron Podrigal (@ar45), Alexey Vasilyev (@vasilevalex), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Jeremy Martinez (@JeremyMartinez51), Le Roy Christophe, Ionut Ionita (@ionutrazvanionita), Ozzyboshi, Julián Moreno Patiño, Dusan Klinec (@ph4r05), Mihai Tiganus (@tallicamike), Andrei Datcu (@andrei-datcu), Matt Lehner, Anca Vamanu, Andrei Dragus, Sergio Gutierrez. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Paiu (@vladpaiu), Razvan Crainea (@razvancrainea), wangdd, Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Nick Altmann (@nikbyte), Alexey Vasilyev (@vasilevalex), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Mihai Tiganus (@tallicamike), Andrei Datcu (@andrei-datcu), Matt Lehner, Anca Vamanu, Andrei Dragus, Sergio Gutierrez. -
- -
diff --git a/modules/drouting/doc/drouting.xml b/modules/drouting/doc/drouting.xml deleted file mode 100644 index 400775c9df3..00000000000 --- a/modules/drouting/doc/drouting.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - Dynamic Routing Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2009-2012 &osipssol; - ©right; 2005-2008 &voicesystem; - - - diff --git a/modules/drouting/doc/drouting_admin.xml b/modules/drouting/doc/drouting_admin.xml deleted file mode 100644 index a6baf3e48cb..00000000000 --- a/modules/drouting/doc/drouting_admin.xml +++ /dev/null @@ -1,2802 +0,0 @@ - - - - &adminguide; - -
- Overview -
- Introduction - - Dynamic Routing is a module for selecting (based on multiple - criteria) the best gateway/destination to be used for delivering a - certain call. Least Cost Routing (LCR) is a special case of dynamic - routing - when the rules are ordered based on costs. Dynamic Routing - comes with many features regarding routing rule selection: - - - prefix based - caller/group based - time based - priority based - - - , processing : - - - stripping and prefixing - default rules - inbound and outbound processing - script route triggering - - - and failure handling: - - serial forking - weight based GW selection - random GW selection - GW probing for crashes - - - -
- -
- Features - - The dynamic routing implementation for &osips; is designed with the - following properties: - - - - - The routing info (destinations, carriers, rules, groups) is stored in a - database and loaded into memory at start up time; reload at runtime via - a Management Interface command. - - - - - - weight-based or random selection of the destinations (from a rule or - from a carrier), failure detection of gateways (with switching to next - available gateway). - - - - - - able to handle large volume of routing info (10M of rules) with minimal - speed/time and memory consumption penalties - - - - - - script integration - Pseudo-variable support in functions; scripting - route triggering when rules are matched - - - - - - bidirectional behavior - inbound and outbound processing (strip and - prefixing when sending and receiving from a destination/GW) - - - - - - blacklisting - the module allows definition of blacklists based on the - destination IPs. This blacklists are to be used to prevent malicious - forwarding to GWs (based on DNS lookups) when the script logic does - none-GE forwarding (like foreign domains). - - - - - - loading routing information from multiple databases - the gateways, rules, groups and - carriers can be grouped by partitions, and each partition may be loaded - from different databases/tables. This makes the routing process partition - based. In order to be able to use a table from a partition, its name must - be found in the "version" table belonging to the database defined in the - partition's db_url. - - - - -
- - -
- Performance - - There were several tests performed regarding the performance of the module - when dealing with a large number of routing rules. - - - The tests were performed with a set of 383000 rules and measured: - - - time to load from DB - used shared memory - - - The time to load was varying between 4 seconds and 8 seconds, depending of - the caching of the DB client - the first load was the slowest (as the DB - query hits the disk drive); the following are faster as data is already - cached in the DB client. So technically speaking, the time to load (without - the time to query which is DB type dependent) is ~4 seconds - - - After loading the data into shared memory ~ 96M of memory were used - exclusively for the DR data. - -
- - -
- Dynamic Routing Concepts - - DR engine uses several concepts in order to define how the routing - should be done (describing all the dependencies between destinations - and routing rules). - - -
- Destination/Gateways - - These are the end SIP entities where actually the traffic needs to be sent - after routing. They are stored in a table called dr_gateways. - Gateway addresses are stored in a separate table because of the need to access them - independent of Dynamic Routing processing (e.g., adding/ removing gateway PRI - prefix before/after performing other operation -- receiving/relaying to gateway). - - - In DR, a gateway is defined by: - - - id (string) - SIP address (SIP URI) - type (integer which allows GWs to be grouped by purpose, - e.g. inbound, outbound, etc.) - strip value (number of digits) from dialled - number - prefix (string) to be added to dialled - number - attributes (not used by DR engine, but only pushed - to script level when routing to this GW) - probing mode (how the GW should be probed at SIP level - - see the probing chapter) - - - The Gateways are to be used from the routing rule or from the carrier - definition. They are all the time referred by their ID. - -
- -
- Carriers - - The carrier concept is used if you need to group gateways in order to - have a better control on how the GWs will be used by DR rules; like - in what order the GWs will be used. - - - Basically, a carrier is a set of gateways which have its own sorting - algorithm and its own attribute string. They are by default defined - in the dr_carriers table. - - - In DR, a carrier is defined by: - - - id (string) - list of gateways with/without weights (string) - (Ex:gw1=10,gw4=10 or gw1,gw2 - - flags : 0x1 - use only the first gateway from the carrier - (depending on the sorting); 0x2 - disable the usage of this - carrier - sort algorithm : how the list of the gateways should be - sorted before being used, NULL - use the DB given order, W - do weight - based re-ordering, Q - do quality based sorting (requires the qrouting - module) - attributes (not used by DR engine, but only pushed - to script level when routing to this carrier) - - - The Carriers are to be used only from the routing rule definition. - They are all the time referred by their ID. - -
- -
- Routing Rules - - These are the actual rules which control the routing. Using - different criterias (prefix, time, priority, etc), they will decide - to which gateways the call will be sent. - - - Default name for the table storing rule definitions is - dr_rules. - - - In DR, a routing rule is defined by: - - - group (list of numbers) - rules can be grouped (a rule may - belong to multiple groups in the same time ) and you can - use only a certain group at a point; like having a premium or - standard or interstate or - intrastate groups of rules to be used in different - cases - prefix (string with digits only) - prefix to be used for - matching this rule (longest prefix matching) - time validity (time recurrence string) - when this rule is - valid from time point of view (see RFC 2445) - priority (number) - priority of the rule - higher value, - higher priority (see rule section alg) - script route ID (string) - if defined, then execute the - route with the specified ID when this rule is matched. That's it, a route - which can be used to perform custom operations on message. NOTE that no - modification is performed at signaling level and you must NOT do - any signaling operations in that script route - list of GWs/carriers (string) - a comma separated list - of gateways or carriers (defined by IDs) to be used for this rule; the - carrier IDs are prefixed with # sign. For each ID (GW or - carrier) you may specify a weight. For how this list will be interpreted - (as order) see the rule selection section. Example of list: - gw1,gw4,#cr3 or gw1=10,gw4=10,#cr3=80 - - attributes (not used by DR engine, but only pushed - to script level when this rule matched and been used) - - - - More on time recurrence: - - - - A date-time expression that defines the time recurrence to be matched for - current rule. Time recurrences are based closely on the recurring time - intervals from the Internet Calendaring and Scheduling Core Object - Specification (calendar COS), RFC 2445. The set of attributes used in - a routing rule specification is a subset of time recurrence attributes. - - - The value stored in database has the basic format of: - ||||||||||| - ]]> - , identical to the input of the check_time_rec() - function of the cfgutils module, including the optional - use of logical operators linking multiple such strings into a larger expression. - - - When an attribute is not specified, the corresponding place must be left - empty, whenever another attribute that follows in the list has to be - specified. - - -
-
- - -
- Routing Rule Processing - - The module can be used to find out which is the best gateway to use for new - calls terminated to PSTN. The algorithm to select the rule is as follows: - - - - the module discovers the routing group of the originating user. This - step is skipped if a routing group is passed from the script as parameter. - - - - - once the group is known, in the subset of the rules for this group the - module looks for the one that matches the destination based on "prefix" - column. The set of rules with the longest prefix is chosen. If no digit - from the prefix matches, the default rules are used (rules with no prefix) - - - - - within the set of rules is applied the time criteria, and the rule which - has the highest priority and matches the time criteria is selected to drive - the routing. - - - - - Once found the rule, it may contain a route ID to execute. If a certain - flag is set, then the processing is stopped after executing the route - block. - - - - - The rule must contain a chain of gateways and carriers. The module will - execute serial forking for each address in the chain (ordering is either done - by simply using the definition order or it may weight-based - weight selection must be - enabled). The next address in chain is used only if the previously has failed. - - - - - With the right gateway address found, the prefix (PRI) of the gateway is - added to the request URI and then the request is forwarded. - - - - - - If no rule is found to match the selection criteria an default action must - be taken (e.g., error response sent back). If the gateway in the chain has - no prefix the request is forwarded without adding any prefix to the request - URI. - -
- - -
- Probing and Disabling destinations - - The module has the capability to monitor the status of the destinations by - doing SIP probing (sending SIP requests like OPTIONS). - - - For each destination, you can configure what kind of probing should be - done (probe_mode column): - - - - (0) - no probing at all; - - - (1) - probing only when the destination is - in disabled mode (disabling via MI command will completely stop the - probing also). The destination will be automatically re-enabled - when the probing will succeed next time; - - - (2) - probing all the time. If disabled, - the destination will be automatically re-enabled when the probing - will succeed next time; - - - - - A destination can become disabled in two ways: - - - script detection - by calling from script the - dr_disable() function after trying the destination. In this case, if - probing mode for the destination is (1) or (2), the destination will - be automatically re-enabled when the probing will succeed. - - - MI command - by calling the dr_gw_status MI - command for disabling (on demand) the destination. If so, the probing - and re-enabling of this destination will be completly disabled until - you re-enable it again via MI command - this is designed to allow - controlled and complete disabling of some destination during - maintenance. - - - -
- -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - - a database module. - - - - - - - - tm module. - - - - - - clusterer - only if "cluster_id" - option is enabled. - - - - - -
- -
- External Libraries or Applications - - - - none. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname>(str) - - The database url. - - - Default value is NULL. - - - - Set <varname>db_url</varname> parameter - -... -modparam("drouting", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
-
- <varname>drd_table</varname>(str) - - The name of the db table storing gateway addresses. - - - Default value is dr_gateways. - - - - Set <varname>drd_table</varname> parameter - -... -modparam("drouting", "drd_table", "dr_gateways") -... - - -
-
- <varname>drr_table</varname>(str) - - The name of the db table storing routing rules. - - - Default value is dr_rules. - - - - Set <varname>drr_table</varname> parameter - -... -modparam("drouting", "drr_table", "rules") -... - - -
- -
- <varname>drg_table</varname>(str) - - The name of the db table storing groups. - - - Default value is dr_groups. - - - - Set <varname>drg_table</varname> parameter - -... -modparam("drouting", "drg_table", "groups") -... - - -
- -
- <varname>drc_table</varname>(str) - - The name of the db table storing definitions of the carriers that will - be used directly by the routing rules. - - - Default value is dr_carriers. - - - - Set <varname>drc_table</varname> parameter - -... -modparam("drouting", "drc_table", "my_dr_carriers") -... - - -
- -
- <varname>ruri_avp</varname> (str) - - The name of the avp for storing Request URIs to be later used - (alternative destiantions for the current one). - - - Default value is $avp(___dr_ruri__) if use_partitions parameter is 0 - or $avp(___dr_ruri__partition_name) where partition_name is the name of the partition - containing the AVP (as fetched from the database) if use_partitions parameter is 1. - - - - Set <varname>ruri_avp</varname> parameter - -... -modparam("drouting", "ruri_avp", '$avp(dr_ruri)') -modparam("drouting", "ruri_avp", '$avp(33)') -... - - -
- - -
- <varname>gw_id_avp</varname> (str) - - The name of the avp for storing the id of the current selected - gateway/destination - once a new destination is selected (via the - use_next_gw() function), the AVP will be updated with the ID of the - new selected gateway/destination. - - - Default value is $avp(___dr_gw_id__) if use_partitions parameter is 0 - or $avp(___dr_gw_id__partition_name) where partition_name is the name of the partition - containing the AVP (as fetched from the database) if use_partitions parameter is 1. - - - - Set <varname>gw_id_avp</varname> parameter - -... -modparam("drouting", "gw_id_avp", '$avp(gw_id)') -modparam("drouting", "gw_id_avp", '$avp(334)') -... - - -
- -
- <varname>gw_priprefix_avp</varname> (str) - - The name of the avp for storing the PRI prefix of the current selected - destination/gateway - once a new destination is selected (via the - use_next_gw() function), the AVP will be updated with the PRI prefix of the - new used destination. - - - Default value is NULL. - - - - Set <varname>gw_priprefix_avp</varname> parameter - -... -modparam("drouting", "gw_priprefix_avp", '$avp(gw_priprefix)') -... - - -
- - -
- <varname>rule_id_avp</varname> (str) - - The name of the avp for storing the id of the current matched - routing rule (see dr_rules table). - - - Default value is NULL. - - - - Set <varname>rule_id_avp</varname> parameter - -... -modparam("drouting", "rule_id_avp", '$avp(rule_id)') -modparam("drouting", "rule_id_avp", '$avp(335)') -... - - -
- -
- <varname>rule_prefix_avp</varname> (str) - - The actual prefix that matched the routing rule (the part from RURI - username that matched the routing rule). - - - Default value is NULL. - - - - Set <varname>rule_prefix_avp</varname> parameter - -... -modparam("drouting", "rule_prefix_avp", '$avp(dr_prefix)') -... - - -
- - -
- <varname>carrier_id_avp</varname> (str) - - AVP to be populate with the ID string for the carrier the - current GW belongs to. - - - Default value is NULL. - - - - Set <varname>carrier_id_avp</varname> parameter - -... -modparam("drouting", "carrier_id_avp", '$avp(carrier_id)') -... - - -
- - -
- <varname>gw_sock_avp</varname> (str) - - The name of the avp for storing sockets for alternative destinations - defined by ruri_avp. - - - Default value is $avp(___dr_sock__) if use_partitions parameter is 0 - or $avp(___dr_sock__partition_name) where partition_name is the name of the partition - containing the AVP (as fetched from the database) if use_partitions parameter is 1. - - - - Set <varname>gw_sock_avp</varname> parameter - -... -modparam("drouting", "gw_sock_avp", '$avp(dr_sock)') -modparam("drouting", "gw_sock_avp", '$avp(77)') -... - - -
- -
- <varname>define_blacklist</varname> (str) - - Defines a blacklist based on a list of GW types - the blacklist will - be populated with the IPs (no port, all protocols) of the GWs having - the specified types. - - - If partitions are used, prefix the blacklist definition string with - the name of the partition followed by ":" separator. - - - Multiple instances of this param are allowed. - - - Default value is NULL. - - - - Set <varname>define_blacklist</varname> parameter - -... -modparam("drouting", "define_blacklist", 'bl_name= 3,5,25,23') -modparam("drouting", "define_blacklist", 'list= 4,2') -modparam("drouting", "define_blacklist", 'pstn:list2 = 5,6') -modparam("drouting", "define_blacklist", 'pstn:list3 = 7,8') -... - - -
- -
- <varname>default_group</varname> (int) - - Group to be used if the caller (FROM user) is not found in the GROUP - table. - - - Default value is NONE. - - - - Set <varname>default_group</varname> parameter - -... -modparam("drouting", "default_group", 4) -... - - -
- -
- <varname>force_dns</varname> (int) - - Force DNS resolving of GW/destination names (if not IPs) during - startup. If not enabled, the GW name will be blindly used during - routing. - - - Default value is 1 (enabled). - - - - Set <varname>force_dns</varname> parameter - -... -modparam("drouting", "force_dns", 0) -... - - -
- -
- <varname>persistent_state</varname> (int) - - Specifies whether the state column - should be loaded at startup and flushed during runtime or not. - - - Default value is 1 (enabled). - - - - Set the <varname>persistent_state</varname> parameter - -... -# disable all DB operations with the state of a gateway -modparam("drouting", "persistent_state", 0) -... - - -
- -
- <varname>no_concurrent_reload</varname> (int) - - If enabled, the module will not allow do run multiple dr_reload - MI commands in parallel (with overlapping) Any new reload will - be rejected (and discarded) while an existing reload is in - progress. - - - If you have a large routing set (millions of rules/prefixes), you - should consider disabling concurrent reload as they will exhaust - the shared memory (by reloading into memory, in the same time, - multiple instances of routing data). - - - Default value is 0 (disabled). - - - - Set <varname>no_concurrent_reload</varname> parameter - -... -# do not allow parallel reload operations -modparam("drouting", "no_concurrent_reload", 1) -... - - -
- -
- <varname>probing_interval</varname> (integer) - - How often (in seconds) the probing of a destination should be done. If - set to 0, the probing will be disabled as functionality (for all - destinations) - - - - Default value is 30. - - - - Set <varname>probing_interval</varname> parameter - -... -modparam("drouting", "probing_interval", 60) -... - - -
- -
- <varname>probing_method</varname> (string) - - The SIP method to be used for the probing requests. - - - - Default value is "OPTIONS". - - - - Set <varname>probing_method</varname> parameter - -... -modparam("drouting", "probing_method", "INFO") -... - - -
- -
- <varname>probing_from</varname> (string) - - The FROM SIP URI to be advertised in the SIP probing requests. - - - - Default value is "sip:prober@localhost". - - - - Set <varname>probing_from</varname> parameter - -... -modparam("drouting", "probing_from", "sip:pinger@192.168.2.10") -... - - -
- -
- <varname>probing_reply_codes</varname> (string) - - A comma separted list of SIP reply codes. The codes defined here - will be considered as valid reply codes for probing messages, - apart for 200. - - - - Default value is NULL. - - - - Set <varname>probing_reply_codes</varname> parameter - -... -modparam("drouting", "probing_reply_codes", "501, 403") -... - - -
- -
- <varname>probing_socket</varname> (string) - - A socket description [proto:]host[:port] of the local socket - (which is used by OpenSIPS for SIP traffic) to be used - (if multiple) for sending the probing messages from. - - - For probing gateway the highest priority has socket from gateway - configuration in dr_gateways table. Then socket from global - probing_socket parameter and the lowest - priority is default behaviour with auto selected socket wich - OpenSIPS listens on. - - - - Default value is NULL. - - - - Set <varname>probing_socket</varname> parameter - -... -modparam("drouting", "probing_socket", "udp:192.168.1.100:5060") -... - - -
- -
- <varname>gw_socket_filter_mode</varname> (string) - - This parameter controls the gateway filtering during DB loading, or which - gateways are loaded or not into memory depending on the configured - socket they have. - - - The supported filtering modes are: - - - - - "all" - all the gateways - defined in DB are loaded into memory, disregarding what socket - value they have. NOTE: for the gw sockets not matching any OpenSIPS - listeners/sockets, the GW will be loaded with NULL/no socket. - - - - - "ignore" - all the gateways - defined in DB are loaded into memory, but ignoring the socket - value they have (the socket will be set to NULL/NONE with no - attempt to check it against the OpenSIPS listeners/sockets). - - - - - "matched-only" - in this mode - the module will load from DB only the gateways that have a - configured a socket matching any of the the OpenSIPS - listeners/sockets. If the gateways socket does not match, it will - be discards, not loaded into memory at all. - - - - - - Default value is "all". - - - - Set <varname>gw_socket_filter_mode</varname> parameter - -... -# multiple OpenSIPS instances sharing a DR setting, so each should -# load only the GWs they have sockets for. -modparam("drouting", "gw_socket_filter_mode", "matched-only") -... -# an OpenSIPs instance not doing routing, but needing to be -# aware of all the gws, so load them all ignoring the sockets -modparam("drouting", "gw_socket_filter_mode", "ignore") -... - - -
- - -
- <varname>cluster_id</varname> (integer) - - The ID of the cluster the module is part of. The clustering support is - used in drouting module for two purposes: for sharing the status of - the gateways/carriers and for controlling the pinging to gateways. - - - If clustering enbled, the module will automatically share changes - over the status of the gateways/destinations/carriers with the other - OpenSIPS instances that are part of a cluster. Whenever such a status - changes (following an MI command, a probing result, a script command), - the module will replicate this status change to all the nodes in this - given cluster. - - - The clustering with sharing tag support may be used to control which - node in the cluster will perform the pinging/probing to - gateways. See the - option. - - - &clusterer_sync_cap_para; - - - For more info on how to define and populate a cluster (with OpenSIPS - nodes) see the clusterer module. - - - - Default value is 0 (none). - - - - Set <varname>cluster_id</varname> parameter - -... -# replicate gw/carrier status with all OpenSIPS in cluster ID 9 -modparam("drouting", "cluster_id", 9) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (string) - - The name of the sharing tag (as defined per clusterer modules) to - control which node is responsible for perform the self-triggered - actions in the module. Such actions may be the gateway probing (see - also the parameter) or - sharing the gateway/carrier status changes. - If defined, only the node with active status of this tag will - perform the actions (pinging and sharing status). - - - The must be defined for this option - to work. - - - This is an optional parameter. If not set, all the nodes in the cluster - will share the status changes. - - - - Default value is empty (none). - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_sharing_tag", "vip") -... - - -
- -
- <varname>cluster_probing_mode</varname> (string) - - This paramter controls how the probing/pinging should be done when - using the clustering support. It is about which node in the cluster - pings which gateway/destination. - - - The must be defined for this option - to work. - - - The supported probing modes are: - - - - - "all" - all the nodes in the - cluster will independetly ping all the defined gateways, - an "all" pings "all" mode. - - - - - "by-shtag" - all the gateways - are pinged by only one node in the cluster, the node having the - active. By - activating the sharing tag on a different node, the pinging - duty will be transfered to another node in the cluster. - - - - - "distributed" - the pinging - effort is distributed across all the nodes in the cluster, so each - node will ping a sub-set of the overall set of gateway. Still all - the gateways will get pinged (and only once per pinging cycle). - The re-partitioning of the pinging effort over the available nodes - in the cluster is automatically done when new nodes are joining or - nodes are dropping out. Still there is no guaratee on which node - will be responsible for pinging which gateway. - - - - - - Default value is "all". - - - - Set <varname>cluster_probing_mode</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_sharing_tag", "vip") -modparam("drouting", "cluster_probing_mode", "by-shtag") -... -# the pinging effort is distributed across all the nodes -modparam("drouting", "cluster_id", 9) -modparam("drouting", "cluster_probing_mode", "distributed") -... - - -
- - -
- <varname>use_domain</varname> (int) - - Flag to configure whether to use domain match when querying - database for user's routing group. - - - Default value is 1. - - - - Set <varname>use_domain</varname> parameter - -... -modparam("drouting", "use_domain", 0) -... - - -
- -
- <varname>drg_user_col</varname> (str) - - The name of the column in group db table where the username is stored. - - - Default value is username. - - - - Set <varname>drg_user_col</varname> parameter - -... -modparam("drouting", "drg_user_col", "user") -... - - -
- -
- <varname>drg_domain_col</varname> (str) - - The name of the column in group db table where the domain is stored. - - - Default value is domain. - - - - Set <varname>drg_domain_col</varname> parameter - -... -modparam("drouting", "drg_domain_col", "host") -... - - -
- -
- <varname>drg_grpid_col</varname> (str) - - The name of the column in group db table where the - group id is stored. - - - Default value is groupid. - - - - Set <varname>drg_grpid_col</varname> parameter - -... -modparam("drouting", "drg_grpid_col", "grpid") -... - - -
- - -
- <varname>use_partitions</varname> (int) - - Flag to configure whether to use partitions for routing. If this - flag is set then the db_partitions_url and - db_partitions_table - variables become mandatory. - - - Default value is 0. - - - - Set <varname>use_partitions</varname> parameter - -... -modparam("drouting", "use_partitions", 1) -... - - -
- -
- <varname>db_partitions_url</varname> (str) - - The url to the database containing partition-specific - information. (partition-specific information includes - partition name, url to the database where information about - the partition is preserved, the names of the tables in which it - is preserved and the AVPs that can be accessed using the .cfg - script). The use_partitions parameter - must be set to 1. - - - Default value is "NULL". - - - - Set <varname>db_partitions_url</varname> parameter - -... -modparam("drouting", "db_partitions_url", "mysql://user:password@localhost/opensips_partitions") -... - - -
- -
- <varname>db_partitions_table</varname> (str) - - The name of the table containing partition definitions. To be - used with use_partitions and db_partitions_url. - - - Default value is dr_partitions. - - - - Set <varname>db_partitions_table</varname> parameter - -... -modparam("drouting", "db_partitions_table", "partition_defs") -... - - -
- -
- <varname>partition_id_pvar</varname> (pvar) - - Variable which will store the name of the name partition when - wildcard(*) operatior is used. - Use_partitions must be set in order to - use this parameter. - - - NOTE: The variable must be WRITABLE! - - - Default value is null(not used). - - - - Set <varname>partition_id_pvar</varname> parameter - -... -modparam("drouting", "partition_id_pvar", "$var(matched_partition)") -... - - -
- -
- <varname>enable_restart_persistency</varname> (int) - - Parameter set to enable restart persistency for the Dynamic Routing module. - When this parameter is set, the drouting module no longer loads the data - from the database after restart, but uses the persistent storage file, and loads - data from it on demand, improving the startup performance. - - - NOTE: If the restart persistent cache is not populated from a previous run, - then the data will be loaded from database at startup! - - - NOTE: A reload will update the cached data. - - - Default value is 0 (disabled). - - - - Set <varname>enable_restart_persistency</varname> parameter - -... -modparam("drouting", "enable_restart_persistency", yes) -... - - -
- -
- <varname>extra_prefix_chars</varname> (str) - - List of ASCII (0-127) characters to be additionally accepted in - the prefixes. By default only '0' - '9' chars (digits) are - accepted. - - - Default value is NULL. - - - - Set <varname>extra_prefix_chars</varname> parameter - -... -modparam("drouting", "extra_prefix_chars", "#-%") -... - - -
- -
- <varname>extra_id_chars</varname> (str) - - A set of extra characters to be allowed in both Gateway and Carrier - unique string identifiers, on top of alphanumeric characters. - - - Default value is _-.. - - - - Set <varname>extra_id_chars</varname> parameter - -... -modparam("drouting", "extra_id_chars", ":_-.") -... - - -
- -
- <varname>rule_tables_query</varname> (str) - - This parameter offers a dynamic, SQL-based way of building a set of - dr_rules-compatible table names, to be - each loaded and then merged into a single "dr_rules" table, - for any given partition. - - - The syntax of the parameter is: - "token : query", - where token is a special name - given to a "dr_rules" table, so OpenSIPS can match it against - the custom queries defined using this parameter. - - - This parameter may be set multiple times (each definition creates - a new mapping). - - - Set the <varname>rule_tables_query</varname> parameter - -... -# first, set the "dr_rules" table name to the name of your query -modparam("drouting", "drr_table", "MY_RULES_QUERY") - -# next, instruct drouting to load both 'dr_rules_a' and 'dr_rules_b', -# then merge all of their rules -modparam("drouting", "rule_tables_query", " - MY_RULES_QUERY: - SELECT 'dr_rules_a' UNION SELECT 'dr_rules_b'") -... - - -
- -
- <varname>generate_data_checksum</varname> (int) - - If enabled, it will generate a checksum ( MD5 ) for drouting loaded data, attach that to the reload_status MI command output and to the reload generated status reports - - - Set the <varname>generate_data_checksum</varname> parameter - -... -modparam("drouting", "generate_data_checksum", 1) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">do_routing([groupID], [flags], [gw_whitelist], [rule_attrs_pvar], [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - Function to trigger routing of the message according to the - rules in the database table and the configured parameters. - - - This function can be used from all routes. - - - If you set use_partitions to 1 the - partition last parameter becomes - mandatory. - - - All parameters are optional. Any of them may be ignored, provided - the necessary separation marks "," are properly placed. - - - - - groupID (int, optional) - number to - specify the group of the caller for routing purposes. - If none specified the function will automatically try to query - the dr_group table to get this - - - - - flags (string, optional) - a list - of letter-like flags for controlling the routing behavior. - Possible flags are: - - - - - F - Enable rule fallback; - normally the engine is using a single rule for routing a call; - by setting this flag, the engine will fallback and use - rules with less priority or shorter prefix when all the - destination from the current rules failed. - - - - - L - Do strict length matching - over the prefix - actually DR engine will do full number - matching and not prefix matching anymore. - - - - - C - Only check if the dialed - number matches any routing rule, without loading / applying any - routing info (no GW is set, the RURI is not altered) - - - - - - - gw_whitelist (string, optional) - a - comma separated white list of gateways. This will force routing over, - at most, this list of carriers or gateways (in other words, - the whitelist will be intersected with the results of the search - through the rules). - - - - - rule_attrs_pvar (var, optional) - a - writable variable which will be populated with the attributes of the - matched dynamic routing rule. - - - - - gw_attrs_pvar (var, optional) - a - writable variable which will be - populated with the attributes of the matched gateway. - - - - - carrier_attrs_pvar (var, optional) - a - a writable variable which will be - populated with the attributes of the matched carrier. - - - - - partition (string, optional) - the name - of the DR partition to be used. This parameter is to be defined - ONLY if the "use_partition" module parameter is turned on. - Besides specifing the name of one partition, you can use the "*" - wildcard sign to force routing over all partitions. - - - - - - - <function>do_routing</function> usage - -... -# all groups, sort on order, use_partitions is 0 -do_routing(); -... -# all groups, sort on order, use_partitions is 1, route by partition named "part" -do_routing( , , , , , ,"part"); -... -# group id 0, sort on order, use_partitions is 0 -do_routing(0); -... -# group id 0, sort on order, use_partitions is 1, route by partition named "part" -do_routing(0, , , , , , "part"); -... -# group id from $var(id), sort on order, use_partitions is 0 -do_routing($var(id)); -... -# all groups, sort on weights, use_partitions is 0 -do_routing(, "W"); -... -# use_partitions is 1, partition and group supplied by AVPs, do strict length matching -do_routing( $avp(grp),"L", , , , ,$avp(partition)) -... -# group id 2, sort on order, fallback rule and also return the gateway attributes -do_routing(2, "F", , , $var(gw_attributes)); -... - - -
- -
- - <function moreinfo="none">route_to_carrier( carriers, [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - Function to trigger the direct routing to a given set carriers (one - or more). So, the routing is not done prefix based, but carrier based - (call will be sent to the GWs of that carrier, based on carrier - policy). - - - This function can be used from all routes. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter also (where the carrier are to be - found). - - - - - - carriers (string) - comma separated - carrier IDs (names) - - - - - gw_attrs_pvar (var, optional) - - an output writable variable which will be populated - with the attributes of the currently matched gateway of - this carrier. - - - - - carrier_attrs_pvar (var, - optional) - an output writable variable which will be populated - with the attributes of this carrier. - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is not accepted by the - function. - - - - - - - <function>route_to_carrier</function> usage - -... -# use_partitions is not set -if ( route_to_carrier("my_top_carrier, def_carrier", , $var(carrier_att)) ) { - xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_carrier("my_top_carrier", , $var(carrier_att), "part") ) { - xlog("Routing to \"my_top_carrier\" - $var(carrier_att)\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_carrier($var(carrierId), , , $var(my_partition)) ) { - xlog("Routing to \"my_top_carrier\"\n"); - t_on_failure("next_gw"); - t_relay(); - exit; -} -... - - -
- -
- - <function moreinfo="none">route_to_gw(gw_id, [gw_attrs_var], [carrier_attrs_var], [partition])</function> - - - Function to trigger the direct routing to a given gateway (or list of - gateways). Attributes and per-gw processing will be available. - - - This function can be used from all routes. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - - - - gw_id (string) - comma - separated list of gateway IDs to be used. - - - - - gw_attrs_pvar (var, optional) - - an output writable variable which will be populated - with the attributes of the currently matched gateway. - - - - - carrier_attrs_pvar (var, - optional) - an output writable variable which will be - populated with the attributes of this carrier. NOTE: the - first carrier pointing to the GW(s) will be considered! - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is not accepted by the - function. - - - - - - - <function>route_to_gw</function> usage - -... -# use_partitions is not set -if ( route_to_gw("gw_europe") ) { - t_relay(); - exit; -} -... -# use_partitions is not set -if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs)) ) { - xlog("Relaying to first gateway from our list - $var(gw_attrs)\n"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_gw("gw_europe", , , "my_partition") ) { - t_relay(); - exit; -} -... -# use_partitions is enabled -if ( route_to_gw("gw1,gw2,gw3", $var(gw_attrs), , "my_partition") ) { - xlog("Relaying to first gateway from our list - $var(gw_attrs)\n"); - t_relay(); - exit; -} -... - - -
- -
- - <function moreinfo="none">use_next_gw( [rule_attrs_pvar], [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - The function takes the next available destination (set by do_routing, - as alternative destinations) and pushes it into the RURI. Note that the - function just sets the RURI (nothing more). - - - If a new RURI is set, the used destination is removed from the - pending set of alternative destinations. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - The function returns true only if a new RURI was set. False - is returned is no other alternative destinations are found or in case - of an internal processing error. It may take the following optional - parameters: - - - - - rule_attrs_pvar (var, optional) - - an output writable variable which will be populated - with the attributes of the matched dynamic routing rule. - - - - - gw_attrs_pvar (var, optional) - an - output writable variable which will be populated - with the attributes of the matched gateway. - - - - - carrier_attrs_pvar (var, optional) - - an output writable variable which will be populated - with the attributes of the matched carrier. - - - - - partition (optinal, string) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is not accepted by the - function. - - - - - <function>use_next_gw</function> usage - -... -# use_partitions is not set -if (use_next_gw()) { - t_relay(); - exit; -} -... -# Also fetch the carrier attributes, if any -if (use_next_gw(, , $var(carrier_attrs))) { - xlog("Carrier attributes of current gateway: $var(carrier_attrs)\n"); - t_relay(); - exit; -} -... -# use_partitions is enabled -if (use_next_gw( , , ,"my_partition")) { - t_relay(); - exit; -} -... -# Also fetch the carrier attributes, if any -if (use_next_gw( , ,$var(carrier_attrs), "my_partition")) { - xlog("Carrier attributes of current gateway: $var(carrier_attrs)\n"); - t_relay(); - exit; -} -... - - -
- -
- - <function moreinfo="none">goes_to_gw( [type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - Function returns true if the destination of the current request - (destination URI or Request URI) points (as IP) to one of the gateways. - There no DNS lookups done if the domain part of the URI is not an IP. - - - This function does not change anything in the message. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - It may take the following optional parameters: - - - - - type (int, optional) - number for - the GW/destination type to be checked; when omitting this - parameter or specifying the special value -1, matching will - be done against all types. - - - - - flags (string, optional) - - letter like flags for controlling what operations should be - performed when a GW matches: - - - - - 's' (Strip) - apply - to the username of RURI the strip defined by the GW - - - - - 'p' (Prefix) - apply - to the username of RURI the prefix defined by the GW - - - - - 'i' (Gateway ID) - - return the gateway id into gw_id_avp AVP - - - - - 'n' (Ignore port) - - ignores port number during matching - - - - - 'c' (Carrier ID) - - return the carrier id into carrier_id_avp AVP - - - - - - - gw_attrs_pvar (var, optional) - - an output writable variable which will be populated with - the attributes of the matched gateway. - - - - - carrier_attrs_pvar (var, optional) - an - output writable variable which will be populated with - the attributes of the matched carrier. - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is accepted by this - function. - - - - - <function>goes_to_gw</function> usage - -... -# use_partitions is not set -if (goes_to_gw( 1, , $var(gw_attrs))) { - sl_send_reply(403,"Forbidden"); - exit; -} -... -# use_partitions is enabledt -if (goes_to_gw(1, , $var(gw_attrs), , "my_partition")) { - sl_send_reply(403,"Forbidden"); - exit; -} -... - - -
- -
- - <function moreinfo="none">is_from_gw([type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - The function checks if the sender of the message (source IP + source - port) is a gateway from a certain group. - - - This function does not change anything in the message. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ONREPLY_ROUTE. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - It may take the following optional parameters: - - - - - type (int, optional) - number for - the GW/destination type to be checked; when omitting this - parameter or specifying the special value -1, matching will - be done against all types. - - - - - flags (string, optional) - - letter like flags for controlling what operations should be - performed when a GW matches: - - - - - 's' (Strip) - apply - to the username of RURI the strip defined by the GW - - - - - 'p' (Prefix) - apply - to the username of RURI the prefix defined by the GW - - - - - 'i' (Gateway ID) - - return the gateway id into gw_id_avp AVP - - - - - 'n' (Ignore port) - - ignores port number during matching - - - - - 'r' (Check protocol) - check protocol - - - - - 'c' (Carrier ID) - - return the carrier id into carrier_id_avp AVP - - - - - - - gw_attrs_pvar (var, optional) - an - output writable variable which will be populated with - the attributes of the matched gateway. - - - - - carrier_attrs_pvar (var, optional) - an - output writable variable which will be populated with - the attributes of the matched carrier. - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is accepted by this - function. - - - - - <function>is_from_gw</function> usage - -# use_partitions is not set -# match the source IP (only) against all gateways -if (is_from_gw(-1, "n")) { - ... -} - -# use_partitions is enabled -# match the source IP and port against all gateways from the "outbound" -# partition and return the matched gateway's carrier -if (is_from_gw(, "c", , , "outbound")) { - ... -} - - -
- -
- - <function moreinfo="none">dr_is_gw( sip_uri, [type], [flags], [gw_attrs_pvar], [carrier_attrs_pvar], [partition])</function> - - - The function checks if the SIP URI hostname part stored inside the - "src_pv" pseudo-variable is a gateway from a certain group. - - - This function does not change anything in the message. - - - This function can be used from all routes. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - It may take the following optional parameters: - - - - - sip_uri (string) - SIP URI. - If the URI hostname part is a FQDN, - it will be resolved prior to matching. - - - - - type (int, optional) - number for - the GW/destination type to be checked; when omitting this - parameter or specifying the special value -1, matching will - be done against all types. - - - - - flags (string, optional) - - letter like flags for controlling what operations should be - performed when a GW matches: - - - - - 's' (Strip) - apply - to the username of RURI the strip defined by the GW - - - - - 'p' (Prefix) - apply - to the username of RURI the prefix defined by the GW - - - - - 'i' (Gateway ID) - - return the gateway id into gw_id_avp AVP - - - - - 'n' (Ignore port) - - ignores port number during matching - - - - - 'c' (Carrier ID) - - return the carrier id into carrier_id_avp AVP - - - - - - - gw_attrs_pvar (var, optional) - an - output writable variable which will be populated with - the attributes of the matched gateway. - - - - - carrier_attrs_pvar (var, optional) - an - output writable variable which will be populated with - the attributes of the matched carrier. - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is accepted by this - function. - - - - - <function>dr_is_gw</function> usage - -# match the SIP URI host within $var(uac) against all gateways -if (dr_is_gw( $var(uac), , "n")) { - ... -} - - -# match the SIP URI host within $var(uac) against -# all gws in "outbound" partition -if (dr_is_gw( $avp(uac), , "n", , , "partition")) { - ... -} - - -
- -
- - <function moreinfo="none">dr_disable([partition])</function> - - - Marks as disabled the last destination that was used for the current - call. The disabling done via this function will prevent the - destination to be used for usage from now on. The probing mechanism - can re-enable this peer (see the probing section in the beginning) - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - - If you set use_partitions parameter to 1 you must - supply the "partition" parameter to instruct on the partition where the - gateway has been defined. - - - It may take the following parameters: - - - - - partition (string, optional) - - the name of the DR partition to be used. This parameter is - to be defined ONLY if the "use_partition" module parameter - is turned on. Wildcard sign is accepted by this - function. - - - - - - <function>dr_disable()</function> usage - -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - dr_disable(); - -} -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - dr_disable("my_partition"); - -} -... - - -
- - -
- - <function moreinfo="none">dr_match(groupID, [flags], number, [rule_attrs_pvar], [partition])</function> - - - The function tries to match/check the given number against the - rules from the database. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE and LOCAL_ROUTE. - - - If you set use_partitions to 1 the - partition last parameter becomes - mandatory. - - - The parameters are: - - - - - groupID (int) - number to - specify the dr group (set of rules) to perform the check against - - - - - flags (string, optional) - a list - of letter-like flags for controlling the checking/matching behavior. - Possible flags are: - - - - - L - Do strict length matching - over the prefix - actually DR engine will do full number - matching and not prefix matching anymore. - - - - - - - number (string) - the number to check - - - - - rule_attrs_pvar (var, optional) - a - writable variable which will be populated with the attributes of the - matched dynamic routing rule. - - - - - partition (string, optional) - the name - of the DR partition to be used. This parameter is to be defined - ONLY if the "use_partition" module parameter is turned on. - - - - - - - <function>dr_match</function> usage - -... -if ( dr_match( 1, "L" , $fU, ,"dids") ) - xlog("Full From Username $fU found in group 1 partition DIDS\n"); -... -if ( dr_match( 1, , $var(did) ) ) - xlog("DID $var(did) matches rules in group 1\n"); -... - - -
- - -
- - -
- Exported MI Functions -
- - <function moreinfo="none">dr_reload</function> - - - Command to reload routing rules from database. - - - - - if use_partition is set to 0 - all routing rules will be reloaded. - - - - inherit_state (optional) : whether inherit old state of the gateway , default is y. - - n: no inherit state - y: inherit state - - - - - - - - - if use_partition is set to 1, the parameters are: - - - partition_name (optional) - if not provided - all the partitions will be reloaded, otherwise just the partition given as parameter will be reloaded. - - - - - - inherit_state (optional) : whether inherit old state of the gateway , default is y. - - n: no inherit state - y: inherit state - - - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi dr_reload part_1 - -
- -
- <varname>dr_gw_status</varname> - - Gets the status (enabled or disabled) of one or multiple gateways. The function - can also be used to set the status of a single gateway. - - - - if use_partitions is set to 0, the parameters are: - - gw_id (optional) - the id of - a gateway. If provided, the function will return/set (depnding if the second - parameter is given) the status of that gateway, otherwise it will list all - gateways along with their statuses. - - status (optional) - the new status - to be forced for a GW (0 - disable, 1 - enable). Only makes sense if - gw_id is provided. - - - - - - - if use_partitions is set to 1, the parameters are: - - partition_name - - gw_id (optional) - the id of - a gateway. If provided, the function will return/set (depnding if the third - parameter is given) the status of that gateway, otherwise it will list all - gateways in the given partition along with their statuses. - - status (optional) - the new status - to be forced for a GW (0 - disable, 1 - enable). Only makes sense if - gw_id is provided. - - - - - - - - <function>dr_gw_status</function> usage when <varname>use_partitions</varname> is set to 0 - -$ opensips-cli -x mi dr_gw_status gw_id=2 -State:: Active -$ opensips-cli -x mi dr_gw_status gw_id=2 status=0 -$ opensips-cli -x mi dr_gw_status gw_id=2 -Enabled:: Disabled MI -$ opensips-cli -x mi dr_gw_status gw_id=3 -Enabled:: Inactive - - - - - <function>dr_gw_status</function> usage when <varname>use_partitions</varname>is set to 1 - -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw -State:: Active -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw status=0 -$ opensips-cli -x mi dr_gw_status partition_name=part_1 gw_id=my_gw -enabled:: disabled mi -$ opensips-cli -x mi dr_gw_status partition_name=partition8 status=3 -enabled:: inactive - - -
- -
- <varname>dr_carrier_status</varname> - - Gets the status (enabled or disabled) of one or multiple carriers. The function - can also be used to set the status of a single carrier. - - - - - if use_partitions is set to 0, the parameters are: - - carrier_id (optional) - the id of - a carrier. If provided, the function will return/set (depnding if the second - parameter is given) the status of that carrier, otherwise it will list all - carriers along with their statuses. - - status (optional) - the new status - to be forced for a carrier (0 - disable, 1 - enable). Only makes sense if - carrier_id is provided. - - - - - - - if use_partitions is set to 1, the parameters are: - - partition_name - - carrier_id (optional) - the id of - a carrier. If provided, the function will return/set (depnding if the third - parameter is given) the status of that carrier, otherwise it will list all - carriers contained in the given partition along with their statuses. - - status (optional) - the new status - to be forced for a carrier (0 - disable, 1 - enable). Only makes sense if - carrier_id is provided. - - - - - - - <function>dr_carrier_status</function> usage when <varname>use_partitions</varname> is 0 - -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 -Enabled:: no -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 status=1 -$ opensips-cli -x mi dr_carrier_status carrier_id=CR1 -Enabled:: yes - - - - <function>dr_carrier_status</function> usage when <varname>use_partitions</varname> is 1 - -$ opensips-cli -x mi dr_carrier_status partition_name=my_partition carrier_id=CR1 -Enabled:: no -$ opensips-cli -x mi dr_carrier_status partition_name=partition_1 carrier_id=CR1 status=1 -$ opensips-cli -x mi dr_carrier_status partition_name=partition_3 carrier_id=CR1 -Enabled:: yes - - -
- -
- <varname>dr_reload_status</varname> - - Gets the time of the last reload for any partition. - - - - - if use_partition is set to 0 - the function - doesn't receive any parameter. It will list the date of the - last reload for the default (and only) partition. - - - - - if use_partition is set to 1, the parameters are: - - - partition_name (optional) - if not provided - the function will list the time of the last update for every - partition. Otherwise, the function will list the time of the last - reload for the given partition. - - - - - - - <function>dr_reload_status</function> usage when <varname>use_partitions</varname> is 0 - -$ opensips-cli -x mi dr_reload_status -Date:: Tue Aug 12 12:26:00 2014 - - - - <function>dr_reload_status</function> usage when <varname>use_partitions</varname> is 1 - -$ opensips-cli -x mi dr_reload_status -Partition:: part_test Date=Tue Aug 12 12:24:13 2014 -Partition:: part_2 Date=Tue Aug 12 12:24:13 2014 -$ opensips-cli -x mi dr_reload_status part_test -Partition:: part_test Date=Tue Aug 12 12:24:13 2014 - - -
- -
- <varname>dr_number_routing</varname> - - Gets the matched prefix along with the list of the gateways / carriers to which a number - would be routed when using the do_routing function. - - - - - if use_partition is set to 1 the function - will have 3 parameters: - - - partition_name - - - group_id (optional) - the group id of the rules to - check against - - - number - the number to test against - - - - - - - if use_partition is set to 0 the function will have 2 parameters: - - - group_id (optional) - the group id of the rules to check against - - - number - the number to test against - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi dr_number_routing partition_name=part1 group_id=3 number=012340987 - -
- -
- - <function moreinfo="none">dr_enable_probing</function> - - - Enables/disables gateway probing or returns the current gateway - probing status. - - Parameters: - - - status (optional) - 1 - enable, - 0 - disable gateway probing - - - - <function>dr_enable_probing</function> usage - -$ opensips-cli -x mi dr_enable_probing -Status:: 1 -$ opensips-cli -x mi dr_enable_probing 0 -$ opensips-cli -x mi dr_enable_probing -Status:: 0 - - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_DROUTING_STATUS</function> - - - This event is raised when the module changes the state of a gateway, - either through an MI command, probing or script function. - - Parameters: - - - partition - the name of the partition. - - - gwid - the gateway identifier. - - - address - the address of the gateway. - - - status - disabled MI if - the gateway was disabled using MI commands, - probing if the gateway is being pinged, - inactive if it was disabled from the script or - active if the gateway is enabled. - - -
-
- - -
- Exported Status/Report Identifiers - - - The module provides the "drouting" Status/Report group, where each - routing partition is defined as a separate SR identifier. - -
- <varname>[partition_name]</varname> - - The status of these identifiers reflects the readiness/status of the - cached data (if available or not when being loaded from DB): - - - - -2 - no data at all (initial status) - - - -1 - no data, initial loading in progress - - - 1 - data loaded, partition ready - - - 2 - data available, a reload in progress - - - - - Reload reporting: - - - In terms of data reloading, the following logs will be reported: - - - - starting DB data loading - - - DB data loading failed, discarding - - - DB data loading successfully completed - - - N gateways loaded (N discarded), N carriers loaded (N discarded), N rules loaded (N discarded) - - - - { - "Name": "Default", - "Reports": [ - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "starting DB data loading" - }, - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "DB data loading successfully completed" - }, - { - "Timestamp": 1652353940, - "Date": "Thu May 12 14:12:20 2022", - "Log": "2 gateways loaded (0 discarded), 2 carriers loaded (0 discarded), 1 rules loaded (0 discarded)" - } - ] - } - -
- -
- <varname>[partition_name];events</varname> - - GW/Carrier switching reporting: - - - For reporting events related to the state changes of the - gateways and carriers, the module provides separate identifiers (still - one per partition). - Why separate ones? The reports on state changing may be verbose and there - is the risk of loose/discard important reports on reloads due to the high - number of logs on state changes; - - - So, each partition will provide the identified "partition_name;events" for - reporting state changes of gateways and carriers, along with the reason - of the change. This identifiers have a 200 records history before - discarding the old ones. - - - { - "Name": "Default;events", - "Reports": [ - { - "Timestamp": 1652353976, - "Date": "Thu May 12 14:12:56 2022", - "Log": "GW <gw1_1>/127.0.1.1 switched to [inactive] due probing reply\n" - }, - { - "Timestamp": 1652353976, - "Date": "Thu May 12 14:12:56 2022", - "Log": "GW <gw2_1>/127.0.1.2 switched to [inactive] due probing reply\n" - } - ] - } - -
- - - For how to access and use the Status/Report information, please see - https://www.opensips.org/Documentation/Interface-StatusReport-3-3. - - -
- - - - -
- Installation - - The module requires 4 tables in the OpenSIPS database: dr_groups, - dr_gateways, dr_carriers, dr_rules. The SQL syntax to create them can be - found in the drouting-create.sql script, located in the database directories - of the opensips/scripts folder. You can also find the complete - database documentation on the project webpage, &osipsdbdocslink;. - -
- -
diff --git a/modules/drouting/doc/drouting_devel.xml b/modules/drouting/doc/drouting_devel.xml deleted file mode 100644 index 58329e007be..00000000000 --- a/modules/drouting/doc/drouting_devel.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - &develguide; - - The module provides no function to be used - by other &osips; modules. - - - diff --git a/modules/drouting/routing.c b/modules/drouting/routing.c index b4bc129ff97..45d7029557e 100644 --- a/modules/drouting/routing.c +++ b/modules/drouting/routing.c @@ -254,7 +254,7 @@ void hash_carrier(pcr_t *pcr,MD5_CTX *hash_ctx) return; MD5Update(hash_ctx, pcr->id.s, pcr->id.len); - MD5Update(hash_ctx, (char *)pcr->sort_alg, sizeof(pcr->sort_alg)); + MD5Update(hash_ctx, (char *)&pcr->sort_alg, sizeof(pcr->sort_alg)); for (i=0;ipgwa_len;i++) { if (pcr->pgwl[i].is_carrier == 1) hash_carrier(pcr->pgwl[i].dst.carrier,hash_ctx); diff --git a/modules/emergency/README b/modules/emergency/README deleted file mode 100644 index b3027b679f4..00000000000 --- a/modules/emergency/README +++ /dev/null @@ -1,431 +0,0 @@ -Emergency Call Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table_routing (string) - 1.3.3. db_table_report (string) - 1.3.4. db_table_provider (string) - 1.3.5. proxy_role (integer) - 1.3.6. url_vpc (string) - 1.3.7. emergency_codes (string) - 1.3.8. timer_interval (interger) - 1.3.9. contingency_hostname (string) - 1.3.10. emergency_call_server (string) - - 1.4. Exported Functions - - 1.4.1. emergency_call() - 1.4.2. failure() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the db_url parameter - 1.2. Setting the db_table_routing parameter - 1.3. Setting the db_table_report parameter - 1.4. Setting the db_table_provider parameter - 1.5. Setting the proxy_role parameter - 1.6. Setting the url_vpc parameter - 1.7. Setting the emergency_codes parameter - 1.8. Setting the timer_interval parameter - 1.9. Setting the contingency_hostname parameter - 1.10. Setting the emergency_call_server parameter - 1.11. emergency_call() usage - 1.12. failure() usage - -Chapter 1. Admin Guide - -1.1. Overview - - The emergency module provides emergency call treatment for - OpenSIPS, following the architecture i2 specification of the - American entity NENA. (National Emergency Number Association). - The NENA solution routes the emergency call to a closer gateway - (ESGW) and this forward the call to a PSAP(call center - responsible for answering emergency calls) that serves the area - of ​​the caller, so this must consider the handling and - transport of caller location information in the SIP protocol. - To attend this new need the NENA solution consists of several - servers: to determine the location (LIS), to determine the area - of emergency treatment depending on location (VPC), validate - location stored (VDB), among others. Along with these elements - have the SIP Proxy that interface with these servers to route - the call. The OpenSIPS can do the functions of these SIP Proxy - through this emergency module, may perform the function of a - Call Server, Redirect Server and Routing Proxy, depending on - the proposed scenario: - * scenario I: The VSP(Voip Serve Provide) retains control - over the processing of emergency calls. The VSP’s Call - Server implements the v2 interface that queries the VPC for - routing information, with this information selects the - proper ESGW, if normal routing fails routes calls via the - PSTN using the contingency number(LRO). - * scenario II: The VSP transfers all emergency calls to - Routing Proxy provider using the v6 SIP interface. Once - done transfer the VSP no longer participates in the call. - The Routing Proxy provider implements the v2 interface, - queries the VPC for for routing information, and forwards - the call. - * scenario III: The VSP requests routing information for the - Redirect Server operator, but remains part of the call. The - Redirect Server obtains the routing information from the - VPC. It returns the call to the VSP’s Call Server with - routing information in the SIP Contact Header. The Call - Server selects the proper ESGW based on this information. - - The emergency module allows the OpenSIPS play the role of a - Call Server, a Proxy or Redirect Server Routing within the - scenarios presented depending on how it is configured. - - 1.2. Scenario I: The VSP that originating the call is the same - as handle the call and sends the routing information request to - the VPC. The emergency module through emergency_call() command - will check if the INVITE received is an emergency call. In this - case, the OpenSIPS will get caller location information from - specific headers and body in the INVITE. With this information - along configuration parameters defined for this module, the - opensips implements the v2 interface that queries the VPC for - routing information (i.e., ESQK, LRO, and either the ERT or - ESGWRI), selects the proper ESGW based on the ESGWRI. When the - call ends the OpenSIPS receives BYE request, it warns the VPC - for clean your data that is based on the call. The OpenSIPS - through failure() command will try to route the calls via the - PSTN using a national contingency number(LRO) if normal routing - fails. - - 1.3.Scenario II: The VSP transfers the call to a Routing Server - provider The emergency module through emergency_call() command - will check if the INVITE received is an emergency call. In this - case, it will forward the call to a Routing Proxy that will - interface with the VPC and route the call. The OpenSIPS will - leave the call, and all the request of this dialog received by - the opensips will be forwarded to the Routing Server. - - 1.4.Scenario III: The VSP requests routing information for the - Redirect Server The emergency module through emergency_call() - command will check if the INVITE received is an emergency call. - In this case, it requests routing information to Redirect - Server. The Redirect has interface with the VPC and return to - VSP's Call Server response whith routing informations on - Contact header. The Call Server uses this information to treat - the call. When the emergency call ends, it must notify the - Redirect Server that inform to VPC to release the resources. - To use this module should informs the mandatory parameters in - script and make the correct filling out of the emergency module - tables, in accordance with the role chosen within the described - scenarios. For more details check the "Emergency calls using - OpenSIPS". - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * Dialog - Dialoge module.. - * TM - Transaction module.. - * RR - Record-Route module.. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libcurl. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - The database url must be specified. - - Default value is “NULL”. - - Example 1.1. Setting the db_url parameter -... -modparam("emergency", "db_url", "mysql://opensips:opensipsrw@localhost/o -pensips”) -... - -1.3.2. db_table_routing (string) - - The name of the db table storing routing information to - emergency calls. - - Default value is “emergency_routing”. - - Example 1.2. Setting the db_table_routing parameter -... -modparam("emergency", "db_table_routing", "emergency_routing") -... - -1.3.3. db_table_report (string) - - The name of the db table that stores the emergency call report. - - Default value is “emergency_report”. - - Example 1.3. Setting the db_table_report parameter -... -modparam("emergency", "db_table_report", "emergency_report") -... - -1.3.4. db_table_provider (string) - - The name of the db table that stores the nodes information of - organization involved in emergency calls. - - Default value is “emergency_service_provider”. - - Example 1.4. Setting the db_table_provider parameter -... -modparam("emergency", "db_table_provider", "emergency_service_provider") -... - -1.3.5. proxy_role (integer) - - This parameter define what role the opensips will take to treat - emergency call: - - 0 – The opensips is the Call Server in scenario I. In this role - the opensips implements the V2 interface, directly queries the - VPC for ESGWRI/ESQK, selects the proper ESGW given the ESGWRI - and routes calls Via the PSTN using the LRO if routing fails. - - 1 – The opensips is the Call Server in scenario II that sends - the INVITE on emergency call to a Routing Proxy provider. The - Routing Proxy provider implements the V2 interface. - - 2 - The opensips is the Routing Proxy in scenario II. In this - role the opensips implements the V2 interface, directly queries - the VPC for ESGWRI/ESQK, selects the proper ESGW given the - ESGWRI and routes calls Via the PSTN using the LRO if routing - fails. - - 3 - The opensips is the Redirect Proxy in scenario III that - receives the INVITE on emergency call from Call Server. The - Redirect Server obtains the ESGWRI/ESQK from the VPC and sends - in the SIP 3xx response to the Call Server. - - 4 - The opensips is the Call Server in scenario III that sends - the INVITE on emergency call to a Redirect Server. The Redirect - Server obtains the ESGWRI/ESQK from the VPC. It returns the - call to the opensips with the ESGWRI/ESQK in the header contact - in the SIP response. The opensips selects the proper ESGW based - on the ESGWRI. - - Default value is “0”. - - Example 1.5. Setting the proxy_role parameter -... -modparam("emergency", "proxy_role", 0)) -... - -1.3.6. url_vpc (string) - - The VPC url that opensips request the routing information to - emergency call. This VPC url has IP:Port format - - Default value is “empty string”. - - Example 1.6. Setting the url_vpc parameter -... -modparam("emergency", "url_vpc", “192.168.0.103:5060”) -... - -1.3.7. emergency_codes (string) - - Local emergency number. Opensips uses this number to recognize - a emergency call beyond the username default defined by - RFC-5031 (urn:service.sos.). Along with the number should be - given a brief description about this code. The format is - code_number-description. It can register multiple emergency - numbers. - - Default value is “NULLg”. - - Example 1.7. Setting the emergency_codes parameter -... -modparam("emergency", "emergency_codes", “911-us emegency code”) -... - -1.3.8. timer_interval (interger) - - Sets the time interval polling to make the copy in memory of - the db_table_routing. - - Default value is “10”. - - Example 1.8. Setting the timer_interval parameter -... -modparam("emergency","timer_interval",20) -... - -1.3.9. contingency_hostname (string) - - The contingency_hostname is the url of the server que will - route the call to the PSTN using the number of contingency. - - Default value is “NULL”. - - Example 1.9. Setting the contingency_hostname parameter -... -modparam("emergency","contingency_hostname",“176.34,29.102:5060”) -... - -1.3.10. emergency_call_server (string) - - The emergency_call_server is the url of the Routing - Proxy/Redirect Server that will handle the emergency call in - cenario II. Its is mandatory if Opensips act as Call Server in - scenario II (proxy_role = 1 and flag_third_enterprise = 0) or - Call Server in scenario III (proxy_role = 2). - - Default value is “NULL”. - - Example 1.10. Setting the emergency_call_server parameter -... -modparam("emergency","emergency_call_server",“124.78.29.123:5060”) -... - -1.4. Exported Functions - -1.4.1. emergency_call() - - Checks whether the incoming call is an emergency call, case it - is treats, and routes the call to the destination determined by - VPC. The function returns true if is a emergency call and the - treat was Ok. - - This function can be used from the REQUEST routes. - - Example 1.11. emergency_call() usage -... -# Example of treat of emergency call - - if (emergency_call()){ - - xlog("emergency call\n"); - t_on_failure("emergency_call"); - t_relay(); - exit; - - } -... - -1.4.2. failure() - - This function is used when trying to route the emergency call - to the destination specified by the VPC and doesn't work, then - uses this function to make one last attempt for a contingency - number. The function returns true if the contingency treat was - OK. - - This function can be used from the FAILURE routes. - - Example 1.12. failure() usage -... -# Example od treat of contingency in emergency call - - if (failure()) { - if (!t_relay()) { - send_reply(500,"Internal Error"); - }; - exit; - } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Evandro Villaron (@evillaron) 152 9 10947 3011 - 2. Robison Tesini (@rtesini) 62 1 3116 2038 - 3. Razvan Crainea (@razvancrainea) 26 17 331 338 - 4. Liviu Chircu (@liviuchircu) 19 13 134 188 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 11 9 52 52 - 6. Alexandra Titoc 10 8 62 19 - 7. Maksym Sobolyev (@sobomax) 6 4 18 17 - 8. Peter Lemenkov (@lemenkov) 5 3 38 17 - 9. Walter Doekes (@wdoekes) 4 2 4 4 - 10. Zero King (@l2dy) 4 2 2 1 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Julián Moreno Patiño, Vlad Patrascu (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jul 2015 - Sep 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2015 - May 2023 - 5. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 6. Zero King (@l2dy) Mar 2020 - Aug 2020 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2015 - Mar 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Evandro Villaron (@evillaron), - Ionut Ionita (@ionutrazvanionita), Robison Tesini (@rtesini). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Julián Moreno Patiño, Evandro Villaron - (@evillaron). - - Documentation Copyrights: - - Copyright © 2014 Villaron/Tesini diff --git a/modules/emergency/README.md b/modules/emergency/README.md new file mode 100644 index 00000000000..b1a8e9ea48a --- /dev/null +++ b/modules/emergency/README.md @@ -0,0 +1,329 @@ +--- +title: "Emergency Call Module" +description: "The emergency module provides emergency call treatment for OpenSIPS, following the architecture i2 specification of the American entity NENA." +--- + +## Admin Guide + + +### Overview + + +The emergency module provides emergency call treatment for OpenSIPS, following the architecture i2 specification of the American entity NENA. (National Emergency Number Association). The NENA solution routes the emergency call to a closer gateway (ESGW) and this forward the call to a PSAP(call center responsible for answering emergency calls) that serves the area of ​​the caller, so this must consider the handling and transport of caller location information in the SIP protocol. + +To attend this new need the NENA solution consists of several servers: to determine the location (LIS), to determine the area of emergency treatment depending on location (VPC), validate location stored (VDB), among others. Along with these elements have the SIP Proxy that interface with these servers to route the call. The OpenSIPS can do the functions of these SIP Proxy through this emergency module, may perform the function of a Call Server, Redirect Server and Routing Proxy, depending on the proposed scenario: + + +- scenario I: The VSP(Voip Serve Provide) retains control over the processing of emergency calls. The VSP’s Call Server implements the v2 interface that queries the VPC for routing information, with this information selects the proper ESGW, if normal routing fails routes calls via the PSTN using the contingency number(LRO). +- scenario II: The VSP transfers all emergency calls to Routing Proxy provider using the v6 SIP interface. Once done transfer the VSP no longer participates in the call. The Routing Proxy provider implements the v2 interface, queries the VPC for for routing information, and forwards the call. +- scenario III: The VSP requests routing information for the Redirect Server operator, but remains part of the call. The Redirect Server obtains the routing information from the VPC. It returns the call to the VSP’s Call Server with routing information in the SIP Contact Header. The Call Server selects the proper ESGW based on this information. + + +The emergency module allows the OpenSIPS play the role of a Call Server, a Proxy or Redirect Server Routing within the scenarios presented depending on how it is configured. + + +1.2. Scenario I: The VSP that originating the call is the same as handle the call and sends the routing information request to the VPC. + +The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, the OpenSIPS will get caller location information from specific headers and body in the INVITE. With this information along configuration parameters defined for this module, the opensips implements the v2 interface that queries the VPC for routing information (i.e., ESQK, LRO, and either the ERT or ESGWRI), selects the proper ESGW based on the ESGWRI. When the call ends the OpenSIPS receives BYE request, it warns the VPC for clean your data that is based on the call. +The OpenSIPS through failure() command will try to route the calls via the PSTN using a national contingency number(LRO) if normal routing fails. + + +1.3.Scenario II: The VSP transfers the call to a Routing Server provider + +The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, it will forward the call to a Routing Proxy that will interface with the VPC and route the call. +The OpenSIPS will leave the call, and all the request of this dialog received by the opensips will be forwarded to the Routing Server. + + +1.4.Scenario III: The VSP requests routing information for the Redirect Server + +The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, it requests routing information to Redirect Server. The Redirect has interface with the VPC and return to VSP's Call Server response whith routing informations on Contact header. +The Call Server uses this information to treat the call. When the emergency call ends, it must notify the Redirect Server that inform to VPC to release the resources. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *Dialog - Dialoge module.*. +- *TM - Transaction module.*. +- *RR - Record-Route module.*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libcurl*. + + +### Exported Parameters + + +#### db_url (string) + + +The database url must be specified. + + +*Default value is "NULL".* + + +```opensips title="Setting the db_url parameter" +... +modparam("emergency", "db_url", "mysql://opensips:opensipsrw@localhost/opensips”) +... + +``` + + +#### db_table_routing (string) + + +The name of the db table storing routing information to emergency calls. + + +*Default value is "emergency_routing".* + + +```opensips title="Setting the db_table_routing parameter" +... +modparam("emergency", "db_table_routing", "emergency_routing") +... + +``` + + +#### db_table_report (string) + + +The name of the db table that stores the emergency call report. + + +*Default value is "emergency_report".* + + +```opensips title="Setting the db_table_report parameter" +... +modparam("emergency", "db_table_report", "emergency_report") +... + +``` + + +#### db_table_provider (string) + + +The name of the db table that stores the nodes information of organization involved in emergency calls. + + +*Default value is "emergency_service_provider".* + + +```opensips title="Setting the db_table_provider parameter" +... +modparam("emergency", "db_table_provider", "emergency_service_provider") +... + +``` + + +#### proxy_role (integer) + + +This parameter define what role the opensips will take to treat emergency +call: +- 0 – The opensips is the Call Server in scenario I. In this role the +opensips implements the V2 interface, directly queries the VPC for +ESGWRI/ESQK, selects the proper ESGW given the ESGWRI and routes calls +Via the PSTN using the LRO if routing fails. +- 1 – The opensips is the Call Server in scenario II that sends the INVITE on +emergency call to a Routing Proxy provider. The Routing Proxy provider +implements the V2 interface. +- 2 - The opensips is the Routing Proxy in scenario II. In this role the +opensips implements the V2 interface, directly queries the VPC for +ESGWRI/ESQK, selects the proper ESGW given the ESGWRI and routes calls +Via the PSTN using the LRO if routing fails. +- 3 - The opensips is the Redirect Proxy in scenario III that receives the +INVITE on emergency call from Call Server. The Redirect Server obtains +the ESGWRI/ESQK from the VPC and sends in the SIP 3xx response to the +Call Server. +- 4 - The opensips is the Call Server in scenario III that sends the INVITE on +emergency call to a Redirect Server. The Redirect Server obtains the +ESGWRI/ESQK from the VPC. It returns the call to the opensips with the +ESGWRI/ESQK in the header contact in the SIP response. The opensips +selects the proper ESGW based on the ESGWRI. + + +*Default value is "0".* + + +```opensips title="Setting the proxy_role parameter" +... +modparam("emergency", "proxy_role", 0)) +... + +``` + + +#### url_vpc (string) + + +The VPC url that opensips request the routing information to emergency +call. This VPC url has IP:Port format + + +*Default value is "empty string".* + + +```opensips title="Setting the url_vpc parameter" +... +modparam("emergency", "url_vpc", “192.168.0.103:5060”) +... + +``` + + +#### emergency_codes (string) + + +Local emergency number. Opensips uses this number to recognize a emergency +call beyond the username default defined by RFC-5031 (urn:service.sos.). +Along with the number should be given a brief description about this code. +The format is code_number-description. It can register multiple emergency +numbers. + + +*Default value is "NULLg".* + + +```opensips title="Setting the emergency_codes parameter" +... +modparam("emergency", "emergency_codes", “911-us emegency code”) +... + +``` + + +#### timer_interval (interger) + + +Sets the time interval polling to make the copy in memory of the +db_table_routing. + + +*Default value is "10".* + + +```opensips title="Setting the timer_interval parameter" +... +modparam("emergency","timer_interval",20) +... + +``` + + +#### contingency_hostname (string) + + +The contingency_hostname is the url of the server que will route the call +to the PSTN using the number of contingency. + + +*Default value is "NULL".* + + +```opensips title="Setting the contingency_hostname parameter" +... +modparam("emergency","contingency_hostname",“176.34,29.102:5060”) +... + +``` + + +#### emergency_call_server (string) + + +The emergency_call_server is the url of the Routing Proxy/Redirect Server +that will handle the emergency call in cenario II. Its is mandatory if Opensips +act as Call Server in scenario II (proxy_role = 1 and flag_third_enterprise = 0) +or Call Server in scenario III (proxy_role = 2). + + +*Default value is "NULL".* + + +```opensips title="Setting the emergency_call_server parameter" +... +modparam("emergency","emergency_call_server",“124.78.29.123:5060”) +... + +``` + + +### Exported Functions + + +#### emergency_call() + + +Checks whether the incoming call is an emergency call, case it is treats, and +routes the call to the destination determined by VPC. + +The function returns true if is a emergency call and the treat was Ok. + + +This function can be used from the *REQUEST* routes. + + +```opensips title="emergency_call() usage" +... +# Example of treat of emergency call +if (emergency_call()){ +    xlog("emergency call\n"); +    t_on_failure("emergency_call"); + t_relay(); + exit; +} +... + +``` + + +#### failure() + + +This function is used when trying to route the emergency call to the +destination specified by the VPC and doesn't work, then uses this function to +make one last attempt for a contingency number. + +The function returns true if the contingency treat was OK. + + +This function can be used from the *FAILURE* routes. + + +```opensips title="failure() usage" +... +# Example od treat of contingency in emergency call +if (failure()) { +   if (!t_relay()) { +      send_reply(500,"Internal Error"); +   }; +   exit; +} +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/emergency/doc/contributors.xml b/modules/emergency/doc/contributors.xml deleted file mode 100644 index 9d8e1b140a1..00000000000 --- a/modules/emergency/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Evandro Villaron (@evillaron) - 152 - 9 - 10947 - 3011 - - - 2. - Robison Tesini (@rtesini) - 62 - 1 - 3116 - 2038 - - - 3. - Razvan Crainea (@razvancrainea) - 26 - 17 - 331 - 338 - - - 4. - Liviu Chircu (@liviuchircu) - 19 - 13 - 134 - 188 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 11 - 9 - 52 - 52 - - - 6. - Alexandra Titoc - 10 - 8 - 62 - 19 - - - 7. - Maksym Sobolyev (@sobomax) - 6 - 4 - 18 - 17 - - - 8. - Peter Lemenkov (@lemenkov) - 5 - 3 - 38 - 17 - - - 9. - Walter Doekes (@wdoekes) - 4 - 2 - 4 - 4 - - - 10. - Zero King (@l2dy) - 4 - 2 - 2 - 1 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Vlad Patrascu (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jul 2015 - Sep 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2015 - May 2023 - - - 5. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 6. - Zero King (@l2dy) - Mar 2020 - Aug 2020 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2015 - Mar 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Evandro Villaron (@evillaron), Ionut Ionita (@ionutrazvanionita), Robison Tesini (@rtesini). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Evandro Villaron (@evillaron). -
- -
diff --git a/modules/emergency/doc/emergency.xml b/modules/emergency/doc/emergency.xml deleted file mode 100644 index 7022bccf115..00000000000 --- a/modules/emergency/doc/emergency.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Emergency Call Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2014 Villaron/Tesini - - - diff --git a/modules/emergency/doc/emergency_admin.xml b/modules/emergency/doc/emergency_admin.xml deleted file mode 100644 index c6e496f752c..00000000000 --- a/modules/emergency/doc/emergency_admin.xml +++ /dev/null @@ -1,412 +0,0 @@ - - - - - &adminguide; - -
- Overview - - -The emergency module provides emergency call treatment for OpenSIPS, following the architecture i2 specification of the American entity NENA. (National Emergency Number Association). The NENA solution routes the emergency call to a closer gateway (ESGW) and this forward the call to a PSAP(call center responsible for answering emergency calls) that serves the area of ​​the caller, so this must consider the handling and transport of caller location information in the SIP protocol. - -To attend this new need the NENA solution consists of several servers: to determine the location (LIS), to determine the area of emergency treatment depending on location (VPC), validate location stored (VDB), among others. Along with these elements have the SIP Proxy that interface with these servers to route the call. The OpenSIPS can do the functions of these SIP Proxy through this emergency module, may perform the function of a Call Server, Redirect Server and Routing Proxy, depending on the proposed scenario: - - - -scenario I: The VSP(Voip Serve Provide) retains control over the processing of emergency calls. The VSP’s Call Server implements the v2 interface that queries the VPC for routing information, with this information selects the proper ESGW, if normal routing fails routes calls via the PSTN using the contingency number(LRO). - - -scenario II: The VSP transfers all emergency calls to Routing Proxy provider using the v6 SIP interface. Once done transfer the VSP no longer participates in the call. The Routing Proxy provider implements the v2 interface, queries the VPC for for routing information, and forwards the call. - - -scenario III: The VSP requests routing information for the Redirect Server operator, but remains part of the call. The Redirect Server obtains the routing information from the VPC. It returns the call to the VSP’s Call Server with routing information in the SIP Contact Header. The Call Server selects the proper ESGW based on this information. - - - -The emergency module allows the OpenSIPS play the role of a Call Server, a Proxy or Redirect Server Routing within the scenarios presented depending on how it is configured. - - - 1.2. Scenario I: The VSP that originating the call is the same as handle the call and sends the routing information request to the VPC. - - The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, the OpenSIPS will get caller location information from specific headers and body in the INVITE. With this information along configuration parameters defined for this module, the opensips implements the v2 interface that queries the VPC for routing information (i.e., ESQK, LRO, and either the ERT or ESGWRI), selects the proper ESGW based on the ESGWRI. When the call ends the OpenSIPS receives BYE request, it warns the VPC for clean your data that is based on the call. - The &osips; through failure() command will try to route the calls via the PSTN using a national contingency number(LRO) if normal routing fails. - - - - 1.3.Scenario II: The VSP transfers the call to a Routing Server provider - - The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, it will forward the call to a Routing Proxy that will interface with the VPC and route the call. - The OpenSIPS will leave the call, and all the request of this dialog received by the opensips will be forwarded to the Routing Server. - - - - 1.4.Scenario III: The VSP requests routing information for the Redirect Server - - The emergency module through emergency_call() command will check if the INVITE received is an emergency call. In this case, it requests routing information to Redirect Server. The Redirect has interface with the VPC and return to VSP's Call Server response whith routing informations on Contact header. - The Call Server uses this information to treat the call. When the emergency call ends, it must notify the Redirect Server that inform to VPC to release the resources. - - To use this module should informs the mandatory parameters in script and make the correct filling out of the emergency module tables, in accordance with the role chosen within the described scenarios. For more details check the "Emergency calls using OpenSIPS". - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - Dialog - Dialoge module.. - - - - - TM - Transaction module.. - - - - - RR - Record-Route module.. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libcurl. - - - - -
-
- -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - The database url must be specified. - - - - Default value is NULL. - - - - Setting the <varname>db_url</varname> parameter - -... -modparam("emergency", "db_url", "mysql://opensips:opensipsrw@localhost/opensips”) -... - - -
- -
- <varname>db_table_routing</varname> (string) - - The name of the db table storing routing information to emergency calls. - - - - Default value is emergency_routing. - - - - Setting the <varname>db_table_routing</varname> parameter - -... -modparam("emergency", "db_table_routing", "emergency_routing") -... - - -
- -
- <varname>db_table_report</varname> (string) - - The name of the db table that stores the emergency call report. - - - - Default value is emergency_report. - - - - Setting the <varname>db_table_report</varname> parameter - -... -modparam("emergency", "db_table_report", "emergency_report") -... - - -
- -
- <varname>db_table_provider</varname> (string) - - The name of the db table that stores the nodes information of organization involved in emergency calls. - - - - - Default value is emergency_service_provider. - - - - Setting the <varname>db_table_provider</varname> parameter - -... -modparam("emergency", "db_table_provider", "emergency_service_provider") -... - - -
- -
- <varname>proxy_role</varname> (integer) - - This parameter define what role the opensips will take to treat emergency - call: - - 0 – The opensips is the Call Server in scenario I. In this role the - opensips implements the V2 interface, directly queries the VPC for - ESGWRI/ESQK, selects the proper ESGW given the ESGWRI and routes calls - Via the PSTN using the LRO if routing fails. - - - 1 – The opensips is the Call Server in scenario II that sends the INVITE on - emergency call to a Routing Proxy provider. The Routing Proxy provider - implements the V2 interface. - - - 2 - The opensips is the Routing Proxy in scenario II. In this role the - opensips implements the V2 interface, directly queries the VPC for - ESGWRI/ESQK, selects the proper ESGW given the ESGWRI and routes calls - Via the PSTN using the LRO if routing fails. - - - 3 - The opensips is the Redirect Proxy in scenario III that receives the - INVITE on emergency call from Call Server. The Redirect Server obtains - the ESGWRI/ESQK from the VPC and sends in the SIP 3xx response to the - Call Server. - - - 4 - The opensips is the Call Server in scenario III that sends the INVITE on - emergency call to a Redirect Server. The Redirect Server obtains the - ESGWRI/ESQK from the VPC. It returns the call to the opensips with the - ESGWRI/ESQK in the header contact in the SIP response. The opensips - selects the proper ESGW based on the ESGWRI. - - - - - Default value is 0. - - - - Setting the <varname>proxy_role</varname> parameter - -... -modparam("emergency", "proxy_role", 0)) -... - - -
- -
- <varname>url_vpc</varname> (string) - - The VPC url that opensips request the routing information to emergency - call. This VPC url has IP:Port format - - - - Default value is empty string. - - - - Setting the <varname>url_vpc</varname> parameter - -... -modparam("emergency", "url_vpc", “192.168.0.103:5060”) -... - - -
- -
- <varname>emergency_codes</varname> (string) - - Local emergency number. Opensips uses this number to recognize a emergency - call beyond the username default defined by RFC-5031 (urn:service.sos.). - Along with the number should be given a brief description about this code. - The format is code_number-description. It can register multiple emergency - numbers. - - - - Default value is NULLg. - - - - Setting the <varname>emergency_codes</varname> parameter - -... -modparam("emergency", "emergency_codes", “911-us emegency code”) -... - - -
- -
- <varname>timer_interval</varname> (interger) - - Sets the time interval polling to make the copy in memory of the - db_table_routing. - - - - Default value is 10. - - - - Setting the <varname>timer_interval</varname> parameter - -... -modparam("emergency","timer_interval",20) -... - - -
- -
- <varname>contingency_hostname</varname> (string) - - The contingency_hostname is the url of the server que will route the call - to the PSTN using the number of contingency. - - - - Default value is NULL. - - - - Setting the <varname>contingency_hostname</varname> parameter - -... -modparam("emergency","contingency_hostname",“176.34,29.102:5060”) -... - - -
- - -
- <varname>emergency_call_server</varname> (string) - - The emergency_call_server is the url of the Routing Proxy/Redirect Server - that will handle the emergency call in cenario II. Its is mandatory if Opensips - act as Call Server in scenario II (proxy_role = 1 and flag_third_enterprise = 0) - or Call Server in scenario III (proxy_role = 2). - - - - Default value is NULL. - - - - Setting the <varname>emergency_call_server</varname> parameter - -... -modparam("emergency","emergency_call_server",“124.78.29.123:5060”) -... - - -
-
- - -
- Exported Functions -
- - <function moreinfo="none">emergency_call()</function> - - - Checks whether the incoming call is an emergency call, case it is treats, and - routes the call to the destination determined by VPC. - - The function returns true if is a emergency call and the treat was Ok. - - - This function can be used from the REQUEST routes. - - - <function moreinfo="none">emergency_call()</function> usage - -... -# Example of treat of emergency call - -    if (emergency_call()){ - -        xlog("emergency call\n"); -        t_on_failure("emergency_call"); -   t_relay(); -   exit; - - } -... - - -
- -
- - <function moreinfo="none">failure()</function> - - - This function is used when trying to route the emergency call to the - destination specified by the VPC and doesn't work, then uses this function to - make one last attempt for a contingency number. - - The function returns true if the contingency treat was OK. - - - This function can be used from the FAILURE routes. - - - <function moreinfo="none">failure()</function> usage - -... -# Example od treat of contingency in emergency call - - if (failure()) { -        if (!t_relay()) { -           send_reply(500,"Internal Error"); -        }; -        exit; - } -... - - -
- -
- -
- diff --git a/modules/emergency/post_curl.c b/modules/emergency/post_curl.c index a42af1de596..afdfed76263 100644 --- a/modules/emergency/post_curl.c +++ b/modules/emergency/post_curl.c @@ -52,7 +52,7 @@ size_t write_data(char *ptr, size_t size, size_t nmemb, void *stream) { data->size += (size * nmemb); #ifdef DEBUG - fprintf(stderr, "data at %p size=%ld nmemb=%ld\n", ptr, size, nmemb); + fprintf(stderr, "data at %p size=%zu nmemb=%zu\n", ptr, size, nmemb); #endif tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */ diff --git a/modules/enum/README b/modules/enum/README deleted file mode 100644 index 7ea72ba22de..00000000000 --- a/modules/enum/README +++ /dev/null @@ -1,432 +0,0 @@ -Enum Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. domain_suffix (string) - 1.3.2. tel_uri_params (string) - 1.3.3. i_enum_suffix (string) - 1.3.4. isn_suffix (string) - 1.3.5. branchlabel (string) - 1.3.6. bl_algorithm (string) - - 1.4. Exported Functions - - 1.4.1. enum_query([suffix], [service], [number]) - 1.4.2. i_enum_query([suffix], [service]) - 1.4.3. isn_query([suffix], [service]) - 1.4.4. is_from_user_enum([suffix], [service]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting domain_suffix module parameter - 1.2. Setting tel_uri_params module parameter - 1.3. Setting i_enum_suffix module parameter - 1.4. Setting isn_suffix module parameter - 1.5. Setting branchlabel module parameter - 1.6. Zone file example - 1.7. Zone file example - 1.8. Setting the bl_algorithm module parameter - 1.9. enum_query usage - 1.10. isn_query usage - 1.11. is_from_user_enum usage - -Chapter 1. Admin Guide - -1.1. Overview - - Enum module implements [i_]enum_query functions that make an - enum query based on the user part of the current Request-URI. - These functions assume that the user part consists of an - international phone number of the form +decimal-digits, where - the number of digits is at least 2 and at most 15. Out of this - number enum_query forms a domain name, where the digits are in - reverse order and separated by dots followed by domain suffix - that by default is “e164.arpa.”. For example, if the user part - is +35831234567, the domain name will be - “7.6.5.4.3.2.1.3.8.5.3.e164.arpa.”. i_enum_query operates in a - similar fashion. The only difference is that it adds a label - (default "i") to branch off from the default, user-ENUM tree to - an infrastructure ENUM tree. - - After forming the domain name, enum_query queries DNS for its - NAPTR records. From the possible response enum_query chooses - those records, whose flags field has string value "u", and - whose services field has string value "e2u+[service:]sip" or - "e2u+type[:subtype][+type[:subtype]...]" (case is ignored in - both cases), and whose regexp field is of the form - !pattern!replacement!. - - Then enum_query sorts the chosen NAPTR records based on their - . After sorting, enum_query replaces the - current Request URI by applying regexp of the most preferred - NAPTR record its user part and appends to the request new - branches by applying regexp of each remaining NAPTR record to - the user part of the current Request URI. If a new URI is a tel - URI, enum_query appends to it as tel URI parameters the value - of tel_uri_params module parameter. Finally, enum_query - associates a q value with each new URI based on the of the corresponding NAPTR record. - - When using enum_query without any parameters, it searches for - NAPTRs with service type "e2u+sip" in the default enum tree. - When using enum_query with a single parameter, this parameter - will be used as enum tree. When using enum_query with two - parameters, the functionality depends on the first letter in - the second parameter. When the first letter is not a '+' sign, - the second parameter will be used to search for NAPTRs with - service type "e2u+parameter:sip". When the second parameter - starts with a '+' sign, the ENUM lookup also supports compound - NAPTRs (e.g. "e2u+voice:sip+video:sip") and searching for - multiple service types within one lookup. Multiple service - types must be separated by a '+' sign. - - Most of the time you want to route based on the RURI. On rare - occasions you may wish to route based on something else. The - function enum_pv_query mimics the behavior of the enum_query - function except the E.164 number in its pseudo variable - argument is used for the enum lookup instead of the user part - of the RURI. Obviously the user part of the RURI is still used - in the NAPTR regexp. - - Enum query returns 1 if the current Request URI was replaced - and -1 if not. - - In addition to standard ENUM, support for ISN (ITAD Subscriber - Numbers) is provided as well. To allow ISN lookups to resolve, - a different formatting algorithm is expected by the DNS server. - Whereas a ENUM NAPTR record expects a DNS query of the form - 9.8.7.6.5.4.3.2.1.suffix, ISN method expects a DNS query of the - form 6.5.1212.suffix. That is, a valid ISN number includes a - prefix of '56' in the example. The rest of the number is a ITAD - (Internet Telephony Administrative Domain) as defined in RFCs - 3872 and 2871, and as allocated by the IANA in - http://www.iana.org/assignments/trip-parameters. The ITAD is - left intact and not refersed as ENUM requires. To learn more - about ISN please refer to documents at www.freenum.org. - - To complete a ISN lookup on the user part of the Request-URI, - isn_query() is used instead of enum_query(). - - Enum module also implements is_from_user_enum function. This - function does an enum lookup on the from user and returns true - if found, false otherwise. - -1.2. Dependencies - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * No dependencies. - -1.3. Exported Parameters - -1.3.1. domain_suffix (string) - - The domain suffix to be added to the domain name obtained from - the digits of an E164 number. Can be overridden by a parameter - to enum_query. - - Default value is “e164.arpa.” - - Example 1.1. Setting domain_suffix module parameter -modparam("enum", "domain_suffix", "e1234.arpa.") - -1.3.2. tel_uri_params (string) - - A string whose contents is appended to each new tel URI in the - request as tel URI parameters. - -Note - - Currently OpenSIPS does not support tel URIs. This means that - at present tel_uri_params is appended as URI parameters to - every URI. - - Default value is “” - - Example 1.2. Setting tel_uri_params module parameter -modparam("enum", "tel_uri_params", ";npdi") - -1.3.3. i_enum_suffix (string) - - The domain suffix to be used for i_enum_query() lookups. Can be - overridden by a parameter to i_enum_query. - - Default value is “e164.arpa.” - - Example 1.3. Setting i_enum_suffix module parameter -modparam("enum", "i_enum_suffix", "e1234.arpa.") - -1.3.4. isn_suffix (string) - - The domain suffix to be used for isn_query() lookups. Can be - overridden by a parameter to isn_query. - - Default value is “freenum.org.” - - Example 1.4. Setting isn_suffix module parameter -modparam("enum", "isn_suffix", "freenum.org.") - -1.3.5. branchlabel (string) - - This parameter determines which label i_enum_query() will use - to branch off to the infrastructure ENUM tree. - - Default value is “"i"” - - Example 1.5. Setting branchlabel module parameter -modparam("enum", "branchlabel", "i") - -1.3.6. bl_algorithm (string) - - This parameter determines which algorithm i_enum_query() will - use to select the position in the DNS tree where the - infrastructure tree branches off the user ENUM tree. - - If set to "cc", i_enum_query() will always inserts the label at - the country-code level. Examples: i.1.e164.arpa, - i.3.4.e164.arpa, i.2.5.3.e164.arpa - - If set to "txt", i_enum_query() will look for a TXT record at - [branchlabel].[reverse-country-code].[i_enum_suffix] to - indicate after how many digits the label should in inserted. - - Example 1.6. Zone file example -i.1.e164.arpa. IN TXT "4" -9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5 -678 999" - - If set to "ebl", i_enum_query() will look for an EBL (ENUM - Branch Label) record at - [branchlabel].[reverse-country-code].[i_enum_suffix]. See - http://www.ietf.org/internet-drafts/draft-lendl-enum-branch-loc - ation-record-00.txt for a description of that record and the - meaning of the fields. The RR type for the EBL has not been - allocated yet. This version of the code uses 65300. See - resolve.h. - - Example 1.7. Zone file example -i.1.e164.arpa. TYPE65300 \# 14 ( - 04 ; position - 01 69 ; separator - 04 65 31 36 34 04 61 72 70 61 00 ; e164.ar -pa -; ) -9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5 -678 999" - - Default value is “cc” - - Example 1.8. Setting the bl_algorithm module parameter -modparam("enum", "bl_algorithm", "txt") - -1.4. Exported Functions - -1.4.1. enum_query([suffix], [service], [number]) - - The function performs an ENUM query on a given E.164 "number" - (or R-URI username if "number" is missing) and rewrites the - Request-URI with the result of the query. See Overview for more - information. - - Meaning of the parameters is as follows: - * suffix (string, optional) - suffix to be appended to the - domain name, domain_suffix if missing - * service (string, optional) - service string to be used in - the service field - * number (string, optional) - a specific E.164 number packed - as a string on which the ENUM query is performed (if - missing the R-URI username ($rU) will be used). - - This function can be used from REQUEST_ROUTE. - - Example 1.9. enum_query usage -... -# search for "e2u+sip" in freenum.org -enum_query("freenum.org.", , $avp(number)); -... -# search for "e2u+sip" in default tree (configured as parameter) -enum_query(); -... -# search for "e2u+voice:sip" in e164.arpa -enum_query("e164.arpa.", "voice"); -... -# search for service type "sip" or "voice:sip" or "video:sip" -# note the '+' sign in front of the second parameter -enum_query("e164.arpa.", "+sip+voice:sip+video:sip", $avp(number)); -... -# querying for service sip and voice:sip -enum_query("e164.arpa."); -enum_query("e164.arpa.", "voice"); -# or use instead -enum_query("e164.arpa.", "+sip+voice:sip"); -... - -1.4.2. i_enum_query([suffix], [service]) - - The function performs an enum query and rewrites the - Request-URI with the result of the query. This the - Infrastructure-ENUM version of enum_query(). The only - difference to enum_query() is in the calculation of the FQDN - where NAPTR records are looked for. - - Meaning of the parameters is as follows: - * suffix (string, optional) - suffix to be appended to the - domain name, i_enum_suffix if missing - * service (string, optional) - service string to be used in - the service field - - See - ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberle - r-carrier-enum-01.txt for the rationale behind this function. - -1.4.3. isn_query([suffix], [service]) - - The function performs a ISN query and rewrites the Request-URI - with the result of the query. See Overview for more - information. - - Meaning of the parameters is as follows: - * suffix (string, optional) - suffix to be appended to the - domain name, isn_suffix if missing - * service (string, optional) - service string to be used in - the service field - - This function can be used from REQUEST_ROUTE. - - See ftp://www.ietf.org/rfc/rfc3872.txt and - ftp://www.ietf.org/rfc/rfc2871.txt for information regarding - the ITAD part of the ISN string. - - Example 1.10. isn_query usage -... -# search for "e2u+sip" in freenum.org -isn_query("freenum.org."); -... -# search for "e2u+sip" in default tree (configured as parameter) -isn_query(); -... -# search for "e2u+voice:sip" in freenum.org -isn_query("freenum.org.", "voice"); -... - -1.4.4. is_from_user_enum([suffix], [service]) - - Checks if the user part of from URI is found in an enum lookup. - Returns 1 if yes and -1 if not. - - Meaning of the parameters is as follows: - * suffix (string, optional) - suffix to be appended to the - domain name, domain_suffix if missing - * service (string, optional) - service string to be used in - the service field - - This function can be used from REQUEST_ROUTE. - - Example 1.11. is_from_user_enum usage -... -if (is_from_user_enum()) { - .... -}; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Juha Heinanen (@juha-h) 36 14 1681 396 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 29 24 307 97 - 3. Liviu Chircu (@liviuchircu) 20 10 240 375 - 4. Jan Janak (@janakj) 19 14 345 75 - 5. Daniel-Constantin Mierla (@miconda) 14 12 46 55 - 6. Vlad Patrascu (@rvlad-patrascu) 9 3 47 251 - 7. Razvan Crainea (@razvancrainea) 8 6 19 17 - 8. Henning Westerholt (@henningw) 8 3 14 190 - 9. Greg Fausak 7 1 493 30 - 10. Andrei Pelinescu-Onciul 5 3 11 7 - - All remaining contributors: Dan Pascu (@danpascu), Jiri Kuthan - (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Klaus - Darilion, Konstantin Bokarius, Klaus Darilion, Andreas Granig, - Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Dusan - Klinec (@ph4r05). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Sep 2005 - May 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Sep 2019 - 5. Liviu Chircu (@liviuchircu) Sep 2012 - Apr 2019 - 6. Dan Pascu (@danpascu) Apr 2019 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 9. Juha Heinanen (@juha-h) Jan 2003 - Apr 2008 - 10. Daniel-Constantin Mierla (@miconda) Oct 2005 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw), Klaus Darilion, Greg - Fausak, Andreas Granig, Klaus Darilion, Andrei - Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg), Jan Janak - (@janakj). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Dan Pascu - (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Juha Heinanen - (@juha-h), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Greg Fausak, Klaus Darilion, - Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2002-2003 Juha Heinanen diff --git a/modules/enum/README.md b/modules/enum/README.md new file mode 100644 index 00000000000..ce2429de5e8 --- /dev/null +++ b/modules/enum/README.md @@ -0,0 +1,388 @@ +--- +title: "Enum Module" +description: "Enum module implements [i_]enum_query functions that make an enum query based on the user part of the current Request-URI." +--- + +## Admin Guide + + +### Overview + + +Enum module implements [i_]enum_query functions that make an enum query +based on the user part of the current Request-URI. These functions +assume that the user part consists of an international phone number +of the form +decimal-digits, where the number of digits is at +least 2 and at most 15. Out of this number +`enum_query` forms a domain name, +where the digits are in reverse order and separated by dots followed by +domain suffix that by default is "e164.arpa.". For example, +if the user part is +35831234567, the domain +name will be "7.6.5.4.3.2.1.3.8.5.3.e164.arpa.". +`i_enum_query` operates in a similar +fashion. The only difference is that it adds a label (default "i") +to branch off from the default, user-ENUM tree to an infrastructure ENUM tree. + + +After forming the domain name, +`enum_query` queries +DNS for its NAPTR records. From the possible response +`enum_query` chooses those records, +whose flags field has string value "u", and whose services field has +string value "e2u+[service:]sip" or +"e2u+type[:subtype][+type[:subtype]...]" (case is ignored in both +cases), and whose regexp field is of the form !pattern!replacement!. + + +Then `enum_query` sorts the chosen +NAPTR records based on their . After sorting, +`enum_query` replaces the current +Request URI by applying regexp of the most preferred NAPTR record its +user part and appends to the request new branches by applying regexp of +each remaining NAPTR record to the user part of the +current Request URI. If a new URI is a tel URI, +`enum_query` appends to it as tel +URI parameters the value of tel_uri_params module parameter. Finally, +`enum_query` associates a q value +with each new URI based on the of the +corresponding NAPTR record. + + +When using `enum_query` without any +parameters, it searches for NAPTRs with service type "e2u+sip" in the +default enum tree. When using +`enum_query` with a single parameter, +this parameter will be used as enum tree. When using +`enum_query` +with two parameters, the functionality depends on the first letter in +the second parameter. When the first letter is not a '+' sign, the +second parameter will be used to search for NAPTRs with service type +"e2u+parameter:sip". When the second parameter starts with a '+' sign, +the ENUM lookup also supports compound NAPTRs +(e.g. "e2u+voice:sip+video:sip") and searching for multiple service +types within one lookup. Multiple service types must be separated +by a '+' sign. + + +Most of the time you want to route based on the RURI. On rare occasions +you may wish to route based on something else. The function +`enum_pv_query` mimics the behavior +of the `enum_query` function except the +E.164 number in its pseudo variable argument is used for the enum lookup instead of the user +part of the RURI. Obviously the user part of the RURI is still used in the +NAPTR regexp. + + +Enum query returns 1 if the current Request URI was replaced +and -1 if not. + + +In addition to standard ENUM, support for ISN (ITAD Subscriber +Numbers) is provided as well. To allow ISN lookups to resolve, +a different formatting algorithm is expected by the DNS server. +Whereas a ENUM NAPTR record expects a DNS query of the form +9.8.7.6.5.4.3.2.1.suffix, ISN method expects a DNS query of +the form 6.5.1212.suffix. That is, a valid ISN number includes +a prefix of '56' in the example. The rest of the number is a +ITAD (Internet Telephony Administrative Domain) as defined +in RFCs 3872 and 2871, and as allocated by the IANA in +http://www.iana.org/assignments/trip-parameters. The ITAD is +left intact and not refersed as ENUM requires. To learn more +about ISN please refer to documents at www.freenum.org. + + +To complete a ISN lookup on the user part of the Request-URI, +isn_query() is used instead of enum_query(). + + +Enum module also implements is_from_user_enum function. +This function does an enum lookup on the from user and +returns true if found, false otherwise. + + +### Dependencies + + +The module depends on the following modules (in the other words the +listed modules must be loaded before this module): + + +- No dependencies. + + +### Exported Parameters + + +#### domain_suffix (string) + + +The domain suffix to be added to the domain name obtained from +the digits of an E164 number. Can be overridden +by a parameter to enum_query. + + +Default value is "e164.arpa." + + +```opensips title="Setting domain_suffix module parameter" +modparam("enum", "domain_suffix", "e1234.arpa.") +``` + + +#### tel_uri_params (string) + + +A string whose contents is appended to each new tel URI in the +request as tel URI parameters. + + +> [!NOTE] +> Currently OpenSIPS does not support tel URIs. This means that at present +tel_uri_params is appended as URI parameters to every URI. + + +Default value is "" + + +```opensips title="Setting tel_uri_params module parameter" +modparam("enum", "tel_uri_params", ";npdi") +``` + + +#### i_enum_suffix (string) + + +The domain suffix to be used for i_enum_query() lookups. +Can be overridden by a parameter to i_enum_query. + + +Default value is "e164.arpa." + + +```opensips title="Setting i_enum_suffix module parameter" +modparam("enum", "i_enum_suffix", "e1234.arpa.") +``` + + +#### isn_suffix (string) + + +The domain suffix to be used for isn_query() lookups. Can +be overridden by a parameter to isn_query. + + +Default value is "freenum.org." + + +```opensips title="Setting isn_suffix module parameter" +modparam("enum", "isn_suffix", "freenum.org.") +``` + + +#### branchlabel (string) + + +This parameter determines which label i_enum_query() will use +to branch off to the infrastructure ENUM tree. + + +Default value is ""i"" + + +```opensips title="Setting branchlabel module parameter" +modparam("enum", "branchlabel", "i") +``` + + +#### bl_algorithm (string) + + +This parameter determines which algorithm i_enum_query() will use +to select the position in the DNS tree where the infrastructure tree +branches off the user ENUM tree. + + +If set to "cc", i_enum_query() will always inserts the +label at the country-code level. +Examples: i.1.e164.arpa, i.3.4.e164.arpa, i.2.5.3.e164.arpa + + +If set to "txt", i_enum_query() will look for a TXT record at +[branchlabel].[reverse-country-code].[i_enum_suffix] to indicate after how many digits the +label should in inserted. + + +```c title="Zone file example" +i.1.e164.arpa. IN TXT "4" +9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5678 999" +``` + + +If set to "ebl", i_enum_query() will look for an EBL (ENUM Branch Label) record at +[branchlabel].[reverse-country-code].[i_enum_suffix]. See http://www.ietf.org/internet-drafts/draft-lendl-enum-branch-location-record-00.txt for a description of that record and the +meaning of the fields. The RR type for the EBL has not been allocated yet. +This version of the code uses 65300. See resolve.h. + + +```c title="Zone file example" +i.1.e164.arpa. TYPE65300 \# 14 ( + 04 ; position + 01 69 ; separator + 04 65 31 36 34 04 61 72 70 61 00 ; e164.arpa +; ) +9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5678 999" +``` + + +*Default value is "cc"* + + +```opensips title="Setting the bl_algorithm module parameter" +modparam("enum", "bl_algorithm", "txt") +``` + + +### Exported Functions + + +#### enum_query([suffix], [service], [number]) + + +The function performs an ENUM query on a given E.164 "number" (or R-URI +username if "number" is missing) and rewrites the Request-URI with +the result of the query. See [overview](#overview) for more +information. + + +Meaning of the parameters is as follows: + + +- *suffix (string, optional)* - suffix to be appended to the +domain name, [domain suffix](#param_domain_suffix) if missing +- *service (string, optional)* - service string to be used in +the service field +- *number (string, optional)* - a specific +E.164 number packed as a string on which the ENUM query is +performed (if missing the R-URI username ($rU) will be used). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="enum_query usage" +... +# search for "e2u+sip" in freenum.org +enum_query("freenum.org.", , $avp(number)); +... +# search for "e2u+sip" in default tree (configured as parameter) +enum_query(); +... +# search for "e2u+voice:sip" in e164.arpa +enum_query("e164.arpa.", "voice"); +... +# search for service type "sip" or "voice:sip" or "video:sip" +# note the '+' sign in front of the second parameter +enum_query("e164.arpa.", "+sip+voice:sip+video:sip", $avp(number)); +... +# querying for service sip and voice:sip +enum_query("e164.arpa."); +enum_query("e164.arpa.", "voice"); +# or use instead +enum_query("e164.arpa.", "+sip+voice:sip"); +... +``` + + +#### i_enum_query([suffix], [service]) + + +The function performs an enum query and rewrites the Request-URI with +the result of the query. This the Infrastructure-ENUM version of enum_query(). +The only difference to enum_query() is in the calculation of the +FQDN where NAPTR records are looked for. + + +Meaning of the parameters is as follows: + + +- *suffix (string, optional)* - suffix to be appended to the +domain name, [i enum suffix](#param_i_enum_suffix) if missing +- *service (string, optional)* - service string to be used in +the service field + + +See ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberler-carrier-enum-01.txt +for the rationale behind this function. + + +#### isn_query([suffix], [service]) + + +The function performs a ISN query and rewrites the Request-URI with +the result of the query. See [overview](#overview) for more +information. + + +Meaning of the parameters is as follows: + + +- *suffix (string, optional)* - suffix to be appended to the +domain name, [isn suffix](#param_isn_suffix) if missing +- *service (string, optional)* - service string to be used in +the service field + + +This function can be used from REQUEST_ROUTE. + + +See ftp://www.ietf.org/rfc/rfc3872.txt and +ftp://www.ietf.org/rfc/rfc2871.txt for information +regarding the ITAD part of the ISN string. + + +```opensips title="isn_query usage" +... +# search for "e2u+sip" in freenum.org +isn_query("freenum.org."); +... +# search for "e2u+sip" in default tree (configured as parameter) +isn_query(); +... +# search for "e2u+voice:sip" in freenum.org +isn_query("freenum.org.", "voice"); +... +``` + + +#### is_from_user_enum([suffix], [service]) + + +Checks if the user part of from URI +is found in an enum lookup. +Returns 1 if yes and -1 if not. + + +Meaning of the parameters is as follows: + + +- *suffix (string, optional)* - suffix to be appended to the +domain name, [domain suffix](#param_domain_suffix) if missing +- *service (string, optional)* - service string to be used in +the service field + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="is_from_user_enum usage" +... +if (is_from_user_enum()) { + .... +}; +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/enum/doc/contributors.xml b/modules/enum/doc/contributors.xml deleted file mode 100644 index 9317f27fce3..00000000000 --- a/modules/enum/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Juha Heinanen (@juha-h) - 36 - 14 - 1681 - 396 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 29 - 24 - 307 - 97 - - - 3. - Liviu Chircu (@liviuchircu) - 20 - 10 - 240 - 375 - - - 4. - Jan Janak (@janakj) - 19 - 14 - 345 - 75 - - - 5. - Daniel-Constantin Mierla (@miconda) - 14 - 12 - 46 - 55 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 9 - 3 - 47 - 251 - - - 7. - Razvan Crainea (@razvancrainea) - 8 - 6 - 19 - 17 - - - 8. - Henning Westerholt (@henningw) - 8 - 3 - 14 - 190 - - - 9. - Greg Fausak - 7 - 1 - 493 - 30 - - - 10. - Andrei Pelinescu-Onciul - 5 - 3 - 11 - 7 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Jiri Kuthan (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Klaus Darilion, Konstantin Bokarius, Klaus Darilion, Andreas Granig, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Dusan Klinec (@ph4r05). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Sep 2005 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Sep 2019 - - - 5. - Liviu Chircu (@liviuchircu) - Sep 2012 - Apr 2019 - - - 6. - Dan Pascu (@danpascu) - Apr 2019 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 9. - Juha Heinanen (@juha-h) - Jan 2003 - Apr 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Oct 2005 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Klaus Darilion, Greg Fausak, Andreas Granig, Klaus Darilion, Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg), Jan Janak (@janakj). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Juha Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Greg Fausak, Klaus Darilion, Jan Janak (@janakj). -
- -
diff --git a/modules/enum/doc/enum.xml b/modules/enum/doc/enum.xml deleted file mode 100644 index 6e5431b3508..00000000000 --- a/modules/enum/doc/enum.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Enum Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2002-2003 Juha Heinanen - - diff --git a/modules/enum/doc/enum_admin.xml b/modules/enum/doc/enum_admin.xml deleted file mode 100644 index 930a25637b7..00000000000 --- a/modules/enum/doc/enum_admin.xml +++ /dev/null @@ -1,430 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Enum module implements [i_]enum_query functions that make an enum query - based on the user part of the current Request-URI. These functions - assume that the user part consists of an international phone number - of the form +decimal-digits, where the number of digits is at - least 2 and at most 15. Out of this number - enum_query forms a domain name, - where the digits are in reverse order and separated by dots followed by - domain suffix that by default is e164.arpa.. For example, - if the user part is +35831234567, the domain - name will be 7.6.5.4.3.2.1.3.8.5.3.e164.arpa.. - i_enum_query operates in a similar - fashion. The only difference is that it adds a label (default "i") - to branch off from the default, user-ENUM tree to an infrastructure ENUM tree. - - - After forming the domain name, - enum_query queries - DNS for its NAPTR records. From the possible response - enum_query chooses those records, - whose flags field has string value "u", and whose services field has - string value "e2u+[service:]sip" or - "e2u+type[:subtype][+type[:subtype]...]" (case is ignored in both - cases), and whose regexp field is of the form !pattern!replacement!. - - - Then enum_query sorts the chosen - NAPTR records based on their <order, preference>. After sorting, - enum_query replaces the current - Request URI by applying regexp of the most preferred NAPTR record its - user part and appends to the request new branches by applying regexp of - each remaining NAPTR record to the user part of the - current Request URI. If a new URI is a tel URI, - enum_query appends to it as tel - URI parameters the value of tel_uri_params module parameter. Finally, - enum_query associates a q value - with each new URI based on the <order, preference> of the - corresponding NAPTR record. - - - When using enum_query without any - parameters, it searches for NAPTRs with service type "e2u+sip" in the - default enum tree. When using - enum_query with a single parameter, - this parameter will be used as enum tree. When using - enum_query - with two parameters, the functionality depends on the first letter in - the second parameter. When the first letter is not a '+' sign, the - second parameter will be used to search for NAPTRs with service type - "e2u+parameter:sip". When the second parameter starts with a '+' sign, - the ENUM lookup also supports compound NAPTRs - (e.g. "e2u+voice:sip+video:sip") and searching for multiple service - types within one lookup. Multiple service types must be separated - by a '+' sign. - - - Most of the time you want to route based on the RURI. On rare occasions - you may wish to route based on something else. The function - enum_pv_query mimics the behavior - of the enum_query function except the - E.164 number in its pseudo variable argument is used for the enum lookup instead of the user - part of the RURI. Obviously the user part of the RURI is still used in the - NAPTR regexp. - - - Enum query returns 1 if the current Request URI was replaced - and -1 if not. - - - In addition to standard ENUM, support for ISN (ITAD Subscriber - Numbers) is provided as well. To allow ISN lookups to resolve, - a different formatting algorithm is expected by the DNS server. - Whereas a ENUM NAPTR record expects a DNS query of the form - 9.8.7.6.5.4.3.2.1.suffix, ISN method expects a DNS query of - the form 6.5.1212.suffix. That is, a valid ISN number includes - a prefix of '56' in the example. The rest of the number is a - ITAD (Internet Telephony Administrative Domain) as defined - in RFCs 3872 and 2871, and as allocated by the IANA in - http://www.iana.org/assignments/trip-parameters. The ITAD is - left intact and not refersed as ENUM requires. To learn more - about ISN please refer to documents at www.freenum.org. - - - To complete a ISN lookup on the user part of the Request-URI, - isn_query() is used instead of enum_query(). - - - Enum module also implements is_from_user_enum function. - This function does an enum lookup on the from user and - returns true if found, false otherwise. - -
- -
- Dependencies - - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): - - - No dependencies. - - - -
- -
- Exported Parameters -
- <varname>domain_suffix</varname> (string) - - The domain suffix to be added to the domain name obtained from - the digits of an E164 number. Can be overridden - by a parameter to enum_query. - - - Default value is e164.arpa. - - - Setting domain_suffix module parameter - -modparam("enum", "domain_suffix", "e1234.arpa.") - - -
- -
- <varname>tel_uri_params</varname> (string) - - A string whose contents is appended to each new tel URI in the - request as tel URI parameters. - - - - Currently &osips; does not support tel URIs. This means that at present - tel_uri_params is appended as URI parameters to every URI. - - - - Default value is - - - Setting tel_uri_params module parameter - -modparam("enum", "tel_uri_params", ";npdi") - - -
-
- <varname>i_enum_suffix</varname> (string) - - The domain suffix to be used for i_enum_query() lookups. - Can be overridden by a parameter to i_enum_query. - - - Default value is e164.arpa. - - - Setting i_enum_suffix module parameter - -modparam("enum", "i_enum_suffix", "e1234.arpa.") - - -
-
- <varname>isn_suffix</varname> (string) - - The domain suffix to be used for isn_query() lookups. Can - be overridden by a parameter to isn_query. - - - Default value is freenum.org. - - - Setting isn_suffix module parameter - -modparam("enum", "isn_suffix", "freenum.org.") - - -
-
- <varname>branchlabel</varname> (string) - - This parameter determines which label i_enum_query() will use - to branch off to the infrastructure ENUM tree. - - - Default value is "i" - - - Setting branchlabel module parameter - -modparam("enum", "branchlabel", "i") - - -
-
- <varname>bl_algorithm</varname> (string) - - This parameter determines which algorithm i_enum_query() will use - to select the position in the DNS tree where the infrastructure tree - branches off the user ENUM tree. - - - If set to "cc", i_enum_query() will always inserts the - label at the country-code level. - Examples: i.1.e164.arpa, i.3.4.e164.arpa, i.2.5.3.e164.arpa - - - If set to "txt", i_enum_query() will look for a TXT record at - [branchlabel].[reverse-country-code].[i_enum_suffix] to indicate after how many digits the - label should in inserted. - - Zone file example - -i.1.e164.arpa. IN TXT "4" -9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5678 999" - - - - - If set to "ebl", i_enum_query() will look for an EBL (ENUM Branch Label) record at - [branchlabel].[reverse-country-code].[i_enum_suffix]. See http://www.ietf.org/internet-drafts/draft-lendl-enum-branch-location-record-00.txt for a description of that record and the - meaning of the fields. The RR type for the EBL has not been allocated yet. - This version of the code uses 65300. See resolve.h. - - Zone file example - -i.1.e164.arpa. TYPE65300 \# 14 ( - 04 ; position - 01 69 ; separator - 04 65 31 36 34 04 61 72 70 61 00 ; e164.arpa -; ) -9.9.9.8.7.6.5.i.4.3.2.1.e164.arpa. IN NAPTR "NAPTR content for +1 234 5678 999" - - - - - - Default value is cc - - - Setting the bl_algorithm module parameter - -modparam("enum", "bl_algorithm", "txt") - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">enum_query([suffix], [service], [number])</function> - - - The function performs an ENUM query on a given E.164 "number" (or R-URI - username if "number" is missing) and rewrites the Request-URI with - the result of the query. See for more - information. - - Meaning of the parameters is as follows: - - - suffix (string, optional) - suffix to be appended to the - domain name, if missing - - - service (string, optional) - service string to be used in - the service field - - - - number (string, optional) - a specific - E.164 number packed as a string on which the ENUM query is - performed (if missing the R-URI username ($rU) will be used). - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">enum_query</function> usage - -... -# search for "e2u+sip" in freenum.org -enum_query("freenum.org.", , $avp(number)); -... -# search for "e2u+sip" in default tree (configured as parameter) -enum_query(); -... -# search for "e2u+voice:sip" in e164.arpa -enum_query("e164.arpa.", "voice"); -... -# search for service type "sip" or "voice:sip" or "video:sip" -# note the '+' sign in front of the second parameter -enum_query("e164.arpa.", "+sip+voice:sip+video:sip", $avp(number)); -... -# querying for service sip and voice:sip -enum_query("e164.arpa."); -enum_query("e164.arpa.", "voice"); -# or use instead -enum_query("e164.arpa.", "+sip+voice:sip"); -... - - -
- -
- - <function moreinfo="none">i_enum_query([suffix], [service])</function> - - - The function performs an enum query and rewrites the Request-URI with - the result of the query. This the Infrastructure-ENUM version of enum_query(). - The only difference to enum_query() is in the calculation of the - FQDN where NAPTR records are looked for. - - Meaning of the parameters is as follows: - - - suffix (string, optional) - suffix to be appended to the - domain name, if missing - - - service (string, optional) - service string to be used in - the service field - - - - - See ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberler-carrier-enum-01.txt - for the rationale behind this function. - -
- -
- - <function moreinfo="none">isn_query([suffix], [service])</function> - - - The function performs a ISN query and rewrites the Request-URI with - the result of the query. See for more - information. - - Meaning of the parameters is as follows: - - - suffix (string, optional) - suffix to be appended to the - domain name, if missing - - - - service (string, optional) - service string to be used in - the service field - - - - - This function can be used from REQUEST_ROUTE. - - - See ftp://www.ietf.org/rfc/rfc3872.txt and - ftp://www.ietf.org/rfc/rfc2871.txt for information - regarding the ITAD part of the ISN string. - - - <function moreinfo="none">isn_query</function> usage - -... -# search for "e2u+sip" in freenum.org -isn_query("freenum.org."); -... -# search for "e2u+sip" in default tree (configured as parameter) -isn_query(); -... -# search for "e2u+voice:sip" in freenum.org -isn_query("freenum.org.", "voice"); -... - - -
- -
- <function moreinfo="none">is_from_user_enum([suffix], [service])</function> - - Checks if the user part of from URI - is found in an enum lookup. - Returns 1 if yes and -1 if not. - - Meaning of the parameters is as follows: - - - suffix (string, optional) - suffix to be appended to the - domain name, if missing - - - service (string, optional) - service string to be used in - the service field - - - - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">is_from_user_enum</function> usage - -... -if (is_from_user_enum()) { - .... -}; -... - - -
-
-
- diff --git a/modules/event_datagram/README b/modules/event_datagram/README deleted file mode 100644 index e39a6978f0f..00000000000 --- a/modules/event_datagram/README +++ /dev/null @@ -1,214 +0,0 @@ -event_datagram Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. DATAGRAM events syntax - 1.3. DATAGRAM socket syntax - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - 1.6. Exported Functions - 1.7. Example - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. E_PIKE_BLOCKED event - 1.2. UNIX socket - 1.3. UDP socket - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides a UNIX/UDP SOCKET transport - layer implementation for the Event Interface. - -1.2. DATAGRAM events syntax - - The event payload is formated as a JSON-RPC notification, with - the event name as the method field and the event parameters as - the params field. - -1.3. DATAGRAM socket syntax - - There are two types of sockets used by this module, based on - the sockets type. An UNIX socket should follow this syntax: - - ['unix:'] unix_socket_path - - An UDP socket should follow this syntax: - - 'udp:' address ':' port - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.5. Exported Parameters - - No parameter exported by this module. - -1.6. Exported Functions - - No function exported to be used from configuration file. - -1.7. Example - - This is an example of an event raised by the pike module when - it decides an ip should be blocked: - - Example 1.1. E_PIKE_BLOCKED event - -{ - "jsonrpc": "2.0", - "method": "E_PIKE_BLOCKED", - "params": { - "ip": "192.168.2.11" - } -} - - - Example 1.2. UNIX socket - -unix:/tmp/opensips_event.sock - - - Example 1.3. UDP socket - -udp:127.0.0.1:8081 - - -Chapter 2. Frequently Asked Questions - - 2.1. - - Both UNIX and UDP type of socket can be used to notify the - events? - - Yes, you can use the both types. - - 2.2. - - What is the maximum lenght of a datagram event? - - The maximum length of a datagram event is 65457 bytes. - - 2.3. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.4. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.5. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 25 16 854 37 - 2. Liviu Chircu (@liviuchircu) 8 6 12 29 - 3. Vlad Patrascu (@rvlad-patrascu) 8 4 27 140 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 3 1 - 5. Maksym Sobolyev (@sobomax) 4 2 2 3 - 6. Peter Lemenkov (@lemenkov) 4 2 2 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Peter Lemenkov (@lemenkov) Jun 2018 - Aug 2020 - 3. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2020 - 4. Razvan Crainea (@razvancrainea) May 2011 - Sep 2019 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 6. Liviu Chircu (@liviuchircu) Mar 2014 - Nov 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2011 www.opensips-solutions.com diff --git a/modules/event_datagram/README.md b/modules/event_datagram/README.md new file mode 100644 index 00000000000..e5964e36179 --- /dev/null +++ b/modules/event_datagram/README.md @@ -0,0 +1,143 @@ +--- +title: "event_datagram Module" +description: "This is a module which provides a UNIX/UDP SOCKET transport layer implementation for the Event Interface." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides a UNIX/UDP SOCKET transport layer +implementation for the Event Interface. + + +### DATAGRAM events syntax + + +The event payload is formated as a JSON-RPC notification, with the event +name as the *method* field and the event parameters as +the *params* field. + + +### DATAGRAM socket syntax + + +There are two types of sockets used by this module, based on the +sockets type. An UNIX socket should follow this syntax: +*['unix:'] unix_socket_path* + + +An UDP socket should follow this syntax: +*'udp:' address ':' port* + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +No parameter exported by this module. + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Example + + +This is an example of an event raised by the pike module +when it decides an ip should be blocked: + + +```c title="E_PIKE_BLOCKED event" +{ + "jsonrpc": "2.0", + "method": "E_PIKE_BLOCKED", + "params": { + "ip": "192.168.2.11" + } +} +``` + + +```c title="UNIX socket" +unix:/tmp/opensips_event.sock +``` + + +```c title="UDP socket" +udp:127.0.0.1:8081 +``` + + +## Frequently Asked Questions + + +**Q: Both UNIX and UDP type of socket can be +used to notify the events?** + + +Yes, you can use the both types. + + +**Q: What is the maximum lenght of a datagram event?** + + +The maximum length of a datagram event is 65457 bytes. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_datagram/doc/contributors.xml b/modules/event_datagram/doc/contributors.xml deleted file mode 100644 index 9d2df7a1750..00000000000 --- a/modules/event_datagram/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 25 - 16 - 854 - 37 - - - 2. - Liviu Chircu (@liviuchircu) - 8 - 6 - 12 - 29 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 8 - 4 - 27 - 140 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 3 - 1 - - - 5. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - 6. - Peter Lemenkov (@lemenkov) - 4 - 2 - 2 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Peter Lemenkov (@lemenkov) - Jun 2018 - Aug 2020 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2020 - - - 4. - Razvan Crainea (@razvancrainea) - May 2011 - Sep 2019 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2014 - Nov 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/event_datagram/doc/event_datagram.xml b/modules/event_datagram/doc/event_datagram.xml deleted file mode 100644 index 554db6f7cfb..00000000000 --- a/modules/event_datagram/doc/event_datagram.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - event_datagram Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011 &osipssol; - - diff --git a/modules/event_datagram/doc/event_datagram_admin.xml b/modules/event_datagram/doc/event_datagram_admin.xml deleted file mode 100644 index dfd5c9f197a..00000000000 --- a/modules/event_datagram/doc/event_datagram_admin.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module which provides a UNIX/UDP SOCKET transport layer - implementation for the Event Interface. - -
- -
- DATAGRAM events syntax - - The event payload is formated as a JSON-RPC notification, with the event - name as the method field and the event parameters as - the params field. - -
- -
- DATAGRAM socket syntax - - There are two types of sockets used by this module, based on the - sockets type. An UNIX socket should follow this syntax: - ['unix:'] unix_socket_path - - - An UDP socket should follow this syntax: - 'udp:' address ':' port - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters - - No parameter exported by this module. - -
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Example - - This is an example of an event raised by the pike module - when it decides an ip should be blocked: - - - E_PIKE_BLOCKED event - - - - - - - UNIX socket - - -unix:/tmp/opensips_event.sock - - - - - - UDP socket - - -udp:127.0.0.1:8081 - - - - -
-
- diff --git a/modules/event_datagram/doc/event_datagram_faq.xml b/modules/event_datagram/doc/event_datagram_faq.xml deleted file mode 100644 index c44e7176d15..00000000000 --- a/modules/event_datagram/doc/event_datagram_faq.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - &faqguide; - - - - - Both UNIX and UDP type of socket can be - used to notify the events? - - - - - Yes, you can use the both types. - - - - - - What is the maximum lenght of a datagram event? - - - - The maximum length of a datagram event is 65457 bytes. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/event_flatstore/README b/modules/event_flatstore/README deleted file mode 100644 index d8250aa8ebc..00000000000 --- a/modules/event_flatstore/README +++ /dev/null @@ -1,332 +0,0 @@ -event_flatstore Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Flatstore socket syntax - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - - 1.4. External Libraries or Applications - 1.5. Exported Parameters - - 1.5.1. max_open_sockets (integer) - 1.5.2. delimiter (string) - 1.5.3. escape_delimiter (string) - 1.5.4. file_permissions (string) - 1.5.5. suppress_event_name (int) - 1.5.6. rotate_period (int) - 1.5.7. rotate_count (int|string) - 1.5.8. rotate_size (int|string) - 1.5.9. suffix (string) - - 1.6. Exported Functions - 1.7. Exported MI Functions - - 1.7.1. evi_flat_rotate - - 1.8. Exported Events - - 1.8.1. E_FLATSTORE_ROTATION - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set max_open_sockets parameter - 1.2. Set delimiter parameter - 1.3. Enable escaping of ',' with '|' - 1.4. Set file_permissions parameter - 1.5. Set suppress_event_name parameter - 1.6. Set rotate_period parameter - 1.7. Rotate after five billion lines - 1.8. Rotate at 2 GiB - 1.9. Set suffix parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The event_flatstore module provides a logging facility for - different events, triggered through the OpenSIPS Event - Interface, directly from the OpenSIPS script. The module logs - the events along with their parameters in plain text files. - -1.2. Flatstore socket syntax - - flatstore:path_to_file - - Meanings: - * flatstore: - informs the Event Interface that the events - sent to this subscriber should be handled by the - event_flatstore module. - * path_to_file - path to the file where the logged events - will be appended to. The file will be created if it does - not exist. It must be a valid path and not a directory. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.4. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.5. Exported Parameters - -1.5.1. max_open_sockets (integer) - - Defines the maximum number of simultaneously opened files by - the module. If the maximum limit is reached, an error message - will be thrown, and further subscriptions will only be possible - after at least one of the current subscriptions will expire. - - Default value is “100”. - - Example 1.1. Set max_open_sockets parameter -... -modparam("event_flatstore", "max_open_sockets", 200) -... - -1.5.2. delimiter (string) - - Sets the separator between the parameters of the event in the - logging file. - - Default value is “,”. - - Example 1.2. Set delimiter parameter -... -modparam("event_flatstore", "delimiter", ";") -... - -1.5.3. escape_delimiter (string) - - Optional replacement sequence that will be written instead of - the delimiter whenever this character (or sequence) occurs - inside a string parameter. This allows you to keep the log file - parse-friendly even when user data itself may contain delimiter - symbols. - - If set, its length must be exactly equal to the length of - delimiter. - - Default value is “""” (escaping disabled). - - Example 1.3. Enable escaping of ',' with '|' -... -modparam("event_flatstore", "delimiter", ",") -modparam("event_flatstore", "escape_delimiter", "|") -... - -1.5.4. file_permissions (string) - - Sets the permissions for the newly created logs. It expects a - string representation of a octal value. - - Default value is “644”. - - Example 1.4. Set file_permissions parameter -... -modparam("event_flatstore", "file_permissions", "664") -... - -1.5.5. suppress_event_name (int) - - Suppresses the name of the event in the log file. - - Default value is “0/OFF” (the event's name is printed). - - Example 1.5. Set suppress_event_name parameter -... -modparam("event_flatstore", "suppress_event_name", 1) -... - -1.5.6. rotate_period (int) - - When used, it triggers a file auto-rotate. The period is - matched against the absolute time of the machine, can be useful - to trigger auto-rotate every minute, or every hour. - - Default value is “0/OFF” (the file is never auto-rotated) - - Example 1.6. Set rotate_period parameter -... -modparam("event_flatstore", "rotate_period", 60) # rotate every minute -modparam("event_flatstore", "rotate_period", 3660) # rotate every hour -... - - ` - -1.5.7. rotate_count (int|string) - - Defines after how many written lines the log file is rotated. - The value may exceed the 32-bit integer limit; in that case - pass it as a string, e.g. "5000000000". - - Default value is “0/OFF”. - - Example 1.7. Rotate after five billion lines -... -modparam("event_flatstore", "rotate_count", "5000000000") -... - -1.5.8. rotate_size (int|string) - - Sets the maximum size of a file before it is rotated. A size - suffix of “k”, “m” or “g” (multiples of 1024) may be provided. - Very large values can be supplied as strings, e.g. "8589934592" - for 8 GiB. - - Default value is “0/OFF”. - - Example 1.8. Rotate at 2 GiB -... -modparam("event_flatstore", "rotate_size", "2g") -... - -1.5.9. suffix (string) - - Modifies the file that OpenSIPS writes events into by appending - a suffix to the the file specified in the flatstore socket. - - The suffix can contain string formats (i.e. variables mixed - with strings). The path of the resulted file is evaluated when - the first event is raised/written in the file after a reload - happend, or when the rotate_period, if specified, triggers a - rotate. - - This parameter does not affect the matching of the event socket - - the matching will be done exclusively using the flatstore - socket registered. - - Default value is “""” (no suffix is added) - - Example 1.9. Set suffix parameter -... -modparam("event_flatstore", "suffix", "$time(%Y)") -... - -1.6. Exported Functions - - No exported functions to be used in the configuration file. - -1.7. Exported MI Functions - -1.7.1. evi_flat_rotate - - It makes the processes reopen the file specified as a parameter - to the command in order to be compatible with a logrotate - command. If the function is not called after the mv command is - executed, the module will continue to write in the renamed - file. - - Name: evi_flat_rotate - - Parameters: path_to_file - - MI FIFO Command Format: -opensips-cli -x mi evi_flat_rotate _path_to_log_file_ - -1.8. Exported Events - -1.8.1. E_FLATSTORE_ROTATION - - The event is raised every time event_flatstore opens a new log - file (manual evi_flat_rotate, auto-rotate by rotate_period, or - thresholds rotate_count/rotate_size). External apps can - subscribe to monitor log-rotation activity. - - Parameters: - * timestamp – Unix epoch (seconds) when the rotation was - performed. - * reason – one of the strings count, size, period or mi. - * filename – full path of the new log file. - * old_filename – full path of the previous log file, or empty - string if none existed. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 27 16 482 303 - 2. Ionel Cerghit (@ionel-cerghit) 23 13 770 135 - 3. Liviu Chircu (@liviuchircu) 12 9 31 62 - 4. Razvan Crainea (@razvancrainea) 9 7 36 5 - 5. Nick Altmann (@nikbyte) 8 1 612 8 - 6. Eseanu Marius Cristian (@eseanucristian) 7 3 254 9 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 7 4 - 8. Maksym Sobolyev (@sobomax) 5 3 4 4 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Nick Altmann (@nikbyte) May 2025 - May 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2017 - Feb 2023 - 3. Liviu Chircu (@liviuchircu) Jan 2016 - Dec 2021 - 4. Vlad Patrascu (@rvlad-patrascu) Jun 2015 - Jul 2020 - 5. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2018 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionel Cerghit (@ionel-cerghit) Jun 2015 - Jul 2015 - 9. Eseanu Marius Cristian (@eseanucristian) Jun 2015 - Jul 2015 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Nick Altmann (@nikbyte), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Ionel Cerghit - (@ionel-cerghit). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/event_flatstore/README.md b/modules/event_flatstore/README.md new file mode 100644 index 00000000000..ec295a344c9 --- /dev/null +++ b/modules/event_flatstore/README.md @@ -0,0 +1,298 @@ +--- +title: "event_flatstore Module" +description: "The *event_flatstore* module provides a logging facility for different events, triggered through the OpenSIPS Event Interface, directly from the OpenSIPS script." +--- + +## Admin Guide + + +### Overview + + +The *event_flatstore* +module provides a logging facility for different events, +triggered through the OpenSIPS Event Interface, directly from the OpenSIPS +script. The module logs the events along with their parameters in plain +text files. + + +### Flatstore socket syntax + + +*flatstore:path_to_file* + + +Meanings: + + +- *flatstore:* - informs the Event Interface that the +events sent to this subscriber should be handled by the +*event_flatstore* module. +- *path_to_file* - path to the file where the logged events will be appended to. The file will be created if it does not exist. It must be a valid path and not a directory. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### max_open_sockets (integer) + + +Defines the maximum number of simultaneously opened files by the +module. If the maximum limit is reached, an error message will be +thrown, and further subscriptions will only be possible after at +least one of the current subscriptions will expire. + + +*Default value is "100".* + + +```opensips title="Set max_open_sockets parameter" +... +modparam("event_flatstore", "max_open_sockets", 200) +... +``` + + +#### delimiter (string) + + +Sets the separator between the parameters of the event in the logging file. + + +*Default value is ",".* + + +```opensips title="Set delimiter parameter" +... +modparam("event_flatstore", "delimiter", ";") +... +``` + + +#### escape_delimiter (string) + + +Optional replacement sequence that will be written *instead +of* the [`delimiter`](#param_delimiter) +whenever this character (or sequence) occurs inside a string +parameter. +This allows you to keep the log file parse-friendly even when user +data itself may contain delimiter symbols. + + +If set, its length *must be exactly equal* to the +length of `delimiter`. + + +*Default value is """" (escaping disabled).* + + +```opensips title="Enable escaping of ',' with '|'" +... +modparam("event_flatstore", "delimiter", ",") +modparam("event_flatstore", "escape_delimiter", "|") +... + +``` + + +#### file_permissions (string) + + +Sets the permissions for the newly created logs. It +expects a string representation of a octal value. + + +*Default value is "644".* + + +```opensips title="Set file_permissions parameter" +... +modparam("event_flatstore", "file_permissions", "664") +... +``` + + +#### suppress_event_name (int) + + +Suppresses the name of the event in the log file. + + +*Default value is "0/OFF" (the event's name is printed).* + + +```opensips title="Set suppress_event_name parameter" +... +modparam("event_flatstore", "suppress_event_name", 1) +... +``` + + +#### rotate_period (int) + + +When used, it triggers a file auto-rotate. The period is matched +against the absolute time of the machine, can be useful to trigger +auto-rotate every minute, or every hour. + + +*Default value is "0/OFF" (the file is never auto-rotated)* + + +```opensips title="Set rotate_period parameter" +... +modparam("event_flatstore", "rotate_period", 60) # rotate every minute +modparam("event_flatstore", "rotate_period", 3660) # rotate every hour +... +``` + + +#### rotate_count (int|string) + + +Defines after how many written lines the log file is rotated. +The value may exceed the 32-bit integer limit; in that case pass +it *as a string*, e.g. "5000000000". + + +*Default value is "0/OFF".* + + +```opensips title="Rotate after five billion lines" +... +modparam("event_flatstore", "rotate_count", "5000000000") +... + +``` + + +#### rotate_size (int|string) + + +Sets the maximum size of a file before it is rotated. A size +suffix of "k", "m" or "g" +(multiples of 1024) may be provided. +Very large values can be supplied as strings, e.g. +"8589934592" for 8 GiB. + + +*Default value is "0/OFF".* + + +```opensips title="Rotate at 2 GiB" +... +modparam("event_flatstore", "rotate_size", "2g") +... +``` + + +#### suffix (string) + + +Modifies the file that OpenSIPS writes events into by +appending a suffix to the the file specified in the flatstore +*socket*. + + +The suffix can contain string formats (i.e. variables mixed with +strings). The path of the resulted file is evaluated when the first +event is raised/written in the file after a reload happend, or when +the *rotate_period*, if specified, triggers a rotate. + + +This parameter does not affect the matching of the event socket - +the matching will be done exclusively using the flatstore +*socket* registered. + + +*Default value is """" (no suffix is added)* + + +```opensips title="Set suffix parameter" +... +modparam("event_flatstore", "suffix", "$time(%Y)") +... +``` + + +### Exported Functions + + +No exported functions to be used in the configuration file. + + +### Exported MI Functions + + +#### evi_flat_rotate + + +It makes the processes reopen the file specified as a parameter to the command in order to be compatible with a logrotate command. If the function is not called after the mv command is executed, the module will continue to write in the renamed file. + + +Name: *evi_flat_rotate* + + +Parameters: *path_to_file* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi evi_flat_rotate _path_to_log_file_ +``` + + +### Exported Events + + +#### E_FLATSTORE_ROTATION + + +The event is raised every time *event_flatstore* +opens a new log file (manual `evi_flat_rotate`, +auto-rotate by `rotate_period`, or +thresholds `rotate_count`/`rotate_size`). +External apps can subscribe to monitor log-rotation activity. + + +Parameters: + + +- *timestamp* – Unix epoch (seconds) when the +rotation was performed. +- *reason* – one of the strings +*count*, *size*, +*period* or *mi*. +- *filename* – full path of the new log file. +- *old_filename* – full path of the previous +log file, or empty string if none existed. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_flatstore/doc/contributors.xml b/modules/event_flatstore/doc/contributors.xml deleted file mode 100644 index 10c830403dd..00000000000 --- a/modules/event_flatstore/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 27 - 16 - 482 - 303 - - - 2. - Ionel Cerghit (@ionel-cerghit) - 23 - 13 - 770 - 135 - - - 3. - Liviu Chircu (@liviuchircu) - 12 - 9 - 31 - 62 - - - 4. - Razvan Crainea (@razvancrainea) - 9 - 7 - 36 - 5 - - - 5. - Nick Altmann (@nikbyte) - 8 - 1 - 612 - 8 - - - 6. - Eseanu Marius Cristian (@eseanucristian) - 7 - 3 - 254 - 9 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 7 - 4 - - - 8. - Maksym Sobolyev (@sobomax) - 5 - 3 - 4 - 4 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Nick Altmann (@nikbyte) - May 2025 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2017 - Feb 2023 - - - 3. - Liviu Chircu (@liviuchircu) - Jan 2016 - Dec 2021 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Jun 2015 - Jul 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2018 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionel Cerghit (@ionel-cerghit) - Jun 2015 - Jul 2015 - - - 9. - Eseanu Marius Cristian (@eseanucristian) - Jun 2015 - Jul 2015 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Nick Altmann (@nikbyte), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Ionel Cerghit (@ionel-cerghit). -
- -
diff --git a/modules/event_flatstore/doc/event_flatstore.xml b/modules/event_flatstore/doc/event_flatstore.xml deleted file mode 100644 index 4ceb2671397..00000000000 --- a/modules/event_flatstore/doc/event_flatstore.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%docentities; - -]> - - - - event_flatstore Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - diff --git a/modules/event_flatstore/doc/event_flatstore_admin.xml b/modules/event_flatstore/doc/event_flatstore_admin.xml deleted file mode 100644 index 10ccaae6b1e..00000000000 --- a/modules/event_flatstore/doc/event_flatstore_admin.xml +++ /dev/null @@ -1,334 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The event_flatstore - module provides a logging facility for different events, - triggered through the &osips; Event Interface, directly from the &osips; - script. The module logs the events along with their parameters in plain - text files. - -
-
- Flatstore socket syntax - - flatstore:path_to_file - - - Meanings: - - - flatstore: - informs the Event Interface that the - events sent to this subscriber should be handled by the - event_flatstore module. - - - path_to_file - path to the file where the logged events will be appended to. The file will be created if it does not exist. It must be a valid path and not a directory. - - - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- Exported Parameters -
- <varname>max_open_sockets</varname> (integer) - - Defines the maximum number of simultaneously opened files by the - module. If the maximum limit is reached, an error message will be - thrown, and further subscriptions will only be possible after at - least one of the current subscriptions will expire. - - - - Default value is 100. - - - - Set <varname>max_open_sockets</varname> parameter - -... -modparam("event_flatstore", "max_open_sockets", 200) -... - - -
-
- <varname>delimiter</varname> (string) - - Sets the separator between the parameters of the event in the logging file. - - - - Default value is ,. - - - - Set <varname>delimiter</varname> parameter - -... -modparam("event_flatstore", "delimiter", ";") -... - - -
-
- <varname>escape_delimiter</varname> (string) - - Optional replacement sequence that will be written instead - of the delimiter - whenever this character (or sequence) occurs inside a string - parameter. - This allows you to keep the log file parse-friendly even when user - data itself may contain delimiter symbols. - - - If set, its length must be exactly equal to the - length of delimiter. - - - - Default value is "" (escaping disabled). - - - - Enable escaping of ',' with '|' - -... -modparam("event_flatstore", "delimiter", ",") -modparam("event_flatstore", "escape_delimiter", "|") -... - - -
-
- <varname>file_permissions</varname> (string) - - Sets the permissions for the newly created logs. It - expects a string representation of a octal value. - - - - Default value is 644. - - - - Set <varname>file_permissions</varname> parameter - -... -modparam("event_flatstore", "file_permissions", "664") -... - - -
-
- <varname>suppress_event_name</varname> (int) - - Suppresses the name of the event in the log file. - - - - Default value is 0/OFF (the event's name is printed). - - - - Set <varname>suppress_event_name</varname> parameter - -... -modparam("event_flatstore", "suppress_event_name", 1) -... - - -
-
- <varname>rotate_period</varname> (int) - - When used, it triggers a file auto-rotate. The period is matched - against the absolute time of the machine, can be useful to trigger - auto-rotate every minute, or every hour. - - - - Default value is 0/OFF (the file is never auto-rotated) - - - - Set <varname>rotate_period</varname> parameter - -... -modparam("event_flatstore", "rotate_period", 60) # rotate every minute -modparam("event_flatstore", "rotate_period", 3660) # rotate every hour -... - - -`
-
- <varname>rotate_count</varname> (int|string) - - Defines after how many written lines the log file is rotated. - The value may exceed the 32-bit integer limit; in that case pass - it as a string, e.g. "5000000000". - - Default value is 0/OFF. - - Rotate after five billion lines - -... -modparam("event_flatstore", "rotate_count", "5000000000") -... - - -
-
- <varname>rotate_size</varname> (int|string) - - Sets the maximum size of a file before it is rotated. A size - suffix of k, m or g - (multiples of 1024) may be provided. - Very large values can be supplied as strings, e.g. - "8589934592" for 8 GiB. - - Default value is 0/OFF. - - Rotate at 2 GiB - -... -modparam("event_flatstore", "rotate_size", "2g") -... - - -
-
- <varname>suffix</varname> (string) - - Modifies the file that &osips; writes events into by - appending a suffix to the the file specified in the flatstore - socket. - - - The suffix can contain string formats (i.e. variables mixed with - strings). The path of the resulted file is evaluated when the first - event is raised/written in the file after a reload happend, or when - the rotate_period, if specified, triggers a rotate. - - - This parameter does not affect the matching of the event socket - - the matching will be done exclusively using the flatstore - socket registered. - - - - Default value is "" (no suffix is added) - - - - Set <varname>suffix</varname> parameter - -... -modparam("event_flatstore", "suffix", "$time(%Y)") -... - - -
-
-
- Exported Functions - - No exported functions to be used in the configuration file. - -
- -
- Exported MI Functions -
- - <function>evi_flat_rotate</function> - - - It makes the processes reopen the file specified as a parameter to the command in order to be compatible with a logrotate command. If the function is not called after the mv command is executed, the module will continue to write in the renamed file. - - - Name: evi_flat_rotate - - Parameters: path_to_file - - MI FIFO Command Format: - - -opensips-cli -x mi evi_flat_rotate _path_to_log_file_ - -
-
- -
- Exported Events - -
- - <function moreinfo="none">E_FLATSTORE_ROTATION</function> - - - - The event is raised every time event_flatstore - opens a new log file (manual evi_flat_rotate, - auto-rotate by rotate_period, or - thresholds rotate_count/rotate_size). - External apps can subscribe to monitor log-rotation activity. - - - Parameters: - - - timestamp – Unix epoch (seconds) when the - rotation was performed. - - - reason – one of the strings - count, size, - period or mi. - - - filename – full path of the new log file. - - - old_filename – full path of the previous - log file, or empty string if none existed. - - -
-
-
diff --git a/modules/event_kafka/README b/modules/event_kafka/README deleted file mode 100644 index 29d91053b3b..00000000000 --- a/modules/event_kafka/README +++ /dev/null @@ -1,240 +0,0 @@ -event_kafka Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Kafka socket syntax - 1.3. Kafka events syntax - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. broker_id (string) - - 1.6. Exported Functions - - 1.6.1. kafka_publish(broker_id, message, [key], - [report_route]) - - 1.7. Examples - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set broker_id parameter - 1.2. kafka_publish() function usage - 1.3. Kafka socket - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of an Apache Kafka producer. - It serves as a transport backend for the Event Interface and - also provides a stand-alone connector to be used from the - OpenSIPS script in order to publish messages to Kafka brokers. - -1.2. Kafka socket syntax - - 'kafka:' brokers '/' topic ['?' properties] - - Meaning of the socket fields: - * brokers - comma-separated list of the addresses (as - host:port) of the Kafka brokers to connect to. These are - the "bootstrap" servers used by the client to discover the - Kafka cluster. This corresponds to the bootstrap.servers / - metadata.broker.list configuration property. - * topic - Kafka topic used to publish messages to. - * properties - configuration properties to be transparently - passed to the Kafka client library. The syntax is: - 'g.'|'t.' property '=' value ['&' 'g.'|'t.' property '=' - value] ... - The g. or t. prefix before each property name specifies - whether it's a global or topic level property, as - classified by the Kafka library. Documentation for the - supported properties can be found here. - Note that some library properties have the topic. prefix as - part of their name, but still fall under the global - category. - key=callid is an extra property that is not passed to the - Kafka library and is interpreted by OpenSIPS itself. When - enabling this property the record published to Kafka will - also include the Call-ID of the current SIP message as key. - -1.3. Kafka events syntax - - The event payload is formated as a JSON-RPC notification, with - the event name as the method field and the event parameters as - the params field. - - The record published to Kafka will also include the Call-ID of - the current SIP message as key, if the key=callid property is - provided in the event socket. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * none. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * librdkafka-dev - - librdkafka-dev can be installed from the Confluent APT or YUM - repositories. - -1.5. Exported Parameters - -1.5.1. broker_id (string) - - This parameter specifies the configuration for a Kafka broker - (or cluster) that can be used to publish messages directly from - the script, using the kafka_publish() function. - - The format of the parameter is: [ID]kafka_socket, where ID is - an identifier for this broker instance and kafka_socket is a - specification similar to the Kafka socket syntax. - - The key=callid property does not have an effect for brokers - configured through this parameter. - - This parameter can be set multiple times. - - Example 1.1. Set broker_id parameter -... -modparam("event_kafka", "broker_id", "[k1]127.0.0.1:9092/topic1?g.linger -.ms=100&t.acks=all") -... - -1.6. Exported Functions - -1.6.1. kafka_publish(broker_id, message, [key], [report_route]) - - Publishes a message to a Kafka broker (or cluster). As the - actual send operation is done in an asynchronous manner, a - report route may be provided in order to check the message - delivery status. - - Returns 1 if the message was succesfully queued for sending or - -1 otherwise. - - This function can be used from any route. - - The function has the following parameters: - * broker_id (string) - the ID of the Kafka broker (or - cluster). Must be one of the IDs defined through the - broker_id modparam. - * message (string) - the payload of the Kafka message to - publish. - * key (string, optional) - the key of the Kafka record to - publish. - * report_route (string, static, optional) - name of a script - route to be executed when the message delivery status is - available. Information about the message publishing will be - available in this route through the following AVP - variables: - + $avp(kafka_id) - broker ID - + $avp(kafka_status) - delivery status, 0 if succesfull, - -1 othewise - + $avp(kafka_key) - message key - + $avp(kafka_msg) - message payload - - Example 1.2. kafka_publish() function usage - ... - $var(msg) = "my msg content"; - kafka_publish("k1", $var(kmsg), $ci, "kafka_report"); - ... - route[kafka_report] { - xlog("Delivery status: $avp(kafka_status) for broker: $a -vp(kafka_id)\n"); - } - ... - -1.7. Examples - - Example 1.3. Kafka socket - - kafka:127.0.0.1:9092/topic1?t.message.timeout.ms=1000&key=callid - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 26 8 1933 31 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 25 37 - 3. Maksym Sobolyev (@sobomax) 4 2 5 5 - 4. Razvan Crainea (@razvancrainea) 4 2 2 1 - 5. Alexandra Titoc 3 1 5 1 - 6. Ken Rice 3 1 1 1 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Razvan Crainea (@razvancrainea) Jul 2024 - Aug 2025 - 3. Peter Lemenkov (@lemenkov) Jul 2025 - Jul 2025 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) May 2023 - Jun 2024 - 6. Vlad Patrascu (@rvlad-patrascu) Aug 2020 - Jun 2023 - 7. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2020 www.opensips-solutions.com diff --git a/modules/event_kafka/README.md b/modules/event_kafka/README.md new file mode 100644 index 00000000000..caf77057b70 --- /dev/null +++ b/modules/event_kafka/README.md @@ -0,0 +1,184 @@ +--- +title: "event_kafka Module" +description: "This module is an implementation of an [Apache Kafka](https://kafka.apache.org/) producer." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of an +[Apache Kafka](https://kafka.apache.org/) producer. +It serves as a transport backend for the Event Interface and also provides a +stand-alone connector to be used from the OpenSIPS script in order to +publish messages to Kafka brokers. + + +### Kafka socket syntax + + +*'kafka:' brokers '/' topic ['?' properties]* + + +Meaning of the socket fields: + + +- *brokers* - comma-separated list of the addresses (as +host:port) of the Kafka brokers to connect to. These are the "bootstrap" +servers used by the client to discover the Kafka cluster. This +corresponds to the *bootstrap.servers* / +*metadata.broker.list* configuration property. +- *topic* - Kafka topic used to publish messages to. +- *properties* - configuration properties to be +transparently passed to the Kafka client library. The syntax is: +*'g.'|'t.' property '=' value ['&' 'g.'|'t.' property '=' value] ...* +The *g.* or *t.* prefix before +each property name specifies whether it's a global or topic level +property, as classified by the Kafka library. Documentation for the +supported properties can be found +[here](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md). +Note that some library properties have the *topic.* +prefix as part of their name, but still fall under the global category. +*key=callid* is an extra property that is not +passed to the Kafka library and is interpreted by OpenSIPS itself. +When enabling this property the record published to Kafka will also +include the Call-ID of the current SIP message as key. + + +### Kafka events syntax + + +The event payload is formated as a JSON-RPC notification, with the event +name as the *method* field and the event parameters as +the *params* field. + + +The record published to Kafka will also include the Call-ID of the current +SIP message as key, if the *key=callid* property is +provided in the event socket. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *none*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *librdkafka-dev* + + +*librdkafka-dev* can be installed from the Confluent +[APT](https://docs.confluent.io/current/installation/installing_cp/deb-ubuntu.html#get-the-software) or +[YUM](https://docs.confluent.io/current/installation/installing_cp/rhel-centos.html#get-the-software) +repositories. + + +### Exported Parameters + + +#### broker_id (string) + + +This parameter specifies the configuration for a Kafka broker +(or cluster) that can be used to publish messages directly +from the script, using the [kafka publish](#func_kafka_publish) function. + + +The format of the parameter is: *[ID]kafka_socket*, +where *ID* is an identifier for this broker instance and +*kafka_socket* is a specification similar to the +[kafka socket syntax](#kafka_socket_syntax). + + +The *key=callid* property does not have an effect for +brokers configured through this parameter. + + +This parameter can be set multiple times. + + +```opensips title="Set broker_id parameter" +... +modparam("event_kafka", "broker_id", "[k1]127.0.0.1:9092/topic1?g.linger.ms=100&t.acks=all") +... +``` + + +### Exported Functions + + +#### kafka_publish(broker_id, message, [key], [report_route]) + + +Publishes a message to a Kafka broker (or cluster). As the actual +send operation is done in an asynchronous manner, a report route +may be provided in order to check the message delivery status. + + +Returns *1* if the message was succesfully queued +for sending or *-1* otherwise. + + +This function can be used from any route. + + +The function has the following parameters: + + +- *broker_id* (string) - the ID of the Kafka broker +(or cluster). +Must be one of the IDs defined through the +[broker id](#param_broker_id) modparam. +- *message* (string) - the payload of the Kafka +message to publish. +- *key* (string, optional) - the key of the Kafka +record to publish. +- *report_route* (string, static, optional) - +name of a script route to be executed when the message delivery +status is available. Information about the message publishing will +be available in this route through the following AVP variables: + * *$avp(kafka_id)* - broker ID + * *$avp(kafka_status)* - delivery status, 0 if succesfull, -1 othewise + * *$avp(kafka_key)* - message key + * *$avp(kafka_msg)* - message payload + + +```opensips title="kafka_publish() function usage" + ... + $var(msg) = "my msg content"; + kafka_publish("k1", $var(kmsg), $ci, "kafka_report"); + ... + route[kafka_report] { + xlog("Delivery status: $avp(kafka_status) for broker: $avp(kafka_id)\n"); + } + ... + +``` + + +### Examples + + +```c title="Kafka socket" + kafka:127.0.0.1:9092/topic1?t.message.timeout.ms=1000&key=callid +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_kafka/doc/contributors.xml b/modules/event_kafka/doc/contributors.xml deleted file mode 100644 index cae8d842031..00000000000 --- a/modules/event_kafka/doc/contributors.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 26 - 8 - 1933 - 31 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 25 - 37 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - 4. - Razvan Crainea (@razvancrainea) - 4 - 2 - 2 - 1 - - - 5. - Alexandra Titoc - 3 - 1 - 5 - 1 - - - 6. - Ken Rice - 3 - 1 - 1 - 1 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jul 2024 - Aug 2025 - - - 3. - Peter Lemenkov (@lemenkov) - Jul 2025 - Jul 2025 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2023 - Jun 2024 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - Aug 2020 - Jun 2023 - - - 7. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/event_kafka/doc/event_kafka.xml b/modules/event_kafka/doc/event_kafka.xml deleted file mode 100644 index eaecdb98749..00000000000 --- a/modules/event_kafka/doc/event_kafka.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - event_kafka Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2020 &osipssol; - diff --git a/modules/event_kafka/doc/event_kafka_admin.xml b/modules/event_kafka/doc/event_kafka_admin.xml deleted file mode 100644 index 9a2a15acb8c..00000000000 --- a/modules/event_kafka/doc/event_kafka_admin.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of an - Apache Kafka producer. - It serves as a transport backend for the Event Interface and also provides a - stand-alone connector to be used from the OpenSIPS script in order to - publish messages to Kafka brokers. - -
- -
- Kafka socket syntax - - 'kafka:' brokers '/' topic ['?' properties] - - - Meaning of the socket fields: - - - brokers - comma-separated list of the addresses (as - host:port) of the Kafka brokers to connect to. These are the "bootstrap" - servers used by the client to discover the Kafka cluster. This - corresponds to the bootstrap.servers / - metadata.broker.list configuration property. - - - topic - Kafka topic used to publish messages to. - - - properties - configuration properties to be - transparently passed to the Kafka client library. The syntax is: - - 'g.'|'t.' property '=' value ['&' 'g.'|'t.' property '=' value] ... - - - The g. or t. prefix before - each property name specifies whether it's a global or topic level - property, as classified by the Kafka library. Documentation for the - supported properties can be found - here. - - - Note that some library properties have the topic. - prefix as part of their name, but still fall under the global category. - - - key=callid is an extra property that is not - passed to the Kafka library and is interpreted by OpenSIPS itself. - When enabling this property the record published to Kafka will also - include the Call-ID of the current SIP message as key. - - - - -
- -
- Kafka events syntax - - The event payload is formated as a JSON-RPC notification, with the event - name as the method field and the event parameters as - the params field. - - - The record published to Kafka will also include the Call-ID of the current - SIP message as key, if the key=callid property is - provided in the event socket. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - librdkafka-dev - - - - - - librdkafka-dev can be installed from the Confluent - APT or - YUM - repositories. - -
-
- -
- Exported Parameters -
- <varname>broker_id</varname> (string) - - This parameter specifies the configuration for a Kafka broker - (or cluster) that can be used to publish messages directly - from the script, using the function. - - - The format of the parameter is: [ID]kafka_socket, - where ID is an identifier for this broker instance and - kafka_socket is a specification similar to the - . - - - The key=callid property does not have an effect for - brokers configured through this parameter. - - - This parameter can be set multiple times. - - - Set <varname>broker_id</varname> parameter - -... -modparam("event_kafka", "broker_id", "[k1]127.0.0.1:9092/topic1?g.linger.ms=100&t.acks=all") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">kafka_publish(broker_id, message, [key], - [report_route])</function> - - - Publishes a message to a Kafka broker (or cluster). As the actual - send operation is done in an asynchronous manner, a report route - may be provided in order to check the message delivery status. - - - Returns 1 if the message was succesfully queued - for sending or -1 otherwise. - - - This function can be used from any route. - - - The function has the following parameters: - - - - - broker_id (string) - the ID of the Kafka broker - (or cluster). - Must be one of the IDs defined through the - modparam. - - - - - message (string) - the payload of the Kafka - message to publish. - - - - - key (string, optional) - the key of the Kafka - record to publish. - - - - - report_route (string, static, optional) - - name of a script route to be executed when the message delivery - status is available. Information about the message publishing will - be available in this route through the following AVP variables: - - - $avp(kafka_id) - broker ID - - - $avp(kafka_status) - delivery status, - 0 if succesfull, -1 othewise - - - $avp(kafka_key) - message key - - - $avp(kafka_msg) - message payload - - - - - - - <function>kafka_publish()</function> function usage - - ... - $var(msg) = "my msg content"; - kafka_publish("k1", $var(kmsg), $ci, "kafka_report"); - ... - route[kafka_report] { - xlog("Delivery status: $avp(kafka_status) for broker: $avp(kafka_id)\n"); - } - ... - - -
-
- -
- Examples - - Kafka socket - - - kafka:127.0.0.1:9092/topic1?t.message.timeout.ms=1000&key=callid - - - - -
- -
diff --git a/modules/event_rabbitmq/README b/modules/event_rabbitmq/README deleted file mode 100644 index 45091d93c2d..00000000000 --- a/modules/event_rabbitmq/README +++ /dev/null @@ -1,649 +0,0 @@ -event_rabbitmq Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. RabbitMQ events syntax - 1.3. RabbitMQ socket syntax - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. heartbeat (integer) - 1.5.2. connect_timeout (integer) - 1.5.3. use_tls (integer) - 1.5.4. timeout (integer) - 1.5.5. server_id (string) - - 1.6. Exported Functions - - 1.6.1. rabbitmq_publish(server_id, routing_key, - message [, [content_type [, headers, - headers_vals]]]) - - 1.7. Example - 1.8. Installation and Running - - 1.8.1. OpenSIPS config file - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set heartbeat parameter - 1.2. Setting the connect_timeout parameter - 1.3. Set the use_tls parameter - 1.4. Set the timeout parameter - 1.5. Set server_id parameter - 1.6. rabbitmq_publish() function usage - 1.7. E_PIKE_BLOCKED event - 1.8. RabbitMQ socket - 1.9. OpenSIPS config script - sample event_rabbitmq usage - 2.1. Event subscription - 2.2. Event subscription - -Chapter 1. Admin Guide - -1.1. Overview - - RabbitMQ (http://www.rabbitmq.com/) is an open source messaging - server. It's purpose is to manage received messages in queues, - taking advantage of the flexible AMQP protocol. - - This module provides the implementation of a RabbitMQ client - that supports two primary functionalities: - * Event-Driven Messaging: It is used to send AMQP messages to - a RabbitMQ server each time the Event Interface triggers an - event subscribed for. - * General Message Publishing: This module also enables - sending AMQP messages directly to a RabbitMQ server. - Messages can be easily customized according to the AMQP - specifications, as well the RabbitMQ extensions. - -1.2. RabbitMQ events syntax - - The event payload is formated as a JSON-RPC notification, with - the event name as the method field and the event parameters as - the params field. - -1.3. RabbitMQ socket syntax - - 'rabbitmq:' [user[':'password] '@' host [':' port] '/' [params - '?'] routing_key - - Meanings: - * 'rabbitmq:' - informs the Event Interface that the events - sent to this subscriber should be handled by the - event_rabbitmq module. - * user - username used for RabbitMQ server authentication. - The default value is 'guest'. - * password - password used for RabbitMQ server - authentication. The default value is 'guest'. - * host - host name of the RabbitMQ server. - * port - port of the RabbitMQ server. The default value is - '5672'. - * params - extra parameters specified as key[=value], - separated by ';': - + exchange - exchange of the RabbitMQ server. The - default value is ''. - + tls_domain - indicates which TLS domain (as defined - using the tls_mgm module) to use for this connection. - The use_tls module parameter must be enabled. - + persistent - indicates that the message should be - published as persistent delivery_mode=2. This - parameter does not have a value. - * routing_key - this is the routing key used by the AMQP - protocol and it is used to identify the queue where the - event should be sent. - NOTE: if the queue does not exist, this module will not try - to create it. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_mgm if use_tls is enabled. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * librabbitmq-dev - -1.5. Exported Parameters - -1.5.1. heartbeat (integer) - - Enables heartbeat support for the AMQP communication. If the - client does not receive a heartbeat from server within the - specified interval, the socket is automatically closed by the - rabbitmq-client. This prevents OpenSIPS from blocking while - waiting for a response from a dead rabbitmq-server. The value - represents the heartbit interval in seconds. - - Default value is “0 (disabled)”. - - Example 1.1. Set heartbeat parameter -... -modparam("event_rabbitmq", "heartbeat", 3) -... - -1.5.2. connect_timeout (integer) - - The maximally allowed duration (in milliseconds) for the - establishment of a TCP connection with a RabbitMQ server. - - Default value is “500” (milliseconds). - - Example 1.2. Setting the connect_timeout parameter -... -modparam("event_rabbitmq", "connect_timeout", 1000) -... - -1.5.3. use_tls (integer) - - Setting this parameter will allow you to use TLS for broker - connections. In order to enable TLS for a specific connection, - you can use the "tls_domain=dom_name" parameter in the - configuration specified through the RabbitMQ socket syntax. - - When using this parameter, you must also ensure that tls_mgm is - loaded and properly configured. Refer to the the module for - additional info regarding TLS client domains. - - Default value is 0 (not enabled) - - Example 1.3. Set the use_tls parameter -... -modparam("tls_mgm", "client_domain", "rmq") -modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") -modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") -modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") -... -modparam("event_rabbitmq", "use_tls", 1) -... - -1.5.4. timeout (integer) - - Indicates the timeout (in milliseconds) of any command (i.e. - publish) sent to the RabbitMQ server. - - NOTE that this parameter is available only starting with - RabbitMQ library version 0.9.0; setting it when using an - earlier version will have no effect, and the publish command - will run in blocking mode. - - Default value is 0 (no timeout - blocking mode) - - Example 1.4. Set the timeout parameter -... -modparam("event_rabbitmq", "timeout", 1000) # timeout after 1s -... - -1.5.5. server_id (string) - - Specify configuration for a RabbitMQ server. It contains a set - of parameters used to customize the connection to the server, - as well as to the messages sent. The format of the parameter is - [id_name] param1=value1; param2=value2;. The uri parameter is - mandatory. - - This parameter can be set multiple times, for each RabbitMQ - server. - - The following parameters can be used: - * uri - Mandatory parameter - a full amqp URI as described - here. Missing fields in the URI will receive default - values, such as: user: guest, password: guest, host: - localhost, vhost: /, port: 5672. TLS connections are - specified using an amqps URI. - * frames - the maximum size of an AMQP frame. Optional - parameter, default size is 131072. - * retries - the number of retries in case a connection is - down. Optional parameter, default is disabled (do not - retry). - * exchange - exchange used to send AMQP messages to. Optional - parameter, default is "". - * heartbeat - interval in seconds used to send heartbeat - messages. Optional parameter, default is disabled. - * immediate - indicate to the broker that the message MUST be - delivered to a consumer immediately. Optional parameter, - default is not immediate. - * mandatory - indicate to the broker that the message MUST be - routed to a queue. Optional parameter, default is not - mandatory. - * non-persistent - indicates that the message should not be - persistent in case the RabbitMQ server restarts. Optional - parameter, default is persistent. - * tls_domain - indicates which TLS domain (as defined using - the tls_mgm module) to use for this connection. This must - be an amqps URI and the use_tls module parameter must be - enabled. - - Example 1.5. Set server_id parameter -... -# connection to a RabbitMQ server on localhost, default port -modparam("event_rabbitmq", "server_id","[ID1] uri = amqp://127.0.0.1") -... -# connection with a 5 seconds interval for heartbeat messages -modparam("event_rabbitmq", "server_id","[ID2] uri = amqp://127.0.0.1; -heartbeat = 5") -... -# TLS connection -modparam("event_rabbitmq", "server_id","[ID3] uri = amqps://127.0.0.1; t -ls_domain=rmq") -... - -1.6. Exported Functions - -1.6.1. rabbitmq_publish(server_id, routing_key, message [, -[content_type [, headers, headers_vals]]]) - - Sends a publish message to a RabbitMQ server. - - This function also allows you to attach AMQP headers and values - in the AMQP message. This is done by specifying a set of - headers names (in the headers parameter) and the corresponding - values (in the headers_vals parameter). The number of AVP - values in the headers must be the same as the one in the - headers_vals. - - This function can be used from any route. - - The function has the following parameters: - * server_id (string) - the id of the RabbitMQ server. Must be - one of the parameters defined in the server_id modparam. - * routing_key (string) - routing key used to deliver the AMQP - message. - * message (string) - the body of the message. - * content_type (string, optional) - content type of the - message sent. By default it is none. - * headers (string, optional) - an AVP containing the names of - the headers within the AMQP message. If set, headers_vals - parameter must also be specified. - * headers_vals (string, optional) - an AVP containing the - corresponding values of the AMQP headers. If set, headers - parameter must also be specified. - - Example 1.6. rabbitmq_publish() function usage - ... - rabbitmq_publish("ID1", "call", "$fU called $rU"); - ... - rabbitmq_publish("ID1", "call", "{ \'caller\': \'$fU\', - \'callee\; \'$rU\'", "applicatio -n/json"); - ... - $avp(hdr_name) = "caller"; - $avp(hdr_value) = $fU; - $avp(hdr_name) = "callee"; - $avp(hdr_value) = $rU; - rabbitmq_publish("ID2", "call", $rb, , $avp(hdr_name), $avp(hdr_ -value)); - ... - -1.7. Example - - This is an example of an event raised by the pike module when - it decides an ip should be blocked: - - Example 1.7. E_PIKE_BLOCKED event - -{ - "jsonrpc": "2.0", - "method": "E_PIKE_BLOCKED", - "params": { - "ip": "192.168.2.11" - } -} - - - Example 1.8. RabbitMQ socket - - rabbitmq:guest:guest@127.0.0.1:5672/pike - - # same socket can be written as - rabbitmq:127.0.0.1/pike - - # TLS broker connection - rabbitmq:127.0.0.1/tls_domain=rmq?pike - -1.8. Installation and Running - -1.8.1. OpenSIPS config file - - This configuration file presents the usage of the - event_rabbitmq module. In this scenario, a message is sent to a - RabbitMQ server everytime OpenSIPS receives a MESSAGE request. - The parameters passed to the server are the R-URI username and - the message body. - - Example 1.9. OpenSIPS config script - sample event_rabbitmq - usage -... -loadmodule "signaling.so" -loadmodule "sl.so" -loadmodule "tm.so" -loadmodule "rr.so" -loadmodule "maxfwd.so" -loadmodule "usrloc.so" -loadmodule "registrar.so" -loadmodule "textops.so" -loadmodule "uri.so" -loadmodule "acc.so" -loadmodule "event_rabbitmq.so" - -startup_route { - if (!subscribe_event("E_SIP_MESSAGE", "rabbitmq:127.0.0.1/sipmsg -")) { - xlog("L_ERR","cannot the RabbitMQ server to the E_SIP_ME -SSAGE event\n"); - } -} - -route{ - - if (!mf_process_maxfwd_header(10)) { - sl_send_reply(483,"Too Many Hops"); - exit; - } - - if (has_totag()) { - if (loose_route()) { - if (is_method("INVITE")) { - record_route(); - } - route(1); - } else { - if ( is_method("ACK") ) { - if ( t_check_trans() ) { - t_relay(); - exit; - } else { - exit; - } - } - sl_send_reply(404,"Not here"); - } - exit; - } - - if (is_method("CANCEL")) - { - if (t_check_trans()) - t_relay(); - exit; - } - - t_check_trans(); - - if (loose_route()) { - xlog("L_ERR", - "Attempt to route with preloaded Route's [$fu/$tu/$ru/$c -i]"); - if (!is_method("ACK")) - sl_send_reply(403,"Preload Route denied"); - exit; - } - - if (!is_method("REGISTER|MESSAGE")) - record_route(); - - if (!is_myself("$rd")) - { - append_hf("P-hint: outbound\r\n"); - route(1); - } - - if (is_method("PUBLISH")) - { - sl_send_reply(503, "Service Unavailable"); - exit; - } - - - if (is_method("REGISTER")) - { - if (!save("location")) - sl_reply_error(); - - exit; - } - - if ($rU==NULL) { - sl_send_reply(484,"Address Incomplete"); - exit; - } - - if (is_method("MESSAGE")) { - $avp(attrs) = "user"; - $avp(vals) = $rU; - $avp(attrs) = "msg"; - $avp(vals) = $rb; - if (!raise_event("E_SIP_MESSAGE", $avp(attrs), $avp(vals -))) - xlog("L_ERR", "cannot raise E_SIP_MESSAGE event\ -n"); - } - - if (!lookup("location", "method-filtering")) { - switch ($retcode) { - case -1: - case -3: - t_newtran(); - t_reply(404, "Not Found"); - exit; - case -2: - sl_send_reply(405, "Method Not Allowed") -; - exit; - } - } - - route(1); -} - - -route[1] { - if (is_method("INVITE")) { - t_on_failure("1"); - } - - if (!t_relay()) { - sl_reply_error(); - }; - exit; -} - - -failure_route[1] { - if (t_was_cancelled()) { - exit; - } -} - -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - What is the maximum lenght of a AMQP message? - - The maximum length of a datagram event is 16384 bytes. - - 2.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.3. - - What is the vhost used by the AMQP server? - - Currently, the only vhost supported is '/'. - - 2.4. - - How can I set a vhost in the socket? - - This version doesn't support a different vhost. - - 2.5. - - How can I send an event to my RabbitMQ server? - - This module acts as a transport module for the OpenSIPS Event - Interface. Therefore, this module should follow the Event - Interface behavior: - - The first step is to subscribe the RabbitMQ server to the - OpenSIPS Event Interface. This can be done using the - subscribe_event core function: - - Example 2.1. Event subscription -startup_route { - subscribe_event("E_RABBITMQ_EVENT", "rabbitmq:127.0.0.1/queue"); -} - - The next step is to raise the event from the script, using the - raise_event core function: - - Example 2.2. Event subscription -route { - ... - /* decided that an event should be raised */ - raise_event("E_RABBITMQ_EVENT"); - ... -} - - NOTE that the event used above is only to exemplify the usage - from the script. Any event published through the OpenSIPS Event - Interface can be raised using this module. - - 2.6. - - Where can I find more information about RabbitMQ? - - You can find more information about RabbitMQ on their official - website ( http://www.rabbitmq.com/). - - 2.7. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.8. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 114 75 3591 442 - 2. Vlad Patrascu (@rvlad-patrascu) 36 20 1044 412 - 3. Alexandra Titoc 27 3 504 1139 - 4. Liviu Chircu (@liviuchircu) 16 13 41 76 - 5. Ovidiu Sas (@ovidiusas) 15 7 336 290 - 6. Maksym Sobolyev (@sobomax) 10 8 21 21 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 10 10 - 8. Peter Lemenkov (@lemenkov) 5 3 2 3 - 9. Ionut Ionita (@ionutrazvanionita) 4 2 52 25 - 10. franklyfox 4 2 44 5 - - All remaining contributors: Jarrod Baumann (@jarrodb), Eric - Tamme (@etamme), Julián Moreno Patiño, Ken Rice, Walter Doekes - (@wdoekes), Vlad Paiu (@vladpaiu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ovidiu Sas (@ovidiusas) Jun 2015 - Nov 2025 - 2. Razvan Crainea (@razvancrainea) Jan 2017 - Oct 2025 - 3. Ken Rice Sep 2025 - Sep 2025 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jun 2023 - 6. Liviu Chircu (@liviuchircu) Apr 2018 - May 2023 - 7. Maksym Sobolyev (@sobomax) Jul 2017 - Feb 2023 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Aug 2020 - 9. Walter Doekes (@wdoekes) Apr 2019 - Apr 2019 - 10. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2019 - - All remaining contributors: Jarrod Baumann (@jarrodb), Julián - Moreno Patiño, Eric Tamme (@etamme), Ionut Ionita - (@ionutrazvanionita), Vlad Paiu (@vladpaiu), franklyfox. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Alexandra Titoc, Razvan Crainea - (@razvancrainea), Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2011 www.opensips-solutions.com diff --git a/modules/event_rabbitmq/README.md b/modules/event_rabbitmq/README.md new file mode 100644 index 00000000000..bfe67c6ce39 --- /dev/null +++ b/modules/event_rabbitmq/README.md @@ -0,0 +1,432 @@ +--- +title: "event_rabbitmq Module" +description: "*RabbitMQ* ([http://www.rabbitmq.com/](http://www.rabbitmq.com/)) is an open source messaging server." +--- + +## Admin Guide + + +### Overview + + +*RabbitMQ* +([http://www.rabbitmq.com/](http://www.rabbitmq.com/)) +is an open source messaging server. It's purpose is to +manage received messages in queues, taking advantage of +the flexible AMQP protocol. + + +This module provides the implementation of a RabbitMQ client +that supports two primary functionalities: + + +- *Event-Driven Messaging:* +It is used to send AMQP messages to a RabbitMQ server +each time the Event Interface triggers an event subscribed for. +- *General Message Publishing:* +This module also enables sending AMQP messages directly to a RabbitMQ +server. Messages can be easily customized according to the AMQP specifications, +as well the RabbitMQ extensions. + + +### RabbitMQ events syntax + + +The event payload is formated as a JSON-RPC notification, with the event +name as the *method* field and the event parameters as +the *params* field. + + +### RabbitMQ socket syntax + + +*'rabbitmq:' [user[':'password] '@' host [':' port] '/' [params '?'] routing_key* + + +Meanings: + + +- *'rabbitmq:'* - informs the Event Interface that the +events sent to this subscriber should be handled by the +*event_rabbitmq* module. +- *user* - username used for RabbitMQ server +authentication. The default value is 'guest'. +- *password* - password used for RabbitMQ server +authentication. The default value is 'guest'. +- *host* - host name of the RabbitMQ server. +- *port* - port of the RabbitMQ server. The +default value is '5672'. +- *params* - extra parameters specified as +*key[=value]*, separated by ';': + * *exchange* - exchange of the RabbitMQ server. + The default value is ''. + * *tls_domain* - indicates which TLS domain (as + defined using the *tls_mgm* module) to use for + this connection. The [use tls](#param_use_tls) module parameter + must be enabled. + * *persistent* - indicates that the message should be + published as persistent *delivery_mode=2*. This + parameter does not have a value. +- *routing_key* - this is the routing key +used by the AMQP protocol and it is used to identify the queue +where the event should be sent. + +> [!NOTE] +> If the queue does not exist, this module will not +> try to create it. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_mgm* if [use tls](#param_use_tls) is enabled. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *librabbitmq-dev* + + +### Exported Parameters + + +#### heartbeat (integer) + + +Enables heartbeat support for the AMQP communication. If the +client does not receive a heartbeat from server within the +specified interval, the socket is automatically closed by the +rabbitmq-client. This prevents OpenSIPS from blocking while +waiting for a response from a dead rabbitmq-server. The value +represents the heartbit interval in seconds. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set heartbeat parameter" +... +modparam("event_rabbitmq", "heartbeat", 3) +... +``` + + +#### connect_timeout (integer) + + +The maximally allowed duration (in milliseconds) for the establishment +of a TCP connection with a RabbitMQ server. + + +*Default value is "500" (milliseconds).* + + +```opensips title="Setting the connect_timeout parameter" +... +modparam("event_rabbitmq", "connect_timeout", 1000) +... + +``` + + +#### use_tls (integer) + + +Setting this parameter will allow you to use TLS for broker connections. +In order to enable TLS for a specific connection, you can use the +"tls_domain=*dom_name*" parameter in the configuration +specified through the [socket syntax](#rabbitmq_socket_syntax). + + +When using this parameter, you must also ensure that +*tls_mgm* is loaded and properly configured. Refer to +the the module for additional info regarding TLS client domains. + + +*Default value is **0** (not enabled)* + + +```opensips title="Set the use_tls parameter" +... +modparam("tls_mgm", "client_domain", "rmq") +modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") +modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") +modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") +... +modparam("event_rabbitmq", "use_tls", 1) +... +``` + + +#### timeout (integer) + + +Indicates the timeout (in milliseconds) of any command (i.e. publish) +sent to the RabbitMQ server. + + +> [!NOTE] +> That this parameter is available only starting with +> RabbitMQ library version *0.9.0*; setting it when using an +> earlier version will have no effect, and the publish command will run in +> blocking mode. + + +*Default value is **0** (no timeout - blocking mode)* + + +```opensips title="Set the timeout parameter" +... +modparam("event_rabbitmq", "timeout", 1000) # timeout after 1s +... +``` + + +#### server_id (string) + + +Specify configuration for a RabbitMQ server. It contains a set +of parameters used to customize the connection to the server, +as well as to the messages sent. The format of the parameter is +*[id_name] param1=value1; param2=value2;*. +The *uri* parameter is mandatory. + + +This parameter can be set multiple times, for each RabbitMQ +server. + + +The following parameters can be used: + + +- *uri* - Mandatory parameter - a full +*amqp* URI as described +[here](https://www.rabbitmq.com/uri-spec.html). +Missing fields in the URI will receive default values, +such as: *user: guest*, +*password: guest*, +*host: localhost*, +*vhost: /*, +*port: 5672*. TLS connections are specified +using an *amqps* URI. +- *frames* - the maximum size of an AMQP +frame. Optional parameter, default size is 131072. +- *retries* - the number of retries in case +a connection is down. Optional parameter, default is disabled +(do not retry). +- *exchange* - exchange used to send AMQP +messages to. Optional parameter, default is *""*. +- *heartbeat* - interval in seconds used +to send heartbeat messages. Optional parameter, default is +disabled. +- *immediate* - indicate to the broker that +the message MUST be delivered to a consumer immediately. +Optional parameter, default is not immediate. +- *mandatory* - indicate to the broker that +the message MUST be routed to a queue. Optional parameter, +default is not mandatory. +- *non-persistent* - indicates that the +message should not be persistent in case the RabbitMQ +server restarts. Optional parameter, default is persistent. +- *tls_domain* - indicates which TLS domain (as +defined using the *tls_mgm* module) to use for +this connection. This must be an *amqps* URI and the +[use tls](#param_use_tls) module parameter must be enabled. + + +```opensips title="Set server_id parameter" +... +# connection to a RabbitMQ server on localhost, default port +modparam("event_rabbitmq", "server_id","[ID1] uri = amqp://127.0.0.1") +... +# connection with a 5 seconds interval for heartbeat messages +modparam("event_rabbitmq", "server_id","[ID2] uri = amqp://127.0.0.1; +heartbeat = 5") +... +# TLS connection +modparam("event_rabbitmq", "server_id","[ID3] uri = amqps://127.0.0.1; tls_domain=rmq") +... + +``` + + +### Exported Functions + + +#### rabbitmq_publish(server_id, routing_key, message [, [content_type [, headers, headers_vals]]]) + + +Sends a publish message to a RabbitMQ server. + + +This function also allows you to attach AMQP headers and values +in the AMQP message. This is done by specifying a set of headers +names (in the *headers* parameter) and the +corresponding values (in the *headers_vals* +parameter). The number of AVP values in the +*headers* must be the same as the one in the +*headers_vals*. + + +This function can be used from any route. + + +The function has the following parameters: + + +- *server_id* (string) - the id of the RabbitMQ server. +Must be one of the parameters defined in the +*server_id* modparam. +- *routing_key* (string) - routing key used to +deliver the AMQP message. +- *message* (string) - the body of the message. +- *content_type* (string, optional) - content type +of the message sent. By default it is *none*. +- *headers* (string, optional) - an AVP containing +the names of the headers within the AMQP message. If set, +*headers_vals* parameter must also be specified. +- *headers_vals* (string, optional) - an AVP containing +the corresponding values of the AMQP headers. If set, +*headers* parameter must also be specified. + + +```opensips title="rabbitmq_publish() function usage" + ... + rabbitmq_publish("ID1", "call", "$fU called $rU"); + ... + rabbitmq_publish("ID1", "call", "{ \'caller\': \'$fU\', + \'callee\; \'$rU\'", "application/json"); + ... + $avp(hdr_name) = "caller"; + $avp(hdr_value) = $fU; + $avp(hdr_name) = "callee"; + $avp(hdr_value) = $rU; + rabbitmq_publish("ID2", "call", $rb, , $avp(hdr_name), $avp(hdr_value)); + ... + +``` + + +### Example + + +This is an example of an event raised by the pike module +when it decides an ip should be blocked: + + +```c title="E_PIKE_BLOCKED event" +{ + "jsonrpc": "2.0", + "method": "E_PIKE_BLOCKED", + "params": { + "ip": "192.168.2.11" + } +} +``` + + +```c title="RabbitMQ socket" +rabbitmq:guest:guest@127.0.0.1:5672/pike + +# same socket can be written as +rabbitmq:127.0.0.1/pike + +# TLS broker connection +rabbitmq:127.0.0.1/tls_domain=rmq?pike +``` + + +## Samples + +[samples](./samples/samples.md "include") + + +## Frequently Asked Questions + + +**Q: What is the maximum lenght of a AMQP message?** + + +The maximum length of a datagram event is 16384 bytes. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: What is the vhost used by the AMQP server?** + + +Currently, the only vhost supported is *'/'*. + + +**Q: How can I set a vhost in the socket?** + + +This version doesn't support a different vhost. + + +**Q: How can I send an event to my RabbitMQ server?** + + +This module acts as a transport module for the OpenSIPS +Event Interface. Therefore, this module should follow the +Event Interface behavior: + +The first step is to subscribe the RabbitMQ server to +the OpenSIPS Event Interface. This can be done using the +*subscribe_event* core function: + +The next step is to raise the event from the script, +using the *raise_event* core function: + +NOTE that the event used above is only to exemplify the +usage from the script. Any event published through the +OpenSIPS Event Interface can be raised using this module. + + +**Q: Where can I find more information about RabbitMQ?** + + +You can find more information about RabbitMQ on +their official website +([http://www.rabbitmq.com/](http://www.rabbitmq.com/)). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_rabbitmq/doc/contributors.xml b/modules/event_rabbitmq/doc/contributors.xml deleted file mode 100644 index 7b962e84c72..00000000000 --- a/modules/event_rabbitmq/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 114 - 75 - 3591 - 442 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 36 - 20 - 1044 - 412 - - - 3. - Alexandra Titoc - 27 - 3 - 504 - 1139 - - - 4. - Liviu Chircu (@liviuchircu) - 16 - 13 - 41 - 76 - - - 5. - Ovidiu Sas (@ovidiusas) - 15 - 7 - 336 - 290 - - - 6. - Maksym Sobolyev (@sobomax) - 10 - 8 - 21 - 21 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 10 - 10 - - - 8. - Peter Lemenkov (@lemenkov) - 5 - 3 - 2 - 3 - - - 9. - Ionut Ionita (@ionutrazvanionita) - 4 - 2 - 52 - 25 - - - 10. - franklyfox - 4 - 2 - 44 - 5 - - - -
-All remaining contributors: Jarrod Baumann (@jarrodb), Eric Tamme (@etamme), Julián Moreno Patiño, Ken Rice, Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ovidiu Sas (@ovidiusas) - Jun 2015 - Nov 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jan 2017 - Oct 2025 - - - 3. - Ken Rice - Sep 2025 - Sep 2025 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jun 2023 - - - 6. - Liviu Chircu (@liviuchircu) - Apr 2018 - May 2023 - - - 7. - Maksym Sobolyev (@sobomax) - Jul 2017 - Feb 2023 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Aug 2020 - - - 9. - Walter Doekes (@wdoekes) - Apr 2019 - Apr 2019 - - - 10. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2019 - - - -
-All remaining contributors: Jarrod Baumann (@jarrodb), Julián Moreno Patiño, Eric Tamme (@etamme), Ionut Ionita (@ionutrazvanionita), Vlad Paiu (@vladpaiu), franklyfox. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Alexandra Titoc, Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/event_rabbitmq/doc/event_rabbitmq.xml b/modules/event_rabbitmq/doc/event_rabbitmq.xml deleted file mode 100644 index f2c6403f7c9..00000000000 --- a/modules/event_rabbitmq/doc/event_rabbitmq.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - event_rabbitmq Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011 &osipssol; - - diff --git a/modules/event_rabbitmq/doc/event_rabbitmq_admin.xml b/modules/event_rabbitmq/doc/event_rabbitmq_admin.xml deleted file mode 100644 index 4389675417d..00000000000 --- a/modules/event_rabbitmq/doc/event_rabbitmq_admin.xml +++ /dev/null @@ -1,499 +0,0 @@ - - - - - &adminguide; - -
- Overview - - RabbitMQ - (http://www.rabbitmq.com/) - is an open source messaging server. It's purpose is to - manage received messages in queues, taking advantage of - the flexible AMQP protocol. - - - - This module provides the implementation of a RabbitMQ client - that supports two primary functionalities: - - - - - Event-Driven Messaging: - It is used to send AMQP messages to a RabbitMQ server - each time the Event Interface triggers an event subscribed for. - - - - General Message Publishing: - This module also enables sending AMQP messages directly to a RabbitMQ - server. Messages can be easily customized according to the AMQP specifications, - as well the RabbitMQ extensions. - - - - - - -
- -
- RabbitMQ events syntax - - The event payload is formated as a JSON-RPC notification, with the event - name as the method field and the event parameters as - the params field. - -
- -
- RabbitMQ socket syntax - - 'rabbitmq:' [user[':'password] '@' host [':' port] '/' [params '?'] routing_key - - - Meanings: - - - 'rabbitmq:' - informs the Event Interface that the - events sent to this subscriber should be handled by the - event_rabbitmq module. - - - user - username used for RabbitMQ server - authentication. The default value is 'guest'. - - - password - password used for RabbitMQ server - authentication. The default value is 'guest'. - - - host - host name of the RabbitMQ server. - - - port - port of the RabbitMQ server. The - default value is '5672'. - - - params - extra parameters specified as - key[=value], separated by ';': - - - exchange - exchange of the RabbitMQ server. - The default value is ''. - - - tls_domain - indicates which TLS domain (as - defined using the tls_mgm module) to use for - this connection. The module parameter - must be enabled. - - - persistent - indicates that the message should be - published as persistent delivery_mode=2. This - parameter does not have a value. - - - - - routing_key - this is the routing key - used by the AMQP protocol and it is used to identify the queue - where the event should be sent. - NOTE: if the queue does not exist, this module will not - try to create it. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_mgm if is enabled. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - librabbitmq-dev - - - - -
-
- -
- Exported Parameters -
- <varname>heartbeat</varname> (integer) - - Enables heartbeat support for the AMQP communication. If the - client does not receive a heartbeat from server within the - specified interval, the socket is automatically closed by the - rabbitmq-client. This prevents OpenSIPS from blocking while - waiting for a response from a dead rabbitmq-server. The value - represents the heartbit interval in seconds. - - - - Default value is 0 (disabled). - - - - Set <varname>heartbeat</varname> parameter - -... -modparam("event_rabbitmq", "heartbeat", 3) -... - - -
-
- <varname>connect_timeout</varname> (integer) - - The maximally allowed duration (in milliseconds) for the establishment - of a TCP connection with a RabbitMQ server. - - - - Default value is 500 (milliseconds). - - - - Setting the <varname>connect_timeout</varname> parameter - -... -modparam("event_rabbitmq", "connect_timeout", 1000) -... - - -
- -
- <varname>use_tls</varname> (integer) - - Setting this parameter will allow you to use TLS for broker connections. - In order to enable TLS for a specific connection, you can use the - "tls_domain=dom_name" parameter in the configuration - specified through the . - - - When using this parameter, you must also ensure that - tls_mgm is loaded and properly configured. Refer to - the the module for additional info regarding TLS client domains. - - - - Default value is 0 (not enabled) - - - - Set the <varname>use_tls</varname> parameter - -... -modparam("tls_mgm", "client_domain", "rmq") -modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") -modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") -modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") -... -modparam("event_rabbitmq", "use_tls", 1) -... - - -
- -
- <varname>timeout</varname> (integer) - - Indicates the timeout (in milliseconds) of any command (i.e. publish) - sent to the RabbitMQ server. - - - NOTE that this parameter is available only starting with - RabbitMQ library version 0.9.0; setting it when using an - earlier version will have no effect, and the publish command will run in - blocking mode. - - - - Default value is 0 (no timeout - blocking mode) - - - - Set the <varname>timeout</varname> parameter - -... -modparam("event_rabbitmq", "timeout", 1000) # timeout after 1s -... - - -
- -
- <varname>server_id</varname> (string) - - Specify configuration for a RabbitMQ server. It contains a set - of parameters used to customize the connection to the server, - as well as to the messages sent. The format of the parameter is - [id_name] param1=value1; param2=value2;. - The uri parameter is mandatory. - - - This parameter can be set multiple times, for each RabbitMQ - server. - - - The following parameters can be used: - - - - uri - Mandatory parameter - a full - amqp URI as described - here. - Missing fields in the URI will receive default values, - such as: user: guest, - password: guest, - host: localhost, - vhost: /, - port: 5672. TLS connections are specified - using an amqps URI. - - - - - frames - the maximum size of an AMQP - frame. Optional parameter, default size is 131072. - - - - - retries - the number of retries in case - a connection is down. Optional parameter, default is disabled - (do not retry). - - - - - exchange - exchange used to send AMQP - messages to. Optional parameter, default is "". - - - - - heartbeat - interval in seconds used - to send heartbeat messages. Optional parameter, default is - disabled. - - - - - immediate - indicate to the broker that - the message MUST be delivered to a consumer immediately. - Optional parameter, default is not immediate. - - - - - mandatory - indicate to the broker that - the message MUST be routed to a queue. Optional parameter, - default is not mandatory. - - - - - non-persistent - indicates that the - message should not be persistent in case the RabbitMQ - server restarts. Optional parameter, default is persistent. - - - - - tls_domain - indicates which TLS domain (as - defined using the tls_mgm module) to use for - this connection. This must be an amqps URI and the - module parameter must be enabled. - - - - - - Set <varname>server_id</varname> parameter - -... -# connection to a RabbitMQ server on localhost, default port -modparam("event_rabbitmq", "server_id","[ID1] uri = amqp://127.0.0.1") -... -# connection with a 5 seconds interval for heartbeat messages -modparam("event_rabbitmq", "server_id","[ID2] uri = amqp://127.0.0.1; -heartbeat = 5") -... -# TLS connection -modparam("event_rabbitmq", "server_id","[ID3] uri = amqps://127.0.0.1; tls_domain=rmq") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">rabbitmq_publish(server_id, routing_key, message - [, [content_type [, headers, headers_vals]]])</function> - - - Sends a publish message to a RabbitMQ server. - - - This function also allows you to attach AMQP headers and values - in the AMQP message. This is done by specifying a set of headers - names (in the headers parameter) and the - corresponding values (in the headers_vals - parameter). The number of AVP values in the - headers must be the same as the one in the - headers_vals. - - - This function can be used from any route. - - - The function has the following parameters: - - - - - server_id (string) - the id of the RabbitMQ server. - Must be one of the parameters defined in the - server_id modparam. - - - - - routing_key (string) - routing key used to - deliver the AMQP message. - - - - - message (string) - the body of the message. - - - - - content_type (string, optional) - content type - of the message sent. By default it is none. - - - - - headers (string, optional) - an AVP containing - the names of the headers within the AMQP message. If set, - headers_vals parameter must also be specified. - - - - - headers_vals (string, optional) - an AVP containing - the corresponding values of the AMQP headers. If set, - headers parameter must also be specified. - - - - - <function>rabbitmq_publish()</function> function usage - - ... - rabbitmq_publish("ID1", "call", "$fU called $rU"); - ... - rabbitmq_publish("ID1", "call", "{ \'caller\': \'$fU\', - \'callee\; \'$rU\'", "application/json"); - ... - $avp(hdr_name) = "caller"; - $avp(hdr_value) = $fU; - $avp(hdr_name) = "callee"; - $avp(hdr_value) = $rU; - rabbitmq_publish("ID2", "call", $rb, , $avp(hdr_name), $avp(hdr_value)); - ... - - -
-
- -
- Example - - This is an example of an event raised by the pike module - when it decides an ip should be blocked: - - - E_PIKE_BLOCKED event - - - - - - - RabbitMQ socket - - - rabbitmq:guest:guest@127.0.0.1:5672/pike - - # same socket can be written as - rabbitmq:127.0.0.1/pike - - # TLS broker connection - rabbitmq:127.0.0.1/tls_domain=rmq?pike - - - -
-
- Installation and Running -
- &osips; config file - - This configuration file presents the usage of the event_rabbitmq - module. In this scenario, a message is sent to a RabbitMQ server - everytime &osips; receives a MESSAGE request. The parameters - passed to the server are the R-URI username and the message - body. - - - &osips; config script - sample event_rabbitmq usage - -... -&rabbitmqcfg; -... - - -
-
-
- diff --git a/modules/event_rabbitmq/doc/event_rabbitmq_faq.xml b/modules/event_rabbitmq/doc/event_rabbitmq_faq.xml deleted file mode 100644 index cc7b5ddef48..00000000000 --- a/modules/event_rabbitmq/doc/event_rabbitmq_faq.xml +++ /dev/null @@ -1,149 +0,0 @@ - - - - - &faqguide; - - - - What is the maximum lenght of a AMQP message? - - - - The maximum length of a datagram event is 16384 bytes. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - What is the vhost used by the AMQP server? - - - - Currently, the only vhost supported is '/'. - - - - - - How can I set a vhost in the socket? - - - - This version doesn't support a different vhost. - - - - - - How can I send an event to my RabbitMQ server? - - - - This module acts as a transport module for the OpenSIPS - Event Interface. Therefore, this module should follow the - Event Interface behavior: - - - The first step is to subscribe the RabbitMQ server to - the OpenSIPS Event Interface. This can be done using the - subscribe_event core function: - - - - Event subscription - -startup_route { - subscribe_event("E_RABBITMQ_EVENT", "rabbitmq:127.0.0.1/queue"); -} - - - - The next step is to raise the event from the script, - using the raise_event core function: - - - Event subscription - -route { - ... - /* decided that an event should be raised */ - raise_event("E_RABBITMQ_EVENT"); - ... -} - - - - NOTE that the event used above is only to exemplify the - usage from the script. Any event published through the - OpenSIPS Event Interface can be raised using this module. - - - - - - - Where can I find more information about RabbitMQ? - - - - You can find more information about RabbitMQ on - their official website - ( - http://www.rabbitmq.com/). - - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/event_rabbitmq/event_rabbitmq.c b/modules/event_rabbitmq/event_rabbitmq.c index f2e6d73df41..cac53964efe 100644 --- a/modules/event_rabbitmq/event_rabbitmq.c +++ b/modules/event_rabbitmq/event_rabbitmq.c @@ -336,12 +336,15 @@ static inline int dupl_string(str* dst, const char* begin, const char* end) return -1; } - if (un_escape(&tmp, dst) < 0) + if (un_escape(&tmp, dst) < 0) { + shm_free(dst->s); + dst->s = NULL; + dst->len = 0; return -1; + } /* NULL-terminate the string */ dst->s[dst->len] = 0; - dst->len++; return 0; } @@ -398,6 +401,8 @@ static evi_reply_sock* rmq_parse(str socket) st = ST_HOST; if (dupl_string(&tmp, begin, socket.s + i)) goto err; param->conn.uri.user = tmp.s; + tmp.s = NULL; + tmp.len = 0; begin = socket.s + i + 1; param->conn.flags |= RMQ_PARAM_USER; break; @@ -427,6 +432,8 @@ static evi_reply_sock* rmq_parse(str socket) if (dupl_string(&tmp, begin, socket.s + i) < 0) goto err; param->conn.uri.password = tmp.s; + tmp.s = NULL; + tmp.len = 0; param->conn.flags |= RMQ_PARAM_PASS; begin = socket.s + i + 1; break; @@ -504,13 +511,14 @@ static evi_reply_sock* rmq_parse(str socket) goto err; param->conn.exchange.bytes = tmp.s; param->conn.exchange.len = tmp.len; + tmp.s = NULL; + tmp.len = 0; param->conn.flags |= RMQ_PARAM_EKEY; } else if (it->s.len > RMQ_TLS_DOM_LEN && !memcmp(it->s.s, RMQ_TLS_DOM_S, RMQ_TLS_DOM_LEN)) { if (dupl_string(¶m->conn.tls_dom_name, it->s.s+RMQ_TLS_DOM_LEN, it->s.s + it->s.len) < 0) goto err; - param->conn.tls_dom_name.len--; param->conn.flags |= RMQ_PARAM_TLS; } else if (it->s.len == RMQ_PERSISTENT_LEN && !memcmp(it->s.s, RMQ_PERSISTENT_S, RMQ_PERSISTENT_LEN)) { @@ -552,11 +560,11 @@ static evi_reply_sock* rmq_parse(str socket) sock->flags |= EVI_PORT; } if (!(param->conn.flags & RMQ_PARAM_USER) || !param->conn.uri.user) { - param->conn.uri.user = shm_malloc(rmq_static_holder.len); + param->conn.uri.user = shm_malloc(rmq_static_holder.len + 1); if (!param->conn.uri.user) { goto err; } - memcpy(param->conn.uri.user, rmq_static_holder.s, rmq_static_holder.len); + memcpy(param->conn.uri.user, rmq_static_holder.s, rmq_static_holder.len + 1); param->conn.uri.password = param->conn.uri.user; param->conn.flags |= RMQ_PARAM_USER|RMQ_PARAM_PASS; } @@ -654,21 +662,21 @@ static str rmq_print(evi_reply_sock *sock) param = sock->params; if (param->conn.flags & RMQ_PARAM_USER) { - DO_PRINT(param->conn.uri.user, strlen(param->conn.uri.user) - 1 /* skip 0 */); + DO_PRINT(param->conn.uri.user, strlen(param->conn.uri.user)); DO_PRINT("@", 1); } if (sock->flags & EVI_ADDRESS) - DO_PRINT(sock->address.s, sock->address.len - 1); + DO_PRINT(sock->address.s, sock->address.len); DO_PRINT("/", 1); /* needs to be changed if it can print a key without RMQ_PARAM_RKEY */ - + if (param->conn.flags & RMQ_PARAM_EKEY) { - DO_PRINT(param->conn.exchange.bytes, param->conn.exchange.len - 1); + DO_PRINT(param->conn.exchange.bytes, param->conn.exchange.len); DO_PRINT("?", 1); } if (param->conn.flags & RMQF_MAND) { - DO_PRINT(param->routing_key.s, param->routing_key.len - 1); + DO_PRINT(param->routing_key.s, param->routing_key.len); } end: return rmq_print_s; diff --git a/modules/event_rabbitmq/rabbitmq_send.c b/modules/event_rabbitmq/rabbitmq_send.c index e5579f76df0..90ac744c8fa 100644 --- a/modules/event_rabbitmq/rabbitmq_send.c +++ b/modules/event_rabbitmq/rabbitmq_send.c @@ -145,6 +145,7 @@ void rmq_free_param(rmq_params_t *rmqp) rmqp->conn.uri.user != rmq_static_holder.s) shm_free(rmqp->conn.uri.user); if ((rmqp->conn.flags & RMQ_PARAM_PASS) && rmqp->conn.uri.password && + rmqp->conn.uri.password != rmqp->conn.uri.user && rmqp->conn.uri.password != rmq_static_holder.s) shm_free(rmqp->conn.uri.password); if ((rmqp->conn.flags & RMQF_MAND) && rmqp->routing_key.s) diff --git a/modules/event_rabbitmq/doc/event_rabbitmq.cfg b/modules/event_rabbitmq/samples/event_rabbitmq.cfg similarity index 100% rename from modules/event_rabbitmq/doc/event_rabbitmq.cfg rename to modules/event_rabbitmq/samples/event_rabbitmq.cfg diff --git a/modules/event_rabbitmq/samples/samples.md b/modules/event_rabbitmq/samples/samples.md new file mode 100644 index 00000000000..7aa1506dd2b --- /dev/null +++ b/modules/event_rabbitmq/samples/samples.md @@ -0,0 +1,10 @@ +### OpenSIPS Config Script - EVENT_RABBITMQ usage + +This configuration file presents the usage of the event_rabbitmq +module. In this scenario, a message is sent to a RabbitMQ server +everytime OpenSIPS receives a MESSAGE request. The parameters +passed to the server are the R-URI username and the message +body. + +[event_rabbitmq.cfg](./event_rabbitmq.cfg "include") + diff --git a/modules/event_routing/README b/modules/event_routing/README deleted file mode 100644 index bf651d292e0..00000000000 --- a/modules/event_routing/README +++ /dev/null @@ -1,432 +0,0 @@ -Event (based) Routing Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Functions - - 1.4.1. notify_on_event(event, filter, route, - timeout) - - 1.5. Exported Asynchronous Functions - - 1.5.1. wait_for_event(event,filter,timeout) - - 1.6. Usage Examples - - 1.6.1. Push Notification - 1.6.2. Call pickup - - 2. Developer Guide - - 2.1. - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. notify_on_event() usage - 1.2. wait_for_event usage - 1.3. Push Notification script - 1.4. Call Pickup script - -Chapter 1. Admin Guide - -1.1. Overview - - The Event (based) Routing module, or shortly the EBR module, - provides a mechanism that allows different SIP processings (of - messages in script) to communicate and synchronize between - through OpenSIPS Events (see - https://opensips.org/Documentation/Interface-Events-2-3). - - This mechanism is based on the Subscribe-Notify concept. Any - SIP processing may subscribe to various OpenSIPS Events Upon - Event raising, the subscriber will be notified, so it will be - able to make use of the data attached to the Event. Note that - the Event raising may take place in a completely different SIP - processing context, completely unrelated to the subscriber - processing. - - Also, the Events are generated either internally by OpenSIPS - (predefined Events), either from the script level (custom - Events). Please refer to the Event Interface documentation for - more on how the Events are generated - (https://opensips.org/Documentation/Interface-Events-2-3). - - Depending on how the notification is handled by the subscribing - processing, we distinguish two main scenarios: - * The subscriber waits in async. mode for the receiving the - notification; the processing of the subscriber will suspend - and it will be fully resumed when the notification is - received (or a timeout occurs). - * The subscriber continues its processing after subscription, - without any waiting. Whenever a notification is received, a - script route (armed by the subscription) will be executed. - Note that this notification route is executed outside any - context of the original processing (nothing is inherited in - this route). The Event triggering the notification is - exposed in the notification route, via AVP variables. - - So, EBR allows your SIP processing to synchronize or the - exchange info between, even if these processings are completely - unrelated from SIP, time or handling perspective. - - With the help of the EBR support, more advanced routing - scenarios are possible now, scenarios where you need to handle - and put together different processing as type and time, like - the handling of various calls with the handling of - registrations or with the DTMF extraction. For more, see the - Examples section. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules are required by this module: - * TM - Transaction module - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - - This module does not provide any script parameters. - -1.4. Exported Functions - -1.4.1. notify_on_event(event, filter, route, timeout) - - This function creates a subscription to a given Event. A filter - can be used (over the attributes of the Event) in order to - filter even more the needed notifications (only Events matching - the filter will be notified to this subscriber). - - Upon Event notification, the given script route (usually called - notification route) will be executed. No variables, SIP - message, SIP transaction/dialog or any other context related to - subscriber will be inherited from subscriber processing into - this notification route. - - The Event attributes will be exposed in the notification route - via AVP variables as $avp(attr_name) = attr_value. - - As an exception, in the notification route, the EBR module will - make available the transaction ID from the subscriber context. - Note that it's not the transaction itself, but its ID. There - are some TM functions (like t_inject_branches) which can - operate on transactions based on their ID. Of course, you need - to have a transaction create in the subscriber processing - before calling the notify_on_event() function. - - This function can be used from REQUEST_ROUTE. - - Parameters: - * event (string) -the name of the Event to subscribe for - * filter (var) - a AVP variable holding (as multi value - array) all the filters to be applied on the event (before - notification). The filter value has the format "key=value" - where the "key" must match an attribute name of the Event. - The "value" is the desired value for the attribute; it may - be a shell wildcard pattern. Ex: "aor=bob@*" - * route (string) -the name of the script route to be executed - upon Event notification - * timeout (int) - for how long the subscription is active - before expiring (integer in seconds). Note: during its - lifetime, a subscription may be notified several or zero - times. - - Example 1.1. notify_on_event() usage -... -$avp(filter) = "aor=*@opensips.org" -notify_on_event("E_UL_AOR_INSERT",$avp(filter),"reg_done",60); -... -route[reg_done] { - xlog("a new user $avp(aor) registered with opensips.org domain\n -"); -} - -1.5. Exported Asynchronous Functions - -1.5.1. wait_for_event(event,filter,timeout) - - Similar to the notify_on_event, this function creates an Event - subscriber for the given event and filter. But this function - will do async waiting (with suspend and resume) for receiving - the notification on the desired Event. - - The meaning of the parameters is the same as for - notify_on_event. - - Example 1.2. wait_for_event usage -... -# wait for callee to register -$avp(filter) = "aor="+$rU+"@"+$rd -async( wait_for_event("E_UL_AOR_INSERT",$avp(filter), 40), resume_call) -; -# done -... -route[resume_call] { - xlog("user $avp(aor) is now registered\n"); - lookup("location"); - t_relay(); -} - -1.6. Usage Examples - -1.6.1. Push Notification - - We use notify_on_event to capture the events on new contact - registrations for callee. Once the call is sent to callee, - based on the notification (for new contacts) we inject the - newly registered contacts as new branches in the ongoing - transaction. - - Schematics : when we send a call to a user, we subscribe to see - any new contacts being registered by the user. On such a - notification, we add the new contact as a new branch to the - ongoing transaction (ringing) to user. - - Example 1.3. Push Notification script -... -route[route_to_user] { - - # prepare transaction for branch injection; it is mandatory - # to create the transaction before the subscription, otherwise - # the EBR module will not pass the transaction ID into the - # notification route - t_newtran(); - - # keep the transaction alive (even if all branches will - # terminate) until the FR INVITE timer hits (we want to wait - # for new possible contacts being registered) - t_wait_for_new_branches(); - - # subscribe to new contact registration event, - # but for our callee only - $avp(filter) = "aor="+$rU; - notify_on_event("E_UL_CONTACT_INSERT",$avp(filter), - "fork_call", 20); - - # fetch already registered contacts and relay if any - if (lookup("location")) - route(relay); - # if there were no contacts available (so no branches - # created so far), the created transaction will still be - # waiting for new branches due to the usage of the - # t_wait_for_new_branches() function - - exit; -} - -route[fork_call] -{ - xlog("user $avp(aor) registered a new " - "contact $avp(uri), injecting\n"); - # take the contact described by the E_UL_CONTACT_INSERT - # event and inject it as a new branch into the original - # transaction - t_inject_branches("event"); -} -... - -1.6.2. Call pickup - - The scenario is Alice calling to bob, Bob does not pickup and - Charlie is performing call pickup (to get the call from Alice) - - We use notify_on_event to link the two calls: the one from - Alice to Bob and the one from Charlie to call pickup service. - - Schematics: when we send a call to a user within a pickup - group, we subscribe to see if there is any call to the pickup - service (from another member of the same pickup group). When we - have a call to the pickup service, we raise from script an - event - this event will be notified to the first call and we - cancel the branches to Bob and inject the registered contacts - for the user calling to pickup group (Charlie). - - Example 1.4. Call Pickup script -... -route[handle_call] - if ($rU=="33") { - ## this is a call to the pickup service - ## (Charlie calling 33) - - # reject incoming call as we will generate an back call - # from the original call (Alice to Bob) - t_newtran(); - send_reply(480, "Gone"); - - # raise the pickup custom event - # with pickup group 1 and picker being Charlie (caller) - $avp(attr-name) = "group"; - $avp(attr-val) = "1"; - $avp(attr-name) = "picker"; - $avp(attr-val) = $fu; - raise_event("E_CALL_PICKUP", $avp(attr-name), $avp(attr-val)); - - exit; - } else { - - ## this is a call to a subscriber - ## (Alice calls Bob) - - # apply user location - if (!lookup("location", "method-filtering")) { - send_reply(404, "Not Found"); - exit; - } - - # prepare transaction for branch injection; it is mandatory - # to create the transaction before the subscription, otherwise - # the EBR module will not pass the transaction ID into the - # notification route - t_newtran(); - - # subscribe to a call pickup event, but for our group only - $avp(filter) = "group=1"; - notify_on_event("E_CALL_PICKUP",$avp(filter), - "handle_pickup", 20); - - t_relay(); - } - exit; -} - -route[handle_pickup] -{ - xlog("call picked by $avp(picker), fetching its contacts\n"); - if (lookup("location","", $avp(picker))) { - # take the contacts retured by lookup() (for Charlie) - # and inject them into the original call, but also cancel - # any existing ongoing branch (ringing to Bob) - t_inject_branches("msg","cancel"); - } -} - -Chapter 2. Developer Guide - - This modules does not export any internal API. - -Chapter 3. Frequently Asked Questions - - 3.1. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 3.2. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 3.3. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 30 13 1802 53 - 2. Liviu Chircu (@liviuchircu) 29 20 494 220 - 3. Vlad Patrascu (@rvlad-patrascu) 9 5 75 148 - 4. Razvan Crainea (@razvancrainea) 6 4 9 5 - 5. Fabian Gast (@fgast) 4 2 27 7 - 6. Maksym Sobolyev (@sobomax) 4 2 5 6 - 7. Vlad Paiu (@vladpaiu) 3 1 8 1 - 8. Zero King (@l2dy) 3 1 2 2 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2017 - Aug 2025 - 2. Liviu Chircu (@liviuchircu) Sep 2017 - Nov 2024 - 3. Vlad Paiu (@vladpaiu) Nov 2024 - Nov 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2020 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Razvan Crainea (@razvancrainea) Apr 2017 - Sep 2019 - 8. Fabian Gast (@fgast) Nov 2018 - Dec 2018 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Zero King (@l2dy), - Vlad Patrascu (@rvlad-patrascu), Fabian Gast (@fgast), Peter - Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2017 www.opensips-solutions.com diff --git a/modules/event_routing/README.md b/modules/event_routing/README.md new file mode 100644 index 00000000000..f031b47ba6b --- /dev/null +++ b/modules/event_routing/README.md @@ -0,0 +1,362 @@ +--- +title: "Event (based) Routing Module" +description: "The Event (based) Routing module, or shortly the EBR module, provides a mechanism that allows different SIP processings (of messages in script) to communicate and synchronize between through OpenSIPS Events (see https://docs.opensips.org/manual/3-6/interface-events/)." +--- + +## Admin Guide + + +### Overview + + +The Event (based) Routing module, or shortly the EBR module, provides a +mechanism that allows different SIP processings (of messages in script) to +communicate and synchronize between through OpenSIPS Events +(see https://docs.opensips.org/manual/3-6/interface-events/). + + +This mechanism is based on the Subscribe-Notify concept. Any SIP processing +may subscribe to various OpenSIPS Events Upon Event raising, the +subscriber will be notified, so it will be able to make use of the data +attached to the Event. Note that the Event raising may take place in a +completely different SIP processing context, completely unrelated to the +subscriber processing. + + +Also, the Events are generated either internally by OpenSIPS (predefined +Events), either from the script level (custom Events). Please refer to the +Event Interface documentation for more on how the Events are generated +(https://docs.opensips.org/manual/3-6/interface-events/). + + +Depending on how the notification is handled by the subscribing processing, +we distinguish two main scenarios: + + +- The subscriber waits in async. mode for the receiving the notification; +the processing of the subscriber will suspend and it will be fully +resumed when the notification is received (or a timeout occurs). +- The subscriber continues its processing after subscription, without any +waiting. Whenever a notification is received, a script route (armed by +the subscription) will be executed. Note that this notification route +is executed outside any context of the original processing (nothing +is inherited in this route). The Event triggering the notification is +exposed in the notification route, via AVP variables. + + +So, EBR allows your SIP processing to synchronize or the exchange info +between, even if these processings are completely unrelated from SIP, time +or handling perspective. + + +With the help of the EBR support, more advanced routing scenarios are +possible now, scenarios where you need to handle and put together different +processing as type and time, like the handling of various calls with the +handling of registrations or with the DTMF extraction. For more, see +the [Examples](#usage_examples) section. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules are required by this module: + + +- *TM* - Transaction module + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +This module does not provide any script parameters. + + +### Exported Functions + + +#### notify_on_event(event, filter, route, timeout) + + +This function creates a subscription to a given Event. A filter can be +used (over the attributes of the Event) in order to filter even more +the needed notifications (only Events matching the filter will be +notified to this subscriber). + + +Upon Event notification, the given script route (usually called +notification route) will be executed. No variables, SIP message, SIP +transaction/dialog or any other context related to subscriber will be +inherited from subscriber processing into this notification route. + + +The Event attributes will be exposed in the notification route via AVP +variables as *$avp(attr_name) = attr_value*. + + +As an exception, in the notification route, the EBR module will make +available the transaction ID from the subscriber context. Note that +it's not the transaction itself, but its ID. There are some TM +functions (like *t_inject_branches*) which can +operate on transactions based on their ID. Of course, you need to +have a transaction create in the subscriber processing before calling +the *notify_on_event()* function. + + +This function can be used from REQUEST_ROUTE. + + +Parameters: + + +- *event* (string) -the name of the Event to subscribe for +- *filter* (var) - a AVP variable holding (as multi +value array) all the filters to be applied on the event (before +notification). The filter value has the format "key=value" +where the "key" must match an attribute name of the Event. The +"value" is the desired value for the attribute; it may be a shell +wildcard pattern. Ex: "aor=bob@*" +- *route* (string) -the name of the script route to be +executed upon Event notification +- *timeout* (int) - for how long the subscription is +active before expiring (integer in seconds). Note: during its +lifetime, a subscription may be notified several or zero times. + + +```opensips title="notify_on_event() usage" +... +$avp(filter) = "aor=*@opensips.org" +notify_on_event("E_UL_AOR_INSERT",$avp(filter),"reg_done",60); +... +route[reg_done] { + xlog("a new user $avp(aor) registered with opensips.org domain\n"); +} +``` + + +### Exported Asynchronous Functions + + +#### wait_for_event(event,filter,timeout) + + +Similar to the *notify_on_event*, this function +creates an Event subscriber for the given event and filter. But this +function will do async waiting (with suspend and resume) for receiving +the notification on the desired Event. + + +The meaning of the parameters is the same as for +*notify_on_event*. + + +```opensips title="wait_for_event usage" +... +# wait for callee to register +$avp(filter) = "aor="+$rU+"@"+$rd +async( wait_for_event("E_UL_AOR_INSERT",$avp(filter), 40), resume_call); +# done +... +route[resume_call] { + xlog("user $avp(aor) is now registered\n"); + lookup("location"); + t_relay(); +} +``` + + +### Usage Examples + + +#### Push Notification + + +We use *notify_on_event* to capture the events on +new contact registrations for callee. Once the call is sent to callee, +based on the notification (for new contacts) we inject the newly +registered contacts as new branches in the ongoing transaction. + + +Schematics : when we send a call to a user, we subscribe to see any +new contacts being registered by the user. On such a notification, +we add the new contact as a new branch to the ongoing transaction +(ringing) to user. + + +```opensips title="Push Notification script" +... +route[route_to_user] { + + # prepare transaction for branch injection; it is mandatory + # to create the transaction before the subscription, otherwise + # the EBR module will not pass the transaction ID into the + # notification route + t_newtran(); + + # keep the transaction alive (even if all branches will + # terminate) until the FR INVITE timer hits (we want to wait + # for new possible contacts being registered) + t_wait_for_new_branches(); + + # subscribe to new contact registration event, + # but for our callee only + $avp(filter) = "aor="+$rU; + notify_on_event("E_UL_CONTACT_INSERT",$avp(filter), + "fork_call", 20); + + # fetch already registered contacts and relay if any + if (lookup("location")) + route(relay); + # if there were no contacts available (so no branches + # created so far), the created transaction will still be + # waiting for new branches due to the usage of the + # t_wait_for_new_branches() function + + exit; +} + +route[fork_call] +{ + xlog("user $avp(aor) registered a new " + "contact $avp(uri), injecting\n"); + # take the contact described by the E_UL_CONTACT_INSERT + # event and inject it as a new branch into the original + # transaction + t_inject_branches("event"); +} +... +``` + + +#### Call pickup + + +The scenario is Alice calling to bob, Bob does not pickup and Charlie +is performing call pickup (to get the call from Alice) + + +We use *notify_on_event* to link the two calls: the +one from Alice to Bob and the one from Charlie to call pickup service. + + +Schematics: when we send a call to a user within a pickup group, we +subscribe to see if there is any call to the pickup service (from +another member of the same pickup group). When we have a call to +the pickup service, we raise from script an event - this event will +be notified to the first call and we cancel the branches to Bob and +inject the registered contacts for the user calling to pickup group +(Charlie). + + +```opensips title="Call Pickup script" +... +route[handle_call] + if ($rU=="33") { + ## this is a call to the pickup service + ## (Charlie calling 33) + + # reject incoming call as we will generate an back call + # from the original call (Alice to Bob) + t_newtran(); + send_reply(480, "Gone"); + + # raise the pickup custom event + # with pickup group 1 and picker being Charlie (caller) + $avp(attr-name) = "group"; + $avp(attr-val) = "1"; + $avp(attr-name) = "picker"; + $avp(attr-val) = $fu; + raise_event("E_CALL_PICKUP", $avp(attr-name), $avp(attr-val)); + + exit; + } else { + + ## this is a call to a subscriber + ## (Alice calls Bob) + + # apply user location + if (!lookup("location", "method-filtering")) { + send_reply(404, "Not Found"); + exit; + } + + # prepare transaction for branch injection; it is mandatory + # to create the transaction before the subscription, otherwise + # the EBR module will not pass the transaction ID into the + # notification route + t_newtran(); + + # subscribe to a call pickup event, but for our group only + $avp(filter) = "group=1"; + notify_on_event("E_CALL_PICKUP",$avp(filter), + "handle_pickup", 20); + + t_relay(); + } + exit; +} + +route[handle_pickup] +{ + xlog("call picked by $avp(picker), fetching its contacts\n"); + if (lookup("location","", $avp(picker))) { + # take the contacts retured by lookup() (for Charlie) + # and inject them into the original call, but also cancel + # any existing ongoing branch (ringing to Bob) + t_inject_branches("msg","cancel"); + } +} +``` + + +## Developer Guide + + +This modules does not export any internal API. + + +## Frequently Asked Questions + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_routing/api.h b/modules/event_routing/api.h index 6e267f32dba..aea37275333 100644 --- a/modules/event_routing/api.h +++ b/modules/event_routing/api.h @@ -49,6 +49,7 @@ typedef struct ebr_api { * @notify: mandatory callback, a hook where to take action once the * desired event takes place * @timeout: lifetime of the subscription (seconds) + * @flags: optional EBR_SUBS_* flags * * Return: 0 on successful registration, -1 otherwise * @@ -61,7 +62,7 @@ typedef struct ebr_api { int (*notify_on_event) (struct sip_msg *msg, ebr_event *event, const ebr_filter *filters, ebr_pack_params_cb pack_params, - ebr_notify_cb notify, int timeout); + ebr_notify_cb notify, int timeout, int flags); /** * async_wait_for_event() - subscribe to the @event given by @filters. diff --git a/modules/event_routing/doc/contributors.xml b/modules/event_routing/doc/contributors.xml deleted file mode 100644 index 35eb676499c..00000000000 --- a/modules/event_routing/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 30 - 13 - 1802 - 53 - - - 2. - Liviu Chircu (@liviuchircu) - 29 - 20 - 494 - 220 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 9 - 5 - 75 - 148 - - - 4. - Razvan Crainea (@razvancrainea) - 6 - 4 - 9 - 5 - - - 5. - Fabian Gast (@fgast) - 4 - 2 - 27 - 7 - - - 6. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 6 - - - 7. - Vlad Paiu (@vladpaiu) - 3 - 1 - 8 - 1 - - - 8. - Zero King (@l2dy) - 3 - 1 - 2 - 2 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2017 - Aug 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Sep 2017 - Nov 2024 - - - 3. - Vlad Paiu (@vladpaiu) - Nov 2024 - Nov 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2020 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Razvan Crainea (@razvancrainea) - Apr 2017 - Sep 2019 - - - 8. - Fabian Gast (@fgast) - Nov 2018 - Dec 2018 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/event_routing/doc/event_routing.xml b/modules/event_routing/doc/event_routing.xml deleted file mode 100644 index 34cb4f8e394..00000000000 --- a/modules/event_routing/doc/event_routing.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Event (based) Routing Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2017 &osipssol; - - diff --git a/modules/event_routing/doc/event_routing_admin.xml b/modules/event_routing/doc/event_routing_admin.xml deleted file mode 100644 index 24f744ba370..00000000000 --- a/modules/event_routing/doc/event_routing_admin.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Event (based) Routing module, or shortly the EBR module, provides a - mechanism that allows different SIP processings (of messages in script) to - communicate and synchronize between through OpenSIPS Events - (see https://opensips.org/Documentation/Interface-Events-2-3). - - - This mechanism is based on the Subscribe-Notify concept. Any SIP processing - may subscribe to various OpenSIPS Events Upon Event raising, the - subscriber will be notified, so it will be able to make use of the data - attached to the Event. Note that the Event raising may take place in a - completely different SIP processing context, completely unrelated to the - subscriber processing. - - - Also, the Events are generated either internally by OpenSIPS (predefined - Events), either from the script level (custom Events). Please refer to the - Event Interface documentation for more on how the Events are generated - (https://opensips.org/Documentation/Interface-Events-2-3). - - - Depending on how the notification is handled by the subscribing processing, - we distinguish two main scenarios: - - - - - The subscriber waits in async. mode for the receiving the notification; - the processing of the subscriber will suspend and it will be fully - resumed when the notification is received (or a timeout occurs). - - - - - The subscriber continues its processing after subscription, without any - waiting. Whenever a notification is received, a script route (armed by - the subscription) will be executed. Note that this notification route - is executed outside any context of the original processing (nothing - is inherited in this route). The Event triggering the notification is - exposed in the notification route, via AVP variables. - - - - - So, EBR allows your SIP processing to synchronize or the exchange info - between, even if these processings are completely unrelated from SIP, time - or handling perspective. - - - With the help of the EBR support, more advanced routing scenarios are - possible now, scenarios where you need to handle and put together different - processing as type and time, like the handling of various calls with the - handling of registrations or with the DTMF extraction. For more, see - the section. - -
- -
- Dependencies -
- &osips; Modules - - The following modules are required by this module: - - - - TM - Transaction module - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Parameters - - This module does not provide any script parameters. - -
- - -
- Exported Functions - -
- - <function moreinfo="none">notify_on_event(event, filter, route, timeout)</function> - - - This function creates a subscription to a given Event. A filter can be - used (over the attributes of the Event) in order to filter even more - the needed notifications (only Events matching the filter will be - notified to this subscriber). - - - Upon Event notification, the given script route (usually called - notification route) will be executed. No variables, SIP message, SIP - transaction/dialog or any other context related to subscriber will be - inherited from subscriber processing into this notification route. - - - The Event attributes will be exposed in the notification route via AVP - variables as $avp(attr_name) = attr_value. - - - As an exception, in the notification route, the EBR module will make - available the transaction ID from the subscriber context. Note that - it's not the transaction itself, but its ID. There are some TM - functions (like t_inject_branches) which can - operate on transactions based on their ID. Of course, you need to - have a transaction create in the subscriber processing before calling - the notify_on_event() function. - - - This function can be used from REQUEST_ROUTE. - - Parameters: - - - event (string) -the name of the Event to subscribe for - - - filter (var) - a AVP variable holding (as multi - value array) all the filters to be applied on the event (before - notification). The filter value has the format "key=value" - where the "key" must match an attribute name of the Event. The - "value" is the desired value for the attribute; it may be a shell - wildcard pattern. Ex: "aor=bob@*" - - - route (string) -the name of the script route to be - executed upon Event notification - - - timeout (int) - for how long the subscription is - active before expiring (integer in seconds). Note: during its - lifetime, a subscription may be notified several or zero times. - - - - <function>notify_on_event()</function> usage - -... -$avp(filter) = "aor=*@opensips.org" -notify_on_event("E_UL_AOR_INSERT",$avp(filter),"reg_done",60); -... -route[reg_done] { - xlog("a new user $avp(aor) registered with opensips.org domain\n"); -} - - -
- -
- - -
- Exported Asynchronous Functions - -
- - <function moreinfo="none">wait_for_event(event,filter,timeout)</function> - - - Similar to the notify_on_event, this function - creates an Event subscriber for the given event and filter. But this - function will do async waiting (with suspend and resume) for receiving - the notification on the desired Event. - - - The meaning of the parameters is the same as for - notify_on_event. - - - <function>wait_for_event</function> usage - -... -# wait for callee to register -$avp(filter) = "aor="+$rU+"@"+$rd -async( wait_for_event("E_UL_AOR_INSERT",$avp(filter), 40), resume_call); -# done -... -route[resume_call] { - xlog("user $avp(aor) is now registered\n"); - lookup("location"); - t_relay(); -} - - -
- -
- - -
- Usage Examples - -
- - <function moreinfo="none">Push Notification</function> - - - We use notify_on_event to capture the events on - new contact registrations for callee. Once the call is sent to callee, - based on the notification (for new contacts) we inject the newly - registered contacts as new branches in the ongoing transaction. - - - Schematics : when we send a call to a user, we subscribe to see any - new contacts being registered by the user. On such a notification, - we add the new contact as a new branch to the ongoing transaction - (ringing) to user. - - - Push Notification script - -... -route[route_to_user] { - - # prepare transaction for branch injection; it is mandatory - # to create the transaction before the subscription, otherwise - # the EBR module will not pass the transaction ID into the - # notification route - t_newtran(); - - # keep the transaction alive (even if all branches will - # terminate) until the FR INVITE timer hits (we want to wait - # for new possible contacts being registered) - t_wait_for_new_branches(); - - # subscribe to new contact registration event, - # but for our callee only - $avp(filter) = "aor="+$rU; - notify_on_event("E_UL_CONTACT_INSERT",$avp(filter), - "fork_call", 20); - - # fetch already registered contacts and relay if any - if (lookup("location")) - route(relay); - # if there were no contacts available (so no branches - # created so far), the created transaction will still be - # waiting for new branches due to the usage of the - # t_wait_for_new_branches() function - - exit; -} - -route[fork_call] -{ - xlog("user $avp(aor) registered a new " - "contact $avp(uri), injecting\n"); - # take the contact described by the E_UL_CONTACT_INSERT - # event and inject it as a new branch into the original - # transaction - t_inject_branches("event"); -} -... - - -
- -
- - <function moreinfo="none">Call pickup</function> - - - The scenario is Alice calling to bob, Bob does not pickup and Charlie - is performing call pickup (to get the call from Alice) - - - We use notify_on_event to link the two calls: the - one from Alice to Bob and the one from Charlie to call pickup service. - - - Schematics: when we send a call to a user within a pickup group, we - subscribe to see if there is any call to the pickup service (from - another member of the same pickup group). When we have a call to - the pickup service, we raise from script an event - this event will - be notified to the first call and we cancel the branches to Bob and - inject the registered contacts for the user calling to pickup group - (Charlie). - - - - Call Pickup script - -... -route[handle_call] - if ($rU=="33") { - ## this is a call to the pickup service - ## (Charlie calling 33) - - # reject incoming call as we will generate an back call - # from the original call (Alice to Bob) - t_newtran(); - send_reply(480, "Gone"); - - # raise the pickup custom event - # with pickup group 1 and picker being Charlie (caller) - $avp(attr-name) = "group"; - $avp(attr-val) = "1"; - $avp(attr-name) = "picker"; - $avp(attr-val) = $fu; - raise_event("E_CALL_PICKUP", $avp(attr-name), $avp(attr-val)); - - exit; - } else { - - ## this is a call to a subscriber - ## (Alice calls Bob) - - # apply user location - if (!lookup("location", "method-filtering")) { - send_reply(404, "Not Found"); - exit; - } - - # prepare transaction for branch injection; it is mandatory - # to create the transaction before the subscription, otherwise - # the EBR module will not pass the transaction ID into the - # notification route - t_newtran(); - - # subscribe to a call pickup event, but for our group only - $avp(filter) = "group=1"; - notify_on_event("E_CALL_PICKUP",$avp(filter), - "handle_pickup", 20); - - t_relay(); - } - exit; -} - -route[handle_pickup] -{ - xlog("call picked by $avp(picker), fetching its contacts\n"); - if (lookup("location","", $avp(picker))) { - # take the contacts retured by lookup() (for Charlie) - # and inject them into the original call, but also cancel - # any existing ongoing branch (ringing to Bob) - t_inject_branches("msg","cancel"); - } -} - - -
- -
- - -
- diff --git a/modules/event_routing/doc/event_routing_devel.xml b/modules/event_routing/doc/event_routing_devel.xml deleted file mode 100644 index 5eacc3b05ba..00000000000 --- a/modules/event_routing/doc/event_routing_devel.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - &develguide; -
- This modules does not export any internal API. -
- -
- diff --git a/modules/event_routing/doc/event_routing_faq.xml b/modules/event_routing/doc/event_routing_faq.xml deleted file mode 100644 index 4b1c4df9306..00000000000 --- a/modules/event_routing/doc/event_routing_faq.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - &faqguide; - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/event_routing/ebr_data.c b/modules/event_routing/ebr_data.c index 14830f43af4..d76ad5de8ae 100644 --- a/modules/event_routing/ebr_data.c +++ b/modules/event_routing/ebr_data.c @@ -506,6 +506,31 @@ int notify_ebr_subscriptions( ebr_event *ev, evi_params_t *params) shm_free(job); continue; /* keep it and try next time */ } + } else + if ((sub->flags & EBR_SUBS_TYPE_NOTY) && + (sub->flags & EBR_SUBS_EXPIRE_NOTIFY)) { + job =(ebr_ipc_job*)shm_malloc( sizeof(ebr_ipc_job) ); + if (job==NULL) { + LM_ERR("failed to allocated new IPC job, skipping..\n"); + continue; + } + job->ev = ev; + job->data = sub->data; + job->flags = sub->flags; + job->tm = sub->tm; + job->avps = NULL; + + if (sub->flags & EBR_DATA_TYPE_ROUT) + job->data = dup_ref_script_route_in_shm + ((struct script_route_ref *)job->data, 1); + + if (ipc_send_job( process_no, ebr_ipc_type, (void*)job)<0) { + LM_ERR("failed to send job via IPC, skipping...\n"); + if ((sub->flags & EBR_DATA_TYPE_ROUT) && job->data) + shm_free(job->data); + shm_free(job); + continue; + } } /* unlink it */ @@ -647,34 +672,68 @@ void ebr_timeout(unsigned int ticks, void* param) for ( sub=ev->subs ; sub ; sub_prev=sub, sub=sub_next ) { sub_next = sub->next; - /* skip valid and non WAIT subscriptions */ - if ( (sub->flags&EBR_SUBS_TYPE_WAIT)==0 || sub->expire>my_time ) + if (sub->expire>my_time) continue; - LM_DBG("subscription type [%s] from process %d(pid %d) on " - "event <%.*s> expired at %d, now %d\n", - (sub->flags&EBR_SUBS_TYPE_WAIT)?"WAIT":"NOTIFY", - sub->proc_no, pt[sub->proc_no].pid, - sub->event->event_name.len, sub->event->event_name.s, - sub->expire, my_time ); + if (sub->flags&EBR_SUBS_TYPE_WAIT) { + LM_DBG("subscription type [%s] from process %d(pid %d) on " + "event <%.*s> expired at %d, now %d\n", + (sub->flags&EBR_SUBS_TYPE_WAIT)?"WAIT":"NOTIFY", + sub->proc_no, pt[sub->proc_no].pid, + sub->event->event_name.len, sub->event->event_name.s, + sub->expire, my_time ); - /* fire the job */ - job =(ebr_ipc_job*)shm_malloc( sizeof(ebr_ipc_job) ); - if (job==NULL) { - LM_ERR("failed to allocated new IPC job, skipping..\n"); - continue; /* with the next subscription */ - } - job->ev = ev; - job->data = sub->data; - job->flags = sub->flags; - job->tm = sub->tm; - job->avps = NULL; - /* sent the event notification via IPC to resume on the - * subscribing process */ - if (ipc_send_job( sub->proc_no, ebr_ipc_type , (void*)job)<0) { - LM_ERR("failed to send job via IPC, skipping...\n"); - shm_free(job); - continue; /* with the next subscription */ + job =(ebr_ipc_job*)shm_malloc( sizeof(ebr_ipc_job) ); + if (job==NULL) { + LM_ERR("failed to allocated new IPC job, skipping..\n"); + continue; /* with the next subscription */ + } + job->ev = ev; + job->data = sub->data; + job->flags = sub->flags; + job->tm = sub->tm; + job->avps = NULL; + /* sent the event notification via IPC to resume on the + * subscribing process */ + if (ipc_send_job( sub->proc_no, ebr_ipc_type , (void*)job)<0) { + LM_ERR("failed to send job via IPC, skipping...\n"); + shm_free(job); + continue; /* with the next subscription */ + } + } else + if ((sub->flags & EBR_SUBS_TYPE_NOTY) && + (sub->flags & EBR_SUBS_EXPIRE_NOTIFY)) { + LM_DBG("subscription type [%s] from process %d(pid %d) on " + "event <%.*s> expired at %d, now %d, notifying\n", + (sub->flags&EBR_SUBS_TYPE_WAIT)?"WAIT":"NOTIFY", + sub->proc_no, pt[sub->proc_no].pid, + sub->event->event_name.len, sub->event->event_name.s, + sub->expire, my_time); + + job =(ebr_ipc_job*)shm_malloc( sizeof(ebr_ipc_job) ); + if (job==NULL) { + LM_ERR("failed to allocated new IPC job, skipping..\n"); + continue; + } + job->ev = ev; + job->data = sub->data; + job->flags = sub->flags; + job->tm = sub->tm; + job->avps = NULL; + + if (sub->flags & EBR_DATA_TYPE_ROUT) + job->data = dup_ref_script_route_in_shm + ((struct script_route_ref *)job->data, 1); + + if (ipc_send_job( process_no, ebr_ipc_type, (void*)job)<0) { + LM_ERR("failed to send job via IPC, skipping...\n"); + if ((sub->flags & EBR_DATA_TYPE_ROUT) && job->data) + shm_free(job->data); + shm_free(job); + continue; + } + } else { + continue; } /* unlink it */ diff --git a/modules/event_routing/ebr_data.h b/modules/event_routing/ebr_data.h index 9a18f2c5a20..057fdd0d1c3 100644 --- a/modules/event_routing/ebr_data.h +++ b/modules/event_routing/ebr_data.h @@ -44,6 +44,7 @@ struct _ebr_event; #define EBR_SUBS_TYPE_NOTY (1<<1) #define EBR_DATA_TYPE_ROUT (1<<2) #define EBR_DATA_TYPE_FUNC (1<<3) +#define EBR_SUBS_EXPIRE_NOTIFY (1<<4) typedef struct usr_avp *(*ebr_pack_params_cb) (evi_params_t *params); diff --git a/modules/event_routing/event_routing.c b/modules/event_routing/event_routing.c index b474dac4399..25ca9516e67 100644 --- a/modules/event_routing/event_routing.c +++ b/modules/event_routing/event_routing.c @@ -56,7 +56,7 @@ ebr_event *get_ebr_event(const str *name); int api_notify_on_event(struct sip_msg *msg, ebr_event *event, const ebr_filter *filters, ebr_pack_params_cb pack_params, - ebr_notify_cb notify, int timeout); + ebr_notify_cb notify, int timeout, int flags); int api_wait_for_event(struct sip_msg *msg, async_ctx *ctx, ebr_event *event, const ebr_filter *filters, ebr_pack_params_cb pack_params, int timeout); @@ -341,7 +341,7 @@ static int notify_on_event(struct sip_msg *msg, ebr_event* event, int api_notify_on_event(struct sip_msg *msg, ebr_event *event, const ebr_filter *filters, ebr_pack_params_cb pack_params, - ebr_notify_cb notify, int timeout) + ebr_notify_cb notify, int timeout, int flags) { ebr_filter *filters_cpy; @@ -361,7 +361,7 @@ int api_notify_on_event(struct sip_msg *msg, ebr_event *event, /* we have a valid EBR event here, let's subscribe on it */ if (add_ebr_subscription( msg, event, filters_cpy, timeout, pack_params, notify, - EBR_SUBS_TYPE_NOTY|EBR_DATA_TYPE_FUNC ) <0 ) { + EBR_SUBS_TYPE_NOTY|EBR_DATA_TYPE_FUNC|flags ) <0 ) { LM_ERR("failed to add ebr subscription for event %d\n", event->event_id); return -1; diff --git a/modules/event_sqs/README b/modules/event_sqs/README deleted file mode 100644 index 1163d302f4f..00000000000 --- a/modules/event_sqs/README +++ /dev/null @@ -1,228 +0,0 @@ -event_sqs Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - 1.2.3. Deploying Amazon SQS locally on your computer - - 1.3. Exported Parameters - - 1.3.1. queue_url (string) - - 1.4. Exported Functions - - 1.4.1. sqs_publish_message(queue_id, message) - 1.4.2. - - 1.5. Examples - - 1.5.1. Event-Driven Messaging with Event Interface - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set queue_url parameter - 1.2. sqs_publish_message() function usage - -Chapter 1. Admin Guide - -1.1. Overview - - The event_sqs module is an implementation of an Amazon SQS - producer. It serves as a transport backend for the Event - Interface and also provides a stand-alone connector to be used - from the OpenSIPS script in order to publish messages to SQS - queues. - - https://aws.amazon.com/sqs/ - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - There is no need to load any module before this module. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * AWS SDK for C++: - By following these steps, you'll have the AWS SDK for C++ - installed and configured on your Linux system, allowing you - to integrate with SQS: AWS SDK for C++ Installation Guide - Additional instructions for installation can be found at: - AWS SDK for C++ GitHub Repository - -1.2.3. Deploying Amazon SQS locally on your computer - - For testing purposes, you can run SQS locally. To achieve this, - you start localstack on your computer: - -pip install localstack -localstack start - - Don't forget to set the necessary environment variables for - testing, for example: - -export AWS_ACCESS_KEY_ID=test -export AWS_SECRET_ACCESS_KEY=test -export AWS_DEFAULT_REGION=us-east-1 - - Here you can find some cli commands such as create-queue, - send/receive-message, etc.: - https://docs.aws.amazon.com/cli/latest/reference/sqs/ - -1.3. Exported Parameters - -1.3.1. queue_url (string) - - This parameter specifies the configuration for an SQS queue - that can be used to publish messages directly from the script, - using the sqs_publish_message() function or to send messages - using raise_event function. - - The format of the parameter is: [ID]sqs_url, where ID is an - identifier for this SQS queue instance and sqs_url is the full - url of the queue. - - The queue_url contains: - * endpoint - * region - - This parameter can be set multiple times. - - Example 1.1. Set queue_url parameter - -... - -modparam("event_sqs", "queue_url", - "[q1]https://sqs.us-west-2.amazonaws.com/123456789012/Queue1") - -modparam("event_sqs", "queue_url", - "[q2]http://sqs.us-east-1.localhost.localstack.cloud:4566/0000 -00000000/Queue2") - -... - -1.4. Exported Functions - -1.4.1. sqs_publish_message(queue_id, message) - - Publishes a message to an SQS queue. As the actual send - operation is done asynchronously, this function does not block - and returns immediately after queuing the message for sending. - - This function can be used from any route. - - The function has the following parameters: - * queue_id (string) The ID of the SQS queue. Must be one of - the IDs defined through the `queue_url` modparam. - * message (string) - The payload of the message to publish. - - Example 1.2. sqs_publish_message() function usage - -... - -$var(msg) = "Hello, this is a message to SQS!"; -sqs_publish_message("q1", $var(msg)); - -... - -1.5. Examples - -1.5.1. Event-Driven Messaging with Event Interface - - OpenSIPS' event interface can be utilized to send messages to - SQS by subscribing to an event and raising it when needed. - - Steps: - * Event Subscription: - First, register the event subscription in your OpenSIPS - configuration file within the `startup_route`: - -subscribe_event("MY_EVENT", - "sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/000000 -000000/Queue2"); - - * Event Subscription via CLI: - After starting OpenSIPS, you can subscribe to the event - from another terminal using the OpenSIPS CLI: - -opensips-cli -x mi event_subscribe MY_EVENT \ - sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/00000 -0000000/Queue2 - - * Raise the Event and Send Message: - Finally, to send a message, raise the subscribed event with - the desired message content: - -opensips-cli -x mi raise_event MY_EVENT 'OpenSIPS Message' - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Alexandra Titoc 28 7 1629 366 - 2. Razvan Crainea (@razvancrainea) 5 3 9 4 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Sep 2024 - Sep 2024 - 2. Alexandra Titoc Aug 2024 - Aug 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Alexandra - Titoc. - - Documentation Copyrights: - - Copyright © 2024 www.opensips-solutions.com diff --git a/modules/event_sqs/README.md b/modules/event_sqs/README.md new file mode 100644 index 00000000000..c5ff0bf076f --- /dev/null +++ b/modules/event_sqs/README.md @@ -0,0 +1,180 @@ +--- +title: "event_sqs Module" +description: "The event_sqs module is an implementation of an Amazon SQS producer." +--- + +## Admin Guide + + +### Overview + + +The event_sqs module is an implementation of an Amazon SQS producer. +It serves as a transport backend for the Event Interface and also provides a stand-alone +connector to be used from the OpenSIPS script in order to publish messages to SQS queues. +[https://aws.amazon.com/sqs/](https://aws.amazon.com/sqs/) + + +### Dependencies + + +#### OpenSIPS Modules + + +There is no need to load any module before this module. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *AWS SDK for C++:* +By following these steps, you'll have the AWS SDK for C++ installed and +configured on your Linux system, allowing you to integrate with SQS: +[AWS SDK for C++ Installation Guide](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/setup-linux.html) +Additional instructions for installation can be found at: +[AWS SDK for C++ GitHub Repository](https://github.com/aws/aws-sdk-cpp) + + +#### Deploying Amazon SQS locally on your computer + + +For testing purposes, you can run SQS locally. To achieve this, you start localstack on your computer: + + +```c +pip install localstack +localstack start + +``` + + +Don't forget to set the necessary environment variables for testing, for example: + + +```c +export AWS_ACCESS_KEY_ID=test +export AWS_SECRET_ACCESS_KEY=test +export AWS_DEFAULT_REGION=us-east-1 + +``` + + +Here you can find some cli commands such as create-queue, send/receive-message, etc.: +[https://docs.aws.amazon.com/cli/latest/reference/sqs/](https://docs.aws.amazon.com/cli/latest/reference/sqs/) + + +### Exported Parameters + + +#### queue_url (string) + + +This parameter specifies the configuration for an SQS queue that can be used +to publish messages directly from the script, using the sqs_publish_message() function +or to send messages using raise_event function. + + +The format of the parameter is: [ID]sqs_url, where ID is an identifier +for this SQS queue instance and sqs_url is the full url of the queue. + + +The queue_url contains: + + +- *endpoint* +- *region* + + +This parameter can be set multiple times. + + +```opensips title="Set queue_url parameter" +... + +modparam("event_sqs", "queue_url", + "[q1]https://sqs.us-west-2.amazonaws.com/123456789012/Queue1") + +modparam("event_sqs", "queue_url", + "[q2]http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2") + +... + +``` + + +### Exported Functions + + +#### sqs_publish_message(queue_id, message) + + +Publishes a message to an SQS queue. As the actual +send operation is done asynchronously, this function does not block and returns +immediately after queuing the message for sending. + + +This function can be used from any route. + + +The function has the following parameters: + + +- *queue_id (string)* The ID of the SQS queue. Must be one of the IDs defined through the `queue_url` modparam. +- *message (string)* - The payload of the message to publish. + + +```opensips title="sqs_publish_message() function usage" +... + +$var(msg) = "Hello, this is a message to SQS!"; +sqs_publish_message("q1", $var(msg)); + +... + +``` + + +### Examples + + +#### Event-Driven Messaging with *Event Interface* + + +OpenSIPS' event interface can be utilized to send messages to SQS by subscribing to an event and raising it when needed. + + +Steps: + + +- *Event Subscription:* +First, register the event subscription in your OpenSIPS configuration file within the `startup_route`: + + ``` + subscribe_event("MY_EVENT", + "sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2"); + + ``` +- *Event Subscription via CLI:* +After starting OpenSIPS, you can subscribe to the event from another terminal using the OpenSIPS CLI: + + ``` + opensips-cli -x mi event_subscribe MY_EVENT \ + sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2 + + ``` +- *Raise the Event and Send Message:* +Finally, to send a message, raise the subscribed event with the desired message content: + + ``` + opensips-cli -x mi raise_event MY_EVENT 'OpenSIPS Message' + + ``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_sqs/doc/contributors.xml b/modules/event_sqs/doc/contributors.xml deleted file mode 100644 index c71d2752800..00000000000 --- a/modules/event_sqs/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Alexandra Titoc - 28 - 7 - 1629 - 366 - - - 2. - Razvan Crainea (@razvancrainea) - 5 - 3 - 9 - 4 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Sep 2024 - Sep 2024 - - - 2. - Alexandra Titoc - Aug 2024 - Aug 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Alexandra Titoc. -
- -
diff --git a/modules/event_sqs/doc/event_sqs.xml b/modules/event_sqs/doc/event_sqs.xml deleted file mode 100644 index c7217ac42b5..00000000000 --- a/modules/event_sqs/doc/event_sqs.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - event_sqs Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 &osipssol; - diff --git a/modules/event_sqs/doc/event_sqs_admin.xml b/modules/event_sqs/doc/event_sqs_admin.xml deleted file mode 100644 index 42dd07c5a0d..00000000000 --- a/modules/event_sqs/doc/event_sqs_admin.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The event_sqs module is an implementation of an Amazon SQS producer. - It serves as a transport backend for the Event Interface and also provides a stand-alone - connector to be used from the OpenSIPS script in order to publish messages to SQS queues. - - - - - - -
- - -
- Dependencies -
- &osips; Modules - - There is no need to load any module before this module. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - AWS SDK for C++: - - By following these steps, you'll have the AWS SDK for C++ installed and - configured on your Linux system, allowing you to integrate with SQS: - AWS SDK for C++ Installation Guide - - - Additional instructions for installation can be found at: - AWS SDK for C++ GitHub Repository - - - - -
- -
- Deploying Amazon SQS locally on your computer - - For testing purposes, you can run SQS locally. To achieve this, you start localstack on your computer: - - -pip install localstack -localstack start - - - - Don't forget to set the necessary environment variables for testing, for example: - - - -export AWS_ACCESS_KEY_ID=test -export AWS_SECRET_ACCESS_KEY=test -export AWS_DEFAULT_REGION=us-east-1 - - - Here you can find some cli commands such as create-queue, send/receive-message, etc.: - - -
-
- -
- Exported Parameters -
- <varname>queue_url</varname> (string) - - This parameter specifies the configuration for an SQS queue that can be used - to publish messages directly from the script, using the sqs_publish_message() function - or to send messages using raise_event function. - - - - The format of the parameter is: [ID]sqs_url, where ID is an identifier - for this SQS queue instance and sqs_url is the full url of the queue. - - - The queue_url contains: - - endpoint - region - - - - This parameter can be set multiple times. - - - - Set queue_url parameter - - -... - -modparam("event_sqs", "queue_url", - "[q1]https://sqs.us-west-2.amazonaws.com/123456789012/Queue1") - -modparam("event_sqs", "queue_url", - "[q2]http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2") - -... - - - -
-
- - - - -
- Exported Functions - -
- sqs_publish_message(queue_id, message) - Publishes a message to an SQS queue. As the actual - send operation is done asynchronously, this function does not block and returns - immediately after queuing the message for sending. - This function can be used from any route. - The function has the following parameters: - - - - queue_id (string) The ID of the SQS queue. Must be one of the IDs defined through the `queue_url` modparam. - - - - - - message (string) - The payload of the message to publish. - - - - -
- -
- - sqs_publish_message() function usage - - -... - -$var(msg) = "Hello, this is a message to SQS!"; -sqs_publish_message("q1", $var(msg)); - -... - - -
- - -
- -
- Examples - -
- Event-Driven Messaging with <emphasis>Event Interface</emphasis> - - - OpenSIPS' event interface can be utilized to send messages to SQS by subscribing to an event and raising it when needed. - - Steps: - - Event Subscription: - First, register the event subscription in your OpenSIPS configuration file within the `startup_route`: - - -subscribe_event("MY_EVENT", - "sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2"); - - - - Event Subscription via CLI: - After starting OpenSIPS, you can subscribe to the event from another terminal using the OpenSIPS CLI: - - -opensips-cli -x mi event_subscribe MY_EVENT \ - sqs:http://sqs.us-east-1.localhost.localstack.cloud:4566/000000000000/Queue2 - - - - Raise the Event and Send Message: - Finally, to send a message, raise the subscribed event with the desired message content: - - -opensips-cli -x mi raise_event MY_EVENT 'OpenSIPS Message' - - - - - - -
-
- -
- diff --git a/modules/event_stream/README b/modules/event_stream/README deleted file mode 100644 index b6c62f818c3..00000000000 --- a/modules/event_stream/README +++ /dev/null @@ -1,346 +0,0 @@ -event_stream Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Stream socket syntax - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. reliable_mode (integer) - 1.4.2. timeout (integer) - 1.4.3. event_param (string) - - 1.5. Exported Functions - 1.6. Examples - - 1.6.1. - 1.6.2. JSON-RPC notification - 1.6.3. JSON-RPC Request - 1.6.4. JSON-RPC Notification with Event's name - 1.6.5. Custom JSON-RPC Notification from script - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set reliable_mode parameter - 1.2. Set timeout parameter - 1.3. Set event_param parameter - 1.4. Stream socket - 1.5. E_PIKE_BLOCKED JSON-RPC notification - 1.6. E_PIKE_BLOCKED JSON-RPC request (reliable_mode) - 1.7. E_PIKE_BLOCKED notification with event name - 1.8. E_PIKE_BLOCKED event - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a TCP transport layer implementation for - the Event Interface. The module can either send a JSON-RPC - notification or a standard request and wait for the response - (when used in reliable_mode). - - As the JSON-RPC is sent directly over TCP, avoiding any - application transport layer (such as HTTP), this module offers - a very lightweight and reliable way of delivering events to an - application server. - - In order to be notified, a JSON-RPC server has to subscribe for - a certain event provided by OpenSIPS. This can be done using - the generic MI Interface (event_subscribe function) or from - OpenSIPS script (subscribe_event core function). - -1.2. Stream socket syntax - - 'tcp:' host ':' port ['/' method] - - Meaning: - * 'tcp:' - specifies the transport protocol used by the Event - Interface to send the command. the tcp token indicates that - the subscriber's events should be notified using the - event_strea, module. - * host - host name of the JSON-RPC server. - * port - port of the JSON-RPC server. - * method - method called remotely by the JSON-RPC client. - NOTE: this parameter is optional - if it is missing, the - method used is the actual event subscribed to (i.e. if - localhost:8080 subscribes to the E_PIKE_BLOCKED event, the - RPC call will use the E_PIKE_BLOCKED method. - - The JSON-RPC command is built as it follows: - * id - uniquly generated if reliable_mode is used, otherwise - (for notifications) null. - * method - if no method is specified in the socket, the name - of the event is set as method, otherwise the token - specified is used. - * params - if the event sent contains named parameters, then - this parameter contains a JSON object with an object for - each parameter. If the event sent only contains values, the - parameters will be sent as an array. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * none. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. reliable_mode (integer) - - This parameter controls the way the event_stream module - communicates with the JSON-RPC server. If enabled, (set to 1), - each event is translated to a JSON-RPC request. If disabled, - each event will be sent as a JSON-RPC notification - there will - be no reply expected by our client. - - Note that if you need a reliable communication with the - JSON-RPC server, where each event sent needs to be confirmed - (by a JSON-RPC response), you must set this parameter to 1/yes. - If you are using this module in a failover setup (using the - event_virtual module), it is recommended to set this parameter - to 1/yes. - - Default value is “0 (disabled)”. - - Example 1.1. Set reliable_mode parameter -... -modparam("event_stream", "reliable_mode", yes) -... - -1.4.2. timeout (integer) - - Specified the amount of milliseconds the module waits for a - command to complete. In reliable_mode, it specifies the time - module waits the request to be sent and a reply received. In - non-reliable_mode, it represents only the time opensips takes - to send the JSON-RPC notification. - - NOTE that if the event is not using names for its parameters, - the event will be the first parameter in the JSON-RPC command. - - Default value is “1000 milliseconds = 1 second”. - - Example 1.2. Set timeout parameter -... -# only wait for 200 milliseonds for a reply -modparam("event_stream", "timeout", 200) -... - -1.4.3. event_param (string) - - By default, the name of the event subscribed to is not send in - the JSON-RPC command. If one needs to send the name of the - event as well, you can use this parameter to specify the name - of JSON object within the params that will contain the name of - the event. - - Default value is “disabled” - event is not added. - - Example 1.3. Set event_param parameter -... -modparam("event_stream", "event_param", "opensips_event") -# json resulted will contain the "opensips_event": EVENT token -... - -1.5. Exported Functions - - No function exported to be used from configuration file. - -1.6. Examples - - Example 1.4. Stream socket - - # calls the 'block_ip' method - tcp:127.0.0.1:8080/block_ip - - # calls the 'E_PIKE_BLOCKED' method, if subscribed to the E_PIKE -_BLOCKED event - tcp:127.0.0.1:8080 - - -1.6.2. JSON-RPC notification - - This is an example of an event raised when reliable_mode is - disabled by the pike module when it decides an ip should be - blocked: - - Example 1.5. E_PIKE_BLOCKED JSON-RPC notification - -{ - "jsonrpc": "2.0", - "method": "E_PIKE_BLOCKED", - "params": { - "ip": "192.168.2.11" - } -} - - -1.6.3. JSON-RPC Request - - This is an example of an event raised in reliable_mode by the - pike module when it decides an ip should be blocked: - - Example 1.6. E_PIKE_BLOCKED JSON-RPC request (reliable_mode) - -# request -{ - "id": 915243442, - "jsonrpc": "2.0", - "method": "E_PIKE_BLOCKED", - "params": { - "ip": "192.168.2.11" - } -} - -# reply -{ - "jsonrpc": "2.0", - "result": 8, - "id": 915243442 -} - - -1.6.4. JSON-RPC Notification with Event's name - - when having the event_param set to opensips_event, the event - raised by the pike module will look like the following: - - Example 1.7. E_PIKE_BLOCKED notification with event name - -# module configuration -modparam("event_stream", "event_param", "opensips_event") - -# Stream socket: tcp:HOST:PORT/handle_cmd - -# JSON-RPC command sent -{ - "jsonrpc": "2.0", - "method": "handle_cmd", - "params": { - "opensips_event": "E_PIKE_BLOCKED" - "ip": "192.168.2.11" - } -} - - -1.6.5. Custom JSON-RPC Notification from script - - This example contains a snippet to send a custom event from the - script using the event_stream module. - - Note that we are only populating values for the event, we are - not assinging names to those values. Therefore, the parameters - will be sent as an array. - - Example 1.8. E_PIKE_BLOCKED event - -startup_route { - subscribe_event("E_MY_EVENT", "tcp:127.0.0.1:8080"); -} - -route { - ... - $avp(attr-val) = 3; - $avp(attr-val) = 5; - raise_event("E_MY_EVENT", $avp(attr-val)); - ... -} - -# JSON-RPC command sent -{ - "jsonrpc": "2.0", - "method": "E_MY_EVENT", - "params": [3, 5] -} - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 32 14 1802 100 - 2. Vlad Patrascu (@rvlad-patrascu) 10 6 105 145 - 3. Liviu Chircu (@liviuchircu) 8 6 14 42 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 7 9 - 5. Maksym Sobolyev (@sobomax) 4 2 3 4 - 6. Peter Lemenkov (@lemenkov) 4 2 2 2 - 7. Alexandra Titoc 3 1 1 1 - 8. Ryan Bullock 2 1 2 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ryan Bullock Apr 2025 - Apr 2025 - 2. Liviu Chircu (@liviuchircu) Apr 2018 - Mar 2025 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Vlad Patrascu (@rvlad-patrascu) May 2020 - Jun 2023 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Aug 2020 - 7. Razvan Crainea (@razvancrainea) Mar 2018 - Jan 2020 - 8. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2019 - Apr 2019 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2018 www.opensips-solutions.com diff --git a/modules/event_stream/README.md b/modules/event_stream/README.md new file mode 100644 index 00000000000..8f54deab425 --- /dev/null +++ b/modules/event_stream/README.md @@ -0,0 +1,303 @@ +--- +title: "event_stream Module" +description: "This module provides a TCP transport layer implementation for the Event Interface." +--- + +## Admin Guide + + +### Overview + + +This module provides a TCP transport layer implementation for the Event +Interface. The module can either send a JSON-RPC notification or a +standard request and wait for the response (when used in +*reliable_mode*). + + +As the JSON-RPC is sent directly over TCP, avoiding any application +transport layer (such as HTTP), this module offers a very lightweight +and reliable way of delivering events to an application server. + + +In order to be notified, a JSON-RPC server has to subscribe for a +certain event provided by OpenSIPS. This can be done using the generic +MI Interface (*event_subscribe* function) or from +OpenSIPS script (*subscribe_event* core function). + + +### Stream socket syntax + + +*'tcp:' host ':' port ['/' method]* + + +Meaning: + + +- *'tcp:'* - specifies the +transport protocol used by the Event Interface +to send the command. the *tcp* +token indicates that the subscriber's events should be +notified using the +*event_strea,* module. +- *host* - host name of the JSON-RPC server. +- *port* - port of the JSON-RPC server. +- *method* - method called remotely by the +JSON-RPC client. +NOTE: this parameter is optional - if it is missing, +the method used is the actual event subscribed +to (i.e. if *localhost:8080* +subscribes to the *E_PIKE_BLOCKED* +event, the RPC call will use the +*E_PIKE_BLOCKED* method. + + +The JSON-RPC command is built as it follows: + + +- *id* - uniquly generated if +*reliable_mode* is used, otherwise (for +notifications) *null*. +- *method* - if no method is specified in the +socket, the name of the event is set as method, otherwise +the token specified is used. +- *params* - if the event sent contains +named parameters, then this parameter contains a JSON object +with an object for each parameter. If the event sent only +contains values, the parameters will be sent as an array. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *none*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### reliable_mode (integer) + + +This parameter controls the way the +*event_stream* module communicates +with the JSON-RPC server. If enabled, (set to +*1*), each event is translated to +a JSON-RPC request. If disabled, each event will be sent +as a JSON-RPC notification - there will be no reply +expected by our client. + + +Note that if you need a reliable communication with +the JSON-RPC server, where each event sent needs to be +confirmed (by a JSON-RPC response), you must set this parameter +to *1/yes*. If you are using this +module in a failover setup (using the +*event_virtual* module), it is recommended +to set this parameter to *1/yes*. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set reliable_mode parameter" +... +modparam("event_stream", "reliable_mode", yes) +... +``` + + +#### timeout (integer) + + +Specified the amount of milliseconds the module +waits for a command to complete. In +*reliable_mode*, it specifies the time +module waits the request to be sent and a reply received. +In non-*reliable_mode*, it represents +only the time opensips takes to send the JSON-RPC +notification. + + +NOTE that if the event is not using names for its parameters, +the event will be the first parameter in the JSON-RPC command. + + +*Default value is "1000 milliseconds = 1 second".* + + +```opensips title="Set timeout parameter" +... +# only wait for 200 milliseonds for a reply +modparam("event_stream", "timeout", 200) +... +``` + + +#### event_param (string) + + +By default, the name of the event subscribed to is not +send in the JSON-RPC command. If one needs to send the +name of the event as well, you can use this parameter to +specify the name of JSON object within the params that +will contain the name of the event. + + +*Default value is "disabled" - event is not added.* + + +```opensips title="Set event_param parameter" +... +modparam("event_stream", "event_param", "opensips_event") +# json resulted will contain the "opensips_event": EVENT token +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Examples + + +```c title="Stream socket" + # calls the 'block_ip' method + tcp:127.0.0.1:8080/block_ip + + # calls the 'E_PIKE_BLOCKED' method, if subscribed to the E_PIKE_BLOCKED event + tcp:127.0.0.1:8080 +``` + + +#### JSON-RPC notification + + +This is an example of an event raised when +*reliable_mode* is disabled +by the pike module when it decides an ip should be blocked: + + +```c title="E_PIKE_BLOCKED JSON-RPC notification" +{ + "jsonrpc": "2.0", + "method": "E_PIKE_BLOCKED", + "params": { + "ip": "192.168.2.11" + } +} +``` + + +#### JSON-RPC Request + + +This is an example of an event raised in +*reliable_mode* by the pike module +when it decides an ip should be blocked: + + +```c title="E_PIKE_BLOCKED JSON-RPC request (reliable_mode)" +# request +{ + "id": 915243442, + "jsonrpc": "2.0", + "method": "E_PIKE_BLOCKED", + "params": { + "ip": "192.168.2.11" + } +} + +# reply +{ + "jsonrpc": "2.0", + "result": 8, + "id": 915243442 +} +``` + + +#### JSON-RPC Notification with Event's name + + +when having the *event_param* set to +*opensips_event*, the event raised by +the pike module will look like the following: + + +```c title="E_PIKE_BLOCKED notification with event name" +# module configuration +modparam("event_stream", "event_param", "opensips_event") + +# Stream socket: tcp:HOST:PORT/handle_cmd + +# JSON-RPC command sent +{ + "jsonrpc": "2.0", + "method": "handle_cmd", + "params": { + "opensips_event": "E_PIKE_BLOCKED" + "ip": "192.168.2.11" + } +} +``` + + +#### Custom JSON-RPC Notification from script + + +This example contains a snippet to send a custom +event from the script using the +*event_stream* module. + + +Note that we are only populating values for the +event, we are not assinging names to those values. +Therefore, the parameters will be sent as an array. + + +```c title="E_PIKE_BLOCKED event" +startup_route { + subscribe_event("E_MY_EVENT", "tcp:127.0.0.1:8080"); +} + +route { + ... + $avp(attr-val) = 3; + $avp(attr-val) = 5; + raise_event("E_MY_EVENT", $avp(attr-val)); + ... +} + +# JSON-RPC command sent +{ + "jsonrpc": "2.0", + "method": "E_MY_EVENT", + "params": [3, 5] +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_stream/doc/contributors.xml b/modules/event_stream/doc/contributors.xml deleted file mode 100644 index 37785b2e612..00000000000 --- a/modules/event_stream/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 32 - 14 - 1802 - 100 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 10 - 6 - 105 - 145 - - - 3. - Liviu Chircu (@liviuchircu) - 8 - 6 - 14 - 42 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 7 - 9 - - - 5. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 6. - Peter Lemenkov (@lemenkov) - 4 - 2 - 2 - 2 - - - 7. - Alexandra Titoc - 3 - 1 - 1 - 1 - - - 8. - Ryan Bullock - 2 - 1 - 2 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ryan Bullock - Apr 2025 - Apr 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Apr 2018 - Mar 2025 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2020 - Jun 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Aug 2020 - - - 7. - Razvan Crainea (@razvancrainea) - Mar 2018 - Jan 2020 - - - 8. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2019 - Apr 2019 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/event_stream/doc/event_stream.xml b/modules/event_stream/doc/event_stream.xml deleted file mode 100644 index 20136513ad6..00000000000 --- a/modules/event_stream/doc/event_stream.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - event_stream Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2018 &osipssol; - diff --git a/modules/event_stream/doc/event_stream_admin.xml b/modules/event_stream/doc/event_stream_admin.xml deleted file mode 100644 index 34052eadf31..00000000000 --- a/modules/event_stream/doc/event_stream_admin.xml +++ /dev/null @@ -1,361 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a TCP transport layer implementation for the Event - Interface. The module can either send a JSON-RPC notification or a - standard request and wait for the response (when used in - reliable_mode). - - - - As the JSON-RPC is sent directly over TCP, avoiding any application - transport layer (such as HTTP), this module offers a very lightweight - and reliable way of delivering events to an application server. - - - - In order to be notified, a JSON-RPC server has to subscribe for a - certain event provided by OpenSIPS. This can be done using the generic - MI Interface (event_subscribe function) or from - OpenSIPS script (subscribe_event core function). - -
- -
- Stream socket syntax - - 'tcp:' host ':' port ['/' method] - - - Meaning: - - - 'tcp:' - specifies the - transport protocol used by the Event Interface - to send the command. the tcp - token indicates that the subscriber's events should be - notified using the - event_strea, module. - - - host - host name of the JSON-RPC server. - - - port - port of the JSON-RPC server. - - - method - method called remotely by the - JSON-RPC client. - NOTE: this parameter is optional - if it is missing, - the method used is the actual event subscribed - to (i.e. if localhost:8080 - subscribes to the E_PIKE_BLOCKED - event, the RPC call will use the - E_PIKE_BLOCKED method. - - - - - - - The JSON-RPC command is built as it follows: - - - id - uniquly generated if - reliable_mode is used, otherwise (for - notifications) null. - - - method - if no method is specified in the - socket, the name of the event is set as method, otherwise - the token specified is used. - - - params - if the event sent contains - named parameters, then this parameter contains a JSON object - with an object for each parameter. If the event sent only - contains values, the parameters will be sent as an array. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters -
- <varname>reliable_mode</varname> (integer) - - This parameter controls the way the - event_stream module communicates - with the JSON-RPC server. If enabled, (set to - 1), each event is translated to - a JSON-RPC request. If disabled, each event will be sent - as a JSON-RPC notification - there will be no reply - expected by our client. - - - Note that if you need a reliable communication with - the JSON-RPC server, where each event sent needs to be - confirmed (by a JSON-RPC response), you must set this parameter - to 1/yes. If you are using this - module in a failover setup (using the - event_virtual module), it is recommended - to set this parameter to 1/yes. - - - - Default value is 0 (disabled). - - - - Set <varname>reliable_mode</varname> parameter - -... -modparam("event_stream", "reliable_mode", yes) -... - - -
-
- <varname>timeout</varname> (integer) - - Specified the amount of milliseconds the module - waits for a command to complete. In - reliable_mode, it specifies the time - module waits the request to be sent and a reply received. - In non-reliable_mode, it represents - only the time opensips takes to send the JSON-RPC - notification. - - - NOTE that if the event is not using names for its parameters, - the event will be the first parameter in the JSON-RPC command. - - - - Default value is 1000 milliseconds = 1 second. - - - - Set <varname>timeout</varname> parameter - -... -# only wait for 200 milliseonds for a reply -modparam("event_stream", "timeout", 200) -... - - -
-
- <varname>event_param</varname> (string) - - By default, the name of the event subscribed to is not - send in the JSON-RPC command. If one needs to send the - name of the event as well, you can use this parameter to - specify the name of JSON object within the params that - will contain the name of the event. - - - - Default value is disabled - event is not added. - - - - Set <varname>event_param</varname> parameter - -... -modparam("event_stream", "event_param", "opensips_event") -# json resulted will contain the "opensips_event": EVENT token -... - - -
-
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Examples -
- - Stream socket - - - # calls the 'block_ip' method - tcp:127.0.0.1:8080/block_ip - - # calls the 'E_PIKE_BLOCKED' method, if subscribed to the E_PIKE_BLOCKED event - tcp:127.0.0.1:8080 - - - -
- -
- JSON-RPC notification - - This is an example of an event raised when - reliable_mode is disabled - by the pike module when it decides an ip should be blocked: - - - E_PIKE_BLOCKED JSON-RPC notification - - - - -
- -
- JSON-RPC Request - - This is an example of an event raised in - reliable_mode by the pike module - when it decides an ip should be blocked: - - - E_PIKE_BLOCKED JSON-RPC request (reliable_mode) - - - - -
- -
- JSON-RPC Notification with Event's name - - when having the event_param set to - opensips_event, the event raised by - the pike module will look like the following: - - - E_PIKE_BLOCKED notification with event name - - - - -
- -
- Custom JSON-RPC Notification from script - - This example contains a snippet to send a custom - event from the script using the - event_stream module. - - - Note that we are only populating values for the - event, we are not assinging names to those values. - Therefore, the parameters will be sent as an array. - - - E_PIKE_BLOCKED event - - - - -
- -
-
diff --git a/modules/event_virtual/README b/modules/event_virtual/README deleted file mode 100644 index 72df18e97ab..00000000000 --- a/modules/event_virtual/README +++ /dev/null @@ -1,181 +0,0 @@ -event_virtual Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Virtual socket syntax - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - - 1.4. External Libraries or Applications - 1.5. Exported Parameters - - 1.5.1. failover_timeout (integer) - - 1.6. Exported Functions - 1.7. Example - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the failover_timeout parameter - 1.2. Virtual socket - -Chapter 1. Admin Guide - -1.1. Overview - - The event_virtual module provides the possibility to have - multiple external applications, using different transport - protocols, subscribed to the OpenSIPS Event Interface as a - single virtual subscriber, for a specific event. When an event - is triggered, the event_virtual module notifies the specified - transport modules using one of the following policies: - * PARALLEL - all subscribers (applications) are notified at - once - * FAILOVER - for every event raised, try to notify the - subscribers, in the order in which they are given, until - the first successful notification. A failed subscriber is - skipped for further notifications until the - failover_timeout passes. - * ROUND-ROBIN - for every event raised, notify the - subscribers alternatively, in the order in which they are - given (for each raised event notify a different subscriber) - - Only one expire value can be used (for the whole virtual - subscription), and not one for each individual subscriber. - -1.2. Virtual socket syntax - - virtual:policy subscriber_1 [[subscriber_2] ...] - - Meanings: - * virtual: - informs the Event Interface that the events sent - to this subscriber should be handled by the event_virtual - module - * policy - subscriber notification policy, can have one of - the following values: 'PARALLEL', 'FAILOVER', 'ROUND-ROBIN' - (with the behaviour described above) - + !! Important: Policies must always be specified as - uppercase strings! - * subscriber_1 - use the socket syntax for this specific - subscriber (eg. "rabbitmq:guest:guest@127.0.0.1:5672/pike") - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - - The OpenSIPS event modules which implement the transport - protocols used by the subscribers. - -1.4. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.5. Exported Parameters - -1.5.1. failover_timeout (integer) - - The minimum duration in seconds that a failed subscriber is - skipped for further notifications. This parameter only affects - the FAILOVER policy. - - Default value is “30”. - - Example 1.1. Setting the failover_timeout parameter -... -modparam("event_virtual", "failover_timeout", 5) -... - -1.6. Exported Functions - - No exported functions to be used in the configuration file. - -1.7. Example - - Example 1.2. Virtual socket - - The sockets of the subscribers may be separated by any number - of spaces or tabs: - - virtual:PARALLEL rabbitmq:guest:guest@127.0.0.1:5672/pike flatst -ore:/var/log/opensips_proxy.log - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 22 10 1057 125 - 2. Liviu Chircu (@liviuchircu) 8 6 39 36 - 3. Razvan Crainea (@razvancrainea) 6 4 4 2 - 4. Maksym Sobolyev (@sobomax) 4 2 3 4 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 3 2 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Liviu Chircu (@liviuchircu) May 2016 - Dec 2021 - 3. Vlad Patrascu (@rvlad-patrascu) Jul 2015 - Jul 2020 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu - (@liviuchircu), Peter Lemenkov (@lemenkov). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/event_virtual/README.md b/modules/event_virtual/README.md new file mode 100644 index 00000000000..5aa54fb115f --- /dev/null +++ b/modules/event_virtual/README.md @@ -0,0 +1,109 @@ +--- +title: "event_virtual Module" +description: "The *event_virtual* module provides the possibility to have multiple external applications, using different transport protocols, subscribed to the OpenSIPS Event Interface as a single virtual subscriber, for a specific event." +--- + +## Admin Guide + + +### Overview + + +The *event_virtual* +module provides the possibility to have multiple external applications, using different transport protocols, subscribed to the OpenSIPS Event Interface as a single virtual subscriber, for a specific event. When an event is triggered, the event_virtual module notifies the specified transport modules using one of the following policies: + + +- *PARALLEL* - all subscribers (applications) are notified at once +- *FAILOVER* - for every event raised, try to +notify the subscribers, in the order in which they are given, +until the first successful notification. A failed subscriber is +skipped for further notifications until the +[failover timeout](#param_failover_timeout) passes. +- *ROUND-ROBIN* - for every event raised, notify the subscribers alternatively, in the order in which they are given (for each raised event notify a different subscriber) + + +Only one expire value can be used (for the whole virtual subscription), and not one for each individual subscriber. + + +### Virtual socket syntax + + +*virtual:policy subscriber_1 [[subscriber_2] ...]* + + +Meanings: + + +- *virtual:* - informs the Event Interface that the +events sent to this subscriber should be handled by the +*event_virtual* module +- *policy* - subscriber notification policy, can have one of the following values: 'PARALLEL', 'FAILOVER', 'ROUND-ROBIN' (with the behaviour described above) + + + *!! Important: Policies must always be specified as + uppercase strings!* +- *subscriber_1* - use the socket syntax for this specific subscriber (eg. "rabbitmq:guest:guest@127.0.0.1:5672/pike") + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: +*The OpenSIPS event modules which implement the transport protocols used by the subscribers*. + + +### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### failover_timeout (integer) + + +The minimum duration in seconds that a failed subscriber is +skipped for further notifications. This parameter only affects +the *FAILOVER* policy. + + +*Default value is "30".* + + +```opensips title="Setting the failover_timeout parameter" +... +modparam("event_virtual", "failover_timeout", 5) +... + +``` + + +### Exported Functions + + +No exported functions to be used in the configuration file. + + +### Example + + +The sockets of the subscribers may be separated by any number of spaces or tabs: + + +```c title="Virtual socket" + virtual:PARALLEL rabbitmq:guest:guest@127.0.0.1:5672/pike flatstore:/var/log/opensips_proxy.log +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_virtual/doc/contributors.xml b/modules/event_virtual/doc/contributors.xml deleted file mode 100644 index 5c25a643496..00000000000 --- a/modules/event_virtual/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 22 - 10 - 1057 - 125 - - - 2. - Liviu Chircu (@liviuchircu) - 8 - 6 - 39 - 36 - - - 3. - Razvan Crainea (@razvancrainea) - 6 - 4 - 4 - 2 - - - 4. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 3 - 2 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Liviu Chircu (@liviuchircu) - May 2016 - Dec 2021 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - Jul 2015 - Jul 2020 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov). -
- -
diff --git a/modules/event_virtual/doc/event_virtual.xml b/modules/event_virtual/doc/event_virtual.xml deleted file mode 100644 index bf94403d4ac..00000000000 --- a/modules/event_virtual/doc/event_virtual.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - event_virtual Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/event_virtual/doc/event_virtual_admin.xml b/modules/event_virtual/doc/event_virtual_admin.xml deleted file mode 100644 index ee4aace88bd..00000000000 --- a/modules/event_virtual/doc/event_virtual_admin.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The event_virtual - module provides the possibility to have multiple external applications, using different transport protocols, subscribed to the &osips; Event Interface as a single virtual subscriber, for a specific event. When an event is triggered, the event_virtual module notifies the specified transport modules using one of the following policies: - - - PARALLEL - all subscribers (applications) are notified at once - - - FAILOVER - for every event raised, try to - notify the subscribers, in the order in which they are given, - until the first successful notification. A failed subscriber is - skipped for further notifications until the - passes. - - - ROUND-ROBIN - for every event raised, notify the subscribers alternatively, in the order in which they are given (for each raised event notify a different subscriber) - - - Only one expire value can be used (for the whole virtual subscription), and not one for each individual subscriber. - -
-
- Virtual socket syntax - - virtual:policy subscriber_1 [[subscriber_2] ...] - - - Meanings: - - - - virtual: - informs the Event Interface that the - events sent to this subscriber should be handled by the - event_virtual module - - - - policy - subscriber notification policy, can have one of the following values: 'PARALLEL', 'FAILOVER', 'ROUND-ROBIN' (with the behaviour described above) - - - - !! Important: Policies must always be specified as - uppercase strings! - - - - - - subscriber_1 - use the socket syntax for this specific subscriber (eg. "rabbitmq:guest:guest@127.0.0.1:5672/pike") - - - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - The OpenSIPS event modules which implement the transport protocols used by the subscribers. - - -
-
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- Exported Parameters -
- <varname>failover_timeout</varname> (integer) - - The minimum duration in seconds that a failed subscriber is - skipped for further notifications. This parameter only affects - the FAILOVER policy. - - - - Default value is 30. - - - - Setting the <varname>failover_timeout</varname> parameter - -... -modparam("event_virtual", "failover_timeout", 5) -... - - -
-
-
- Exported Functions - - No exported functions to be used in the configuration file. - -
-
- Example - - Virtual socket - - The sockets of the subscribers may be separated by any number of spaces or tabs: - - - - virtual:PARALLEL rabbitmq:guest:guest@127.0.0.1:5672/pike flatstore:/var/log/opensips_proxy.log - - - -
-
diff --git a/modules/event_xmlrpc/README b/modules/event_xmlrpc/README deleted file mode 100644 index 70a29edda08..00000000000 --- a/modules/event_xmlrpc/README +++ /dev/null @@ -1,204 +0,0 @@ -event_xmlrpc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. XMLRPC socket syntax - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. use_struct_param (integer) - - 1.5. Exported Functions - 1.6. Example - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set use_struct_param parameter - 1.2. E_PIKE_BLOCKED event - 1.3. XMLRPC socket - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of an XMLRPC client used to - notify XMLRPC servers whenever certain notifications are raised - by OpenSIPS. It acts as a transport layer for the Event - Notification Interface. - - Basicly, the module executes a remote procedure call when an - event is raised from OpenSIPS's script, core or modules using - the Event Interface. - - In order to be notified, an XMLRPC server has to subscribe for - a certain event provided by OpenSIPS. This can be done using - the generic MI Interface (event_subscribe function) or from - OpenSIPS script (subscribe_event core function). - -1.2. XMLRPC socket syntax - - 'xmlrpc:' host ':' port ':' method - - Meanings: - * 'xmlrpc:' - informs the Event Interface that the events - sent to this subscriber should be handled by the - event_xmlrpc module. - * host - host name of the XMLRPC server. - * port - port of the XMLRPC server. - * method - method called remotely by the XMLRPC client. - NOTE: the client does not wait for a response from the - XMLRPC server. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * none. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. use_struct_param (integer) - - When raising an event, pack the name and value of the - parameters in a XMLRPC structure. This provides an easier way - for some XMLRPC server implementations to interpret the - parameters. Set it to zero to disable or to non-zero to enable - it. - - Default value is “0 (disabled)”. - - Example 1.1. Set use_struct_param parameter -... -modparam("event_xmlrpc", "use_struct_param", 1) -... - -1.5. Exported Functions - - No function exported to be used from configuration file. - -1.6. Example - - This is an example of an event raised by the pike module when - it decides an ip should be blocked: - - Example 1.2. E_PIKE_BLOCKED event - - -POST /RPC2 HTTP/1.1. -Host: 127.0.0.1:8081. -Connection: close. -User-Agent: OpenSIPS XMLRPC Notifier. -Content-type: text/xml. -Content-length: 240. - . - - - e_dummy_h - - - E_MY_EVENT - - - ip - 192.168.2.11 - - - - - - Example 1.3. XMLRPC socket - - # calls the 'block_ip' function - xmlrpc:127.0.0.1:8080:block_ip - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 37 23 1239 131 - 2. Liviu Chircu (@liviuchircu) 10 8 63 39 - 3. Vlad Patrascu (@rvlad-patrascu) 10 6 208 65 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 8 9 - 5. Maksym Sobolyev (@sobomax) 5 3 4 4 - 6. Ionut Ionita (@ionutrazvanionita) 3 1 103 28 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - 8. Ryan Bullock (@rrb3942) 2 1 8 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Oct 2013 - Jun 2023 - 2. Vlad Patrascu (@rvlad-patrascu) Jul 2015 - Jun 2023 - 3. Maksym Sobolyev (@sobomax) Feb 2017 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) May 2012 - Jan 2020 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Ionut Ionita (@ionutrazvanionita) Jan 2016 - Jan 2016 - 8. Ryan Bullock (@rrb3942) Jan 2013 - Jan 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2012 www.opensips-solutions.com diff --git a/modules/event_xmlrpc/README.md b/modules/event_xmlrpc/README.md new file mode 100644 index 00000000000..1f1f06b6eaf --- /dev/null +++ b/modules/event_xmlrpc/README.md @@ -0,0 +1,138 @@ +--- +title: "event_xmlrpc Module" +description: "This module is an implementation of an XMLRPC client used to notify XMLRPC servers whenever certain notifications are raised by OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of an XMLRPC client used to notify +XMLRPC servers whenever certain notifications are raised by OpenSIPS. It +acts as a transport layer for the Event Notification Interface. + + +Basicly, the module executes a remote procedure call when an event is +raised from OpenSIPS's script, core or modules using the Event +Interface. + + +In order to be notified, an XMLRPC server has to subscribe for a certain +event provided by OpenSIPS. This can be done using the generic MI +Interface (*event_subscribe* function) or from +OpenSIPS script (*subscribe_event* core function). + + +### XMLRPC socket syntax + + +*'xmlrpc:' host ':' port ':' method* + + +Meanings: + + +- *'xmlrpc:'* - informs the Event Interface +that the events sent to this subscriber should be handled +by the *event_xmlrpc* module. +- *host* - host name of the XMLRPC server. +- *port* - port of the XMLRPC server. +- *method* - method called remotely by the +XMLRPC client. +NOTE: the client does not wait for a response from the +XMLRPC server. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *none*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### use_struct_param (integer) + + +When raising an event, pack the name and value of the +parameters in a XMLRPC structure. This provides an easier +way for some XMLRPC server implementations to interpret +the parameters. +Set it to zero to disable or to non-zero to enable it. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set use_struct_param parameter" +... +modparam("event_xmlrpc", "use_struct_param", 1) +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Example + + +This is an example of an event raised by the pike module +when it decides an ip should be blocked: + + +```c title="E_PIKE_BLOCKED event" +POST /RPC2 HTTP/1.1. +Host: 127.0.0.1:8081. +Connection: close. +User-Agent: OpenSIPS XMLRPC Notifier. +Content-type: text/xml. +Content-length: 240. + . + + + e_dummy_h + + + E_MY_EVENT + + + ip + 192.168.2.11 + + + +``` + + +```c title="XMLRPC socket" +# calls the 'block_ip' function +xmlrpc:127.0.0.1:8080:block_ip +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/event_xmlrpc/doc/contributors.xml b/modules/event_xmlrpc/doc/contributors.xml deleted file mode 100644 index d7f43d3414d..00000000000 --- a/modules/event_xmlrpc/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 37 - 23 - 1239 - 131 - - - 2. - Liviu Chircu (@liviuchircu) - 10 - 8 - 63 - 39 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 10 - 6 - 208 - 65 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 8 - 9 - - - 5. - Maksym Sobolyev (@sobomax) - 5 - 3 - 4 - 4 - - - 6. - Ionut Ionita (@ionutrazvanionita) - 3 - 1 - 103 - 28 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 8. - Ryan Bullock (@rrb3942) - 2 - 1 - 8 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Oct 2013 - Jun 2023 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - Jul 2015 - Jun 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2017 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - May 2012 - Jan 2020 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Ionut Ionita (@ionutrazvanionita) - Jan 2016 - Jan 2016 - - - 8. - Ryan Bullock (@rrb3942) - Jan 2013 - Jan 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/event_xmlrpc/doc/event_xmlrpc.xml b/modules/event_xmlrpc/doc/event_xmlrpc.xml deleted file mode 100644 index 8dbb682639a..00000000000 --- a/modules/event_xmlrpc/doc/event_xmlrpc.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - event_xmlrpc Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2012 &osipssol; - - diff --git a/modules/event_xmlrpc/doc/event_xmlrpc_admin.xml b/modules/event_xmlrpc/doc/event_xmlrpc_admin.xml deleted file mode 100644 index 77a5c233993..00000000000 --- a/modules/event_xmlrpc/doc/event_xmlrpc_admin.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of an XMLRPC client used to notify - XMLRPC servers whenever certain notifications are raised by OpenSIPS. It - acts as a transport layer for the Event Notification Interface. - - - - Basicly, the module executes a remote procedure call when an event is - raised from OpenSIPS's script, core or modules using the Event - Interface. - - - - In order to be notified, an XMLRPC server has to subscribe for a certain - event provided by OpenSIPS. This can be done using the generic MI - Interface (event_subscribe function) or from - OpenSIPS script (subscribe_event core function). - -
- -
- XMLRPC socket syntax - - 'xmlrpc:' host ':' port ':' method - - - Meanings: - - - 'xmlrpc:' - informs the Event Interface - that the events sent to this subscriber should be handled - by the event_xmlrpc module. - - - host - host name of the XMLRPC server. - - - port - port of the XMLRPC server. - - - method - method called remotely by the - XMLRPC client. - NOTE: the client does not wait for a response from the - XMLRPC server. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters -
- <varname>use_struct_param</varname> (integer) - - When raising an event, pack the name and value of the - parameters in a XMLRPC structure. This provides an easier - way for some XMLRPC server implementations to interpret - the parameters. - Set it to zero to disable or to non-zero to enable it. - - - - Default value is 0 (disabled). - - - - Set <varname>use_struct_param</varname> parameter - -... -modparam("event_xmlrpc", "use_struct_param", 1) -... - - -
-
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Example - - This is an example of an event raised by the pike module - when it decides an ip should be blocked: - - - E_PIKE_BLOCKED event - - - - e_dummy_h - - - E_MY_EVENT - - - ip - 192.168.2.11 - - - -]]> - - - - - XMLRPC socket - - - # calls the 'block_ip' function - xmlrpc:127.0.0.1:8080:block_ip - - - - -
-
diff --git a/modules/example/README b/modules/example/README deleted file mode 100644 index 4b2326fd4a6..00000000000 --- a/modules/example/README +++ /dev/null @@ -1,185 +0,0 @@ -Example Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_str (string) - 1.3.2. default_int (integer) - - 1.4. Exported Functions - - 1.4.1. example() - 1.4.2. example_str([string]) - 1.4.3. example_int([int]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “default_str” parameter - 1.2. Set “default_int” parameter - 1.3. example usage - 1.4. example_str() usage - 1.5. example_int() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module serves as an example of how to write a module in - OpenSIPS. Its primary goal is to simplify the development of - new modules for newcomers, providing a clear and accessible - starting point. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. default_str (string) - - The default parameter used when the example_str() function is - called without any parameter. - - Default value is “” (empty sring). - - Example 1.1. Set “default_str” parameter -... -modparam("example", "default_str", "TEST") -... - -1.3.2. default_int (integer) - - The default parameter used when the example_int() function is - called without any parameter. - - Default value is “0”. - - Example 1.2. Set “default_int” parameter -... -modparam("example", "default_int", -1) -... - -1.4. Exported Functions - -1.4.1. example() - - Function that simply prints a message to log, saying that it - has been called. - - This function can be used from any route. - - Example 1.3. example usage -... -example(); -... - -1.4.2. example_str([string]) - - Function that simply prints a message to log, saying that it - has been called. If a parameter is passed, it is printed in the - log, otherwise the value of default_str parameter is used. - - Meaning of the parameters is as follows: - * string (string, optional) - parameter to be logged - - This function can be used from any route. - - Example 1.4. example_str() usage -... -example_str("test"); -... - -1.4.3. example_int([int]) - - Function that simply prints a message to log, saying that it - has been called. If a parameter is passed, it is printed in the - log, otherwise the value of default_int parameter is used. - - Meaning of the parameters is as follows: - * int (integer, optional) - parameter to be logged - - This function can be used from any route. - - Example 1.5. example_int() usage -... -example_int(10); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 4 1 349 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jul 2024 - Jul 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Solutions; diff --git a/modules/example/README.md b/modules/example/README.md new file mode 100644 index 00000000000..5dd4299c4e0 --- /dev/null +++ b/modules/example/README.md @@ -0,0 +1,145 @@ +--- +title: "Example Module" +description: "This module serves as an example of how to write a module in OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module serves as an example of how to write a module in OpenSIPS. +Its primary goal is to simplify the development of new modules for +newcomers, providing a clear and accessible starting point. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### default_str (string) + + +The default parameter used when the [example str](#func_example_str) +function is called without any parameter. + + +*Default value is "" (empty sring).* + + +```opensips title="Set 'default_str' parameter" +... +modparam("example", "default_str", "TEST") +... +``` + + +#### default_int (integer) + + +The default parameter used when the [example int](#func_example_int) +function is called without any parameter. + + +*Default value is "0".* + + +```opensips title="Set 'default_int' parameter" +... +modparam("example", "default_int", -1) +... +``` + + +### Exported Functions + + +#### example() + + +Function that simply prints a message to log, saying that it has been called. + + +This function can be used from any route. + + +```opensips title="example usage" +... +example(); +... +``` + + +#### example_str([string]) + + +Function that simply prints a message to log, saying that it has been called. +If a parameter is passed, it is printed in the log, otherwise the value of +[default str](#param_default_str) parameter is used. + + +Meaning of the parameters is as follows: + + +- *string (string, optional)* - parameter to be logged + + +This function can be used from any route. + + +```opensips title="example_str() usage" +... +example_str("test"); +... +``` + + +#### example_int([int]) + + +Function that simply prints a message to log, saying that it has been called. +If a parameter is passed, it is printed in the log, otherwise the value of +[default int](#param_default_int) parameter is used. + + +Meaning of the parameters is as follows: + + +- *int (integer, optional)* - parameter to be logged + + +This function can be used from any route. + + +```opensips title="example_int() usage" +... +example_int(10); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/example/doc/contributors.xml b/modules/example/doc/contributors.xml deleted file mode 100644 index 880497a1f9b..00000000000 --- a/modules/example/doc/contributors.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 4 - 1 - 349 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jul 2024 - Jul 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/example/doc/example.xml b/modules/example/doc/example.xml deleted file mode 100644 index f59aa3e4494..00000000000 --- a/modules/example/doc/example.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Example Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Solutions; - diff --git a/modules/example/doc/example_admin.xml b/modules/example/doc/example_admin.xml deleted file mode 100644 index 994061a5d94..00000000000 --- a/modules/example/doc/example_admin.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module serves as an example of how to write a module in OpenSIPS. - Its primary goal is to simplify the development of new modules for - newcomers, providing a clear and accessible starting point. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>default_str</varname> (string) - - The default parameter used when the - function is called without any parameter. - - - - Default value is (empty sring). - - - - Set <quote>default_str</quote> parameter - -... -modparam("example", "default_str", "TEST") -... - - -
-
- <varname>default_int</varname> (integer) - - The default parameter used when the - function is called without any parameter. - - - - Default value is 0. - - - - Set <quote>default_int</quote> parameter - -... -modparam("example", "default_int", -1) -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">example()</function> - - - Function that simply prints a message to log, saying that it has been called. - - - This function can be used from any route. - - - <function moreinfo="none">example</function> usage - -... -example(); -... - - -
-
- - <function moreinfo="none">example_str([string])</function> - - - Function that simply prints a message to log, saying that it has been called. - If a parameter is passed, it is printed in the log, otherwise the value of - parameter is used. - - Meaning of the parameters is as follows: - - - string (string, optional) - parameter to be logged - - - - - This function can be used from any route. - - - <function moreinfo="none">example_str()</function> usage - -... -example_str("test"); -... - - -
-
- - <function moreinfo="none">example_int([int])</function> - - - Function that simply prints a message to log, saying that it has been called. - If a parameter is passed, it is printed in the log, otherwise the value of - parameter is used. - - Meaning of the parameters is as follows: - - - int (integer, optional) - parameter to be logged - - - - - This function can be used from any route. - - - <function moreinfo="none">example_int()</function> usage - -... -example_int(10); -... - - -
-
- -
diff --git a/modules/exec/README b/modules/exec/README deleted file mode 100644 index 14b48ad4551..00000000000 --- a/modules/exec/README +++ /dev/null @@ -1,322 +0,0 @@ -exec Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. setvars (integer) - 1.3.2. time_to_kill (integer) - - 1.4. Exported Functions - - 1.4.1. exec(command, [stdin], [stdout], [stderr], - [envavp]) - - 1.5. Exported Asyncronous Functions - - 1.5.1. exec(command, [stdin], [stdout], [stderr], - [envavp]) - - 1.6. Known Issues - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “setvars” parameter - 1.2. Set “time_to_kill” parameter - 1.3. exec usage - 1.4. async exec usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Exec module enables the execution of external commands from - the OpenSIPS script. Any valid shell commands are accepted. The - final input string is evaluated and executed using the - "/bin/sh" symlink/binary. OpenSIPS may additionally pass a lot - more information about the request using environment variables: - * SIP_HF_ contains value of each header field in - request. If a header field occurred multiple times, values - are concatenated and comma-separated. is in - capital letters. Ff a header-field name occurred in compact - form, is canonical. - * SIP_TID is transaction identifier. All request - retransmissions or CANCELs/ACKs associated with a previous - INVITE result in the same value. - * SIP_DID is dialog identifier, which is the same as to-tag. - Initially, it is empty. - * SIP_SRCIP is source IP address from which request came. - * SIP_ORURI is original request URI. - * SIP_RURI is current request URI (if unchanged, equal to - original). - * SIP_USER is userpart of current request URI. - * SIP_OUSER is userpart of original request URI. - - NOTE: Any environment variables which are given to the exec - module functions must be specified using the '$$' delimiter - (e.g., $$SIP_OUSER), otherwise they will be evaluated as - OpenSIPS pseudo-variables, throwing scripting errors. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. setvars (integer) - - Set to 1 to enable setting all above-mentioned environment - variables for all executed commands. - - WARNING: Before enabling this parameter, make sure your - "/bin/sh" is safe from the Shellshock bash vulnerability!!! - - Default value is 0 (disabled). - - Example 1.1. Set “setvars” parameter -... -modparam("exec", "setvars", 1) -... - -1.3.2. time_to_kill (integer) - - If set, this parameter specifies the longest time (in seconds) - that a program is allowed to execute. Once this duration is - exceeded, the program is terminated (SIGTERM). - - NOTE: due to internal limitations, a SIGTERM will actually be - sent to all job pids once the "time_to_kill" expiration timeout - hits. On a standard system, this should have no side-effects, - as pids are monotonically increasing in a slow manner, and - OpenSIPS should run under the "opensips" user, thus rendering - it unable to terminate non-child processes. If this is not the - case on your system, do not use the OpenSIPS "time_to_kill" - feature -- rather implement it within your external app! - - Default value is 0 (disabled). - - Example 1.2. Set “time_to_kill” parameter -... -modparam("exec", "time_to_kill", 20) -... - -1.4. Exported Functions - -1.4.1. exec(command, [stdin], [stdout], [stderr], [envavp]) - - Executes an external command. The input is passed to the - standard input of the new process, if specified, and the output - is saved in the output variable. - - The function waits for the external script until it provided - all its output (not necessary to actually finish). If no output - (standard output or standard error) is required by the - function, it will not block at all - it will simply launch the - external script and continue the script. - - Meaning of the parameters is as follows: - * command (string) - command to be executed - * stdin (string, optional) - string to be passed to the - standard input of the command - * stdout (var, optional) - optional output variable which - will hold the standard output of the process - * stderr (var, optional) - optional output variable which - will hold the standard error of the process - * envavp (var, optional) - optional AVP which holds the - values for the environment variables to be passed for the - command. The names of the environment variables will be - "OSIPS_EXEC_#", where "#" starts from 0. For example, if we - push two values (e.g. "b" and "a") into an AVP variable, - which acts like a stack, OSIPS_EXEC_0 will hold "a", while - OSIPS_EXEC_1 will hold "b". - - NOTE: If expecting a multi-line formatted output, you should - use $avp variables for the "stdout" and "stderr" parameters, to - avoid only receiving the last lines of each stream. - - WARNING: any OpenSIPS pseudo-vars which may contain special - bourne shell (sh/bash) characters should be placed inside - quotes, e.g. exec("update-stats.sh '$(ct{re.subst,/'//g})'"); - - WARNING: "stdin"/"stdout"/"stderr" parameters are not designed - for large amounts of data, so one should be careful when using - them. Because of the basic implementation, filled up pipes - could cause a read deadlock. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, - ONREPLY_ROUTE. - - Example 1.3. exec usage -... -$avp(env) = "a"; -$avp(env) = "b"; -exec("ls -l", , $var(out), $var(err), $avp(env)); -xlog("The output is $var(out)\n"); -xlog("Received the following error\n$var(err)"); -... -$var(input) = "input"; -exec("/home/../myscript.sh", "this is my $var(input) for exec\n", , , $a -vp(env)); -... - -1.5. Exported Asyncronous Functions - -1.5.1. exec(command, [stdin], [stdout], [stderr], [envavp]) - - Executes an external command. This function does exactly the - same as exec() (in terms of input, output and processing), but - in an asynchronous way. The script execution is suspended until - the external script provided all its output. OpenSIPS waits for - the external script to close its output stream, not necessarily - to terminate (so the script may still be running when OpenSIPS - resumes the script execution on "seeing" EOF on the the output - stream) - NOTE: if the stdout variable is missing, OpenSIPS will assume - that the output of the external script is not needed and it - will NOT WAIT at all for the script. So, if triggered via - "launch()", there will be no asynchronous waiting, so no resume - route triggering!! - - NOTE: this function ignore the "stderr" parameter for now - the - asynchronous waiting is done only on the output stream !! This - may be fixed in the following versions. - - To read and understand more on the asynchronous functions, how - to use them and what are their advantages, please refer to the - OpenSIPS online Manual. - - Example 1.4. async exec usage -{ -... -async(exec("ruri-changer.sh", $ru, $ru), resume); -} - -route [resume] { -... -} - -1.6. Known Issues - - When imposing an execution timeout using time_to_kill, make - sure your "/bin/sh" is a shell which does not fork when - executed, case in which the job itself will not be killed, but - rather its parent shell, while the job is silently inherited by - "init" and will continue to run. "/bin/dash" is one of these - troublesome shell environments. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 44 29 651 534 - 2. Liviu Chircu (@liviuchircu) 40 23 344 827 - 3. Jiri Kuthan (@jiriatipteldotorg) 28 11 1579 152 - 4. Daniel-Constantin Mierla (@miconda) 26 19 440 131 - 5. Razvan Crainea (@razvancrainea) 20 16 320 59 - 6. Jan Janak (@janakj) 16 10 463 111 - 7. Ionut Ionita (@ionutrazvanionita) 15 7 612 117 - 8. Andrei Pelinescu-Onciul 11 8 29 105 - 9. Vlad Patrascu (@rvlad-patrascu) 8 2 46 297 - 10. Henning Westerholt (@henningw) 4 2 8 8 - - All remaining contributors: Walter Doekes (@wdoekes), Maksym - Sobolyev (@sobomax), Zero King (@l2dy), Dror Wald, Anca Vamanu, - Dan Pascu (@danpascu), Elena-Ramona Modroiu, Konstantin - Bokarius, Vlad Paiu (@vladpaiu), Andreas Granig, Julián Moreno - Patiño, Octavian Cerna, Peter Lemenkov (@lemenkov), Edson - Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Feb 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2004 - Apr 2020 - 4. Zero King (@l2dy) Mar 2020 - Mar 2020 - 5. Razvan Crainea (@razvancrainea) Jun 2011 - Jan 2020 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionut Ionita (@ionutrazvanionita) Oct 2014 - Feb 2017 - 9. Octavian Cerna Oct 2016 - Oct 2016 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Walter Doekes (@wdoekes), Vlad Paiu - (@vladpaiu), Anca Vamanu, Dror Wald, Dan Pascu (@danpascu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona - Modroiu, Andreas Granig, Jan Janak (@janakj), Andrei - Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Walter - Doekes (@wdoekes), Ionut Ionita (@ionutrazvanionita), Razvan - Crainea (@razvancrainea), Anca Vamanu, Dror Wald, Dan Pascu - (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan - Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/exec/README.md b/modules/exec/README.md new file mode 100644 index 00000000000..31618e5c6e4 --- /dev/null +++ b/modules/exec/README.md @@ -0,0 +1,243 @@ +--- +title: "exec Module" +description: "The Exec module enables the execution of external commands from the OpenSIPS script." +--- + +## Admin Guide + + +### Overview + + +The Exec module enables the execution of external commands from the +OpenSIPS script. Any valid shell commands are accepted. The final input +string is evaluated and executed using the "/bin/sh" symlink/binary. +OpenSIPS may additionally pass a lot more information about the request +using environment variables: + + +- SIP_HF_ contains value of each header field in +request. If a header field occurred multiple times, values are +concatenated and comma-separated. is in capital +letters. Ff a header-field name occurred in compact form, + is canonical. +- SIP_TID is transaction identifier. All request retransmissions or +CANCELs/ACKs associated with a previous INVITE result in the same +value. +- SIP_DID is dialog identifier, which is the same as to-tag. +Initially, it is empty. +- SIP_SRCIP is source IP address from which request came. +- SIP_ORURI is original request URI. +- SIP_RURI is *current* request URI (if +unchanged, equal to original). +- SIP_USER is userpart of *current* request URI. +- SIP_OUSER is userpart of original request URI. + + +> [!NOTE] +> Any environment variables which are given to the exec module +> functions must be specified using the '$$' delimiter (e.g., $$SIP_OUSER), +> otherwise they will be evaluated as OpenSIPS pseudo-variables, +> throwing scripting errors. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### setvars (integer) + + +Set to 1 to enable setting all above-mentioned environment variables +for all executed commands. + + +> [!WARNING] +> Before enabling this parameter, make sure +> your "/bin/sh" is safe from the Shellshock bash vulnerability! + + +*Default value is 0 (disabled).* + + +```opensips title="Set 'setvars' parameter" +... +modparam("exec", "setvars", 1) +... +``` + + +#### time_to_kill (integer) + + +If set, this parameter specifies the longest time (in seconds) that a +program is allowed to execute. Once this duration is exceeded, the +program is terminated (SIGTERM). + + +> [!NOTE] +> Due to internal limitations, a SIGTERM will actually be sent to +> **all** job pids once the "time_to_kill" +> expiration timeout hits. On a standard system, this should have no +> side-effects, as pids are monotonically increasing in a slow manner, +> and OpenSIPS should run under the "opensips" user, thus rendering it +> unable to terminate non-child processes. If this is not the case on +> your system, do not use the OpenSIPS "time_to_kill" feature -- rather +> implement it within your external app! + + +*Default value is 0 (disabled).* + + +```opensips title="Set 'time_to_kill' parameter" +... +modparam("exec", "time_to_kill", 20) +... +``` + + +### Exported Functions + + +#### exec(command, [stdin], [stdout], [stderr], [envavp]) + + +Executes an external command. The input is passed to the standard input of the new +process, if specified, and the output is saved in the output variable. + + +The function waits for the external script until it provided all its output (not +necessary to actually finish). If no output (standard output or standard error) +is required by the function, it will not block at all - it will simply launch the +external script and continue the script. + + +Meaning of the parameters is as follows: + + +- *command (string)* - command to be executed +- *stdin (string, optional)* - string to be +passed to the standard input of the command +- *stdout (var, optional)* - optional +output variable which will hold the standard output of the +process +- *stderr (var, optional)* - optional +output variable which will hold the standard error of the +process +- *envavp (var, optional)* - optional AVP +which holds the values for the +environment variables to be passed for the command. The names of the environment +variables will be "OSIPS_EXEC_#", where "#" starts from 0. For example, if we +push two values (e.g. "b" and "a") into an AVP variable, which acts like a stack, +OSIPS_EXEC_0 will hold "a", while OSIPS_EXEC_1 will hold "b". + + +> [!NOTE] +> If expecting a multi-line formatted output, you should use $avp +> variables for the "stdout" and "stderr" parameters, to avoid only +> receiving the last lines of each stream. + + +> [!WARNING] +> Any OpenSIPS pseudo-vars which may contain special bourne shell (sh/bash) +> characters should be placed inside quotes, e.g. +> exec("update-stats.sh '$(ct{re.subst,/'//g})'"); + + +> [!WARNING] +> "stdin"/"stdout"/"stderr" parameters are not designed for large amounts of +> data, so one should be careful when using them. Because of the basic implementation, +> filled up pipes could cause a read deadlock. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, ONREPLY_ROUTE. + + +```opensips title="exec usage" +... +$avp(env) = "a"; +$avp(env) = "b"; +exec("ls -l", , $var(out), $var(err), $avp(env)); +xlog("The output is $var(out)\n"); +xlog("Received the following error\n$var(err)"); +... +$var(input) = "input"; +exec("/home/../myscript.sh", "this is my $var(input) for exec\n", , , $avp(env)); +... +``` + + +### Exported Asynchronous Functions + + +#### exec(command, [stdin], [stdout], [stderr], [envavp]) + + +Executes an external command. This function does exactly the same as +[exec](#func_exec) (in terms of input, output and processing), +but in an asynchronous way. The script execution is suspended until +the external script provided all its output. OpenSIPS waits for the +external script to close its output stream, not necessarily to +terminate (so the script may still be running when OpenSIPS +resumes the script execution on "seeing" EOF on the the output stream) + + +> [!NOTE] +> This function ignore the "stderr" parameter for now - the +> asynchronous waiting is done only on the output stream !! This may +> be fixed in the following versions. + + +To read and understand more on the asynchronous functions, how to use +them and what are their advantages, please refer to the OpenSIPS +online Manual. + + +```opensips title="async exec usage" +{ +... +async(exec("ruri-changer.sh", $ru, $ru), resume); +} + +route [resume] { +... +} +``` + + +### Known Issues + + +When imposing an execution timeout using +**[time to kill](#param_time_to_kill)**, +make sure your "/bin/sh" is a shell which does not fork when executed, +case in which the job itself will not be killed, but rather its parent shell, +while the job is silently inherited by "init" and will continue to run. +"/bin/dash" is one of these troublesome shell environments. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/exec/doc/contributors.xml b/modules/exec/doc/contributors.xml deleted file mode 100644 index 7126444c49d..00000000000 --- a/modules/exec/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 44 - 29 - 651 - 534 - - - 2. - Liviu Chircu (@liviuchircu) - 40 - 23 - 344 - 827 - - - 3. - Jiri Kuthan (@jiriatipteldotorg) - 28 - 11 - 1579 - 152 - - - 4. - Daniel-Constantin Mierla (@miconda) - 26 - 19 - 440 - 131 - - - 5. - Razvan Crainea (@razvancrainea) - 20 - 16 - 320 - 59 - - - 6. - Jan Janak (@janakj) - 16 - 10 - 463 - 111 - - - 7. - Ionut Ionita (@ionutrazvanionita) - 15 - 7 - 612 - 117 - - - 8. - Andrei Pelinescu-Onciul - 11 - 8 - 29 - 105 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 8 - 2 - 46 - 297 - - - 10. - Henning Westerholt (@henningw) - 4 - 2 - 8 - 8 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Maksym Sobolyev (@sobomax), Zero King (@l2dy), Dror Wald, Anca Vamanu, Dan Pascu (@danpascu), Elena-Ramona Modroiu, Konstantin Bokarius, Vlad Paiu (@vladpaiu), Andreas Granig, Julián Moreno Patiño, Octavian Cerna, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Feb 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2004 - Apr 2020 - - - 4. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jan 2020 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionut Ionita (@ionutrazvanionita) - Oct 2014 - Feb 2017 - - - 9. - Octavian Cerna - Oct 2016 - Oct 2016 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu), Anca Vamanu, Dror Wald, Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona Modroiu, Andreas Granig, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Ionut Ionita (@ionutrazvanionita), Razvan Crainea (@razvancrainea), Anca Vamanu, Dror Wald, Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/exec/doc/exec.xml b/modules/exec/doc/exec.xml deleted file mode 100644 index 0d922100ae8..00000000000 --- a/modules/exec/doc/exec.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - exec Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/exec/doc/exec_admin.xml b/modules/exec/doc/exec_admin.xml deleted file mode 100644 index 44f06089b94..00000000000 --- a/modules/exec/doc/exec_admin.xml +++ /dev/null @@ -1,310 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Exec module enables the execution of external commands from the - &osips; script. Any valid shell commands are accepted. The final input - string is evaluated and executed using the "/bin/sh" symlink/binary. - &osips; may additionally pass a lot more information about the request - using environment variables: - - - - - SIP_HF_<hf_name> contains value of each header field in - request. If a header field occurred multiple times, values are - concatenated and comma-separated. <hf_name> is in capital - letters. Ff a header-field name occurred in compact form, - <hf_name> is canonical. - - - - - SIP_TID is transaction identifier. All request retransmissions or - CANCELs/ACKs associated with a previous INVITE result in the same - value. - - - - - SIP_DID is dialog identifier, which is the same as to-tag. - Initially, it is empty. - - - - - SIP_SRCIP is source &ip; address from which request came. - - - - - SIP_ORURI is original request &uri;. - - - - - SIP_RURI is current request &uri; (if - unchanged, equal to original). - - - - - SIP_USER is userpart of current request &uri;. - - - - - SIP_OUSER is userpart of original request &uri;. - - - - - NOTE: Any environment variables which are given to the exec module - functions must be specified using the '$$' delimiter (e.g., $$SIP_OUSER), - otherwise they will be evaluated as &osips; pseudo-variables, - throwing scripting errors. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>setvars</varname> (integer) - - Set to 1 to enable setting all above-mentioned environment variables - for all executed commands. - - - WARNING: Before enabling this parameter, make sure - your "/bin/sh" is safe from the Shellshock bash vulnerability!!! - - - - Default value is 0 (disabled). - - - - Set <quote>setvars</quote> parameter - -... -modparam("exec", "setvars", 1) -... - - -
-
- <varname>time_to_kill</varname> (integer) - - If set, this parameter specifies the longest time (in seconds) that a - program is allowed to execute. Once this duration is exceeded, the - program is terminated (SIGTERM). - - - NOTE: due to internal limitations, a SIGTERM will actually be sent to - all job pids once the "time_to_kill" - expiration timeout hits. On a standard system, this should have no - side-effects, as pids are monotonically increasing in a slow manner, - and OpenSIPS should run under the "opensips" user, thus rendering it - unable to terminate non-child processes. If this is not the case on - your system, do not use the OpenSIPS "time_to_kill" feature -- rather - implement it within your external app! - - - - Default value is 0 (disabled). - - - - Set <quote>time_to_kill</quote> parameter - -... -modparam("exec", "time_to_kill", 20) -... - - -
- -
-
- Exported Functions -
- - <function moreinfo="none">exec(command, [stdin], [stdout], [stderr], [envavp])</function> - - - Executes an external command. The input is passed to the standard input of the new - process, if specified, and the output is saved in the output variable. - - - The function waits for the external script until it provided all its output (not - necessary to actually finish). If no output (standard output or standard error) - is required by the function, it will not block at all - it will simply launch the - external script and continue the script. - - Meaning of the parameters is as follows: - - - command (string) - command to be executed - - - - stdin (string, optional) - string to be - passed to the standard input of the command - - - - stdout (var, optional) - optional - output variable which will hold the standard output of the - process - - - - stderr (var, optional) - optional - output variable which will hold the standard error of the - process - - - - envavp (var, optional) - optional AVP - which holds the values for the - environment variables to be passed for the command. The names of the environment - variables will be "OSIPS_EXEC_#", where "#" starts from 0. For example, if we - push two values (e.g. "b" and "a") into an AVP variable, which acts like a stack, - OSIPS_EXEC_0 will hold "a", while OSIPS_EXEC_1 will hold "b". - - - - - NOTE: If expecting a multi-line formatted output, you should use $avp - variables for the "stdout" and "stderr" parameters, to avoid only - receiving the last lines of each stream. - - - WARNING: any OpenSIPS pseudo-vars which may contain special bourne shell (sh/bash) - characters should be placed inside quotes, e.g. - exec("update-stats.sh '$(ct{re.subst,/'//g})'"); - - - WARNING: "stdin"/"stdout"/"stderr" parameters are not designed for large amounts of - data, so one should be careful when using them. Because of the basic implementation, - filled up pipes could cause a read deadlock. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE, ONREPLY_ROUTE. - - - <function moreinfo="none">exec</function> usage - -... -$avp(env) = "a"; -$avp(env) = "b"; -exec("ls -l", , $var(out), $var(err), $avp(env)); -xlog("The output is $var(out)\n"); -xlog("Received the following error\n$var(err)"); -... -$var(input) = "input"; -exec("/home/../myscript.sh", "this is my $var(input) for exec\n", , , $avp(env)); -... - - -
- -
- -
- Exported Asyncronous Functions -
- - <function moreinfo="none">exec(command, [stdin], [stdout], [stderr], [envavp])</function> - - - Executes an external command. This function does exactly the same as - (in terms of input, output and processing), - but in an asynchronous way. The script execution is suspended until - the external script provided all its output. OpenSIPS waits for the - external script to close its output stream, not necessarily to - terminate (so the script may still be running when OpenSIPS - resumes the script execution on "seeing" EOF on the the output stream) - - NOTE: if the stdout variable is missing, OpenSIPS will assume that the - output of the external script is not needed and it will NOT WAIT at - all for the script. So, if triggered via "launch()", there will be no - asynchronous waiting, so no resume route triggering!! - - - - NOTE: this function ignore the "stderr" parameter for now - the - asynchronous waiting is done only on the output stream !! This may - be fixed in the following versions. - - - To read and understand more on the asynchronous functions, how to use - them and what are their advantages, please refer to the OpenSIPS - online Manual. - - - <function moreinfo="none">async exec</function> usage - -{ -... -async(exec("ruri-changer.sh", $ru, $ru), resume); -} - -route [resume] { -... -} - - -
-
- -
- Known Issues - - When imposing an execution timeout using - , - make sure your "/bin/sh" is a shell which does not fork when executed, - case in which the job itself will not be killed, but rather its parent shell, - while the job is silently inherited by "init" and will continue to run. - "/bin/dash" is one of these troublesome shell environments. - -
-
- diff --git a/modules/fraud_detection/README b/modules/fraud_detection/README deleted file mode 100644 index 7ee85cc14f6..00000000000 --- a/modules/fraud_detection/README +++ /dev/null @@ -1,553 +0,0 @@ -Fraud Detection Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Monitored Stats - 1.1.2. Fraud rules - - 1.2. Dependencies - - 1.2.1. OpenSIPS modules - 1.2.2. External libraries or applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. use_utc_time (integer) - 1.3.3. table_name (string) - 1.3.4. rid_col (string) - 1.3.5. pid_col (string) - 1.3.6. prefix_col (string) - 1.3.7. start_h (string) - 1.3.8. end_h (string) - 1.3.9. days_col (string) - 1.3.10. cpm_thresh_warn_col (string) - 1.3.11. cpm_thresh_crit_col (string) - 1.3.12. calldur_thresh_warn_col (string) - 1.3.13. calldur_thresh_crit_col (string) - 1.3.14. totalc_thresh_warn_col (string) - 1.3.15. totalc_thresh_crit_col (string) - 1.3.16. concalls_thresh_warn_col (string) - 1.3.17. concalls_thresh_crit_col (string) - 1.3.18. seqcalls_thresh_warn_col (string) - 1.3.19. seqcalls_thresh_crit_col (string) - - 1.4. Exported Functions - - 1.4.1. check_fraud(user, number, profile_id) - - 1.5. Exported MI Functions - - 1.5.1. show_fraud_stats - 1.5.2. fraud_reload - - 1.6. Exported Events - - 1.6.1. E_FRD_WARNING - 1.6.2. E_FRD_CRITICAL - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set the “db_url” parameter - 1.2. Set the “use_utc_time” parameter - 1.3. Set the “table_name” parameter - 1.4. Set “rid_col” parameter - 1.5. Set “pid_col” parameter - 1.6. Set “prefix_col” parameter - 1.7. Set “start_h” parameter - 1.8. Set “end_h” parameter - 1.9. Set “days_col” parameter - 1.10. Set “cpm_thresh_warn_col” parameter - 1.11. Set “cpm_thresh_crit_col” parameter - 1.12. Set “calldur_thresh_warn_col” parameter - 1.13. Set “calldur_thresh_crit_col” parameter - 1.14. Set “totalc_thresh_warn_col” parameter - 1.15. Set “totalc_thresh_crit_col” parameter - 1.16. Set “concalls_thresh_warn_col” parameter - 1.17. Set “concalls_thresh_crit_col” parameter - 1.18. Set “seqcalls_thresh_warn_col” parameter - 1.19. Set “seqcalls_thresh_crit_col” parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a way to prevent some basic fraud attacks. - Alerts are provided through return codes and events. - -1.1.1. Monitored Stats - - Basically, this module watches the following parameters: - * Total calls - * Calls per minute - * Concurrent calls - * Number of sequential calls - * Call duration - - Each of the above parameters is monitored for every user and - every called prefix separately. The stats are altered whenever - the check_fraud function is called. The function assumes a new - call is made, and checks the called number against all the - rules from the supplied profile. The rule's prefix is - considered to be the called prefix which along with the - provided user will be used to monitor values for the 5 - parameters. - -1.1.2. Fraud rules - - A rule is a set of two thresholds (warning and critical - thresholds) for each of the five parameters (as described - above) and is only available for a specified prefix. Further - more, a rule will only match between the indicated hours in the - indicated days of the week (similarly to a dr rule). A fraud - profile is simply a group of fraud rules and is used to only to - limit the list of rules to match when calling the check_fraud - function. - -1.2. Dependencies - -1.2.1. OpenSIPS modules - - The following modules must be loaded before this module: - * drouting - * dialog - -1.2.2. External libraries or applications - - The following libraries or applications must be installed - before running OpenSIPS with this module: - * none. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Database where to load the rules from. - - Default value is “NULL”. At least one db_url should be defined - for the fraud_detection module to work. - - Example 1.1. Set the “db_url” parameter -... -modparam("fraud_detection", "db_url", "mysql://user:passwb@localhost/dat -abase") -... - -1.3.2. use_utc_time (integer) - - Set this parameter to non-zero in order to enable UTC-based - interval matching and statistics resets, rather than local - time-based. - - The default value is “0” (use local time). - - Example 1.2. Set the “use_utc_time” parameter -... -modparam("fraud_detection", "use_utc_time", 1) -... - -1.3.3. table_name (string) - - If you want to load the rules from the database you must set - this parameter as the database name. - - The default value is “fraud_detection”. - - Example 1.3. Set the “table_name” parameter -... -modparam("fraud_detection", "table_name", "my_fraud") -... - -1.3.4. rid_col (string) - - The column's name in the database storing the fraud rule's id. - - Default value is “ruleid”. - - Example 1.4. Set “rid_col” parameter -... -modparam("fraud_detection", "rid_col", "theruleid") -... - -1.3.5. pid_col (string) - - The column's name in the database storing the fraud profile's - id. - - Please keep in mind that a profile is merely a set of rules. - - Default value is “profileid”. - - Example 1.5. Set “pid_col” parameter -... -modparam("fraud_detection", "pid_col", "profile") -... - -1.3.6. prefix_col (string) - - The column's name in the database storing the prefix for which - the fraud rule will match. - - Default value is “prefix”. - - Example 1.6. Set “prefix_col” parameter -... -modparam("fraud_detection", "prefix_col", "myprefix") -... - -1.3.7. start_h (string) - - The column's name in the database storing the the start time of - the interval in which the rule will match. - - The time needs to be specified as string using the format: - “HH:MM” - - Default value is “start_hour”. - - Example 1.7. Set “start_h” parameter -... -modparam("fraud_detection", "start_h", "the_start_time") -... - -1.3.8. end_h (string) - - The column's name in the database storing the the end time of - the interval in which the rule will match. - - The time needs to be specified as string using the format: - “HH:MM” - - Default value is “end_hour”. - - Example 1.8. Set “end_h” parameter -... -modparam("fraud_detection", "end_h", "the_end_time") -... - -1.3.9. days_col (string) - - The column's name in the database storing the week days in - which the fraud rule's interval is available. - - The daysoftheweek needs to be specified as a string containing - a list of days or intervals. Each day must be specified using - the first three letters of its name. A valid string would be: - "Fri-Mon, Wed, Thu" - - Default value is “daysoftheweek”. - - Example 1.9. Set “days_col” parameter -... -modparam("fraud_detection", "days_col", "days") -... - -1.3.10. cpm_thresh_warn_col (string) - - The column's name in the database storing the warning threshold - value for calls per minute. - - Default value is “cpm_warning”. - - Example 1.10. Set “cpm_thresh_warn_col” parameter -... -modparam("fraud_detection", "cpm_thresh_warn_col", "cpm_warn_thresh") -... - -1.3.11. cpm_thresh_crit_col (string) - - The column's name in the database storing the critical - threshold value for calls per minute. - - Default value is “cpm_critical”. - - Example 1.11. Set “cpm_thresh_crit_col” parameter -... -modparam("fraud_detection", "cpm_thresh_crit_col", "cpm_crit_thresh") -... - -1.3.12. calldur_thresh_warn_col (string) - - The column's name in the database storing the warning threshold - value for call duration. - - Default value is “call_duration_warning”. - - Example 1.12. Set “calldur_thresh_warn_col” parameter -... -modparam("fraud_detection", "calldur_thresh_warn_col", "calldur_warn_thr -esh") -... - -1.3.13. calldur_thresh_crit_col (string) - - The column's name in the database storing the critical - threshold value for call duration. - - Default value is “call_duration_critical”. - - Example 1.13. Set “calldur_thresh_crit_col” parameter -... -modparam("fraud_detection", "calldur_thresh_crit_col", "calldur_crit_thr -esh") -... - -1.3.14. totalc_thresh_warn_col (string) - - The column's name in the database storing the warning threshold - value for the number of total calls. - - Default value is “total_calls_warning”. - - Example 1.14. Set “totalc_thresh_warn_col” parameter -... -modparam("fraud_detection", "totalc_thresh_warn_col", "totalc_warn_thres -h") -... - -1.3.15. totalc_thresh_crit_col (string) - - The column's name in the database storing the critical - threshold value for the number of total calls. - - Default value is “total_calls_critical”. - - Example 1.15. Set “totalc_thresh_crit_col” parameter -... -modparam("fraud_detection", "totalc_thresh_crit_col", "totalc_crit_thres -h") -... - -1.3.16. concalls_thresh_warn_col (string) - - The column's name in the database storing the warning threshold - value for the number of concurrent calls. - - Default value is “concurrent_calls_warning”. - - Example 1.16. Set “concalls_thresh_warn_col” parameter -... -modparam("fraud_detection", "concalls_thresh_warn_col", "concalls_warn_t -hresh") -... - -1.3.17. concalls_thresh_crit_col (string) - - The column's name in the database storing the critical - threshold value for the number of concurrent calls. - - Default value is “concurrent_calls_critical”. - - Example 1.17. Set “concalls_thresh_crit_col” parameter -... -modparam("fraud_detection", "concalls_thresh_crit_col", "concalls_crit_t -hresh") -... - -1.3.18. seqcalls_thresh_warn_col (string) - - The column's name in the database storing the warning threshold - value for the number of sequential calls. - - Default value is “sequential_calls_warning”. - - Example 1.18. Set “seqcalls_thresh_warn_col” parameter -... -modparam("fraud_detection", "seqcalls_thresh_warn_col", "seqcalls_warn_t -hresh") -... - -1.3.19. seqcalls_thresh_crit_col (string) - - The column's name in the database storing the critical - threshold value for the number of sequential calls. - - Default value is “sequential_calls_critical”. - - Example 1.19. Set “seqcalls_thresh_crit_col” parameter -... -modparam("fraud_detection", "seqcalls_thresh_crit_col", "seqcalls_crit_t -hresh") -... - -1.4. Exported Functions - -1.4.1. check_fraud(user, number, profile_id) - - This method should be called each time a given user calls a - given number. It will try to match a fraud rule within the - given fraud profile and update the stats (see above). - Furthermore, the stats will be checked against the rule's - thresholds. If any of the stats is above its threshold value, - the appropriate event will also be raised (see further details - below). - - Designed to only work with initial INVITE messages! If a dialog - is not already present, one will be created (equivalent of - create_dialog()). - - Meaning of the parameters is as follows: - * user (string) - the user who is making the call. Please - keep in mind that the user doesn't have to be registered. - This string is only used to keep different stats for - different registered users. - * number (string) - the number the user is calling to. - * profile_id (int) - the fraud profile id (i.e. the subset of - fraud rules) in which to try and find a matching fraud - rule. - - The meaning of the return code is as follows: - * 2 - no matching fraud rule was found - * 1 - a matching rule was found, but there is no parameter - above the rule's threshlod, i.e - everything is ok - * -1 - there is a parameter above the warning threshold - value. Check the raised event for more info - * -2 - there is a parameter above the critical threshold - value. Check the raised event for more info - * -3 - something went wrong (internal mechanism failed) - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - -1.5. Exported MI Functions - -1.5.1. show_fraud_stats - - Show the current statistics for all dials of a user to a - prefix. - - NOTE: Since the fraud statistics are refreshed on-the-fly, as - check_fraud() is called, this function will return stale data - if check_fraud() has not been called at least once for the - (user, prefix) pair within a newly matching time interval! - - Name: show_fraud_stats - - Parameters: - * user - * prefix - -1.5.2. fraud_reload - - Reload the all the fraud rules. - - Name: fraud_reload - - Parameters: none - -1.6. Exported Events - -1.6.1. E_FRD_WARNING - - This event is raised whenever one of the 5 monitored parameters - is above the warning threshold value - - Parameters: - * param - the name of the parameter. - * value - the current value of the parameter. - * threshold - the warning threshold value. - * user - the user who initiated the call. - * called_number - the number that was called. - * rule_id - the id of the fraud rule that matched when the - call was initiated - * profile_id - the profile id used - -1.6.2. E_FRD_CRITICAL - - This event is raised whenever one of the 5 monitored parameters - is above the warning threshold value - - Parameters: - * param - the name of the parameter. - * value - the current value of the parameter. - * threshold - the warning threshold value. - * user - the user who initiated the call. - * called_number - the number that was called. - * rule_id - the id of the fraud rule that matched when the - call was initiated - * profile_id - the profile id used - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 51 42 383 284 - 2. Andrei Datcu (@andrei-datcu) 38 11 2665 235 - 3. Razvan Crainea (@razvancrainea) 8 6 14 11 - 4. Vlad Patrascu (@rvlad-patrascu) 8 5 73 114 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 7 5 20 31 - 6. Maksym Sobolyev (@sobomax) 5 3 7 8 - 7. Ahron Greenberg 3 1 22 11 - 8. Ionut Ionita (@ionutrazvanionita) 3 1 21 6 - 9. Alexandra Titoc 3 1 13 1 - 10. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Ahron Greenberg Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2015 - Aug 2022 - 5. Razvan Crainea (@razvancrainea) Feb 2015 - Oct 2021 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ionut Ionita (@ionutrazvanionita) Jan 2016 - Jan 2016 - 10. Andrei Datcu (@andrei-datcu) Aug 2014 - Sep 2014 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ahron Greenberg, Liviu Chircu (@liviuchircu), - Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), - Bogdan-Andrei Iancu (@bogdan-iancu), Andrei Datcu - (@andrei-datcu). - - Documentation Copyrights: - - Copyright © 2014 www.opensips-solutions.com diff --git a/modules/fraud_detection/README.md b/modules/fraud_detection/README.md new file mode 100644 index 00000000000..9256395d771 --- /dev/null +++ b/modules/fraud_detection/README.md @@ -0,0 +1,556 @@ +--- +title: "Fraud Detection Module" +description: "This module provides a way to prevent some basic fraud attacks." +--- + +## Admin Guide + + +### Overview + + +This module provides a way to prevent some basic fraud attacks. +Alerts are provided through return codes and events. + + +#### Monitored Stats + + +Basically, this module watches the following parameters: + + +- Total calls +- Calls per minute +- Concurrent calls +- Number of sequential calls +- Call duration + + +Each of the above parameters is monitored for every user and +every called prefix separately. The stats are altered whenever +the *check_fraud* function is called. The +function assumes a new call is made, and checks the called +number against all the rules from the supplied profile. The +rule's prefix is considered to be the called prefix which along with +the provided user will be used to monitor values for the 5 +parameters. + + +#### Fraud rules + + +A rule is a set of two thresholds (warning and critical thresholds) for each of the +five parameters (as described above) and is only available for a specified prefix. +Further more, a rule will only match between the indicated hours in the indicated days +of the week (similarly to a dr rule). A fraud profile is simply a group of fraud rules +and is used to only to limit the list of rules to match when calling the check_fraud +function. + + +### Dependencies + + +#### OpenSIPS modules + + +The following modules must be loaded before this module: + + +- drouting +- dialog + + +#### External libraries or applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module: + + +- *none*. + + +### Exported Parameters + + +#### db_url (string) + + +Database where to load the rules from. + + +*Default value is "NULL". At least one db_url should +be defined for the fraud_detection module to work.* + + +```opensips title="Set the 'db_url' parameter" +... +modparam("fraud_detection", "db_url", "mysql://user:passwb@localhost/database") +... +``` + + +#### use_utc_time (integer) + + +Set this parameter to non-zero in order to enable UTC-based interval +matching and statistics resets, rather than local time-based. + + +*The default value is "0" (use local time).* + + +```opensips title="Set the 'use_utc_time' parameter" +... +modparam("fraud_detection", "use_utc_time", 1) +... +``` + + +#### table_name (string) + + +If you want to load the rules from the database you must set +this parameter as the database name. + + +*The default value is "fraud_detection".* + + +```opensips title="Set the 'table_name' parameter" +... +modparam("fraud_detection", "table_name", "my_fraud") +... +``` + + +#### rid_col (string) + + +The column's name in the database storing the +fraud rule's id. + + +*Default value is "ruleid".* + + +```opensips title="Set 'rid_col' parameter" +... +modparam("fraud_detection", "rid_col", "theruleid") +... +``` + + +#### pid_col (string) + + +The column's name in the database storing the +fraud profile's id. + + +Please keep in mind that a profile is merely +a set of rules. + + +*Default value is "profileid".* + + +```opensips title="Set 'pid_col' parameter" +... +modparam("fraud_detection", "pid_col", "profile") +... +``` + + +#### prefix_col (string) + + +The column's name in the database storing the +prefix for which the fraud rule will match. + + +*Default value is "prefix".* + + +```opensips title="Set 'prefix_col' parameter" +... +modparam("fraud_detection", "prefix_col", "myprefix") +... +``` + + +#### start_h (string) + + +The column's name in the database storing the +the start time of the interval in which the +rule will match. + + +The time needs to be specified as string using +the format: "HH:MM" + + +*Default value is "start_hour".* + + +```opensips title="Set 'start_h' parameter" +... +modparam("fraud_detection", "start_h", "the_start_time") +... +``` + + +#### end_h (string) + + +The column's name in the database storing the +the end time of the interval in which the +rule will match. + + +The time needs to be specified as string using +the format: "HH:MM" + + +*Default value is "end_hour".* + + +```opensips title="Set 'end_h' parameter" +... +modparam("fraud_detection", "end_h", "the_end_time") +... +``` + + +#### days_col (string) + + +The column's name in the database storing the +week days in which the fraud rule's interval +is available. + + +The daysoftheweek needs to be specified as a +string containing a list of days or intervals. +Each day must be specified using the first +three letters of its name. A valid string +would be: "Fri-Mon, Wed, Thu" + + +*Default value is "daysoftheweek".* + + +```opensips title="Set 'days_col' parameter" +... +modparam("fraud_detection", "days_col", "days") +... +``` + + +#### cpm_thresh_warn_col (string) + + +The column's name in the database storing the +warning threshold value for calls per minute. + + +*Default value is "cpm_warning".* + + +```opensips title="Set 'cpm_thresh_warn_col' parameter" +... +modparam("fraud_detection", "cpm_thresh_warn_col", "cpm_warn_thresh") +... +``` + + +#### cpm_thresh_crit_col (string) + + +The column's name in the database storing the +critical threshold value for calls per minute. + + +*Default value is "cpm_critical".* + + +```opensips title="Set 'cpm_thresh_crit_col' parameter" +... +modparam("fraud_detection", "cpm_thresh_crit_col", "cpm_crit_thresh") +... +``` + + +#### calldur_thresh_warn_col (string) + + +The column's name in the database storing the +warning threshold value for call duration. + + +*Default value is "call_duration_warning".* + + +```opensips title="Set 'calldur_thresh_warn_col' parameter" +... +modparam("fraud_detection", "calldur_thresh_warn_col", "calldur_warn_thresh") +... +``` + + +#### calldur_thresh_crit_col (string) + + +The column's name in the database storing the +critical threshold value for call duration. + + +*Default value is "call_duration_critical".* + + +```opensips title="Set 'calldur_thresh_crit_col' parameter" +... +modparam("fraud_detection", "calldur_thresh_crit_col", "calldur_crit_thresh") +... +``` + + +#### totalc_thresh_warn_col (string) + + +The column's name in the database storing the +warning threshold value for the number of total calls. + + +*Default value is "total_calls_warning".* + + +```opensips title="Set 'totalc_thresh_warn_col' parameter" +... +modparam("fraud_detection", "totalc_thresh_warn_col", "totalc_warn_thresh") +... +``` + + +#### totalc_thresh_crit_col (string) + + +The column's name in the database storing the +critical threshold value for the number of total calls. + + +*Default value is "total_calls_critical".* + + +```opensips title="Set 'totalc_thresh_crit_col' parameter" +... +modparam("fraud_detection", "totalc_thresh_crit_col", "totalc_crit_thresh") +... +``` + + +#### concalls_thresh_warn_col (string) + + +The column's name in the database storing the +warning threshold value for the number of +concurrent calls. + + +*Default value is "concurrent_calls_warning".* + + +```opensips title="Set 'concalls_thresh_warn_col' parameter" +... +modparam("fraud_detection", "concalls_thresh_warn_col", "concalls_warn_thresh") +... +``` + + +#### concalls_thresh_crit_col (string) + + +The column's name in the database storing the +critical threshold value for the number of +concurrent calls. + + +*Default value is "concurrent_calls_critical".* + + +```opensips title="Set 'concalls_thresh_crit_col' parameter" +... +modparam("fraud_detection", "concalls_thresh_crit_col", "concalls_crit_thresh") +... +``` + + +#### seqcalls_thresh_warn_col (string) + + +The column's name in the database storing the +warning threshold value for the number of +sequential calls. + + +*Default value is "sequential_calls_warning".* + + +```opensips title="Set 'seqcalls_thresh_warn_col' parameter" +... +modparam("fraud_detection", "seqcalls_thresh_warn_col", "seqcalls_warn_thresh") +... +``` + + +#### seqcalls_thresh_crit_col (string) + + +The column's name in the database storing the +critical threshold value for the number of +sequential calls. + + +*Default value is "sequential_calls_critical".* + + +```opensips title="Set 'seqcalls_thresh_crit_col' parameter" +... +modparam("fraud_detection", "seqcalls_thresh_crit_col", "seqcalls_crit_thresh") +... +``` + + +### Exported Functions + + +#### check_fraud(user, number, profile_id) + + +This method should be called each time a given *user* +calls a given *number*. It will try to match a fraud rule +within the given fraud profile and update the stats (see above). Furthermore, +the stats will be checked against the rule's thresholds. If any of the stats +is above its threshold value, the appropriate event will also be raised +(see further details below). + + +Designed to only work with initial INVITE messages! If a dialog is +not already present, one will be created (equivalent of +create_dialog()). + + +Meaning of the parameters is as follows: + + +- *user* (string) - the user who is making the call. Please keep in mind that +the user doesn't have to be registered. This string is only used to keep different stats +for different registered users. +- *number* (string) - the number the user is calling to. +- *profile_id* (int) - the fraud profile id (i.e. the subset of fraud +rules) in which to try and find a matching fraud rule. + + +The meaning of the return code is as follows: + + +- *2* - no matching fraud rule was found +- *1* - a matching rule was found, but there is no +parameter above the rule's threshlod, i.e - everything is ok +- *-1* - there is a parameter above the warning threshold value. +Check the raised event for more info +- *-2* - there is a parameter above the critical threshold value. +Check the raised event for more info +- *-3* - something went wrong (internal mechanism failed) + + +This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. + + +### Exported MI Functions + + +#### show_fraud_stats + + +Show the current statistics for all dials of a +*user* to a *prefix*. + + +> [!NOTE] +> Since the fraud statistics are refreshed on-the-fly, as +> check_fraud() is called, **this function will +> return stale data** if check_fraud() has not been called at +> least once for the (user, prefix) pair within a newly matching time +> interval! + + +Name: *show_fraud_stats* + + +Parameters: + + +- user +- prefix + + +#### fraud_reload + + +Reload the all the fraud rules. + + +Name: *fraud_reload* + + +Parameters: *none* + + +### Exported Events + + +#### E_FRD_WARNING + + +This event is raised whenever one of the 5 monitored parameters +is above the warning threshold value + + +Parameters: + + +- *param* - the name of the parameter. +- *value* - the current value of the parameter. +- *threshold* - the warning threshold value. +- *user* - the user who initiated the call. +- *called_number* - the number that was called. +- *rule_id* - the id of the fraud rule that matched +when the call was initiated +- *profile_id* - the profile id used + + +#### E_FRD_CRITICAL + + +This event is raised whenever one of the 5 monitored parameters +is above the warning threshold value + + +Parameters: + + +- *param* - the name of the parameter. +- *value* - the current value of the parameter. +- *threshold* - the warning threshold value. +- *user* - the user who initiated the call. +- *called_number* - the number that was called. +- *rule_id* - the id of the fraud rule that matched +when the call was initiated +- *profile_id* - the profile id used + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/fraud_detection/doc/contributors.xml b/modules/fraud_detection/doc/contributors.xml deleted file mode 100644 index 3c26c3e90b6..00000000000 --- a/modules/fraud_detection/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 51 - 42 - 383 - 284 - - - 2. - Andrei Datcu (@andrei-datcu) - 38 - 11 - 2665 - 235 - - - 3. - Razvan Crainea (@razvancrainea) - 8 - 6 - 14 - 11 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 8 - 5 - 73 - 114 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 5 - 20 - 31 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 7 - 8 - - - 7. - Ahron Greenberg - 3 - 1 - 22 - 11 - - - 8. - Ionut Ionita (@ionutrazvanionita) - 3 - 1 - 21 - 6 - - - 9. - Alexandra Titoc - 3 - 1 - 13 - 1 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Ahron Greenberg - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2015 - Aug 2022 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2015 - Oct 2021 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Jan 2016 - Jan 2016 - - - 10. - Andrei Datcu (@andrei-datcu) - Aug 2014 - Sep 2014 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ahron Greenberg, Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Andrei Datcu (@andrei-datcu). -
- -
diff --git a/modules/fraud_detection/doc/fraud_detection.xml b/modules/fraud_detection/doc/fraud_detection.xml deleted file mode 100644 index 062a208ccf5..00000000000 --- a/modules/fraud_detection/doc/fraud_detection.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Fraud Detection Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2014 &osipssol; - diff --git a/modules/fraud_detection/doc/fraud_detection_admin.xml b/modules/fraud_detection/doc/fraud_detection_admin.xml deleted file mode 100644 index 7f6bc41a90a..00000000000 --- a/modules/fraud_detection/doc/fraud_detection_admin.xml +++ /dev/null @@ -1,726 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a way to prevent some basic fraud attacks. - Alerts are provided through return codes and events. - -
- Monitored Stats - - Basically, this module watches the following parameters: - - - - Total calls - - - - - Calls per minute - - - - - Concurrent calls - - - - - Number of sequential calls - - - - - Call duration - - - - - - Each of the above parameters is monitored for every user and - every called prefix separately. The stats are altered whenever - the check_fraud function is called. The - function assumes a new call is made, and checks the called - number against all the rules from the supplied profile. The - rule's prefix is considered to be the called prefix which along with - the provided user will be used to monitor values for the 5 - parameters. - -
- -
- Fraud rules - - A rule is a set of two thresholds (warning and critical thresholds) for each of the - five parameters (as described above) and is only available for a specified prefix. - Further more, a rule will only match between the indicated hours in the indicated days - of the week (similarly to a dr rule). A fraud profile is simply a group of fraud rules - and is used to only to limit the list of rules to match when calling the check_fraud - function. - -
-
-
- Dependencies -
- &osips; modules - - The following modules must be loaded before this module: - - - - drouting - - - - - dialog - - - - -
-
- External libraries or applications - - The following libraries or applications must be installed before - running &osips; with this module: - - - - none. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - Database where to load the rules from. - - - - Default value is NULL. At least one db_url should - be defined for the fraud_detection module to work. - - - - Set the <quote>db_url</quote> parameter - -... -modparam("fraud_detection", "db_url", "mysql://user:passwb@localhost/database") -... - - -
- -
- <varname>use_utc_time</varname> (integer) - - Set this parameter to non-zero in order to enable UTC-based interval - matching and statistics resets, rather than local time-based. - - - - The default value is 0 (use local time). - - - - Set the <quote>use_utc_time</quote> parameter - -... -modparam("fraud_detection", "use_utc_time", 1) -... - - -
- -
- <varname>table_name</varname> (string) - - If you want to load the rules from the database you must set - this parameter as the database name. - - - - The default value is fraud_detection. - - - - Set the <quote>table_name</quote> parameter - -... -modparam("fraud_detection", "table_name", "my_fraud") -... - - -
- -
- <varname>rid_col</varname> (string) - - The column's name in the database storing the - fraud rule's id. - - - - Default value is ruleid. - - - - Set <quote>rid_col</quote> parameter - -... -modparam("fraud_detection", "rid_col", "theruleid") -... - - -
- -
- <varname>pid_col</varname> (string) - - The column's name in the database storing the - fraud profile's id. - - - Please keep in mind that a profile is merely - a set of rules. - - - - Default value is profileid. - - - - Set <quote>pid_col</quote> parameter - -... -modparam("fraud_detection", "pid_col", "profile") -... - - -
- -
- <varname>prefix_col</varname> (string) - - The column's name in the database storing the - prefix for which the fraud rule will match. - - - - Default value is prefix. - - - - Set <quote>prefix_col</quote> parameter - -... -modparam("fraud_detection", "prefix_col", "myprefix") -... - - -
- -
- <varname>start_h</varname> (string) - - The column's name in the database storing the - the start time of the interval in which the - rule will match. - - - The time needs to be specified as string using - the format: HH:MM - - - - Default value is start_hour. - - - - Set <quote>start_h</quote> parameter - -... -modparam("fraud_detection", "start_h", "the_start_time") -... - - -
- -
- <varname>end_h</varname> (string) - - The column's name in the database storing the - the end time of the interval in which the - rule will match. - - - The time needs to be specified as string using - the format: HH:MM - - - - Default value is end_hour. - - - - Set <quote>end_h</quote> parameter - -... -modparam("fraud_detection", "end_h", "the_end_time") -... - - -
- -
- <varname>days_col</varname> (string) - - The column's name in the database storing the - week days in which the fraud rule's interval - is available. - - - The daysoftheweek needs to be specified as a - string containing a list of days or intervals. - Each day must be specified using the first - three letters of its name. A valid string - would be: "Fri-Mon, Wed, Thu" - - - - Default value is daysoftheweek. - - - - Set <quote>days_col</quote> parameter - -... -modparam("fraud_detection", "days_col", "days") -... - - -
- -
- <varname>cpm_thresh_warn_col</varname> (string) - - The column's name in the database storing the - warning threshold value for calls per minute. - - - - Default value is cpm_warning. - - - - Set <quote>cpm_thresh_warn_col</quote> parameter - -... -modparam("fraud_detection", "cpm_thresh_warn_col", "cpm_warn_thresh") -... - - -
- -
- <varname>cpm_thresh_crit_col</varname> (string) - - The column's name in the database storing the - critical threshold value for calls per minute. - - - - Default value is cpm_critical. - - - - Set <quote>cpm_thresh_crit_col</quote> parameter - -... -modparam("fraud_detection", "cpm_thresh_crit_col", "cpm_crit_thresh") -... - - -
- -
- <varname>calldur_thresh_warn_col</varname> (string) - - The column's name in the database storing the - warning threshold value for call duration. - - - - Default value is call_duration_warning. - - - - Set <quote>calldur_thresh_warn_col</quote> parameter - -... -modparam("fraud_detection", "calldur_thresh_warn_col", "calldur_warn_thresh") -... - - -
- -
- <varname>calldur_thresh_crit_col</varname> (string) - - The column's name in the database storing the - critical threshold value for call duration. - - - - Default value is call_duration_critical. - - - - Set <quote>calldur_thresh_crit_col</quote> parameter - -... -modparam("fraud_detection", "calldur_thresh_crit_col", "calldur_crit_thresh") -... - - -
- -
- <varname>totalc_thresh_warn_col</varname> (string) - - The column's name in the database storing the - warning threshold value for the number of total calls. - - - - Default value is total_calls_warning. - - - - Set <quote>totalc_thresh_warn_col</quote> parameter - -... -modparam("fraud_detection", "totalc_thresh_warn_col", "totalc_warn_thresh") -... - - -
- -
- <varname>totalc_thresh_crit_col</varname> (string) - - The column's name in the database storing the - critical threshold value for the number of total calls. - - - - Default value is total_calls_critical. - - - - Set <quote>totalc_thresh_crit_col</quote> parameter - -... -modparam("fraud_detection", "totalc_thresh_crit_col", "totalc_crit_thresh") -... - - -
- -
- <varname>concalls_thresh_warn_col</varname> (string) - - The column's name in the database storing the - warning threshold value for the number of - concurrent calls. - - - - Default value is concurrent_calls_warning. - - - - Set <quote>concalls_thresh_warn_col</quote> parameter - -... -modparam("fraud_detection", "concalls_thresh_warn_col", "concalls_warn_thresh") -... - - -
- -
- <varname>concalls_thresh_crit_col</varname> (string) - - The column's name in the database storing the - critical threshold value for the number of - concurrent calls. - - - - Default value is concurrent_calls_critical. - - - - Set <quote>concalls_thresh_crit_col</quote> parameter - -... -modparam("fraud_detection", "concalls_thresh_crit_col", "concalls_crit_thresh") -... - - -
- -
- <varname>seqcalls_thresh_warn_col</varname> (string) - - The column's name in the database storing the - warning threshold value for the number of - sequential calls. - - - - Default value is sequential_calls_warning. - - - - Set <quote>seqcalls_thresh_warn_col</quote> parameter - -... -modparam("fraud_detection", "seqcalls_thresh_warn_col", "seqcalls_warn_thresh") -... - - -
- -
- <varname>seqcalls_thresh_crit_col</varname> (string) - - The column's name in the database storing the - critical threshold value for the number of - sequential calls. - - - - Default value is sequential_calls_critical. - - - - Set <quote>seqcalls_thresh_crit_col</quote> parameter - -... -modparam("fraud_detection", "seqcalls_thresh_crit_col", "seqcalls_crit_thresh") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">check_fraud(user, number, profile_id)</function> - - - This method should be called each time a given user - calls a given number. It will try to match a fraud rule - within the given fraud profile and update the stats (see above). Furthermore, - the stats will be checked against the rule's thresholds. If any of the stats - is above its threshold value, the appropriate event will also be raised - (see further details below). - - - Designed to only work with initial INVITE messages! If a dialog is - not already present, one will be created (equivalent of - create_dialog()). - - Meaning of the parameters is as follows: - - - - user (string) - the user who is making the call. Please keep in mind that - the user doesn't have to be registered. This string is only used to keep different stats - for different registered users. - - - - - number (string) - the number the user is calling to. - - - - - profile_id (int) - the fraud profile id (i.e. the subset of fraud - rules) in which to try and find a matching fraud rule. - - - - - The meaning of the return code is as follows: - - - - - 2 - no matching fraud rule was found - - - - - 1 - a matching rule was found, but there is no - parameter above the rule's threshlod, i.e - everything is ok - - - - - -1 - there is a parameter above the warning threshold value. - Check the raised event for more info - - - - - -2 - there is a parameter above the critical threshold value. - Check the raised event for more info - - - - - -3 - something went wrong (internal mechanism failed) - - - - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">show_fraud_stats</function> - - - Show the current statistics for all dials of a - user to a prefix. - - - NOTE: Since the fraud statistics are refreshed on-the-fly, as - check_fraud() is called, this function will - return stale data if check_fraud() has not been called at - least once for the (user, prefix) pair within a newly matching time - interval! - - - Name: show_fraud_stats - - Parameters: - - user - - prefix - -
-
- - <function moreinfo="none">fraud_reload</function> - - - Reload the all the fraud rules. - - - Name: fraud_reload - - Parameters: none -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_FRD_WARNING</function> - - - This event is raised whenever one of the 5 monitored parameters - is above the warning threshold value - Parameters: - - - param - the name of the parameter. - - - value - the current value of the parameter. - - - threshold - the warning threshold value. - - - user - the user who initiated the call. - - - called_number - the number that was called. - - - rule_id - the id of the fraud rule that matched - when the call was initiated - - - profile_id - the profile id used - - -
-
- - <function moreinfo="none">E_FRD_CRITICAL</function> - - - This event is raised whenever one of the 5 monitored parameters - is above the warning threshold value - Parameters: - - - param - the name of the parameter. - - - value - the current value of the parameter. - - - threshold - the warning threshold value. - - - user - the user who initiated the call. - - - called_number - the number that was called. - - - rule_id - the id of the fraud rule that matched - when the call was initiated - - - profile_id - the profile id used - - -
-
- -
- diff --git a/modules/freeswitch/README b/modules/freeswitch/README deleted file mode 100644 index bcbdea041c0..00000000000 --- a/modules/freeswitch/README +++ /dev/null @@ -1,175 +0,0 @@ -freeswitch Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. External Libraries or Applications - 1.3. Exported Parameters - - 1.3.1. event_heartbeat_interval (integer) - 1.3.2. esl_connect_timeout (integer) - 1.3.3. esl_cmd_timeout (integer) - 1.3.4. esl_cmd_polling_itv (integer) - - 1.4. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the event_heartbeat_interval parameter - 1.2. Setting the esl_connect_timeout parameter - 1.3. Setting the esl_cmd_timeout parameter - 1.4. Setting the esl_cmd_polling_itv parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The "freeswitch" module is a C driver for the FreeSWITCH Event - Socket Layer interface. It can interact with one or more - FreeSWITCH servers either by issuing commands to them, or by - receiving events from them. - - This driver can be seen as a centralized FreeSWITCH ESL - connection manager. OpenSIPS modules may use its API in order - to easily establish, reference and reuse ESL connections. - - A FreeSWITCH ESL URL is of the form: - fs://[username]:password@host[:port]. The default ESL port is - 8021. - -1.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. event_heartbeat_interval (integer) - - The expected interval between FreeSWITCH HEARTBEAT event - arrivals. - - Default value is “1” (second). - - Example 1.1. Setting the event_heartbeat_interval parameter -... -modparam("freeswitch", "event_heartbeat_interval", 20) -... - -1.3.2. esl_connect_timeout (integer) - - The maximally allowed duration for the establishment of an ESL - connection. - - Default value is “5000” (milliseconds). - - Example 1.2. Setting the esl_connect_timeout parameter -... -modparam("freeswitch", "esl_connect_timeout", 3000) -... - -1.3.3. esl_cmd_timeout (integer) - - The maximally allowed duration for the execution of an ESL - command. This interval does not include the connect duration. - - Default value is “5000” (milliseconds). - - Example 1.3. Setting the esl_cmd_timeout parameter -... -modparam("freeswitch", "esl_cmd_timeout", 3000) -... - -1.3.4. esl_cmd_polling_itv (integer) - - The sleep interval used when polling for an ESL command - response. Since the value of this parameter imposes a minimal - duration for any ESL command, you should run OpenSIPS in debug - mode in order to first determine an expected response time for - an arbitrary ESL command, then tune this parameter accordingly. - - Default value is “1000” (microseconds). - - Example 1.4. Setting the esl_cmd_polling_itv parameter -... -modparam("freeswitch", "esl_cmd_polling_itv", 3000) -... - -1.4. Exported Functions - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 115 53 4261 1560 - 2. Razvan Crainea (@razvancrainea) 12 10 30 21 - 3. Vlad Patrascu (@rvlad-patrascu) 5 3 21 41 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 8 5 - 5. rance 3 2 3 0 - 6. Maksym Sobolyev (@sobomax) 3 1 8 8 - 7. Peter Lemenkov (@lemenkov) 3 1 2 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2017 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Feb 2017 - Jul 2021 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2018 - Apr 2021 - 5. rance Oct 2020 - Mar 2021 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2017 www.opensips-solutions.com diff --git a/modules/freeswitch/README.md b/modules/freeswitch/README.md new file mode 100644 index 00000000000..ea5450eee65 --- /dev/null +++ b/modules/freeswitch/README.md @@ -0,0 +1,114 @@ +--- +title: "freeswitch Module" +description: "The freeswitch module is a C driver for the FreeSWITCH Event Socket Layer interface." +--- + +## Admin Guide + + +### Overview + + +The *"freeswitch"* module is a C driver for the +FreeSWITCH Event Socket Layer interface. It can interact with one or more +FreeSWITCH servers either by issuing commands to them, or by receiving +events from them. + + +This driver can be seen as a centralized FreeSWITCH ESL connection manager. +OpenSIPS modules may use its API in order to easily establish, reference +and reuse ESL connections. + + +A FreeSWITCH ESL URL is of the form: +**fs://[username]:password@host[:port]**. +The default ESL port is 8021. + + +### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### event_heartbeat_interval (integer) + + +The expected interval between FreeSWITCH HEARTBEAT event arrivals. + + +*Default value is "1" (second).* + + +```opensips title="Setting the event_heartbeat_interval parameter" +... +modparam("freeswitch", "event_heartbeat_interval", 20) +... +``` + + +#### esl_connect_timeout (integer) + + +The maximally allowed duration for the establishment of an ESL connection. + + +*Default value is "5000" (milliseconds).* + + +```opensips title="Setting the esl_connect_timeout parameter" +... +modparam("freeswitch", "esl_connect_timeout", 3000) +... +``` + + +#### esl_cmd_timeout (integer) + + +The maximally allowed duration for the execution of an ESL command. +This interval does not include the connect duration. + + +*Default value is "5000" (milliseconds).* + + +```opensips title="Setting the esl_cmd_timeout parameter" +... +modparam("freeswitch", "esl_cmd_timeout", 3000) +... +``` + + +#### esl_cmd_polling_itv (integer) + + +The sleep interval used when polling for an ESL command response. Since the +value of this parameter imposes a minimal duration for any ESL command, +you should run OpenSIPS in debug mode in order to first determine an expected +response time for an arbitrary ESL command, then tune this parameter accordingly. + + +*Default value is "1000" (microseconds).* + + +```opensips title="Setting the esl_cmd_polling_itv parameter" +... +modparam("freeswitch", "esl_cmd_polling_itv", 3000) +... +``` + + +### Exported Functions + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/freeswitch/doc/contributors.xml b/modules/freeswitch/doc/contributors.xml deleted file mode 100644 index c72b3b26861..00000000000 --- a/modules/freeswitch/doc/contributors.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 115 - 53 - 4261 - 1560 - - - 2. - Razvan Crainea (@razvancrainea) - 12 - 10 - 30 - 21 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 21 - 41 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 8 - 5 - - - 5. - rance - 3 - 2 - 3 - 0 - - - 6. - Maksym Sobolyev (@sobomax) - 3 - 1 - 8 - 8 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 2 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2017 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Feb 2017 - Jul 2021 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2018 - Apr 2021 - - - 5. - rance - Oct 2020 - Mar 2021 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/freeswitch/doc/freeswitch.xml b/modules/freeswitch/doc/freeswitch.xml deleted file mode 100644 index 56cb5534df5..00000000000 --- a/modules/freeswitch/doc/freeswitch.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%docentities; - -]> - - - - freeswitch Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2017 &osipssol; - diff --git a/modules/freeswitch/doc/freeswitch_admin.xml b/modules/freeswitch/doc/freeswitch_admin.xml deleted file mode 100644 index ed43755c477..00000000000 --- a/modules/freeswitch/doc/freeswitch_admin.xml +++ /dev/null @@ -1,128 +0,0 @@ - - - - &adminguide; - -
- Overview - - The "freeswitch" module is a C driver for the - FreeSWITCH Event Socket Layer interface. It can interact with one or more - FreeSWITCH servers either by issuing commands to them, or by receiving - events from them. - - - This driver can be seen as a centralized FreeSWITCH ESL connection manager. - OpenSIPS modules may use its API in order to easily establish, reference - and reuse ESL connections. - - - A FreeSWITCH ESL URL is of the form: - fs://[username]:password@host[:port]. - The default ESL port is 8021. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None - - - - -
- -
- Exported Parameters -
- <varname>event_heartbeat_interval</varname> (integer) - - The expected interval between FreeSWITCH HEARTBEAT event arrivals. - - - - Default value is 1 (second). - - - - Setting the <varname>event_heartbeat_interval</varname> parameter - -... -modparam("freeswitch", "event_heartbeat_interval", 20) -... - - -
-
- <varname>esl_connect_timeout</varname> (integer) - - The maximally allowed duration for the establishment of an ESL connection. - - - - Default value is 5000 (milliseconds). - - - - Setting the <varname>esl_connect_timeout</varname> parameter - -... -modparam("freeswitch", "esl_connect_timeout", 3000) -... - - -
-
- <varname>esl_cmd_timeout</varname> (integer) - - The maximally allowed duration for the execution of an ESL command. - This interval does not include the connect duration. - - - - Default value is 5000 (milliseconds). - - - - Setting the <varname>esl_cmd_timeout</varname> parameter - -... -modparam("freeswitch", "esl_cmd_timeout", 3000) -... - - -
-
- <varname>esl_cmd_polling_itv</varname> (integer) - - The sleep interval used when polling for an ESL command response. Since the - value of this parameter imposes a minimal duration for any ESL command, - you should run OpenSIPS in debug mode in order to first determine an expected - response time for an arbitrary ESL command, then tune this parameter accordingly. - - - - Default value is 1000 (microseconds). - - - - Setting the <varname>esl_cmd_polling_itv</varname> parameter - -... -modparam("freeswitch", "esl_cmd_polling_itv", 3000) -... - - -
-
- -
- Exported Functions -
-
diff --git a/modules/freeswitch_scripting/README b/modules/freeswitch_scripting/README deleted file mode 100644 index 77196999815..00000000000 --- a/modules/freeswitch_scripting/README +++ /dev/null @@ -1,371 +0,0 @@ -freeswitch_scripting Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. db_col_username (string) - 1.3.4. db_col_password (string) - 1.3.5. db_col_ip (string) - 1.3.6. db_col_port (string) - 1.3.7. db_col_events (string) - 1.3.8. fs_subscribe (string) - - 1.4. Exported Functions - - 1.4.1. freeswitch_esl(command, freeswitch_url[, - response_var]) - - 1.5. Exported MI Commands - - 1.5.1. fs_subscribe - 1.5.2. fs_unsubscribe - 1.5.3. fs_list - 1.5.4. fs_reload - - 1.6. Exported Events - - 1.6.1. E_FREESWITCH - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the db_url parameter - 1.2. Setting the db_table parameter - 1.3. Setting the db_col_username parameter - 1.4. Setting the db_col_password parameter - 1.5. Setting the db_col_ip parameter - 1.6. Setting the db_col_port parameter - 1.7. Setting the db_col_events parameter - 1.8. Setting the fs_subscribe parameter - 1.9. freeswitch_esl() usage - -Chapter 1. Admin Guide - -1.1. Overview - - freeswitch_scripting is a helper module that exposes full - control over the FreeSWITCH ESL interface to the OpenSIPS - script. - - It allows the OpenSIPS script writer to subscribe to generic - FreeSWITCH ESL events as well as to run arbitrary FreeSWITCH - ESL commands and interpret their results. It makes use of the - freeswitch module for the management of ESL connections and - event subscriptions. - - Credits for the initial idea and working code samples providing - both ESL events and commands go to Giovanni Maruzzelli - . - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded together with this module: - * freeswitch - * (optional) an SQL DB module - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. db_url (string) - - An SQL database URL which the module will use in order to load - a set of FreeSWITCH ESL sockets and their event subscriptions. - - Default value is “NULL” (DB support disabled). - - Example 1.1. Setting the db_url parameter -... -modparam("freeswitch_scripting", "db_url", "dbdriver://username:password -@dbhost/dbname") -... - -1.3.2. db_table (string) - - The SQL table name for this module. - - Default value is “freeswitch”. - - Example 1.2. Setting the db_table parameter -... -modparam("freeswitch_scripting", "db_table", "freeswitch_sockets") -... - -1.3.3. db_col_username (string) - - The SQL column name for the "username" ESL connect information. - - Default value is “username”. - - Example 1.3. Setting the db_col_username parameter -... -modparam("freeswitch_scripting", "db_col_username", "user") -... - -1.3.4. db_col_password (string) - - The SQL column name for the "password" ESL connect information. - - Default value is “password”. - - Example 1.4. Setting the db_col_password parameter -... -modparam("freeswitch_scripting", "db_col_password", "pass") -... - -1.3.5. db_col_ip (string) - - The SQL column name for the "ip" ESL connect information. - - Default value is “ip”. - - Example 1.5. Setting the db_col_ip parameter -... -modparam("freeswitch_scripting", "db_col_ip", "ip_addr") -... - -1.3.6. db_col_port (string) - - The SQL column name for the "port" ESL connect information. - - Default value is “port”. - - Example 1.6. Setting the db_col_port parameter -... -modparam("freeswitch_scripting", "db_col_port", "tcp_port") -... - -1.3.7. db_col_events (string) - - The SQL column name for the comma-separated, case-sensitive - FreeSWITCH event names which OpenSIPS will subscribe to. - - Default value is “events_csv”. - - Example 1.7. Setting the db_col_events parameter -... -modparam("freeswitch_scripting", "db_col_events", "fs_events") -... - -1.3.8. fs_subscribe (string) - - Add a FreeSWITCH ESL URL to which OpenSIPS will connect at - startup. The URL syntax includes support for specifying a list - of events to subscribe to and follows this pattern: - [fs://][[username]:password@]host[:port][?event1[,event2]...] - - This parameter can be set multiple times. - - Example 1.8. Setting the fs_subscribe parameter -... -modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.10?CHA -NNEL_STATE") -modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.11:802 -1?DTMF,BACKGROUND_JOB") -... - -1.4. Exported Functions - -1.4.1. freeswitch_esl(command, freeswitch_url[, response_var]) - - Run an arbitrary command on an arbitrary FreeSWITCH ESL socket. - The socket need not necessarily be defined in the database or - through fs_subscribe. However, if this is the case, then the - "password" part of the URL becomes mandatory. - - The current OpenSIPS worker will block until an answer from - FreeSWITCH arrives. The timeout for this operation can be - controlled via the esl_cmd_timeout parameter of the freeswitch - connection manager module. - - Meaning of the parameters is as follows: - * command (string) - the ESL command string to execute. - * freeswitch_url (string) - the ESL interface to connect to. - The syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2].. - .]. The "?events" part of the URL will be silently - discarded. - * response_var (var, optional) - a variable which will hold - the text result of the ESL command. - - Return value - * 1 (success) - the ESL command executed successfully and any - output variables were successfully written to. Note that - this does not say anything about the nature of the ESL - answer (it may well be a "-ERR" type of response) - * -1 (failure) - internal error or the ESL command failed to - execute - - This function can be used from any route. - - Example 1.9. freeswitch_esl() usage -... - # ESL socket 10.0.0.10 is defined in the database (password "Clu -eCon") - $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123 -456789}user/1010 9386\njob-uuid: foobar", "10.0.0.10", "$var(response)") -; - if ($var(rc) < 0) { - xlog("failed to execute ESL command ($var(rc))\n"); - return -1; - } -... - # ESL socket 10.0.0.10 is new, we must specify a password - $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123 -456789}user/1010 9386\njob-uuid: foobar", ":ClueCon@10.0.0.10", $var(res -ponse)); - if ($var(rc) < 0) { - xlog("failed to execute ESL command ($var(rc))\n"); - return -1; - } -... - -1.5. Exported MI Commands - -1.5.1. fs_subscribe - - Ensures that the given FreeSWITCH ESL socket is subscribed to - the given list of events. In case an event cannot be subscribed - to, the freeswitch driver will periodically retry to subscribe - to it until an fs_unsubscribe MI command for the respective - event is issued. - - Parameters: - * freeswitch_url - the ESL interface to connect to. The - syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2].. - .]. The "?events" part of the URL will be silently - discarded. - * event - the name of the event to subscribe to - * ... - (other events) - -1.5.2. fs_unsubscribe - - Ensures that the given FreeSWITCH ESL socket is unsubscribed - from the given list of events. - - Parameters: - * freeswitch_url - the ESL interface to search for. The - syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2].. - .]. The "?events" part of the URL will be silently - discarded. - * event - the name of the event to unsubscribe from - * ... - (other events) - -1.5.3. fs_list - - Displays the current set of FreeSWITCH ESL sockets and the list - of events that the module is subscribed to for each socket. - -1.5.4. fs_reload - - Replaces the current set* of FreeSWITCH ESL sockets along with - their respective events with the current data (ESL sockets and - their events) found in the "freeswitch" table. - - * this includes any sockets/events provisioned through - fs_subscribe, MI fs_subscribe commands or previous DB data set. - -1.6. Exported Events - -1.6.1. E_FREESWITCH - - This event is raised when OpenSIPS receives an ESL event - notification from a socket that the "freeswitch_scripting" - module is subscribed to. - - Parameters: - * name - the name of the event - * sender - the FreeSWITCH sender IP address - * body - the full JSON-encoded body of the event, as sent by - FreeSWITCH. Use the json module ($json variable) to easily - interpret it. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 49 27 1935 277 - 2. Vlad Patrascu (@rvlad-patrascu) 8 3 137 124 - 3. Razvan Crainea (@razvancrainea) 5 3 3 1 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 4 2 - 5. Maksym Sobolyev (@sobomax) 3 1 4 4 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Dec 2017 - Feb 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Mar 2020 - 4. Razvan Crainea (@razvancrainea) May 2019 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) Jan 2019 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov). - - Documentation Copyrights: - - Copyright © 2017 www.opensips-solutions.com diff --git a/modules/freeswitch_scripting/README.md b/modules/freeswitch_scripting/README.md new file mode 100644 index 00000000000..33799af2d9d --- /dev/null +++ b/modules/freeswitch_scripting/README.md @@ -0,0 +1,337 @@ +--- +title: "freeswitch_scripting Module" +description: "freeswitch_scripting is a helper module that exposes full control over the FreeSWITCH ESL interface to the OpenSIPS script." +--- + +## Admin Guide + + +### Overview + + +*freeswitch_scripting* is a helper module that +exposes full control over the FreeSWITCH ESL interface to the OpenSIPS +script. + + +It allows the OpenSIPS script writer to subscribe +to generic FreeSWITCH ESL events as well as to run arbitrary +FreeSWITCH ESL commands and interpret their results. +It makes use of the [freeswitch](../freeswitch) +module for the management of ESL connections and event subscriptions. + + +Credits for the initial idea and working code samples providing +both ESL events and commands go to Giovanni Maruzzelli +. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded together with this module: + + +- *freeswitch* +- *(optional) an SQL DB module* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### db_url (string) + + +An SQL database URL which the module will use in order to +load a set of FreeSWITCH ESL sockets and their event subscriptions. + + +*Default value is "NULL" (DB support disabled).* + + +```opensips title="Setting the db_url parameter" +... +modparam("freeswitch_scripting", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### db_table (string) + + +The SQL table name for this module. + + +*Default value is "freeswitch".* + + +```opensips title="Setting the db_table parameter" +... +modparam("freeswitch_scripting", "db_table", "freeswitch_sockets") +... +``` + + +#### db_col_username (string) + + +The SQL column name for the "username" ESL connect information. + + +*Default value is "username".* + + +```opensips title="Setting the db_col_username parameter" +... +modparam("freeswitch_scripting", "db_col_username", "user") +... +``` + + +#### db_col_password (string) + + +The SQL column name for the "password" ESL connect information. + + +*Default value is "password".* + + +```opensips title="Setting the db_col_password parameter" +... +modparam("freeswitch_scripting", "db_col_password", "pass") +... +``` + + +#### db_col_ip (string) + + +The SQL column name for the "ip" ESL connect information. + + +*Default value is "ip".* + + +```opensips title="Setting the db_col_ip parameter" +... +modparam("freeswitch_scripting", "db_col_ip", "ip_addr") +... +``` + + +#### db_col_port (string) + + +The SQL column name for the "port" ESL connect information. + + +*Default value is "port".* + + +```opensips title="Setting the db_col_port parameter" +... +modparam("freeswitch_scripting", "db_col_port", "tcp_port") +... +``` + + +#### db_col_events (string) + + +The SQL column name for the comma-separated, case-sensitive FreeSWITCH +event names which OpenSIPS will subscribe to. + + +*Default value is "events_csv".* + + +```opensips title="Setting the db_col_events parameter" +... +modparam("freeswitch_scripting", "db_col_events", "fs_events") +... +``` + + +#### fs_subscribe (string) + + +Add a FreeSWITCH ESL URL to which OpenSIPS will connect at startup. +The URL syntax includes support for specifying a list of events to +subscribe to and follows this pattern: +**[fs://][[username]:password@]host[:port][?event1[,event2]...]** + + +*This parameter can be set multiple times.* + + +```opensips title="Setting the fs_subscribe parameter" +... +modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.10?CHANNEL_STATE") +modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.11:8021?DTMF,BACKGROUND_JOB") +... +``` + + +### Exported Functions + + +#### freeswitch_esl(command, freeswitch_url[, response_var]) + + +Run an arbitrary command on an arbitrary FreeSWITCH ESL socket. The +socket need not necessarily be defined in the database or through +**[fs subscribe](#param_fs_subscribe)**. +However, if this is the case, then the "password" part of the URL +becomes mandatory. + + +The current OpenSIPS worker will block until an answer from FreeSWITCH +arrives. The timeout for this operation can be controlled via the +**esl_cmd_timeout** parameter of the +freeswitch connection manager module. + + +Meaning of the parameters is as follows: + + +- *command* (string) - the ESL command string to +execute. +- *freeswitch_url* (string) - the ESL interface to +connect to. The syntax is: +[fs://][[username]:password@]host[:port][?event1[,event2]...]. +The "?events" part of the URL will be silently discarded. +- *response_var (var, optional)* - a +variable which will hold the text result of the ESL command. + + +**Return value** + + +- 1 (success) - the ESL command executed successfully and any +output variables were successfully written to. Note that this +does not say anything about the nature of the ESL answer (it +may well be a "-ERR" type of response) +- -1 (failure) - internal error or the ESL command failed to +execute + + +This function can be used from any route. + + +```opensips title="*freeswitch_esl()* usage" +... + # ESL socket 10.0.0.10 is defined in the database (password "ClueCon") + $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123456789}user/1010 9386\njob-uuid: foobar", "10.0.0.10", "$var(response)"); + if ($var(rc) < 0) { + xlog("failed to execute ESL command ($var(rc))\n"); + return -1; + } +... + # ESL socket 10.0.0.10 is new, we must specify a password + $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123456789}user/1010 9386\njob-uuid: foobar", ":ClueCon@10.0.0.10", $var(response)); + if ($var(rc) < 0) { + xlog("failed to execute ESL command ($var(rc))\n"); + return -1; + } +... +``` + + +### Exported MI Commands + + +#### fs_subscribe + + +Ensures that the given FreeSWITCH ESL socket is subscribed to the given +list of events. In case an event cannot be subscribed to, the freeswitch +driver will periodically retry to subscribe to it until an fs_unsubscribe +MI command for the respective event is issued. + + +Parameters: + + +- *freeswitch_url* - the ESL interface to +connect to. The syntax is: +[fs://][[username]:password@]host[:port][?event1[,event2]...]. +The "?events" part of the URL will be silently discarded. +- *event* - the name of the event to subscribe to +- *...* - (other events) + + +#### fs_unsubscribe + + +Ensures that the given FreeSWITCH ESL socket is unsubscribed from the given +list of events. + + +Parameters: + + +- *freeswitch_url* - the ESL interface to +search for. The syntax is: +[fs://][[username]:password@]host[:port][?event1[,event2]...]. +The "?events" part of the URL will be silently discarded. +- *event* - the name of the event to unsubscribe from +- *...* - (other events) + + +#### fs_list + + +Displays the current set of FreeSWITCH ESL sockets and the list of events +that the module is subscribed to for each socket. + + +#### fs_reload + + +Replaces the current set* of FreeSWITCH ESL sockets along with their respective +events with the current data (ESL sockets and their events) found in the +"freeswitch" table. + + +* this includes any sockets/events provisioned through +[fs subscribe](#param_fs_subscribe), MI +[mi fs subscribe](#fs_subscribe) commands or previous DB data set. + + +### Exported Events + + +#### E_FREESWITCH + + +This event is raised when OpenSIPS receives an ESL event notification from +a socket that the "freeswitch_scripting" module is subscribed to. + + +Parameters: + + +- *name* - the name of the event +- *sender* - the FreeSWITCH sender IP address +- *body* - the full JSON-encoded body of the event, +as sent by FreeSWITCH. Use the json module ($json variable) +to easily interpret it. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/freeswitch_scripting/doc/contributors.xml b/modules/freeswitch_scripting/doc/contributors.xml deleted file mode 100644 index 76d7e0bf2d9..00000000000 --- a/modules/freeswitch_scripting/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 49 - 27 - 1935 - 277 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 8 - 3 - 137 - 124 - - - 3. - Razvan Crainea (@razvancrainea) - 5 - 3 - 3 - 1 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 4 - 2 - - - 5. - Maksym Sobolyev (@sobomax) - 3 - 1 - 4 - 4 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Dec 2017 - Feb 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Mar 2020 - - - 4. - Razvan Crainea (@razvancrainea) - May 2019 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - Jan 2019 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov). -
- -
diff --git a/modules/freeswitch_scripting/doc/freeswitch_scripting.xml b/modules/freeswitch_scripting/doc/freeswitch_scripting.xml deleted file mode 100644 index 12f744564b7..00000000000 --- a/modules/freeswitch_scripting/doc/freeswitch_scripting.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%docentities; - -]> - - - - freeswitch_scripting Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2017 &osipssol; - diff --git a/modules/freeswitch_scripting/doc/freeswitch_scripting_admin.xml b/modules/freeswitch_scripting/doc/freeswitch_scripting_admin.xml deleted file mode 100644 index d0556587554..00000000000 --- a/modules/freeswitch_scripting/doc/freeswitch_scripting_admin.xml +++ /dev/null @@ -1,420 +0,0 @@ - - - - &adminguide; - -
- Overview - - freeswitch_scripting is a helper module that - exposes full control over the FreeSWITCH ESL interface to the OpenSIPS - script. - - - It allows the OpenSIPS script writer to subscribe - to generic FreeSWITCH ESL events as well as to run arbitrary - FreeSWITCH ESL commands and interpret their results. - It makes use of the freeswitch - module for the management of ESL connections and event subscriptions. - - - Credits for the initial idea and working code samples providing - both ESL events and commands go to Giovanni Maruzzelli - <gmaruzz@opentelecom.it>. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded together with this module: - - - - freeswitch - - - - - (optional) an SQL DB module - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - An SQL database URL which the module will use in order to - load a set of FreeSWITCH ESL sockets and their event subscriptions. - - - - Default value is NULL (DB support disabled). - - - - Setting the <varname>db_url</varname> parameter - -... -modparam("freeswitch_scripting", "db_url", "&exampledb;") -... - - -
- -
- <varname>db_table</varname> (string) - - The SQL table name for this module. - - - - Default value is freeswitch. - - - - Setting the <varname>db_table</varname> parameter - -... -modparam("freeswitch_scripting", "db_table", "freeswitch_sockets") -... - - -
- -
- <varname>db_col_username</varname> (string) - - The SQL column name for the "username" ESL connect information. - - - - Default value is username. - - - - Setting the <varname>db_col_username</varname> parameter - -... -modparam("freeswitch_scripting", "db_col_username", "user") -... - - -
- -
- <varname>db_col_password</varname> (string) - - The SQL column name for the "password" ESL connect information. - - - - Default value is password. - - - - Setting the <varname>db_col_password</varname> parameter - -... -modparam("freeswitch_scripting", "db_col_password", "pass") -... - - -
- -
- <varname>db_col_ip</varname> (string) - - The SQL column name for the "ip" ESL connect information. - - - - Default value is ip. - - - - Setting the <varname>db_col_ip</varname> parameter - -... -modparam("freeswitch_scripting", "db_col_ip", "ip_addr") -... - - -
- -
- <varname>db_col_port</varname> (string) - - The SQL column name for the "port" ESL connect information. - - - - Default value is port. - - - - Setting the <varname>db_col_port</varname> parameter - -... -modparam("freeswitch_scripting", "db_col_port", "tcp_port") -... - - -
- -
- <varname>db_col_events</varname> (string) - - The SQL column name for the comma-separated, case-sensitive FreeSWITCH - event names which OpenSIPS will subscribe to. - - - - Default value is events_csv. - - - - Setting the <varname>db_col_events</varname> parameter - -... -modparam("freeswitch_scripting", "db_col_events", "fs_events") -... - - -
- -
- <varname>fs_subscribe</varname> (string) - - Add a FreeSWITCH ESL URL to which OpenSIPS will connect at startup. - The URL syntax includes support for specifying a list of events to - subscribe to and follows this pattern: - [fs://][[username]:password@]host[:port][?event1[,event2]...] - - - - This parameter can be set multiple times. - - - - Setting the <varname>fs_subscribe</varname> parameter - -... -modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.10?CHANNEL_STATE") -modparam("freeswitch_scripting", "fs_subscribe", ":ClueCon@10.0.0.11:8021?DTMF,BACKGROUND_JOB") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">freeswitch_esl(command, freeswitch_url[, response_var])</function> - - - Run an arbitrary command on an arbitrary FreeSWITCH ESL socket. The - socket need not necessarily be defined in the database or through - . - However, if this is the case, then the "password" part of the URL - becomes mandatory. - - - The current OpenSIPS worker will block until an answer from FreeSWITCH - arrives. The timeout for this operation can be controlled via the - esl_cmd_timeout parameter of the - freeswitch connection manager module. - - - Meaning of the parameters is as follows: - - - command (string) - the ESL command string to - execute. - - - - - freeswitch_url (string) - the ESL interface to - connect to. The syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2]...]. - The "?events" part of the URL will be silently discarded. - - - - response_var (var, optional) - a - variable which will hold the text result of the ESL command. - - - - Return value - - - - 1 (success) - the ESL command executed successfully and any - output variables were successfully written to. Note that this - does not say anything about the nature of the ESL answer (it - may well be a "-ERR" type of response) - - - - - -1 (failure) - internal error or the ESL command failed to - execute - - - - - This function can be used from any route. - - - <function moreinfo="none"> - <emphasis>freeswitch_esl()</emphasis></function> usage - -... - # ESL socket 10.0.0.10 is defined in the database (password "ClueCon") - $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123456789}user/1010 9386\njob-uuid: foobar", "10.0.0.10", "$var(response)"); - if ($var(rc) < 0) { - xlog("failed to execute ESL command ($var(rc))\n"); - return -1; - } -... - # ESL socket 10.0.0.10 is new, we must specify a password - $var(rc) = freeswitch_esl("bgapi originate {origination_uuid=123456789}user/1010 9386\njob-uuid: foobar", ":ClueCon@10.0.0.10", $var(response)); - if ($var(rc) < 0) { - xlog("failed to execute ESL command ($var(rc))\n"); - return -1; - } -... - - -
- -
- -
- Exported MI Commands -
- fs_subscribe - - Ensures that the given FreeSWITCH ESL socket is subscribed to the given - list of events. In case an event cannot be subscribed to, the freeswitch - driver will periodically retry to subscribe to it until an fs_unsubscribe - MI command for the respective event is issued. - - Parameters: - - - freeswitch_url - the ESL interface to - connect to. The syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2]...]. - The "?events" part of the URL will be silently discarded. - - - event - the name of the event to subscribe to - - - ... - (other events) - - -
-
- fs_unsubscribe - - Ensures that the given FreeSWITCH ESL socket is unsubscribed from the given - list of events. - - Parameters: - - - freeswitch_url - the ESL interface to - search for. The syntax is: - [fs://][[username]:password@]host[:port][?event1[,event2]...]. - The "?events" part of the URL will be silently discarded. - - - event - the name of the event to unsubscribe from - - - ... - (other events) - - -
-
- fs_list - - Displays the current set of FreeSWITCH ESL sockets and the list of events - that the module is subscribed to for each socket. - -
-
- fs_reload - - Replaces the current set* of FreeSWITCH ESL sockets along with their respective - events with the current data (ESL sockets and their events) found in the - "freeswitch" table. - - - * this includes any sockets/events provisioned through - , MI - commands or previous DB data set. - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_FREESWITCH</function> - - - This event is raised when OpenSIPS receives an ESL event notification from - a socket that the "freeswitch_scripting" module is subscribed to. - - Parameters: - - - name - the name of the event - - - sender - the FreeSWITCH sender IP address - - - body - the full JSON-encoded body of the event, - as sent by FreeSWITCH. Use the json module ($json variable) - to easily interpret it. - - -
- -
- -
diff --git a/modules/gflags/README b/modules/gflags/README deleted file mode 100644 index 13b00a2bdc7..00000000000 --- a/modules/gflags/README +++ /dev/null @@ -1,290 +0,0 @@ -gflags Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. initial (integer) - - 1.4. Exported Functions - - 1.4.1. set_gflag(flag) - 1.4.2. reset_gflag(flag) - 1.4.3. is_gflag(flag) - - 1.5. Exported MI Functions - - 1.5.1. set_gflag - 1.5.2. reset_gflag - 1.5.3. is_gflag - 1.5.4. get_gflags - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. initial parameter usage - 1.2. set_gflag() usage - 1.3. reset_gflag() usage - 1.4. is_gflag() usage - 1.5. set_gflag usage - 1.6. reset_gflag usage - 1.7. is_gflag usage - 1.8. get_gflags usage - -Chapter 1. Admin Guide - -1.1. Overview - - gflags module (global flags) keeps a bitmap of flags in shared - memory and may be used to change behaviour of server based on - value of the flags. Example: - if (is_gflag(1)) { - t_relay("udp:10.0.0.1:5060"); - } else { - t_relay("udp:10.0.0.2:5060"); - } - - The benefit of this module is the value of the switch flags can - be manipulated by external applications such as web interface - or command line tools. The size of bitmap is 32. - - The module exports external commands that can be used to change - the global flags via Management Interface. The MI commands are: - “set_gflag”, “reset_gflag” and “is_gflag”. - -1.2. Dependencies - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * none - -1.3. Exported Parameters - -1.3.1. initial (integer) - - The initial value of global flags bitmap. - - Default value is “0”. - - Example 1.1. initial parameter usage -modparam("gflags", "initial", 15) - -1.4. Exported Functions - -1.4.1. set_gflag(flag) - - Set the bit at the position “flag” in global flags. - - The “flag” (int) parameter can have a value in the range of - 0..31. - - This function may be used from any route. - - Example 1.2. set_gflag() usage -... -set_gflag(4); -... - -1.4.2. reset_gflag(flag) - - Reset the bit at the position “flag” in global flags. - - The “flag” (int) parameter can have a value in the range of - 0..31. - - This function may be used from any route. - - Example 1.3. reset_gflag() usage -... -reset_gflag(4); -... - -1.4.3. is_gflag(flag) - - Check if bit at the position “flag” in global flags is set. - - The “flag” (int) parameter can have a value in the range of - 0..31. - - This function may be used from any route. - - Example 1.4. is_gflag() usage -... -if(is_gflag(4)) -{ - log("global flag 4 is set\n"); -} else { - log("global flag 4 is not set\n"); -}; -... - -1.5. Exported MI Functions - - Functions that check or change some flags accepts one parameter - which is the flag bitmap/mask specifing the corresponding - flags. It is not possible to specify directly the flag position - that should be changed as in the functions available in the - routing script. - -1.5.1. set_gflag - - Set the value of some flags (specified by bitmask) to 1. - - The parameter value must be a bitmask in decimal or hexa - format. The bitmaks has a 32 bit size. - - Example 1.5. set_gflag usage -... -$ opensips-cli -x mi set_gflag 1 -$ opensips-cli -x mi set_gflag 0x3 -... - -1.5.2. reset_gflag - - Reset the value of some flags to 0. - - The parameter value must be a bitmask in decimal or hexa - format. The bitmaks has a 32 bit size. - - Example 1.6. reset_gflag usage -... -$ opensips-cli -x mi reset_gflag 1 -$ opensips-cli -x mi reset_gflag 0x3 -... - -1.5.3. is_gflag - - Returns true if the all the flags from the bitmask are set. - - The parameter value must be a bitmask in decimal or hexa - format. The bitmaks has a 32 bit size. - - The function returns TRUE if all the flags from the set are set - and FALSE if at least one is not set. - - Example 1.7. is_gflag usage -... -$ opensips-cli -x mi set_gflag 1024 -$ opensips-cli -x mi is_gflag 1024 -TRUE -$ opensips-cli -x mi is_gflag 1025 -TRUE -$ opensips-cli -x mi is_gflag 1023 -FALSE -$ opensips-cli -x mi set_gflag 0x10 -$ opensips-cli -x mi is_gflag 1023 -TRUE -$ opensips-cli -x mi is_gflag 1007 -FALSE -$ opensips-cli -x mi is_gflag 16 -TRUE -... - -1.5.4. get_gflags - - Return the bitmap with all flags. The function gets no - parameters and returns the bitmap in hexa and decimal format. - - Example 1.8. get_gflags usage -... -$ opensips-cli -x mi get_gflags -0x3039 -12345 -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 41 31 423 326 - 2. Daniel-Constantin Mierla (@miconda) 14 12 42 22 - 3. Liviu Chircu (@liviuchircu) 13 11 27 59 - 4. Razvan Crainea (@razvancrainea) 10 8 26 24 - 5. Henning Westerholt (@henningw) 8 6 42 31 - 6. Jiri Kuthan (@jiriatipteldotorg) 8 4 278 4 - 7. Vlad Patrascu (@rvlad-patrascu) 7 4 88 94 - 8. Maksym Sobolyev (@sobomax) 4 2 3 4 - 9. Richard Revels 3 1 24 11 - 10. Anca Vamanu 3 1 6 3 - - All remaining contributors: Konstantin Bokarius, Andrei - Pelinescu-Onciul, Dan Pascu (@danpascu), Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Klaus Darilion, Ancuta - Onofrei. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - Oct 2022 - 4. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 5. Dan Pascu (@danpascu) May 2019 - May 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Anca Vamanu Sep 2009 - Sep 2009 - 9. Richard Revels Aug 2008 - Aug 2008 - 10. Daniel-Constantin Mierla (@miconda) Oct 2005 - Jun 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw), Ancuta Onofrei, Klaus - Darilion, Andrei Pelinescu-Onciul, Jiri Kuthan - (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan - Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Richard - Revels, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Klaus Darilion. - - Documentation Copyrights: - - Copyright © 2004 FhG FOKUS diff --git a/modules/gflags/README.md b/modules/gflags/README.md new file mode 100644 index 00000000000..cfcf6da81d8 --- /dev/null +++ b/modules/gflags/README.md @@ -0,0 +1,228 @@ +--- +title: "gflags Module" +description: "gflags module (global flags) keeps a bitmap of flags in shared memory and may be used to change behaviour of server based on value of the flags." +--- + +## Admin Guide + + +### Overview + + +gflags module (global flags) keeps a bitmap of flags in shared memory +and may be used to change behaviour of server based on value of the flags. +Example: + + +```opensips +if (is_gflag(1)) { + t_relay("udp:10.0.0.1:5060"); +} else { + t_relay("udp:10.0.0.2:5060"); +} +``` + + +The benefit of this module is the value of the switch flags +can be manipulated by external applications such as web interface +or command line tools. The size of bitmap is 32. + + +The module exports external commands that can be used to change +the global flags via Management Interface. The MI commands are: +"set_gflag", "reset_gflag" and +"is_gflag". + + +### Dependencies + + +The module depends on the following modules (in the other words the +listed modules must be loaded before this module): + + +- *none* + + +### Exported Parameters + + +#### initial (integer) + + +The initial value of global flags bitmap. + + +Default value is "0". + + +```opensips title="initial parameter usage" +modparam("gflags", "initial", 15) +``` + + +### Exported Functions + + +#### set_gflag(flag) + + +Set the bit at the position "flag" in global flags. + + +The "flag" (int) parameter can have a value in the range of 0..31. + + +This function may be used from any route. + + +```opensips title="set_gflag() usage" +... +set_gflag(4); +... +``` + + +#### reset_gflag(flag) + + +Reset the bit at the position "flag" in global flags. + + +The "flag" (int) parameter can have a value in the range of 0..31. + + +This function may be used from any route. + + +```opensips title="reset_gflag() usage" +... +reset_gflag(4); +... +``` + + +#### is_gflag(flag) + + +Check if bit at the position "flag" in global flags is +set. + + +The "flag" (int) parameter can have a value in the range of 0..31. + + +This function may be used from any route. + + +```opensips title="is_gflag() usage" +... +if(is_gflag(4)) +{ + log("global flag 4 is set\n"); +} else { + log("global flag 4 is not set\n"); +}; +... +``` + + +### Exported MI Functions + + +Functions that check or change some flags accepts one parameter +which is the flag bitmap/mask specifing the corresponding flags. +It is not possible to specify directly the flag position that +should be changed as in the functions available in the routing +script. + + +#### set_gflag + + +Set the value of some flags (specified by bitmask) to 1. + + +The parameter value must be a bitmask in decimal or hexa format. +The bitmaks has a 32 bit size. + + +```bash title="set_gflag usage" +... +$ opensips-cli -x mi set_gflag 1 +$ opensips-cli -x mi set_gflag 0x3 +... +``` + + +#### reset_gflag + + +Reset the value of some flags to 0. + + +The parameter value must be a bitmask in decimal or hexa format. +The bitmaks has a 32 bit size. + + +```bash title="reset_gflag usage" +... +$ opensips-cli -x mi reset_gflag 1 +$ opensips-cli -x mi reset_gflag 0x3 +... +``` + + +#### is_gflag + + +Returns true if the all the flags from the bitmask are set. + + +The parameter value must be a bitmask in decimal or hexa format. +The bitmaks has a 32 bit size. + + +The function returns TRUE if all the flags from the set are set +and FALSE if at least one is not set. + + +```bash title="is_gflag usage" +... +$ opensips-cli -x mi set_gflag 1024 +$ opensips-cli -x mi is_gflag 1024 +TRUE +$ opensips-cli -x mi is_gflag 1025 +TRUE +$ opensips-cli -x mi is_gflag 1023 +FALSE +$ opensips-cli -x mi set_gflag 0x10 +$ opensips-cli -x mi is_gflag 1023 +TRUE +$ opensips-cli -x mi is_gflag 1007 +FALSE +$ opensips-cli -x mi is_gflag 16 +TRUE +... +``` + + +#### get_gflags + + +Return the bitmap with all flags. The function gets no +parameters and returns the bitmap in hexa and decimal format. + + +```bash title="get_gflags usage" +... +$ opensips-cli -x mi get_gflags +0x3039 +12345 +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/gflags/doc/contributors.xml b/modules/gflags/doc/contributors.xml deleted file mode 100644 index 25e458b5a2f..00000000000 --- a/modules/gflags/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 41 - 31 - 423 - 326 - - - 2. - Daniel-Constantin Mierla (@miconda) - 14 - 12 - 42 - 22 - - - 3. - Liviu Chircu (@liviuchircu) - 13 - 11 - 27 - 59 - - - 4. - Razvan Crainea (@razvancrainea) - 10 - 8 - 26 - 24 - - - 5. - Henning Westerholt (@henningw) - 8 - 6 - 42 - 31 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 8 - 4 - 278 - 4 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 7 - 4 - 88 - 94 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 9. - Richard Revels - 3 - 1 - 24 - 11 - - - 10. - Anca Vamanu - 3 - 1 - 6 - 3 - - - -
-All remaining contributors: Konstantin Bokarius, Andrei Pelinescu-Onciul, Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Klaus Darilion, Ancuta Onofrei. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - Oct 2022 - - - 4. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 5. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Anca Vamanu - Sep 2009 - Sep 2009 - - - 9. - Richard Revels - Aug 2008 - Aug 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Oct 2005 - Jun 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Ancuta Onofrei, Klaus Darilion, Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Richard Revels, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Klaus Darilion. -
- -
diff --git a/modules/gflags/doc/gflags.xml b/modules/gflags/doc/gflags.xml deleted file mode 100644 index f5643633daa..00000000000 --- a/modules/gflags/doc/gflags.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - gflags Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2004 &fhg; - - diff --git a/modules/gflags/doc/gflags_admin.xml b/modules/gflags/doc/gflags_admin.xml deleted file mode 100644 index f12236f6c75..00000000000 --- a/modules/gflags/doc/gflags_admin.xml +++ /dev/null @@ -1,243 +0,0 @@ - - - - - &adminguide; - -
- Overview - - gflags module (global flags) keeps a bitmap of flags in shared memory - and may be used to change behaviour of server based on value of the flags. - Example: - - if (is_gflag(1)) { - t_relay("udp:10.0.0.1:5060"); - } else { - t_relay("udp:10.0.0.2:5060"); - } - - - - The benefit of this module is the value of the switch flags - can be manipulated by external applications such as web interface - or command line tools. The size of bitmap is 32. - - - The module exports external commands that can be used to change - the global flags via Management Interface. The MI commands are: - set_gflag, reset_gflag and - is_gflag. - -
- -
- Dependencies - - The module depends on the following modules (in the other words the - listed modules must be loaded before this module): - - - none - - - -
- -
- Exported Parameters -
- <varname>initial</varname> (integer) - - The initial value of global flags bitmap. - - - Default value is 0. - - - <varname>initial</varname> parameter usage - -modparam("gflags", "initial", 15) - - -
-
- -
- Exported Functions -
- <function moreinfo="none">set_gflag(flag)</function> - - Set the bit at the position flag in global flags. - - - The flag (int) parameter can have a value in the range of 0..31. - - - This function may be used from any route. - - - <function moreinfo="none">set_gflag()</function> usage - -... -set_gflag(4); -... - - -
- -
- <function moreinfo="none">reset_gflag(flag)</function> - - Reset the bit at the position flag in global flags. - - - The flag (int) parameter can have a value in the range of 0..31. - - - This function may be used from any route. - - - <function moreinfo="none">reset_gflag()</function> usage - -... -reset_gflag(4); -... - - -
- -
- <function moreinfo="none">is_gflag(flag)</function> - - Check if bit at the position flag in global flags is - set. - - - The flag (int) parameter can have a value in the range of 0..31. - - - This function may be used from any route. - - - <function moreinfo="none">is_gflag()</function> usage - -... -if(is_gflag(4)) -{ - log("global flag 4 is set\n"); -} else { - log("global flag 4 is not set\n"); -}; -... - - -
- -
- -
- Exported MI Functions - Functions that check or change some flags accepts one parameter - which is the flag bitmap/mask specifing the corresponding flags. - It is not possible to specify directly the flag position that - should be changed as in the functions available in the routing - script. - -
- <function moreinfo="none">set_gflag</function> - - Set the value of some flags (specified by bitmask) to 1. - - - The parameter value must be a bitmask in decimal or hexa format. - The bitmaks has a 32 bit size. - - - <function moreinfo="none">set_gflag</function> usage - -... -$ opensips-cli -x mi set_gflag 1 -$ opensips-cli -x mi set_gflag 0x3 -... - - - -
-
- <function moreinfo="none">reset_gflag</function> - - Reset the value of some flags to 0. - - - The parameter value must be a bitmask in decimal or hexa format. - The bitmaks has a 32 bit size. - - - - <function moreinfo="none">reset_gflag</function> usage - -... -$ opensips-cli -x mi reset_gflag 1 -$ opensips-cli -x mi reset_gflag 0x3 -... - - -
-
- <function moreinfo="none">is_gflag</function> - - Returns true if the all the flags from the bitmask are set. - - - The parameter value must be a bitmask in decimal or hexa format. - The bitmaks has a 32 bit size. - - - The function returns TRUE if all the flags from the set are set - and FALSE if at least one is not set. - - - <function moreinfo="none">is_gflag</function> usage - -... -$ opensips-cli -x mi set_gflag 1024 -$ opensips-cli -x mi is_gflag 1024 -TRUE -$ opensips-cli -x mi is_gflag 1025 -TRUE -$ opensips-cli -x mi is_gflag 1023 -FALSE -$ opensips-cli -x mi set_gflag 0x10 -$ opensips-cli -x mi is_gflag 1023 -TRUE -$ opensips-cli -x mi is_gflag 1007 -FALSE -$ opensips-cli -x mi is_gflag 16 -TRUE -... - - -
-
- <function moreinfo="none">get_gflags</function> - - Return the bitmap with all flags. The function gets no - parameters and returns the bitmap in hexa and decimal format. - - - - <function moreinfo="none">get_gflags</function> usage - -... -$ opensips-cli -x mi get_gflags -0x3039 -12345 -... - - -
-
- -
- diff --git a/modules/group/README b/modules/group/README deleted file mode 100644 index aeeca3fd619..00000000000 --- a/modules/group/README +++ /dev/null @@ -1,438 +0,0 @@ -group Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Strict membership checking - 1.1.2. Regular Expression based checking - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. table (string) - 1.3.3. user_column (string) - 1.3.4. domain_column (string) - 1.3.5. group_column (string) - 1.3.6. use_domain (integer) - 1.3.7. re_table (string) - 1.3.8. re_exp_column (string) - 1.3.9. re_gid_column (string) - 1.3.10. multiple_gid (integer) - 1.3.11. aaa_url (string) - - 1.4. Exported Functions - - 1.4.1. db_is_user_in(uri, group) - 1.4.2. db_get_user_group(uri, output_avp) - 1.4.3. aaa_is_user_in(uri, group) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set table parameter - 1.3. Set user_column parameter - 1.4. Set domain_column parameter - 1.5. Set group_column parameter - 1.6. Set use_domain parameter - 1.7. Set re_table parameter - 1.8. Set re_exp_column parameter - 1.9. Set re_gid_column parameter - 1.10. Set multiple_gid parameter - 1.11. Set aaa_url parameter - 1.12. db_is_user_in usage - 1.13. db_get_user_group usage - 1.14. aaa_is_user_in usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides functionalities for different methods of - group membership checking. - -1.1.1. Strict membership checking - - There is a database table that contains list of users and - groups they belong to. The module provides the possibility to - check if a specific user belongs to a specific group. - - There is no DB caching support, each check involving a DB - query. - -1.1.2. Regular Expression based checking - - Another database table contains list of regular expressions and - group IDs. A matching occurs if the user URI match the regular - expression. This type of matching may be used to fetch the - group ID(s) the user belongs to (via RE matching) . - - Due performance reasons (regular expression evaluation), DB - cache support is available: the table content is loaded into - memory at startup and all regular expressions are compiled. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * A database module, like mysql, postgres or dbtext. - * An AAA module, like radius or diameter. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - URL of the database table to be used. - - Example 1.1. Set db_url parameter - -... -modparam("group", "db_url", "mysql://username:password@dbhost/opensips") -... - - -1.3.2. table (string) - - Name of the table holding strict definitions of groups and - their members. - - Default value is “grp”. - - Example 1.2. Set table parameter - -... -modparam("group", "table", "grp_table") -... - - -1.3.3. user_column (string) - - Name of the “table” column holding usernames. - - Default value is “username”. - - Example 1.3. Set user_column parameter - -... -modparam("group", "user_column", "user") -... - - -1.3.4. domain_column (string) - - Name of the “table” column holding domains. - - Default value is “domain”. - - Example 1.4. Set domain_column parameter - -... -modparam("group", "domain_column", "realm") -... - - -1.3.5. group_column (string) - - Name of the “table” column holding groups. - - Default value is “grp”. - - Example 1.5. Set group_column parameter - -... -modparam("group", "group_column", "grp") -... - - -1.3.6. use_domain (integer) - - If enabled (set to non zero value) then domain will be used - also used for strict group matching; otherwise only the - username part will be used. - - Default value is 0 (no). - - Example 1.6. Set use_domain parameter - -... -modparam("group", "use_domain", 1) -... - - -1.3.7. re_table (string) - - Name of the table holding definitions for regular-expression - based groups. If no table is defined, the regular-expression - support is disabled. - - Default value is “NULL”. - - Example 1.7. Set re_table parameter - -... -modparam("group", "re_table", "re_grp") -... - - -1.3.8. re_exp_column (string) - - Name of the “re_table” column holding the regular expression - used for user matching. - - Default value is “reg_exp”. - - Example 1.8. Set re_exp_column parameter - -... -modparam("group", "re_exp_column", "re") -... - - -1.3.9. re_gid_column (string) - - Name of the “re_table” column holding the group IDs. - - Default value is “group_id”. - - Example 1.9. Set re_gid_column parameter - -... -modparam("group", "re_gid_column", "grp_id") -... - - -1.3.10. multiple_gid (integer) - - If enabled (non zero value) the regular-expression matching - will return all group IDs that match the user; otherwise only - the first will be returned. - - Default value is “1”. - - Example 1.10. Set multiple_gid parameter - -... -modparam("group", "multiple_gid", 0) -... - - -1.3.11. aaa_url (string) - - This is the url representing the AAA protocol used and the - location of the configuration file of this protocol. - - Example 1.11. Set aaa_url parameter -... -modparam("group", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.c -onf") -... - - -1.4. Exported Functions - -1.4.1. db_is_user_in(uri, group) - - This function is to be used for script group membership. The - function returns true if username in the given URI is member of - the given group and false if not. - - Meaning of the parameters is as follows: - * uri (string) - a SIP URI whose username and optionally - domain to be used. Possible values: - + "Request-URI" - Use Request-URI username and - (optionally) domain. - + "To" - Use To username and (optionally) domain. - + "From" - Use From username and (optionally) domain. - + "Credentials" - Use digest credentials username. - + (default) - parse the given input as a SIP URI - * group (string) - the group to check - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.12. db_is_user_in usage - -... -if (db_is_user_in("Request-URI", "ld")) { - ... -} -... -$avp(grouptocheck)="offline"; - -if (db_is_user_in("Credentials", $avp(grouptocheck))) { - ... -} -... - - -1.4.2. db_get_user_group(uri, output_avp) - - This function is to be used for regular expression based group - membership, using DB support. The function returns true if the - username in the given "uri" belongs to at least one group. - - All matching group IDs shall be returned in "output_avp" if - multiple_gid is enabled, otherwise only the first one to match - (the records are attempted in reversed order of the results - returned by the RDBMS). - - Meaning of the parameters is as follows: - * uri (string) - a SIP URI to be matched against the regular - expressions: - + "Request-URI" - Use Request-URI - + "To" - Use To URI. - + "From" - Use From URI - + "Credentials" - Use digest credentials username and - realm. - + (default) - parse the given input as a SIP URI - * output_avp (var) - a list of matched group IDs - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.13. db_get_user_group usage - -... -if (db_get_user_group("Request-URI", $avp(10))) { - xdbg("User $ru belongs to the following groups: $(avp(10)[*])\n"); - .... -}; -... - - -1.4.3. aaa_is_user_in(uri, group) - - This function checks group membership, using AAA support. The - function returns true if username in the given "uri" is member - of the given group and false if not. - - Meaning of the parameters is as follows: - * uri (string) - a SIP URI whose username and optionally - domain to be used, this can be one of: - + "Request-URI" - Use Request-URI username and - (optionally) domain. - + "To" - Use To username and (optionally) domain. - + "From" - Use From username and (optionally) domain. - + "Credentials" - Use digest credentials username. - * group (string) - Name of the group to check. - - This function can be used from REQUEST_ROUTE. - - Example 1.14. aaa_is_user_in usage - -... -if (aaa_is_user_in("Request-URI", "ld")) { - ... -}; -... - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 46 31 848 397 - 2. Jan Janak (@janakj) 35 20 1370 148 - 3. Daniel-Constantin Mierla (@miconda) 24 18 176 226 - 4. Liviu Chircu (@liviuchircu) 16 12 87 154 - 5. Razvan Crainea (@razvancrainea) 9 7 16 39 - 6. Irina-Maria Stanescu 9 4 466 59 - 7. Andrei Pelinescu-Onciul 7 5 101 40 - 8. Henning Westerholt (@henningw) 7 5 27 46 - 9. Vlad Patrascu (@rvlad-patrascu) 5 2 78 106 - 10. Sergio Gutierrez 5 1 122 72 - - All remaining contributors: Edson Gellert Schubert, Jiri Kuthan - (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Peter - Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Dan Pascu - (@danpascu), Konstantin Bokarius, Alexandra Titoc, Norman - Brandinger (@NormB), UnixDev, Anca Vamanu. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Jun 2011 - Jun 2021 - 5. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - May 2020 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2005 - Mar 2020 - 8. Dan Pascu (@danpascu) Oct 2007 - Apr 2019 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 10. Irina-Maria Stanescu Aug 2009 - Dec 2009 - - All remaining contributors: Anca Vamanu, UnixDev, Sergio - Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Norman Brandinger (@NormB), Jan Janak (@janakj), Andrei - Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), Irina-Maria Stanescu, Sergio - Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Dan Pascu (@danpascu), Jan - Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL - - Copyright © 2003 FhG FOKUS diff --git a/modules/group/README.md b/modules/group/README.md new file mode 100644 index 00000000000..26c23622192 --- /dev/null +++ b/modules/group/README.md @@ -0,0 +1,373 @@ +--- +title: "group Module" +description: "This module provides functionalities for different methods of group membership checking." +--- + +## Admin Guide + + +### Overview + + +This module provides functionalities for different methods of group +membership checking. + + +#### Strict membership checking + + +There is a database table that contains list of users and groups +they belong to. The module provides the possibility to check if a +specific user belongs to a specific group. + + +There is no DB caching support, each check involving a DB query. + + +#### Regular Expression based checking + + +Another database table contains list of regular expressions and +group IDs. A matching occurs if the user URI match the regular +expression. This type of matching may be used to fetch the +group ID(s) the user belongs to (via RE matching) . + + +Due performance reasons (regular expression evaluation), DB cache +support is available: the table content is loaded into memory at +startup and all regular expressions are compiled. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- A database module, like mysql, postgres or dbtext. +- An AAA module, like radius or diameter. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +URL of the database table to be used. + + +```opensips title="Set db_url parameter" +... +modparam("group", "db_url", "mysql://username:password@dbhost/opensips") +... +``` + + +#### table (string) + + +Name of the table holding strict definitions of groups and +their members. + + +*Default value is "grp".* + + +```opensips title="Set table parameter" +... +modparam("group", "table", "grp_table") +... +``` + + +#### user_column (string) + + +Name of the "table" column holding usernames. + + +*Default value is "username".* + + +```opensips title="Set user_column parameter" +... +modparam("group", "user_column", "user") +... +``` + + +#### domain_column (string) + + +Name of the "table" column holding domains. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("group", "domain_column", "realm") +... +``` + + +#### group_column (string) + + +Name of the "table" column holding groups. + + +*Default value is "grp".* + + +```opensips title="Set group_column parameter" +... +modparam("group", "group_column", "grp") +... +``` + + +#### use_domain (integer) + + +If enabled (set to non zero value) then domain will be used also used +for strict group matching; otherwise only the username part will be +used. + + +*Default value is 0 (no).* + + +```opensips title="Set use_domain parameter" +... +modparam("group", "use_domain", 1) +... +``` + + +#### re_table (string) + + +Name of the table holding definitions for regular-expression +based groups. If no table is defined, the regular-expression +support is disabled. + + +*Default value is "NULL".* + + +```opensips title="Set re_table parameter" +... +modparam("group", "re_table", "re_grp") +... +``` + + +#### re_exp_column (string) + + +Name of the "re_table" column holding the regular +expression used for user matching. + + +*Default value is "reg_exp".* + + +```opensips title="Set re_exp_column parameter" +... +modparam("group", "re_exp_column", "re") +... +``` + + +#### re_gid_column (string) + + +Name of the "re_table" column holding the group IDs. + + +*Default value is "group_id".* + + +```opensips title="Set re_gid_column parameter" +... +modparam("group", "re_gid_column", "grp_id") +... +``` + + +#### multiple_gid (integer) + + +If enabled (non zero value) the regular-expression matching will +return all group IDs that match the user; otherwise only the first +will be returned. + + +*Default value is "1".* + + +```opensips title="Set multiple_gid parameter" +... +modparam("group", "multiple_gid", 0) +... +``` + + +#### aaa_url (string) + + +This is the url representing the AAA protocol used and the location of the configuration file of this protocol. + + +```opensips title="Set aaa_url parameter" +... +modparam("group", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") +... +``` + + +### Exported Functions + + +#### db_is_user_in(uri, group) + + +This function is to be used for script group membership. The function +returns true if username in the given URI is member of the given +group and false if not. + + +Meaning of the parameters is as follows: + + +- *uri (string)* - a SIP URI whose +username and optionally domain to be used. Possible values: + * "Request-URI" - Use Request-URI username and + (optionally) domain. + + + * "To" - Use To username and (optionally) domain. + + + * "From" - Use From username and (optionally) domain. + + + * "Credentials" - Use digest credentials username. + + + * (default) - parse the given input as a SIP URI +- *group (string)* - the group to check + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="db_is_user_in usage" +... +if (db_is_user_in("Request-URI", "ld")) { + ... +} +... +$avp(grouptocheck)="offline"; + +if (db_is_user_in("Credentials", $avp(grouptocheck))) { + ... +} +... +``` + + +#### db_get_user_group(uri, output_avp) + + +This function is to be used for regular expression based group +membership, using DB support. The function returns true if the username in +the given "uri" belongs to at least one group. + + +All matching group IDs +shall be returned in "output_avp" if [multiple gid](#param_multiple_gid) +is enabled, otherwise only the first one to match (the records are +attempted in reversed order of the results returned by the RDBMS). + + +Meaning of the parameters is as follows: + + +- *uri (string)* - a SIP URI to be matched +against the regular expressions: + * "Request-URI" - Use Request-URI + * "To" - Use To URI. + * "From" - Use From URI + * "Credentials" - Use digest credentials username + and realm. + * (default) - parse the given input as a SIP URI +- *output_avp (var)* - a list of matched +group IDs + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="db_get_user_group usage" +... +if (db_get_user_group("Request-URI", $avp(10))) { + xdbg("User $ru belongs to the following groups: $(avp(10)[*])\n"); + .... +}; +... +``` + + +#### aaa_is_user_in(uri, group) + + +This function checks group membership, using AAA support. +The function returns true if username in the given "uri" is member of +the given group and false if not. + + +Meaning of the parameters is as follows: + + +- *uri (string)* - a SIP URI whose +username and optionally domain to be used, this can be one of: + * "Request-URI" - Use Request-URI username and + (optionally) domain. + * "To" - Use To username and (optionally) domain. + * "From" - Use From username and (optionally) domain. + * "Credentials" - Use digest credentials username. +- *group (string)* - Name of the group to check. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="aaa_is_user_in usage" +... +if (aaa_is_user_in("Request-URI", "ld")) { + ... +}; +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/group/doc/contributors.xml b/modules/group/doc/contributors.xml deleted file mode 100644 index da828b56e7e..00000000000 --- a/modules/group/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 46 - 31 - 848 - 397 - - - 2. - Jan Janak (@janakj) - 35 - 20 - 1370 - 148 - - - 3. - Daniel-Constantin Mierla (@miconda) - 24 - 18 - 176 - 226 - - - 4. - Liviu Chircu (@liviuchircu) - 16 - 12 - 87 - 154 - - - 5. - Razvan Crainea (@razvancrainea) - 9 - 7 - 16 - 39 - - - 6. - Irina-Maria Stanescu - 9 - 4 - 466 - 59 - - - 7. - Andrei Pelinescu-Onciul - 7 - 5 - 101 - 40 - - - 8. - Henning Westerholt (@henningw) - 7 - 5 - 27 - 46 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 5 - 2 - 78 - 106 - - - 10. - Sergio Gutierrez - 5 - 1 - 122 - 72 - - - -
-All remaining contributors: Edson Gellert Schubert, Jiri Kuthan (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Dan Pascu (@danpascu), Konstantin Bokarius, Alexandra Titoc, Norman Brandinger (@NormB), UnixDev, Anca Vamanu. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jun 2021 - - - 5. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - May 2020 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2005 - Mar 2020 - - - 8. - Dan Pascu (@danpascu) - Oct 2007 - Apr 2019 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 10. - Irina-Maria Stanescu - Aug 2009 - Dec 2009 - - - -
-All remaining contributors: Anca Vamanu, UnixDev, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Norman Brandinger (@NormB), Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Irina-Maria Stanescu, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dan Pascu (@danpascu), Jan Janak (@janakj). -
- -
diff --git a/modules/group/doc/group.xml b/modules/group/doc/group.xml deleted file mode 100644 index 404b03166c1..00000000000 --- a/modules/group/doc/group.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - group Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - ©right; 2003 &fhg; - - diff --git a/modules/group/doc/group_admin.xml b/modules/group/doc/group_admin.xml deleted file mode 100644 index 10c9281dc41..00000000000 --- a/modules/group/doc/group_admin.xml +++ /dev/null @@ -1,501 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides functionalities for different methods of group - membership checking. - -
- Strict membership checking - - There is a database table that contains list of users and groups - they belong to. The module provides the possibility to check if a - specific user belongs to a specific group. - - - There is no DB caching support, each check involving a DB query. - -
-
- Regular Expression based checking - - Another database table contains list of regular expressions and - group IDs. A matching occurs if the user URI match the regular - expression. This type of matching may be used to fetch the - group ID(s) the user belongs to (via RE matching) . - - - Due performance reasons (regular expression evaluation), DB cache - support is available: the table content is loaded into memory at - startup and all regular expressions are compiled. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - A database module, like mysql, postgres or dbtext. - - - - - An AAA module, like radius or diameter. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - &url; of the database table to be used. - - - - Set <varname>db_url</varname> parameter - - -... -modparam("group", "db_url", "mysql://username:password@dbhost/opensips") -... - - - -
- -
- <varname>table</varname> (string) - - Name of the table holding strict definitions of groups and - their members. - - - - Default value is grp. - - - - Set <varname>table</varname> parameter - - -... -modparam("group", "table", "grp_table") -... - - - -
- -
- <varname>user_column</varname> (string) - - Name of the table column holding usernames. - - - - Default value is username. - - - - Set <varname>user_column</varname> parameter - - -... -modparam("group", "user_column", "user") -... - - - -
- -
- <varname>domain_column</varname> (string) - - Name of the table column holding domains. - - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - - -... -modparam("group", "domain_column", "realm") -... - - - -
- -
- <varname>group_column</varname> (string) - - Name of the table column holding groups. - - - - Default value is grp. - - - - Set <varname>group_column</varname> parameter - - -... -modparam("group", "group_column", "grp") -... - - - -
- -
- <varname>use_domain</varname> (integer) - - If enabled (set to non zero value) then domain will be used also used - for strict group matching; otherwise only the username part will be - used. - - - - Default value is 0 (no). - - - - Set <varname>use_domain</varname> parameter - - -... -modparam("group", "use_domain", 1) -... - - - -
- -
- <varname>re_table</varname> (string) - - Name of the table holding definitions for regular-expression - based groups. If no table is defined, the regular-expression - support is disabled. - - - - Default value is NULL. - - - - Set <varname>re_table</varname> parameter - - -... -modparam("group", "re_table", "re_grp") -... - - - -
- -
- <varname>re_exp_column</varname> (string) - - Name of the re_table column holding the regular - expression used for user matching. - - - - Default value is reg_exp. - - - - Set <varname>re_exp_column</varname> parameter - - -... -modparam("group", "re_exp_column", "re") -... - - - -
- -
- <varname>re_gid_column</varname> (string) - - Name of the re_table column holding the group IDs. - - - - Default value is group_id. - - - - Set <varname>re_gid_column</varname> parameter - - -... -modparam("group", "re_gid_column", "grp_id") -... - - - -
- -
- <varname>multiple_gid</varname> (integer) - - If enabled (non zero value) the regular-expression matching will - return all group IDs that match the user; otherwise only the first - will be returned. - - - - Default value is 1. - - - - Set <varname>multiple_gid</varname> parameter - - -... -modparam("group", "multiple_gid", 0) -... - - - -
-
- <varname>aaa_url</varname> (string) - - This is the url representing the AAA protocol used and the location of the configuration file of this protocol. - - - Set <varname>aaa_url</varname> parameter - -... -modparam("group", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") -... - - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">db_is_user_in(uri, group)</function> - - - This function is to be used for script group membership. The function - returns true if username in the given &uri; is member of the given - group and false if not. - - Meaning of the parameters is as follows: - - - uri (string) - a SIP &uri; whose - username and optionally domain to be used. Possible values: - - - "Request-URI" - Use Request-URI username and - (optionally) domain. - - - "To" - Use To username and (optionally) domain. - - - "From" - Use From username and (optionally) domain. - - - "Credentials" - Use digest credentials username. - - - (default) - parse the given input as a SIP URI - - - - - - group (string) - the group to check - - - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>db_is_user_in</function> usage - - -... -if (db_is_user_in("Request-URI", "ld")) { - ... -} -... -$avp(grouptocheck)="offline"; - -if (db_is_user_in("Credentials", $avp(grouptocheck))) { - ... -} -... - - - -
- - -
- - <function moreinfo="none">db_get_user_group(uri, output_avp)</function> - - - This function is to be used for regular expression based group - membership, using DB support. The function returns true if the username in - the given "uri" belongs to at least one group. - All matching group IDs - shall be returned in "output_avp" if - is enabled, otherwise only the first one to match (the records are - attempted in reversed order of the results returned by the RDBMS). - - Meaning of the parameters is as follows: - - - uri (string) - a SIP &uri; to be matched - against the regular expressions: - - - "Request-URI" - Use Request-URI - - - "To" - Use To URI. - - - "From" - Use From URI - - - "Credentials" - Use digest credentials username - and realm. - - - (default) - parse the given input as a SIP URI - - - - - - output_avp (var) - a list of matched - group IDs - - - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>db_get_user_group</function> usage - - -... -if (db_get_user_group("Request-URI", $avp(10))) { - xdbg("User $ru belongs to the following groups: $(avp(10)[*])\n"); - .... -}; -... - - - -
-
- - <function moreinfo="none">aaa_is_user_in(uri, group)</function> - - - This function checks group membership, using AAA support. - The function returns true if username in the given "uri" is member of - the given group and false if not. - - Meaning of the parameters is as follows: - - - uri (string) - a SIP &uri; whose - username and optionally domain to be used, this can be one of: - - - "Request-URI" - Use Request-URI username and - (optionally) domain. - - - "To" - Use To username and (optionally) domain. - - - "From" - Use From username and (optionally) domain. - - - "Credentials" - Use digest credentials username. - - - - - - group (string) - Name of the group to check. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>aaa_is_user_in</function> usage - - -... -if (aaa_is_user_in("Request-URI", "ld")) { - ... -}; -... - - - -
-
- - -
- diff --git a/modules/h350/README b/modules/h350/README deleted file mode 100644 index 30a5c59a74c..00000000000 --- a/modules/h350/README +++ /dev/null @@ -1,709 +0,0 @@ -H350 Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Example H.350 commObject LDAP Entry - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. ldap_session (string) - 1.3.2. base_dn (string) - 1.3.3. search_scope (string) - - 1.4. Exported Functions - - 1.4.1. h350_sipuri_lookup(sip_uri) - 1.4.2. h350_auth_lookup(auth_username, - "username_avp_spec/pwd_avp_spec") - - 1.4.3. h350_result_call_preferences(avp_name_prefix) - 1.4.4. h350_result_service_level(avp_name_prefix) - - Resources - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Example H.350 commObject storing SIP account data - 1.2. ldap_session parameter usage - 1.3. base_dn parameter usage - 1.4. search_scope parameter usage - 1.5. Example Usage - 1.6. Example Usage - 1.7. Example H.350 callPreferenceURI simple call forwarding - rules - - 1.8. Example Usage - 1.9. Example SIPIdentityServiceLevel values and resulting AVPs - 1.10. Example Usage - -Chapter 1. Admin Guide - -1.1. Overview - - The OpenSIPS H350 module enables an OpenSIPS SIP proxy server - to access SIP account data stored in an LDAP [RFC4510] - directory containing H.350 [H.350] commObjects. ITU-T - Recommendation H.350 standardizes LDAP object classes to store - Real-Time Communication (RTC) account data. In particular, - H.350.4 [H.350.4] defines an object class called sipIdentity - that includes attribute specifications for SIP account data - like SIP URI, SIP digest username/password, or service level. - This allows to store SIP account data in a vendor neutral way - and lets different entities, like SIP proxies, provisioning, or - billing applications, access the data in a standardized format. - - The ViDe H.350 Cookbook [vide-h.350-cb] is a good reference for - deploying an H.350 directory. Besides general information on - H.350, LDAP, and related standards, this document explains how - to set up an H.350/LDAP directory and discusses different - deployment scenarios. - - The H350 module uses the OpenSIPS LDAP module to import H.350 - attribute values into the OpenSIPS routing script variable - space. The module exports functions to parse and store the - H.350 attribute values from the OpenSIPS routing script. It - allows a script writer to implement H.350 based SIP digest - authentication, call forwarding, SIP URI alias to AOR - rewriting, and service level parsing. - -1.1.1. Example H.350 commObject LDAP Entry - - The following example shows a typical H.350 commObject LDAP - entry storing SIP account data. - - Example 1.1. Example H.350 commObject storing SIP account data -Attribute Name Attribute Value(s) --------------- ----------------- - -# LDAP URI identifying the owner of this commObject, typically -# points to an entry in the enterprise directory -commOwner ldap://dir.example.com/dc=example,dc=com??one?(uid=bob) - -# Unique identifier for this commObject, used for referencing -# this object e.g. from the enterprise directory -commUniqueId 298217asdjgj213 - -# Determines if this commObject should be listed on white pages -commPrivate false - -# Valid SIP URIs for this account (can be used to store alias SIP URIs -# like DIDs as well) -SIPIdentitySIPURI sip:bob@example.com - sip:bob@alias.example.com - sip:+1919123456@alias.example.com -# SIP digest username -SIPIdentityUserName bob - -# SIP digest password -SIPIdentityPassword pwd - -# SIP proxy address -SIPIdentityProxyAddress sip.example.com - -# SIP registrar address -SIPIdentityRegistrarAddress sip.example.com - -# Call preferences: Forward to voicemail on no response -# after 20 seconds and on busy -callPreferenceURI sip:bob@voicemail.example.com n:20000 - sip:bob@voicemail.example.com b - -# Account service level(s) -SIPIdentityServiceLevel long_distance - conferencing - -# H.350 object classes -objectClass top - commObject - SIPIdentity - callPreferenceURIObject - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (the listed modules - must be loaded before this module): - * LDAP - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * OpenLDAP library (libldap), libldap header files - (libldap-dev) are needed for compilation - -1.3. Exported Parameters - -1.3.1. ldap_session (string) - - Name of the LDAP session to be used for H.350 queries, as - defined in the LDAP module configuration file. - - Default value: "" - - Example 1.2. ldap_session parameter usage -modparam("h350", "ldap_session", "h350"); - -1.3.2. base_dn (string) - - Base LDAP DN to start LDAP search for H.350 entries. For best - performance, this should be set to the direct ancestor of the - H.350 objects. - - Default value: "" - - Example 1.3. base_dn parameter usage -modparam("h350", "base_dn", "ou=h350,dc=example,dc=com"); - -1.3.3. search_scope (string) - - LDAP search scope for H.350 queries, one of "one", "base", or - "sub". - - Default value: "one" - - Example 1.4. search_scope parameter usage -modparam("h350", "search_scope", "sub"); - -1.4. Exported Functions - -1.4.1. h350_sipuri_lookup(sip_uri) - - This function performs an LDAP search query for an H.350 - commObject with a SIPIdentitySIPURI of sip_uri. The sip_uri - parameter first gets escaped according the rules for LDAP - filter strings. The result of the LDAP search is stored - internally and can be accessed either by one of the - h350_result* or one of the ldap_result* functions from the - OpenSIPS LDAP module. - - The function returns -1 (FALSE) for internal errors, and -2 - (FALSE) if no H.350 commObject was found with a matching - sip_uri. n > 0 (TRUE) is returned if n H.350 commObjects were - found. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Function Parameters: - - sip_uri (string) - H.350 SIPIdentitySIPURI to search for in directory. - - Return Values: - - n > 0 (TRUE): - - + n H.350 commObjects found. - - -1 (FALSE): - - + Internal error occurred. - - -2 (FALSE): - - + No H.350 commObject found. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.5. Example Usage -# -# H.350 lookup for callee -# - -if (!h350_sipuri_lookup("sip:$rU@$rd")) -{ - switch ($retcode) - { - case -2: - xlog("L_INFO", - "h350 callee lookup: no entry found in H.350 directory"); - exit; - case -1: - sl_send_reply(500, "Internal server error"); - exit; - } -} - -# now h350_result* or ldap_result* functions can be used - -1.4.2. h350_auth_lookup(auth_username, -"username_avp_spec/pwd_avp_spec") - - This function performs an LDAP search query for SIP digest - authentication credentials in an H.350 directory. The H.350 - directory is searched for a commObject with SIPIdentityUserName - of auth_username. If such a commObject is found, the SIP digest - authentication username and password are stored in AVPs - username_avp_spec and pwd_avp_spec, respectively. - pv_*_authorize functions from AUTH module can then be used to - perform SIP digest authentication. - - The function returns 1 (TRUE) if an H.350 commObject was found, - -1 (FALSE) in case of an internal error, and -2 (FALSE) if no - matching commObject was found. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Function Parameters: - - auth_username (string) - H.350 SIPIdentityUserName to search for in directory. - - username_avp_spec (var) - Specification for authentication username AVP, e.g. - $avp(username). - - pwd_avp_spec (var) - Specification for authentication password AVP, e.g. - $avp(pwd). - - Return Values: - - 1 (TRUE): - - + H.350 commObject found and SIP digest authentication - credentials stored in username_avp_spec and - pwd_avp_spec. - - -1 (FALSE): - - + Internal error occurred. - - -2 (FALSE): - - + No H.350 commObject found. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.6. Example Usage -# -- auth params -- -modparam("auth", "username_spec", "$avp(auth_user)") -modparam("auth", "password_spec", "$avp(auth_pwd)") -modparam("auth", "calculate_ha1", 1) - -# -- h350 params -- -modparam("h350", "ldap_session", "h350") -modparam("h350", "base_dn", "ou=h350,dc=example,dc=com") -modparam("h350", "search_scope", "one") - - -route[1] -{ - # - # H.350 based SIP digest authentication - # - - # challenge all requests not including an Auth header - if (!(is_present_hf("Authorization") || - is_present_hf("Proxy-Authorization"))) - { - if (is_method("REGISTER")) - { - www_challenge("example.com", 0); - exit; - } - proxy_challenge("example.com", 0); - exit; - } - - # get digest password from H.350 using auth username ($au) - if (!h350_auth_lookup($au, - "$avp(auth_user)/$avp(auth_pwd)")) - { - switch ($retcode) - { - case -2: - sl_send_reply(401, "Unauthorized"); - exit; - case -1: - sl_send_reply(500, "Internal server error"); - exit; - } - } - - # REGISTER requests - if (is_method("REGISTER")) - { - if (!pv_www_authorize("example.com")) - { - if ($retcode == -5) - { - sl_send_reply(500, "Internal server error"); - exit; - } - else { - www_challenge("example.com", 0); - exit; - } - } - - consume_credentials(); - xlog("L_INFO", - "REGISTER request successfully authenticated"); - return(1); - } - - # non-REGISTER requests - if (!pv_proxy_authorize("example.com")) - { - if ($retcode == -5) - { - sl_send_reply(500, "Internal server error"); - exit; - } - else { - proxy_challenge("example.com", 0); - exit; - } - } - - consume_credentials(); - xlog("L_INFO", "$rm request successfully authenticated"); - return(1); -} - -1.4.3. h350_result_call_preferences(avp_name_prefix) - - This function parses the callPreferenceURI attribute of an - H.350 commObject, which must have been fetched through - h350_*_lookup or ldap_search. callPreferenceURI is a - multi-valued attribute that stores call preference rules like - e.g. forward-on-busy or forward-unconditionally. Directory - services architecture for call forwarding and preferences - [H.350.6] defines a format for simple call forwarding rules: - - target_uri type[:argument] - - In a SIP environment, target_uri is typically the call - forwarding rule's target SIP URI, although it could be any type - of URI, e.g. an HTTP pointer to a CPL script. Four different - values are specified for type: b for "forward on busy", n for - "forward on no answer", u for "forward unconditionally", and f - for "forward on destination not found". The optional argument - is a string indicating the time in milliseconds after which the - call forwarding should occur. - - Example 1.7. Example H.350 callPreferenceURI simple call - forwarding rules - -# Example 1: -# forward to sip:voicemail@example.com on no answer after 15 seconds: - -callPreferenceURI: sip:voicemail@example.com n:15000 - -# Example 2: -# unconditionally forward to sip:alice@example.com: - -callPreferenceURI: sip:alice@example.com u - -# Example 3: -# forward to sip:bob@example.com and sip:alice@example.com -# (forking) on destination not found: - -callPreferenceURI: sip:bob@example.com f -callPreferenceURI: sip:alice@example.com f - - h350_result_call_preferences stores these call forwarding rules - as AVPs according to the following rules: - -# -# AVP storing a forwarding rule's target URI -# - -AVP name = avp_name_prefix + '_' + type -AVP value = target_uri - -# -# AVP storing a forwarding rule's argument -# - -AVP name = avp_name_prefix + '_' + type + '_t' -AVP value = argument / 1000 - - Example 1 from above would result in two AVPs: $avp("prefix_n") - = "sip:voicemail@example.com" and $avp("prefix_n_t") = 15. - - Example 2: $avp("prefix_u") = "sip:alice@example.com". - - Example 3: $avp("prefix_f[1]") = "sip:bob@example.com" and - $avp("prefix_f[2]]") = "sip:alice@example.com". - - These AVPs can then be used to implement the desired behavior - in the OpenSIPS routing script. - - This function returns the number of successfully parsed simple - call forwarding rules (TRUE), in case the H.350 - callPreferenceURI attribute contained one or multiple values - matching the simple call forwarding rule syntax described - above. It returns -1 (FALSE) for internal errors, and -2 - (FALSE) if none of the rules matched or if no callPreferenceURI - attribute was found. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Function Parameters: - - avp_name_prefix (string) - Name prefix for call forwarding rule AVPs, as described - above. - - Return Values: - - n > 0 (TRUE): - - + n simple call forwarding rules found. - - -1 (FALSE): - - + Internal error occurred. - - -2 (FALSE): - - + No simple call forwarding rule found, or - callPreferenceURI not present. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.8. Example Usage -# -# H.350 lookup for callee -# - -... h350_sipuri_lookup("sip:$rU@$rd") ... - -# -# store H.350 call preferences in AVP -# - -if (!h350_result_call_preferences("callee_pref_") && ($retcode == -1)) -{ - sl_send_reply(500, "Internal server error"); - exit; -} - -# $avp(callee_pref_u) == CFU URI(s) -# $avp(callee_pref_n) == CFNR URI(s) -# $avp(callee_pref_n_t) == CFNR timeout in seconds -# $avp(callee_pref_b) == CFB URI(s) -# $avp(callee_pref_f) == CFOFFLINE URI(s) - -# -# Example for forward-unconditionally (CFU) -# - -if ($avp(callee_pref_u) != NULL) -{ - # push CFU URI into R-URI and additional branches - # --> request can fork - $ru = $avp(callee_pref_u); - $avp(callee_pref_u) = NULL; - while ($avp(callee_pref_u)!=NULL) { - $branch = $avp(callee_pref_u); - $avp(callee_pref_u) = NULL; - } - sl_send_reply(181, "Call is being forwarded"); - t_relay(); - exit; -} - -1.4.4. h350_result_service_level(avp_name_prefix) - - Directory services architecture for SIP [H.350.4] defines a - multi-valued LDAP attribute named SIPIdentityServiceLevel, - which can be used to store SIP account service level values in - an LDAP directory. This function parses the - SIPIdentityServiceLevel attribute and stores all service level - values as AVPs for later retrieval in the OpenSIPS routing - script. The function accesses the H.350 commObject fetched by a - call to h350_*_lookup or ldap_search. - - The resulting AVPs have a name of the form avp_name_prefix + - SIPIdentityServiceLevel attribute value, and an integer value - of 1. - - Example 1.9. Example SIPIdentityServiceLevel values and - resulting AVPs -SIPIdentityServiceLevel: longdistance -SIPIdentityServiceLevel: international -SIPIdentityServiceLevel: 900 - -after calling h350_result_service_level("sl_"), the following AVPs -will be available in the routing script: - -$avp("sl_longdistance") = 1 -$avp("sl_international") = 1 -$avp("sl_900") = 1 - - This function returns the number of added AVPs (TRUE), -1 - (FALSE)for internal errors, and -2 (FALSE)if no - SIPIdentityServiceLevel attribute was found. - - The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Function Parameters: - - avp_name_prefix (string) - Name prefix for service level AVPs, as described above. - - Return Values: - - n > 0 (TRUE): - - + n AVPs added. - - -1 (FALSE): - - + Internal error occurred. - - -2 (FALSE): - - + No SIPIdentityServiceLevel attribute found. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.10. Example Usage -# -# H.350 SIP digest authentication for caller -# - -... h350_auth_lookup("$au", ...) ... - -# -# store caller's service level as AVP -# - -if (!h350_result_service_level("caller_sl_") && ($retcode == -1)) -{ - sl_send_reply(500, "Internal server error"); - exit; -} - -# -# make routing decision based on service level AVPs -# - -if ($avp(caller_sl_international) != NULL) -{ - t_relay(); -} -else { - sl_send_reply(403, "Forbidden"); -} -exit; - -Resources - - [H.350] Directory Services Architecture for Multimedia - Conferencing. August 2003. ITU-T. - - [H.350.4] Directory services architecture for SIP. August 2003. - ITU-T. - - [H.350.6] Directory services architecture for call forwarding - and preferences. March 2004. ITU-T. - - [ViDe-H.350-Cookbook] ViDe H.350 Cookbook. 2005. ViDe. - - [RFC4510] Lightweight Directory Access Protocol (LDAP): - Technical Specification Road Map. June 2006. Internet - Engineering Task Force. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Christian Schlatter 21 3 1993 1 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 16 14 58 58 - 3. Daniel-Constantin Mierla (@miconda) 12 9 79 83 - 4. Liviu Chircu (@liviuchircu) 11 9 25 39 - 5. Razvan Crainea (@razvancrainea) 10 7 53 61 - 6. Vlad Patrascu (@rvlad-patrascu) 9 3 80 247 - 7. Maksym Sobolyev (@sobomax) 4 2 3 4 - 8. Konstantin Bokarius 3 1 1 4 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - 10. Edson Gellert Schubert 3 1 0 85 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2008 - Feb 2024 - 3. Razvan Crainea (@razvancrainea) Jun 2011 - Feb 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Daniel-Constantin Mierla (@miconda) Sep 2007 - Mar 2008 - 8. Konstantin Bokarius Mar 2008 - Mar 2008 - 9. Edson Gellert Schubert Feb 2008 - Feb 2008 - 10. Christian Schlatter Aug 2007 - Dec 2007 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), - Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Christian Schlatter. - - Documentation Copyrights: - - Copyright © 2007 University of North Carolina diff --git a/modules/h350/README.md b/modules/h350/README.md new file mode 100644 index 00000000000..e15e3ae5e8e --- /dev/null +++ b/modules/h350/README.md @@ -0,0 +1,592 @@ +--- +title: "H350 Module" +description: "The OpenSIPS H350 module enables an OpenSIPS SIP proxy server to access SIP account data stored in an LDAP [RFC4510](#RFC4510) directory containing H.350 [H350](#H350) *commObjects*." +--- + +## Admin Guide + + +### Overview + + +The OpenSIPS H350 module enables an OpenSIPS SIP proxy server to access SIP account data stored in an LDAP [RFC4510](#RFC4510) directory containing H.350 [H350](#H350) *commObjects*. ITU-T Recommendation H.350 standardizes LDAP object classes to store Real-Time Communication (RTC) account data. In particular, *H.350.4* [H350 4](#H350-4) defines an object class called *sipIdentity* that includes attribute specifications for SIP account data like SIP URI, SIP digest username/password, or service level. This allows to store SIP account data in a vendor neutral way and lets different entities, like SIP proxies, provisioning, or billing applications, access the data in a standardized format. + + +The *ViDe H.350 Cookbook* [vide H350 cookbook](#vide-H350-cookbook) is a good reference for deploying an H.350 directory. Besides general information on H.350, LDAP, and related standards, this document explains how to set up an H.350/LDAP directory and discusses different deployment scenarios. + + +The H350 module uses the OpenSIPS LDAP module to import H.350 attribute values into the OpenSIPS routing script variable space. The module exports functions to parse and store the H.350 attribute values from the OpenSIPS routing script. It allows a script writer to implement H.350 based SIP digest authentication, call forwarding, SIP URI alias to AOR rewriting, and service level parsing. + + +#### Example H.350 commObject LDAP Entry + + +The following example shows a typical H.350 commObject LDAP entry storing SIP account data. + + +```c title="Example H.350 commObject storing SIP account data" +Attribute Name Attribute Value(s) +-------------- ----------------- + +# LDAP URI identifying the owner of this commObject, typically +# points to an entry in the enterprise directory +commOwner ldap://dir.example.com/dc=example,dc=com??one?(uid=bob) + +# Unique identifier for this commObject, used for referencing +# this object e.g. from the enterprise directory +commUniqueId 298217asdjgj213 + +# Determines if this commObject should be listed on white pages +commPrivate false + +# Valid SIP URIs for this account (can be used to store alias SIP URIs +# like DIDs as well) +SIPIdentitySIPURI sip:bob@example.com + sip:bob@alias.example.com + sip:+1919123456@alias.example.com +# SIP digest username +SIPIdentityUserName bob + +# SIP digest password +SIPIdentityPassword pwd + +# SIP proxy address +SIPIdentityProxyAddress sip.example.com + +# SIP registrar address +SIPIdentityRegistrarAddress sip.example.com + +# Call preferences: Forward to voicemail on no response +# after 20 seconds and on busy +callPreferenceURI sip:bob@voicemail.example.com n:20000 + sip:bob@voicemail.example.com b + +# Account service level(s) +SIPIdentityServiceLevel long_distance + conferencing + +# H.350 object classes +objectClass top + commObject + SIPIdentity + callPreferenceURIObject + +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (the listed modules +must be loaded before this module): + + +- LDAP + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- OpenLDAP library (libldap), libldap header files +(libldap-dev) are needed for compilation + + +### Exported Parameters + + +#### ldap_session (string) + + +Name of the LDAP session to be used for H.350 queries, as defined in the LDAP module configuration file. + + +Default value: "" + + +```opensips title="ldap_session parameter usage" +modparam("h350", "ldap_session", "h350"); + +``` + + +#### base_dn (string) + + +Base LDAP DN to start LDAP search for H.350 entries. For best performance, this should be set to the direct ancestor of the H.350 objects. + + +Default value: "" + + +```opensips title="base_dn parameter usage" +modparam("h350", "base_dn", "ou=h350,dc=example,dc=com"); + +``` + + +#### search_scope (string) + + +LDAP search scope for H.350 queries, one of "one", "base", or "sub". + + +Default value: "one" + + +```opensips title="search_scope parameter usage" +modparam("h350", "search_scope", "sub"); + +``` + + +### Exported Functions + + +#### h350_sipuri_lookup(sip_uri) + + +This function performs an LDAP search query for an H.350 commObject with a SIPIdentitySIPURI of `sip_uri`. The `sip_uri` parameter first gets escaped according the rules for LDAP filter strings. The result of the LDAP search is stored internally and can be accessed either by one of the *h350_result** or one of the *ldap_result** functions from the OpenSIPS LDAP module. + + +The function returns `-1` (FALSE) for internal errors, and `-2` (FALSE) if no H.350 commObject was found with a matching `sip_uri`. `n` > 0 (TRUE) is returned if `n` H.350 commObjects were found. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. + + +**sip_uri (string)** + + +H.350 SIPIdentitySIPURI to search for in directory. + + +**`n` > 0 (TRUE):** + + +- `n` H.350 commObjects found. + + +**`-1` (FALSE):** + + +- Internal error occurred. + + +**`-2` (FALSE):** + + +- No H.350 commObject found. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +# +# H.350 lookup for callee +# + +if (!h350_sipuri_lookup("sip:$rU@$rd")) +{ + switch ($retcode) + { + case -2: + xlog("L_INFO", + "h350 callee lookup: no entry found in H.350 directory"); + exit; + case -1: + sl_send_reply(500, "Internal server error"); + exit; + } +} + +# now h350_result* or ldap_result* functions can be used + +``` + + +#### h350_auth_lookup(auth_username, "username_avp_spec/pwd_avp_spec") + + +This function performs an LDAP search query for SIP digest authentication credentials in an H.350 directory. The H.350 directory is searched for a commObject with SIPIdentityUserName of `auth_username`. If such a commObject is found, the SIP digest authentication username and password are stored in AVPs `username_avp_spec` and `pwd_avp_spec`, respectively. *pv_*_authorize* functions from AUTH module can then be used to perform SIP digest authentication. + + +The function returns `1` (TRUE) if an H.350 commObject was found, `-1` (FALSE) in case of an internal error, and `-2` (FALSE) if no matching commObject was found. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. + + +**auth_username (string)** + + +H.350 SIPIdentityUserName to search for in directory. + + +**username_avp_spec (var)** + + +Specification for authentication username AVP, e.g. `$avp(username)`. + + +**pwd_avp_spec (var)** + + +Specification for authentication password AVP, e.g. `$avp(pwd)`. + + +**`1` (TRUE):** + + +- H.350 commObject found and SIP digest authentication credentials stored in `username_avp_spec` and `pwd_avp_spec`. + + +**`-1` (FALSE):** + + +- Internal error occurred. + + +**`-2` (FALSE):** + + +- No H.350 commObject found. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +# -- auth params -- +modparam("auth", "username_spec", "$avp(auth_user)") +modparam("auth", "password_spec", "$avp(auth_pwd)") +modparam("auth", "calculate_ha1", 1) + +# -- h350 params -- +modparam("h350", "ldap_session", "h350") +modparam("h350", "base_dn", "ou=h350,dc=example,dc=com") +modparam("h350", "search_scope", "one") + + +route[1] +{ + # + # H.350 based SIP digest authentication + # + + # challenge all requests not including an Auth header + if (!(is_present_hf("Authorization") || + is_present_hf("Proxy-Authorization"))) + { + if (is_method("REGISTER")) + { + www_challenge("example.com", 0); + exit; + } + proxy_challenge("example.com", 0); + exit; + } + + # get digest password from H.350 using auth username ($au) + if (!h350_auth_lookup($au, + "$avp(auth_user)/$avp(auth_pwd)")) + { + switch ($retcode) + { + case -2: + sl_send_reply(401, "Unauthorized"); + exit; + case -1: + sl_send_reply(500, "Internal server error"); + exit; + } + } + + # REGISTER requests + if (is_method("REGISTER")) + { + if (!pv_www_authorize("example.com")) + { + if ($retcode == -5) + { + sl_send_reply(500, "Internal server error"); + exit; + } + else { + www_challenge("example.com", 0); + exit; + } + } + + consume_credentials(); + xlog("L_INFO", + "REGISTER request successfully authenticated"); + return(1); + } + + # non-REGISTER requests + if (!pv_proxy_authorize("example.com")) + { + if ($retcode == -5) + { + sl_send_reply(500, "Internal server error"); + exit; + } + else { + proxy_challenge("example.com", 0); + exit; + } + } + + consume_credentials(); + xlog("L_INFO", "$rm request successfully authenticated"); + return(1); +} + +``` + + +#### h350_result_call_preferences(avp_name_prefix) + + +This function parses the callPreferenceURI attribute of an H.350 commObject, which must have been fetched through *h350_*_lookup* or *ldap_search*. callPreferenceURI is a multi-valued attribute that stores call preference rules like e.g. forward-on-busy or forward-unconditionally. *Directory services architecture for call forwarding and preferences* [H350 6](#H350-6) defines a format for simple call forwarding rules: + + +`target_uri type[:argument]` + + +In a SIP environment, `target_uri` is typically the call forwarding rule's target SIP URI, although it could be any type of URI, e.g. an HTTP pointer to a CPL script. Four different values are specified for `type`: `b` for "forward on busy", `n` for "forward on no answer", `u` for "forward unconditionally", and `f` for "forward on destination not found". The optional `argument` is a string indicating the time in milliseconds after which the call forwarding should occur. + + +```c title="Example H.350 callPreferenceURI simple call forwarding rules" +# Example 1: +# forward to sip:voicemail@example.com on no answer after 15 seconds: + +callPreferenceURI: sip:voicemail@example.com n:15000 + +# Example 2: +# unconditionally forward to sip:alice@example.com: + +callPreferenceURI: sip:alice@example.com u + +# Example 3: +# forward to sip:bob@example.com and sip:alice@example.com +# (forking) on destination not found: + +callPreferenceURI: sip:bob@example.com f +callPreferenceURI: sip:alice@example.com f + +``` + + +*h350_result_call_preferences* stores these call forwarding rules as AVPs according to the following rules: + + +```c +# +# AVP storing a forwarding rule's target URI +# + +AVP name = avp_name_prefix + '_' + type +AVP value = target_uri + +# +# AVP storing a forwarding rule's argument +# + +AVP name = avp_name_prefix + '_' + type + '_t' +AVP value = argument / 1000 + +``` + + +Example 1 from above would result in two AVPs: `$avp("prefix_n") = "sip:voicemail@example.com"` and `$avp("prefix_n_t") = 15`. + + +Example 2: `$avp("prefix_u") = "sip:alice@example.com"`. + + +Example 3: `$avp("prefix_f[1]") = "sip:bob@example.com"` and `$avp("prefix_f[2]]") = "sip:alice@example.com"`. + + +These AVPs can then be used to implement the desired behavior in the OpenSIPS routing script. + + +This function returns the number of successfully parsed simple call forwarding rules (TRUE), in case the H.350 callPreferenceURI attribute contained one or multiple values matching the simple call forwarding rule syntax described above. It returns `-1` (FALSE) for internal errors, and `-2` (FALSE) if none of the rules matched or if no callPreferenceURI attribute was found. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. + + +**avp_name_prefix (string)** + + +Name prefix for call forwarding rule AVPs, as described above. + + +**`n` > 0 (TRUE):** + + +- `n` simple call forwarding rules found. + + +**`-1` (FALSE):** + + +- Internal error occurred. + + +**`-2` (FALSE):** + + +- No simple call forwarding rule found, or callPreferenceURI not present. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +# +# H.350 lookup for callee +# + +... h350_sipuri_lookup("sip:$rU@$rd") ... + +# +# store H.350 call preferences in AVP +# + +if (!h350_result_call_preferences("callee_pref_") && ($retcode == -1)) +{ + sl_send_reply(500, "Internal server error"); + exit; +} + +# $avp(callee_pref_u) == CFU URI(s) +# $avp(callee_pref_n) == CFNR URI(s) +# $avp(callee_pref_n_t) == CFNR timeout in seconds +# $avp(callee_pref_b) == CFB URI(s) +# $avp(callee_pref_f) == CFOFFLINE URI(s) + +# +# Example for forward-unconditionally (CFU) +# + +if ($avp(callee_pref_u) != NULL) +{ + # push CFU URI into R-URI and additional branches + # --> request can fork + $ru = $avp(callee_pref_u); + $avp(callee_pref_u) = NULL; + while ($avp(callee_pref_u)!=NULL) { + $branch = $avp(callee_pref_u); + $avp(callee_pref_u) = NULL; + } + sl_send_reply(181, "Call is being forwarded"); + t_relay(); + exit; +} + +``` + + +#### h350_result_service_level(avp_name_prefix) + + +*Directory services architecture for SIP* [H350 4](#H350-4) defines a multi-valued LDAP attribute named SIPIdentityServiceLevel, which can be used to store SIP account service level values in an LDAP directory. This function parses the SIPIdentityServiceLevel attribute and stores all service level values as AVPs for later retrieval in the OpenSIPS routing script. The function accesses the H.350 commObject fetched by a call to *h350_*_lookup* or *ldap_search*. + + +The resulting AVPs have a name of the form `avp_name_prefix + SIPIdentityServiceLevel attribute value`, and an integer value of `1`. + + +```opensips title="Example SIPIdentityServiceLevel values and resulting AVPs" +SIPIdentityServiceLevel: longdistance +SIPIdentityServiceLevel: international +SIPIdentityServiceLevel: 900 + +after calling h350_result_service_level("sl_"), the following AVPs +will be available in the routing script: + +$avp("sl_longdistance") = 1 +$avp("sl_international") = 1 +$avp("sl_900") = 1 + +``` + + +This function returns the number of added AVPs (TRUE), `-1` (FALSE)for internal errors, and `-2` (FALSE)if no SIPIdentityServiceLevel attribute was found. + + +The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. + + +**avp_name_prefix (string)** + + +Name prefix for service level AVPs, as described above. + + +**`n` > 0 (TRUE):** + + +- `n` AVPs added. + + +**`-1` (FALSE):** + + +- Internal error occurred. + + +**`-2` (FALSE):** + + +- No SIPIdentityServiceLevel attribute found. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +# +# H.350 SIP digest authentication for caller +# + +... h350_auth_lookup("$au", ...) ... + +# +# store caller's service level as AVP +# + +if (!h350_result_service_level("caller_sl_") && ($retcode == -1)) +{ + sl_send_reply(500, "Internal server error"); + exit; +} + +# +# make routing decision based on service level AVPs +# + +if ($avp(caller_sl_international) != NULL) +{ + t_relay(); +} +else { + sl_send_reply(403, "Forbidden"); +} +exit; + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/h350/doc/contributors.xml b/modules/h350/doc/contributors.xml deleted file mode 100644 index f556e48bc10..00000000000 --- a/modules/h350/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Christian Schlatter - 21 - 3 - 1993 - 1 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 16 - 14 - 58 - 58 - - - 3. - Daniel-Constantin Mierla (@miconda) - 12 - 9 - 79 - 83 - - - 4. - Liviu Chircu (@liviuchircu) - 11 - 9 - 25 - 39 - - - 5. - Razvan Crainea (@razvancrainea) - 10 - 7 - 53 - 61 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 9 - 3 - 80 - 247 - - - 7. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 8. - Konstantin Bokarius - 3 - 1 - 1 - 4 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 10. - Edson Gellert Schubert - 3 - 1 - 0 - 85 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2008 - Feb 2024 - - - 3. - Razvan Crainea (@razvancrainea) - Jun 2011 - Feb 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Daniel-Constantin Mierla (@miconda) - Sep 2007 - Mar 2008 - - - 8. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 9. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - 10. - Christian Schlatter - Aug 2007 - Dec 2007 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Christian Schlatter. -
- -
diff --git a/modules/h350/doc/h350.xml b/modules/h350/doc/h350.xml deleted file mode 100644 index 9bb02a1ba64..00000000000 --- a/modules/h350/doc/h350.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - H350 Module - &osips; - - - - &admin; - &faq; - &biblio; - &contrib; - - &docCopyrights; - ©right; 2007 University of North Carolina - diff --git a/modules/h350/doc/h350_admin.xml b/modules/h350/doc/h350_admin.xml deleted file mode 100644 index b8e625317b2..00000000000 --- a/modules/h350/doc/h350_admin.xml +++ /dev/null @@ -1,814 +0,0 @@ - - &adminguide; - -
- Overview - - - The OpenSIPS H350 module enables an OpenSIPS SIP proxy server to access SIP account data stored in an LDAP directory containing H.350 commObjects. ITU-T Recommendation H.350 standardizes LDAP object classes to store Real-Time Communication (RTC) account data. In particular, H.350.4 defines an object class called sipIdentity that includes attribute specifications for SIP account data like SIP URI, SIP digest username/password, or service level. This allows to store SIP account data in a vendor neutral way and lets different entities, like SIP proxies, provisioning, or billing applications, access the data in a standardized format. - - - - The ViDe H.350 Cookbook is a good reference for deploying an H.350 directory. Besides general information on H.350, LDAP, and related standards, this document explains how to set up an H.350/LDAP directory and discusses different deployment scenarios. - - - - The H350 module uses the OpenSIPS LDAP module to import H.350 attribute values into the OpenSIPS routing script variable space. The module exports functions to parse and store the H.350 attribute values from the OpenSIPS routing script. It allows a script writer to implement H.350 based SIP digest authentication, call forwarding, SIP URI alias to AOR rewriting, and service level parsing. - - -
- Example H.350 commObject LDAP Entry - - - The following example shows a typical H.350 commObject LDAP entry storing SIP account data. - - - - Example H.350 commObject storing SIP account data - - -Attribute Name Attribute Value(s) --------------- ----------------- - -# LDAP URI identifying the owner of this commObject, typically -# points to an entry in the enterprise directory -commOwner ldap://dir.example.com/dc=example,dc=com??one?(uid=bob) - -# Unique identifier for this commObject, used for referencing -# this object e.g. from the enterprise directory -commUniqueId 298217asdjgj213 - -# Determines if this commObject should be listed on white pages -commPrivate false - -# Valid SIP URIs for this account (can be used to store alias SIP URIs -# like DIDs as well) -SIPIdentitySIPURI sip:bob@example.com - sip:bob@alias.example.com - sip:+1919123456@alias.example.com -# SIP digest username -SIPIdentityUserName bob - -# SIP digest password -SIPIdentityPassword pwd - -# SIP proxy address -SIPIdentityProxyAddress sip.example.com - -# SIP registrar address -SIPIdentityRegistrarAddress sip.example.com - -# Call preferences: Forward to voicemail on no response -# after 20 seconds and on busy -callPreferenceURI sip:bob@voicemail.example.com n:20000 - sip:bob@voicemail.example.com b - -# Account service level(s) -SIPIdentityServiceLevel long_distance - conferencing - -# H.350 object classes -objectClass top - commObject - SIPIdentity - callPreferenceURIObject - - -
-
- -
- Dependencies - -
- OpenSIPS Modules - - The module depends on the following modules (the listed modules - must be loaded before this module): - - - - LDAP - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running OpenSIPS with this module loaded: - - - - OpenLDAP library (libldap), libldap header files - (libldap-dev) are needed for compilation - - -
-
- -
- Exported Parameters - -
- ldap_session (string) - - - Name of the LDAP session to be used for H.350 queries, as defined in the LDAP module configuration file. - - - - Default value: "" - - - - <varname>ldap_session</varname> parameter usage - - -modparam("h350", "ldap_session", "h350"); - - -
- -
- base_dn (string) - - - Base LDAP DN to start LDAP search for H.350 entries. For best performance, this should be set to the direct ancestor of the H.350 objects. - - - - Default value: "" - - - - <varname>base_dn</varname> parameter usage - - -modparam("h350", "base_dn", "ou=h350,dc=example,dc=com"); - - -
- -
- search_scope (string) - - - LDAP search scope for H.350 queries, one of "one", "base", or "sub". - - - - Default value: "one" - - - - <varname>search_scope</varname> parameter usage - - -modparam("h350", "search_scope", "sub"); - - -
-
- -
- Exported Functions - -
- h350_sipuri_lookup(sip_uri) - - - This function performs an LDAP search query for an H.350 commObject with a SIPIdentitySIPURI of sip_uri. The sip_uri parameter first gets escaped according the rules for LDAP filter strings. The result of the LDAP search is stored internally and can be accessed either by one of the h350_result* or one of the ldap_result* functions from the OpenSIPS LDAP module. - - - - The function returns -1 (FALSE) for internal errors, and -2 (FALSE) if no H.350 commObject was found with a matching sip_uri. n > 0 (TRUE) is returned if n H.350 commObjects were found. - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. - - - - Function Parameters: - - - sip_uri (string) - - - - H.350 SIPIdentitySIPURI to search for in directory. - - - - - - - Return Values: - - - n > 0 (TRUE): - - - - - - n H.350 commObjects found. - - - - - - - - -1 (FALSE): - - - - - - Internal error occurred. - - - - - - - - -2 (FALSE): - - - - - - No H.350 commObject found. - - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - - Example Usage - - -# -# H.350 lookup for callee -# - -if (!h350_sipuri_lookup("sip:$rU@$rd")) -{ - switch ($retcode) - { - case -2: - xlog("L_INFO", - "h350 callee lookup: no entry found in H.350 directory"); - exit; - case -1: - sl_send_reply(500, "Internal server error"); - exit; - } -} - -# now h350_result* or ldap_result* functions can be used - - -
- -
- h350_auth_lookup(auth_username, "username_avp_spec/pwd_avp_spec") - - - This function performs an LDAP search query for SIP digest authentication credentials in an H.350 directory. The H.350 directory is searched for a commObject with SIPIdentityUserName of auth_username. If such a commObject is found, the SIP digest authentication username and password are stored in AVPs username_avp_spec and pwd_avp_spec, respectively. pv_*_authorize functions from AUTH module can then be used to perform SIP digest authentication. - - - - The function returns 1 (TRUE) if an H.350 commObject was found, -1 (FALSE) in case of an internal error, and -2 (FALSE) if no matching commObject was found. - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. - - - - Function Parameters: - - - auth_username (string) - - - - H.350 SIPIdentityUserName to search for in directory. - - - - - - username_avp_spec (var) - - - - Specification for authentication username AVP, e.g. $avp(username). - - - - - - pwd_avp_spec (var) - - - - Specification for authentication password AVP, e.g. $avp(pwd). - - - - - - - Return Values: - - - 1 (TRUE): - - - - - - H.350 commObject found and SIP digest authentication credentials stored in username_avp_spec and pwd_avp_spec. - - - - - - - - -1 (FALSE): - - - - - - Internal error occurred. - - - - - - - - -2 (FALSE): - - - - - - No H.350 commObject found. - - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -# -- auth params -- -modparam("auth", "username_spec", "$avp(auth_user)") -modparam("auth", "password_spec", "$avp(auth_pwd)") -modparam("auth", "calculate_ha1", 1) - -# -- h350 params -- -modparam("h350", "ldap_session", "h350") -modparam("h350", "base_dn", "ou=h350,dc=example,dc=com") -modparam("h350", "search_scope", "one") - - -route[1] -{ - # - # H.350 based SIP digest authentication - # - - # challenge all requests not including an Auth header - if (!(is_present_hf("Authorization") || - is_present_hf("Proxy-Authorization"))) - { - if (is_method("REGISTER")) - { - www_challenge("example.com", 0); - exit; - } - proxy_challenge("example.com", 0); - exit; - } - - # get digest password from H.350 using auth username ($au) - if (!h350_auth_lookup($au, - "$avp(auth_user)/$avp(auth_pwd)")) - { - switch ($retcode) - { - case -2: - sl_send_reply(401, "Unauthorized"); - exit; - case -1: - sl_send_reply(500, "Internal server error"); - exit; - } - } - - # REGISTER requests - if (is_method("REGISTER")) - { - if (!pv_www_authorize("example.com")) - { - if ($retcode == -5) - { - sl_send_reply(500, "Internal server error"); - exit; - } - else { - www_challenge("example.com", 0); - exit; - } - } - - consume_credentials(); - xlog("L_INFO", - "REGISTER request successfully authenticated"); - return(1); - } - - # non-REGISTER requests - if (!pv_proxy_authorize("example.com")) - { - if ($retcode == -5) - { - sl_send_reply(500, "Internal server error"); - exit; - } - else { - proxy_challenge("example.com", 0); - exit; - } - } - - consume_credentials(); - xlog("L_INFO", "$rm request successfully authenticated"); - return(1); -} - - -
- -
- h350_result_call_preferences(avp_name_prefix) - - - This function parses the callPreferenceURI attribute of an H.350 commObject, which must have been fetched through h350_*_lookup or ldap_search. callPreferenceURI is a multi-valued attribute that stores call preference rules like e.g. forward-on-busy or forward-unconditionally. Directory services architecture for call forwarding and preferences defines a format for simple call forwarding rules: - - -
- - target_uri type[:argument] - -
- - - In a SIP environment, target_uri is typically the call forwarding rule's target SIP URI, although it could be any type of URI, e.g. an HTTP pointer to a CPL script. Four different values are specified for type: b for "forward on busy", n for "forward on no answer", u for "forward unconditionally", and f for "forward on destination not found". The optional argument is a string indicating the time in milliseconds after which the call forwarding should occur. - - - - Example H.350 callPreferenceURI simple call forwarding rules - - -# Example 1: -# forward to sip:voicemail@example.com on no answer after 15 seconds: - -callPreferenceURI: sip:voicemail@example.com n:15000 - -# Example 2: -# unconditionally forward to sip:alice@example.com: - -callPreferenceURI: sip:alice@example.com u - -# Example 3: -# forward to sip:bob@example.com and sip:alice@example.com -# (forking) on destination not found: - -callPreferenceURI: sip:bob@example.com f -callPreferenceURI: sip:alice@example.com f - - - - - h350_result_call_preferences stores these call forwarding rules as AVPs according to the following rules: - - -
- -# -# AVP storing a forwarding rule's target URI -# - -AVP name = avp_name_prefix + '_' + type -AVP value = target_uri - -# -# AVP storing a forwarding rule's argument -# - -AVP name = avp_name_prefix + '_' + type + '_t' -AVP value = argument / 1000 - -
- - - Example 1 from above would result in two AVPs: $avp("prefix_n") = "sip:voicemail@example.com" and $avp("prefix_n_t") = 15. - - - - Example 2: $avp("prefix_u") = "sip:alice@example.com". - - - - Example 3: $avp("prefix_f[1]") = "sip:bob@example.com" and $avp("prefix_f[2]]") = "sip:alice@example.com". - - - - These AVPs can then be used to implement the desired behavior in the OpenSIPS routing script. - - - - This function returns the number of successfully parsed simple call forwarding rules (TRUE), in case the H.350 callPreferenceURI attribute contained one or multiple values matching the simple call forwarding rule syntax described above. It returns -1 (FALSE) for internal errors, and -2 (FALSE) if none of the rules matched or if no callPreferenceURI attribute was found. - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. - - - - Function Parameters: - - - avp_name_prefix (string) - - - - Name prefix for call forwarding rule AVPs, as described above. - - - - - - - Return Values: - - - n > 0 (TRUE): - - - - - - n simple call forwarding rules found. - - - - - - - - -1 (FALSE): - - - - - - Internal error occurred. - - - - - - - - -2 (FALSE): - - - - - - No simple call forwarding rule found, or callPreferenceURI not present. - - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - - Example Usage - - -# -# H.350 lookup for callee -# - -... h350_sipuri_lookup("sip:$rU@$rd") ... - -# -# store H.350 call preferences in AVP -# - -if (!h350_result_call_preferences("callee_pref_") && ($retcode == -1)) -{ - sl_send_reply(500, "Internal server error"); - exit; -} - -# $avp(callee_pref_u) == CFU URI(s) -# $avp(callee_pref_n) == CFNR URI(s) -# $avp(callee_pref_n_t) == CFNR timeout in seconds -# $avp(callee_pref_b) == CFB URI(s) -# $avp(callee_pref_f) == CFOFFLINE URI(s) - -# -# Example for forward-unconditionally (CFU) -# - -if ($avp(callee_pref_u) != NULL) -{ - # push CFU URI into R-URI and additional branches - # --> request can fork - $ru = $avp(callee_pref_u); - $avp(callee_pref_u) = NULL; - while ($avp(callee_pref_u)!=NULL) { - $branch = $avp(callee_pref_u); - $avp(callee_pref_u) = NULL; - } - sl_send_reply(181, "Call is being forwarded"); - t_relay(); - exit; -} - - -
- -
- h350_result_service_level(avp_name_prefix) - - - Directory services architecture for SIP defines a multi-valued LDAP attribute named SIPIdentityServiceLevel, which can be used to store SIP account service level values in an LDAP directory. This function parses the SIPIdentityServiceLevel attribute and stores all service level values as AVPs for later retrieval in the OpenSIPS routing script. The function accesses the H.350 commObject fetched by a call to h350_*_lookup or ldap_search. - - - - The resulting AVPs have a name of the form avp_name_prefix + SIPIdentityServiceLevel attribute value, and an integer value of 1. - - - - Example SIPIdentityServiceLevel values and resulting AVPs - -SIPIdentityServiceLevel: longdistance -SIPIdentityServiceLevel: international -SIPIdentityServiceLevel: 900 - -after calling h350_result_service_level("sl_"), the following AVPs -will be available in the routing script: - -$avp("sl_longdistance") = 1 -$avp("sl_international") = 1 -$avp("sl_900") = 1 - - - - - This function returns the number of added AVPs (TRUE), -1 (FALSE)for internal errors, and -2 (FALSE)if no SIPIdentityServiceLevel attribute was found. - - - - The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE and BRANCH_ROUTE. - - - - Function Parameters: - - - avp_name_prefix (string) - - - - Name prefix for service level AVPs, as described above. - - - - - - - Return Values: - - - n > 0 (TRUE): - - - - - - n AVPs added. - - - - - - - - -1 (FALSE): - - - - - - Internal error occurred. - - - - - - - - -2 (FALSE): - - - - - - No SIPIdentityServiceLevel attribute found. - - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - - Example Usage - - -# -# H.350 SIP digest authentication for caller -# - -... h350_auth_lookup("$au", ...) ... - -# -# store caller's service level as AVP -# - -if (!h350_result_service_level("caller_sl_") && ($retcode == -1)) -{ - sl_send_reply(500, "Internal server error"); - exit; -} - -# -# make routing decision based on service level AVPs -# - -if ($avp(caller_sl_international) != NULL) -{ - t_relay(); -} -else { - sl_send_reply(403, "Forbidden"); -} -exit; - - -
-
- -
- diff --git a/modules/h350/doc/h350_biblio.xml b/modules/h350/doc/h350_biblio.xml deleted file mode 100644 index 85ee851ae63..00000000000 --- a/modules/h350/doc/h350_biblio.xml +++ /dev/null @@ -1,71 +0,0 @@ - - Resources - - - - H.350 - - <ulink url="http://www.itu.int/rec/T-REC-H.350/en">Directory - Services Architecture for Multimedia Conferencing</ulink> - - August 2003 - - - ITU-T - - - - - H.350.4 - - <ulink url="http://www.itu.int/rec/T-REC-H.350.4/en">Directory - services architecture for SIP</ulink> - - August 2003 - - - ITU-T - - - - - H.350.6 - - <ulink url="http://www.itu.int/rec/T-REC-H.350.6/en">Directory services architecture for call forwarding and preferences</ulink> - - March 2004 - - - ITU-T - - - - - ViDe-H.350-Cookbook - - <ulink url="http://www.vide.net/cookbookh350/">ViDe H.350 Cookbook</ulink> - - 2005 - - - ViDe - - - - - RFC4510 - - <ulink url="http://tools.ietf.org/html/rfc4510">Lightweight - Directory Access Protocol (LDAP): Technical Specification Road - Map</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - - diff --git a/modules/http2d/README b/modules/http2d/README deleted file mode 100644 index 850f4de9279..00000000000 --- a/modules/http2d/README +++ /dev/null @@ -1,293 +0,0 @@ -HTTP2D MODULE - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. ip (string) - 1.3.2. port (integer) - 1.3.3. tls_cert_path (string) - 1.3.4. tls_cert_key (string) - 1.3.5. max_headers_size (integer) - 1.3.6. response_timeout (integer) - - 1.4. Exported Functions - - 1.4.1. http2_send_response(code, [headers_json], - [data]) - - 1.5. Exported Events - - 1.5.1. E_HTTP2_REQUEST - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the ip parameter - 1.2. Setting the port parameter - 1.3. Setting the tls_cert_path parameter - 1.4. Setting the tls_cert_key parameter - 1.5. Setting the max_headers_size parameter - 1.6. Setting the response_timeout parameter - 1.7. http2_send_response() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides an RFC 7540/9113 HTTP/2 server - implementation with "h2" ALPN support, based on the nghttp2 - library (https://nghttp2.org/). - - HTTP/2, introduced in 2015, is a binary protocol with added - transactional layers (SESSION, FRAME), which allow identifying - and managing multiple, concurrent transfers over the same - TCP/TLS connection. Thus, the revised protocol primarily aims - to reduce resource usage for both clients and servers, by - reducing the amount of TCP and/or TLS handshakes performed when - loading a given web page. - - The OpenSIPS http2d server includes support for both "h2" (TLS - secured) and "h2c" (cleartext) HTTP/2 connections. The requests - arrive at opensips.cfg level using the E_HTTP2_REQUEST event, - where script writers may process the data and respond - accordingly. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - None. - -1.2.2. External Libraries or Applications - - The HTTP/2 server is provided by the nghttp2 library, which - runs on top of the libevent server framework. - - Overall, the following libraries must be installed before - running OpenSIPS with this module loaded: - * libnghttp2 - * libevent, libevent_openssl - * libssl, libcrypto - -1.3. Exported Parameters - -1.3.1. ip (string) - - The listening IPv4 address. - - Default value is "127.0.0.1". - - Example 1.1. Setting the ip parameter - -modparam("http2d", "ip", "127.0.0.2") - - -1.3.2. port (integer) - - The listening port. - - Default value is 443. - - Example 1.2. Setting the port parameter - -modparam("http2d", "port", 5000) - - -1.3.3. tls_cert_path (string) - - File path to the TLS certificate, in PEM format. - - Default value is NULL (not set). - - Example 1.3. Setting the tls_cert_path parameter - -modparam("http2d", "tls_cert_path", "/etc/pki/http2/cert.pem") - - -1.3.4. tls_cert_key (string) - - File path to the TLS private key, in PEM format. - - Default value is NULL (not set). - - Example 1.4. Setting the tls_cert_key parameter - -modparam("http2d", "tls_cert_key", "/etc/pki/http2/private/key.pem") - - -1.3.5. max_headers_size (integer) - - The maximum amount of bytes allowed for all header field names - and values combined in a single HTTP/2 request processed by the - server. Once this threshold is reached, extra headers will no - longer be provided at script level and will be reported as - errors instead. - - Default value is 8192 bytes. - - Example 1.5. Setting the max_headers_size parameter - -modparam("http2d", "max_headers_size", 16384) - - -1.3.6. response_timeout (integer) - - The maximum amount of time, in milliseconds, that the library - will allow the opensips.cfg processing to take for a given - HTTP/2 request. - - Once this timeout is reached, the module will auto-generate a - 408 (request timeout) reply. - - Default value is 2000 ms. - - Example 1.6. Setting the response_timeout parameter - -modparam("http2d", "response_timeout", 5000) - - -1.4. Exported Functions - -1.4.1. http2_send_response(code, [headers_json], [data]) - - Sends a response for the HTTP/2 request being processed. The - ":status" header field will be automatically included by the - module as 1st header, so it must not be included in the - headers_json array. - - Parameters - * code (integer) - The HTTP/2 reply code - * headers_json (string, default: NULL) - Optional JSON Array - containing {"header": "value"} elements, denoting HTTP/2 - headers and their values to be included in the response - message. - * data (string, default: NULL) - Optional DATA payload to - include in the response message. - - Return Codes - * 1 - Success - * -1 - Internal Error - - This function can only be used from an EVENT_ROUTE. - - Example 1.7. http2_send_response() usage - -event_route [E_HTTP2_REQUEST] { - xlog(":: Method: $param(method)\n"); - xlog(":: Path: $param(path)\n"); - xlog(":: Headers: $param(headers)\n"); - xlog(":: Data: $param(data)\n"); - - $json(hdrs) := $param(headers); - xlog("content-type: $json(hdrs/content-type)\n"); - - $var(rpl_headers) = "[ - { \"content-type\": \"application/json\" }, - { \"server\": \"OpenSIPS 3.5\" }, - { \"x-current-time\": \"1711457142\" }, - { \"x-call-cost\": \"0.355\" } - ]"; - - $var(data) = "{\"status\": \"success\"}"; - - if (!http2_send_response(200, $var(rpl_headers), $var(data))) - xlog("ERROR - failed to send HTTP/2 response\n"); -} - - -1.5. Exported Events - -1.5.1. E_HTTP2_REQUEST - - This event is raised whenever the http2d module is loaded and - OpenSIPS receives an HTTP/2 request on the configured listening - interface(s). - - Parameters: - * method (string) - value of the ":method" HTTP/2 header - * path (string) - value of the ":path" HTTP/2 header - * headers (string) - JSON Array with all headers of the - request, including pseudo-headers - * data (string, default: NULL) - If the request included a - payload, this parameter will hold its contents - - Note that this event is currently designed to be mainly - consumed by an event_route, since that is the only way to gain - access to the http2_send_response() function in order to build - custom response messages. On the other hand, if the application - does not mind the answer being always a 200 with no payload, - this event can be successfully consumed through any other - EVI-compatible delivery channel ☺️ - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 30 8 2085 215 - 2. Razvan Crainea (@razvancrainea) 4 2 56 4 - 3. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2024 - Aug 2025 - 2. Peter Lemenkov (@lemenkov) Jul 2025 - Jul 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2024 - May 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2024 www.opensips-solutions.com diff --git a/modules/http2d/README.md b/modules/http2d/README.md new file mode 100644 index 00000000000..cb17a3fd2c0 --- /dev/null +++ b/modules/http2d/README.md @@ -0,0 +1,236 @@ +--- +title: "HTTP2D MODULE" +description: "This module provides an RFC 7540/9113 HTTP/2 server implementation with h2 ALPN support, based on the nghttp2 library ([https://nghttp2.org/](https://nghttp2.org/))." +--- + +## Admin Guide + + +### Overview + + +This module provides an RFC 7540/9113 HTTP/2 server implementation with "h2" ALPN support, +based on the **nghttp2** library ([https://nghttp2.org/](https://nghttp2.org/)). + + +HTTP/2, introduced in 2015, is a binary protocol with added transactional layers (SESSION, FRAME), +which allow identifying and managing multiple, concurrent transfers over the same TCP/TLS connection. +Thus, the revised protocol primarily aims to reduce resource usage for both clients and servers, by +reducing the amount of TCP and/or TLS handshakes performed when loading a given web page. + + +The OpenSIPS **http2d** server includes support for both "h2" (TLS secured) +and "h2c" (cleartext) HTTP/2 connections. The requests arrive at +*opensips.cfg* level using the [http2 request](#event_e_http2_request) event, +where script writers may process the data and respond accordingly. + + +### Dependencies + + +#### OpenSIPS Modules + + +None. + + +#### External Libraries or Applications + + +The HTTP/2 server is provided by the **nghttp2** library, +which runs on top of the **libevent** server framework. + + +Overall, the following libraries must be installed before running +OpenSIPS with this module loaded: + + +- *libnghttp2* +- *libevent*, *libevent_openssl* +- *libssl*, *libcrypto* + + +### Exported Parameters + + +#### ip (string) + + +The listening IPv4 address. + + +Default value is *"127.0.0.1"*. + + +```opensips title="Setting the ip parameter" +modparam("http2d", "ip", "127.0.0.2") +``` + + +#### port (integer) + + +The listening port. + + +Default value is *443*. + + +```opensips title="Setting the port parameter" +modparam("http2d", "port", 5000) +``` + + +#### tls_cert_path (string) + + +File path to the TLS certificate, in PEM format. + + +Default value is *NULL* (not set). + + +```opensips title="Setting the tls_cert_path parameter" +modparam("http2d", "tls_cert_path", "/etc/pki/http2/cert.pem") +``` + + +#### tls_cert_key (string) + + +File path to the TLS private key, in PEM format. + + +Default value is *NULL* (not set). + + +```opensips title="Setting the tls_cert_key parameter" +modparam("http2d", "tls_cert_key", "/etc/pki/http2/private/key.pem") +``` + + +#### max_headers_size (integer) + + +The maximum amount of bytes allowed for all header field names and values +combined in a single HTTP/2 request processed by the server. Once this +threshold is reached, extra headers will no longer be provided at script +level and will be reported as errors instead. + + +Default value is *8192* bytes. + + +```opensips title="Setting the max_headers_size parameter" +modparam("http2d", "max_headers_size", 16384) +``` + + +#### response_timeout (integer) + + +The maximum amount of time, in milliseconds, that the library will +allow the opensips.cfg processing to take for a given HTTP/2 request. + + +Once this timeout is reached, the module will auto-generate a +408 (request timeout) reply. + + +Default value is *2000* ms. + + +```opensips title="Setting the response_timeout parameter" +modparam("http2d", "response_timeout", 5000) +``` + + +### Exported Functions + + +#### http2_send_response(code, [headers_json], [data]) + + +Sends a response for the HTTP/2 request being processed. The *":status"* +header field will be automatically included by the module as 1st header, so it must not be +included in the *headers_json* array. + + +*Parameters* + + +- *code* (integer) - The HTTP/2 reply code +- *headers_json* (string, default: *NULL*) + - Optional JSON Array containing {"header": "value"} elements, denoting HTTP/2 +headers and their values to be included in the response message. +- *data* (string, default: *NULL*) + - Optional DATA payload to include in the response message. + + +*Return Codes* + + +- **1** - Success +- **-1** - Internal Error + + +This function can only be used from an *EVENT_ROUTE*. + + +```opensips title="http2_send_response() usage" +event_route [E_HTTP2_REQUEST] { + xlog(":: Method: $param(method)\n"); + xlog(":: Path: $param(path)\n"); + xlog(":: Headers: $param(headers)\n"); + xlog(":: Data: $param(data)\n"); + + $json(hdrs) := $param(headers); + xlog("content-type: $json(hdrs/content-type)\n"); + + $var(rpl_headers) = "[ + { \"content-type\": \"application/json\" }, + { \"server\": \"OpenSIPS 3.5\" }, + { \"x-current-time\": \"1711457142\" }, + { \"x-call-cost\": \"0.355\" } + ]"; + + $var(data) = "{\"status\": \"success\"}"; + + if (!http2_send_response(200, $var(rpl_headers), $var(data))) + xlog("ERROR - failed to send HTTP/2 response\n"); +} +``` + + +### Exported Events + + +#### E_HTTP2_REQUEST + + +This event is raised whenever the *http2d* +module is loaded and OpenSIPS receives an HTTP/2 request on the configured +listening interface(s). + + +Parameters: + + +- *method (string)* - value of the ":method" HTTP/2 header +- *path (string)* - value of the ":path" HTTP/2 header +- *headers (string)* - JSON Array with all headers of the request, +including pseudo-headers +- *data (string, default: NULL)* - If the request included a payload, +this parameter will hold its contents + + +Note that this event is currently designed to be mainly consumed by an *event_route*, +since that is the only way to gain access to the [http2 send response](#func_http2_send_response) +function in order to build custom response messages. On the other hand, +if the application does not mind the answer being always a 200 with no payload, +this event can be successfully consumed through any other EVI-compatible delivery channel ☺️ + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/http2d/doc/contributors.xml b/modules/http2d/doc/contributors.xml deleted file mode 100644 index 92fdf17d549..00000000000 --- a/modules/http2d/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 30 - 8 - 2085 - 215 - - - 2. - Razvan Crainea (@razvancrainea) - 4 - 2 - 56 - 4 - - - 3. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2024 - Aug 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jul 2025 - Jul 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2024 - May 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/http2d/doc/http2d.xml b/modules/http2d/doc/http2d.xml deleted file mode 100644 index 0da060b9c72..00000000000 --- a/modules/http2d/doc/http2d.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - HTTP2D MODULE - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 &osipssol; - diff --git a/modules/http2d/doc/http2d_admin.xml b/modules/http2d/doc/http2d_admin.xml deleted file mode 100644 index 4e4ee53cbc3..00000000000 --- a/modules/http2d/doc/http2d_admin.xml +++ /dev/null @@ -1,299 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides an RFC 7540/9113 HTTP/2 server implementation with "h2" ALPN support, - based on the nghttp2 library (). - - - - HTTP/2, introduced in 2015, is a binary protocol with added transactional layers (SESSION, FRAME), - which allow identifying and managing multiple, concurrent transfers over the same TCP/TLS connection. - Thus, the revised protocol primarily aims to reduce resource usage for both clients and servers, by - reducing the amount of TCP and/or TLS handshakes performed when loading a given web page. - - - - The OpenSIPS http2d server includes support for both "h2" (TLS secured) - and "h2c" (cleartext) HTTP/2 connections. The requests arrive at - opensips.cfg level using the event, - where script writers may process the data and respond accordingly. - -
- -
- Dependencies -
- &osips; Modules - - None. - -
- -
- External Libraries or Applications - - The HTTP/2 server is provided by the nghttp2 library, - which runs on top of the libevent server framework. - - - Overall, the following libraries must be installed before running - &osips; with this module loaded: - - - - libnghttp2 - - - - libevent, libevent_openssl - - - - libssl, libcrypto - - - -
-
- -
- Exported Parameters -
- <varname>ip (string)</varname> - - The listening IPv4 address. - - - Default value is "127.0.0.1". - - - Setting the <varname>ip</varname> parameter - - -modparam("http2d", "ip", "127.0.0.2") - - - -
- -
- <varname>port (integer)</varname> - - The listening port. - - - Default value is 443. - - - Setting the <varname>port</varname> parameter - - -modparam("http2d", "port", 5000) - - - -
- -
- <varname>tls_cert_path (string)</varname> - - File path to the TLS certificate, in PEM format. - - - Default value is NULL (not set). - - - Setting the <varname>tls_cert_path</varname> parameter - - -modparam("http2d", "tls_cert_path", "/etc/pki/http2/cert.pem") - - - -
- -
- <varname>tls_cert_key (string)</varname> - - File path to the TLS private key, in PEM format. - - - Default value is NULL (not set). - - - Setting the <varname>tls_cert_key</varname> parameter - - -modparam("http2d", "tls_cert_key", "/etc/pki/http2/private/key.pem") - - - -
- -
- <varname>max_headers_size (integer)</varname> - - The maximum amount of bytes allowed for all header field names and values - combined in a single HTTP/2 request processed by the server. Once this - threshold is reached, extra headers will no longer be provided at script - level and will be reported as errors instead. - - - Default value is 8192 bytes. - - - Setting the <varname>max_headers_size</varname> parameter - - -modparam("http2d", "max_headers_size", 16384) - - - -
- -
- <varname>response_timeout (integer)</varname> - - The maximum amount of time, in milliseconds, that the library will - allow the opensips.cfg processing to take for a given HTTP/2 request. - - - Once this timeout is reached, the module will auto-generate a - 408 (request timeout) reply. - - - Default value is 2000 ms. - - - Setting the <varname>response_timeout</varname> parameter - - -modparam("http2d", "response_timeout", 5000) - - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">http2_send_response(code, [headers_json], [data])</function> - - - Sends a response for the HTTP/2 request being processed. The ":status" - header field will be automatically included by the module as 1st header, so it must not be - included in the headers_json array. - - Parameters - - - code (integer) - The HTTP/2 reply code - - - headers_json (string, default: NULL) - - Optional JSON Array containing {"header": "value"} elements, denoting HTTP/2 - headers and their values to be included in the response message. - - - data (string, default: NULL) - - Optional DATA payload to include in the response message. - - - - Return Codes - - - 1 - Success - - - - -1 - Internal Error - - - - - - This function can only be used from an EVENT_ROUTE. - - - <function moreinfo="none">http2_send_response()</function> usage - - -event_route [E_HTTP2_REQUEST] { - xlog(":: Method: $param(method)\n"); - xlog(":: Path: $param(path)\n"); - xlog(":: Headers: $param(headers)\n"); - xlog(":: Data: $param(data)\n"); - - $json(hdrs) := $param(headers); - xlog("content-type: $json(hdrs/content-type)\n"); - - $var(rpl_headers) = "[ - { \"content-type\": \"application/json\" }, - { \"server\": \"OpenSIPS 3.5\" }, - { \"x-current-time\": \"1711457142\" }, - { \"x-call-cost\": \"0.355\" } - ]"; - - $var(data) = "{\"status\": \"success\"}"; - - if (!http2_send_response(200, $var(rpl_headers), $var(data))) - xlog("ERROR - failed to send HTTP/2 response\n"); -} - - - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_HTTP2_REQUEST</function> - - - This event is raised whenever the http2d - module is loaded and OpenSIPS receives an HTTP/2 request on the configured - listening interface(s). - - Parameters: - - - method (string) - value of the ":method" HTTP/2 header - - - path (string) - value of the ":path" HTTP/2 header - - - headers (string) - JSON Array with all headers of the request, - including pseudo-headers - - - data (string, default: NULL) - If the request included a payload, - this parameter will hold its contents - - - - - Note that this event is currently designed to be mainly consumed by an event_route, - since that is the only way to gain access to the - function in order to build custom response messages. On the other hand, - if the application does not mind the answer being always a 200 with no payload, - this event can be successfully consumed through any other EVI-compatible delivery channel ☺️ - -
- -
- -
diff --git a/modules/http2d/server.c b/modules/http2d/server.c index 0154e1e8518..382963711b5 100644 --- a/modules/http2d/server.c +++ b/modules/http2d/server.c @@ -584,7 +584,7 @@ static int on_request_recv(nghttp2_session *session, rc = pthread_cond_timedwait(&ng_h2_response->cond, &ng_h2_response->mutex, &wait_until); diff_ns = get_clock_diff(&begin); - LM_DBG("waited %lld ns in total\n", diff_ns); + LM_DBG("waited %llu ns in total\n", diff_ns); if (rc != 0) { pthread_mutex_unlock(&ng_h2_response->mutex); @@ -635,7 +635,7 @@ static int on_frame_recv_callback(nghttp2_session *session, switch (frame->hd.type) { case NGHTTP2_DATA: case NGHTTP2_HEADERS: - LM_DBG("h2 header [%d], %p %ld\n", frame->hd.type, frame->headers.nva, frame->headers.nvlen); + LM_DBG("h2 header [%d], %p %zu\n", frame->hd.type, frame->headers.nva, frame->headers.nvlen); /* Check that the client request has finished */ if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { stream_data = @@ -1049,4 +1049,3 @@ void http2_server(int rank) run(int2str(h2_port, NULL), h2_tls_key.s, h2_tls_cert.s); LM_ERR("HTTP2 server exiting!\n"); } - diff --git a/modules/httpd/README b/modules/httpd/README deleted file mode 100644 index b07acc67d9c..00000000000 --- a/modules/httpd/README +++ /dev/null @@ -1,371 +0,0 @@ -httpd Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Overview - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. ip(string) - 1.4.2. port(integer) - 1.4.3. conn_timeout(integer) - 1.4.4. buf_size (integer) - 1.4.5. post_buf_size (integer) - 1.4.6. receive_buf_size (integer) - 1.4.7. tls_cert_file (string) - 1.4.8. tls_key_file (string) - 1.4.9. tls_ciphers (string) - - 1.5. Exported MI Functions - - 1.5.1. httpd_list_root_path - - 1.6. Exported Functions - 1.7. Known issues - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. register_httpdcb (module, root_path, - httpd_acces_handler_cb, httpd_flush_data_cb, - httpd_init_proc_cb) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set ip parameter - 1.2. Set port parameter - 1.3. Set conn_timeout parameter - 1.4. Set buf_size parameter - 1.5. Set post_buf_size parameter - 1.6. Set receive_buf_size parameter - 1.7. Set tls_cert_file parameter - 1.8. Set tls_key_file parameter - 1.9. Set tls_key_file parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides an HTTP transport layer for OpenSIPS. - - Implementation of httpd module's http server is based on - libmicrohttpd library. - -1.2. Overview - - TLS for the http server is enabled by setting the tls_cert_file - and tls_key_file parameters. If this is enabled, support for - plain http is disabled. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libmicrohttpd, with EPOLL support. This typically means a - version newer than 0.9.50. - - WARNING! Please be aware about an EPOLL support regression in - the libmicrohttpd library and packaging which affects the - OpenSIPS httpd module, which was fixed according to the below - timeline. The effect of the regression is that the HTTP reply - body is sometimes never written by the library, causing the - client (e.g. opensips-cli) to hang indefinitely waiting for it: - * versions 0.9.51 - 0.9.52 have been tested and work - correctly - * regression introduced in 0.9.53 (Apr 2017), lasting until - 0.9.71 (May 2020) - * regression is fixed since 0.9.72 (Dec 2020) - -1.4. Exported Parameters - -1.4.1. ip(string) - - The IP address used by the HTTP server to listen for incoming - requests. - - The default value is "*" (bind to all IPv6 and IPv4 - interfaces). - - Example 1.1. Set ip parameter -... -modparam("httpd", "ip", "127.0.0.1") -... - -1.4.2. port(integer) - - The port number used by the HTTP server to listen for incoming - requests. - - The default value is 8888. Ports lower than 1024 are not - accepted. - - Example 1.2. Set port parameter -... -modparam("httpd", "port", 8000) -... - -1.4.3. conn_timeout(integer) - - Auto-close TCP connections which are idle for more than the - designated timeout, in seconds. Set to zero to never close any - connections. - - Note: the connection auto-close routine only seems to be - executed in an "on-demand" fashion, during an HTTPD network - event (e.g. on a new connection), which although not ideal, it - should be good enough in practical terms. - - The default timeout is 30 seconds. - - Example 1.3. Set conn_timeout parameter -... -modparam("httpd", "conn_timeout", 10) -... - -1.4.4. buf_size (integer) - - It specifies the maximum length (in bytes) of the buffer used - to write in the html response. - - If the size of the buffer is set to zero, it will be - automatically set to a quarter of the size of the pkg memory. - - The default value is 0. - - Example 1.4. Set buf_size parameter -... -modparam("httpd", "buf_size", 524288) -... - -1.4.5. post_buf_size (integer) - - It specifies the length (in bytes) of the POST HTTP requests - processing buffer. For large POST request, the default value - might require to be increased. - - The default value is 1024. The minumal value is 256. - - Example 1.5. Set post_buf_size parameter -... -modparam("httpd", "post_buf_size", 4096) -... - -1.4.6. receive_buf_size (integer) - - It specifies the maximum length (in bytes) of the received HTTP - requests. For receiving large POST request, the default value - might require to be increased. - - The default value is 1024. - - Example 1.6. Set receive_buf_size parameter -... -modparam("httpd", "receive_buf_size", 4096) -... - -1.4.7. tls_cert_file (string) - - Public certificate file for httpd. It will be used as - server-side certificate for incoming TLS connections. - - The default value is "" - - Example 1.7. Set tls_cert_file parameter -... -modparam("httpd", "tls_cert_file", "/etc/opensips/tls/server.pem") -... - -1.4.8. tls_key_file (string) - - Private key of the above certificate. I must be kept in a safe - place with tight permissions! - - The default value is "" - - Example 1.8. Set tls_key_file parameter -... -modparam("httpd", "tls_key_file", "/etc/opensips/tls/server.key") -... - -1.4.9. tls_ciphers (string) - - You can specify the list of algorithms for authentication and - encryption that you allow. To obtain a list of ciphers and then - choose, use the gnutls-cli application: - * gnutls-cli -l - -Warning - - Do not use the NULL algorithms (no encryption) ... never!!! - - The default value is - "SECURE256:+SECURE192:-VERS-ALL:+VERS-TLS1.2" - - Example 1.9. Set tls_key_file parameter -... -modparam("httpd", "tls_ciphers", "SECURE256:+SECURE192:-VERS-ALL:+VERS-T -LS1.2") -... - -1.5. Exported MI Functions - -1.5.1. httpd_list_root_path - - Lists all the registered http root paths into the httpd module. - When a request comes in, if the root parth is in the list, the - request will be sent to the module that register it. - - Name: httpd_list_root_path - - Parameters: none - - MI FIFO Command Format: -opensips-cli -x mi httpd_list_root_path - -1.6. Exported Functions - - No function exported to be used from configuration file. - -1.7. Known issues - - Due to the fact that OpenSIPS is a multiprocess application, - the microhttpd library is used in "external select" mode. This - ensures that the library is not running in multithread mode and - the library is entirely controled by OpenSIPS. Due to this - particular mode of operations, for now, the entire http - response is built in a pre-allocated buffer (see buf_size - parameter). - - Future realeases of this module will address this issue. - - Running the http daemon as non root on ports below 1024 is - forbidden by default in linux (kernel>=2.6.24). To allow the - port binding, one can use setcap to give extra privilleges to - opensips binary: -setcap 'cap_net_bind_service=+ep' /usr/local/sbin/opensips - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. register_httpdcb (module, root_path, httpd_acces_handler_cb, -httpd_flush_data_cb, httpd_init_proc_cb) - - Register a new http root with it's associated callbacks into - the httpd module. - - Meaning of the parameters is as follows: - * const char *mod - name of the module that register an http - root path to be handled; - * str *root_path - the registered root path; - * httpd_acces_handler_cb f1 - handler to the callback method - to be called on root path match; - * httpd_flush_data_cb f2 - handler to the callback method to - be called for sending extra data (at a later time); - * httpd_init_proc_cb f3 - handler to the callback method to - be called during httpd process init; - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 48 30 1667 147 - 2. Razvan Crainea (@razvancrainea) 24 21 118 68 - 3. Liviu Chircu (@liviuchircu) 23 19 172 82 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 14 12 103 54 - 5. Vlad Patrascu (@rvlad-patrascu) 10 7 52 89 - 6. Ionut Ionita (@ionutrazvanionita) 8 6 65 21 - 7. Vlad Paiu (@vladpaiu) 4 2 68 16 - 8. Maksym Sobolyev (@sobomax) 4 2 5 5 - 9. Alexandra Titoc 4 2 2 1 - 10. Fabian Gast (@fgast) 4 1 150 3 - - All remaining contributors: Stephane Alnet, Stas Kobzar, Dusan - Klinec (@ph4r05), Ken Rice, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Vlad Paiu (@vladpaiu) Dec 2024 - Dec 2024 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Razvan Crainea (@razvancrainea) Mar 2015 - Oct 2021 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2013 - Aug 2021 - 8. Fabian Gast (@fgast) Aug 2020 - Aug 2020 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 10. Ovidiu Sas (@ovidiusas) Jan 2012 - Jan 2019 - - All remaining contributors: Peter Lemenkov (@lemenkov), Ionut - Ionita (@ionutrazvanionita), Dusan Klinec (@ph4r05), Stas - Kobzar, Stephane Alnet. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Fabian - Gast (@fgast), Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Ovidiu Sas - (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2012-2013 VoIP Embedded, Inc. diff --git a/modules/httpd/README.md b/modules/httpd/README.md new file mode 100644 index 00000000000..890516e032d --- /dev/null +++ b/modules/httpd/README.md @@ -0,0 +1,330 @@ +--- +title: "httpd Module" +description: "This module provides an HTTP transport layer for OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module provides an HTTP transport layer for OpenSIPS. + + +Implementation of httpd module's http server is based on +libmicrohttpd library. + + +### Overview + + +TLS for the http server is enabled by setting the `tls_cert_file` +and `tls_key_file` parameters. If this is enabled, support for plain +http is disabled. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libmicrohttpd*, with EPOLL support. This +typically means a version newer than **0.9.50**. + + +**WARNING!** Please be aware about an +EPOLL support regression in the *libmicrohttpd* +library and packaging which affects the OpenSIPS httpd module, which +was fixed according to the below timeline. The effect of the +regression is that the HTTP reply body is *sometimes* +never written by the library, causing the client (e.g. opensips-cli) +to hang indefinitely waiting for it: + + +- versions **0.9.51** - **0.9.52** +have been tested and work correctly +- regression introduced in **0.9.53** (Apr 2017), +lasting until **0.9.71** (May 2020) +- regression is fixed since **0.9.72** (Dec 2020) + + +### Exported Parameters + + +#### ip(string) + + +The IP address used by the HTTP server to listen for incoming +requests. + + +*The default value is "*"* (bind to all IPv6 and IPv4 interfaces). + + +```opensips title="Set ip parameter" +... +modparam("httpd", "ip", "127.0.0.1") +... +``` + + +#### port(integer) + + +The port number used by the HTTP server to listen for incoming +requests. + + +*The default value is 8888.* +Ports lower than 1024 are not accepted. + + +```opensips title="Set port parameter" +... +modparam("httpd", "port", 8000) +... +``` + + +#### conn_timeout(integer) + + +Auto-close TCP connections which are idle for more than the designated +timeout, in seconds. Set to zero to never close any connections. + + +> [!NOTE] +> The connection auto-close routine only seems to be executed +> in an "on-demand" fashion, during an HTTPD network event (e.g. on a new +> connection), which although not ideal, it should be good enough in +> practical terms. + + +*The default timeout is 30 seconds.* + + +```opensips title="Set conn_timeout parameter" +... +modparam("httpd", "conn_timeout", 10) +... +``` + + +#### buf_size (integer) + + +It specifies the maximum length (in bytes) of the buffer +used to write in the html response. + + +If the size of the buffer is set to zero, it will be automatically +set to a quarter of the size of the pkg memory. + + +*The default value is 0.* + + +```opensips title="Set buf_size parameter" +... +modparam("httpd", "buf_size", 524288) +... +``` + + +#### post_buf_size (integer) + + +It specifies the length (in bytes) of the POST HTTP requests +processing buffer. For large POST request, the default value +might require to be increased. + + +*The default value is 1024. The minumal value is 256.* + + +```opensips title="Set post_buf_size parameter" +... +modparam("httpd", "post_buf_size", 4096) +... +``` + + +#### receive_buf_size (integer) + + +It specifies the maximum length (in bytes) of the received HTTP requests. +For receiving large POST request, the default value might require to be increased. + + +*The default value is 1024.* + + +```opensips title="Set receive_buf_size parameter" +... +modparam("httpd", "receive_buf_size", 4096) +... +``` + + +#### tls_cert_file (string) + + +Public certificate file for httpd. It will be used as server-side certificate for incoming TLS connections. + + +*The default value is ""* + + +```opensips title="Set tls_cert_file parameter" +... +modparam("httpd", "tls_cert_file", "/etc/opensips/tls/server.pem") +... +``` + + +#### tls_key_file (string) + + +Private key of the above certificate. I must be kept in a safe place with tight permissions! + + +*The default value is ""* + + +```opensips title="Set tls_key_file parameter" +... +modparam("httpd", "tls_key_file", "/etc/opensips/tls/server.key") +... +``` + + +#### tls_ciphers (string) + + +You can specify the list of algorithms for authentication and encryption that you allow. +To obtain a list of ciphers +and then choose, use the gnutls-cli application: + + +- gnutls-cli -l + + +> [!WARNING] +> Do not use the NULL algorithms (no encryption) ... never!!! + + +*The default value is "SECURE256:+SECURE192:-VERS-ALL:+VERS-TLS1.2"* + + +```opensips title="Set tls_key_file parameter" +... +modparam("httpd", "tls_ciphers", "SECURE256:+SECURE192:-VERS-ALL:+VERS-TLS1.2") +... +``` + + +### Exported MI Functions + + +#### httpd_list_root_path + + +Lists all the registered http root paths into the httpd module. +When a request comes in, if the root parth is in the list, +the request will be sent to the module that register it. + + +Name: *httpd_list_root_path* + + +Parameters: none + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi httpd_list_root_path + +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Known Issues + + +Due to the fact that OpenSIPS is a multiprocess application, +the microhttpd library is used in "external select" mode. +This ensures that the library is not running in +multithread mode and the library is entirely controled +by OpenSIPS. Due to this particular mode of operations, +for now, the entire http response is built in a pre-allocated +buffer (see buf_size parameter). + + +Future realeases of this module will address this issue. + + +Running the http daemon as non root on ports below 1024 is +forbidden by default in linux (kernel>=2.6.24). +To allow the port binding, one can use +*setcap* to give +extra privilleges to opensips binary: + + +```c +setcap 'cap_net_bind_service=+ep' /usr/local/sbin/opensips + +``` + + +## Developer Guide + + +### Available Functions + + +#### register_httpdcb (module, root_path, httpd_acces_handler_cb, httpd_flush_data_cb, httpd_init_proc_cb) + + +Register a new http root with it's associated callbacks into the httpd module. + + +Meaning of the parameters is as follows: + + +- *const char *mod* + - name of the module that register an http root path to be handled; +- *str *root_path* + - the registered root path; +- *httpd_acces_handler_cb f1* + - handler to the callback method to be called on root path match; +- *httpd_flush_data_cb f2* + - handler to the callback method to be called for sending extra data (at a later time); +- *httpd_init_proc_cb f3* + - handler to the callback method to be called during httpd process init; + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/httpd/doc/contributors.xml b/modules/httpd/doc/contributors.xml deleted file mode 100644 index 81e6a866781..00000000000 --- a/modules/httpd/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 48 - 30 - 1667 - 147 - - - 2. - Razvan Crainea (@razvancrainea) - 24 - 21 - 118 - 68 - - - 3. - Liviu Chircu (@liviuchircu) - 23 - 19 - 172 - 82 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 14 - 12 - 103 - 54 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 10 - 7 - 52 - 89 - - - 6. - Ionut Ionita (@ionutrazvanionita) - 8 - 6 - 65 - 21 - - - 7. - Vlad Paiu (@vladpaiu) - 4 - 2 - 68 - 16 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - 9. - Alexandra Titoc - 4 - 2 - 2 - 1 - - - 10. - Fabian Gast (@fgast) - 4 - 1 - 150 - 3 - - - -
-All remaining contributors: Stephane Alnet, Stas Kobzar, Dusan Klinec (@ph4r05), Ken Rice, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Vlad Paiu (@vladpaiu) - Dec 2024 - Dec 2024 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Razvan Crainea (@razvancrainea) - Mar 2015 - Oct 2021 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2013 - Aug 2021 - - - 8. - Fabian Gast (@fgast) - Aug 2020 - Aug 2020 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 10. - Ovidiu Sas (@ovidiusas) - Jan 2012 - Jan 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Dusan Klinec (@ph4r05), Stas Kobzar, Stephane Alnet. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Fabian Gast (@fgast), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/httpd/doc/httpd.xml b/modules/httpd/doc/httpd.xml deleted file mode 100644 index 6868855eaba..00000000000 --- a/modules/httpd/doc/httpd.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - httpd Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2012-2013 VoIP Embedded, Inc. - - - diff --git a/modules/httpd/doc/httpd_admin.xml b/modules/httpd/doc/httpd_admin.xml deleted file mode 100644 index 2174d8f8b2a..00000000000 --- a/modules/httpd/doc/httpd_admin.xml +++ /dev/null @@ -1,335 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides an HTTP transport layer for &osips;. - - - Implementation of httpd module's http server is based on - libmicrohttpd library. - -
- -
- Overview - - TLS for the http server is enabled by setting the tls_cert_file - and tls_key_file parameters. If this is enabled, support for plain - http is disabled. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libmicrohttpd, with EPOLL support. This - typically means a version newer than 0.9.50. - - - - - - WARNING! Please be aware about an - EPOLL support regression in the libmicrohttpd - library and packaging which affects the OpenSIPS httpd module, which - was fixed according to the below timeline. The effect of the - regression is that the HTTP reply body is sometimes - never written by the library, causing the client (e.g. opensips-cli) - to hang indefinitely waiting for it: - - - - versions 0.9.51 - 0.9.52 - have been tested and work correctly - - - - - regression introduced in 0.9.53 (Apr 2017), - lasting until 0.9.71 (May 2020) - - - - - regression is fixed since 0.9.72 (Dec 2020) - - - - - - -
-
- -
- Exported Parameters -
- <varname>ip</varname>(string) - - The IP address used by the HTTP server to listen for incoming - requests. - - - The default value is "*" (bind to all IPv6 and IPv4 interfaces). - - - Set <varname>ip</varname> parameter - -... -modparam("httpd", "ip", "127.0.0.1") -... - - -
-
- <varname>port</varname>(integer) - - The port number used by the HTTP server to listen for incoming - requests. - - - The default value is 8888. - Ports lower than 1024 are not accepted. - - - Set <varname>port</varname> parameter - -... -modparam("httpd", "port", 8000) -... - - -
- -
- <varname>conn_timeout</varname>(integer) - - Auto-close TCP connections which are idle for more than the designated - timeout, in seconds. Set to zero to never close any connections. - - - Note: the connection auto-close routine only seems to be executed - in an "on-demand" fashion, during an HTTPD network event (e.g. on a new - connection), which although not ideal, it should be good enough in - practical terms. - - - The default timeout is 30 seconds. - - - Set <varname>conn_timeout</varname> parameter - -... -modparam("httpd", "conn_timeout", 10) -... - - -
- -
- <varname>buf_size</varname> (integer) - - It specifies the maximum length (in bytes) of the buffer - used to write in the html response. - - - If the size of the buffer is set to zero, it will be automatically - set to a quarter of the size of the pkg memory. - - - The default value is 0. - - - Set <varname>buf_size</varname> parameter - -... -modparam("httpd", "buf_size", 524288) -... - - -
-
- <varname>post_buf_size</varname> (integer) - - It specifies the length (in bytes) of the POST HTTP requests - processing buffer. For large POST request, the default value - might require to be increased. - - - The default value is 1024. The minumal value is 256. - - - Set <varname>post_buf_size</varname> parameter - -... -modparam("httpd", "post_buf_size", 4096) -... - - -
- -
- <varname>receive_buf_size</varname> (integer) - - It specifies the maximum length (in bytes) of the received HTTP requests. - For receiving large POST request, the default value might require to be increased. - - - The default value is 1024. - - - Set <varname>receive_buf_size</varname> parameter - -... -modparam("httpd", "receive_buf_size", 4096) -... - - -
-
- <varname>tls_cert_file</varname> (string) - - Public certificate file for httpd. It will be used as server-side certificate for incoming TLS connections. - - - The default value is "" - - - Set <varname>tls_cert_file</varname> parameter - -... -modparam("httpd", "tls_cert_file", "/etc/opensips/tls/server.pem") -... - - -
-
- <varname>tls_key_file</varname> (string) - - Private key of the above certificate. I must be kept in a safe place with tight permissions! - - - The default value is "" - - - Set <varname>tls_key_file</varname> parameter - -... -modparam("httpd", "tls_key_file", "/etc/opensips/tls/server.key") -... - - -
-
- <varname>tls_ciphers</varname> (string) - - You can specify the list of algorithms for authentication and encryption that you allow. - To obtain a list of ciphers - and then choose, use the gnutls-cli application: - - - - gnutls-cli -l - - - - Do not use the NULL algorithms (no encryption) ... never!!! - - - - The default value is "SECURE256:+SECURE192:-VERS-ALL:+VERS-TLS1.2" - - - Set <varname>tls_key_file</varname> parameter - -... -modparam("httpd", "tls_ciphers", "SECURE256:+SECURE192:-VERS-ALL:+VERS-TLS1.2") -... - - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">httpd_list_root_path</function> - - Lists all the registered http root paths into the httpd module. - When a request comes in, if the root parth is in the list, - the request will be sent to the module that register it. - - - Name: httpd_list_root_path - - Parameters: none - - MI FIFO Command Format: - - -opensips-cli -x mi httpd_list_root_path - -
-
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Known issues - - Due to the fact that &osips; is a multiprocess application, - the microhttpd library is used in "external select" mode. - This ensures that the library is not running in - multithread mode and the library is entirely controled - by &osips;. Due to this particular mode of operations, - for now, the entire http response is built in a pre-allocated - buffer (see buf_size parameter). - - - Future realeases of this module will address this issue. - - - Running the http daemon as non root on ports below 1024 is - forbidden by default in linux (kernel>=2.6.24). - To allow the port binding, one can use - setcap to give - extra privilleges to opensips binary: - -setcap 'cap_net_bind_service=+ep' /usr/local/sbin/opensips - - -
- -
- diff --git a/modules/httpd/doc/httpd_devel.xml b/modules/httpd/doc/httpd_devel.xml deleted file mode 100644 index 8b167336bcc..00000000000 --- a/modules/httpd/doc/httpd_devel.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - &develguide; -
- Available Functions - -
- - <function moreinfo="none">register_httpdcb (module, root_path, httpd_acces_handler_cb, httpd_flush_data_cb, httpd_init_proc_cb)</function> - - - Register a new http root with it's associated callbacks into the httpd module. - - Meaning of the parameters is as follows: - - - const char *mod - - name of the module that register an http root path to be handled; - - - - str *root_path - - the registered root path; - - - - httpd_acces_handler_cb f1 - - handler to the callback method to be called on root path match; - - - - httpd_flush_data_cb f2 - - handler to the callback method to be called for sending extra data (at a later time); - - - - httpd_init_proc_cb f3 - - handler to the callback method to be called during httpd process init; - - - -
- -
- -
- diff --git a/modules/httpd/httpd_proc.c b/modules/httpd/httpd_proc.c index 0d4b43f207d..708e00b40dc 100644 --- a/modules/httpd/httpd_proc.c +++ b/modules/httpd/httpd_proc.c @@ -290,13 +290,18 @@ static MHD_RET post_iterator (void *cls, LM_DBG("[%.*s]->[%.*s]\n", key_len, key, (int)size, value); kv = (str_str_t*)slinkedl_append(pr->p_list, - sizeof(str_str_t) + key_len + size); + sizeof(str_str_t) + key_len + size + 1); + if (!kv) { + LM_ERR("oom\n"); + pr->status = -1; return MHD_NO; + } p = (char*)(kv + 1); kv->key.len = key_len; kv->key.s = p; memcpy(p, key, key_len); p += key_len; kv->val.len = size; kv->val.s = p; memcpy(p, value, size); + p[size] = '\0'; LM_DBG("inserting element pr=[%p] pp=[%p] p_list=[%p]\n", pr, pr->pp, pr->p_list); @@ -567,7 +572,11 @@ MHD_RET answer_to_connection (void *cls, struct MHD_Connection *connection, /* Save the entire body as the '1' key */ kv = (str_str_t*)slinkedl_append(pr->p_list, sizeof(str_str_t) + 1 + - *upload_data_size); + *upload_data_size + 1); + if (!kv) { + LM_ERR("oom\n"); + return MHD_NO; + } p = (char*)(kv + 1); kv->key.len = 1; kv->key.s = p; memcpy(p, "1", 1); @@ -575,6 +584,7 @@ MHD_RET answer_to_connection (void *cls, struct MHD_Connection *connection, kv->val.len = *upload_data_size; kv->val.s = p; memcpy(p, upload_data, *upload_data_size); + p[*upload_data_size] = '\0'; break; default: LM_ERR("Unhandled data for ContentType [%d]\n", diff --git a/modules/identity/README b/modules/identity/README deleted file mode 100644 index d433fc39459..00000000000 --- a/modules/identity/README +++ /dev/null @@ -1,410 +0,0 @@ -Identity Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. privKey (string) - 1.3.2. authCert (string) - 1.3.3. certUri (string) - 1.3.4. verCert (string) - 1.3.5. caList (string) - 1.3.6. crlList (string) - 1.3.7. useCrls (integer) - - 1.4. Exported Functions - - 1.4.1. authservice() - 1.4.2. verifier() - - 1.5. Known Limitations - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set privKey parameter - 1.2. Set authCert parameter - 1.3. Set certUri parameter - 1.4. Set verCert parameter - 1.5. Set caList parameter - 1.6. Set crlList parameter - 1.7. Set privKey parameter - 1.8. authservice() usage - 1.9. verifier() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module adds support for SIP Identity (see RFC 4474). - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * openssl (libssl). - -1.3. Exported Parameters - -1.3.1. privKey (string) - - Filename of private RSA-key of authentication service. This - file must be in PEM format. - - Example 1.1. Set privKey parameter -... -modparam("identity", "privKey", "/etc/openser/privkey.pem") -... - -1.3.2. authCert (string) - - Filename of certificate which belongs to privKey. This file - must be in PEM format. - - Example 1.2. Set authCert parameter -... -modparam("identity", "authCert", "/etc/openser/cert.pem") -... - -1.3.3. certUri (string) - - URI from which the certificate of the authentication service - can be acquired. This string will be placed in the - Identity-Info header. - - Example 1.3. Set certUri parameter -... -modparam("identity", "certUri", "http://www.myserver.com/cert.pem") -... - -1.3.4. verCert (string) - - Path containing certificates for the verifier. Certificates - must be in PEM format. The URI in the Identity-Info header - field is used to find the corresponding certificate for the - request. For this purpose the verifier replaces every character - which is not alphanumeric, no “_” and no “.” with a “-”. A “.” - at the beginning of the URI is forbidden. If the URI is - “http://www.test.com/cert.pem” the verifier will look for the - file “http---www.test.com-cert.pem”, for example. It is also - possible to store a whole certificate chain in a file. In this - case certificates must be in right order, end certificate - first. - - Example 1.4. Set verCert parameter -... -modparam("identity", "verCert", "/etc/openser/verCert/") -... - -1.3.5. caList (string) - - File containing all trusted (root) certificates for the - verifier. Certificates must be in PEM format. - - Example 1.5. Set caList parameter -... -modparam("identity", "caList", "/etc/openser/caList.pem") -... - -1.3.6. crlList (string) - - File containing certificate revocation lists (crls) for the - verifier. Setting this parameter is only necessary if useCrls - is set to “1”. - - Example 1.6. Set crlList parameter -... -modparam("identity", "crlList", "/etc/openser/crls.pem") -... - -1.3.7. useCrls (integer) - - Switch to decide whether to use revocation lists (“1”) or not - (“0”). - - Default value is “0”. - - Example 1.7. Set privKey parameter -... -modparam("identity", "useCrls", 1) -... - -1.4. Exported Functions - -1.4.1. authservice() - - This function performs the steps of an authentication service. - Before you call this function, you have to ensure that - * the server is responsible for this request (from URI - matches local SIP domain) - * the sender of the request is authorized to claim the - identity given in the From header field. - - This function returns the following values: - * -3: Date header field does not match validity period of - cert. Identity header has not been added. - * -2: message out of time (e.g. message to old), Identity - header has not been added. - * -1: An error occurred. - * 1: everything OK, Identity header has been added. - - This function can be used from REQUEST_ROUTE. - - Example 1.8. authservice() usage -... -# CANCEL and ACK cannot be challenged -if (($rm=="CANCEL") || ($rm"ACK")) -{ - route(1); # forward - exit; -} - -# some clients (e.g. Kphone) do not answer, when a BYE is challenged -if ($rm=="BYE") -{ - route(1); # forward - exit; -} - -### Authentication Service ### - -# check whether I am authoritative -if($fd!="mysipdomain.de") -{ - route(1); # forward - exit; -} - -if(!proxy_authorize("mysipdomain.de","subscriber")) -{ - proxy_challenge("mysipdomain.de",0); - exit; -} - -if ($au!=$fU) -{ - sl_send_reply(403, "Use From=ID"); - exit; -} -consume_credentials(); - -authservice(); -switch($retcode) -{ - case -3: - xlog("L_DBG" ,"authservice: Date header field does not match val -idity period of cert\n"); - break; - case -2: - xlog("L_DBG" ,"authservice: msg out of time (max. +- 10 minutes -allowed)\n"); - break; - case -1: - xlog("L_DBG" ,"authservice: ERROR, returnvalue: -1\n"); - break; - case 1: - xlog("L_DBG" ,"authservice: everything OK\n"); - break; - default: - xlog("L_DBG" ,"unknown returnvalue of authservice\n"); - -} - -route(1); #forward with ($retcode=1) or without ($retcode!=1) Identity h -eader -... - -1.4.2. verifier() - - This function performs the steps of an verifier. The returned - code tells you the result of the verification: - * -438: Signature does not correspond to the message. - 438-response should be send. - * -437: Certificate cannot be validated. 437-response should - be send. - * -436: Certificate is not available. 436-response should be - send. - * -428: Message does not have an Identity header. - 428-response should be send. - * -3: Error verifying Date header field. - * -2: Authentication service is not authoritative. - * -1: An unknown error occurred. - * 1: verification OK - - This function can be used from REQUEST_ROUTE. - - Example 1.9. verifier() usage -... -# we have to define the same exceptions as we did for the authentication - service -if (($rm=="CANCEL") || ($rm"ACK")) -{ - route(1); # forward - exit; -} - -if ($rm=="BYE") -{ - route(1); # forward - exit; -} - -verifier(); -switch($retcode) -{ - case -438: - xlog("L_DBG" ,"verifier: returnvalue: -438\n"); - sl_send_reply(438, "Invalid Identity Header"); - exit; - break; - case -437: - xlog("L_DBG" ,"verifier: returnvalue: -437\n"); - sl_send_reply(437, "Unsupported Certificate"); - exit; - break; - case -436: - xlog("L_DBG" ,"verifier: returnvalue: -436\n"); - sl_send_reply(436, "Bad Identity-Info"); - exit; - break; - case -428: - xlog("L_DBG" ,"verifier: returnvalue: -428\n"); - sl_send_reply(428, "Use Identity Header"); - exit; - break; - case -3: - xlog("L_DBG" ,"verifier: error verifying Date header field\n"); - exit; - break; - case -2: - xlog("L_DBG" ,"verifier: authentication service is not authorita -tive\n"); - exit; - break; - case -1: - xlog("L_DBG" ,"verifier: ERROR, returnvalue: -1\n"); - exit; - break; - case 1: - xlog("L_DBG" ,"verifier: verification OK\n"); - route(1); # forward - exit; - break; - default: - xlog("L_DBG" ,"unknown returnvalue of verifier\n"); - exit; -} -exit; -... - -1.5. Known Limitations - - * Certificates are not downloaded. They have to be stored - locally. - * Call-IDs of valid requests containing an Identity header - are not recorded. Hence the verifier does not provide full - replay protection. - * Authentication service and verifier use the original - request. Changes resulting from message processing in - OpenSER script are ignored. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Alexander Christ 23 1 2571 0 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 14 12 28 19 - 3. Liviu Chircu (@liviuchircu) 12 9 23 69 - 4. Razvan Crainea (@razvancrainea) 11 9 82 24 - 5. Vlad Patrascu (@rvlad-patrascu) 6 4 15 16 - 6. Sergio Gutierrez 4 2 7 2 - 7. Maksym Sobolyev (@sobomax) 4 2 3 20 - 8. Alexandra Titoc 3 2 7 0 - 9. Ovidiu Sas (@ovidiusas) 3 1 18 2 - 10. Julián Moreno Patiño 3 1 2 2 - - All remaining contributors: Peter Lemenkov (@lemenkov), Saúl - Ibarra Corretgé (@saghul). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Sep 2020 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Jan 2021 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2009 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Saúl Ibarra Corretgé (@saghul) Oct 2014 - Oct 2014 - 10. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - - All remaining contributors: Sergio Gutierrez, Alexander Christ. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Alexander Christ. - - Documentation Copyrights: - - Copyright © 2007 Alexander Christ, Cologne University of - Applied Sciences diff --git a/modules/identity/README.md b/modules/identity/README.md new file mode 100644 index 00000000000..a133e00db15 --- /dev/null +++ b/modules/identity/README.md @@ -0,0 +1,309 @@ +--- +title: "Identity Module" +description: "This module adds support for SIP Identity (see RFC 4474)." +--- + +## Admin Guide + + +### Overview + + +This module adds support for SIP Identity (see RFC 4474). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *openssl (libssl)*. + + +### Exported Parameters + + +#### privKey (string) + + +Filename of private RSA-key of authentication service. This file must be in PEM format. + + +```opensips title="Set privKey parameter" +... +modparam("identity", "privKey", "/etc/openser/privkey.pem") +... +``` + + +#### authCert (string) + + +Filename of certificate which belongs to `privKey`. This file must be in PEM format. + + +```opensips title="Set authCert parameter" +... +modparam("identity", "authCert", "/etc/openser/cert.pem") +... +``` + + +#### certUri (string) + + +URI from which the certificate of the authentication service can be acquired. This string will be placed in the Identity-Info header. + + +```opensips title="Set certUri parameter" +... +modparam("identity", "certUri", "http://www.myserver.com/cert.pem") +... +``` + + +#### verCert (string) + + +Path containing certificates for the verifier. Certificates must be in PEM format. The URI in the Identity-Info header field is used to find the corresponding certificate for the request. For this purpose the verifier replaces every character which is not alphanumeric, no "_" and no "." with a "-". A "." at the beginning of the URI is forbidden. If the URI is "http://www.test.com/cert.pem" the verifier will look for the file "http---www.test.com-cert.pem", for example. +It is also possible to store a whole certificate chain in a file. In this case certificates must be in right order, end certificate first. + + +```opensips title="Set verCert parameter" +... +modparam("identity", "verCert", "/etc/openser/verCert/") +... +``` + + +#### caList (string) + + +File containing all trusted (root) certificates for the verifier. Certificates must be in PEM format. + + +```opensips title="Set caList parameter" +... +modparam("identity", "caList", "/etc/openser/caList.pem") +... +``` + + +#### crlList (string) + + +File containing certificate revocation lists (crls) for the verifier. Setting this parameter is only necessary if `useCrls` is set to "1". + + +```opensips title="Set crlList parameter" +... +modparam("identity", "crlList", "/etc/openser/crls.pem") +... +``` + + +#### useCrls (integer) + + +Switch to decide whether to use revocation lists ("1") or not ("0"). + + +*Default value is "0".* + + +```opensips title="Set privKey parameter" +... +modparam("identity", "useCrls", 1) +... +``` + + +### Exported Functions + + +#### authservice() + + +This function performs the steps of an authentication service. Before you call this function, you have to ensure +that + + +- the server is responsible for this request (from URI matches local SIP domain) +- the sender of the request is authorized to claim the identity given in the From header field. + + +- -3: Date header field does not match validity period of cert. Identity header has not been added. +- -2: message out of time (e.g. message to old), Identity header has not been added. +- -1: An error occurred. +- 1: everything OK, Identity header has been added. + + +```opensips title="authservice() usage" +... +# CANCEL and ACK cannot be challenged +if (($rm=="CANCEL") || ($rm"ACK")) +{ + route(1); # forward + exit; +} + +# some clients (e.g. Kphone) do not answer, when a BYE is challenged +if ($rm=="BYE") +{ + route(1); # forward + exit; +} + +### Authentication Service ### + +# check whether I am authoritative +if($fd!="mysipdomain.de") +{ + route(1); # forward + exit; +} + +if(!proxy_authorize("mysipdomain.de","subscriber")) +{ + proxy_challenge("mysipdomain.de",0); + exit; +} + +if ($au!=$fU) +{ + sl_send_reply(403, "Use From=ID"); + exit; +} +consume_credentials(); + +authservice(); +switch($retcode) +{ + case -3: + xlog("L_DBG" ,"authservice: Date header field does not match validity period of cert\n"); + break; + case -2: + xlog("L_DBG" ,"authservice: msg out of time (max. +- 10 minutes allowed)\n"); + break; + case -1: + xlog("L_DBG" ,"authservice: ERROR, returnvalue: -1\n"); + break; + case 1: + xlog("L_DBG" ,"authservice: everything OK\n"); + break; + default: + xlog("L_DBG" ,"unknown returnvalue of authservice\n"); + +} + +route(1); #forward with ($retcode=1) or without ($retcode!=1) Identity header +... +``` + + +#### verifier() + + +This function performs the steps of an verifier. The returned code tells you the result of the verification: + + +- -438: Signature does not correspond to the message. 438-response should be send. +- -437: Certificate cannot be validated. 437-response should be send. +- -436: Certificate is not available. 436-response should be send. +- -428: Message does not have an Identity header. 428-response should be send. +- -3: Error verifying Date header field. +- -2: Authentication service is not authoritative. +- -1: An unknown error occurred. +- 1: verification OK + + +```opensips title="verifier() usage" +... +# we have to define the same exceptions as we did for the authentication service +if (($rm=="CANCEL") || ($rm"ACK")) +{ + route(1); # forward + exit; +} + +if ($rm=="BYE") +{ + route(1); # forward + exit; +} + +verifier(); +switch($retcode) +{ + case -438: + xlog("L_DBG" ,"verifier: returnvalue: -438\n"); + sl_send_reply(438, "Invalid Identity Header"); + exit; + break; + case -437: + xlog("L_DBG" ,"verifier: returnvalue: -437\n"); + sl_send_reply(437, "Unsupported Certificate"); + exit; + break; + case -436: + xlog("L_DBG" ,"verifier: returnvalue: -436\n"); + sl_send_reply(436, "Bad Identity-Info"); + exit; + break; + case -428: + xlog("L_DBG" ,"verifier: returnvalue: -428\n"); + sl_send_reply(428, "Use Identity Header"); + exit; + break; + case -3: + xlog("L_DBG" ,"verifier: error verifying Date header field\n"); + exit; + break; + case -2: + xlog("L_DBG" ,"verifier: authentication service is not authoritative\n"); + exit; + break; + case -1: + xlog("L_DBG" ,"verifier: ERROR, returnvalue: -1\n"); + exit; + break; + case 1: + xlog("L_DBG" ,"verifier: verification OK\n"); + route(1); # forward + exit; + break; + default: + xlog("L_DBG" ,"unknown returnvalue of verifier\n"); + exit; +} +exit; +... +``` + + +### Known Limitations + + +- Certificates are not downloaded. They have to be stored locally. +- Call-IDs of valid requests containing an Identity header are not recorded. +Hence the verifier does not provide full replay protection. +- Authentication service and verifier use the original request. Changes resulting from message processing in OpenSER script are ignored. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/identity/doc/contributors.xml b/modules/identity/doc/contributors.xml deleted file mode 100644 index a8f61227f7b..00000000000 --- a/modules/identity/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Alexander Christ - 23 - 1 - 2571 - 0 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 14 - 12 - 28 - 19 - - - 3. - Liviu Chircu (@liviuchircu) - 12 - 9 - 23 - 69 - - - 4. - Razvan Crainea (@razvancrainea) - 11 - 9 - 82 - 24 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 15 - 16 - - - 6. - Sergio Gutierrez - 4 - 2 - 7 - 2 - - - 7. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 20 - - - 8. - Alexandra Titoc - 3 - 2 - 7 - 0 - - - 9. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 18 - 2 - - - 10. - Julián Moreno Patiño - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Saúl Ibarra Corretgé (@saghul). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Sep 2020 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Jan 2021 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2009 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Saúl Ibarra Corretgé (@saghul) - Oct 2014 - Oct 2014 - - - 10. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - -
-All remaining contributors: Sergio Gutierrez, Alexander Christ. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Alexander Christ. -
- -
diff --git a/modules/identity/doc/identity.xml b/modules/identity/doc/identity.xml deleted file mode 100644 index c9f4a5b1794..00000000000 --- a/modules/identity/doc/identity.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - Identity Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Alexander Christ, Cologne University of Applied Sciences - - - diff --git a/modules/identity/doc/identity_admin.xml b/modules/identity/doc/identity_admin.xml deleted file mode 100644 index 470161287bc..00000000000 --- a/modules/identity/doc/identity_admin.xml +++ /dev/null @@ -1,416 +0,0 @@ - - - - - &adminguide; - -
- Overview - This module adds support for SIP Identity (see RFC 4474). -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - openssl (libssl). - - - - -
-
-
- Exported Parameters - - - -
- <varname>privKey</varname> (string) - - Filename of private RSA-key of authentication service. This file must be in PEM format. - - - - Set <varname>privKey</varname> parameter - -... -modparam("identity", "privKey", "/etc/openser/privkey.pem") -... - - -
- - - -
- <varname>authCert</varname> (string) - - Filename of certificate which belongs to privKey. This file must be in PEM format. - - - - Set <varname>authCert</varname> parameter - -... -modparam("identity", "authCert", "/etc/openser/cert.pem") -... - - -
- - -
- <varname>certUri</varname> (string) - - URI from which the certificate of the authentication service can be acquired. This string will be placed in the Identity-Info header. - - - - Set <varname>certUri</varname> parameter - -... -modparam("identity", "certUri", "http://www.myserver.com/cert.pem") -... - - -
- - -
- <varname>verCert</varname> (string) - - Path containing certificates for the verifier. Certificates must be in PEM format. The URI in the Identity-Info header field is used to find the corresponding certificate for the request. For this purpose the verifier replaces every character which is not alphanumeric, no _ and no . with a -. A . at the beginning of the URI is forbidden. If the URI is http://www.test.com/cert.pem the verifier will look for the file http---www.test.com-cert.pem, for example. - It is also possible to store a whole certificate chain in a file. In this case certificates must be in right order, end certificate first. - - - - Set <varname>verCert</varname> parameter - -... -modparam("identity", "verCert", "/etc/openser/verCert/") -... - - -
- - -
- <varname>caList</varname> (string) - - File containing all trusted (root) certificates for the verifier. Certificates must be in PEM format. - - - - Set <varname>caList</varname> parameter - -... -modparam("identity", "caList", "/etc/openser/caList.pem") -... - - -
- - -
- <varname>crlList</varname> (string) - - File containing certificate revocation lists (crls) for the verifier. Setting this parameter is only necessary if useCrls is set to 1. - - - - Set <varname>crlList</varname> parameter - -... -modparam("identity", "crlList", "/etc/openser/crls.pem") -... - - -
- - -
- <varname>useCrls</varname> (integer) - - Switch to decide whether to use revocation lists (1) or not (0). - - - - Default value is 0. - - - - - Set <varname>privKey</varname> parameter - -... -modparam("identity", "useCrls", 1) -... - - -
- - -
-
- Exported Functions - -
- - <function moreinfo="none">authservice()</function> - - - This function performs the steps of an authentication service. Before you call this function, you have to ensure - that - - - - the server is responsible for this request (from URI matches local SIP domain) - - - - the sender of the request is authorized to claim the identity given in the From header field. - - - - - This function returns the following values: - - - -3: Date header field does not match validity period of cert. Identity header has not been added. - - - - -2: message out of time (e.g. message to old), Identity header has not been added. - - - - -1: An error occurred. - - - - 1: everything OK, Identity header has been added. - - - - This function can be used from REQUEST_ROUTE. - - <function>authservice()</function> usage - -... -# CANCEL and ACK cannot be challenged -if (($rm=="CANCEL") || ($rm"ACK")) -{ - route(1); # forward - exit; -} - -# some clients (e.g. Kphone) do not answer, when a BYE is challenged -if ($rm=="BYE") -{ - route(1); # forward - exit; -} - -### Authentication Service ### - -# check whether I am authoritative -if($fd!="mysipdomain.de") -{ - route(1); # forward - exit; -} - -if(!proxy_authorize("mysipdomain.de","subscriber")) -{ - proxy_challenge("mysipdomain.de",0); - exit; -} - -if ($au!=$fU) -{ - sl_send_reply(403, "Use From=ID"); - exit; -} -consume_credentials(); - -authservice(); -switch($retcode) -{ - case -3: - xlog("L_DBG" ,"authservice: Date header field does not match validity period of cert\n"); - break; - case -2: - xlog("L_DBG" ,"authservice: msg out of time (max. +- 10 minutes allowed)\n"); - break; - case -1: - xlog("L_DBG" ,"authservice: ERROR, returnvalue: -1\n"); - break; - case 1: - xlog("L_DBG" ,"authservice: everything OK\n"); - break; - default: - xlog("L_DBG" ,"unknown returnvalue of authservice\n"); - -} - -route(1); #forward with ($retcode=1) or without ($retcode!=1) Identity header -... - - -
- - -
- - <function moreinfo="none">verifier()</function> - - - This function performs the steps of an verifier. The returned code tells you the result of the verification: - - - - -438: Signature does not correspond to the message. 438-response should be send. - - - - -437: Certificate cannot be validated. 437-response should be send. - - - - -436: Certificate is not available. 436-response should be send. - - - - -428: Message does not have an Identity header. 428-response should be send. - - - - -3: Error verifying Date header field. - - - - -2: Authentication service is not authoritative. - - - - -1: An unknown error occurred. - - - - 1: verification OK - - - - This function can be used from REQUEST_ROUTE. - - <function>verifier()</function> usage - -... -# we have to define the same exceptions as we did for the authentication service -if (($rm=="CANCEL") || ($rm"ACK")) -{ - route(1); # forward - exit; -} - -if ($rm=="BYE") -{ - route(1); # forward - exit; -} - -verifier(); -switch($retcode) -{ - case -438: - xlog("L_DBG" ,"verifier: returnvalue: -438\n"); - sl_send_reply(438, "Invalid Identity Header"); - exit; - break; - case -437: - xlog("L_DBG" ,"verifier: returnvalue: -437\n"); - sl_send_reply(437, "Unsupported Certificate"); - exit; - break; - case -436: - xlog("L_DBG" ,"verifier: returnvalue: -436\n"); - sl_send_reply(436, "Bad Identity-Info"); - exit; - break; - case -428: - xlog("L_DBG" ,"verifier: returnvalue: -428\n"); - sl_send_reply(428, "Use Identity Header"); - exit; - break; - case -3: - xlog("L_DBG" ,"verifier: error verifying Date header field\n"); - exit; - break; - case -2: - xlog("L_DBG" ,"verifier: authentication service is not authoritative\n"); - exit; - break; - case -1: - xlog("L_DBG" ,"verifier: ERROR, returnvalue: -1\n"); - exit; - break; - case 1: - xlog("L_DBG" ,"verifier: verification OK\n"); - route(1); # forward - exit; - break; - default: - xlog("L_DBG" ,"unknown returnvalue of verifier\n"); - exit; -} -exit; -... - - -
- - -
-
- Known Limitations - - - - - Certificates are not downloaded. They have to be stored locally. - - - - Call-IDs of valid requests containing an Identity header are not recorded. - Hence the verifier does not provide full replay protection. - - - - Authentication service and verifier use the original request. Changes resulting from message processing in OpenSER script are ignored. - - - - - -
-
- diff --git a/modules/imc/README b/modules/imc/README deleted file mode 100644 index bfcad81cd97..00000000000 --- a/modules/imc/README +++ /dev/null @@ -1,388 +0,0 @@ -imc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (str) - 1.3.2. rooms_table (str) - 1.3.3. members_table (str) - 1.3.4. hash_size (integer) - 1.3.5. imc_cmd_start_char (str) - 1.3.6. outbound_proxy (str) - - 1.4. Exported Functions - - 1.4.1. imc_manager() - - 1.5. Exported MI Functions - - 1.5.1. imc_list_rooms - 1.5.2. imc_list_members - - 1.6. Exported Statistics - - 1.6.1. active_rooms - - 1.7. IMC Commands - 1.8. Installation - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set rooms_table parameter - 1.3. Set members_table parameter - 1.4. Set hash_size parameter - 1.5. Set imc_cmd_start_char parameter - 1.6. Set outbound_proxy parameter - 1.7. Usage of imc_manager() function - 1.8. List of commands - -Chapter 1. Admin Guide - -1.1. Overview - - This module offers support for instant message conference. It - follows the architecture of IRC channels, you can send commands - embedded in MESSAGE body, because there are no SIP UA clients - which have GUI for IM conferencing. - - You have to define an URI corresponding to im conferencing - manager, where user can send commands to create a new - conference room. Once the conference room is created, users can - send commands directly to conferece's URI. - - To ease the integration in the configuration file, the - interpreter of the IMC commands are embeded in the module, from - configuration poin of view, there is only one function which - has to be executed for both messages and commands. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * mysql. - * tm. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (str) - - The database url. - - The default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("imc", "db_url", "dbdriver://username:password@dbhost/dbname") -... - -1.3.2. rooms_table (str) - - The name of the table storing IMC rooms. - - The default value is "imc_rooms". - - Example 1.2. Set rooms_table parameter -... -modparam("imc", "rooms_table", "rooms") -... - -1.3.3. members_table (str) - - The name of the table storing IMC members. - - The default value is "imc_members". - - Example 1.3. Set members_table parameter -... -modparam("imc", "rooms_table", "members") -... - -1.3.4. hash_size (integer) - - The power of 2 to get the size of the hash table used for - storing members and rooms. - - The default value is 4 (resultimg in hash size 16). - - Example 1.4. Set hash_size parameter -... -modparam("imc", "hash_size", 8) -... - -1.3.5. imc_cmd_start_char (str) - - The character which indicates that the body of the message is a - command. - - The default value is "#". - - Example 1.5. Set imc_cmd_start_char parameter -... -modparam("imc", "imc_cmd_start_char", "#") -... - -1.3.6. outbound_proxy (str) - - The SIP address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or - when using a separate OpenSIPS instance for imc processing. If - not set, the message will be sent to the address in destination - URI. - - Default value is NULL. - - Example 1.6. Set outbound_proxy parameter -... -modparam("imc", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - -1.4. Exported Functions - -1.4.1. imc_manager() - - Handles Message method.It detects if the body of the message is - a conference command.If so it executes it, otherwise it sends - the message to all the members in the room. - - This function can be used from REQUEST_ROUTE. - - Example 1.7. Usage of imc_manager() function -... -# the rooms will be named chat-xyz to avoid overlapping -# with usernames -if(is_method("MESSAGE) - && ($ru=~ "sip:chat-[0-9]+@" || ($ru=~ "sip:chat-manager@") - imc_manager(); -... - -1.5. Exported MI Functions - -1.5.1. imc_list_rooms - - Lists of the IM Conferencing rooms. - - Name: imc_list_rooms - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi imc_list_rooms - -1.5.2. imc_list_members - - Listing of the members in IM Conferencing rooms. - - Name: imc_list_members - - Parameters: - * room : the room for which you want to list the members - - MI FIFO Command Format: - opensips-cli -x mi imc_list_members sip:chat-000@opensip -s.org - -1.6. Exported Statistics - -1.6.1. active_rooms - - Number of active IM Conferencing rooms. - -1.7. IMC Commands - - A command is identified by the starting character. A command - must be written in one line. By default, the starting character - is '#'. You can change it via "imc_cmd_start_char" parameter. - - Next picture presents the list of commands and their - parameters. - - Example 1.8. List of commands -... - -1.create - -creates a conference room - -takes 2 parameters: - 1) the name of the room - 2)optional- "private" -if present the created room is private - and new members can be added only though invitations - -the user is added as the first member and owner of the room - -eg: #create chat-000 private - -2.join - -makes the user member of a room - -takes one optional parameter - the address of the room -if not - present it will be considered to be the address in the To - header of the message - -if the room does not exist the command is treated as create - -eg:join sip:chat-000@opensips.org, - or just, #join, sent to sip:chat-000@opensips.org - -3.invite - -invites a user to become a member of a room - -takes 2 parameters: - 1)the complete address of the user - 2)the address of the room -if not present it will be considered - to be the address in the To header of the message - -only certain users have the right to invite other user: the owner - and the administrators - -eg: #invite sip:john@opensips.org sip:chat-000@opensips.org - or #invite john@opensips.org sent to sip:chat-000@opensips.org - -4.accept - -accepting an invitation - -takes one optional parameter - the address of the room - if not - present it will be considered to be the address in the To header - of the message - -eg: #accept sip:john@opensips.org - -5.deny - -rejects an invitation - -the parameter is the same as for accept - -6.remove - -deletes a member from a room - -takes 2 parameters: - 1)the complete address of the member - 2)the address of the room -if not present it will be considered - to be the address in the To header of the message - -only certain members have the right to remove other members - -eg: #remove sip:john@opensips.org, sent to sip:chat-000@opensips.org - -7.exit - -leaving a room - -takes one optional parameter - the address of the room - if not - present it will be considered to be the address in the To header - of the message - -if the user is the owner of the room, the room will be destroyed - -8.destroy - -removing a room - -the parameter is the same as for exit - -only the owner of a room has the right to destroy it - -9.list - -list members in a room - -... - -1.8. Installation - - Before running OpenSIPS with IMC, you have to setup the - database tables where the module will store the data. For that, - if the tables were not created by the installation script or - you choose to install everything by yourself you can use the - imc-create.sql SQL script in the database directories in the - opensips/scripts folder as template. You can also find the - complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 43 12 1604 1007 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 42 29 308 548 - 3. Anca Vamanu 32 5 3014 16 - 4. Razvan Crainea (@razvancrainea) 18 16 34 40 - 5. Liviu Chircu (@liviuchircu) 15 12 39 66 - 6. Henning Westerholt (@henningw) 10 7 76 105 - 7. Vlad Patrascu (@rvlad-patrascu) 9 6 75 80 - 8. Elena-Ramona Modroiu 4 2 68 5 - 9. Maksym Sobolyev (@sobomax) 4 2 5 6 - 10. Alexandra Titoc 4 2 4 2 - - All remaining contributors: John Riordan, Sergio Gutierrez, - Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert - Schubert, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - Apr 2020 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Walter Doekes (@wdoekes) May 2014 - May 2014 - 9. John Riordan May 2009 - May 2009 - 10. Sergio Gutierrez Nov 2008 - Nov 2008 - - All remaining contributors: Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Henning Westerholt (@henningw), Anca Vamanu, Elena-Ramona - Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Peter - Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Anca Vamanu, Henning Westerholt (@henningw), - Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2006-2008 Voice Sistem SRL diff --git a/modules/imc/README.md b/modules/imc/README.md new file mode 100644 index 00000000000..fe44828d4e5 --- /dev/null +++ b/modules/imc/README.md @@ -0,0 +1,335 @@ +--- +title: "imc Module" +description: "This module offers support for instant message conference." +--- + +## Admin Guide + + +### Overview + + +This module offers support for instant message conference. It +follows the architecture of IRC channels, you can send commands +embedded in MESSAGE body, because there are no SIP UA clients +which have GUI for IM conferencing. + + +You have to define an URI corresponding to im conferencing manager, where +user can send commands to create a new conference room. Once the conference +room is created, users can send commands directly to conferece's URI. + + +To ease the integration in the configuration file, the interpreter of +the IMC commands are embeded in the module, from configuration poin of +view, there is only one function which has to be executed for both +messages and commands. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *mysql*. +- *tm*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (str) + + +The database url. + + +*The default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("imc", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### rooms_table (str) + + +The name of the table storing IMC rooms. + + +*The default value is "imc_rooms".* + + +```opensips title="Set rooms_table parameter" +... +modparam("imc", "rooms_table", "rooms") +... +``` + + +#### members_table (str) + + +The name of the table storing IMC members. + + +*The default value is "imc_members".* + + +```opensips title="Set members_table parameter" +... +modparam("imc", "rooms_table", "members") +... +``` + + +#### hash_size (integer) + + +The power of 2 to get the size of the hash table used for storing +members and rooms. + + +*The default value is 4 (resultimg in hash size 16).* + + +```opensips title="Set hash_size parameter" +... +modparam("imc", "hash_size", 8) +... +``` + + +#### imc_cmd_start_char (str) + + +The character which indicates that the body of the message is a command. + + +*The default value is "#".* + + +```opensips title="Set imc_cmd_start_char parameter" +... +modparam("imc", "imc_cmd_start_char", "#") +... +``` + + +#### outbound_proxy (str) + + +The SIP address used as next hop when sending the message. Very +useful when using OpenSIPS with a domain name not in DNS, or +when using a separate OpenSIPS instance for imc processing. If +not set, the message will be sent to the address in destination +URI. + + +*Default value is NULL.* + + +```opensips title="Set outbound_proxy parameter" +... +modparam("imc", "outbound_proxy", "sip:opensips.org;transport=tcp") +... +``` + + +### Exported Functions + + +#### imc_manager() + + +Handles Message method.It detects if the body of the message is a +conference command.If so it executes it, otherwise it sends the +message to all the members in the room. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Usage of imc_manager() function" +... +# the rooms will be named chat-xyz to avoid overlapping +# with usernames +if(is_method("MESSAGE) + && ($ru=~ "sip:chat-[0-9]+@" || ($ru=~ "sip:chat-manager@") + imc_manager(); +... +``` + + +### Exported MI Functions + + +#### imc_list_rooms + + +Lists of the IM Conferencing rooms. + + +Name: *imc_list_rooms* + + +Parameters: none + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi imc_list_rooms + +``` + + +#### imc_list_members + + +Listing of the members in IM Conferencing rooms. + + +Name: *imc_list_members* + + +Parameters: + + +- *room* : the room for which you want to list the members + + +MI FIFO Command Format: + + +```bash + opensips-cli -x mi imc_list_members sip:chat-000@opensips.org + +``` + + +### Exported Statistics + + +#### active_rooms + + +Number of active IM Conferencing rooms. + + +### IMC Commands + + +A command is identified by the starting character. A command must be +written in one line. By default, the starting character is '#'. You +can change it via "imc_cmd_start_char" parameter. + + +Next picture presents the list of commands and their parameters. + + +```c title="List of commands" +... + +1.create + -creates a conference room + -takes 2 parameters: + 1) the name of the room + 2)optional- "private" -if present the created room is private + and new members can be added only though invitations + -the user is added as the first member and owner of the room + -eg: #create chat-000 private + +2.join + -makes the user member of a room + -takes one optional parameter - the address of the room -if not + present it will be considered to be the address in the To + header of the message + -if the room does not exist the command is treated as create + -eg:join sip:chat-000@opensips.org, + or just, #join, sent to sip:chat-000@opensips.org + +3.invite + -invites a user to become a member of a room + -takes 2 parameters: + 1)the complete address of the user + 2)the address of the room -if not present it will be considered + to be the address in the To header of the message + -only certain users have the right to invite other user: the owner + and the administrators + -eg: #invite sip:john@opensips.org sip:chat-000@opensips.org + or #invite john@opensips.org sent to sip:chat-000@opensips.org + +4.accept + -accepting an invitation + -takes one optional parameter - the address of the room - if not + present it will be considered to be the address in the To header + of the message + -eg: #accept sip:john@opensips.org + +5.deny + -rejects an invitation + -the parameter is the same as for accept + +6.remove + -deletes a member from a room + -takes 2 parameters: + 1)the complete address of the member + 2)the address of the room -if not present it will be considered + to be the address in the To header of the message + -only certain members have the right to remove other members + -eg: #remove sip:john@opensips.org, sent to sip:chat-000@opensips.org + +7.exit + -leaving a room + -takes one optional parameter - the address of the room - if not + present it will be considered to be the address in the To header + of the message + -if the user is the owner of the room, the room will be destroyed + +8.destroy + -removing a room + -the parameter is the same as for exit + -only the owner of a room has the right to destroy it + +9.list + -list members in a room + +... +``` + + +### Installation + + +Before running OpenSIPS with IMC, you have to setup the database +tables where the module will store the data. For that, if the +tables were not created by the installation script or you choose +to install everything by yourself you can use the imc-create.sql +SQL script in the database directories in the +opensips/scripts folder as template. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/imc/doc/contributors.xml b/modules/imc/doc/contributors.xml deleted file mode 100644 index 3878d6c6966..00000000000 --- a/modules/imc/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 43 - 12 - 1604 - 1007 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 42 - 29 - 308 - 548 - - - 3. - Anca Vamanu - 32 - 5 - 3014 - 16 - - - 4. - Razvan Crainea (@razvancrainea) - 18 - 16 - 34 - 40 - - - 5. - Liviu Chircu (@liviuchircu) - 15 - 12 - 39 - 66 - - - 6. - Henning Westerholt (@henningw) - 10 - 7 - 76 - 105 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 9 - 6 - 75 - 80 - - - 8. - Elena-Ramona Modroiu - 4 - 2 - 68 - 5 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 6 - - - 10. - Alexandra Titoc - 4 - 2 - 4 - 2 - - - -
-All remaining contributors: John Riordan, Sergio Gutierrez, Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - Apr 2020 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - 9. - John Riordan - May 2009 - May 2009 - - - 10. - Sergio Gutierrez - Nov 2008 - Nov 2008 - - - -
-All remaining contributors: Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Anca Vamanu, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Anca Vamanu, Henning Westerholt (@henningw), Elena-Ramona Modroiu. -
- -
diff --git a/modules/imc/doc/imc.xml b/modules/imc/doc/imc.xml deleted file mode 100644 index dfa051cc5fb..00000000000 --- a/modules/imc/doc/imc.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - imc Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006-2008 &voicesystem; - - - diff --git a/modules/imc/doc/imc_admin.xml b/modules/imc/doc/imc_admin.xml deleted file mode 100644 index 982b1ec9b13..00000000000 --- a/modules/imc/doc/imc_admin.xml +++ /dev/null @@ -1,375 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module offers support for instant message conference. It - follows the architecture of IRC channels, you can send commands - embedded in MESSAGE body, because there are no SIP UA clients - which have GUI for IM conferencing. - - - You have to define an URI corresponding to im conferencing manager, where - user can send commands to create a new conference room. Once the conference - room is created, users can send commands directly to conferece's URI. - - - To ease the integration in the configuration file, the interpreter of - the IMC commands are embeded in the module, from configuration poin of - view, there is only one function which has to be executed for both - messages and commands. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - mysql. - - - - - tm. - - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (str) - - The database url. - - - - The default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("imc", "db_url", "&exampledb;") -... - - -
-
- <varname>rooms_table</varname> (str) - - The name of the table storing IMC rooms. - - - - The default value is "imc_rooms". - - - - Set <varname>rooms_table</varname> parameter - -... -modparam("imc", "rooms_table", "rooms") -... - - -
-
- <varname>members_table</varname> (str) - - The name of the table storing IMC members. - - - - The default value is "imc_members". - - - - Set <varname>members_table</varname> parameter - -... -modparam("imc", "rooms_table", "members") -... - - -
-
- <varname>hash_size</varname> (integer) - - The power of 2 to get the size of the hash table used for storing - members and rooms. - - - - The default value is 4 (resultimg in hash size 16). - - - - Set <varname>hash_size</varname> parameter - -... -modparam("imc", "hash_size", 8) -... - - -
-
- <varname>imc_cmd_start_char</varname> (str) - - The character which indicates that the body of the message is a command. - - - - The default value is "#". - - - - Set <varname>imc_cmd_start_char</varname> parameter - -... -modparam("imc", "imc_cmd_start_char", "#") -... - - -
-
- <varname>outbound_proxy</varname> (str) - - The SIP address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or - when using a separate OpenSIPS instance for imc processing. If - not set, the message will be sent to the address in destination - URI. - - - - Default value is NULL. - - - - Set <varname>outbound_proxy</varname> parameter - -... -modparam("imc", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - - -
- -
-
- Exported Functions -
- - <function moreinfo="none">imc_manager()</function> - - - Handles Message method.It detects if the body of the message is a - conference command.If so it executes it, otherwise it sends the - message to all the members in the room. - - - This function can be used from REQUEST_ROUTE. - - - Usage of <varname>imc_manager()</varname> function - -... -# the rooms will be named chat-xyz to avoid overlapping -# with usernames -if(is_method("MESSAGE) - && ($ru=~ "sip:chat-[0-9]+@" || ($ru=~ "sip:chat-manager@") - imc_manager(); -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">imc_list_rooms</function> - - - Lists of the IM Conferencing rooms. - - - Name: imc_list_rooms - - Parameters: none - - - MI FIFO Command Format: - - - opensips-cli -x mi imc_list_rooms - -
- -
- - <function moreinfo="none">imc_list_members</function> - - - Listing of the members in IM Conferencing rooms. - - - Name: imc_list_members - - Parameters: - - room : the room for which you want to list the members - - - - MI FIFO Command Format: - - - opensips-cli -x mi imc_list_members sip:chat-000@opensips.org - -
-
- - -
- Exported Statistics -
- - <function moreinfo="none">active_rooms</function> - - - Number of active IM Conferencing rooms. - - -
-
- - -
- IMC Commands - - A command is identified by the starting character. A command must be - written in one line. By default, the starting character is '#'. You - can change it via "imc_cmd_start_char" parameter. - - - Next picture presents the list of commands and their parameters. - - - - List of commands - -... - -1.create - -creates a conference room - -takes 2 parameters: - 1) the name of the room - 2)optional- "private" -if present the created room is private - and new members can be added only though invitations - -the user is added as the first member and owner of the room - -eg: #create chat-000 private - -2.join - -makes the user member of a room - -takes one optional parameter - the address of the room -if not - present it will be considered to be the address in the To - header of the message - -if the room does not exist the command is treated as create - -eg:join sip:chat-000@opensips.org, - or just, #join, sent to sip:chat-000@opensips.org - -3.invite - -invites a user to become a member of a room - -takes 2 parameters: - 1)the complete address of the user - 2)the address of the room -if not present it will be considered - to be the address in the To header of the message - -only certain users have the right to invite other user: the owner - and the administrators - -eg: #invite sip:john@opensips.org sip:chat-000@opensips.org - or #invite john@opensips.org sent to sip:chat-000@opensips.org - -4.accept - -accepting an invitation - -takes one optional parameter - the address of the room - if not - present it will be considered to be the address in the To header - of the message - -eg: #accept sip:john@opensips.org - -5.deny - -rejects an invitation - -the parameter is the same as for accept - -6.remove - -deletes a member from a room - -takes 2 parameters: - 1)the complete address of the member - 2)the address of the room -if not present it will be considered - to be the address in the To header of the message - -only certain members have the right to remove other members - -eg: #remove sip:john@opensips.org, sent to sip:chat-000@opensips.org - -7.exit - -leaving a room - -takes one optional parameter - the address of the room - if not - present it will be considered to be the address in the To header - of the message - -if the user is the owner of the room, the room will be destroyed - -8.destroy - -removing a room - -the parameter is the same as for exit - -only the owner of a room has the right to destroy it - -9.list - -list members in a room - -... - - -
-
- Installation - - Before running &osips; with IMC, you have to setup the database - tables where the module will store the data. For that, if the - tables were not created by the installation script or you choose - to install everything by yourself you can use the imc-create.sql - SQL script in the database directories in the - opensips/scripts folder as template. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- -
- diff --git a/modules/imc/imc_cmd.c b/modules/imc/imc_cmd.c index b07d7b72009..7a8cba0fb57 100644 --- a/modules/imc/imc_cmd.c +++ b/modules/imc/imc_cmd.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "../../mem/shm_mem.h" #include "../../mem/mem.h" @@ -46,6 +47,26 @@ int imc_send_message(str *src, str *dst, str *headers, str *body); int imc_room_broadcast(imc_room_p room, str *ctype, str *body); void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps); +static int imc_body_print_user(str *body, const char *fmt, str *user) +{ + body->s = imc_body_buf; + body->len = snprintf(body->s, IMC_BUF_SIZE, fmt, user->len, user->s); + + if(body->len < 0) + { + LM_ERR("unable to print message\n"); + body->len = 0; + return -1; + } + if(body->len >= IMC_BUF_SIZE) + { + LM_ERR("buffer size overflow\n"); + body->len = 0; + return -1; + } + return body->len; +} + /** * parse cmd */ @@ -220,10 +241,8 @@ int imc_handle_create(struct sip_msg* msg, imc_cmd_t *cmd, } LM_DBG("added as member [%.*s]\n",member->uri.len, member->uri.s); /* send info message */ - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, - "*** <%.*s> has joined the room", - member->uri.len, member->uri.s); + body.len = imc_body_print_user(&body, + "*** <%.*s> has joined the room", &member->uri); if(body.len>0) imc_room_broadcast(room, &imc_hdr_ctype, &body); @@ -322,9 +341,8 @@ int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd, build_inform: /* send info message */ - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room", - member->uri.len, member->uri.s); + body.len = imc_body_print_user(&body, "*** <%.*s> has joined the room", + &member->uri); if(body.len>0) imc_room_broadcast(room, &imc_hdr_ctype, &body); @@ -549,9 +567,8 @@ int imc_handle_accept(struct sip_msg* msg, imc_cmd_t *cmd, member->flags &= ~IMC_MEMBER_INVITED; /* send info message */ - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room", - member->uri.len, member->uri.s); + body.len = imc_body_print_user(&body, "*** <%.*s> has joined the room", + &member->uri); if(body.len>0) imc_room_broadcast(room, &imc_hdr_ctype, &body); @@ -689,9 +706,8 @@ int imc_handle_remove(struct sip_msg* msg, imc_cmd_t *cmd, member->flags |= IMC_MEMBER_DELETED; imc_del_member(room, &inv_uri.user, &inv_uri.host); - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room", - member->uri.len, member->uri.s); + body.len = imc_body_print_user(&body, "*** <%.*s> has joined the room", + &member->uri); if(body.len>0) imc_room_broadcast(room, &imc_hdr_ctype, &body); @@ -740,10 +756,8 @@ int imc_handle_deny(struct sip_msg* msg, imc_cmd_t *cmd, #if 0 /* send info message */ - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, - "The user [%.*s] has denied the invitation", - src->user.len, src->user.s); + body.len = imc_body_print_user(&body, + "The user [%.*s] has denied the invitation", &src->user); if(body.len>0) imc_send_message(&room->uri, &memeber->uri, &imc_hdr_ctype, &body); #endif @@ -771,8 +785,10 @@ int imc_handle_list(struct sip_msg* msg, imc_cmd_t *cmd, imc_member_p member = 0; imc_member_p imp = 0; str room_name; - str body; + str body = {0, 0}; char *p; + int marker_len; + int entry_len; /* the user wants to leave the room */ room_name = cmd->param[0].s?cmd->param[0]:dst->user; @@ -793,7 +809,43 @@ int imc_handle_list(struct sip_msg* msg, imc_cmd_t *cmd, src->user.len, src->user.s, room_name.len, room_name.s); goto error; } - p = imc_body_buf; + + body.len = sizeof("Members:\n") - 1; + imp = room->members; + while(imp) + { + if((imp->flags&IMC_MEMBER_INVITED)||(imp->flags&IMC_MEMBER_DELETED) + || (imp->flags&IMC_MEMBER_SKIP)) + { + imp = imp->next; + continue; + } + + marker_len = ((imp->flags & IMC_MEMBER_OWNER) || + (imp->flags & IMC_MEMBER_ADMIN)) ? 1 : 0; + if(imp->uri.len > INT_MAX - marker_len - 1) + { + LM_ERR("member uri too large [%d]\n", imp->uri.len); + goto error; + } + entry_len = marker_len + imp->uri.len + 1; + if(entry_len > INT_MAX - 1 - body.len) + { + LM_ERR("member list too large\n"); + goto error; + } + body.len += entry_len; + imp = imp->next; + } + + body.s = pkg_malloc(body.len + 1); + if(body.s == NULL) + { + LM_ERR("no more pkg memory\n"); + goto error; + } + + p = body.s; memcpy(p, "Members:\n", 9); p+=9; imp = room->members; @@ -810,24 +862,25 @@ int imc_handle_list(struct sip_msg* msg, imc_cmd_t *cmd, *p++ = '*'; else if(imp->flags & IMC_MEMBER_ADMIN) *p++ = '~'; - strncpy(p, imp->uri.s, imp->uri.len); + memcpy(p, imp->uri.s, imp->uri.len); p += imp->uri.len; *p++ = '\n'; imp = imp->next; } - imc_release_room(room); - /* write over last '\n' */ *(--p) = 0; - body.s = imc_body_buf; body.len = p-body.s; LM_DBG("members = [%.*s]\n", body.len, body.s); imc_send_message(&room->uri, &member->uri, &imc_hdr_ctype, &body); + pkg_free(body.s); + imc_release_room(room); return 0; error: + if(body.s) + pkg_free(body.s); if(room!=NULL) imc_release_room(room); return -1; @@ -883,10 +936,8 @@ int imc_handle_exit(struct sip_msg* msg, imc_cmd_t *cmd, /* delete user */ member->flags |= IMC_MEMBER_DELETED; imc_del_member(room, &src->user, &src->host); - body.s = imc_body_buf; - body.len = snprintf(body.s, IMC_BUF_SIZE, - "The user [%.*s] has left the room", - src->user.len, src->user.s); + body.len = imc_body_print_user(&body, + "The user [%.*s] has left the room", &src->user); if(body.len>0) imc_room_broadcast(room, &imc_hdr_ctype, &body); } @@ -997,12 +1048,16 @@ int imc_handle_unknown(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst) body.len = snprintf(body.s, IMC_BUF_SIZE, "invalid command '%.*s' - send ''%.*shelp' for details", cmd->name.len, cmd->name.s, imc_cmd_start_str.len, imc_cmd_start_str.s); - - if(body.len<=0) + if(body.len <= 0) { LM_ERR("unable to print message\n"); return -1; } + if(body.len >= IMC_BUF_SIZE) + { + LM_ERR("buffer size overflow\n"); + return -1; + } LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s); tmb.t_request(&imc_msg_type, /* Request method */ @@ -1236,4 +1291,3 @@ void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps) shm_free(*ps->param); return; } - diff --git a/modules/jabber/README b/modules/jabber/README deleted file mode 100644 index 6357135ea9c..00000000000 --- a/modules/jabber/README +++ /dev/null @@ -1,574 +0,0 @@ -jabber Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. New Features - - 1.2. Admin's Guide - 1.3. Admin Guide - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. db_url (string) - 1.5.2. jaddress (string) - 1.5.3. jport (integer) - 1.5.4. jdomain (string) - 1.5.5. aliases (string) - 1.5.6. proxy (string) - 1.5.7. registrar (string) - 1.5.8. workers (integer) - 1.5.9. max_jobs (integer) - 1.5.10. cache_time (integer) - 1.5.11. delay_time (integer) - 1.5.12. sleep_time (integer) - 1.5.13. check_time (integer) - 1.5.14. priority (str) - - 1.6. Exported Functions - - 1.6.1. jab_send_message() - 1.6.2. jab_join_jconf() - 1.6.3. jab_exit_jconf() - 1.6.4. jab_go_online() - 1.6.5. jab_go_offline() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set jaddress parameter - 1.3. Set jport parameter - 1.4. Set jdomain parameter - 1.5. Set jdomain parameter - 1.6. Set proxy parameter - 1.7. Set registrar parameter - 1.8. Set workers parameter - 1.9. Set max_jobs parameter - 1.10. Set cache_time parameter - 1.11. Set delay_time parameter - 1.12. Set sleep_time parameter - 1.13. Set check_time parameter - 1.14. Set priority parameter - 1.15. jab_send_message() usage - 1.16. jab_join_jconf() usage - 1.17. jab_exit_jconf() usage - 1.18. jab_go_online() usage - 1.19. jab_go_offline() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is new version of Jabber module that integrates XODE XML - parser for parsing Jabber messages. That introduces a new - module dependency: expat library. - - Expat is a common XML library and is the fastest available for - Linux/Unix, the second over all, after msxml library. It is - integrated in most of well known Linux distributions. - -1.1.1. New Features - - * Presence support (see doc/xxjab.cfg for a sample cfg file) - (January 2003). - * SIP to Jabber conference support (December 2003). - * Possibility to manage all kinds of Jabber messages - (message/presence/iq) (December 2003). - * Aliases -- Possibility to set host aliases for addresses - (see parameter's desc.) (December 2003). - * Send received SIP MESSAGE messages to different IM networks - (Jabber, ICQ,MSN, AIM, Yahoo) using a Jabber server - (December 2003). - * Send incoming Jabber instant messages as SIP MESSAGE - messages. - * Gateways detection -- Ability to see whether an IM gateway - is up or down. - -1.2. Admin's Guide - -Note - - A more complete guide about SIMPLE2Jabber gateway can be found - at https://opensips.org/. The part below will be removed soon, - only the manual from web will be updated. - - The Jabber server setup is not a subject of this guide. Check - http://www.jabber.org for that. - - Useful scripts, for creating Jabber Gateway database, or for - managing the Jabber accounts form web are located in 'doc' - subdirectory of the module. - - Main steps of using the Jabber gateway: - * Create the MySQL database. - * Setup the local Jabber server. - * Set the module parameter values in cfg file of OpenSIPS, - load the dependent modules, set up the routing rules for - Jabber gateway. - * Run OpenSIPS. - - The administrator of OpenSIPS/Jabber gateway must inform the - users what are the aliases for Jabber/Other IM networks. Other - IMs could be AIM, ICQ, MSN, Yahoo, and so on. - - These aliases depend on the server hostname where runs OpenSIPS - and how local Jabber server is setup. - - Next is presented a use case. Prologue: - * OpenSIPS is running on “server.org”. - * Local Jabber server is running on “jabsrv.server.org”. - * Jabber network alias (first part of “jdomain”) is - “jabber.server.org” - - The aliases for other IM networks must be the same as JID set - in Jabber configuration file for each IM transport. - - The JIDs of Jabber transports must start with the name of the - network. For AIM, JID must start with “aim.”, for ICQ with - “icq” (that because I use icqv7-t), for MSN with “msn.” and for - Yahoo with “yahoo.”. The gateway needs these to find out what - transport is working and which not. For our use case these - could be like “aim.server.org”, “icq.server.org”, - “msn.server.org”, “yahoo.server.org”. - - It is indicated to have these aliases in DNS, thus the client - application can resolve the DNS name. Otherwise there must be - set the outbound proxy to OpenSIPS server. - - *** Routing rules for Jabber gateway First step is to configure - OpenSIPS to recognize messages for Jabber gateway. Look at - “doc/xjab.cfg” to see a sample. The idea is to look in messages - for destination address and if it contains Jabber alias or - other IM alias, that means the message is for Jabber gateway. - - Next step is to find out what means that message for Jabber - gateway. It could be a special message what triggers the - gateway to take an action or is a simple message which should - be delivered to Jabber network (using the method - “jab_send_message”). - - The special messages are for: - * Registering to Jabber server (go online in Jabber - network)--here must be called “jab_go_online” method. - * Leaving the Jabber network (go offline in Jabber - network)--here must be called “jab_go_offline” method. - * Joining a Jabber conference room--here must be called - “jab_join_jconf”. - * Leaving a Jabber conference room--here must be called - “jab_exit_jconf”. - - The destination address must follow the following patterns: - * For Jabber network: - “usernamejabber_server@jabber_alias”. - * For Jabber conference: - “nicknameroomconference_server@jabber_alias”. - * For AIM network: “aim_username@aim_alias”. - * For ICQ network: “icq_number@icq_alias”. - * For MSN network: “msn_usernamemsn_server@msn_alias”. - msn_server can be “msn.com” or “hotmail.com”. - * For YAHOO network: “yahoo_username@yahoo_alias”. - -Note - - “jabber_alias” is the first part of “jdomain”. - -1.3. Admin Guide - - The user must activate his Jabber account associated with his - SIP id. For each other IM network on which he wants to send - messages, he must set an account for that IM network. The - gateway is not able to create new account in foreign networks, - excepting local Jabber server. - - When you want to send a message to someone in other IM network, - you must set the destination of the message according with the - pattern corresponding to that IM network (see last part of - “Admin guide” chapter). - - Sending a message to user@jabber.xxx.org which is in Jabber - network, the destination must be: - userjabber.xxx.org@jabber_alias. - - For someone who is in Yahoo network the destination must be: - user@yahoo_alias - -Note - - The OpenSIPS administrator have to set the Jabber transports - for each IM network in order to be able to send messages to - those networks. The alias of each IM network can be found out - from OpenSIPS admin. - - You cannot send messages from your SIP client to your - associated Jabber account--is something like sending messages - to yourself. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * A database module. - * pa (Optionally) - Presence Agent. - * tm - Transaction Manager. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * Expat library. - -1.5. Exported Parameters - -1.5.1. db_url (string) - - SQL URL of database. - - Default value is “mysql://root@127.0.0.1/sip_jab”. - - Example 1.1. Set db_url parameter -... -modparam("jabber", "db_url", "mysql://username:password@host/sip_jab") -... - -1.5.2. jaddress (string) - - IP or hostname of Jabber server -- it must be the same as the - value from tag of Jabber server config file. - - Default value is “127.0.0.1”. - - Example 1.2. Set jaddress parameter -... -modparam("jabber", "jaddress", "1.2.3.4") -... - -1.5.3. jport (integer) - - Port number of Jabber server. - - Default value is “5222”. - - Example 1.3. Set jport parameter -... -modparam("jabber", "jport", 1234) -... - -1.5.4. jdomain (string) - - Format: jabber.sipserver.com=. If the destination is for - Jabber network the URI should be like: - usernamejabber_server@jdomain or - nicknameroomnameconference_server@jdomain - - must be a un-reserved character. By default this - character is * . The destination will be transformed to - username@jabber_server or roomname@conference_server/nickname - before the message is sent to Jabber server. - - Default value is none. - - Example 1.4. Set jdomain parameter -... -modparam("jabber", "jdomain", "jabber.sipserver.com=*") -... - -1.5.5. aliases (string) - - Aliases for IM networks. - - Format: “N;alias1=;...;aliasN=;” Destinations - like '*@aliasX' could have other format than those specified - for Jabber network. All from user part of the - destination address will be changed to if the - destination address contains . - - (Ex: jdomain is 'jabber.x.com=*' and msn_alias is - 'msn.x.com=%'. The destination address forM MSN Network, on SIP - side, is like 'username*hotmail.com@msn.x.com'. The destination - address will be transformed to - 'username%hotmail.com@msn.x.com'. 'msn.x.com' must be the same - as the JID associated with MSN transport in Jabber - configuration file (usually is 'jabberd.xml')) - - Default value is none. - - Example 1.5. Set jdomain parameter -... -modparam("jabber", "aliases", "1;msn.x.com=%") -... - -1.5.6. proxy (string) - - Outbound proxy address. - - Format: ip_address:port hostname:port - - All SIP messages generated by gateway will be sent to that - address. If is missing, the message will be delivered to the - hostname of the destination address - - Default value is none. - - Example 1.6. Set proxy parameter -... -modparam("jabber", "proxy", "10.0.0.1:5060 sipserver.com:5060") -... - -1.5.7. registrar (string) - - The address in whose behalf the INFO and ERROR messages are - sent. - - Default value is “jabber_gateway@127.0.0.1”. - - Example 1.7. Set registrar parameter -... -modparam("jabber", "registrar", "jabber_gateway@127.0.0.1") -... - -1.5.8. workers (integer) - - Number of workers. - - Default value is 2. - - Example 1.8. Set workers parameter -... -modparam("jabber", "workers", 2) -... - -1.5.9. max_jobs (integer) - - Maximum jobs per worker. - - Default value is 10. - - Example 1.9. Set max_jobs parameter -... -modparam("jabber", "max_jobs", 10) -... - -1.5.10. cache_time (integer) - - Cache time of a Jabber connection. - - Default value is 600. - - Example 1.10. Set cache_time parameter -... -modparam("jabber", "cache_time", 600) -... - -1.5.11. delay_time (integer) - - Time to keep a SIP message (in seconds). - - Default value is 90 seconds. - - Example 1.11. Set delay_time parameter -... -modparam("jabber", "delay_time", 90) -... - -1.5.12. sleep_time (integer) - - Time between expired Jabber connections checking (in seconds). - - Default value is 20 seconds. - - Example 1.12. Set sleep_time parameter -... -modparam("jabber", "sleep_time", 20) -... - -1.5.13. check_time (integer) - - Time between checking the status of JabberGW workers (in - seconds). - - Default value is 20 seconds. - - Example 1.13. Set check_time parameter -... -modparam("jabber", "check_time", 20) -... - -1.5.14. priority (str) - - Presence priority for Jabber gateway. - - Default value is “9”. - - Example 1.14. Set priority parameter -... -modparam("jabber", "priority", "3") -... - -1.6. Exported Functions - -1.6.1. jab_send_message() - - Converts SIP MESSAGE message to a Jabber message and sends it - to Jabber server. - - This function can be used from REQUEST_ROUTE. - - Example 1.15. jab_send_message() usage -... -jab_send_message(); -... - -1.6.2. jab_join_jconf() - - Join a Jabber conference--the nickname, room name and - conference server address should be included in To header as: - nickname%roomname%conference_server@jdomain . If the nickname - is missing, then the SIP username is used. - - This function can be used from REQUEST_ROUTE. - - Example 1.16. jab_join_jconf() usage -... -jab_join_jconf(); -... - -1.6.3. jab_exit_jconf() - - Leave a Jabber conference--the nickname, room name and - conference server address should be included in To header as: - nickname%roomname%conference_server@jdomain . - - This function can be used from REQUEST_ROUTE. - - Example 1.17. jab_exit_jconf() usage -... -jab_exit_jconf(); -... - -1.6.4. jab_go_online() - - Register to the Jabber server with associated Jabber ID of the - SIP user. - - This function can be used from REQUEST_ROUTE. - - Example 1.18. jab_go_online() usage -... -jab_go_online(); -... - -1.6.5. jab_go_offline() - - Log off from Jabber server the associated Jabber ID of the SIP - user. - - This function can be used from REQUEST_ROUTE. - - Example 1.19. jab_go_offline() usage -... -jab_go_offline(); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 381 80 19649 8172 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 55 33 1383 558 - 3. Jan Janak (@janakj) 33 15 1007 498 - 4. Razvan Crainea (@razvancrainea) 23 21 71 51 - 5. Andrei Pelinescu-Onciul 19 12 101 336 - 6. Liviu Chircu (@liviuchircu) 15 11 72 136 - 7. Vlad Patrascu (@rvlad-patrascu) 6 4 35 12 - 8. Jiri Kuthan (@jiriatipteldotorg) 6 3 313 0 - 9. Maksym Sobolyev (@sobomax) 5 3 6 6 - 10. Peter Lemenkov (@lemenkov) 4 2 33 8 - - All remaining contributors: Henning Westerholt (@henningw), - Alexandra Titoc, Elena-Ramona Modroiu, Jamey Hicks, Konstantin - Bokarius, John Riordan, Vlad Paiu (@vladpaiu), Julián Moreno - Patiño, Klaus Darilion, Zero King (@l2dy), Edson Gellert - Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 5. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2002 - Apr 2020 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Peter Lemenkov (@lemenkov) May 2007 - Jun 2018 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Vlad Paiu (@vladpaiu) Feb 2012 - Feb 2012 - - All remaining contributors: John Riordan, Klaus Darilion, - Henning Westerholt (@henningw), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei - Pelinescu-Onciul, Jamey Hicks, Jiri Kuthan - (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Klaus Darilion, Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/jabber/README.md b/modules/jabber/README.md new file mode 100644 index 00000000000..107c7d85aea --- /dev/null +++ b/modules/jabber/README.md @@ -0,0 +1,553 @@ +--- +title: "jabber Module" +description: "This is new version of Jabber module that integrates XODE XML parser for parsing Jabber messages." +--- + +## Admin Guide + + +### Overview + + +This is new version of Jabber module that integrates XODE +XML parser for parsing Jabber messages. That +introduces a new module dependency: expat library. + + +Expat is a common XML library and is the fastest +available for Linux/Unix, the second over all, after msxml library. It +is integrated in most of well known Linux distributions. + + +#### New Features + + +- Presence support (see doc/xxjab.cfg for a sample cfg file) +(January 2003). +- SIP to Jabber conference support (December 2003). +- Possibility to manage all kinds of Jabber messages +(message/presence/iq) (December 2003). +- Aliases -- Possibility to set host aliases for addresses +(see parameter's desc.) (December 2003). +- Send received SIP MESSAGE messages to different IM networks +(Jabber, ICQ,MSN, AIM, Yahoo) using a Jabber server (December 2003). +- Send incoming Jabber instant messages as SIP MESSAGE messages. +- Gateways detection -- Ability to see whether an IM gateway is up +or down. + + +### Admin's Guide + + +> [!NOTE] +> A more complete guide about SIMPLE2Jabber gateway can be found +> at [https://opensips.org/](https://opensips.org/). The part below will be removed soon, only the manual +> from web will be updated. + + +The Jabber server setup is not a subject of this guide. Check [http://www.jabber.org](http://www.jabber.org) for that. + + +Useful scripts, for creating Jabber Gateway database, or for managing +the Jabber accounts form web are located in 'doc' subdirectory of the +module. + + +Main steps of using the Jabber gateway: + + +- Create the MySQL database. +- Setup the local Jabber server. +- Set the module parameter values in cfg file of OpenSIPS, load the +dependent modules, set up the routing rules for Jabber gateway. +- Run OpenSIPS. + + +The administrator of OpenSIPS/Jabber gateway *must* +inform the users what are the aliases for Jabber/Other IM networks. +Other IMs could be AIM, ICQ, +MSN, Yahoo, and so on. + + +These aliases depend on the server hostname where runs OpenSIPS and +how local Jabber server is setup. + + +Next is presented a use case. Prologue: + + +- OpenSIPS is running on "server.org". +- Local Jabber server is running on "jabsrv.server.org". +- Jabber network alias (first part of "jdomain") is +"jabber.server.org" + + +The aliases for other IM networks *must* be the +same as JID set in Jabber configuration file for +each IM transport. + + +The JIDs of Jabber transports +*must* start with the name of the network. +For AIM, JID must start +with "aim.", for ICQ with +"icq" (that because I use icqv7-t), for +MSN with "msn." and for +Yahoo with "yahoo.". The gateway needs these to find +out what transport is working and which not. For our use case these +could be like "aim.server.org", +"icq.server.org", +"msn.server.org", "yahoo.server.org". + + +It is indicated to have these aliases in DNS, thus +the client application can resolve the DNS name. +Otherwise there must be set the outbound proxy to OpenSIPS server. + + +*** Routing rules for Jabber gateway First step is to configure OpenSIPS +to recognize messages for Jabber gateway. Look at +"doc/xjab.cfg" to see a sample. The idea is to look in +messages for destination address and if it contains Jabber alias or +other IM alias, that means the message is for Jabber gateway. + + +Next step is to find out what means that message for Jabber gateway. +It could be a special message what triggers the gateway to take an +action or is a simple message which should be delivered to Jabber +network (using the method "jab_send_message"). + + +The special messages are for: + + +- Registering to Jabber server (go online in Jabber network)--here +must be called "jab_go_online" method. +- Leaving the Jabber network (go offline in Jabber network)--here +must be called "jab_go_offline" method. +- Joining a Jabber conference room--here must be called +"jab_join_jconf". +- Leaving a Jabber conference room--here must be called +"jab_exit_jconf". + + +The destination address *must* follow the +following patterns: + + +- For Jabber network: +"usernamejabber_server@jabber_alias". +- For Jabber conference: "nicknameroomconference_server@jabber_alias". +- For AIM network: +"aim_username@aim_alias". +- For ICQ network: +"icq_number@icq_alias". +- For MSN network: +"msn_usernamemsn_server@msn_alias". +msn_server can be "msn.com" or +"hotmail.com". +- For YAHOO network: "yahoo_username@yahoo_alias". + + +> [!NOTE] +> "jabber_alias" is the first part of "jdomain". + + +### Admin Guide + + +The user must activate his Jabber account associated with his SIP id. For each other +IM network on which he wants to send messages, he must set an account for that IM +network. The gateway is not able to create new account in foreign networks, excepting +local Jabber server. + + +When you want to send a message to someone in other IM network, you must set the +destination of the message according with the pattern corresponding to that IM network +(see last part of "Admin guide" chapter). + + +Sending a message to user@jabber.xxx.org which is in Jabber network, the +destination must be: userjabber.xxx.org@jabber_alias. + + +For someone who is in Yahoo network the destination must be: +user@yahoo_alias + + +> [!NOTE] +> The OpenSIPS administrator have to set the Jabber transports for each IM network in +order to be able to send messages to those networks. The alias of each IM network +can be found out from OpenSIPS admin. You cannot send messages from your SIP client to your associated Jabber +account--is something like sending messages to yourself. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- A database module. +- *pa* (Optionally) - Presence Agent. +- *tm* - Transaction Manager. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *Expat* library. + + +### Exported Parameters + + +#### db_url (string) + + +SQL URL of database. + + +*Default value is "mysql://root@127.0.0.1/sip_jab".* + + +```opensips title="Set db_url parameter" +... +modparam("jabber", "db_url", "mysql://username:password@host/sip_jab") +... +``` + + +#### jaddress (string) + + +IP or hostname of Jabber server -- it must be the same as the value from +tag of Jabber server config file. + + +*Default value is "127.0.0.1".* + + +```opensips title="Set jaddress parameter" +... +modparam("jabber", "jaddress", "1.2.3.4") +... +``` + + +#### jport (integer) + + +Port number of Jabber server. + + +*Default value is "5222".* + + +```opensips title="Set jport parameter" +... +modparam("jabber", "jport", 1234) +... +``` + + +#### jdomain (string) + + +Format: jabber.sipserver.com=. If the destination is for Jabber network +the URI should be like: usernamejabber_server@jdomain or +nicknameroomnameconference_server@jdomain + + + must be a un-reserved character. By default this character is * . The +destination will be transformed to username@jabber_server or +roomname@conference_server/nickname before the message is sent to Jabber server. + + +*Default value is none.* + + +```opensips title="Set jdomain parameter" +... +modparam("jabber", "jdomain", "jabber.sipserver.com=*") +... +``` + + +#### aliases (string) + + +Aliases for IM networks. + + +Format: "N;alias1=;...;aliasN=;" +Destinations like '*@aliasX' could have other format than those specified for Jabber +network. All from user part of the destination address will be +changed to if the destination address contains . + + +(Ex: jdomain is 'jabber.x.com=*' and msn_alias is 'msn.x.com=%'. The destination +address forM MSN Network, on SIP side, is like +'username*hotmail.com@msn.x.com'. The destination address will be transformed to +'username%hotmail.com@msn.x.com'. 'msn.x.com' must be the same as the +JID associated with MSN transport in Jabber +configuration file (usually is 'jabberd.xml')) + + +*Default value is none.* + + +```opensips title="Set jdomain parameter" +... +modparam("jabber", "aliases", "1;msn.x.com=%") +... +``` + + +#### proxy (string) + + +Outbound proxy address. + + +Format: ip_address:port hostname:port + + +All SIP messages generated by gateway will be sent to that address. If is +missing, the message will be delivered to the hostname of the destination address + + +Default value is none. + + +```opensips title="Set proxy parameter" +... +modparam("jabber", "proxy", "10.0.0.1:5060 sipserver.com:5060") +... +``` + + +#### registrar (string) + + +The address in whose behalf the INFO and ERROR messages are sent. + + +*Default value is "jabber_gateway@127.0.0.1".* + + +```opensips title="Set registrar parameter" +... +modparam("jabber", "registrar", "jabber_gateway@127.0.0.1") +... +``` + + +#### workers (integer) + + +Number of workers. + + +*Default value is 2.* + + +```opensips title="Set workers parameter" +... +modparam("jabber", "workers", 2) +... +``` + + +#### max_jobs (integer) + + +Maximum jobs per worker. + + +*Default value is 10.* + + +```opensips title="Set max_jobs parameter" +... +modparam("jabber", "max_jobs", 10) +... +``` + + +#### cache_time (integer) + + +Cache time of a Jabber connection. + + +*Default value is 600.* + + +```opensips title="Set cache_time parameter" +... +modparam("jabber", "cache_time", 600) +... +``` + + +#### delay_time (integer) + + +Time to keep a SIP message (in seconds). + + +*Default value is 90 seconds.* + + +```opensips title="Set delay_time parameter" +... +modparam("jabber", "delay_time", 90) +... +``` + + +#### sleep_time (integer) + + +Time between expired Jabber connections checking (in seconds). + + +*Default value is 20 seconds.* + + +```opensips title="Set sleep_time parameter" +... +modparam("jabber", "sleep_time", 20) +... +``` + + +#### check_time (integer) + + +Time between checking the status of JabberGW workers (in seconds). + + +*Default value is 20 seconds.* + + +```opensips title="Set check_time parameter" +... +modparam("jabber", "check_time", 20) +... +``` + + +#### priority (str) + + +Presence priority for Jabber gateway. + + +*Default value is "9".* + + +```opensips title="Set priority parameter" +... +modparam("jabber", "priority", "3") +... +``` + + +### Exported Functions + + +#### jab_send_message() + + +Converts SIP MESSAGE message to a Jabber message and sends it to Jabber server. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jab_send_message() usage" +... +jab_send_message(); +... +``` + + +#### jab_join_jconf() + + +Join a Jabber conference--the nickname, room name and conference server address +should be included in To header as: nickname%roomname%conference_server@jdomain . If +the nickname is missing, then the SIP username is used. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jab_join_jconf() usage" +... +jab_join_jconf(); +... +``` + + +#### jab_exit_jconf() + + +Leave a Jabber conference--the nickname, room name and conference server address +should be included in To header as: nickname%roomname%conference_server@jdomain . + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jab_exit_jconf() usage" +... +jab_exit_jconf(); +... +``` + + +#### jab_go_online() + + +Register to the Jabber server with associated Jabber ID of the SIP user. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jab_go_online() usage" +... +jab_go_online(); +... +``` + + +#### jab_go_offline() + + +Log off from Jabber server the associated Jabber ID of the SIP user. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="jab_go_offline() usage" +... +jab_go_offline(); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/jabber/doc/contributors.xml b/modules/jabber/doc/contributors.xml deleted file mode 100644 index 9a061dfd553..00000000000 --- a/modules/jabber/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 381 - 80 - 19649 - 8172 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 55 - 33 - 1383 - 558 - - - 3. - Jan Janak (@janakj) - 33 - 15 - 1007 - 498 - - - 4. - Razvan Crainea (@razvancrainea) - 23 - 21 - 71 - 51 - - - 5. - Andrei Pelinescu-Onciul - 19 - 12 - 101 - 336 - - - 6. - Liviu Chircu (@liviuchircu) - 15 - 11 - 72 - 136 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 35 - 12 - - - 8. - Jiri Kuthan (@jiriatipteldotorg) - 6 - 3 - 313 - 0 - - - 9. - Maksym Sobolyev (@sobomax) - 5 - 3 - 6 - 6 - - - 10. - Peter Lemenkov (@lemenkov) - 4 - 2 - 33 - 8 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Alexandra Titoc, Elena-Ramona Modroiu, Jamey Hicks, Konstantin Bokarius, John Riordan, Vlad Paiu (@vladpaiu), Julián Moreno Patiño, Klaus Darilion, Zero King (@l2dy), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2002 - Apr 2020 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Peter Lemenkov (@lemenkov) - May 2007 - Jun 2018 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Vlad Paiu (@vladpaiu) - Feb 2012 - Feb 2012 - - - -
-All remaining contributors: John Riordan, Klaus Darilion, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jamey Hicks, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/jabber/doc/jabber.xml b/modules/jabber/doc/jabber.xml deleted file mode 100644 index b03038219b7..00000000000 --- a/modules/jabber/doc/jabber.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - jabber Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/jabber/doc/jabber_admin.xml b/modules/jabber/doc/jabber_admin.xml deleted file mode 100644 index 001ab6fab85..00000000000 --- a/modules/jabber/doc/jabber_admin.xml +++ /dev/null @@ -1,741 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is new version of Jabber module that integrates XODE - XML parser for parsing Jabber messages. That - introduces a new module dependency: expat library. - - - Expat is a common XML library and is the fastest - available for Linux/Unix, the second over all, after msxml library. It - is integrated in most of well known Linux distributions. - -
- New Features - - - - Presence support (see doc/xxjab.cfg for a sample cfg file) - (January 2003). - - - - - SIP to Jabber conference support (December 2003). - - - - - Possibility to manage all kinds of Jabber messages - (message/presence/iq) (December 2003). - - - - - Aliases -- Possibility to set host aliases for addresses - (see parameter's desc.) (December 2003). - - - - - Send received &sip; MESSAGE messages to different &im; networks - (Jabber, ICQ,MSN, AIM, Yahoo) using a Jabber server (December 2003). - - - - - Send incoming Jabber instant messages as &sip; MESSAGE messages. - - - - - Gateways detection -- Ability to see whether an &im; gateway is up - or down. - - - -
-
- - -
- Admin's Guide - - - A more complete guide about SIMPLE2Jabber gateway can be found - at &osipshomelink;. The part below will be removed soon, only the manual - from web will be updated. - - - - The Jabber server setup is not a subject of this guide. Check http://www.jabber.org for that. - - - Useful scripts, for creating Jabber Gateway database, or for managing - the Jabber accounts form web are located in 'doc' subdirectory of the - module. - - - Main steps of using the Jabber gateway: - - - - - Create the MySQL database. - - - - - Setup the local Jabber server. - - - - - Set the module parameter values in cfg file of &osips;, load the - dependent modules, set up the routing rules for Jabber gateway. - - - - - Run &osips;. - - - - - The administrator of &osips;/Jabber gateway must - inform the users what are the aliases for Jabber/Other &im; networks. - Other &im;s could be AIM, ICQ, - MSN, Yahoo, and so on. - - - These aliases depend on the server hostname where runs &osips; and - how local Jabber server is setup. - - - Next is presented a use case. Prologue: - - - - &osips; is running on server.org. - - - - Local Jabber server is running on jabsrv.server.org. - - - - - Jabber network alias (first part of jdomain) is - jabber.server.org - - - - - The aliases for other &im; networks must be the - same as JID set in Jabber configuration file for - each &im; transport. - - - The JIDs of Jabber transports - must start with the name of the network. - For AIM, JID must start - with aim., for ICQ with - icq (that because I use icqv7-t), for - MSN with msn. and for - Yahoo with yahoo.. The gateway needs these to find - out what transport is working and which not. For our use case these - could be like aim.server.org, - icq.server.org, - msn.server.org, yahoo.server.org. - - - It is indicated to have these aliases in DNS, thus - the client application can resolve the DNS name. - Otherwise there must be set the outbound proxy to &osips; server. - - - *** Routing rules for Jabber gateway First step is to configure &osips; - to recognize messages for Jabber gateway. Look at - doc/xjab.cfg to see a sample. The idea is to look in - messages for destination address and if it contains Jabber alias or - other &im; alias, that means the message is for Jabber gateway. - - - Next step is to find out what means that message for Jabber gateway. - It could be a special message what triggers the gateway to take an - action or is a simple message which should be delivered to Jabber - network (using the method jab_send_message). - - - The special messages are for: - - - - - Registering to Jabber server (go online in Jabber network)--here - must be called jab_go_online method. - - - - - Leaving the Jabber network (go offline in Jabber network)--here - must be called jab_go_offline method. - - - - - Joining a Jabber conference room--here must be called - jab_join_jconf. - - - - - Leaving a Jabber conference room--here must be called - jab_exit_jconf. - - - - - The destination address must follow the - following patterns: - - - - - For Jabber network: - username<delim>jabber_server@jabber_alias. - - - - - For Jabber conference: nickname<delim>room<delim>conference_server@jabber_alias. - - - - - For AIM network: - aim_username@aim_alias. - - - - - For ICQ network: - icq_number@icq_alias. - - - - - For MSN network: - msn_username<delim>msn_server@msn_alias. - msn_server can be msn.com or - hotmail.com. - - - - - For YAHOO network: yahoo_username@yahoo_alias. - - - - - - jabber_alias is the first part of jdomain. - - -
-
- &adminguide; - - The user must activate his Jabber account associated with his &sip; id. For each other - &im; network on which he wants to send messages, he must set an account for that &im; - network. The gateway is not able to create new account in foreign networks, excepting - local Jabber server. - - - When you want to send a message to someone in other &im; network, you must set the - destination of the message according with the pattern corresponding to that &im; network - (see last part of Admin guide chapter). - - - Sending a message to user@jabber.xxx.org which is in Jabber network, the - destination must be: user<delim>jabber.xxx.org@jabber_alias. - - - For someone who is in Yahoo network the destination must be: - user@yahoo_alias - - - - The &osips; administrator have to set the Jabber transports for each &im; network in - order to be able to send messages to those networks. The alias of each &im; network - can be found out from &osips; admin. - - - You cannot send messages from your &sip; client to your associated Jabber - account--is something like sending messages to yourself. - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - A database module. - - - - - pa (Optionally) - Presence Agent. - - - - - tm - Transaction Manager. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - Expat library. - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (string) - - SQL &url; of database. - - - - Default value is mysql://root@127.0.0.1/sip_jab. - - - - Set <varname>db_url</varname> parameter - -... -modparam("jabber", "db_url", "mysql://username:password@host/sip_jab") -... - - -
- -
- <varname>jaddress</varname> (string) - - &ip; or hostname of Jabber server -- it must be the same as the value from <host> - tag of Jabber server config file. - - - - Default value is 127.0.0.1. - - - - Set <varname>jaddress</varname> parameter - -... -modparam("jabber", "jaddress", "1.2.3.4") -... - - -
- -
- <varname>jport</varname> (integer) - - Port number of Jabber server. - - - - Default value is 5222. - - - - Set <varname>jport</varname> parameter - -... -modparam("jabber", "jport", 1234) -... - - -
- -
- <varname>jdomain</varname> (string) - - Format: jabber.sipserver.com=<delim>. If the destination is for Jabber network - the &uri; should be like: username<delim>jabber_server@jdomain or - nickname<delim>roomname<delim>conference_server@jdomain - - - <delim> must be a un-reserved character. By default this character is * . The - destination will be transformed to username@jabber_server or - roomname@conference_server/nickname before the message is sent to Jabber server. - - - - Default value is none. - - - - Set <varname>jdomain</varname> parameter - -... -modparam("jabber", "jdomain", "jabber.sipserver.com=*") -... - - -
- -
- <varname>aliases</varname> (string) - - Aliases for &im; networks. - - - Format: N;alias1=<delim1>;...;aliasN=<delimN>; - Destinations like '*@aliasX' could have other format than those specified for Jabber - network. All <delim> from user part of the destination address will be - changed to <delimX> if the destination address contains <aliasX>. - - - (Ex: jdomain is 'jabber.x.com=*' and msn_alias is 'msn.x.com=%'. The destination - address forM MSN Network, on &sip; side, is like - 'username*hotmail.com@msn.x.com'. The destination address will be transformed to - 'username%hotmail.com@msn.x.com'. 'msn.x.com' must be the same as the - JID associated with MSN transport in Jabber - configuration file (usually is 'jabberd.xml')) - - - - Default value is none. - - - - Set <varname>jdomain</varname> parameter - -... -modparam("jabber", "aliases", "1;msn.x.com=%") -... - - -
- -
- <varname>proxy</varname> (string) - - Outbound proxy address. - - - Format: ip_address:port hostname:port - - - All &sip; messages generated by gateway will be sent to that address. If is - missing, the message will be delivered to the hostname of the destination address - - - Default value is none. - - - Set <varname>proxy</varname> parameter - -... -modparam("jabber", "proxy", "10.0.0.1:5060 sipserver.com:5060") -... - - -
- -
- <varname>registrar</varname> (string) - - The address in whose behalf the INFO and ERROR messages are sent. - - - - Default value is jabber_gateway@127.0.0.1. - - - - Set <varname>registrar</varname> parameter - -... -modparam("jabber", "registrar", "jabber_gateway@127.0.0.1") -... - - -
- -
- <varname>workers</varname> (integer) - - Number of workers. - - - - Default value is 2. - - - - Set <varname>workers</varname> parameter - -... -modparam("jabber", "workers", 2) -... - - -
- -
- <varname>max_jobs</varname> (integer) - - Maximum jobs per worker. - - - - Default value is 10. - - - - Set <varname>max_jobs</varname> parameter - -... -modparam("jabber", "max_jobs", 10) -... - - -
- -
- <varname>cache_time</varname> (integer) - - Cache time of a Jabber connection. - - - - Default value is 600. - - - - Set <varname>cache_time</varname> parameter - -... -modparam("jabber", "cache_time", 600) -... - - -
- -
- <varname>delay_time</varname> (integer) - - Time to keep a &sip; message (in seconds). - - - - Default value is 90 seconds. - - - - Set <varname>delay_time</varname> parameter - -... -modparam("jabber", "delay_time", 90) -... - - -
- -
- <varname>sleep_time</varname> (integer) - - Time between expired Jabber connections checking (in seconds). - - - - Default value is 20 seconds. - - - - Set <varname>sleep_time</varname> parameter - -... -modparam("jabber", "sleep_time", 20) -... - - -
- -
- <varname>check_time</varname> (integer) - - Time between checking the status of JabberGW workers (in seconds). - - - - Default value is 20 seconds. - - - - Set <varname>check_time</varname> parameter - -... -modparam("jabber", "check_time", 20) -... - - -
- -
- <varname>priority</varname> (str) - - Presence priority for Jabber gateway. - - - - Default value is 9. - - - - Set <varname>priority</varname> parameter - -... -modparam("jabber", "priority", "3") -... - - -
- -
-
- Exported Functions -
- - <function moreinfo="none">jab_send_message()</function> - - - Converts &sip; MESSAGE message to a Jabber message and sends it to Jabber server. - - - This function can be used from REQUEST_ROUTE. - - - <function>jab_send_message()</function> usage - -... -jab_send_message(); -... - - -
-
- - <function moreinfo="none">jab_join_jconf()</function> - - - Join a Jabber conference--the nickname, room name and conference server address - should be included in To header as: nickname%roomname%conference_server@jdomain . If - the nickname is missing, then the &sip; username is used. - - - This function can be used from REQUEST_ROUTE. - - - <function>jab_join_jconf()</function> usage - -... -jab_join_jconf(); -... - - -
-
- - <function moreinfo="none">jab_exit_jconf()</function> - - - Leave a Jabber conference--the nickname, room name and conference server address - should be included in To header as: nickname%roomname%conference_server@jdomain . - - - This function can be used from REQUEST_ROUTE. - - - <function>jab_exit_jconf()</function> usage - -... -jab_exit_jconf(); -... - - -
- -
- - <function moreinfo="none">jab_go_online()</function> - - - Register to the Jabber server with associated Jabber ID of the &sip; user. - - - This function can be used from REQUEST_ROUTE. - - - <function>jab_go_online()</function> usage - -... -jab_go_online(); -... - - -
- -
- - <function moreinfo="none">jab_go_offline()</function> - - - Log off from Jabber server the associated Jabber ID of the &sip; user. - - - This function can be used from REQUEST_ROUTE. - - - <function>jab_go_offline()</function> usage - -... -jab_go_offline(); -... - - -
-
-
- diff --git a/modules/jabber/xjab_jcon.c b/modules/jabber/xjab_jcon.c index d6265a00ca7..52cdd7060e7 100644 --- a/modules/jabber/xjab_jcon.c +++ b/modules/jabber/xjab_jcon.c @@ -114,6 +114,11 @@ int xj_jcon_connect(xj_jcon jbc) LM_DBG("failed to get info about Jabber server address\n"); goto error; } + if(he->h_addrtype != AF_INET || he->h_length != sizeof(address.sin_addr)) + { + LM_DBG("invalid Jabber server address family or length\n"); + goto error; + } memset(&address, 0, sizeof(address)); // fill the fields of the address @@ -816,4 +821,3 @@ int xj_jcon_del_jconf(xj_jcon jbc, str *sid, char dl, int flag) } /********** *********/ - diff --git a/modules/janus/README b/modules/janus/README deleted file mode 100644 index 8802df3e889..00000000000 --- a/modules/janus/README +++ /dev/null @@ -1,306 +0,0 @@ -JANUS Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. External Libraries or Applications - - 1.2.1. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. janus_send_timeout (integer) - 1.3.2. janus_max_msg_chunks (integer) - 1.3.3. janus_cmd_timeout (integer) - 1.3.4. janus_cmd_polling_itv (integer) - 1.3.5. janus_ping_interval (integer) - 1.3.6. janus_db_url (string) - 1.3.7. janus_db_table (string) - - 1.4. Exported Functions - - 1.4.1. janus_send_requeest(janus_id, janus_command[, - response_var]) - - 1.4.2. Exported Events - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the janus_send_timeout parameter - 1.2. Setting the janus_max_msg_chunks parameter - 1.3. Setting the janus_cmd_timeout parameter - 1.4. Setting the janus_cmd_polling_itv parameter - 1.5. Setting the janus_ping_interval parameter - 1.6. Setting the janus_db_url parameter - 1.7. Setting the janus_db_table parameter - 1.8. janus_send_request() usage - 1.9. E_JANUS_EVENT example - -Chapter 1. Admin Guide - -1.1. Overview - - The "janus" module is a C driver for the Janus websocket - protocol. It can interact with one or more Janus servers either - by issuing commands to them, or by receiving events from them. - - This driver can be seen as a centralized Janus connection - manager. It will connect to each Janus server, establish the - connection hanler ID and the clients can be transparent from - the connection handler ID point of view, simply passing the - desired Janus commands that they want to run. - -1.2. External Libraries or Applications - -1.2.1. OpenSIPS Modules - - The following modules must be loaded together with this module: - * an SQL DB module - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. janus_send_timeout (integer) - - Time in milliseconds after a Janus WebSocket connection will be - closed if it is not available for blocking writing in this - interval (and OpenSIPS wants to send something on it). - - Default value is “1000” (milliseconds). - - Example 1.1. Setting the janus_send_timeout parameter -... -modparam("janus", "janus_send_timeout", 2000) -... - -1.3.2. janus_max_msg_chunks (integer) - - The maximum number of chunks in which a Janus message is - expected to arrive via WebSocket. If a received packet is more - fragmented than this, the connection is dropped - - Default value is “4” - - Example 1.2. Setting the janus_max_msg_chunks parameter -... -modparam("janus", "janus_max_msg_chunks", 8) -... - -1.3.3. janus_cmd_timeout (integer) - - The maximally allowed duration for the execution of an Janus - command. This interval does not include the connect duration. - - Default value is “5000” (milliseconds). - - Example 1.3. Setting the janus_cmd_timeout parameter -... -modparam("janus", "janus_cmd_timeout", 3000) -... - -1.3.4. janus_cmd_polling_itv (integer) - - The sleep interval used when polling for an Janus command - response. Since the value of this parameter imposes a minimal - duration for any Janus command, you should run OpenSIPS in - debug mode in order to first determine an expected response - time for an arbitrary Janus command, then tune this parameter - accordingly. - - Default value is “1000” (microseconds). - - Example 1.4. Setting the janus_cmd_polling_itv parameter -... -modparam("janus", "janus_cmd_polling_itv", 3000) -... - -1.3.5. janus_ping_interval (integer) - - The time interval at which OpenSIPS will do keepalive pinging - on the Janus connect - - Default value is “5” (seconds). - - Example 1.5. Setting the janus_ping_interval parameter -... -modparam("janus", "janus_ping_interval", 10) -... - -1.3.6. janus_db_url (string) - - The DB URL from where OpenSIPS will load the list of Janus - connection - - Default value is “"none"” (needs to be set for the module to - start). - - Example 1.6. Setting the janus_db_url parameter -... -modparam("janus", "janus_db_url", "mysql://root@localhost/opensips") -... - -1.3.7. janus_db_table (string) - - The DB Table from where OpenSIPS will load the list of Janus - connection - - Default value is “janus” - - Example 1.7. Setting the janus_db_table parameter -... -modparam("janus", "janus_db_table", "my_janus_table") -... - -1.4. Exported Functions - -1.4.1. janus_send_requeest(janus_id, janus_command[, response_var]) - - Run an arbitrary command on an arbitrary Janus socket. The - janus_id must be defined in the database - - The current OpenSIPS worker will block until an answer from - Janus arrives. The timeout for this operation can be controlled - via the janus_cmd_timeout param. - - Meaning of the parameters is as follows: - * janus_id (string) - the ID of the janus connection as - defined in the databsae. - * janus_command (string) - the JANUS command to run. - * response_var (var, optional) - a variable which will hold - the text result of the Janus command. - - Return value - * 1 (success) - the Janus command executed successfully and - any output variables were successfully written to. Note - that this does not say anything about the nature of the - Janus answer (it may well be a "-ERR" type of response) - * -1 (failure) - internal error or the Janus command failed - to execute - - This function can be used from any route. - - Example 1.8. janus_send_request() usage -... -# if the DB contains: -# id: 1 -# janus_id: test_janus -# janus_url: janusws://my_janus_host:80/janus?room=abcd - - $var(rc) = janus_send_request("test_janus", "{ - "janus": "attach", - "plugin": "janus.plugin.videoroom", - "transaction": "abcdef123456", - "session_id": 987654321 -}", $var(response)); - if (!$var(rc)) { - xlog("failed to execute Janus command ($var(rc))\n"); - return -1; - } - xlog("Janus response is $var(response) \n"); -... -... - -1.4.2. Exported Events - -1.4.2.1. E_JANUS_EVENT - - This event is raised when a notification is received from a - Janus server. - - Parameters represent the janus_id and the janus_url that - originated the notification, and the full janus_body of the - event received - * janus_id - the janus id as defined in the database - * janus_url - the janus url as defined in the database - * janus_body - full body of the notification received from - janus - - Example 1.9. E_JANUS_EVENT example -... -# if the DB contains: -# id: 1 -# janus_id: test_janus -# janus_url: janusws://my_janus_host:80/janus?room=abcd - -event_route[E_JANUS_EVENT] { - xlog("Received janus event from $param(janus_id) - $param(janus_ -url) - $param(janus_body) \n"); - $json(janus_body) := $param(janus_body); - $avp(janus_sender) = $json(janus_body/sender); - if ($avp(janus_sender) != NULL) { - xlog("Received event from sender $avp(janus_sender) \n") -; - } -} -... -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 45 7 4390 5 - 2. Razvan Crainea (@razvancrainea) 4 2 1 3 - 3. Nick Altmann (@nikbyte) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Vlad Paiu (@vladpaiu) Dec 2024 - May 2025 - 2. Razvan Crainea (@razvancrainea) Mar 2025 - Mar 2025 - 3. Nick Altmann (@nikbyte) Feb 2025 - Feb 2025 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Project; diff --git a/modules/janus/README.md b/modules/janus/README.md new file mode 100644 index 00000000000..ad97efa5eea --- /dev/null +++ b/modules/janus/README.md @@ -0,0 +1,260 @@ +--- +title: "JANUS Module" +description: "The *\"janus\"* module is a C driver for the Janus websocket protocol." +--- + +## Admin Guide + + +### Overview + + +The *"janus"* module is a C driver for the +Janus websocket protocol. It can interact with one or more +Janus servers either by issuing commands to them, or by receiving +events from them. + + +This driver can be seen as a centralized Janus connection manager. +It will connect to each Janus server, establish the connection hanler ID and the clients can be transparent from the connection handler ID point of view, simply passing the desired Janus commands that they want to run. + + +### External Libraries or Applications + + +#### OpenSIPS Modules + + +The following modules must be loaded together with this module: + + +- *an SQL DB module* + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### janus_send_timeout (integer) + + +Time in milliseconds after a Janus WebSocket connection will be closed if it is not available for blocking writing in this interval (and OpenSIPS wants to send something on it). + + +*Default value is "1000" (milliseconds).* + + +```opensips title="Setting the janus_send_timeout parameter" +... +modparam("janus", "janus_send_timeout", 2000) +... +``` + + +#### janus_max_msg_chunks (integer) + + +The maximum number of chunks in which a Janus message is expected to arrive via WebSocket. If a received packet is more fragmented than this, the connection is dropped + + +*Default value is "4"* + + +```opensips title="Setting the janus_max_msg_chunks parameter" +... +modparam("janus", "janus_max_msg_chunks", 8) +... +``` + + +#### janus_cmd_timeout (integer) + + +The maximally allowed duration for the execution of an Janus command. +This interval does not include the connect duration. + + +*Default value is "5000" (milliseconds).* + + +```opensips title="Setting the janus_cmd_timeout parameter" +... +modparam("janus", "janus_cmd_timeout", 3000) +... +``` + + +#### janus_cmd_polling_itv (integer) + + +The sleep interval used when polling for an Janus command response. Since the +value of this parameter imposes a minimal duration for any Janus command, +you should run OpenSIPS in debug mode in order to first determine an expected +response time for an arbitrary Janus command, then tune this parameter accordingly. + + +*Default value is "1000" (microseconds).* + + +```opensips title="Setting the janus_cmd_polling_itv parameter" +... +modparam("janus", "janus_cmd_polling_itv", 3000) +... +``` + + +#### janus_ping_interval (integer) + + +The time interval at which OpenSIPS will do keepalive pinging on the Janus connect + + +*Default value is "5" (seconds).* + + +```opensips title="Setting the janus_ping_interval parameter" +... +modparam("janus", "janus_ping_interval", 10) +... +``` + + +#### janus_db_url (string) + + +The DB URL from where OpenSIPS will load the list of Janus connection + + +*Default value is ""none"" (needs to be set for the module to start).* + + +```opensips title="Setting the janus_db_url parameter" +... +modparam("janus", "janus_db_url", "mysql://root@localhost/opensips") +... +``` + + +#### janus_db_table (string) + + +The DB Table from where OpenSIPS will load the list of Janus connection + + +*Default value is "janus"* + + +```opensips title="Setting the janus_db_table parameter" +... +modparam("janus", "janus_db_table", "my_janus_table") +... +``` + + +### Exported Functions + + +#### janus_send_requeest(janus_id, janus_command[, response_var]) + + +Run an arbitrary command on an arbitrary Janus socket. The +janus_id must be defined in the database + + +The current OpenSIPS worker will block until an answer from Janus +arrives. The timeout for this operation can be controlled via the +**janus_cmd_timeout** param. + + +Meaning of the parameters is as follows: + + +- *janus_id* (string) - the ID of the janus connection as defined in the databsae. +- *janus_command* (string) - the JANUS command to run. +- *response_var (var, optional)* - a +variable which will hold the text result of the Janus command. + + +**Return value** + + +- 1 (success) - the Janus command executed successfully and any +output variables were successfully written to. Note that this +does not say anything about the nature of the Janus answer (it +may well be a "-ERR" type of response) +- -1 (failure) - internal error or the Janus command failed to +execute + + +This function can be used from any route. + + +```opensips title="*janus_send_request()* usage" +... +# if the DB contains: +# id: 1 +# janus_id: test_janus +# janus_url: janusws://my_janus_host:80/janus?room=abcd + + $var(rc) = janus_send_request("test_janus", "{ + "janus": "attach", + "plugin": "janus.plugin.videoroom", + "transaction": "abcdef123456", + "session_id": 987654321 +}", $var(response)); + if (!$var(rc)) { + xlog("failed to execute Janus command ($var(rc))\n"); + return -1; + } + xlog("Janus response is $var(response) \n"); +... +... +``` + + +#### Exported Events + + +##### E_JANUS_EVENT + + +This event is raised when a notification is received from a Janus server. + + +Parameters represent the janus_id and the janus_url that originated the notification, and the full janus_body of the event received + + +- *janus_id* - the janus id as defined in the database +- *janus_url* - the janus url as defined in the database +- *janus_body* - full body of the notification received from janus + + +```opensips title="*E_JANUS_EVENT* example" +... +# if the DB contains: +# id: 1 +# janus_id: test_janus +# janus_url: janusws://my_janus_host:80/janus?room=abcd + +event_route[E_JANUS_EVENT] { + xlog("Received janus event from $param(janus_id) - $param(janus_url) - $param(janus_body) \n"); + $json(janus_body) := $param(janus_body); + $avp(janus_sender) = $json(janus_body/sender); + if ($avp(janus_sender) != NULL) { + xlog("Received event from sender $avp(janus_sender) \n"); + } +} +... +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/janus/doc/contributors.xml b/modules/janus/doc/contributors.xml deleted file mode 100644 index 746557426e1..00000000000 --- a/modules/janus/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 45 - 7 - 4390 - 5 - - - 2. - Razvan Crainea (@razvancrainea) - 4 - 2 - 1 - 3 - - - 3. - Nick Altmann (@nikbyte) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Vlad Paiu (@vladpaiu) - Dec 2024 - May 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Mar 2025 - Mar 2025 - - - 3. - Nick Altmann (@nikbyte) - Feb 2025 - Feb 2025 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/janus/doc/janus.xml b/modules/janus/doc/janus.xml deleted file mode 100644 index b63d6dd1e6e..00000000000 --- a/modules/janus/doc/janus.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%docentities; - -]> - - - - JANUS Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Project; - diff --git a/modules/janus/doc/janus_admin.xml b/modules/janus/doc/janus_admin.xml deleted file mode 100644 index e6db3b03226..00000000000 --- a/modules/janus/doc/janus_admin.xml +++ /dev/null @@ -1,320 +0,0 @@ - - - - &adminguide; - -
- Overview - - The "janus" module is a C driver for the - Janus websocket protocol. It can interact with one or more - Janus servers either by issuing commands to them, or by receiving - events from them. - - - This driver can be seen as a centralized Janus connection manager. - It will connect to each Janus server, establish the connection hanler ID and the clients can be transparent from the connection handler ID point of view, simply passing the desired Janus commands that they want to run. - -
- -
-
- &osips; Modules - - The following modules must be loaded together with this module: - - - - an SQL DB module - - - - -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None - - - - -
- -
- Exported Parameters -
- <varname>janus_send_timeout</varname> (integer) - - Time in milliseconds after a Janus WebSocket connection will be closed if it is not available for blocking writing in this interval (and OpenSIPS wants to send something on it). - - - - Default value is 1000 (milliseconds). - - - - Setting the <varname>janus_send_timeout</varname> parameter - -... -modparam("janus", "janus_send_timeout", 2000) -... - - -
-
- <varname>janus_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a Janus message is expected to arrive via WebSocket. If a received packet is more fragmented than this, the connection is dropped - - - - Default value is 4 - - - - Setting the <varname>janus_max_msg_chunks</varname> parameter - -... -modparam("janus", "janus_max_msg_chunks", 8) -... - - -
-
- <varname>janus_cmd_timeout</varname> (integer) - - The maximally allowed duration for the execution of an Janus command. - This interval does not include the connect duration. - - - - Default value is 5000 (milliseconds). - - - - Setting the <varname>janus_cmd_timeout</varname> parameter - -... -modparam("janus", "janus_cmd_timeout", 3000) -... - - -
-
- <varname>janus_cmd_polling_itv</varname> (integer) - - The sleep interval used when polling for an Janus command response. Since the - value of this parameter imposes a minimal duration for any Janus command, - you should run OpenSIPS in debug mode in order to first determine an expected - response time for an arbitrary Janus command, then tune this parameter accordingly. - - - - Default value is 1000 (microseconds). - - - - Setting the <varname>janus_cmd_polling_itv</varname> parameter - -... -modparam("janus", "janus_cmd_polling_itv", 3000) -... - - -
- -
- <varname>janus_ping_interval</varname> (integer) - - The time interval at which OpenSIPS will do keepalive pinging on the Janus connect - - - - Default value is 5 (seconds). - - - - Setting the <varname>janus_ping_interval</varname> parameter - -... -modparam("janus", "janus_ping_interval", 10) -... - - -
- -
- <varname>janus_db_url</varname> (string) - - The DB URL from where OpenSIPS will load the list of Janus connection - - - - Default value is "none" (needs to be set for the module to start). - - - - Setting the <varname>janus_db_url</varname> parameter - -... -modparam("janus", "janus_db_url", "mysql://root@localhost/opensips") -... - - -
- -
- <varname>janus_db_table</varname> (string) - - The DB Table from where OpenSIPS will load the list of Janus connection - - - - Default value is janus - - - - Setting the <varname>janus_db_table</varname> parameter - -... -modparam("janus", "janus_db_table", "my_janus_table") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">janus_send_requeest(janus_id, janus_command[, response_var])</function> - - - Run an arbitrary command on an arbitrary Janus socket. The - janus_id must be defined in the database - - - The current OpenSIPS worker will block until an answer from Janus - arrives. The timeout for this operation can be controlled via the - janus_cmd_timeout param. - - - Meaning of the parameters is as follows: - - - janus_id (string) - the ID of the janus connection as defined in the databsae. - - - - - janus_command (string) - the JANUS command to run. - - - - response_var (var, optional) - a - variable which will hold the text result of the Janus command. - - - - Return value - - - - 1 (success) - the Janus command executed successfully and any - output variables were successfully written to. Note that this - does not say anything about the nature of the Janus answer (it - may well be a "-ERR" type of response) - - - - - -1 (failure) - internal error or the Janus command failed to - execute - - - - - This function can be used from any route. - - - <function moreinfo="none"> - <emphasis>janus_send_request()</emphasis></function> usage - -... -# if the DB contains: -# id: 1 -# janus_id: test_janus -# janus_url: janusws://my_janus_host:80/janus?room=abcd - - $var(rc) = janus_send_request("test_janus", "{ - "janus": "attach", - "plugin": "janus.plugin.videoroom", - "transaction": "abcdef123456", - "session_id": 987654321 -}", $var(response)); - if (!$var(rc)) { - xlog("failed to execute Janus command ($var(rc))\n"); - return -1; - } - xlog("Janus response is $var(response) \n"); -... -... - - -
- -
- Exported Events -
- - <function moreinfo="none">E_JANUS_EVENT</function> - - - This event is raised when a notification is received from a Janus server. - - - Parameters represent the janus_id and the janus_url that originated the notification, and the full janus_body of the event received - - - - janus_id - the janus id as defined in the database - - - janus_url - the janus url as defined in the database - - - janus_body - full body of the notification received from janus - - - - <function moreinfo="none"> - <emphasis>E_JANUS_EVENT</emphasis></function> example - -... -# if the DB contains: -# id: 1 -# janus_id: test_janus -# janus_url: janusws://my_janus_host:80/janus?room=abcd - -event_route[E_JANUS_EVENT] { - xlog("Received janus event from $param(janus_id) - $param(janus_url) - $param(janus_body) \n"); - $json(janus_body) := $param(janus_body); - $avp(janus_sender) = $json(janus_body/sender); - if ($avp(janus_sender) != NULL) { - xlog("Received event from sender $avp(janus_sender) \n"); - } -} -... -... - - -
-
-
-
diff --git a/modules/janus/janus_common.c b/modules/janus/janus_common.c index f0c45ed9d5d..e08dafd4812 100644 --- a/modules/janus/janus_common.c +++ b/modules/janus/janus_common.c @@ -112,6 +112,10 @@ int janus_raise_event(janus_connection *conn, cJSON *request) } full_json = cJSON_Print(request); + if (!full_json) { + LM_ERR("cJSON_Print failed\n"); + goto err_free_params; + } cJSON_Minify(full_json); full_json_s.s = full_json; full_json_s.len = strlen(full_json); @@ -191,10 +195,15 @@ int handle_janus_json_request(janus_connection *conn, cJSON *request) } full_json = cJSON_Print(request); + if (!full_json) { + LM_ERR("cJSON_Print failed\n"); + return 1; + } cJSON_Minify(full_json); reply->text.s = shm_strdup(full_json); if (reply->text.s == NULL) { + pkg_free(full_json); /* we're out of mem, let the requestor timeout, don't disconnect janus */ return 1; } @@ -220,24 +229,32 @@ int populate_janus_handler_id(janus_connection *conn, cJSON *request) aux = cJSON_GetObjectItem(request, "janus"); if (aux == NULL || aux->type != cJSON_String || (reply_status.s = aux->valuestring) == NULL) { - LM_ERR("Unexpected JANUS reply received - %s\n",cJSON_Print(request)); + char *dbg = cJSON_Print(request); + LM_ERR("Unexpected JANUS reply received - %s\n", dbg); + pkg_free(dbg); return -1; } if (memcmp(reply_status.s,"success",7) != 0) { - LM_ERR("non-succesful JANUS reply received - %s\n",cJSON_Print(request)); + char *dbg = cJSON_Print(request); + LM_ERR("non-succesful JANUS reply received - %s\n", dbg); + pkg_free(dbg); return -1; } aux = cJSON_GetObjectItem(request, "data"); if (aux == NULL || aux->type != cJSON_Object) { - LM_ERR("Unexpected JANUS reply received, no data in %s\n",cJSON_Print(request)); + char *dbg = cJSON_Print(request); + LM_ERR("Unexpected JANUS reply received, no data in %s\n", dbg); + pkg_free(dbg); return -1; } aux2 = cJSON_GetObjectItem(aux, "id"); if (aux2 == NULL || aux2->type != cJSON_Number) { - LM_ERR("Unexpected JANUS reply received, id is not number %s\n",cJSON_Print(request)); + char *dbg = cJSON_Print(request); + LM_ERR("Unexpected JANUS reply received, id is not number %s\n", dbg); + pkg_free(dbg); return -1; } diff --git a/modules/janus/janus_mod.c b/modules/janus/janus_mod.c index c0e1cd83077..cc856fa7ac3 100644 --- a/modules/janus/janus_mod.c +++ b/modules/janus/janus_mod.c @@ -208,12 +208,14 @@ static int w_janus_send_request(struct sip_msg *msg, str *janus_id,str *request, if ((conn = get_janus_connection_by_id(janus_id)) == NULL) { LM_ERR("Unknown JANUS ID %.*s\n",janus_id->len,janus_id->s); + cJSON_Delete(j_request); return -1; } LM_DBG("Found our conn, prep to send out %.*s !! \n",request->len,request->s); reply_id = janus_ipc_send_request(conn,j_request); + cJSON_Delete(j_request); /* tree was serialized to shm; free pkg copy */ if (reply_id == 0) { LM_ERR("Failed to queue request %.*s towards %.*s\n", request->len,request->s, diff --git a/modules/janus/janus_proc.c b/modules/janus/janus_proc.c index 8f30bf7e620..299492ae7c2 100644 --- a/modules/janus/janus_proc.c +++ b/modules/janus/janus_proc.c @@ -282,14 +282,23 @@ uint64_t janus_ipc_send_request(janus_connection *sock, cJSON *janus_cmd) lock_stop_write(sock->lists_lk); full_cmd.s = cJSON_Print(janus_cmd); + if (!full_cmd.s) { + shm_free(cmd); + LM_ERR("cJSON_Print failed (pkg OOM)\n"); + return 0; + } full_cmd.len = strlen(full_cmd.s); if (shm_nt_str_dup(&cmd->janus_cmd, &full_cmd) != 0) { + pkg_free(full_cmd.s); shm_free(cmd); LM_ERR("oom\n"); return 0; } + /* cJSON_Print() allocates from pkg via module hooks; free after shm copy */ + pkg_free(full_cmd.s); + janus_transaction_id = cmd->janus_transaction_id; if (ipc_send_job(*janus_mgr_process_no, ipc_hdl_run_janus, cmd) != 0) { diff --git a/modules/janus/ws_common.h b/modules/janus/ws_common.h index 822ba6bcd48..e9e81762bbc 100644 --- a/modules/janus/ws_common.h +++ b/modules/janus/ws_common.h @@ -483,7 +483,7 @@ static int janus_connection_read_data(janus_connection *sock, struct janus_ws_re size=req->tcp.pos-req->tcp.parsed; if (size) { - LM_DBG("We still have %lu bytes, keeping connection \n", size); + LM_DBG("We still have %ld bytes, keeping connection \n", size); } if (handle_janus_json_request(sock, req->body) <0) { @@ -613,7 +613,7 @@ static int janus_connection_handler_id(janus_connection *sock, struct janus_ws_r size=req->tcp.pos-req->tcp.parsed; if (size) { - LM_DBG("We still have %lu bytes, keeping connection \n", size); + LM_DBG("We still have %ld bytes, keeping connection \n", size); } if (populate_janus_handler_id(sock, req->body) <0) { diff --git a/modules/janus/ws_handshake_common.h b/modules/janus/ws_handshake_common.h index 73edca3de99..9ccff247ae9 100644 --- a/modules/janus/ws_handshake_common.h +++ b/modules/janus/ws_handshake_common.h @@ -1164,6 +1164,13 @@ static int janus_ws_read_http(janus_connection *c, struct tcp_req *r) case '8': case '9': r->content_len=r->content_len*10+(*p-'0'); + if (r->content_len>=TCP_BUF_SIZE) { + LM_ERR("Content-Length value %d bigger than the " + "reading buffer\n", r->content_len); + r->error = TCP_REQ_BAD_LEN; + r->state = H_SKIP; + r->content_len = 0; + } break; case '\r': case ' ': diff --git a/modules/json/README b/modules/json/README deleted file mode 100644 index 5f50508b17b..00000000000 --- a/modules/json/README +++ /dev/null @@ -1,506 +0,0 @@ -JSON Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. enable_long_quoting (boolean) - - 1.4. Exported Pseudo-Variables - - 1.4.1. $json(id) - 1.4.2. $json_pretty(id) - 1.4.3. $json_compact(id) - - 1.5. Exported Functions - - 1.5.1. json_link($json(dest_id), $json(source_id)) - 1.5.2. - json_merge(main_json_var,patch_json_var,output - _var)) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set enable_long_quoting parameter - 1.2. Accessing the $json variable - 1.3. Iterating through an array using variables - 1.4. iteration over $json object keys - 1.5. iteration over $json object values - 1.6. iteration over $json array values - 1.7. Appending integers to arrays - 1.8. Deleting the last element in an array - 1.9. Adding a string value to a json object - 1.10. Initializing an array - 1.11. Setting a boolean or null value - 1.12. Adding a json to another json - 1.13. Creating a reference - 1.14. [LOGICAL ERROR] Creating a circular reference - 1.15. Using json_merge - -Chapter 1. Admin Guide - -1.1. Overview - - This module introduces a new type of variable that provides - both serialization and de-serialization from JSON format. - - The variable provides ways to access objects and arrays to - add,replace or delete values from the script. - - The correct approach is to consider a json object as a - hashtable ( you can put (key;value) pairs, and you can delete - and get values by key) and a json array as an array ( you can - append, delete and replace values). - - Since the JSON format can have objects inside other objects you - can have multiple nested hashtables or arrays and you can - access these using paths. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - This module does not depend on other modules. - -1.2.2. External Libraries or Applications - - * libjson The libjson C library can be downloaded from: - http://oss.metaparadigm.com/json-c/ - -1.3. Exported Parameters - -1.3.1. enable_long_quoting (boolean) - - Enable this parameter if your input JSONs contain signed - integers which do not fit into 4 bytes (e.g. larger than - 2147483647, etc.). If the parameter is enabled, 4-byte integers - will continue to be returned as integers, while larger values - will be returned as strings, in order to avoid the integer - overflow. - - Default value is false. - - Example 1.1. Set enable_long_quoting parameter -... -modparam("json", "enable_long_quoting", true) -... -# normalize the "gateway_id" int/string value to be always a string -$var(gateway_id) = "" + $json(body/gateway_id); -... - -1.4. Exported Pseudo-Variables - -1.4.1. $json(id) - - The json variable provides methods to access fields in json - objects and indexes in json arrays. - -1.4.1.1. Variable lifetime - - The json variables will be available to the process that - created them from the moment they were initialized. They will - not reset per message or per transaction. If you want to use - the on a per message basis you should initialize them each - time. - -1.4.1.2. Accessing the $json(id) variable - - The grammar that describes the id is: - - id = name(identifier)* - - identifier = key | index - - key = /string | /$var - - index = [integer] | [$var] | [] - - The "[]" index represents appending to the array. It should - only be used when trying to set a value and not when trying to - get one. - - Negative indexes can be used to access an array starting from - the end. So "[-1]" signifies the last element. - - IMPORTANT: The id strictly complies to this grammar. You should - be careful when using spaces because they will NOT be ignored. - This was done to allow keys that contain spaces. - - Variables can be used as indexes or keys. Variables that will - be used as indexes must contain integer values. Variables that - will be used as keys should contain string values. - - Trying to get a value from a non-existing path (key or value) - will return the NULL value and notice messages will be placed - in the log describing the value of the json and the path used. - - Trying to replace or insert a value in a non-existing path will - cause an error in setting the value and notice messages will be - printed in the log describing the value of the json and the - path used - - Example 1.2. Accessing the $json variable -... -$json(obj1/key) = "value"; #replace or insert the (key,value) - #pair into the json object; - -$json(matrix1[1][2]) = 1; #replace the element at index 2 in the elemen -t - #at index 1 in an array - -xlog("$json(name/key1[0][-1]/key2)"); # a more complex example - -... - - Example 1.3. Iterating through an array using variables -... - -$json(ar1) := "[1,2,3,4]"; - -$var(i) = 0; - -while( $json(ar1[$var(i)]) ) -{ - - #print each value - xlog("Found:[$json(ar1[$var(i)])]\n"); - - #increment each value - $json(ar1[$var(i)]) = $json(ar1[$var(i)]) + 1 ; - - $var(i) = $var(i) + 1; - -} - - -... - -1.4.1.3. Traversal - - Dynamic traversal of a JSON object or array is possible by - using a for each statement, similarly to the indexed pseudo - variables iteration. However, note that indexing the $json - variable is not supported in any other statements (this refers - to indexing the entire variable and not to the indexes accepted - in the grammar of the id). - - In order to explicitly iterate over a JSON object keys or - values, you can use the .keys or .values suffix for the path - specified in the id. - - Example 1.4. iteration over $json object keys -... -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(k) in $(json(foo.keys)[*])) - xlog("$var(k) "); -... - - Example 1.5. iteration over $json object values -... -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(v) in $(json(foo.values)[*])) - xlog("$var(v) "); - -# equivalent to: - -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(v) in $(json(foo)[*])) - xlog("$var(v) "); -... - - Example 1.6. iteration over $json array values -... -$json(foo) := "[1, 2, 3]"; -for ($var(v) in $(json(foo)[*])) - xlog("$var(v) "); -... - -1.4.1.4. Returned values from $json(id) - - If the value specified by the id is an integer it will be - returned as an integer value. - - If the value specified by the id is a string it will be - returned as a string. - - If the value specified by the id is any other type of json ( - null, boolean, object, array ) the serialized version of the - object will be returned as a string value. Using this and the - ":=" operator you can duplicate json objects and put them in - other json objects ( for string or integer you may use the "=" - operator). - - If the id does not exist a NULL value will be returned. - -1.4.1.5. Operators for the $json(id) variable - - There are 2 operators available for this variable. - -1.4.1.5.1. The "=" operator - - This will cause the value to be taken as is and be added to the - json object ( e.g. string value or integer value ). - - Setting a value to NULL will cause it to be deleted. - - Example 1.7. Appending integers to arrays -... -$json(array1[]) = 1; -... - - Example 1.8. Deleting the last element in an array -... -$json(array1[-1]) = NULL; -... - - Example 1.9. Adding a string value to a json object -... -$json(object1/some_key) = "some_value"; -... - -1.4.1.5.2. The ":=" operator - - This will cause the value to be taken and interpreted as a json - object ( e.g. this operator should be used to parse json inputs - ). - - Example 1.10. Initializing an array -... -$json(array1) := "[]"; -... - - Example 1.11. Setting a boolean or null value -... -$json(array1[]) := "null"; -$json(array1[]) := "true"; -$json(array1[]) := "false"; -... - - Example 1.12. Adding a json to another json -... - -$json(array) := "[1,2,3]"; -$json(object) := "{}"; -$json(object/array) := $json(array) ; -... - -1.4.2. $json_pretty(id) - - The json_pretty variable has the same purpose as the json - variable, but prints the JSON object in a pretty format, adding - spaces and tabs to make the output more readable. - -1.4.3. $json_compact(id) - - The json_compact variable has the same purpose as the json - variable, but prints the JSON object in a more compact form, - without formatting spaces. - -1.5. Exported Functions - -1.5.1. json_link($json(dest_id), $json(source_id)) - - This function can be used to link json objects together. This - will work simillar to setting a value to an object, the only - difference is that the second object is not copied, only a - reference is created. - - Changes to any of the objects will be visible in both of them. - - You can use this method either to create references so each - time you access the field you don't have to go through the full - path (for speed efficiency and shorter code), or if you have an - object that must be added to many other objects and you don't - want to copy it each time (space and speed efficiency). - - You can think of this object exactly as a reference in an - object-oriented language. Modifying fields referenced by the - variable will cause modifications in all the objects, BUT - modifying the variable itsef will not cause any changes to - other objects. - - WARNING: You should be careful when using references. If you - accidentally create a circular reference and try to get the - value from the object you will crash OPENSIPS. - - Example 1.13. Creating a reference -... - -$json(b) := "[{},{},{}]"; - -json_link($json(stub), $json(b[0])); - -$json(stub/ana) = "are"; #add to the stub -$json(stub/ar) := "[]"; -$json(stub/ar[]) = 1; -$json(stub/ar[]) = 2; -$json(stub/ar[]) = 3; - -$json(b[0]/ar[0]) = NULL; # delete from the original object - -xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); - -/*Output: - -Test link : -{ "ana": "are", "ar": [ 2, 3 ] } -[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ] - -*/ - -$json(stub) = NULL; #delete the stub, no change will happen to the sourc -e - - -xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); - -/* Output: - -Test link : - -[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ] - -*/ - - - - - -... - - Example 1.14. [LOGICAL ERROR] Creating a circular reference -... - -$json(b) := "[1]"; - -/* NEVER do this, it is meant only to show where problems might occur * -/ -json_link($json(b[0]), $json(b)); # replace 1 with a reference to b - -xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); - -/* this will cause OPENSIPS to crash because it will continuously try - to get b, then b[0], then b ... */ - - -... - -1.5.2. json_merge(main_json_var,patch_json_var,output_var)) - - The function can be used to patch merge patch_json_var into - main_json_var and the output will be populated into the - output_var - - Example 1.15. Using json_merge -... - -$json(val1) := "{}"; -$json(val1/test1) = "test_val1"; -$json(val1/common_val) = "val_from1"; - -$json(val2) := "{}"; -$json(val2/test2) = "test_val2"; -$json(val1/common_val) = "val_from2"; - -json_merge($json(val1),$json(val2),$var(merged_json)); -xlog("we merged and got $var(merged_json) \n"); -# will print : -# we merged and got {"test1":"test_val1","common_val":"val_from2","test2 -":"test_val2"} - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 20 17 84 92 - 2. Andrei Dragus 19 4 1556 12 - 3. Razvan Crainea (@razvancrainea) 14 11 48 76 - 4. Vlad Paiu (@vladpaiu) 10 7 131 19 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 27 30 - 6. Vlad Patrascu (@rvlad-patrascu) 8 4 195 75 - 7. Maksym Sobolyev (@sobomax) 5 3 12 12 - 8. Björn Esser (@besser82) 5 2 124 44 - 9. Ovidiu Sas (@ovidiusas) 4 2 17 4 - 10. Nick Altmann (@nikbyte) 3 1 47 15 - - All remaining contributors: Anca Vamanu, Peter Lemenkov - (@lemenkov), Bence Szigeti, Julián Moreno Patiño. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Vlad Paiu (@vladpaiu) Jul 2014 - Jan 2025 - 2. Liviu Chircu (@liviuchircu) Oct 2013 - Dec 2024 - 3. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 4. Bence Szigeti Nov 2023 - Nov 2023 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2010 - Apr 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Nick Altmann (@nikbyte) Jan 2018 - Jan 2018 - 10. Björn Esser (@besser82) Dec 2017 - Dec 2017 - - All remaining contributors: Julián Moreno Patiño, Ovidiu Sas - (@ovidiusas), Anca Vamanu, Andrei Dragus. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Nick Altmann (@nikbyte), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Andrei - Dragus. - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/json/README.md b/modules/json/README.md new file mode 100644 index 00000000000..024548f8ef1 --- /dev/null +++ b/modules/json/README.md @@ -0,0 +1,491 @@ +--- +title: "JSON Module" +description: "This module introduces a new type of variable that provides both serialization and de-serialization from JSON format." +--- + +## Admin Guide + + +### Overview + + +This module introduces a new type of variable that provides both +serialization and de-serialization from JSON format. + + +The variable provides ways to access objects and arrays to add,replace +or delete values from the script. + + +The correct approach is to consider a json object as a hashtable +( you can put (key;value) pairs, and you can delete and get +values by key) and a json array as an array ( you can append, +delete and replace values). + + +Since the JSON format can have objects inside other objects +you can have multiple nested hashtables or arrays and you can +access these using paths. + + +### Dependencies + + +#### OpenSIPS Modules + + +This module does not depend on other modules. + + +#### External Libraries or Applications + + +- *libjson* +The libjson C library can be downloaded from: +http://oss.metaparadigm.com/json-c/ + + +### Exported Parameters + + +#### enable_long_quoting (boolean) + + +Enable this parameter if your input JSONs contain signed integers which +do not fit into 4 bytes (e.g. larger than 2147483647, etc.). If the +parameter is enabled, 4-byte integers will continue to be returned as +integers, while larger values will be returned as strings, in order to +avoid the integer overflow. + + +*Default value is *false*.* + + +```opensips title="Set enable_long_quoting parameter" +... +modparam("json", "enable_long_quoting", true) +... +# normalize the "gateway_id" int/string value to be always a string +$var(gateway_id) = "" + $json(body/gateway_id); +... +``` + + +### Exported Pseudo-Variables + + +#### $json(id) + + +The `json` variable provides +methods to access fields in json objects and +indexes in json arrays. + + +##### Variable lifetime + + +The json variables will be available to the +process that created them from the moment they were +initialized. They will not reset per message or per +transaction. If you want to use the on a per message +basis you should initialize them each time. + + +##### Accessing the $json(id) variable + + +The grammar that describes the id is: + + +- id = name(identifier)* + + +- identifier = key | index + + +- key = /string | /$var + + +- index = [integer] | [$var] | [] + + +The "[]" index represents appending to the array. +It should only be used when trying to set a value and +not when trying to get one. + + +Negative indexes can be used to access an array starting +from the end. So "[-1]" signifies the last element. + + +> [!IMPORTANT] +> The id strictly complies to this grammar. +> You should be careful when using spaces because they will +> NOT be ignored. This was done to allow keys that contain +> spaces. + + +Variables can be used as indexes or keys. Variables +that will be used as indexes must contain integer values. +Variables that will be used as keys should contain +string values. + + +Trying to get a value from a non-existing path +(key or value) will return the NULL value and notice +messages will be placed in the log describing the value +of the json and the path used. + + +Trying to replace or insert a value in a +non-existing path will cause an error in setting the value +and notice messages will be printed in the log +describing the value of the json and the path used + + +```opensips title="Accessing the $json variable" +... +$json(obj1/key) = "value"; #replace or insert the (key,value) + #pair into the json object; + +$json(matrix1[1][2]) = 1; #replace the element at index 2 in the element + #at index 1 in an array + +xlog("$json(name/key1[0][-1]/key2)"); # a more complex example + +... + +``` + + +```opensips title="Iterating through an array using variables" +... + +$json(ar1) := "[1,2,3,4]"; + +$var(i) = 0; + +while( $json(ar1[$var(i)]) ) +{ + + #print each value + xlog("Found:[$json(ar1[$var(i)])]\n"); + + #increment each value + $json(ar1[$var(i)]) = $json(ar1[$var(i)]) + 1 ; + + $var(i) = $var(i) + 1; + +} + + +... + +``` + + +##### Traversal + + +Dynamic traversal of a JSON object or array is possible by using a +for each statement, similarly to the indexed pseudo variables iteration. +However, note that indexing the $json variable is not supported in +any other statements (this refers to indexing the entire variable +and not to the indexes accepted in the grammar of the *id*). + + +In order to explicitly iterate over a JSON object keys or values, you can use the +*.keys* or *.values* suffix for the path +specified in the *id*. + + +```opensips title="iteration over $json object keys" +... +$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; +for ($var(k) in $(json(foo.keys)[*])) + xlog("$var(k) "); +... + +``` + + +```opensips title="iteration over $json object values" +... +$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; +for ($var(v) in $(json(foo.values)[*])) + xlog("$var(v) "); + +# equivalent to: + +$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; +for ($var(v) in $(json(foo)[*])) + xlog("$var(v) "); +... + +``` + + +```opensips title="iteration over $json array values" +... +$json(foo) := "[1, 2, 3]"; +for ($var(v) in $(json(foo)[*])) + xlog("$var(v) "); +... + +``` + + +##### Returned values from $json(id) + + +If the value specified by the id is an integer +it will be returned as an integer value. + + +If the value specified by the id is a string it will +be returned as a string. + + +If the value specified by the id is any other +type of json ( null, boolean, object, array ) +the serialized version of the object will be returned +as a string value. Using this and the ":=" +operator you can duplicate json objects and put them +in other json objects ( for string or integer you may +use the "=" operator). + + +If the id does not exist a NULL value will be returned. + + +##### Operators for the $json(id) variable + + +There are 2 operators available for this variable. + + +###### The "=" operator + + +This will cause the value to be taken +as is and be added to the json object +( e.g. string value or integer value ). + + +Setting a value to NULL will cause it to be +deleted. + + +```opensips title="Appending integers to arrays" +... +$json(array1[]) = 1; +... + +``` + + +```opensips title="Deleting the last element in an array" +... +$json(array1[-1]) = NULL; +... + +``` + + +```opensips title="Adding a string value to a json object" +... +$json(object1/some_key) = "some_value"; +... + +``` + + +###### The ":=" operator + + +This will cause the value to be taken +and interpreted as a json object +( e.g. this operator should be used to parse +json inputs ). + + +```opensips title="Initializing an array" +... +$json(array1) := "[]"; +... + +``` + + +```opensips title="Setting a boolean or null value" +... +$json(array1[]) := "null"; +$json(array1[]) := "true"; +$json(array1[]) := "false"; +... + +``` + + +```opensips title="Adding a json to another json" +... + +$json(array) := "[1,2,3]"; +$json(object) := "{}"; +$json(object/array) := $json(array) ; +... + +``` + + +#### $json_pretty(id) + + +The `json_pretty` variable has the +same purpose as the `json` variable, +but prints the JSON object in a pretty format, adding +spaces and tabs to make the output more readable. + + +#### $json_compact(id) + + +The `json_compact` variable has the +same purpose as the `json` variable, +but prints the JSON object in a more compact form, +without formatting spaces. + + +### Exported Functions + + +#### json_link($json(dest_id), $json(source_id)) + + +This function can be used to link json objects together. +This will work simillar to setting a value to an object, +the only difference is that the second object is not +copied, only a reference is created. + + +Changes to any of the objects will be visible in both of +them. + + +You can use this method either to create references +so each time you access the field you don't +have to go through the full path +(for speed efficiency and shorter code), or +if you have an object that must be added to many +other objects and you don't want to copy it each +time (space and speed efficiency). + + +You can think of this object exactly as a reference +in an object-oriented language. Modifying fields +referenced by the variable will cause modifications +in all the objects, BUT modifying the variable itsef +will not cause any changes to other objects. + + +> [!WARNING] +> You should be careful when using references. +> If you accidentally create a circular reference and try +> to get the value from the object you will crash OPENSIPS. + + +```opensips title="Creating a reference" +... + +$json(b) := "[{},{},{}]"; + +json_link($json(stub), $json(b[0])); + +$json(stub/ana) = "are"; #add to the stub +$json(stub/ar) := "[]"; +$json(stub/ar[]) = 1; +$json(stub/ar[]) = 2; +$json(stub/ar[]) = 3; + +$json(b[0]/ar[0]) = NULL; # delete from the original object + +xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); + +/*Output: + +Test link : +{ "ana": "are", "ar": [ 2, 3 ] } +[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ] + +*/ + +$json(stub) = NULL; #delete the stub, no change will happen to the source + + +xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); + +/* Output: + +Test link : + +[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ] + +*/ + + + + + +... + +``` + + +```opensips title="[LOGICAL ERROR] Creating a circular reference" +... + +$json(b) := "[1]"; + +/* NEVER do this, it is meant only to show where problems might occur */ +json_link($json(b[0]), $json(b)); # replace 1 with a reference to b + +xlog("\nTest link :\n$json(stub)\n$json(b)\n\n"); + +/* this will cause OPENSIPS to crash because it will continuously try + to get b, then b[0], then b ... */ + + +... + +``` + + +#### json_merge(main_json_var,patch_json_var,output_var)) + + +The function can be used to patch merge patch_json_var into main_json_var and the output will be populated into the output_var + + +```opensips title="Using json_merge" +... + +$json(val1) := "{}"; +$json(val1/test1) = "test_val1"; +$json(val1/common_val) = "val_from1"; + +$json(val2) := "{}"; +$json(val2/test2) = "test_val2"; +$json(val1/common_val) = "val_from2"; + +json_merge($json(val1),$json(val2),$var(merged_json)); +xlog("we merged and got $var(merged_json) \n"); +# will print : +# we merged and got {"test1":"test_val1","common_val":"val_from2","test2":"test_val2"} + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/json/doc/contributors.xml b/modules/json/doc/contributors.xml deleted file mode 100644 index 9efe99d40fd..00000000000 --- a/modules/json/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 20 - 17 - 84 - 92 - - - 2. - Andrei Dragus - 19 - 4 - 1556 - 12 - - - 3. - Razvan Crainea (@razvancrainea) - 14 - 11 - 48 - 76 - - - 4. - Vlad Paiu (@vladpaiu) - 10 - 7 - 131 - 19 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 27 - 30 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 8 - 4 - 195 - 75 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 12 - 12 - - - 8. - Björn Esser (@besser82) - 5 - 2 - 124 - 44 - - - 9. - Ovidiu Sas (@ovidiusas) - 4 - 2 - 17 - 4 - - - 10. - Nick Altmann (@nikbyte) - 3 - 1 - 47 - 15 - - - -
-All remaining contributors: Anca Vamanu, Peter Lemenkov (@lemenkov), Bence Szigeti, Julián Moreno Patiño. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Vlad Paiu (@vladpaiu) - Jul 2014 - Jan 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Oct 2013 - Dec 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 4. - Bence Szigeti - Nov 2023 - Nov 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2010 - Apr 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Nick Altmann (@nikbyte) - Jan 2018 - Jan 2018 - - - 10. - Björn Esser (@besser82) - Dec 2017 - Dec 2017 - - - -
-All remaining contributors: Julián Moreno Patiño, Ovidiu Sas (@ovidiusas), Anca Vamanu, Andrei Dragus. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Andrei Dragus. -
- -
diff --git a/modules/json/doc/json.xml b/modules/json/doc/json.xml deleted file mode 100644 index 053678e1a29..00000000000 --- a/modules/json/doc/json.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - JSON Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - - - - diff --git a/modules/json/doc/json_admin.xml b/modules/json/doc/json_admin.xml deleted file mode 100644 index b73d7159436..00000000000 --- a/modules/json/doc/json_admin.xml +++ /dev/null @@ -1,574 +0,0 @@ - - - - &adminguide; - -
- Overview - This module introduces a new type of variable that provides both - serialization and de-serialization from JSON format. - - - The variable provides ways to access objects and arrays to add,replace - or delete values from the script. - - - - The correct approach is to consider a json object as a hashtable - ( you can put (key;value) pairs, and you can delete and get - values by key) and a json array as an array ( you can append, - delete and replace values). - - - - Since the JSON format can have objects inside other objects - you can have multiple nested hashtables or arrays and you can - access these using paths. - - - -
- -
- Dependencies -
- &osips; Modules - - This module does not depend on other modules. - -
- -
- External Libraries or Applications - - - - libjson - The libjson C library can be downloaded from: - http://oss.metaparadigm.com/json-c/ - - - - -
-
- -
- Exported Parameters - -
- <varname>enable_long_quoting</varname> (boolean) - - Enable this parameter if your input JSONs contain signed integers which - do not fit into 4 bytes (e.g. larger than 2147483647, etc.). If the - parameter is enabled, 4-byte integers will continue to be returned as - integers, while larger values will be returned as strings, in order to - avoid the integer overflow. - - - - Default value is false. - - - - Set <varname>enable_long_quoting</varname> parameter - -... -modparam("json", "enable_long_quoting", true) -... -# normalize the "gateway_id" int/string value to be always a string -$var(gateway_id) = "" + $json(body/gateway_id); -... - - -
- -
- - -
- Exported Pseudo-Variables - -
- <varname>$json(id)</varname> - - The json variable provides - methods to access fields in json objects and - indexes in json arrays. - - -
- Variable lifetime - - - The json variables will be available to the - process that created them from the moment they were - initialized. They will not reset per message or per - transaction. If you want to use the on a per message - basis you should initialize them each time. - - - -
- -
- Accessing the $json(id) variable - - - The grammar that describes the id is: - - - - id = name(identifier)* - - - identifier = key | index - - - key = /string | /$var - - - index = [integer] | [$var] | [] - - - - The "[]" index represents appending to the array. - It should only be used when trying to set a value and - not when trying to get one. - - - - Negative indexes can be used to access an array starting - from the end. So "[-1]" signifies the last element. - - - - IMPORTANT: The id strictly complies to this grammar. - You should be careful when using spaces because they will - NOT be ignored. This was done to allow keys that contain - spaces. - - - - Variables can be used as indexes or keys. Variables - that will be used as indexes must contain integer values. - Variables that will be used as keys should contain - string values. - - - - - - - Trying to get a value from a non-existing path - (key or value) will return the NULL value and notice - messages will be placed in the log describing the value - of the json and the path used. - - - - Trying to replace or insert a value in a - non-existing path will cause an error in setting the value - and notice messages will be printed in the log - describing the value of the json and the path used - - - - - Accessing the $json variable - -... -$json(obj1/key) = "value"; #replace or insert the (key,value) - #pair into the json object; - -$json(matrix1[1][2]) = 1; #replace the element at index 2 in the element - #at index 1 in an array - -xlog("$json(name/key1[0][-1]/key2)"); # a more complex example - -... - - - - - Iterating through an array using variables - -... - -$json(ar1) := "[1,2,3,4]"; - -$var(i) = 0; - -while( $json(ar1[$var(i)]) ) -{ - - #print each value - xlog("Found:[$json(ar1[$var(i)])]\n"); - - #increment each value - $json(ar1[$var(i)]) = $json(ar1[$var(i)]) + 1 ; - - $var(i) = $var(i) + 1; - -} - - -... - - - -
- -
- Traversal - - Dynamic traversal of a JSON object or array is possible by using a - for each statement, similarly to the indexed pseudo variables iteration. - However, note that indexing the $json variable is not supported in - any other statements (this refers to indexing the entire variable - and not to the indexes accepted in the grammar of the id). - - - In order to explicitly iterate over a JSON object keys or values, you can use the - .keys or .values suffix for the path - specified in the id. - - - - iteration over $json object keys - -... -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(k) in $(json(foo.keys)[*])) - xlog("$var(k) "); -... - - - - - iteration over $json object values - -... -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(v) in $(json(foo.values)[*])) - xlog("$var(v) "); - -# equivalent to: - -$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}"; -for ($var(v) in $(json(foo)[*])) - xlog("$var(v) "); -... - - - - - iteration over $json array values - -... -$json(foo) := "[1, 2, 3]"; -for ($var(v) in $(json(foo)[*])) - xlog("$var(v) "); -... - - -
- -
- Returned values from $json(id) - - - If the value specified by the id is an integer - it will be returned as an integer value. - - - - If the value specified by the id is a string it will - be returned as a string. - - - - If the value specified by the id is any other - type of json ( null, boolean, object, array ) - the serialized version of the object will be returned - as a string value. Using this and the ":=" - operator you can duplicate json objects and put them - in other json objects ( for string or integer you may - use the "=" operator). - - - - - - If the id does not exist a NULL value will be returned. - - - -
- -
- Operators for the $json(id) variable - - - There are 2 operators available for this variable. - - -
- The "=" operator - - This will cause the value to be taken - as is and be added to the json object - ( e.g. string value or integer value ). - - - - Setting a value to NULL will cause it to be - deleted. - - - - Appending integers to arrays - -... -$json(array1[]) = 1; -... - - - - - Deleting the last element in an array - -... -$json(array1[-1]) = NULL; -... - - - - - - Adding a string value to a json object - -... -$json(object1/some_key) = "some_value"; -... - - - -
- -
- The ":=" operator - - This will cause the value to be taken - and interpreted as a json object - ( e.g. this operator should be used to parse - json inputs ). - - - - Initializing an array - -... -$json(array1) := "[]"; -... - - - - - Setting a boolean or null value - -... -$json(array1[]) := "null"; -$json(array1[]) := "true"; -$json(array1[]) := "false"; -... - - - - - Adding a json to another json - -... - -$json(array) := "[1,2,3]"; -$json(object) := "{}"; -$json(object/array) := $json(array) ; -... - - - -
- -
-
-
- <varname>$json_pretty(id)</varname> - - The json_pretty variable has the - same purpose as the json variable, - but prints the JSON object in a pretty format, adding - spaces and tabs to make the output more readable. - -
-
- <varname>$json_compact(id)</varname> - - The json_compact variable has the - same purpose as the json variable, - but prints the JSON object in a more compact form, - without formatting spaces. - -
-
- -
- Exported Functions - - - -
- - <function moreinfo="none"> - json_merge(main_json_var,patch_json_var,output_var)) - </function> - - - The function can be used to patch merge patch_json_var into main_json_var and the output will be populated into the output_var - - - - Using json_merge - -... - -$json(val1) := "{}"; -$json(val1/test1) = "test_val1"; -$json(val1/common_val) = "val_from1"; - -$json(val2) := "{}"; -$json(val2/test2) = "test_val2"; -$json(val1/common_val) = "val_from2"; - -json_merge($json(val1),$json(val2),$var(merged_json)); -xlog("we merged and got $var(merged_json) \n"); -# will print : -# we merged and got {"test1":"test_val1","common_val":"val_from2","test2":"test_val2"} - - -
-
-
- diff --git a/modules/jsonrpc/README b/modules/jsonrpc/README deleted file mode 100644 index 9f34950fe2a..00000000000 --- a/modules/jsonrpc/README +++ /dev/null @@ -1,233 +0,0 @@ -JSON-RPC Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. connect_timeout (integer) - 1.3.2. write_timeout (integer) - 1.3.3. read_timeout (integer) - - 1.4. Exported Functions - - 1.4.1. jsonrpc_request(destination, method, params, - ret_var) - - 1.4.2. jsonrpc_notification(destination, method, - params) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set connect_timeout parameter - 1.2. Set write_timeout parameter - 1.3. Set read_timeout parameter - 1.4. jsonrpc_request() function usage - 1.5. jsonrpc_notification() function usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is an implementation of an JSON-RPC v2.0 client - http://www.jsonrpc.org/specification. that can send a call to a - JSON-RPC server over a TCP connection. - - NOTE that the current version of this module does not support - TCP connection reusage, nor asynchronous commands. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * none. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.3. Exported Parameters - -1.3.1. connect_timeout (integer) - - The amount of milliseconds OpenSIPS waits to connect to the the - JSON-RPC server, until it times out. - - Default value is “500 milliseconds”. - - Example 1.1. Set connect_timeout parameter -... -modparam("jsonrpc", "connect_timeout", 200) -... - -1.3.2. write_timeout (integer) - - The amount of milliseconds OpenSIPS waits to send a RPC command - to the JSON-RPC server, until it times out. - - Default value is “500 milliseconds”. - - Example 1.2. Set write_timeout parameter -... -modparam("jsonrpc", "write_timeout", 300) -... - -1.3.3. read_timeout (integer) - - The amount of milliseconds OpenSIPS waits for the JSON-RPC - server to respond to a JSON-RPC request, until it times out. - Note that these parameter only affects the jsonrpc_request - command. - - Default value is “500 milliseconds”. - - Example 1.3. Set read_timeout parameter -... -modparam("jsonrpc", "read_timeout", 300) -... - -1.4. Exported Functions - -1.4.1. jsonrpc_request(destination, method, params, ret_var) - - Does a JSON-RPC request to the JSON-RPC server indicated in the - destination parameter, and waits for a reply from it. - - This function can be used from any route. - - The function has the following parameters: - * destination (string) - address of the JSON-RPC server. The - format needs to be IP:port. - * method (string) - the method used in the RPC request. - * params (string) - these are the parameters sent to the RPC - method. This parameter needs to be a properly formated JSON - array, or JSON object, according the the JSON-RPC - specifications. - * ret_var a writeable variable used to store the result of - the JSON-RPC command. If the command returns an error, the - variable will be populated with the error JSON, otherwise, - with the body of the JSON-RPC result. - - The function has the following return codes: - * 1 - JSON-RPC command executed successfully, and the server - returned success. You can check the ret_pvar variable for - the result. - * -1 - There was an internal error during processing. - * -2 - There was a connection (timeout or connect) error with - the destination. - * -3 - The JSON-RPC was successfully run, but the server - returned an error. Check the ret_pvar value to find out - more information. - - Example 1.4. jsonrpc_request() function usage - ... - if (!jsonrpc_request("127.0.0.1", "add", "[1,2]", $var(ret))) { - xlog("JSON-RPC command failed with $var(ret)\n"); - exit; - } - xlog(JSON-RPC command returned $var(ret)\n"); - # parse $var(ret) as JSON, or whatever the function returns - ... - -1.4.2. jsonrpc_notification(destination, method, params) - - Does a JSON-RPC notification to the JSON-RPC server indicated - in the destination parameter, but unlike jsonrpc_request(), it - does not wait for a reply from the JSON-RPC server. - - This function can be used from any route. - - The function receives the same parameters as jsonrpc_request(), - except for the ret_pvar. Also, the same values are returned. - - Example 1.5. jsonrpc_notification() function usage - ... - if (!jsonrpc_notification("127.0.0.1", "block_ip", "{ \"ip": \"$ -si\" }")) { - xlog("JSON-RPC notification failed with $rc!\n"); - exit; - } - ... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 16 7 931 11 - 2. Liviu Chircu (@liviuchircu) 6 4 16 32 - 3. Vlad Patrascu (@rvlad-patrascu) 6 2 33 128 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 4 2 - 5. Maksym Sobolyev (@sobomax) 3 1 3 3 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2018 - Apr 2023 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Mar 2018 - Nov 2019 - 4. Vlad Patrascu (@rvlad-patrascu) Apr 2019 - Apr 2019 - 5. Liviu Chircu (@liviuchircu) Apr 2018 - Nov 2018 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2018 www.opensips-solutions.com diff --git a/modules/jsonrpc/README.md b/modules/jsonrpc/README.md new file mode 100644 index 00000000000..4883be96f59 --- /dev/null +++ b/modules/jsonrpc/README.md @@ -0,0 +1,192 @@ +--- +title: "JSON-RPC Module" +description: "This module is an implementation of an JSON-RPC v2.0 client [http://www.jsonrpc.org/specification](http://www.jsonrpc.org/specification). that can send a call to a JSON-RPC server over a TCP connection." +--- + +## Admin Guide + + +### Overview + + +This module is an implementation of an JSON-RPC v2.0 +client [http://www.jsonrpc.org/specification](http://www.jsonrpc.org/specification). +that can send a call to a JSON-RPC server over a TCP connection. + + +> [!NOTE] +> That the current version of this module does not support TCP +> connection reusage, nor asynchronous commands. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *none*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### connect_timeout (integer) + + +The amount of milliseconds OpenSIPS waits to connect to the the +JSON-RPC server, until it times out. + + +*Default value is "500 milliseconds".* + + +```opensips title="Set connect_timeout parameter" +... +modparam("jsonrpc", "connect_timeout", 200) +... +``` + + +#### write_timeout (integer) + + +The amount of milliseconds OpenSIPS waits to send a RPC command to +the JSON-RPC server, until it times out. + + +*Default value is "500 milliseconds".* + + +```opensips title="Set write_timeout parameter" +... +modparam("jsonrpc", "write_timeout", 300) +... +``` + + +#### read_timeout (integer) + + +The amount of milliseconds OpenSIPS waits for the JSON-RPC server +to respond to a JSON-RPC request, until it times out. Note that +these parameter only affects the *jsonrpc_request* +command. + + +*Default value is "500 milliseconds".* + + +```opensips title="Set read_timeout parameter" +... +modparam("jsonrpc", "read_timeout", 300) +... +``` + + +### Exported Functions + + +#### jsonrpc_request(destination, method, params, ret_var) + + +Does a JSON-RPC request to the JSON-RPC server +indicated in the *destination* +parameter, and waits for a reply from it. + + +This function can be used from any route. + + +The function has the following parameters: + + +- *destination* (string) - address of the +JSON-RPC server. The format needs to be +*IP:port*. +- *method* (string) - the method used in +the RPC request. +- *params* (string) - these are the parameters +sent to the RPC method. This parameter needs to be +a properly formated JSON array, or JSON object, +according the the JSON-RPC specifications. +- *ret_var* a writeable variable +used to store the result of the JSON-RPC command. If +the command returns an error, the variable will be +populated with the error JSON, otherwise, with the +body of the JSON-RPC result. + + +The function has the following return codes: + + +- *1* - JSON-RPC command executed +successfully, and the server returned success. You can +check the *ret_pvar* variable for +the result. +- *-1* - There was an internal error +during processing. +- *-2* - There was a connection +(timeout or connect) error with the destination. +- *-3* - The JSON-RPC was +successfully run, but the server returned an error. +Check the *ret_pvar* value to find +out more information. + + +```opensips title="jsonrpc_request() function usage" + ... + if (!jsonrpc_request("127.0.0.1", "add", "[1,2]", $var(ret))) { + xlog("JSON-RPC command failed with $var(ret)\n"); + exit; + } + xlog(JSON-RPC command returned $var(ret)\n"); + # parse $var(ret) as JSON, or whatever the function returns + ... + +``` + + +#### jsonrpc_notification(destination, method, params) + + +Does a JSON-RPC notification to the JSON-RPC server +indicated in the *destination* +parameter, but unlike [jsonrpc request](#func_jsonrpc_request), +it does not wait for a reply from the JSON-RPC server. + + +This function can be used from any route. + + +The function receives the same parameters as +[jsonrpc request](#func_jsonrpc_request), except for the *ret_pvar*. Also, the same values are returned. + + +```opensips title="jsonrpc_notification() function usage" + ... + if (!jsonrpc_notification("127.0.0.1", "block_ip", "{ \"ip": \"$si\" }")) { + xlog("JSON-RPC notification failed with $rc!\n"); + exit; + } + ... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/jsonrpc/doc/contributors.xml b/modules/jsonrpc/doc/contributors.xml deleted file mode 100644 index 7686fe9cebb..00000000000 --- a/modules/jsonrpc/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 16 - 7 - 931 - 11 - - - 2. - Liviu Chircu (@liviuchircu) - 6 - 4 - 16 - 32 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 6 - 2 - 33 - 128 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 4 - 2 - - - 5. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2018 - Apr 2023 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Mar 2018 - Nov 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Apr 2019 - Apr 2019 - - - 5. - Liviu Chircu (@liviuchircu) - Apr 2018 - Nov 2018 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/jsonrpc/doc/jsonrpc.xml b/modules/jsonrpc/doc/jsonrpc.xml deleted file mode 100644 index 1806950868b..00000000000 --- a/modules/jsonrpc/doc/jsonrpc.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - JSON-RPC Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2018 &osipssol; - diff --git a/modules/jsonrpc/doc/jsonrpc_admin.xml b/modules/jsonrpc/doc/jsonrpc_admin.xml deleted file mode 100644 index 2c8ed56fd63..00000000000 --- a/modules/jsonrpc/doc/jsonrpc_admin.xml +++ /dev/null @@ -1,247 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is an implementation of an JSON-RPC v2.0 - client . - that can send a call to a JSON-RPC server over a TCP connection. - - - - NOTE that the current version of this module does not support TCP - connection reusage, nor asynchronous commands. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters -
- <varname>connect_timeout</varname> (integer) - - The amount of milliseconds &osips; waits to connect to the the - JSON-RPC server, until it times out. - - - - Default value is 500 milliseconds. - - - - Set <varname>connect_timeout</varname> parameter - -... -modparam("jsonrpc", "connect_timeout", 200) -... - - -
-
- <varname>write_timeout</varname> (integer) - - The amount of milliseconds &osips; waits to send a RPC command to - the JSON-RPC server, until it times out. - - - - Default value is 500 milliseconds. - - - - Set <varname>write_timeout</varname> parameter - -... -modparam("jsonrpc", "write_timeout", 300) -... - - -
-
- <varname>read_timeout</varname> (integer) - - The amount of milliseconds &osips; waits for the JSON-RPC server - to respond to a JSON-RPC request, until it times out. Note that - these parameter only affects the jsonrpc_request - command. - - - - Default value is 500 milliseconds. - - - - Set <varname>read_timeout</varname> parameter - -... -modparam("jsonrpc", "read_timeout", 300) -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">jsonrpc_request(destination, method, params, ret_var)</function> - - - Does a JSON-RPC request to the JSON-RPC server - indicated in the destination - parameter, and waits for a reply from it. - - - This function can be used from any route. - - - The function has the following parameters: - - - - - destination (string) - address of the - JSON-RPC server. The format needs to be - IP:port. - - - - - method (string) - the method used in - the RPC request. - - - - - params (string) - these are the parameters - sent to the RPC method. This parameter needs to be - a properly formated JSON array, or JSON object, - according the the JSON-RPC specifications. - - - - - ret_var a writeable variable - used to store the result of the JSON-RPC command. If - the command returns an error, the variable will be - populated with the error JSON, otherwise, with the - body of the JSON-RPC result. - - - - - The function has the following return codes: - - - - - 1 - JSON-RPC command executed - successfully, and the server returned success. You can - check the ret_pvar variable for - the result. - - - - - -1 - There was an internal error - during processing. - - - - - -2 - There was a connection - (timeout or connect) error with the destination. - - - - - -3 - The JSON-RPC was - successfully run, but the server returned an error. - Check the ret_pvar value to find - out more information. - - - - - - <function>jsonrpc_request()</function> function usage - - ... - if (!jsonrpc_request("127.0.0.1", "add", "[1,2]", $var(ret))) { - xlog("JSON-RPC command failed with $var(ret)\n"); - exit; - } - xlog(JSON-RPC command returned $var(ret)\n"); - # parse $var(ret) as JSON, or whatever the function returns - ... - - -
-
- - <function moreinfo="none">jsonrpc_notification(destination, method, params)</function> - - - Does a JSON-RPC notification to the JSON-RPC server - indicated in the destination - parameter, but unlike , - it does not wait for a reply from the JSON-RPC server. - - - This function can be used from any route. - - - The function receives the same parameters as - , except for the ret_pvar. Also, the same values are returned. - - - <function>jsonrpc_notification()</function> function usage - - ... - if (!jsonrpc_notification("127.0.0.1", "block_ip", "{ \"ip": \"$si\" }")) { - xlog("JSON-RPC notification failed with $rc!\n"); - exit; - } - ... - - -
-
- -
diff --git a/modules/jsonrpc/jsonrpc.c b/modules/jsonrpc/jsonrpc.c index 705165b42f7..3e978787fc5 100644 --- a/modules/jsonrpc/jsonrpc.c +++ b/modules/jsonrpc/jsonrpc.c @@ -342,6 +342,11 @@ static int jsonrpc_handle_cmd(union sockaddr_union *dst, char *cmd, int *id, if (aux && aux->type!=cJSON_NULL) { /* return the entire error */ vret->rs.s = cJSON_Print(aux); + if (!vret->rs.s) { + LM_ERR("cJSON_Print failed\n"); + ret = -2; + goto end; + } vret->rs.len = strlen(vret->rs.s); vret->flags = PV_VAL_STR; LM_DBG("Error got from JSON-RPC: %s!\n", buffer); @@ -361,12 +366,19 @@ static int jsonrpc_handle_cmd(union sockaddr_union *dst, char *cmd, int *id, pv_get_sintval(NULL, NULL, vret, aux->valueint); else { vret->rs.s = cJSON_Print(aux); + if (!vret->rs.s) { + LM_ERR("cJSON_Print failed\n"); + ret = -2; + goto end; + } vret->rs.len = strlen(vret->rs.s); vret->flags = PV_VAL_STR; } ret = 1; end: + if (obj) + cJSON_Delete(obj); shutdown(fd, SHUT_RDWR); close(fd); return ret; diff --git a/modules/launch_darkly/README b/modules/launch_darkly/README deleted file mode 100644 index 5a272b9f957..00000000000 --- a/modules/launch_darkly/README +++ /dev/null @@ -1,232 +0,0 @@ -launch_darkly Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. sdk_key (string) - 1.3.2. ld_log_level (string) - 1.3.3. connect_wait (integer) - 1.3.4. re_init_interval (integer) - - 1.4. Exported Functions - - 1.4.1. ld_feature_enabled( flag, user, [user_extra], - [fallback]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set sdk_key parameter - 1.2. Set log_level parameter - 1.3. Set connect_wait parameter - 1.4. Set re_init_interval parameter - 1.5. ld_feature_enabled() function usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements support for the Launch Darkly feature - management cloud. The module provide the conectivity to the - cloud and the ability to query for feature flags. - - OpenSIPS uses the server side C/C++ SDK provided by Launch - Darkly. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * none. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * ldserverapi - - ldserverapi must be compiled and installed from the official - GITHUB repository . - - The instructions for a quick installations of the library (note - that it has to be compiled as shared lib in order to be - compatible with the OpenSIPS modules): -... - $ git clone https://github.com/launchdarkly/c-server-sdk.git - $ cd c-server-sdk - $ cmake -DBUILD_SHARED_LIBS=On -DBUILD_TESTING=OFF . - $ sudo make install -... - -1.3. Exported Parameters - -1.3.1. sdk_key (string) - - The LaunchDarkly SDK key used to connect to the service. This - is a mandatory parameter. - - Example 1.1. Set sdk_key parameter -... -modparam("launch_darkly", "sdk_key", "sdk-12345678-abcd-12ab-1234-012345 -6789abc") -... - -1.3.2. ld_log_level (string) - - The LaunchDarkly specific log level to be used by the LD - SDK/libray to log its internal messages. Note that these log - produced by the LD library (according to this ld_log_level) - will be further subject to filtering according to the overall - OpenSIPS log_level. - - Accepted values are LD_LOG_FATAL, LD_LOG_CRITICAL, - LD_LOG_ERROR, LD_LOG_WARNING, LD_LOG_INFO, LD_LOG_DEBUG, - LD_LOG_TRACE. - - If not set or set to an unsupported value, the LD_LOG_WARNING - level will be used by default. - - Example 1.2. Set log_level parameter -... -modparam("launch_darkly", "ld_log_level", "LD_LOG_CRITICAL") -... - -1.3.3. connect_wait (integer) - - The time to wait (in miliseconds) when connecting to the LD - service. An initial failure in connecting to the LD service may - be addressed by increasing this wait value. - - The default value is 500 miliseconds. - - Example 1.3. Set connect_wait parameter -... -modparam("launch_darkly", "connect_wait", 100) -... - -1.3.4. re_init_interval (integer) - - The minimum time interval (in seconds) to try again to init the - LD client in the situation when the module was not able to init - the LC connection at startup. In case of such failure, the - module will automatically re-try to init its LD client - on-demand, whnever the feature flag is checked from script, but - not sooner than `re_init_interval`. Note: if there are no flag - checkings to be performed, the re-init may be attempted longer - than `re_init_interval`. - - The default value is 10 seconds. - - Example 1.4. Set re_init_interval parameter -... -modparam("launch_darkly", "re_init_interval", 30) -... - -1.4. Exported Functions - -1.4.1. ld_feature_enabled( flag, user, [user_extra], [fallback]) - - Function to evaluate a LaunchDarkly boolean feature flag - - Returns 1 if the flag was found TRUE or -1 otherwise. - - In case of error, the fallback (TRUE or FALSE) value will be - returned In such cases, a "fallback" TRUE is returned as 2 and - a fallback FALSE as -2, so you can may a difference between a - real TRUE (returned by the LD service) and a fallback TRUE due - to an error. - - This function can be used from any route. - - The function has the following parameters: - * flag (string) - the key of the flag to evaluate. May not be - NULL or empty. - * user (string) - the user to evaluate the flag against. May - not be NULL or empty. - * user_extra (AVP, optional) - an AVP holding one or multiple - key-value attributes to be attached to the user. The format - of the AVP value is "key=value". - * fallback (int, optional) - the value to be returned on - error. By default FALSE will be returned. - - Example 1.5. ld_feature_enabled() function usage - ... - $avp(extra) = "domainId=123456"; - if (ld_feature_enabled("my-flag","opensips", $avp(extra), false) -) - xlog("-------TRUE\n"); - else - xlog("-------FALSE\n"); - ... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 8 1 717 0 - 2. Razvan Crainea (@razvancrainea) 3 1 43 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2024 - May 2024 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2024 - Jan 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2023 Five9 Inc. diff --git a/modules/launch_darkly/README.md b/modules/launch_darkly/README.md new file mode 100644 index 00000000000..7342bd1e6b5 --- /dev/null +++ b/modules/launch_darkly/README.md @@ -0,0 +1,200 @@ +--- +title: "launch_darkly Module" +description: "This module implements support for the [Launch Darkly](https://launchdarkly.com/) feature management cloud." +--- + +## Admin Guide + + +### Overview + + +This module implements support for the +[Launch Darkly](https://launchdarkly.com/) feature +management cloud. The module provide the conectivity to the cloud and +the ability to query for feature flags. + + +OpenSIPS uses the [server side C/C++ SDK](https://launchdarkly.com/features/sdk/) provided by Launch Darkly. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *none*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *ldserverapi* + + +*ldserverapi* must be compiled and installed +from the official +[GITHUB repository](https://github.com/launchdarkly/c-server-sdk). + + +The instructions for a quick installations of the library (note that it has to be compiled as shared lib in order to be compatible with the OpenSIPS modules): + + +```bash +... +$ git clone https://github.com/launchdarkly/c-server-sdk.git +$ cd c-server-sdk +$ cmake -DBUILD_SHARED_LIBS=On -DBUILD_TESTING=OFF . +$ sudo make install +... +``` + + +### Exported Parameters + + +#### sdk_key (string) + + +The LaunchDarkly SDK key used to connect to the service. This +is a mandatory parameter. + + +```opensips title="Set sdk_key parameter" +... +modparam("launch_darkly", "sdk_key", "sdk-12345678-abcd-12ab-1234-0123456789abc") +... +``` + + +#### ld_log_level (string) + + +The LaunchDarkly specific log level to be used by the LD SDK/libray to +log its internal messages. Note that these log produced by the LD +library (according to this ld_log_level) will be further subject to +filtering according to the overall OpenSIPS log_level. + + +Accepted values are +*LD_LOG_FATAL*, +*LD_LOG_CRITICAL*, +*LD_LOG_ERROR*, +*LD_LOG_WARNING*, +*LD_LOG_INFO*, +*LD_LOG_DEBUG*, +*LD_LOG_TRACE*. + + +If not set or set to an unsupported value, the +*LD_LOG_WARNING* level will be used by default. + + +```opensips title="Set log_level parameter" +... +modparam("launch_darkly", "ld_log_level", "LD_LOG_CRITICAL") +... +``` + + +#### connect_wait (integer) + + +The time to wait (in miliseconds) when connecting to the LD service. +An initial failure in connecting to the LD service may be addressed +by increasing this wait value. + + +The default value is 500 miliseconds. + + +```opensips title="Set connect_wait parameter" +... +modparam("launch_darkly", "connect_wait", 100) +... +``` + + +#### re_init_interval (integer) + + +The minimum time interval (in seconds) to try again to init +the LD client in the situation when the module was not able to init +the LC connection at startup. In case of such failure, the module will +automatically re-try to init its LD client on-demand, whnever the +feature flag is checked from script, but not sooner than +`re_init_interval`. Note: if there are no flag checkings to be +performed, the re-init may be attempted longer than `re_init_interval`. + + +The default value is 10 seconds. + + +```opensips title="Set re_init_interval parameter" +... +modparam("launch_darkly", "re_init_interval", 30) +... +``` + + +### Exported Functions + + +#### ld_feature_enabled( flag, user, [user_extra], [fallback]) + + +Function to evaluate a LaunchDarkly boolean feature flag + + +Returns *1* if the flag was found TRUE +or *-1* otherwise. + + +In case of error, the fallback (TRUE or FALSE) value will be +returned In such cases, a "fallback" TRUE is returned as 2 and a +fallback FALSE as -2, so you can may a difference between a real +TRUE (returned by the LD service) and a fallback TRUE due to an +error. + + +This function can be used from any route. + + +The function has the following parameters: + + +- *flag* (string) - the key of the flag +to evaluate. May not be NULL or empty. +- *user* (string) - the user to evaluate +the flag against. May not be NULL or empty. +- *user_extra* (AVP, optional) - an AVP +holding one or multiple key-value attributes to be +attached to the user. The format of the AVP value is +"key=value". +- *fallback* (int, optional) - the value +to be returned on error. By default FALSE will be returned. + + +```opensips title="ld_feature_enabled() function usage" + ... + $avp(extra) = "domainId=123456"; + if (ld_feature_enabled("my-flag","opensips", $avp(extra), false)) + xlog("-------TRUE\n"); + else + xlog("-------FALSE\n"); + ... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/launch_darkly/doc/contributors.xml b/modules/launch_darkly/doc/contributors.xml deleted file mode 100644 index b3f229e85f5..00000000000 --- a/modules/launch_darkly/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 1 - 717 - 0 - - - 2. - Razvan Crainea (@razvancrainea) - 3 - 1 - 43 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2024 - May 2024 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2024 - Jan 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/launch_darkly/doc/launch_darkly.xml b/modules/launch_darkly/doc/launch_darkly.xml deleted file mode 100644 index 1603c68d525..00000000000 --- a/modules/launch_darkly/doc/launch_darkly.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - launch_darkly Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2023 Five9 Inc. - diff --git a/modules/launch_darkly/doc/launch_darkly_admin.xml b/modules/launch_darkly/doc/launch_darkly_admin.xml deleted file mode 100644 index 6fe2a373351..00000000000 --- a/modules/launch_darkly/doc/launch_darkly_admin.xml +++ /dev/null @@ -1,235 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements support for the - Launch Darkly feature - management cloud. The module provide the conectivity to the cloud and - the ability to query for feature flags. - - - OpenSIPS uses the server side C/C++ SDK provided by Launch Darkly. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - none. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - ldserverapi - - - - - - ldserverapi must be compiled and installed - from the official - GITHUB repository . - - - The instructions for a quick installations of the library (note that it has to be compiled as shared lib in order to be compatible with the OpenSIPS modules): - - -... - $ git clone https://github.com/launchdarkly/c-server-sdk.git - $ cd c-server-sdk - $ cmake -DBUILD_SHARED_LIBS=On -DBUILD_TESTING=OFF . - $ sudo make install -... - -
-
- -
- Exported Parameters - -
- <varname>sdk_key</varname> (string) - - The LaunchDarkly SDK key used to connect to the service. This - is a mandatory parameter. - - - Set <varname>sdk_key</varname> parameter - -... -modparam("launch_darkly", "sdk_key", "sdk-12345678-abcd-12ab-1234-0123456789abc") -... - - -
- -
- <varname>ld_log_level</varname> (string) - - The LaunchDarkly specific log level to be used by the LD SDK/libray to - log its internal messages. Note that these log produced by the LD - library (according to this ld_log_level) will be further subject to - filtering according to the overall OpenSIPS log_level. - - - Accepted values are - LD_LOG_FATAL, - LD_LOG_CRITICAL, - LD_LOG_ERROR, - LD_LOG_WARNING, - LD_LOG_INFO, - LD_LOG_DEBUG, - LD_LOG_TRACE. - - - If not set or set to an unsupported value, the - LD_LOG_WARNING level will be used by default. - - - Set <varname>log_level</varname> parameter - -... -modparam("launch_darkly", "ld_log_level", "LD_LOG_CRITICAL") -... - - -
- -
- <varname>connect_wait</varname> (integer) - - The time to wait (in miliseconds) when connecting to the LD service. - An initial failure in connecting to the LD service may be addressed - by increasing this wait value. - - - The default value is 500 miliseconds. - - - Set <varname>connect_wait</varname> parameter - -... -modparam("launch_darkly", "connect_wait", 100) -... - - -
- -
- <varname>re_init_interval</varname> (integer) - - The minimum time interval (in seconds) to try again to init - the LD client in the situation when the module was not able to init - the LC connection at startup. In case of such failure, the module will - automatically re-try to init its LD client on-demand, whnever the - feature flag is checked from script, but not sooner than - `re_init_interval`. Note: if there are no flag checkings to be - performed, the re-init may be attempted longer than `re_init_interval`. - - - The default value is 10 seconds. - - - Set <varname>re_init_interval</varname> parameter - -... -modparam("launch_darkly", "re_init_interval", 30) -... - - -
- - -
- -
- Exported Functions -
- - <function moreinfo="none">ld_feature_enabled( flag, user, [user_extra], [fallback])</function> - - - Function to evaluate a LaunchDarkly boolean feature flag - - - Returns 1 if the flag was found TRUE - or -1 otherwise. - - - In case of error, the fallback (TRUE or FALSE) value will be - returned In such cases, a "fallback" TRUE is returned as 2 and a - fallback FALSE as -2, so you can may a difference between a real - TRUE (returned by the LD service) and a fallback TRUE due to an - error. - - - This function can be used from any route. - - - The function has the following parameters: - - - - - flag (string) - the key of the flag - to evaluate. May not be NULL or empty. - - - - - user (string) - the user to evaluate - the flag against. May not be NULL or empty. - - - - - user_extra (AVP, optional) - an AVP - holding one or multiple key-value attributes to be - attached to the user. The format of the AVP value is - "key=value". - - - - - fallback (int, optional) - the value - to be returned on error. By default FALSE will be returned. - - - - - - <function>ld_feature_enabled()</function> function usage - - ... - $avp(extra) = "domainId=123456"; - if (ld_feature_enabled("my-flag","opensips", $avp(extra), false)) - xlog("-------TRUE\n"); - else - xlog("-------FALSE\n"); - ... - - -
-
- -
diff --git a/modules/ldap/README b/modules/ldap/README deleted file mode 100644 index e3b2ae6e2ef..00000000000 --- a/modules/ldap/README +++ /dev/null @@ -1,1417 +0,0 @@ -LDAP Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Usage Basics - 1.1.2. LDAP URLs - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. LDAP Configuration File - - 1.3.1. Configuration File Syntax - 1.3.2. LDAP Session Settings - 1.3.3. Configuration File Example - - 1.4. Exported Parameters - - 1.4.1. config_file (string) - 1.4.2. max_async_connections (int) - - 1.5. Exported Functions - - 1.5.1. ldap_search(ldap_url) - 1.5.2. ldap_result(ldap_attr_name, avp_spec, - [avp_type], [regex_subst]) - - 1.5.3. ldap_result_check(ldap_attr_name, - string_to_match, [, regex_subst]) - - 1.5.4. ldap_result_next() - 1.5.5. ldap_filter_url_encode(string, avp_spec) - - 1.6. Exported Async Functions - - 1.6.1. ldap_search(ldap_url) - - 1.7. Installation & Running - - 1.7.1. Compiling the Module - - 2. Developer Guide - - 2.1. Overview - 2.2. API Functions - - 2.2.1. ldap_params_search - 2.2.2. ldap_url_search - 2.2.3. ldap_result_attr_vals - 2.2.4. ldap_value_free_len - 2.2.5. ldap_result_next - 2.2.6. ldap_str2scope - 2.2.7. ldap_rfc4515_escape - 2.2.8. get_ldap_handle - 2.2.9. get_last_ldap_result - - 2.3. Example Usage - - Resources - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 1.1. RFC 4515 Escaping Rules - 1.2. ldap_filter_url_encode() escaping rules - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. ldap_server_url examples - 1.2. ldap_version example - 1.3. ldap_bind_dn example - 1.4. ldap_bind_password example - 1.5. ldap_network_timeout example - 1.6. ldap_client_bind_timeout example - 1.7. ldap_ca_cert_file example - 1.8. ldap_cert_file example - 1.9. ldap_key_file example - 1.10. ldap_require_certificate example - 1.11. Example LDAP Configuration File - 1.12. config_file parameter usage - 1.13. max_async_connections parameter usage - 1.14. Example Usage of ldap_url - 1.15. Example Usage - 1.16. Example Usage - 1.17. Example Usage - 1.18. Example Usage - 1.19. Example Usage - 1.20. Example Usage of ldap_url - 1.21. Example Usage - 2.1. Example code fragment to load LDAP module API - 2.2. Example LDAP module API function call - -Chapter 1. Admin Guide - -1.1. Overview - - The LDAP module implements an LDAP search interface for - OpenSIPS. It exports script functions to perform an LDAP search - operation and to store the search results as OpenSIPS AVPs. - This allows for using LDAP directory data in the OpenSIPS SIP - message routing script. - - The following features are offered by the LDAP module: - * LDAP search function taking an LDAP URL as input both - synchronous and asynchronous - * LDAP result parsing functions to store LDAP data as AVP - * Support for accessing multiple LDAP servers - * LDAP SIMPLE authentication - * LDAP server failover and automatic reconnect - * Configurable LDAP connection and bind timeouts - * Module API for LDAP search operations that can be used by - other OpenSIPS modules - * StartTLS support - - The module implementation makes use of the open source OpenLDAP - library available on most UNIX/Linux platforms. Besides LDAP - server failover and automatic reconnect, this module can handle - multiple LDAP sessions concurrently allowing to access data - stored on different LDAP servers. Each OpenSIPS worker process - maintains one LDAP TCP connection per configured LDAP server. - This enables parallel execution of LDAP requests and offloads - LDAP concurrency control to the LDAP server(s). - - An LDAP search module API is provided that can be used by other - OpenSIPS modules. A module using this API does not have to - implement LDAP connection management and configuration, while - still having access to the full OpenLDAP API for searching and - result handling. - - Since LDAP server implementations are optimized for fast read - access they are a good choice to store SIP provisioning data. - Performance tests have shown that this module achieves lower - data access times and higher call rates than other database - modules like e.g. the OpenSIPS MYSQL module. - -1.1.1. Usage Basics - - First so called LDAP sessions have to be specified in an - external configuration file (as described in Section 1.3, “LDAP - Configuration File”). Each LDAP session includes LDAP server - access parameters like server hostname or connection timeouts. - Normally only a single LDAP session will be used unless there - is a need to access more than one LDAP server. The LDAP session - name will then be used in the OpenSIPS configuration script to - refer to a specific LDAP session. - - The ldap_search function (Section 1.5.1, - “ldap_search(ldap_url)”) performs an LDAP search operation. It - expects an LDAP URL as input which includes the LDAP session - name and search parameters. Section 1.1.2, “LDAP URLs” provides - a quick overview on LDAP URLs. - - The result of an LDAP search is stored internally and can be - accessed with one of the ldap_result* functions. ldap_result - (Section 1.5.2, “ldap_result(ldap_attr_name, avp_spec, - [avp_type], [regex_subst])”) stores resulting LDAP attribute - value as AVPs. ldap_result_check (Section 1.5.3, - “ldap_result_check(ldap_attr_name, string_to_match, [, - regex_subst])”) is a convenience function to compare a string - with LDAP attribute values using regular expression matching. - Finally, ldap_result_next (Section 1.5.4, “ldap_result_next()”) - allows to handle LDAP search queries that return more than one - LDAP entry. - - All ldap_result* functions do always access the LDAP result set - from the last ldap_search call. This should be kept in mind - when calling ldap_search more than once in the OpenSIPS - configuration script. - -1.1.2. LDAP URLs - - ldap_search expects an LDAP URL as argument. This section - describes the format and semantics of an LDAP URL. - - RFC 4516 [RFC4516] describes the format of an LDAP Uniform - Resource Locator (URL). An LDAP URL represents an LDAP search - operation in a compact format. The LDAP URL format is defined - as follows (slightly modified, refer to section 2 of [RFC4516] - for ABNF notation): - - ldap://[ldap_session_name][/dn?attrs[?scope[?filter]]]] - - ldap_session_name - An LDAP session name as defined in the LDAP - configuration file. - - (RFC 4516 defines this as LDAP hostport parameter) - - dn - Base Distinguished Name (DN) of LDAP search or target of - non-search operation, as defined in RFC 4514 [RFC4514] - - attrs - Comma separated list of LDAP attributes to be returned - - scope - Scope for LDAP search, valid values are “base”, “one”, - or “sub” - - filter - LDAP search filter definition following rules of RFC - 4515 [RFC4515] - -Note - - The following table lists characters that have to be - escaped in LDAP search filters: - - Table 1.1. RFC 4515 Escaping Rules - - * \2a - ( \28 - ) \29 - \ \5c - -Note - - Non-URL characters in an LDAP URL have to be escaped using - percent-encoding (refer to section 2.1 of RFC 4516). In - particular this means that any "?" character in an LDAP URL - component must be written as "%3F", since "?" is used as a URL - delimiter. - - The exported function ldap_filter_url_encode (Section 1.5.5, - “ldap_filter_url_encode(string, avp_spec)”) implements RFC - 4515/4516 LDAP search filter and URL escaping rules. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (the listed modules - must be loaded before this module): - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * OpenLDAP library (libldap) v2.1 or greater, libldap header - files (libldap-dev) are needed for compilation - -1.3. LDAP Configuration File - - The module reads an external confiuration file at module - initialization time that includes LDAP session definitions. - -1.3.1. Configuration File Syntax - - The configuration file follows the Windows INI file syntax, - section names are enclosed in square brackets: -[Section_Name] - - Any section can contain zero or more configuration key - assignments of the form -key = value ; comment - - Values can be given enclosed with quotes. If no quotes are - present, the value is understood as containing all characters - between the first and the last non-blank characters. Lines - starting with a hash sign and blank lines are treated as - comments. - - Each section describes one LDAP session that can be referred to - in the OpenSIPS configuration script. Using the section name as - the host part of an LDAP URL tells the module to use the LDAP - session specified in the respective section. An example LDAP - session specification looks like: -[example_ldap] -ldap_server_url = "ldap://ldap1.example.com, ldap://ldap2.exa -mple.com" -ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com -" -ldap_bind_password = "pwd" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 -ldap_ca_cert_file = "/usr/share/ca-certificates/mycert. -pem" -ldap_cert_file = "/var/my-certificate/certificate.pe -m" -ldap_key_file = "/var/my-certificate/key.pem" -ldap_require_certificate = "ALLOW" - - The configuration keys are explained in the following section. - This LDAP session can be referred to in the routing script by - using an LDAP URL like e.g. -ldap://example_ldap/cn=admin,dc=example,dc=com - -1.3.2. LDAP Session Settings - - ldap_server_url (mandatory) - LDAP URL including fully qualified domain name or IP - address of LDAP server optionally followed by a colon - and TCP port to connect: ldap://[:]. - Failover LDAP servers can be added, each separated by a - comma. In the event of connection errors, the module - tries to connect to servers in order of appearance. - - Default value: none, this is a mandatory setting - - Example 1.1. ldap_server_url examples - -ldap_server_url = "ldap://localhost" -ldap_server_url = "ldap://ldap.example.com:7777" -ldap_server_url = "ldap://ldap1.example.com, - ldap://ldap2.example.com:80389" - - ldap_version (optional) - Supported LDAP versions are 2 and 3. - - Default value: 3 (LDAPv3) - - Example 1.2. ldap_version example - -ldap_version = 2 - - ldap_bind_dn (optional) - Authentication user DN used to bind to LDAP server - (module currently only supports SIMPLE_AUTH). Empty - string enables anonymous LDAP bind. - - Default value: “” (empty string --> anonymous bind) - - Example 1.3. ldap_bind_dn example - -ldap_bind_dn = "cn=root,dc=example,dc=com"; - - ldap_bind_password (optional) - Authentication password used to bind to LDAP server - (SIMPLE_AUTH). Empty string enables anonymous bind. - - Default value: “” (empty string --> anonymous bind) - - Example 1.4. ldap_bind_password example - -ldap_bind_password = "secret"; - - ldap_network_timeout (optional) - LDAP TCP connect timeout in milliseconds. Setting this - parameter to a low value enables fast failover if - ldap_server_url contains more than one LDAP server - addresses. - - Default value: 1000 (one second) - - Example 1.5. ldap_network_timeout example - -ldap_network_timeout = 500 ; setting TCP timeout to 500 ms - - ldap_client_bind_timeout (optional) - LDAP bind operation timeout in milliseconds. - - Default value: 1000 (one second) - - Example 1.6. ldap_client_bind_timeout example - -ldap_client_bind_timeout = 1000 - - ldap_ca_cert_file (optional) - LDAP full path of the CA certificate file. - - No default value. It is mandatory in case you wish to - use StartTLS - - Example 1.7. ldap_ca_cert_file example - -ldap_ca_cert_file = "/usr/local/CAcert.pem" - - ldap_cert_file (optional) - LDAP full path of the certificate file. - - No default value. It is mandatory in case you wish to - use StartTLS - - Example 1.8. ldap_cert_file example - -ldap_cert_file = "/usr/local/mycert.pem" - - ldap_key_file (optional) - LDAP full path of the key file. - - No default value. It is mandatory in case you wish to - use StartTLS - - Example 1.9. ldap_key_file example - -ldap_key_file = "/usr/local/mykey.pem" - - ldap_require_certificate (optional) - LDAP peer certificate checking strategy, one of "NEVER", - "HARD", "DEMAND", "ALLOW", "TRY". Lower case letters are - also accepted. - - Default value "NEVER". - - Example 1.10. ldap_require_certificate example - -ldap_require_certificate = "NEVER" - -1.3.3. Configuration File Example - - The following configuration file example includes two LDAP - session definitions that could be used e.g. for accessing H.350 - data and do phone number to name mappings. - - Example 1.11. Example LDAP Configuration File -# LDAP session "sipaccounts": -# -# - using LDAPv3 (default) -# - two redundant LDAP servers -# -[sipaccounts] -ldap_server_url = "ldap://h350-1.example.com, ldap://h350-2.example.com" -ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" -ldap_bind_password = "pwd" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 -#using StartTLS -ldap_ca_cert_file = "/ldap/path/to/ca/certificate.pem" -ldap_cert_file = "/ldap/path/to/certificate.pem" -ldap_key_file = "/ldap/path/to/key/file.pem" -ldap_require_certificate = "NEVER" - - -# LDAP session "campus": -# -# - using LDAPv2 -# - anonymous bind -# -[campus] -ldap_version = 2 -ldap_server_url = "ldap://ldap.example.com" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 - -1.4. Exported Parameters - -1.4.1. config_file (string) - - Full path to LDAP configuration file. - - Default value: /usr/local/etc/opensips/ldap.cfg - - Example 1.12. config_file parameter usage -modparam("ldap", "config_file", "/etc/opensips/ldap.ini") - -1.4.2. max_async_connections (int) - - Number of maximum asynchronous connections that will be started - with the ldap server for executing asynchronous ldap_search - calls. The number of connections is per process, so if there - are 8 worker processes with 20 max_async_connections, there - will be a maximum of 160 connections to the ldap server. - - Default value: 20 - - Example 1.13. max_async_connections parameter usage -modparam("ldap", "max_async_connections", 50) - -1.5. Exported Functions - -1.5.1. ldap_search(ldap_url) - - Performs an LDAP search operation using given LDAP URL and - stores result internally for later retrieval by ldap_result* - functions. If one ore more LDAP entries are found the function - returns the number of found entries which evaluates to TRUE in - the OpenSIPS configuration script. It returns -1 (FALSE) in - case no LDAP entry was found, and -2 (FALSE) if an internal - error like e.g. an LDAP error occurred. - - Function Parameters: - - ldap_url (string) - An LDAP URL defining the LDAP search operation (refer to - Section 1.1.2, “LDAP URLs” for a description of the LDAP - URL format). The hostport part must be one of the LDAP - session names declared in the LDAP configuration script. - - Example 1.14. Example Usage of ldap_url - - Search with LDAP session named sipaccounts, base - ou=sip,dc=example,dc=com, one level deep using search - filter (cn=schlatter) and returning all attributes: - -ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) - - Subtree search with LDAP session named ldap1, base - dc=example,dc=com using search filter (cn=$(avp(name))) - and returning SIPIdentityUserName and - SIPIdentityServiceLevel attributes - -ldap://ldap_1/dc=example,dc=com? - SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) - - Return Values: - - n > 0 (TRUE): - - + Found n matching LDAP entries - - -1 (FALSE): - - + No matching LDAP entries found - - -2 (FALSE): - - + LDAP error (e.g. LDAP server unavailable), or - + internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.15. Example Usage -... -# ldap search -if (!ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$ -rU)")) -{ - switch ($retcode) - { - case -1: - # no LDAP entry found - sl_send_reply(404, "User Not Found"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} -xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)"); - -# save telephone number in $avp(tel_number) -ldap_result("telephoneNumber/$avp(tel_number)"); -... - -1.5.2. ldap_result(ldap_attr_name, avp_spec, [avp_type], -[regex_subst]) - - This function converts LDAP attribute values into AVPs for - later use in the message routing script. It accesses the LDAP - result set fetched by the last ldap_search call. ldap_attr_name - specifies the LDAP attribute name who's value should be stored - in AVP avp_spec. Multi valued LDAP attributes generate an - indexed AVP. The optional regex_subst parameter allows to - further define what part of an attribute value should be stored - as AVP. - - An AVP can either be of type string or integer. As default, - ldap_result stores LDAP attribute values as AVP of type string. - The optional avp_type parameter can be used to explicitly - specify the type of the AVP. It can be either str for string, - or int for integer. If avp_type is specified as int then - ldap_result tries to convert the LDAP attribute values to - integer. In this case, the values are only stored as AVP if the - conversion to integer is successful. - - Function Parameters: - - ldap_attr_name (string) - The name of the LDAP attribute who's value should be - stored, e.g. SIPIdentityServiceLevel or telephonenumber - - avp_spec (var) - Specification of destination AVP, e.g. - $avp(service_level) or $avp(12) - - avp_type (string, optional) - Specification of destination AVP type, either str or - int. If this parameter is not specified then the LDAP - attribute values are stored as AVP of type string. - - regex_subst (string) - Regex substitution that gets applied to LDAP attribute - value before storing it as AVP, e.g. "/^sip:(.+)$/\1/" - to strip off "sip:" from the beginning of an LDAP - attribute value. - - Return Values: - - n > 0 (TRUE) - LDAP attribute ldap_attr_name found in LDAP result set - and n LDAP attribute values stored in avp_spec - - -1 (FALSE) - No LDAP attribute ldap_attr_name found in LDAP result - set - - -2 (FALSE) - Internal error occurred - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.16. Example Usage -... - -# ldap_search call -... - -# save SIPIdentityServiceLevel in $avp(service_level) -if (!ldap_result("SIPIdentityServiceLevel", $avp(service_level))) -{ - switch ($retcode) - { - case -1: - # no SIPIdentityServiceLevel found - sl_send_reply(403, "Forbidden"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} - -# save SIP URI domain in $avp(10) -ldap_result("SIPIdentitySIPURI", $avp(10), "/^[^@]+@(.+)$/\1/"); -... - -1.5.3. ldap_result_check(ldap_attr_name, string_to_match, [, -regex_subst]) - - This function compares ldap_attr_name's value with - string_to_match for equality. It accesses the LDAP result set - fetched by the last ldap_search call. The optional regex_subst - parameter allows to further define what part of the attribute - value should be used for the equality match. If ldap_attr_name - is multi valued, each value is checked against string_to_match. - If one or more of the values do match the function returns 1 - (TRUE). - - Function Parameters: - - ldap_attr_name (string) - The name of the LDAP attribute who's value should be - matched, e.g. SIPIdentitySIPURI - - string_to_match (string) - String to be matched. Included AVPs and pseudo variabels - do get expanded. - - regex_subst (string, optional) - Regex substitution that gets applied to LDAP attribute - value before comparing it with string_to_match, e.g. - "/^[^@]@+(.+)$/\1/" to extract the domain part of a SIP - URI - - Return Values: - - 1 (TRUE) - One or more ldap_attr_name attribute values match - string_to_match (after regex_subst is applied) - - -1 (FALSE) - ldap_attr_name attribute not found or attribute value - doesn't match string_to_match (after regex_subst is - applied) - - -2 (FALSE) - Internal error occurred - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.17. Example Usage -... -# ldap_search call -... - -# check if 'sn' ldap attribute value equals username part of R-URI, -# the same could be achieved with ldap_result_check("sn/$rU") -if (!ldap_result_check("sn", $ru, "/^sip:([^@]).*$/\1/")) -{ - switch ($retcode) - { - case -1: - # R-URI username doesn't match sn - sl_send_reply(401, "Unauthorized"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} -... - -1.5.4. ldap_result_next() - - An LDAP search operation can return multiple LDAP entries. This - function can be used to cycle through all returned LDAP - entries. It returns 1 (TRUE) if there is another LDAP entry - present in the LDAP result set and causes ldap_result* - functions to work on the next LDAP entry. The function returns - -1 (FALSE) if there are no more LDAP entries in the LDAP result - set. - - Return Values: - - 1 (TRUE) - Another LDAP entry is present in the LDAP result set and - result pointer is incremented by one - - -1 (FALSE) - No more LDAP entries are available - - -2 (FALSE) - Internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.18. Example Usage -... -# ldap_search call -... - -ldap_result("telephonenumber/$avp(tel1)"); -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel2)"); -} -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel3)"); -} -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel4)"); -} -... - -1.5.5. ldap_filter_url_encode(string, avp_spec) - - This function applies the following escaping rules to string - and stores the result in AVP avp_spec: - - Table 1.2. ldap_filter_url_encode() escaping rules - character in string gets replaced with defined in - * \2a RFC 4515 - ( \28 RFC 4515 - ) \29 RFC 4515 - \ \5c RFC 4515 - ? %3F RFC 4516 - - The string stored in AVP avp_spec can be safely used in an LDAP - URL filter string. - - Function Parameters: - - string - String to apply RFC 4515 and URL escpaing rules to. AVPs - and pseudo variables do get expanded. Example: - "cn=$avp(name)" - - avp_spec (var) - AVP to store resulting RFC 4515 and URL encoded string, - e.g. $avp(ldap_search) or $avp(10) - - Return Values: - - 1 (TRUE) - RFC 4515 and URL encoded filter_component stored as AVP - avp_name - - -1 (FALSE) - Internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.19. Example Usage -... -if (!ldap_filter_url_encode("cn=$avp(name)", $avp(name_esc))) -{ - # RFC 4515/URL encoding failed --> silently discard request - exit; -} - -xlog("L_INFO", "encoded LDAP filter component: [$avp(name_esc)]\n"); - -if (ldap_search( - "ldap://h350/ou=commObjects,dc=example,dc=com??sub?($avp(name_esc)) -")) - { ... } -... - -1.6. Exported Async Functions - -1.6.1. ldap_search(ldap_url) - - Performs an LDAP search operation using given LDAP URL and - stores result internally for later retrieval by ldap_result* - functions. If one ore more LDAP entries are found the function - returns the number of found entries which evaluates to TRUE in - the OpenSIPS configuration script. It returns -1 (FALSE) in - case no LDAP entry was found, and -2 (FALSE) if an internal - error like e.g. an LDAP error occurred. - - Function Parameters: - - ldap_url (string) - An LDAP URL defining the LDAP search operation (refer to - Section 1.1.2, “LDAP URLs” for a description of the LDAP - URL format). The hostport part must be one of the LDAP - session names declared in the LDAP configuration script. - - Example 1.20. Example Usage of ldap_url - - Search with LDAP session named sipaccounts, base - ou=sip,dc=example,dc=com, one level deep using search - filter (cn=schlatter) and returning all attributes: - -ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) - - Subtree search with LDAP session named ldap1, base - dc=example,dc=com using search filter (cn=$(avp(name))) - and returning SIPIdentityUserName and - SIPIdentityServiceLevel attributes - -ldap://ldap_1/dc=example,dc=com? - SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) - - Return Values: - - n > 0 (TRUE): - - + Found n matching LDAP entries - - -1 (FALSE): - - + No matching LDAP entries found - - -2 (FALSE): - - + LDAP error (e.g. LDAP server unavailable), or - + internal error - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, and ONREPLY_ROUTE. - - Example 1.21. Example Usage -... -# ldap search - -route { - async( ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com? -?one?(cn=$rU)"), resume); -} -.... -route[resume] { -{ - switch ($rc) - { - case -1: - # no LDAP entry found - sl_send_reply(404, "User Not Found"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } - xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)") -; - - # save telephone number in $avp(tel_number) - ldap_result("telephoneNumber", $avp(tel_number)"); -... -} - -1.7. Installation & Running - -1.7.1. Compiling the Module - - OpenLDAP library (libldap) and header files (libldap-dev) v2.1 - or greater (this module was tested with v2.1.3 and v2.3.32) are - required for compiling the LDAP module. The OpenLDAP source is - available at http://www.openldap.org/. - - The OpenLDAP library is available pre-compiled for most - UNIX/Linux flavors. On Debian/Ubuntu, the following packages - must be installed: -# apt-get install libldap2 libldap2-dev - - . - -Chapter 2. Developer Guide - -2.1. Overview - - The LDAP module API can be used by other OpenSIPS modules to - implement LDAP search functionality. This frees the module - implementer from having to care about LDAP connection - management and configuration. - - In order to use this API, a module has to load the API using - the load_ldap_api function which returns a pointer to a - ldap_api structure. This structure includes pointers to the API - functions described below. The LDAP module source file api.h - includes all declarations needed to load the API, it has to be - included in the file that loads the API. Loading the API is - typically done inside a module's mod_init call as the following - example shows: - - Example 2.1. Example code fragment to load LDAP module API -#include "../../sr_module.h" -#include "../ldap/api.h" - -/* - * global pointer to ldap api - */ -extern ldap_api_t ldap_api; - -... - -static int mod_init(void) -{ - /* - * load the LDAP API - */ - if (load_ldap_api(&ldap_api) != 0) - { - LM_ERR("Unable to load LDAP API - this module requires ldap modu -le\n"); - return -1; - } - - ... -} - -... - - - The API functions can then be used like in the following - example: - - Example 2.2. Example LDAP module API function call -... - - rc = ldap_api.ldap_rfc4515_escape(str1, str2, 0); - -... - - -2.2. API Functions - -2.2.1. ldap_params_search - - Performs an LDAP search using the parameters given as function - arguments. -typedef int (*ldap_params_search_t)(int* _ld_result_count, - char* _lds_name, - char* _dn, - int _scope, - char** _attrs, - char* _filter, - ...); - - - Function arguments: - - int* _ld_result_count - The function stores the number of returned LDAP entries - in _ld_result_count. - - char* _lds_name - LDAP session name as configured in the LDAP module - configuration file. - - char* _dn - LDAP search DN. - - int _scope - LDAP search scope, one of LDAP_SCOPE_ONELEVEL, - LDAP_SCOPE_BASE, or LDAP_SCOPE_SUBTREE, as defined in - OpenLDAP's ldap.h. - - char** _attrs - A null-terminated array of attribute types to return - from entries. If empty (NULL), all attribute types are - returned. - - char* _filter - LDAP search filter string according to RFC 4515. printf - patterns in this string do get replaced with the - function arguments' values following the _filter - argument. - - Return Values: - - -1 - Internal error. - - 0 - Success, _ld_result_count includes the number of LDAP - entries found. - -2.2.2. ldap_url_search - - Performs an LDAP search using an LDAP URL. -typedef int (*ldap_url_search_t)(char* _ldap_url, - int* _result_count); - - - Function arguments: - - char* _ldap_url - LDAP URL as described in Section 1.1.2, “LDAP URLs”. - - int* _result_count - The function stores the number of returned LDAP entries - in _ld_result_count. - - Return Values: - - -1 - Internal error. - - 0 - Success, _ld_result_count includes the number of LDAP - entries found. - -2.2.3. ldap_result_attr_vals - - Retrieve the value(s) of a returned LDAP attribute. The - function accesses the LDAP result returned by the last call of - ldap_params_search or ldap_url_search. The berval structure is - defined in OpenLDAP's ldap.h, which has to be included. - - This function allocates memory to store the LDAP attribute - value(s). This memory has to freed with the function - ldap_value_free_len (see next section). -typedef int (*ldap_result_attr_vals_t)(str* _attr_name, - struct berval ***_vals); - - -typedef struct berval { - ber_len_t bv_len; - char *bv_val; -} BerValue; - - - Function arguments: - - str* _attr_name - str structure holding the LDAP attribute name. - - struct berval ***_vals - A null-terminated array of the attribute's value(s). - - Return Values: - - -1 - Internal error. - - 0 - Success, _vals includes the attribute's value(s). - - 1 - No attribute value found. - -2.2.4. ldap_value_free_len - - Function used to free memory allocated by - ldap_result_attr_vals. The berval structure is defined in - OpenLDAP's ldap.h, which has to be included. -typedef void (*ldap_value_free_len_t)(struct berval **_vals); - -typedef struct berval { - ber_len_t bv_len; - char *bv_val; -} BerValue; - - - Function arguments: - - struct berval **_vals - berval array returned by ldap_result_attr_vals. - -2.2.5. ldap_result_next - - Increments the LDAP result pointer. -typedef int (*ldap_result_next_t)(); - - - Return Values: - - -1 - No LDAP result found, probably because - ldap_params_search or ldap_url_search was not called. - - 0 - Success, LDAP result pointer points now to next result. - - 1 - No more results available. - -2.2.6. ldap_str2scope - - Converts LDAP search scope string into integer value e.g. for - ldap_params_search. -typedef int (*ldap_str2scope_t)(char* scope_str); - - - Function arguments: - - char* scope_str - LDAP search scope string. One of "one", "onelevel", - "base", "sub", or "subtree". - - Return Values: - - -1 - scope_str not recognized. - - n >= 0 - LDAP search scope integer. - -2.2.7. ldap_rfc4515_escape - - Applies escaping rules described in Section 1.5.5, - “ldap_filter_url_encode(string, avp_spec)”. -typedef int (*ldap_rfc4515_escape_t)(str *sin, str *sout, int url_encode -); - - - Function arguments: - - str *sin - str structure holding the string to apply the escaping - rules. - - str *sout - str structure holding the escaped string. The length of - this string must be at least three times the length of - sin plus one. - - int url_encode - Flag that specifies if a '?' character gets escaped with - '%3F' or not. If url_encode equals 0, '?' does not get - escaped. - - Return Values: - - -1 - Internal error. - - 0 - Success, sout contains escaped string. - -2.2.8. get_ldap_handle - - Returns the OpenLDAP LDAP handle for a specific LDAP session. - This allows a module implementor to use the OpenLDAP API - functions directly, instead of using the API functions exported - by the OpenSIPS LDAP module. The LDAP structure is defined in - OpenLDAP's ldap.h, which has to be included. -typedef int (*get_ldap_handle_t)(char* _lds_name, LDAP** _ldap_handle); - - - Function arguments: - - char* _lds_name - LDAP session name as specified in the LDAP module - configuration file. - - LDAP** _ldap_handle - OpenLDAP LDAP handle returned by this function. - - Return Values: - - -1 - Internal error. - - 0 - Success, _ldap_handle contains the OpenLDAP LDAP handle. - -2.2.9. get_last_ldap_result - - Returns the OpenLDAP LDAP handle and OpenLDAP result handle of - the last LDAP search operation. These handles can be used as - input for OpenLDAP LDAP result API functions. LDAP and - LDAPMessage structures are defined in OpenLDAP's ldap.h, which - has to be included. -typedef void (*get_last_ldap_result_t) - (LDAP** _last_ldap_handle, LDAPMessage** _last_ldap_result) -; - - - Function arguments: - - LDAP** _last_ldap_handle - OpenLDAP LDAP handle returned by this function. - - LDAPMessage** _last_ldap_result - OpenLDAP result handle returned by this function. - -2.3. Example Usage - - The following example shows how this API can be used to perform - an LDAP search operation. It is assumed that the API is loaded - and available through the ldap_api pointer. -... - -int rc, ld_result_count, scope = 0; -char* sip_username = "test"; - -/* - * get LDAP search scope integer - */ -scope = ldap_api.ldap_str2scope("sub"); -if (scope == -1) -{ - LM_ERR("ldap_str2scope failed\n"); - return -1; -} - -/* - * perform LDAP search - */ - -if (ldap_api.ldap_params_search( - &ld_result_count, - "campus", - "dc=example,dc=com", - scope, - NULL, - "(&(objectClass=SIPIdentity)(SIPIdentityUserName=%s))", - sip_username) - != 0) -{ - LM_ERR("LDAP search failed\n"); - return -1; -} - -/* - * check result count - */ -if (ld_result_count < 1) -{ - LM_ERR("LDAP search returned no entry\n"); - return 1; -} - -/* - * get password attribute value - */ - -struct berval **attr_vals = NULL; -str ldap_pwd_attr_name = str_init("SIPIdentityPassword"); -str res_password; - -rc = ldap_api.ldap_result_attr_vals(&ldap_pwd_attr_name, &attr_vals); -if (rc < 0) -{ - LM_ERR("ldap_result_attr_vals failed\n"); - ldap_api.ldap_value_free_len(attr_vals); - return -1; -} -if (rc == 1) -{ - LM_INFO("No password attribute value found for [%s]\n", sip_username -); - ldap_api.ldap_value_free_len(attr_vals); - return 2; -} - -res_password.s = attr_vals[0]->bv_val; -res_password.len = attr_vals[0]->bv_len; - -ldap_api.ldap_value_free_len(attr_vals); - -LM_INFO("Password for user [%s]: [%s]\n", sip_username, res_password.s); - -... - -return 0; - - -Resources - - [RFC4510] Lightweight Directory Access Protocol (LDAP): - Technical Specification Road Map. June 2006. Internet - Engineering Task Force. - - [RFC4511] Lightweight Directory Access Protocol (LDAP): The - Protocol. June 2006. Internet Engineering Task Force. - - [RFC4514] Lightweight Directory Access Protocol (LDAP): String - Representation of Distinguished Names. June 2006. Internet - Engineering Task Force. - - [RFC4515] Lightweight Directory Access Protocol (LDAP): String - Representation of Search Filters. June 2006. Internet - Engineering Task Force. - - [RFC4516] Lightweight Directory Access Protocol (LDAP): Uniform - Resource Locator. June 2006. Internet Engineering Task Force. - - [RFC2617] HTTP Authentication: Basic and Digest Access - Authentication. June 1999. Internet Engineering Task Force. - - [RFC3261] SIP: Session Initiation Protocol. June 2002. Internet - Engineering Task Force. - - [H.350] Directory Services Architecture for Multimedia - Conferencing. August 2003. ITU-T. - - [H.350.4] Directory services architecture for SIP. August 2003. - ITU-T. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Christian Schlatter 59 6 5764 237 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 25 20 142 138 - 3. Ionut Ionita (@ionutrazvanionita) 22 5 1359 252 - 4. Razvan Crainea (@razvancrainea) 17 14 62 76 - 5. Liviu Chircu (@liviuchircu) 13 10 19 62 - 6. Daniel-Constantin Mierla (@miconda) 12 9 84 83 - 7. Vlad Patrascu (@rvlad-patrascu) 12 3 155 420 - 8. Maksym Sobolyev (@sobomax) 5 3 5 8 - 9. Razvan Pistolea 4 1 39 66 - 10. Anca Vamanu 3 1 14 14 - - All remaining contributors: tcresson, Dusan Klinec (@ph4r05), - Petr Písař, Henning Westerholt (@henningw), Konstantin - Bokarius, Peter Lemenkov (@lemenkov), Zero King (@l2dy), Edson - Gellert Schubert, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Oct 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. tcresson Sep 2023 - Sep 2023 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Petr Písař Mar 2022 - Mar 2022 - 7. Razvan Crainea (@razvancrainea) Jun 2011 - Jan 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Dusan Klinec (@ph4r05), Anca Vamanu, Razvan Pistolea, Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Christian - Schlatter. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Ionut Ionita (@ionutrazvanionita), - Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Christian Schlatter. - - Documentation Copyrights: - - Copyright © 2007 University of North Carolina diff --git a/modules/ldap/README.md b/modules/ldap/README.md new file mode 100644 index 00000000000..a28b3b41ba0 --- /dev/null +++ b/modules/ldap/README.md @@ -0,0 +1,1494 @@ +--- +title: "LDAP Module" +description: "The LDAP module implements an LDAP search interface for OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +The LDAP module implements an LDAP search interface for OpenSIPS. It exports script functions to perform an LDAP search operation and to store the search results as OpenSIPS AVPs. This allows for using LDAP directory data in the OpenSIPS SIP message routing script. + + +The following features are offered by the LDAP module: + + +- LDAP search function taking an LDAP URL as input both synchronous and asynchronous +- LDAP result parsing functions to store LDAP data as AVP +- Support for accessing multiple LDAP servers +- LDAP SIMPLE authentication +- LDAP server failover and automatic reconnect +- Configurable LDAP connection and bind timeouts +- Module API for LDAP search operations that can be used by other OpenSIPS modules +- StartTLS support + + +The module implementation makes use of the open source OpenLDAP library available on most UNIX/Linux platforms. Besides LDAP server failover and automatic reconnect, this module can handle multiple LDAP sessions concurrently allowing to access data stored on different LDAP servers. Each OpenSIPS worker process maintains one LDAP TCP connection per configured LDAP server. This enables parallel execution of LDAP requests and offloads LDAP concurrency control to the LDAP server(s). + + +An LDAP search module API is provided that can be used by other OpenSIPS modules. A module using this API does not have to implement LDAP connection management and configuration, while still having access to the full OpenLDAP API for searching and result handling. + + +Since LDAP server implementations are optimized for fast read access they are a good choice to store SIP provisioning data. Performance tests have shown that this module achieves lower data access times and higher call rates than other database modules like e.g. the OpenSIPS MYSQL module. + + +#### Usage Basics + + +First so called LDAP sessions have to be specified in an external configuration file (as described in [ldap config](#ldap_configuration_file)). Each LDAP session includes LDAP server access parameters like server hostname or connection timeouts. Normally only a single LDAP session will be used unless there is a need to access more than one LDAP server. The LDAP session name will then be used in the OpenSIPS configuration script to refer to a specific LDAP session. + + +The `ldap_search` function ([ldap search fn](#func_ldap_search)) performs an LDAP search operation. It expects an LDAP URL as input which includes the LDAP session name and search parameters. [ldap urls](#ldap_urls) provides a quick overview on LDAP URLs. + + +The result of an LDAP search is stored internally and can be accessed with one of the `ldap_result*` functions. `ldap_result` ([ldap result fn](#func_ldap_result)) stores resulting LDAP attribute value as AVPs. `ldap_result_check` ([ldap result check fn](#func_ldap_result_check)) is a convenience function to compare a string with LDAP attribute values using regular expression matching. Finally, `ldap_result_next` ([ldap result next fn](#func_ldap_result_next)) allows to handle LDAP search queries that return more than one LDAP entry. + + +All `ldap_result*` functions do always access the LDAP result set from the last `ldap_search` call. This should be kept in mind when calling `ldap_search` more than once in the OpenSIPS configuration script. + + +#### LDAP URLs + + +`ldap_search` expects an LDAP URL as argument. This section describes the format and semantics of an LDAP URL. + + +RFC 4516 [RFC4516](#RFC4516) describes the format of an LDAP Uniform Resource Locator (URL). An LDAP URL represents an LDAP search operation in a compact format. The LDAP URL format is defined as follows (slightly modified, refer to section 2 of [RFC4516](#RFC4516) for ABNF notation): + + +`ldap://[ldap_session_name][/dn?attrs[?scope[?filter]]]]` + + +**`ldap_session_name`** + + +An LDAP session name as defined in the LDAP +configuration file. + + +(RFC 4516 defines this as LDAP hostport parameter) + + +**`dn`** + + +Base Distinguished Name (DN) of LDAP search or target of +non-search operation, as defined in RFC 4514 [RFC4514](#RFC4514) + + +**`attrs`** + + +Comma separated list of LDAP attributes to be +returned + + +**`scope`** + + +Scope for LDAP search, valid values are +"base", "one", or +"sub" + + +**`filter`** + + +LDAP search filter definition following rules of RFC 4515 +[RFC4515](#RFC4515) + + +> [!NOTE] +> The following table lists characters that have to be +> escaped in LDAP search filters: + + +> [!NOTE] +> Non-URL characters in an LDAP URL have to be escaped using +> percent-encoding (refer to section 2.1 of RFC 4516). In particular +> this means that any "?" character in an LDAP URL component must be +> written as "%3F", since "?" is used as a URL delimiter. The exported function `ldap_filter_url_encode` ([ldap filter url encode fn](#func_ldap_filter_url_encode)) +> implements RFC 4515/4516 LDAP search filter and URL escaping +> rules. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (the listed modules +must be loaded before this module): + + +- *No dependencies on other OpenSIPS modules.* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- OpenLDAP library (libldap) v2.1 or greater, libldap header files +(libldap-dev) are needed for compilation + + +### LDAP Configuration File + + +The module reads an external confiuration file at module +initialization time that includes LDAP session definitions. + + +#### Configuration File Syntax + + +The configuration file follows the Windows INI file syntax, +section names are enclosed in square brackets: + + +```c +[Section_Name] +``` + + +Any +section can contain zero or more configuration key assignments of the +form + + +```c +key = value ; comment +``` + + +Values can +be given enclosed with quotes. If no quotes are present, the value is +understood as containing all characters between the first and the last +non-blank characters. Lines starting with a hash sign and blank lines +are treated as comments. + + +Each section describes one LDAP session that can be referred to +in the OpenSIPS configuration script. Using the section name as the +host part of an LDAP URL tells the module to use the LDAP session +specified in the respective section. An example LDAP session +specification looks like: + + +```c +[example_ldap] +ldap_server_url = "ldap://ldap1.example.com, ldap://ldap2.example.com" +ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" +ldap_bind_password = "pwd" +ldap_network_timeout = 500 +ldap_client_bind_timeout = 500 +ldap_ca_cert_file = "/usr/share/ca-certificates/mycert.pem" +ldap_cert_file = "/var/my-certificate/certificate.pem" +ldap_key_file = "/var/my-certificate/key.pem" +ldap_require_certificate = "ALLOW" +``` + + +The configuration keys are +explained in the following section. This LDAP session can be referred +to in the routing script by using an LDAP URL like +e.g. + + +```c +ldap://example_ldap/cn=admin,dc=example,dc=com +``` + + +#### LDAP Session Settings + + +**ldap_server_url (mandatory)** + + +LDAP URL including fully qualified domain name or IP address of LDAP server optionally followed by a colon and TCP port to connect: `ldap://[:]`. Failover LDAP servers can be added, each separated by a comma. In the event of connection errors, the module tries to connect to servers in order of appearance. + + +Default value: none, this is a mandatory setting + + +```c title="ldap_server_url examples" +ldap_server_url = "ldap://localhost" +ldap_server_url = "ldap://ldap.example.com:7777" +ldap_server_url = "ldap://ldap1.example.com, + ldap://ldap2.example.com:80389" + +``` + + +**ldap_version (optional)** + + +Supported LDAP versions are 2 and 3. + + +Default value: `3` (LDAPv3) + + +```c title="ldap_version example" +ldap_version = 2 +``` + + +**ldap_bind_dn (optional)** + + +Authentication user DN used to bind to LDAP server (module +currently only supports SIMPLE_AUTH). Empty string enables +anonymous LDAP bind. + + +Default value: "" (empty string --> +anonymous bind) + + +```c title="ldap_bind_dn example" +ldap_bind_dn = "cn=root,dc=example,dc=com"; +``` + + +**ldap_bind_password (optional)** + + +Authentication password used to bind to LDAP server +(SIMPLE_AUTH). Empty string enables anonymous bind. + + +Default value: "" (empty string --> +anonymous bind) + + +```c title="ldap_bind_password example" +ldap_bind_password = "secret"; +``` + + +**ldap_network_timeout (optional)** + + +LDAP TCP connect timeout in milliseconds. Setting this +parameter to a low value enables fast failover if `ldap_server_url` contains more than one LDAP server addresses. + + +Default value: 1000 (one second) + + +```c title="ldap_network_timeout example" +ldap_network_timeout = 500 ; setting TCP timeout to 500 ms +``` + + +**ldap_client_bind_timeout (optional)** + + +LDAP bind operation timeout in milliseconds. + + +Default value: 1000 (one second) + + +```c title="ldap_client_bind_timeout example" +ldap_client_bind_timeout = 1000 +``` + + +**ldap_ca_cert_file (optional)** + + +LDAP full path of the CA certificate file. + + +No default value. It is mandatory in case you wish to use StartTLS + + +```c title="ldap_ca_cert_file example" +ldap_ca_cert_file = "/usr/local/CAcert.pem" +``` + + +**ldap_cert_file (optional)** + + +LDAP full path of the certificate file. + + +No default value. It is mandatory in case you wish to use StartTLS + + +```c title="ldap_cert_file example" +ldap_cert_file = "/usr/local/mycert.pem" +``` + + +**ldap_key_file (optional)** + + +LDAP full path of the key file. + + +No default value. It is mandatory in case you wish to use StartTLS + + +```c title="ldap_key_file example" +ldap_key_file = "/usr/local/mykey.pem" +``` + + +**ldap_require_certificate (optional)** + + +LDAP peer certificate checking strategy, one of "NEVER", "HARD", "DEMAND", "ALLOW", "TRY". +Lower case letters are also accepted. + + +Default value "NEVER". + + +```c title="ldap_require_certificate example" +ldap_require_certificate = "NEVER" +``` + + +#### Configuration File Example + + +The following configuration file example includes two LDAP +session definitions that could be used e.g. for accessing H.350 data +and do phone number to name mappings. + + +```c title="Example LDAP Configuration File" +# LDAP session "sipaccounts": +# +# - using LDAPv3 (default) +# - two redundant LDAP servers +# +[sipaccounts] +ldap_server_url = "ldap://h350-1.example.com, ldap://h350-2.example.com" +ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" +ldap_bind_password = "pwd" +ldap_network_timeout = 500 +ldap_client_bind_timeout = 500 +#using StartTLS +ldap_ca_cert_file = "/ldap/path/to/ca/certificate.pem" +ldap_cert_file = "/ldap/path/to/certificate.pem" +ldap_key_file = "/ldap/path/to/key/file.pem" +ldap_require_certificate = "NEVER" + + +# LDAP session "campus": +# +# - using LDAPv2 +# - anonymous bind +# +[campus] +ldap_version = 2 +ldap_server_url = "ldap://ldap.example.com" +ldap_network_timeout = 500 +ldap_client_bind_timeout = 500 + +``` + + +### Exported Parameters + + +#### config_file (string) + + +Full path to LDAP configuration file. + + +Default value: +`/usr/local/etc/opensips/ldap.cfg` + + +```opensips title="config_file parameter usage" +modparam("ldap", "config_file", "/etc/opensips/ldap.ini") + +``` + + +#### max_async_connections (int) + + +Number of maximum asynchronous connections that will be started +with the ldap server for executing asynchronous ldap_search calls. +The number of connections is per process, so if there are 8 +worker processes with 20 max_async_connections, there will be a +maximum of 160 connections to the ldap server. + + +Default value: `20` + + +```opensips title="max_async_connections parameter usage" +modparam("ldap", "max_async_connections", 50) + +``` + + +### Exported Functions + + +#### ldap_search(ldap_url) + + +Performs an LDAP search operation using given LDAP URL and stores result +internally for later retrieval by `ldap_result*` functions. If one ore +more LDAP entries are found the function returns the number of found +entries which evaluates to TRUE in the OpenSIPS configuration script. +It returns `-1` (`FALSE`) in case no +LDAP entry was found, and `-2` +(`FALSE`) if an internal error like e.g. an LDAP +error occurred. + + +**`ldap_url (string)`** + + +An LDAP URL defining the LDAP search operation (refer to +[ldap urls](#ldap_urls) for a description of the LDAP URL +format). The hostport part must be one of the LDAP session names +declared in the LDAP configuration script. + + +Search with LDAP session named +`sipaccounts`, base +`ou=sip,dc=example,dc=com`, +`one` level deep using search filter +`(cn=schlatter)` and returning all +attributes: + + +```c title="Example Usage of ldap_url" +ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) +``` + + +Subtree search with LDAP session named +`ldap1`, base +`dc=example,dc=com` using search filter +`(cn=$(avp(name)))` and returning +`SIPIdentityUserName` and +`SIPIdentityServiceLevel` attributes + + +```opensips title="Example Usage of ldap_url" +ldap://ldap_1/dc=example,dc=com? + SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) + +``` + + +**`n` > 0 (TRUE):** + + +- Found `n` matching LDAP +entries + + +**`-1` (FALSE):** + + +- No matching LDAP entries found + + +**`-2` (FALSE):** + + +- LDAP error (e.g. LDAP server unavailable), or +- internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... +# ldap search +if (!ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$rU)")) +{ + switch ($retcode) + { + case -1: + # no LDAP entry found + sl_send_reply(404, "User Not Found"); + exit; + case -2: + # internal error + sl_send_reply(500, "Internal server error"); + exit; + default: + exit; + } +} +xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)"); + +# save telephone number in $avp(tel_number) +ldap_result("telephoneNumber/$avp(tel_number)"); +... + +``` + + +#### ldap_result(ldap_attr_name, avp_spec, [avp_type], [regex_subst]) + + +This function converts LDAP attribute values into AVPs for later +use in the message routing script. It accesses the LDAP result set +fetched by the last `ldap_search` call. +`ldap_attr_name` specifies the LDAP attribute name +who's value should be stored in AVP `avp_spec`. Multi +valued LDAP attributes generate an indexed AVP. The optional +`regex_subst` parameter allows to further define what +part of an attribute value should be stored as AVP. + + +An AVP can either be of type string or integer. As default, `ldap_result` stores LDAP attribute values as AVP of type string. The optional `avp_type` parameter can be used to explicitly specify the type of the AVP. It can be either `str` for string, or `int` for integer. If `avp_type` is specified as `int` then `ldap_result` tries to convert the LDAP attribute values to integer. In this case, the values are only stored as AVP if the conversion to integer is successful. + + +**ldap_attr_name (string)** + + +The name of the LDAP attribute who's value should be +stored, e.g. `SIPIdentityServiceLevel` or +`telephonenumber` + + +**avp_spec (var)** + + +Specification of destination AVP, e.g. +`$avp(service_level)` or +`$avp(12)` + + +**avp_type (string, optional)** + + +Specification of destination AVP type, either `str` or `int`. If this parameter is not specified then the LDAP attribute values are stored as AVP of type string. + + +**regex_subst (string)** + + +Regex substitution that gets applied to LDAP attribute +value before storing it as AVP, e.g. +`"/^sip:(.+)$/\1/"` to strip off "sip:" from +the beginning of an LDAP attribute value. + + +**`n` > 0 (TRUE)** + + +LDAP attribute `ldap_attr_name` found in LDAP result set and `n` LDAP attribute values stored in `avp_spec` + + +**-1 (FALSE)** + + +No LDAP attribute `ldap_attr_name` found +in LDAP result set + + +**-2 (FALSE)** + + +Internal error occurred + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... + +# ldap_search call +... + +# save SIPIdentityServiceLevel in $avp(service_level) +if (!ldap_result("SIPIdentityServiceLevel", $avp(service_level))) +{ + switch ($retcode) + { + case -1: + # no SIPIdentityServiceLevel found + sl_send_reply(403, "Forbidden"); + exit; + case -2: + # internal error + sl_send_reply(500, "Internal server error"); + exit; + default: + exit; + } +} + +# save SIP URI domain in $avp(10) +ldap_result("SIPIdentitySIPURI", $avp(10), "/^[^@]+@(.+)$/\1/"); +... + +``` + + +#### ldap_result_check(ldap_attr_name, string_to_match, [, regex_subst]) + + +This function compares `ldap_attr_name`'s value +with `string_to_match` for equality. It accesses the LDAP result set +fetched by the last `ldap_search` call. The +optional `regex_subst` parameter allows to further +define what part of the attribute value should be used for the +equality match. If `ldap_attr_name` is multi valued, +each value is checked against `string_to_match`. If +one or more of the values do match the function returns `1` +(TRUE). + + +**ldap_attr_name (string)** + + +The name of the LDAP attribute who's value should be +matched, e.g. `SIPIdentitySIPURI` + + +**string_to_match (string)** + + +String to be matched. Included AVPs and pseudo variabels +do get expanded. + + +**regex_subst (string, optional)** + + +Regex substitution that gets applied to LDAP attribute +value before comparing it with string_to_match, e.g. +`"/^[^@]@+(.+)$/\1/"` to extract the domain part +of a SIP URI + + +**1 (TRUE)** + + +One or more `ldap_attr_name` attribute values match +`string_to_match` (after +`regex_subst` is applied) + + +**-1 (FALSE)** + + +`ldap_attr_name` attribute not found or +attribute value doesn't match `string_to_match` +(after `regex_subst` is applied) + + +**-2 (FALSE)** + + +Internal error occurred + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... +# ldap_search call +... + +# check if 'sn' ldap attribute value equals username part of R-URI, +# the same could be achieved with ldap_result_check("sn/$rU") +if (!ldap_result_check("sn", $ru, "/^sip:([^@]).*$/\1/")) +{ + switch ($retcode) + { + case -1: + # R-URI username doesn't match sn + sl_send_reply(401, "Unauthorized"); + exit; + case -2: + # internal error + sl_send_reply(500, "Internal server error"); + exit; + default: + exit; + } +} +... + +``` + + +#### ldap_result_next() + + +An LDAP search operation can return multiple LDAP entries. This +function can be used to cycle through all returned LDAP entries. It +returns 1 (TRUE) if there is another LDAP entry present in the LDAP +result set and causes `ldap_result*` functions to work on the next LDAP +entry. The function returns -1 (FALSE) if there are no more LDAP +entries in the LDAP result set. + + +**1 (TRUE)** + + +Another LDAP entry is present in the LDAP result set and +result pointer is incremented by one + + +**-1 (FALSE)** + + +No more LDAP entries are available + + +**`-2` (FALSE)** + + +Internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... +# ldap_search call +... + +ldap_result("telephonenumber/$avp(tel1)"); +if (ldap_result_next()) +{ + ldap_result("telephonenumber/$avp(tel2)"); +} +if (ldap_result_next()) +{ + ldap_result("telephonenumber/$avp(tel3)"); +} +if (ldap_result_next()) +{ + ldap_result("telephonenumber/$avp(tel4)"); +} +... + +``` + + +#### ldap_filter_url_encode(string, avp_spec) + + +This function applies the following escaping rules to +`string` and stores the result in AVP +`avp_spec`: + + +**ldap_filter_url_encode() escaping rules** + + +| character in +`string` | gets replaced with | defined in | +| --- | --- | --- | +| * | \2a | RFC 4515 | +| ( | \28 | RFC 4515 | +| ) | \29 | RFC 4515 | +| \ | \5c | RFC 4515 | +| ? | %3F | RFC 4516 | + + +The string stored in AVP `avp_spec` can be safely used in an LDAP +URL filter string. + + +**`string`** + + +String to apply RFC 4515 and URL escpaing rules to. +AVPs and pseudo variables do get expanded. Example: +`"cn=$avp(name)"` + + +**`avp_spec (var)`** + + +AVP to store resulting RFC 4515 +and URL encoded string, e.g. `$avp(ldap_search)` +or `$avp(10)` + + +**`1` (TRUE)** + + +RFC 4515 and URL encoded +`filter_component` stored as AVP +`avp_name` + + +**`-1` (FALSE)** + + +Internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... +if (!ldap_filter_url_encode("cn=$avp(name)", $avp(name_esc))) +{ + # RFC 4515/URL encoding failed --> silently discard request + exit; +} + +xlog("L_INFO", "encoded LDAP filter component: [$avp(name_esc)]\n"); + +if (ldap_search( + "ldap://h350/ou=commObjects,dc=example,dc=com??sub?($avp(name_esc))")) + { ... } +... + +``` + + +### Exported Asynchronous Functions + + +#### ldap_search(ldap_url) + + +Performs an LDAP search operation using given LDAP URL and stores result +internally for later retrieval by `ldap_result*` functions. If one ore +more LDAP entries are found the function returns the number of found +entries which evaluates to TRUE in the OpenSIPS configuration script. +It returns `-1` (`FALSE`) in case no +LDAP entry was found, and `-2` +(`FALSE`) if an internal error like e.g. an LDAP +error occurred. + + +**`ldap_url (string)`** + + +An LDAP URL defining the LDAP search operation (refer to +[ldap urls](#ldap_urls) for a description of the LDAP URL +format). The hostport part must be one of the LDAP session names +declared in the LDAP configuration script. + + +Search with LDAP session named +`sipaccounts`, base +`ou=sip,dc=example,dc=com`, +`one` level deep using search filter +`(cn=schlatter)` and returning all +attributes: + + +```c title="Example Usage of ldap_url" +ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) +``` + + +Subtree search with LDAP session named +`ldap1`, base +`dc=example,dc=com` using search filter +`(cn=$(avp(name)))` and returning +`SIPIdentityUserName` and +`SIPIdentityServiceLevel` attributes + + +```opensips title="Example Usage of ldap_url" +ldap://ldap_1/dc=example,dc=com? + SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) + +``` + + +**`n` > 0 (TRUE):** + + +- Found `n` matching LDAP +entries + + +**`-1` (FALSE):** + + +- No matching LDAP entries found + + +**`-2` (FALSE):** + + +- LDAP error (e.g. LDAP server unavailable), or +- internal error + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. + + +```opensips title="Example Usage" +... +# ldap search + +route { + async( ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$rU)"), resume); +} +.... +route[resume] { +{ + switch ($rc) + { + case -1: + # no LDAP entry found + sl_send_reply(404, "User Not Found"); + exit; + case -2: + # internal error + sl_send_reply(500, "Internal server error"); + exit; + default: + exit; + } + xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)"); + + # save telephone number in $avp(tel_number) + ldap_result("telephoneNumber", $avp(tel_number)"); +... +} + +``` + + +### Installation & Running + + +#### Compiling the Module + + +OpenLDAP library (libldap) and header files (libldap-dev) v2.1 or greater (this module was tested with v2.1.3 and v2.3.32) are required for compiling the LDAP module. The OpenLDAP source is available at [http://www.openldap.org/](http://www.openldap.org/). + + +The OpenLDAP library is available pre-compiled for most UNIX/Linux flavors. On Debian/Ubuntu, the following packages must be installed: + + +```bash +$ apt-get install libldap2 libldap2-dev +``` + + +. + + +## Developer Guide + + +### Overview + + +The LDAP module API can be used by other OpenSIPS modules to implement LDAP search functionality. This frees the module implementer from having to care about LDAP connection management and configuration. + + +In order to use this API, a module has to load the API using the `load_ldap_api` function which returns a pointer to a `ldap_api` structure. This structure includes pointers to the API functions described below. The LDAP module source file `api.h` includes all declarations needed to load the API, it has to be included in the file that loads the API. Loading the API is typically done inside a module's `mod_init` call as the following example shows: + + +```c title="Example code fragment to load LDAP module API" +#include "../../sr_module.h" +#include "../ldap/api.h" + +/* + * global pointer to ldap api + */ +extern ldap_api_t ldap_api; + +... + +static int mod_init(void) +{ + /* + * load the LDAP API + */ + if (load_ldap_api(&ldap_api) != 0) + { + LM_ERR("Unable to load LDAP API - this module requires ldap module\n"); + return -1; + } + + ... +} + +... + + +``` + + +The API functions can then be used like in the following example: + + +```c title="Example LDAP module API function call" +... + + rc = ldap_api.ldap_rfc4515_escape(str1, str2, 0); + +... + + +``` + + +### API Functions + + +#### ldap_params_search + + +Performs an LDAP search using the parameters given as function arguments. + + +```c +typedef int (*ldap_params_search_t)(int* _ld_result_count, + char* _lds_name, + char* _dn, + int _scope, + char** _attrs, + char* _filter, + ...); + + +``` + + +**int* _ld_result_count** + + +The function stores the number of returned LDAP entries in `_ld_result_count`. + + +**char* _lds_name** + + +LDAP session name as configured in the LDAP module configuration file. + + +**char* _dn** + + +LDAP search DN. + + +**int _scope** + + +LDAP search scope, one of `LDAP_SCOPE_ONELEVEL`, `LDAP_SCOPE_BASE`, or `LDAP_SCOPE_SUBTREE`, as defined in OpenLDAP's `ldap.h`. + + +**char** _attrs** + + +A null-terminated array of attribute types to return from entries. If empty (`NULL`), all attribute types are returned. + + +**char* _filter** + + +LDAP search filter string according to RFC 4515. `printf` patterns in this string do get replaced with the function arguments' values following the `_filter` argument. + + +**-1** + + +Internal error. + + +**0** + + +Success, `_ld_result_count` includes the number of LDAP entries found. + + +#### ldap_url_search + + +Performs an LDAP search using an LDAP URL. + + +```c +typedef int (*ldap_url_search_t)(char* _ldap_url, + int* _result_count); + + +``` + + +**char* _ldap_url** + + +LDAP URL as described in [ldap urls](#ldap_urls). + + +**int* _result_count** + + +The function stores the number of returned LDAP entries in `_ld_result_count`. + + +**-1** + + +Internal error. + + +**0** + + +Success, `_ld_result_count` includes the number of LDAP entries found. + + +#### ldap_result_attr_vals + + +Retrieve the value(s) of a returned LDAP attribute. The function accesses the LDAP result returned by the last call of `ldap_params_search` or `ldap_url_search`. The `berval` structure is defined in OpenLDAP's `ldap.h`, which has to be included. + + +This function allocates memory to store the LDAP attribute value(s). This memory has to freed with the function `ldap_value_free_len` (see next section). + + +```c +typedef int (*ldap_result_attr_vals_t)(str* _attr_name, + struct berval ***_vals); + +typedef struct berval { + ber_len_t bv_len; + char *bv_val; +} BerValue; + + +``` + + +**str* _attr_name** + + +`str` structure holding the LDAP attribute name. + + +**struct berval ***_vals** + + +A null-terminated array of the attribute's value(s). + + +**-1** + + +Internal error. + + +**0** + + +Success, `_vals` includes the attribute's value(s). + + +**1** + + +No attribute value found. + + +#### ldap_value_free_len + + +Function used to free memory allocated by `ldap_result_attr_vals`. The `berval` structure is defined in OpenLDAP's `ldap.h`, which has to be included. + + +```c +typedef void (*ldap_value_free_len_t)(struct berval **_vals); + +typedef struct berval { + ber_len_t bv_len; + char *bv_val; +} BerValue; + + +``` + + +**struct berval **_vals** + + +`berval` array returned by `ldap_result_attr_vals`. + + +#### ldap_result_next + + +Increments the LDAP result pointer. + + +```c +typedef int (*ldap_result_next_t)(); + + +``` + + +**-1** + + +No LDAP result found, probably because `ldap_params_search` or `ldap_url_search` was not called. + + +**0** + + +Success, LDAP result pointer points now to next result. + + +**1** + + +No more results available. + + +#### ldap_str2scope + + +Converts LDAP search scope string into integer value e.g. for `ldap_params_search`. + + +```c +typedef int (*ldap_str2scope_t)(char* scope_str); + + +``` + + +**char* scope_str** + + +LDAP search scope string. One of "one", "onelevel", "base", "sub", or "subtree". + + +**-1** + + +`scope_str` not recognized. + + +**n >= 0** + + +LDAP search scope integer. + + +#### ldap_rfc4515_escape + + +Applies escaping rules described in [ldap filter url encode fn](#func_ldap_filter_url_encode). + + +```c +typedef int (*ldap_rfc4515_escape_t)(str *sin, str *sout, int url_encode); + + +``` + + +**str *sin** + + +`str` structure holding the string to apply the escaping rules. + + +**str *sout** + + +`str` structure holding the escaped string. The length of this string must be at least three times the length of `sin` plus one. + + +**int url_encode** + + +Flag that specifies if a '?' character gets escaped with '%3F' or not. If `url_encode` equals `0`, '?' does not get escaped. + + +**-1** + + +Internal error. + + +**0** + + +Success, `sout` contains escaped string. + + +#### get_ldap_handle + + +Returns the OpenLDAP LDAP handle for a specific LDAP session. This allows a module implementor to use the OpenLDAP API functions directly, instead of using the API functions exported by the OpenSIPS LDAP module. The `LDAP` structure is defined in OpenLDAP's `ldap.h`, which has to be included. + + +```c +typedef int (*get_ldap_handle_t)(char* _lds_name, LDAP** _ldap_handle); + + +``` + + +**char* _lds_name** + + +LDAP session name as specified in the LDAP module configuration file. + + +**LDAP** _ldap_handle** + + +OpenLDAP LDAP handle returned by this function. + + +**-1** + + +Internal error. + + +**0** + + +Success, `_ldap_handle` contains the OpenLDAP LDAP handle. + + +#### get_last_ldap_result + + +Returns the OpenLDAP LDAP handle and OpenLDAP result handle of the last LDAP search operation. These handles can be used as input for OpenLDAP LDAP result API functions. `LDAP` and `LDAPMessage` structures are defined in OpenLDAP's `ldap.h`, which has to be included. + + +```c +typedef void (*get_last_ldap_result_t) + (LDAP** _last_ldap_handle, LDAPMessage** _last_ldap_result); + + +``` + + +**LDAP** _last_ldap_handle** + + +OpenLDAP LDAP handle returned by this function. + + +**LDAPMessage** _last_ldap_result** + + +OpenLDAP result handle returned by this function. + + +### Example Usage + + +The following example shows how this API can be used to perform an LDAP search operation. It is assumed that the API is loaded and available through the `ldap_api` pointer. + + +```c +... + +int rc, ld_result_count, scope = 0; +char* sip_username = "test"; + +/* + * get LDAP search scope integer + */ +scope = ldap_api.ldap_str2scope("sub"); +if (scope == -1) +{ + LM_ERR("ldap_str2scope failed\n"); + return -1; +} + +/* + * perform LDAP search + */ + +if (ldap_api.ldap_params_search( + &ld_result_count, + "campus", + "dc=example,dc=com", + scope, + NULL, + "(&(objectClass=SIPIdentity)(SIPIdentityUserName=%s))", + sip_username) + != 0) +{ + LM_ERR("LDAP search failed\n"); + return -1; +} + +/* + * check result count + */ +if (ld_result_count < 1) +{ + LM_ERR("LDAP search returned no entry\n"); + return 1; +} + +/* + * get password attribute value + */ + +struct berval **attr_vals = NULL; +str ldap_pwd_attr_name = str_init("SIPIdentityPassword"); +str res_password; + +rc = ldap_api.ldap_result_attr_vals(&ldap_pwd_attr_name, &attr_vals); +if (rc < 0) +{ + LM_ERR("ldap_result_attr_vals failed\n"); + ldap_api.ldap_value_free_len(attr_vals); + return -1; +} +if (rc == 1) +{ + LM_INFO("No password attribute value found for [%s]\n", sip_username); + ldap_api.ldap_value_free_len(attr_vals); + return 2; +} + +res_password.s = attr_vals[0]->bv_val; +res_password.len = attr_vals[0]->bv_len; + +ldap_api.ldap_value_free_len(attr_vals); + +LM_INFO("Password for user [%s]: [%s]\n", sip_username, res_password.s); + +... + +return 0; + + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/ldap/doc/contributors.xml b/modules/ldap/doc/contributors.xml deleted file mode 100644 index 451a38ac081..00000000000 --- a/modules/ldap/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Christian Schlatter - 59 - 6 - 5764 - 237 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 25 - 20 - 142 - 138 - - - 3. - Ionut Ionita (@ionutrazvanionita) - 22 - 5 - 1359 - 252 - - - 4. - Razvan Crainea (@razvancrainea) - 17 - 14 - 62 - 76 - - - 5. - Liviu Chircu (@liviuchircu) - 13 - 10 - 19 - 62 - - - 6. - Daniel-Constantin Mierla (@miconda) - 12 - 9 - 84 - 83 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 12 - 3 - 155 - 420 - - - 8. - Maksym Sobolyev (@sobomax) - 5 - 3 - 5 - 8 - - - 9. - Razvan Pistolea - 4 - 1 - 39 - 66 - - - 10. - Anca Vamanu - 3 - 1 - 14 - 14 - - - -
-All remaining contributors: tcresson, Dusan Klinec (@ph4r05), Petr Písař, Henning Westerholt (@henningw), Konstantin Bokarius, Peter Lemenkov (@lemenkov), Zero King (@l2dy), Edson Gellert Schubert, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Oct 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - tcresson - Sep 2023 - Sep 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Petr Písař - Mar 2022 - Mar 2022 - - - 7. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jan 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Dusan Klinec (@ph4r05), Anca Vamanu, Razvan Pistolea, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Christian Schlatter. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Christian Schlatter. -
- -
diff --git a/modules/ldap/doc/ldap.xml b/modules/ldap/doc/ldap.xml deleted file mode 100644 index c89b82e4b80..00000000000 --- a/modules/ldap/doc/ldap.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - LDAP Module - &osips; - - - - &admin; - &devel; - &faq; - &biblio; - &contrib; - - &docCopyrights; - ©right; 2007 University of North Carolina - diff --git a/modules/ldap/doc/ldap_admin.xml b/modules/ldap/doc/ldap_admin.xml deleted file mode 100644 index d83892e0c89..00000000000 --- a/modules/ldap/doc/ldap_admin.xml +++ /dev/null @@ -1,1270 +0,0 @@ - - &adminguide; - -
- Overview - - The LDAP module implements an LDAP search interface for OpenSIPS. It exports script functions to perform an LDAP search operation and to store the search results as OpenSIPS AVPs. This allows for using LDAP directory data in the OpenSIPS SIP message routing script. - - The following features are offered by the LDAP module: - - - LDAP search function taking an LDAP URL as input both synchronous and asynchronous - - - LDAP result parsing functions to store LDAP data as AVP - - - Support for accessing multiple LDAP servers - - - LDAP SIMPLE authentication - - - LDAP server failover and automatic reconnect - - - Configurable LDAP connection and bind timeouts - - - Module API for LDAP search operations that can be used by other OpenSIPS modules - - - StartTLS support - - - - The module implementation makes use of the open source OpenLDAP library available on most UNIX/Linux platforms. Besides LDAP server failover and automatic reconnect, this module can handle multiple LDAP sessions concurrently allowing to access data stored on different LDAP servers. Each OpenSIPS worker process maintains one LDAP TCP connection per configured LDAP server. This enables parallel execution of LDAP requests and offloads LDAP concurrency control to the LDAP server(s). - - An LDAP search module API is provided that can be used by other OpenSIPS modules. A module using this API does not have to implement LDAP connection management and configuration, while still having access to the full OpenLDAP API for searching and result handling. - - Since LDAP server implementations are optimized for fast read access they are a good choice to store SIP provisioning data. Performance tests have shown that this module achieves lower data access times and higher call rates than other database modules like e.g. the OpenSIPS MYSQL module. - -
- Usage Basics - - - First so called LDAP sessions have to be specified in an external configuration file (as described in ). Each LDAP session includes LDAP server access parameters like server hostname or connection timeouts. Normally only a single LDAP session will be used unless there is a need to access more than one LDAP server. The LDAP session name will then be used in the OpenSIPS configuration script to refer to a specific LDAP session. - - - - The ldap_search function () performs an LDAP search operation. It expects an LDAP URL as input which includes the LDAP session name and search parameters. provides a quick overview on LDAP URLs. - - - - The result of an LDAP search is stored internally and can be accessed with one of the ldap_result* functions. ldap_result () stores resulting LDAP attribute value as AVPs. ldap_result_check () is a convenience function to compare a string with LDAP attribute values using regular expression matching. Finally, ldap_result_next () allows to handle LDAP search queries that return more than one LDAP entry. - - - - All ldap_result* functions do always access the LDAP result set from the last ldap_search call. This should be kept in mind when calling ldap_search more than once in the OpenSIPS configuration script. - -
- -
- LDAP URLs - - - ldap_search expects an LDAP URL as argument. This section describes the format and semantics of an LDAP URL. - - - - RFC 4516 describes the format of an LDAP Uniform Resource Locator (URL). An LDAP URL represents an LDAP search operation in a compact format. The LDAP URL format is defined as follows (slightly modified, refer to section 2 of for ABNF notation): - - -
- ldap://[ldap_session_name][/dn?attrs[?scope[?filter]]]] -
- - - - ldap_session_name - - - An LDAP session name as defined in the LDAP - configuration file. - - (RFC 4516 defines this as LDAP hostport parameter) - - - - - dn - - - Base Distinguished Name (DN) of LDAP search or target of - non-search operation, as defined in RFC 4514 - - - - - attrs - - - Comma separated list of LDAP attributes to be - returned - - - - - scope - - - Scope for LDAP search, valid values are - base, one, or - sub - - - - - filter - - - LDAP search filter definition following rules of RFC 4515 - - The following table lists characters that have to be - escaped in LDAP search filters: - - - RFC 4515 Escaping Rules - - - - - * - - \2a - - - - ( - - \28 - - - - ) - - \29 - - - - \ - - \5c - - - -
-
-
-
-
- - - Non-URL characters in an LDAP URL have to be escaped using - percent-encoding (refer to section 2.1 of RFC 4516). In particular - this means that any "?" character in an LDAP URL component must be - written as "%3F", since "?" is used as a URL delimiter. - The exported function ldap_filter_url_encode () - implements RFC 4515/4516 LDAP search filter and URL escaping - rules. - -
-
- -
- Dependencies - -
- OpenSIPS Modules - - The module depends on the following modules (the listed modules - must be loaded before this module): - - - - No dependencies on other OpenSIPS modules. - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running OpenSIPS with this module loaded: - - - - OpenLDAP library (libldap) v2.1 or greater, libldap header files - (libldap-dev) are needed for compilation - - -
-
- -
- LDAP Configuration File - - The module reads an external confiuration file at module - initialization time that includes LDAP session definitions. - -
- Configuration File Syntax - - The configuration file follows the Windows INI file syntax, - section names are enclosed in square brackets:[Section_Name]Any - section can contain zero or more configuration key assignments of the - formkey = value ; commentValues can - be given enclosed with quotes. If no quotes are present, the value is - understood as containing all characters between the first and the last - non-blank characters. Lines starting with a hash sign and blank lines - are treated as comments. - - Each section describes one LDAP session that can be referred to - in the OpenSIPS configuration script. Using the section name as the - host part of an LDAP URL tells the module to use the LDAP session - specified in the respective section. An example LDAP session - specification looks like: - -[example_ldap] -ldap_server_url = "ldap://ldap1.example.com, ldap://ldap2.example.com" -ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" -ldap_bind_password = "pwd" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 -ldap_ca_cert_file = "/usr/share/ca-certificates/mycert.pem" -ldap_cert_file = "/var/my-certificate/certificate.pem" -ldap_key_file = "/var/my-certificate/key.pem" -ldap_require_certificate = "ALLOW" - - The configuration keys are - explained in the following section. This LDAP session can be referred - to in the routing script by using an LDAP URL like - e.g.ldap://example_ldap/cn=admin,dc=example,dc=com - -
- -
- LDAP Session Settings - - - - ldap_server_url (mandatory) - - - - LDAP URL including fully qualified domain name or IP address of LDAP server optionally followed by a colon and TCP port to connect: ldap://<FQDN/IP>[:<port>]. Failover LDAP servers can be added, each separated by a comma. In the event of connection errors, the module tries to connect to servers in order of appearance. - - - Default value: none, this is a mandatory setting - - - <varname>ldap_server_url</varname> examples - - -ldap_server_url = "ldap://localhost" -ldap_server_url = "ldap://ldap.example.com:7777" -ldap_server_url = "ldap://ldap1.example.com, - ldap://ldap2.example.com:80389" - - - - - - - ldap_version (optional) - - - Supported LDAP versions are 2 and 3. - - Default value: 3 (LDAPv3) - - - <varname>ldap_version</varname> example - - ldap_version = 2 - - - - - - ldap_bind_dn (optional) - - - Authentication user DN used to bind to LDAP server (module - currently only supports SIMPLE_AUTH). Empty string enables - anonymous LDAP bind. - - Default value: (empty string --> - anonymous bind) - - - <varname>ldap_bind_dn</varname> example - - ldap_bind_dn = "cn=root,dc=example,dc=com"; - - - - - - ldap_bind_password (optional) - - - Authentication password used to bind to LDAP server - (SIMPLE_AUTH). Empty string enables anonymous bind. - - Default value: (empty string --> - anonymous bind) - - - <varname>ldap_bind_password</varname> example - - ldap_bind_password = "secret"; - - - - - - ldap_network_timeout (optional) - - - LDAP TCP connect timeout in milliseconds. Setting this - parameter to a low value enables fast failover if ldap_server_url contains more than one LDAP server addresses. - - Default value: 1000 (one second) - - - <varname>ldap_network_timeout</varname> example - - ldap_network_timeout = 500 ; setting TCP timeout to 500 ms - - - - - - ldap_client_bind_timeout (optional) - - - LDAP bind operation timeout in milliseconds. - - Default value: 1000 (one second) - - - <varname>ldap_client_bind_timeout</varname> - example - - ldap_client_bind_timeout = 1000 - - - - - - ldap_ca_cert_file (optional) - - - LDAP full path of the CA certificate file. - - No default value. It is mandatory in case you wish to use StartTLS - - - <varname>ldap_ca_cert_file</varname> - example - - ldap_ca_cert_file = "/usr/local/CAcert.pem" - - - - - - ldap_cert_file (optional) - - - LDAP full path of the certificate file. - - No default value. It is mandatory in case you wish to use StartTLS - - - <varname>ldap_cert_file</varname> - example - - ldap_cert_file = "/usr/local/mycert.pem" - - - - - - ldap_key_file (optional) - - - LDAP full path of the key file. - - No default value. It is mandatory in case you wish to use StartTLS - - - <varname>ldap_key_file</varname> - example - - ldap_key_file = "/usr/local/mykey.pem" - - - - - - ldap_require_certificate (optional) - - - LDAP peer certificate checking strategy, one of "NEVER", "HARD", "DEMAND", "ALLOW", "TRY". - Lower case letters are also accepted. - - Default value "NEVER". - - - <varname>ldap_require_certificate</varname> - example - - ldap_require_certificate = "NEVER" - - - - - -
- -
- Configuration File Example - - The following configuration file example includes two LDAP - session definitions that could be used e.g. for accessing H.350 data - and do phone number to name mappings. - - - Example LDAP Configuration File - - -# LDAP session "sipaccounts": -# -# - using LDAPv3 (default) -# - two redundant LDAP servers -# -[sipaccounts] -ldap_server_url = "ldap://h350-1.example.com, ldap://h350-2.example.com" -ldap_bind_dn = "cn=sip_proxy,ou=accounts,dc=example,dc=com" -ldap_bind_password = "pwd" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 -#using StartTLS -ldap_ca_cert_file = "/ldap/path/to/ca/certificate.pem" -ldap_cert_file = "/ldap/path/to/certificate.pem" -ldap_key_file = "/ldap/path/to/key/file.pem" -ldap_require_certificate = "NEVER" - - -# LDAP session "campus": -# -# - using LDAPv2 -# - anonymous bind -# -[campus] -ldap_version = 2 -ldap_server_url = "ldap://ldap.example.com" -ldap_network_timeout = 500 -ldap_client_bind_timeout = 500 - - -
-
- -
- Exported Parameters - -
- config_file (string) - - Full path to LDAP configuration file. - - Default value: - /usr/local/etc/opensips/ldap.cfg - - - <varname>config_file</varname> parameter usage - - -modparam("ldap", "config_file", "/etc/opensips/ldap.ini") - - -
- -
- max_async_connections (int) - - Number of maximum asynchronous connections that will be started - with the ldap server for executing asynchronous ldap_search calls. - The number of connections is per process, so if there are 8 - worker processes with 20 max_async_connections, there will be a - maximum of 160 connections to the ldap server. - - - Default value: 20 - - - <varname>max_async_connections</varname> parameter usage - - -modparam("ldap", "max_async_connections", 50) - - - -
-
- -
- Exported Functions - -
- ldap_search(ldap_url) - - Performs an LDAP search operation using given LDAP URL and stores result - internally for later retrieval by ldap_result* functions. If one ore - more LDAP entries are found the function returns the number of found - entries which evaluates to TRUE in the OpenSIPS configuration script. - It returns -1 (FALSE) in case no - LDAP entry was found, and -2 - (FALSE) if an internal error like e.g. an LDAP - error occurred. - - - Function Parameters: - - - ldap_url (string) - - - An LDAP URL defining the LDAP search operation (refer to - for a description of the LDAP URL - format). The hostport part must be one of the LDAP session names - declared in the LDAP configuration script. - - - Example Usage of ldap_url - - Search with LDAP session named - sipaccounts, base - ou=sip,dc=example,dc=com, - one level deep using search filter - (cn=schlatter) and returning all - attributes: - - ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) - - Subtree search with LDAP session named - ldap1, base - dc=example,dc=com using search filter - (cn=$(avp(name))) and returning - SIPIdentityUserName and - SIPIdentityServiceLevel attributes - - -ldap://ldap_1/dc=example,dc=com? - SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) - - - - - - - - Return Values: - - - n > 0 (TRUE): - - - - - Found n matching LDAP - entries - - - - - - - -1 (FALSE): - - - - - No matching LDAP entries found - - - - - - - -2 (FALSE): - - - - - LDAP error (e.g. LDAP server unavailable), or - - - - internal error - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... -# ldap search -if (!ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$rU)")) -{ - switch ($retcode) - { - case -1: - # no LDAP entry found - sl_send_reply(404, "User Not Found"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} -xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)"); - -# save telephone number in $avp(tel_number) -ldap_result("telephoneNumber/$avp(tel_number)"); -... - - -
- -
- ldap_result(ldap_attr_name, avp_spec, [avp_type], [regex_subst]) - - This function converts LDAP attribute values into AVPs for later - use in the message routing script. It accesses the LDAP result set - fetched by the last ldap_search call. - ldap_attr_name specifies the LDAP attribute name - who's value should be stored in AVP avp_spec. Multi - valued LDAP attributes generate an indexed AVP. The optional - regex_subst parameter allows to further define what - part of an attribute value should be stored as AVP. - - - An AVP can either be of type string or integer. As default, ldap_result stores LDAP attribute values as AVP of type string. The optional avp_type parameter can be used to explicitly specify the type of the AVP. It can be either str for string, or int for integer. If avp_type is specified as int then ldap_result tries to convert the LDAP attribute values to integer. In this case, the values are only stored as AVP if the conversion to integer is successful. - - - - Function Parameters: - - - ldap_attr_name (string) - - - The name of the LDAP attribute who's value should be - stored, e.g. SIPIdentityServiceLevel or - telephonenumber - - - - - avp_spec (var) - - - Specification of destination AVP, e.g. - $avp(service_level) or - $avp(12) - - - - - avp_type (string, optional) - - - - Specification of destination AVP type, either str or int. If this parameter is not specified then the LDAP attribute values are stored as AVP of type string. - - - - - - regex_subst (string) - - - Regex substitution that gets applied to LDAP attribute - value before storing it as AVP, e.g. - "/^sip:(.+)$/\1/" to strip off "sip:" from - the beginning of an LDAP attribute value. - - - - - - Return Values: - - - n > 0 (TRUE) - - - - LDAP attribute ldap_attr_name found in LDAP result set and n LDAP attribute values stored in avp_spec - - - - - - -1 (FALSE) - - - No LDAP attribute ldap_attr_name found - in LDAP result set - - - - - -2 (FALSE) - - - Internal error occurred - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... - -# ldap_search call -... - -# save SIPIdentityServiceLevel in $avp(service_level) -if (!ldap_result("SIPIdentityServiceLevel", $avp(service_level))) -{ - switch ($retcode) - { - case -1: - # no SIPIdentityServiceLevel found - sl_send_reply(403, "Forbidden"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} - -# save SIP URI domain in $avp(10) -ldap_result("SIPIdentitySIPURI", $avp(10), "/^[^@]+@(.+)$/\1/"); -... - - -
- -
- ldap_result_check(ldap_attr_name, string_to_match, [, - regex_subst]) - - This function compares ldap_attr_name's value - with string_to_match for equality. It accesses the LDAP result set - fetched by the last ldap_search call. The - optional regex_subst parameter allows to further - define what part of the attribute value should be used for the - equality match. If ldap_attr_name is multi valued, - each value is checked against string_to_match. If - one or more of the values do match the function returns 1 - (TRUE). - - - Function Parameters: - - - ldap_attr_name (string) - - - The name of the LDAP attribute who's value should be - matched, e.g. SIPIdentitySIPURI - - - - - string_to_match (string) - - - String to be matched. Included AVPs and pseudo variabels - do get expanded. - - - - - regex_subst (string, optional) - - - Regex substitution that gets applied to LDAP attribute - value before comparing it with string_to_match, e.g. - "/^[^@]@+(.+)$/\1/" to extract the domain part - of a SIP URI - - - - - - Return Values: - - - 1 (TRUE) - - - One or more ldap_attr_name attribute values match - string_to_match (after - regex_subst is applied) - - - - - -1 (FALSE) - - - ldap_attr_name attribute not found or - attribute value doesn't match string_to_match - (after regex_subst is applied) - - - - - -2 (FALSE) - - - Internal error occurred - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... -# ldap_search call -... - -# check if 'sn' ldap attribute value equals username part of R-URI, -# the same could be achieved with ldap_result_check("sn/$rU") -if (!ldap_result_check("sn", $ru, "/^sip:([^@]).*$/\1/")) -{ - switch ($retcode) - { - case -1: - # R-URI username doesn't match sn - sl_send_reply(401, "Unauthorized"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } -} -... - - -
- -
- ldap_result_next() - - An LDAP search operation can return multiple LDAP entries. This - function can be used to cycle through all returned LDAP entries. It - returns 1 (TRUE) if there is another LDAP entry present in the LDAP - result set and causes ldap_result* functions to work on the next LDAP - entry. The function returns -1 (FALSE) if there are no more LDAP - entries in the LDAP result set. - - - Return Values: - - - 1 (TRUE) - - - Another LDAP entry is present in the LDAP result set and - result pointer is incremented by one - - - - - -1 (FALSE) - - - No more LDAP entries are available - - - - -2 (FALSE) - - - Internal error - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... -# ldap_search call -... - -ldap_result("telephonenumber/$avp(tel1)"); -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel2)"); -} -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel3)"); -} -if (ldap_result_next()) -{ - ldap_result("telephonenumber/$avp(tel4)"); -} -... - - -
- -
- ldap_filter_url_encode(string, avp_spec) - - This function applies the following escaping rules to - string and stores the result in AVP - avp_spec: - - - ldap_filter_url_encode() escaping rules - - - - - character in - string - - gets replaced with - - defined in - - - - - - * - - \2a - - RFC 4515 - - - - ( - - \28 - - RFC 4515 - - - - ) - - \29 - - RFC 4515 - - - - \ - - \5c - - RFC 4515 - - - - ? - - %3F - - RFC 4516 - - - -
- - The string stored in AVP avp_spec can be safely used in an LDAP - URL filter string. - - - Function Parameters: - - - string - - - String to apply RFC 4515 and URL escpaing rules to. - AVPs and pseudo variables do get expanded. Example: - "cn=$avp(name)" - - - - - avp_spec (var) - - - AVP to store resulting RFC 4515 - and URL encoded string, e.g. $avp(ldap_search) - or $avp(10) - - - - - - Return Values: - - - 1 (TRUE) - - - RFC 4515 and URL encoded - filter_component stored as AVP - avp_name - - - - - -1 (FALSE) - - - Internal error - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... -if (!ldap_filter_url_encode("cn=$avp(name)", $avp(name_esc))) -{ - # RFC 4515/URL encoding failed --> silently discard request - exit; -} - -xlog("L_INFO", "encoded LDAP filter component: [$avp(name_esc)]\n"); - -if (ldap_search( - "ldap://h350/ou=commObjects,dc=example,dc=com??sub?($avp(name_esc))")) - { ... } -... - - -
-
- -
- Exported Async Functions - -
- ldap_search(ldap_url) - - Performs an LDAP search operation using given LDAP URL and stores result - internally for later retrieval by ldap_result* functions. If one ore - more LDAP entries are found the function returns the number of found - entries which evaluates to TRUE in the OpenSIPS configuration script. - It returns -1 (FALSE) in case no - LDAP entry was found, and -2 - (FALSE) if an internal error like e.g. an LDAP - error occurred. - - - Function Parameters: - - - ldap_url (string) - - - An LDAP URL defining the LDAP search operation (refer to - for a description of the LDAP URL - format). The hostport part must be one of the LDAP session names - declared in the LDAP configuration script. - - - Example Usage of ldap_url - - Search with LDAP session named - sipaccounts, base - ou=sip,dc=example,dc=com, - one level deep using search filter - (cn=schlatter) and returning all - attributes: - - ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=schlatter) - - Subtree search with LDAP session named - ldap1, base - dc=example,dc=com using search filter - (cn=$(avp(name))) and returning - SIPIdentityUserName and - SIPIdentityServiceLevel attributes - - -ldap://ldap_1/dc=example,dc=com? - SIPIdentityUserName,SIPIdentityServiceLevel?sub?(cn=$(avp(name))) - - - - - - - - Return Values: - - - n > 0 (TRUE): - - - - - Found n matching LDAP - entries - - - - - - - -1 (FALSE): - - - - - No matching LDAP entries found - - - - - - - -2 (FALSE): - - - - - LDAP error (e.g. LDAP server unavailable), or - - - - internal error - - - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE, and ONREPLY_ROUTE. - - - - Example Usage - - -... -# ldap search - -route { - async( ldap_search("ldap://sipaccounts/ou=sip,dc=example,dc=com??one?(cn=$rU)"), resume); -} -.... -route[resume] { -{ - switch ($rc) - { - case -1: - # no LDAP entry found - sl_send_reply(404, "User Not Found"); - exit; - case -2: - # internal error - sl_send_reply(500, "Internal server error"); - exit; - default: - exit; - } - xlog("L_INFO", "ldap_search: found [$retcode] entries for (cn=$rU)"); - - # save telephone number in $avp(tel_number) - ldap_result("telephoneNumber", $avp(tel_number)"); -... -} - - -
- - -
- - - -
- Installation & Running - -
- Compiling the Module - - - OpenLDAP library (libldap) and header files (libldap-dev) v2.1 or greater (this module was tested with v2.1.3 and v2.3.32) are required for compiling the LDAP module. The OpenLDAP source is available at http://www.openldap.org/. - - - The OpenLDAP library is available pre-compiled for most UNIX/Linux flavors. On Debian/Ubuntu, the following packages must be installed: # apt-get install libldap2 libldap2-dev. - -
-
-
- diff --git a/modules/ldap/doc/ldap_biblio.xml b/modules/ldap/doc/ldap_biblio.xml deleted file mode 100644 index 465a956f9e3..00000000000 --- a/modules/ldap/doc/ldap_biblio.xml +++ /dev/null @@ -1,127 +0,0 @@ - - Resources - - - - RFC4510 - - <ulink url="http://tools.ietf.org/html/rfc4510">Lightweight - Directory Access Protocol (LDAP): Technical Specification Road - Map</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - RFC4511 - - <ulink url="http://tools.ietf.org/html/rfc4511">Lightweight - Directory Access Protocol (LDAP): The Protocol</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - RFC4514 - - <ulink url="http://tools.ietf.org/html/rfc4514">Lightweight - Directory Access Protocol (LDAP): String Representation of - Distinguished Names</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - RFC4515 - - <ulink url="http://tools.ietf.org/html/rfc4515">Lightweight - Directory Access Protocol (LDAP): String Representation of Search - Filters</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - RFC4516 - - <ulink url="http://tools.ietf.org/html/rfc4516">Lightweight - Directory Access Protocol (LDAP): Uniform Resource - Locator</ulink> - - June 2006 - - - Internet Engineering Task Force - - - - - RFC2617 - - <ulink url="http://tools.ietf.org/html/rfc2617">HTTP - Authentication: Basic and Digest Access Authentication</ulink> - - June 1999 - - - Internet Engineering Task Force - - - - - RFC3261 - - <ulink url="http://tools.ietf.org/html/rfc3261">SIP: Session - Initiation Protocol</ulink> - - June 2002 - - - Internet Engineering Task Force - - - - - H.350 - - <ulink url="http://www.itu.int/rec/T-REC-H.350/en">Directory - Services Architecture for Multimedia Conferencing</ulink> - - August 2003 - - - ITU-T - - - - - H.350.4 - - <ulink url="http://www.itu.int/rec/T-REC-H.350.4/en">Directory - services architecture for SIP</ulink> - - August 2003 - - - ITU-T - - - - - diff --git a/modules/ldap/doc/ldap_devel.xml b/modules/ldap/doc/ldap_devel.xml deleted file mode 100644 index 92c6c595c07..00000000000 --- a/modules/ldap/doc/ldap_devel.xml +++ /dev/null @@ -1,595 +0,0 @@ - - - - &develguide; -
- Overview - - The LDAP module API can be used by other OpenSIPS modules to implement LDAP search functionality. This frees the module implementer from having to care about LDAP connection management and configuration. - - - In order to use this API, a module has to load the API using the load_ldap_api function which returns a pointer to a ldap_api structure. This structure includes pointers to the API functions described below. The LDAP module source file api.h includes all declarations needed to load the API, it has to be included in the file that loads the API. Loading the API is typically done inside a module's mod_init call as the following example shows: - - Example code fragment to load LDAP module API - - - - - - The API functions can then be used like in the following example: - - Example LDAP module API function call - - - - - -
- -
- API Functions - -
- ldap_params_search - - Performs an LDAP search using the parameters given as function arguments. - - - - - Function arguments: - - int* _ld_result_count - - - The function stores the number of returned LDAP entries in _ld_result_count. - - - - - char* _lds_name - - - LDAP session name as configured in the LDAP module configuration file. - - - - - char* _dn - - - LDAP search DN. - - - - - int _scope - - - LDAP search scope, one of LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_BASE, or LDAP_SCOPE_SUBTREE, as defined in OpenLDAP's ldap.h. - - - - - char** _attrs - - - A null-terminated array of attribute types to return from entries. If empty (NULL), all attribute types are returned. - - - - - char* _filter - - - LDAP search filter string according to RFC 4515. printf patterns in this string do get replaced with the function arguments' values following the _filter argument. - - - - - - - Return Values: - - -1 - - - Internal error. - - - - - 0 - - - Success, _ld_result_count includes the number of LDAP entries found. - - - - -
- -
- ldap_url_search - - Performs an LDAP search using an LDAP URL. - - - - - Function arguments: - - char* _ldap_url - - - LDAP URL as described in . - - - - - int* _result_count - - - The function stores the number of returned LDAP entries in _ld_result_count. - - - - - - Return Values: - - -1 - - - Internal error. - - - - - 0 - - - Success, _ld_result_count includes the number of LDAP entries found. - - - - -
- -
- ldap_result_attr_vals - - Retrieve the value(s) of a returned LDAP attribute. The function accesses the LDAP result returned by the last call of ldap_params_search or ldap_url_search. The berval structure is defined in OpenLDAP's ldap.h, which has to be included. - - - This function allocates memory to store the LDAP attribute value(s). This memory has to freed with the function ldap_value_free_len (see next section). - - - - - Function arguments: - - str* _attr_name - - - str structure holding the LDAP attribute name. - - - - - struct berval ***_vals - - - A null-terminated array of the attribute's value(s). - - - - - - Return Values: - - -1 - - - Internal error. - - - - - 0 - - - Success, _vals includes the attribute's value(s). - - - - - 1 - - - No attribute value found. - - - - -
- -
- ldap_value_free_len - - Function used to free memory allocated by ldap_result_attr_vals. The berval structure is defined in OpenLDAP's ldap.h, which has to be included. - - - - - Function arguments: - - struct berval **_vals - - - berval array returned by ldap_result_attr_vals. - - - - -
- -
- ldap_result_next - - Increments the LDAP result pointer. - - - - - Return Values: - - -1 - - - No LDAP result found, probably because ldap_params_search or ldap_url_search was not called. - - - - - 0 - - - Success, LDAP result pointer points now to next result. - - - - - 1 - - - No more results available. - - - - -
- -
- ldap_str2scope - - Converts LDAP search scope string into integer value e.g. for ldap_params_search. - - - - - Function arguments: - - char* scope_str - - - LDAP search scope string. One of "one", "onelevel", "base", "sub", or "subtree". - - - - - - Return Values: - - -1 - - - scope_str not recognized. - - - - - n >= 0 - - - LDAP search scope integer. - - - - -
- -
- ldap_rfc4515_escape - - Applies escaping rules described in . - - - - - Function arguments: - - str *sin - - - str structure holding the string to apply the escaping rules. - - - - - str *sout - - - str structure holding the escaped string. The length of this string must be at least three times the length of sin plus one. - - - - - int url_encode - - - Flag that specifies if a '?' character gets escaped with '%3F' or not. If url_encode equals 0, '?' does not get escaped. - - - - - - Return Values: - - -1 - - - Internal error. - - - - - 0 - - - Success, sout contains escaped string. - - - - -
- -
- get_ldap_handle - - Returns the OpenLDAP LDAP handle for a specific LDAP session. This allows a module implementor to use the OpenLDAP API functions directly, instead of using the API functions exported by the OpenSIPS LDAP module. The LDAP structure is defined in OpenLDAP's ldap.h, which has to be included. - - - - - Function arguments: - - char* _lds_name - - - LDAP session name as specified in the LDAP module configuration file. - - - - - LDAP** _ldap_handle - - - OpenLDAP LDAP handle returned by this function. - - - - - - Return Values: - - -1 - - - Internal error. - - - - - 0 - - - Success, _ldap_handle contains the OpenLDAP LDAP handle. - - - - -
- -
- get_last_ldap_result - - Returns the OpenLDAP LDAP handle and OpenLDAP result handle of the last LDAP search operation. These handles can be used as input for OpenLDAP LDAP result API functions. LDAP and LDAPMessage structures are defined in OpenLDAP's ldap.h, which has to be included. - - - - - Function arguments: - - LDAP** _last_ldap_handle - - - OpenLDAP LDAP handle returned by this function. - - - - - LDAPMessage** _last_ldap_result - - - OpenLDAP result handle returned by this function. - - - - -
-
-
- Example Usage - - The following example shows how this API can be used to perform an LDAP search operation. It is assumed that the API is loaded and available through the ldap_api pointer. - - bv_val; -res_password.len = attr_vals[0]->bv_len; - -ldap_api.ldap_value_free_len(attr_vals); - -LM_INFO("Password for user [%s]: [%s]\n", sip_username, res_password.s); - -... - -return 0; -]]> - -
-
- diff --git a/modules/load_balancer/README b/modules/load_balancer/README deleted file mode 100644 index 8c352be5f2e..00000000000 --- a/modules/load_balancer/README +++ /dev/null @@ -1,844 +0,0 @@ -Load Balancer Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Probing and Disabling destinations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. db_url (string) - 1.5.2. db_table (string) - 1.5.3. probing_interval (integer) - 1.5.4. probing_method (string) - 1.5.5. probing_from (string) - 1.5.6. probing_reply_codes (string) - 1.5.7. probing_verbose (number) - 1.5.8. lb_define_blacklist (string) - 1.5.9. fetch_freeswitch_stats (integer) - 1.5.10. initial_freeswitch_load (integer) - 1.5.11. cluster_id (integer) - 1.5.12. cluster_sharing_tag (string) - - 1.6. Exported Functions - - 1.6.1. lb_start(grp,resources[,flags],[attrs]) - 1.6.2. lb_next([attrs]) - 1.6.3. - lb_start_or_next(grp,resources[,flags],[attrs] - ) - - 1.6.4. load_balance(grp,resources[,flags],[attrs]) - 1.6.5. lb_reset() - 1.6.6. lb_is_started() - 1.6.7. lb_disable_dst() - 1.6.8. - lb_is_destination(ip,port,[group],[active],[at - trs]]) - - 1.6.9. lb_count_call(ip,port,grp,resources[,undo]) - - 1.7. Exported MI Functions - - 1.7.1. lb_reload - 1.7.2. lb_resize - 1.7.3. lb_list - 1.7.4. lb_status - - 1.8. Exported Events - - 1.8.1. E_LOAD_BALANCER_STATUS - - 2. Developer Guide - - 2.1. Available Functions - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set db_table parameter - 1.3. Set probing_interval parameter - 1.4. Set probing_method parameter - 1.5. Set probing_from parameter - 1.6. Set probing_reply_codes parameter - 1.7. Set probing_verbose parameter - 1.8. Set the lb_define_blacklist parameter - 1.9. Set the fetch_freeswitch_load parameter - 1.10. Set the initial_freeswitch_load parameter - 1.11. Set cluster_id parameter - 1.12. Set cluster_sharing_tag parameter - 1.13. lb_start usage - 1.14. lb_next() usage - 1.15. lb_next() usage - 1.16. lb_disable_dst() usage - 1.17. lb_is_destination usage - 1.18. lb_count_call usage - 1.19. lb_list usage - 1.20. lb_status usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Load-Balancer module comes to provide traffic routing based - on load. Shortly, when OpenSIPS routes calls to a set of - destinations, it is able to keep the load status (as number of - ongoing calls) of each destination and to choose to route to - the less loaded destination (at that moment). OpenSIPS is aware - of the capacity of each destination - it is preconfigured with - the maximum load accepted by the destinations. To be more - precise, when routing, OpenSIPS will consider the less loaded - destination not the destination with the smallest number of - ongoing calls, but the destination with the largest available - slot. - - Also the module has the capability to do failover (to try a new - destination if the selected one does not respond), to keep - state of the destinations (to remember the failed destination - and avoid using them agai) and to check the health of the - destination (by doing probing of the destination and auto - re-enabling). - -1.2. How it works - - Please refer to the Load-Balancer tutorial from the OpenSIPS - website: - https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9. - -1.3. Probing and Disabling destinations - - The module has the capability to monitor the status of the - destinations by doing SIP probing (sending SIP requests like - OPTIONS). - - For each destination, you can configure what kind of probing - should be done (probe_mode column): - * (0) - no probing at all; - * (1) - probing only when the destination is in disabled mode - (disabling via MI command will competely stop the probing - also). The destination will be automatically re-enabled - when the probing will succeed next time; - * (2) - probing all the time. If disabled, the destination - will be automatically re-enabled when the probing will - succeed next time; - - A destination can become disabled in two ways: - * script detection - by calling from script the lb_disabled() - function after try the destination. In this case, if - probing mode for the destination is (1) or (2), the - destination will be automatically re-enabled when the - probing will succeed. - * MI command - by calling the lb_status MI command for - disabling (on demand) the destination. If so, the probing - and re-enabling of this destination will be completly - disabled until you re-enable it again via MI command - this - is designed to allow controlled and complete disabling of - some destination during maintenance. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * Dialog - Dialog module - freeswitch. - only if "fetch_freeswitch_stats" is enabled. - * dialog - TM module (only if probing is enabled) - * clusterer - only if "cluster_id" option is enabled. - * database - one of the DB modules - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. db_url (string) - - The URL pointing to the database where the load-balancing rules - are stored. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("load_balancer", "db_url", "dbdriver://username:password@dbhost -/dbname") -... - -1.5.2. db_table (string) - - The name of the DB table containing the load-balancing rules. - - Default value is “load_balancer”. - - Example 1.2. Set db_table parameter -... -modparam("load_balancer", "db_table", "lb") -... - -1.5.3. probing_interval (integer) - - How often (in seconds) the probing of a destination should be - done. If set to 0, the probing will be disabled as - functionality (for all destinations) - - Default value is “30”. - - Example 1.3. Set probing_interval parameter -... -modparam("load_balancer", "probing_interval", 60) -... - -1.5.4. probing_method (string) - - The SIP method to be used for the probing requests. - - Default value is “"OPTIONS"”. - - Example 1.4. Set probing_method parameter -... -modparam("load_balancer", "probing_method", "INFO") -... - -1.5.5. probing_from (string) - - The FROM SIP URI to be advertised in the SIP probing requests. - - Default value is “"sip:prober@localhost"”. - - Example 1.5. Set probing_from parameter -... -modparam("load_balancer", "probing_from", "sip:pinger@192.168.2.10") -... - -1.5.6. probing_reply_codes (string) - - A comma separted list of SIP reply codes. The codes defined - here will be considered as valid reply codes for probing - messages, apart for 200. - - Default value is “NULL”. - - Example 1.6. Set probing_reply_codes parameter -... -modparam("load_balancer", "probing_reply_codes", "501, 403") -... - -1.5.7. probing_verbose (number) - - A boolean option to enable extra logging related to the - enabling or disabling of the destinations based on probing - replies and MI commands. - - A 0 value means disabled, anything else means enabled. - - The extra logging will be done on INFO level. - - Default value is “0” (disabled). - - Example 1.7. Set probing_verbose parameter -... -modparam("load_balancer", "probing_verbose", 1) -... - -1.5.8. lb_define_blacklist (string) - - Defines a blacklist based on a lb group. This list will contain - the IPs (no port, all protocols) of the destinations matching - the given group. - - Multiple instances of this param are allowed. - - Default value is “NULL”. - - Example 1.8. Set the lb_define_blacklist parameter -... -modparam("load_balancer", "lb_define_blacklist", "list= 1,4,3") -modparam("load_balancer", "lb_define_blacklist", "blist2= 2,10,6") -... - -1.5.9. fetch_freeswitch_stats (integer) - - If enabled, the maximum value of a resource may also consist of - FreeSWITCH Event Socket Layer URLs, e.g. - "channels=fs://:password@freeswitch.example.com" or - "channels=fs://user:password@127.0.0.1:8021". The default ESL - port is 8021. - - OpenSIPS will establish a connection with the given socket and - periodically update the internal maximum value of the given - resource using statistics pushed by the FreeSWITCH box. - - The max value of a resource is updated every - event_heartbeat_interval seconds (see the "freeswitch" OpenSIPS - module for more details regarding this setting), as the stats - arrive from FreeSWITCH. - - Given the following format for FreeSWITCH heartbeat messages: -{ - ... - "FreeSWITCH-Hostname": "pbx2", - "FreeSWITCH-IPv4": "172.17.0.3", - "Idle-CPU": "78.400000", - "Max-Sessions": "1000", - "Session-Count": "0", - ... -} - - , the load balancer uses the following formula in order to - periodically update its "max_load" values for each FreeSWITCH - box (FreeSWITCH data is highlighted in bold): - - max_load = (Idle-CPU / 100) * (Max-Sessions - (Session-Count - - current_load)) - - Default value is “0” (disabled). - - Example 1.9. Set the fetch_freeswitch_load parameter -... -modparam("load_balancer", "fetch_freeswitch_stats", 1) -... - -1.5.10. initial_freeswitch_load (integer) - - This parameter is only relevant for some seconds after module - startup/reload, when no statistics from newly loaded FreeSWITCH - ESL sockets have arrived, yet the routing of calls must remain - unaffected. Any FreeSWITCH-enabled resource will inherit this - value for the entire interval mentioned above (up to 20 - seconds!). - - Default value is “1000”. - - Example 1.10. Set the initial_freeswitch_load parameter -... -modparam("load_balancer", "initial_freeswitch_load", 200) -... - -1.5.11. cluster_id (integer) - - The ID of the cluster the module is part of. The clustering - support is used in load-balancer module for two purposes: for - sharing the status of the destinations and for controlling the - pinging to destinations. - - If clustering enbled, the module will automatically share - changes over the status of the destinations with the other - OpenSIPS instances that are part of a cluster. Whenever such a - status changes (following an MI command, a probing result, a - script command), the module will replicate this status change - to all the nodes in this given cluster. - - The clustering with sharing tag support may be used to control - which node in the cluster will perform the pinging/probing to - destinations. See the cluster_sharing_tag option. - - This OpenSIPS cluster exposes the "load_balancer-status-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - For more info on how to define and populate a cluster (with - OpenSIPS nodes) see the "clusterer" module. - - Default value is “0 (none)”. - - Example 1.11. Set cluster_id parameter -... -# replicate destination status with all OpenSIPS in cluster ID 9 -modparam("load_balancer", "cluster_id", 9) -... - -1.5.12. cluster_sharing_tag (string) - - The name of the sharing tag (as defined per clusterer modules) - to control which node is responsible for perform the - self-triggered actions in the module. Such actions may be the - destination probing or sharing the changes in the destination - status. If defined, only the node with active status of this - tag will perform the actions (pinging and sharing status). - - The cluster_id must be defined for this option to work. - - This is an optional parameter. If not set, all the nodes in the - cluster will individually do the probing and share the status - changes. - - Default value is “empty (none)”. - - Example 1.12. Set cluster_sharing_tag parameter -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("load_balancer", "cluster_id", 9) -modparam("load_balancer", "cluster_sharing_tag", "vip") -... - -1.6. Exported Functions - -1.6.1. lb_start(grp,resources[,flags],[attrs]) - - The function starts a new load-balancing session over the - available destinations. This translates into finding the less - loaded destination that can provide the requested resources and - belong to a requested group. - - Meaning of the parameters is as follows: - * grp (int) - group id for the destinations; the destination - may be grouped in several groups you can you for differnet - scenarios. - * resources (string) - a semi-colon separated list of - resources required by the current call. - * flags (string, optional) - various flags to controll the LB - algorithm ( or computing the available load on the system): - + n - Negative availability - use destinations with - negative availability (exceeded capacity); do not - ignore resources with negative availability, and thus - able to select for load balancing destinations with - exceeded capacity. This might be needed in scenarios - where we want to limit generic calls volume and always - pass important/high-priority calls. - + r - Relative value - the relative available load (how - many percentages are free) is used in computing the - load of each pear/resource; Without this flag, the - Absolute value is assumed - the effective available - load ( maximum_load - current_load) is used in - computing the load of each pear/resource. - + s - Pick a random destination if multiple destinations - with the same load are found, instead of always - picking first matched destination. This could help to - offload an excessive load from the first destination - and distribute load in situations when failed calls - always routed to first destination, since they almost - does not affect load counters of destinations. - * attrs (var, optional) - a writable variable to be populated - with the attributes of the selected destination. - - The function may return: - * 1 (true) - if a new destination URI is set, pointing to the - selected destination. NOTE that the RURI will not be - changed by this function. - * -1 (false) - generic internal error (memory allocation, - parsing) - * -2 (false) - no capacity available (detinations are up and - available, but they do not have any availabe channels) - * -3 (false) - no destinations available (the requested - resources did not match any active destination) - * -4 (false) - bad resources (requested resources do not - exist) - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.13. lb_start usage -... -if (lb_start(1,"trascoding;conference")) { - # dst URI points to the new destination - xlog("sending call to $du\n"); - t_relay(); - exit; -} -... - -1.6.2. lb_next([attrs]) - - Function to be used to pull the next available (and less - loaded) destination. You need to have an ongoing LB session - (started with lb_start()). - - This function is mainly used for implementing failover for the - LB destinations. - - Meaning of the parameters is as follows: - * attrs (var, optional) - a writable variable to be populated - with the attributes of the selected destination. - - The function may return: - * 1 (true) - if a new destination URI is set, pointing to the - selected destination. NOTE that the RURI will not be - changed by this function. - * -1 (false) - generic internal error (memory allocation, - parsing) - * -2 (false) - no capacity available (detinations are up and - available, but they do not have any availabe channels) - * -3 (false) - no more destinations available (the requested - resources did not match any active destination) - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.14. lb_next() usage -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - /* check next available LB destination */ - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - exit; - } -} - -... - -1.6.3. lb_start_or_next(grp,resources[,flags],[attrs]) - - This is just a wrapper function to simplify scripting. If there - is no ongoing LB session, it acts as lb_start(); If there is an - ongoing LB session, it acts as lb_next(). - -1.6.4. load_balance(grp,resources[,flags],[attrs]) - - Old name of the lb_start_or_next() function. - - Take care, this will become obsolete. - -1.6.5. lb_reset() - - Function to stop and flush a current LB session. To be used in - failure route, if you want to stop the current LB session (not - to try any other destinations from this session) and to start a - completly new one. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.15. lb_next() usage -... -if (t_check_status("(5[0-9][0-9])")) { - /* check next available LB destination */ - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - exit; - } -} else if (t_check_status("(408)")) { - lb_reset(); - if (lb_start(1,"conference")) { - t_relay(); - exit; - } -} -... - -1.6.6. lb_is_started() - - Function to check if there is any ongoing LB session. Returns - true if so. - - This function can be used in any type of route. - -1.6.7. lb_disable_dst() - - Marks as disabled the last destination that was used for the - current call. The disabling done via this function will prevent - the destination to be used for usage from now on. The probing - mechanism can re-enable this peer (see the probing section in - the beginning) - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.16. lb_disable_dst() usage -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - lb_disable_dst(); - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - } else { - t_reply(500,"Error"); - } -} - -... - -1.6.8. lb_is_destination(ip,port,[group],[active],[attrs]]) - - Checks if the given IP and PORT belongs to a destination - configured in the load-balancer's list. Returns true if found - and active (see the "active" parameter). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Meaning of the parameters is as follows: - * ip (string) - IP to be checked - * port (int) - PORT to be checked. A value 0 means "any" - - will match any port. - * group (int, optional) - in what LB group the destination - should be looked for; If not specified, the search will be - in all groups. - * active (int, optional)- if "1", the search will be - performed only over "active" (not disabled) destinations. - If missing, the search will consider any kind of - destinations. - * attrs (var, optional) - a writable variable to be populated - with the attributes of the identified destination. - - Example 1.17. lb_is_destination usage -... -if (lb_is_destination($si,$sp) ) { - # request from a LB destination -} -... - -1.6.9. lb_count_call(ip,port,grp,resources[,undo]) - - The function counts the current call as load for a given - destination with some given resources. Note that this call is - not going through the load-balancing logic (there are not - routing decision taken for the call); it is simply counted by - LB as ongoing call for a destination; - - Meaning of the parameters is as follows: - * ip (string) - IP to identify the destination the call has - to be counted for. - * port (int) - PORT to identify the destination the call has - to be counted for. - * grp (int) - group id for the destinations; if no knows, - "-1" will mean all groups. - * resources - (string) a semi-colon separated list of - resources required by the current call. - * undo - (int, optional) if set to a non zero value, it will - force the function to un-count - actually it will undo the - counting of this call as load in the current LB session; - this might be needed if we count call for particular - resources and then need to un-count it. - - Function returns true if the call was properly taken into - consideration for estimating the load on the destination. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.18. lb_count_call usage -... -# count as load also the calls orgininated by lb destinations -if (lb_is_destination($si,$sp) ) { - # inbound call from destination - lb_count_call($si,$sp,-1,"conference"); -} else { - # outbound call to destinations - if ( !load_balance(1,"conference") ) { - send_reply(503,"unavailable"); - exit(); - } - # dst URI points to the new destination - xlog("sending call to $du\n"); - t_relay(); - exit; -} -... - -1.7. Exported MI Functions - -1.7.1. lb_reload - - Trigers the reload of the load balancing data from the DB. - - MI FIFO Command Format: - opensips-cli -x mi lb_reload - -1.7.2. lb_resize - - Changes the capacity for a resource of a destination. - - Parameters: - * destination_id - the ID (as per DB) of the destination. - * res_name - name of the resource you want to resize. - * new_capacity - new resource capacity. - - MI FIFO Command Format: - opensips-cli -x mi lb_resize 11 voicemail 56 - -1.7.3. lb_list - - Lists all the destinations and the maximum and current load for - each resource of the destination. - - Example 1.19. lb_list usage -$ opensips-cli -x mi lb_list -Destination:: sip:127.0.0.1:5100 id=1 enabled=yes auto-re=on - Resource:: pstn max=3 load=0 - Resource:: transc max=5 load=1 - Resource:: vm max=5 load=2 -Destination:: sip:127.0.0.1:5200 id=2 enabled=no auto-re=on - Resource:: pstn max=6 load=0 - Resource:: trans max=57 load=0 - Resource:: vm max=5 load=0 - -1.7.4. lb_status - - Gets or sets the status (enabled or disabled) of a destination. - - Parameters: - * destination_id - the ID (as per DB) of the destination. - * new_status (optional) - If no new status is given, the - function will return the current status. If a new status is - given (0 - disable, 1 - enable), this status will be forced - for the destination. - - Example 1.20. lb_status usage -$ opensips-cli -x mi lb_status 2 -enable:: no -$ opensips-cli -x mi lb_status 2 1 -$ opensips-cli -x mi lb_status 2 -enable:: yes - -1.8. Exported Events - -1.8.1. E_LOAD_BALANCER_STATUS - - This event is raised when the module changes the state of a - destination, either through MI or probing. - - Parameters: - * group - the group of the destination. - * uri - the URI of the destination. - * status - disabled if the destination was disabled or - enabled if the destination is being used. - -Chapter 2. Developer Guide - -2.1. Available Functions - - NONE - -Chapter 3. Frequently Asked Questions - - 3.1. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 3.2. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 3.3. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 124 74 4331 755 - 2. Liviu Chircu (@liviuchircu) 43 34 688 172 - 3. Vlad Patrascu (@rvlad-patrascu) 38 19 623 766 - 4. Sergey Khripchenko (@shripchenko) 28 10 1058 516 - 5. Razvan Crainea (@razvancrainea) 27 21 266 148 - 6. Vlad Paiu (@vladpaiu) 5 3 7 5 - 7. Maksym Sobolyev (@sobomax) 5 3 6 7 - 8. Walter Doekes (@wdoekes) 5 3 3 3 - 9. Jeremy Martinez (@JeremyMartinez51) 5 2 193 1 - 10. Ezequiel Lovelle (@lovelle) 4 2 3 3 - - All remaining contributors: Anca Vamanu, Andrei Dragus, James - Van Vleet, Dusan Klinec (@ph4r05), Peter Lemenkov (@lemenkov), - Zero King (@l2dy), agree. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Oct 2010 - Oct 2024 - 2. Liviu Chircu (@liviuchircu) Sep 2012 - Sep 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2009 - Oct 2023 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) Mar 2017 - Jul 2022 - 6. agree Jan 2022 - Jan 2022 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Jeremy Martinez (@JeremyMartinez51) Feb 2017 - Feb 2017 - 10. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - - All remaining contributors: Sergey Khripchenko (@shripchenko), - Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Vlad - Paiu (@vladpaiu), Andrei Dragus, James Van Vleet, Anca Vamanu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), agree, Zero King - (@l2dy), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Sergey Khripchenko (@shripchenko), - Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Vlad - Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/load_balancer/README.md b/modules/load_balancer/README.md new file mode 100644 index 00000000000..0e6d52378a3 --- /dev/null +++ b/modules/load_balancer/README.md @@ -0,0 +1,858 @@ +--- +title: "Load Balancer Module" +description: "The Load-Balancer module comes to provide traffic routing based on load." +--- + +## Admin Guide + + +### Overview + + +The Load-Balancer module comes to provide traffic routing based on load. +Shortly, when OpenSIPS routes calls to a set of destinations, it is able +to keep the load status (as number of ongoing calls) of each destination +and to choose to route to the less loaded destination (at that moment). +OpenSIPS is aware of the capacity of each destination - it is preconfigured +with the maximum load accepted by the destinations. To be more precise, +when routing, OpenSIPS will consider the less loaded destination not the +destination with the smallest number of ongoing calls, but the destination +with the largest available slot. + + +Also the module has the capability to do failover (to try a new destination +if the selected one does not respond), to keep state of the destinations +(to remember the failed destination and avoid using them agai) and to +check the health of the destination (by doing probing of the destination +and auto re-enabling). + + +### How it works + + +Please refer to the Load-Balancer tutorial from the OpenSIPS website: +[https://docs.opensips.org/tutorials/loadbalancing/](https://docs.opensips.org/tutorials/loadbalancing/). + + +### Probing and Disabling destinations + + +The module has the capability to monitor the status of the destinations by +doing SIP probing (sending SIP requests like OPTIONS). + + +For each destination, you can configure what kind of probing should be +done (probe_mode column): + + +- *(0)* - no probing at all; +- *(1)* - probing only when the destination is +in disabled mode (disabling via MI command will competely stop the +probing also). The destination will be automatically re-enabled +when the probing will succeed next time; +- *(2)* - probing all the time. If disabled, +the destination will be automatically re-enabled when the probing +will succeed next time; + + +A destination can become disabled in two ways: + + +- script detection +- MI command + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *Dialog* - Dialog module +*freeswitch*. - only if +"fetch_freeswitch_stats" is enabled. +- *dialog* - TM module (only if probing is +enabled) +- *clusterer* - only if "cluster_id" +option is enabled. +- *database* - one of the DB modules + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +The URL pointing to the database where the load-balancing rules +are stored. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("load_balancer", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### db_table (string) + + +The name of the DB table containing the load-balancing rules. + + +*Default value is "load_balancer".* + + +```opensips title="Set db_table parameter" +... +modparam("load_balancer", "db_table", "lb") +... +``` + + +#### probing_interval (integer) + + +How often (in seconds) the probing of a destination should be done. If +set to 0, the probing will be disabled as functionality (for all +destinations) + + +*Default value is "30".* + + +```opensips title="Set probing_interval parameter" +... +modparam("load_balancer", "probing_interval", 60) +... +``` + + +#### probing_method (string) + + +The SIP method to be used for the probing requests. + + +*Default value is ""OPTIONS"".* + + +```opensips title="Set probing_method parameter" +... +modparam("load_balancer", "probing_method", "INFO") +... +``` + + +#### probing_from (string) + + +The FROM SIP URI to be advertised in the SIP probing requests. + + +*Default value is ""sip:prober@localhost"".* + + +```opensips title="Set probing_from parameter" +... +modparam("load_balancer", "probing_from", "sip:pinger@192.168.2.10") +... +``` + + +#### probing_reply_codes (string) + + +A comma separted list of SIP reply codes. The codes defined here +will be considered as valid reply codes for probing messages, +apart for 200. + + +*Default value is "NULL".* + + +```opensips title="Set probing_reply_codes parameter" +... +modparam("load_balancer", "probing_reply_codes", "501, 403") +... +``` + + +#### probing_verbose (number) + + +A boolean option to enable extra logging related to the +enabling or disabling of the destinations based on probing +replies and MI commands. + + +A 0 value means disabled, anything else means enabled. + + +The extra logging will be done on INFO level. + + +*Default value is "0" (disabled).* + + +```opensips title="Set probing_verbose parameter" +... +modparam("load_balancer", "probing_verbose", 1) +... +``` + + +#### lb_define_blacklist (string) + + +Defines a blacklist based on a lb group. This list will contain the IPs +(no port, all protocols) of the destinations matching the given group. + + +Multiple instances of this param are allowed. + + +*Default value is "NULL".* + + +```opensips title="Set the lb_define_blacklist parameter" +... +modparam("load_balancer", "lb_define_blacklist", "list= 1,4,3") +modparam("load_balancer", "lb_define_blacklist", "blist2= 2,10,6") +... +``` + + +#### fetch_freeswitch_stats (integer) + + +If enabled, the maximum value of a resource may also consist of +FreeSWITCH Event Socket Layer URLs, e.g. *"channels=fs://:password@freeswitch.example.com"* +or *"channels=fs://user:password@127.0.0.1:8021"*. The default ESL port is 8021. + + +OpenSIPS will establish a connection with the given socket and +periodically update the internal maximum value of the given resource +using statistics pushed by the FreeSWITCH box. + + +The max value of a resource is updated every *event_heartbeat_interval* +seconds (see the "freeswitch" OpenSIPS module for more details +regarding this setting), as the stats arrive from FreeSWITCH. + + +Given the following format for FreeSWITCH heartbeat messages: + + +```json +{ + ... + "FreeSWITCH-Hostname": "pbx2", + "FreeSWITCH-IPv4": "172.17.0.3", + "Idle-CPU": "78.400000", + "Max-Sessions": "1000", + "Session-Count": "0", + ... +} +``` + + +, the load balancer uses the following formula in order to periodically +update its "max_load" values for each FreeSWITCH box (FreeSWITCH data +is highlighted in bold): + + +*max_load = (**Idle-CPU** / 100) + * (**Max-Sessions** - +(**Session-Count** - +current_load))* + + +*Default value is "0" (disabled).* + + +```opensips title="Set the fetch_freeswitch_load parameter" +... +modparam("load_balancer", "fetch_freeswitch_stats", 1) +... +``` + + +#### initial_freeswitch_load (integer) + + +This parameter is only relevant for some seconds after module startup/reload, +when no statistics from newly loaded FreeSWITCH ESL sockets have arrived, yet the +routing of calls must remain unaffected. Any FreeSWITCH-enabled resource will +inherit this value for the entire interval mentioned above (up to 20 seconds!). + + +*Default value is "1000".* + + +```opensips title="Set the initial_freeswitch_load parameter" +... +modparam("load_balancer", "initial_freeswitch_load", 200) +... +``` + + +#### cluster_id (integer) + + +The ID of the cluster the module is part of. The clustering support is +used in load-balancer module for two purposes: for sharing the status +of the destinations and for controlling the pinging to destinations. + + +If clustering enbled, the module will automatically share changes +over the status of the destinations with the other +OpenSIPS instances that are part of a cluster. Whenever such a status +changes (following an MI command, a probing result, a script command), +the module will replicate this status change to all the nodes in this +given cluster. + + +The clustering with sharing tag support may be used to control which +node in the cluster will perform the pinging/probing to +destinations. See the +[cluster sharing tag](#param_cluster_sharing_tag) option. + + +This OpenSIPS cluster exposes the **"load_balancer-status-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +For more info on how to define and populate a cluster (with OpenSIPS +nodes) see the "clusterer" module. + + +*Default value is "0 (none)".* + + +```opensips title="Set cluster_id parameter" +... +# replicate destination status with all OpenSIPS in cluster ID 9 +modparam("load_balancer", "cluster_id", 9) +... +``` + + +#### cluster_sharing_tag (string) + + +The name of the sharing tag (as defined per clusterer modules) to +control which node is responsible for perform the self-triggered +actions in the module. Such actions may be the destination probing or +sharing the changes in the destination status. +If defined, only the node with active status of this tag will +perform the actions (pinging and sharing status). + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +This is an optional parameter. If not set, all the nodes in the cluster +will individually do the probing and share the status changes. + + +*Default value is "empty (none)".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +# and broadcast the status changes +modparam("load_balancer", "cluster_id", 9) +modparam("load_balancer", "cluster_sharing_tag", "vip") +... +``` + + +### Exported Functions + + +#### lb_start(grp,resources[,flags],[attrs]) + + +The function starts a new load-balancing session over the available +destinations. This translates into finding the less loaded destination +that can provide the requested resources and belong to a requested +group. + + +Meaning of the parameters is as follows: + + +- *grp* (int) - group id for the destinations; +the destination may be grouped in several groups you can you for +differnet scenarios. +- *resources* (string) - a +semi-colon separated list of resources required by the current +call. +- *flags* (string, optional) - various flags +to controll the LB algorithm ( or computing the available load on +the system): + + - *n* - Negative availability - use +destinations with negative availability (exceeded capacity); +do not ignore resources with negative availability, and thus +able to select for load balancing destinations with exceeded +capacity. This might be needed in scenarios where we want to +limit generic calls volume and always pass +important/high-priority calls. + - *r* - Relative value - the relative +available load (how many percentages are free) is used in +computing the load of each pear/resource; Without this flag, +the Absolute value is assumed - the effective +available load ( maximum_load - current_load) is used in +computing the load of each pear/resource. + - *s* - Pick a random destination if +multiple destinations with the same load are found, instead +of always picking first matched destination. +This could help to offload an excessive load from the first +destination and distribute load in situations when failed +calls always routed to first destination, since they almost +does not affect load counters of destinations. +- *attrs* (var, optional) - a writable variable +to be populated with the attributes of the selected destination. + + +The function may return: + + +- *1 (true)* - if a new destination URI is +set, pointing to the selected destination. NOTE that the RURI will +not be changed by this function. +- *-1 (false)* - generic internal error +(memory allocation, parsing) +- *-2 (false)* - no capacity available +(detinations are up and available, but they do not have any +availabe channels) +- *-3 (false)* - no destinations available +(the requested resources did not match any active destination) +- *-4 (false)* - bad resources +(requested resources do not exist) + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="lb_start usage" +... +if (lb_start(1,"trascoding;conference")) { + # dst URI points to the new destination + xlog("sending call to $du\n"); + t_relay(); + exit; +} +... +``` + + +#### lb_next([attrs]) + + +Function to be used to pull the next available (and less loaded) +destination. You need to have an ongoing LB session (started with +lb_start()). + + +This function is mainly used for implementing failover for the LB +destinations. + + +Meaning of the parameters is as follows: + + +- *attrs* (var, optional) - a writable variable +to be populated with the attributes of the selected destination. + + +The function may return: + + +- *1 (true)* - if a new destination URI is +set, pointing to the selected destination. NOTE that the RURI will +not be changed by this function. +- *-1 (false)* - generic internal error +(memory allocation, parsing) +- *-2 (false)* - no capacity available +(detinations are up and available, but they do not have any +availabe channels) +- *-3 (false)* - no more destinations +available (the requested resources did not match any active +destination) + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="lb_next() usage" +... +if (t_check_status("(408)|(5[0-9][0-9])")) { + /* check next available LB destination */ + if ( lb_next() ) { + t_on_failure("1"); + xlog("-----------new dst is $du\n"); + t_relay(); + exit; + } +} + +... +``` + + +#### lb_start_or_next(grp,resources[,flags],[attrs]) + + +This is just a wrapper function to simplify scripting. If there is no +ongoing LB session, it acts as lb_start(); If there is an ongoing LB +session, it acts as lb_next(). + + +#### load_balance(grp,resources[,flags],[attrs]) + + +Old name of the lb_start_or_next() function. + + +Take care, this will become obsolete. + + +#### lb_reset() + + +Function to stop and flush a current LB session. To be used in +failure route, if you want to stop the current LB session (not to try +any other destinations from this session) and to start a completly new +one. + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="lb_next() usage" +... +if (t_check_status("(5[0-9][0-9])")) { + /* check next available LB destination */ + if ( lb_next() ) { + t_on_failure("1"); + xlog("-----------new dst is $du\n"); + t_relay(); + exit; + } +} else if (t_check_status("(408)")) { + lb_reset(); + if (lb_start(1,"conference")) { + t_relay(); + exit; + } +} +... +``` + + +#### lb_is_started() + + +Function to check if there is any ongoing LB session. Returns true if +so. + + +This function can be used in any type of route. + + +#### lb_disable_dst() + + +Marks as disabled the last destination that was used for the current +call. The disabling done via this function will prevent the +destination to be used for usage from now on. The probing mechanism +can re-enable this peer (see the probing section in the beginning) + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="lb_disable_dst() usage" +... +if (t_check_status("(408)|(5[0-9][0-9])")) { + lb_disable_dst(); + if ( lb_next() ) { + t_on_failure("1"); + xlog("-----------new dst is $du\n"); + t_relay(); + } else { + t_reply(500,"Error"); + } +} + +... +``` + + +#### lb_is_destination(ip,port,[group],[active],[attrs]]) + + +Checks if the given IP and PORT belongs to a destination configured in +the load-balancer's list. Returns true if found and active (see the +"active" parameter). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +Meaning of the parameters is as follows: + + +- *ip* (string) - IP to be checked +- *port* (int) - PORT to be checked. +A value 0 means "any" - will match any port. +- *group* (int, optional) - in what LB group +the destination should be looked for; If not specified, the search +will be in all groups. +- *active* (int, optional)- if "1", the search will be +performed only over "active" (not disabled) destinations. If +missing, the search will consider any kind of destinations. +- *attrs* (var, optional) - a writable variable +to be populated with the attributes of the identified destination. + + +```opensips title="lb_is_destination usage" +... +if (lb_is_destination($si,$sp) ) { + # request from a LB destination +} +... +``` + + +#### lb_count_call(ip,port,grp,resources[,undo]) + + +The function counts the current call as load for a given destination +with some given resources. Note that this call is not going through +the load-balancing logic (there are not routing decision taken for the +call); it is simply counted by LB as ongoing call for a destination; + + +Meaning of the parameters is as follows: + + +- *ip* (string) - IP to identify the destination +the call has to be counted for. +- *port* (int) - PORT to identify the destination +the call has to be counted for. +- *grp* (int) - group id for the destinations; if +no knows, "-1" will mean all groups. +- *resources* - (string) a semi-colon separated +list of resources required by the current call. +- *undo* - (int, optional) if set to a non zero +value, it will force the function to un-count - +actually it will undo the counting of this call as load in the +current LB session; this might be needed if we count call for +particular resources and then need to un-count it. + + +Function returns true if the call was properly taken into consideration +for estimating the load on the destination. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="lb_count_call usage" +... +# count as load also the calls orgininated by lb destinations +if (lb_is_destination($si,$sp) ) { + # inbound call from destination + lb_count_call($si,$sp,-1,"conference"); +} else { + # outbound call to destinations + if ( !load_balance(1,"conference") ) { + send_reply(503,"unavailable"); + exit(); + } + # dst URI points to the new destination + xlog("sending call to $du\n"); + t_relay(); + exit; +} +... +``` + + +### Exported MI Functions + + +#### lb_reload + + +Trigers the reload of the load balancing data from the DB. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi lb_reload +``` + + +#### lb_resize + + +Changes the capacity for a resource of a destination. + + +Parameters: + + +- *destination_id* - the ID (as per DB) of the destination. +- *res_name* - name of the resource you want to resize. +- *new_capacity* - new resource capacity. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi lb_resize 11 voicemail 56 +``` + + +#### lb_list + + +Lists all the destinations and the maximum and current load for each +resource of the destination. + + +```bash title="lb_list usage" +$ opensips-cli -x mi lb_list +Destination:: sip:127.0.0.1:5100 id=1 enabled=yes auto-re=on + Resource:: pstn max=3 load=0 + Resource:: transc max=5 load=1 + Resource:: vm max=5 load=2 +Destination:: sip:127.0.0.1:5200 id=2 enabled=no auto-re=on + Resource:: pstn max=6 load=0 + Resource:: trans max=57 load=0 + Resource:: vm max=5 load=0 +``` + + +#### lb_status + + +Gets or sets the status (enabled or disabled) of a destination. + + +Parameters: + + +- *destination_id* - the ID (as per DB) of the destination. +- *new_status* (optional) - If no new status is given, the +function will return the current status. If a new status is given +(0 - disable, 1 - enable), this status will be forced for the +destination. + + +```bash title="lb_status usage" +$ opensips-cli -x mi lb_status 2 +enable:: no +$ opensips-cli -x mi lb_status 2 1 +$ opensips-cli -x mi lb_status 2 +enable:: yes +``` + + +### Exported Events + + +#### E_LOAD_BALANCER_STATUS + + +This event is raised when the module changes the state of a destination, +either through MI or probing. + + +Parameters: + + +- *group* - the group of the destination. +- *uri* - the URI of the destination. +- *status* - *disabled* if +the destination was disabled or *enabled* if +the destination is being used. + + +## Developer Guide + + +### Available Functions + + +NONE + + +## Frequently Asked Questions + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/load_balancer/doc/contributors.xml b/modules/load_balancer/doc/contributors.xml deleted file mode 100644 index cf2d6dc36de..00000000000 --- a/modules/load_balancer/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 124 - 74 - 4331 - 755 - - - 2. - Liviu Chircu (@liviuchircu) - 43 - 34 - 688 - 172 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 38 - 19 - 623 - 766 - - - 4. - Sergey Khripchenko (@shripchenko) - 28 - 10 - 1058 - 516 - - - 5. - Razvan Crainea (@razvancrainea) - 27 - 21 - 266 - 148 - - - 6. - Vlad Paiu (@vladpaiu) - 5 - 3 - 7 - 5 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 6 - 7 - - - 8. - Walter Doekes (@wdoekes) - 5 - 3 - 3 - 3 - - - 9. - Jeremy Martinez (@JeremyMartinez51) - 5 - 2 - 193 - 1 - - - 10. - Ezequiel Lovelle (@lovelle) - 4 - 2 - 3 - 3 - - - -
-All remaining contributors: Anca Vamanu, Andrei Dragus, James Van Vleet, Dusan Klinec (@ph4r05), Peter Lemenkov (@lemenkov), Zero King (@l2dy), agree. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Oct 2010 - Oct 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Sep 2012 - Sep 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2009 - Oct 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - Mar 2017 - Jul 2022 - - - 6. - agree - Jan 2022 - Jan 2022 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Jeremy Martinez (@JeremyMartinez51) - Feb 2017 - Feb 2017 - - - 10. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - -
-All remaining contributors: Sergey Khripchenko (@shripchenko), Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu), Andrei Dragus, James Van Vleet, Anca Vamanu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), agree, Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Sergey Khripchenko (@shripchenko), Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/load_balancer/doc/load_balancer.xml b/modules/load_balancer/doc/load_balancer.xml deleted file mode 100644 index 11f522d3547..00000000000 --- a/modules/load_balancer/doc/load_balancer.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - Load Balancer Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - diff --git a/modules/load_balancer/doc/load_balancer_admin.xml b/modules/load_balancer/doc/load_balancer_admin.xml deleted file mode 100644 index 4a464b3b326..00000000000 --- a/modules/load_balancer/doc/load_balancer_admin.xml +++ /dev/null @@ -1,1034 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Load-Balancer module comes to provide traffic routing based on load. - Shortly, when &osips; routes calls to a set of destinations, it is able - to keep the load status (as number of ongoing calls) of each destination - and to choose to route to the less loaded destination (at that moment). - &osips; is aware of the capacity of each destination - it is preconfigured - with the maximum load accepted by the destinations. To be more precise, - when routing, &osips; will consider the less loaded destination not the - destination with the smallest number of ongoing calls, but the destination - with the largest available slot. - - - Also the module has the capability to do failover (to try a new destination - if the selected one does not respond), to keep state of the destinations - (to remember the failed destination and avoid using them agai) and to - check the health of the destination (by doing probing of the destination - and auto re-enabling). - -
- -
- How it works - - Please refer to the Load-Balancer tutorial from the &osips; website: - https://opensips.org/Documentation/Tutorials-LoadBalancing-1-9. - -
- -
- Probing and Disabling destinations - - The module has the capability to monitor the status of the destinations by - doing SIP probing (sending SIP requests like OPTIONS). - - - For each destination, you can configure what kind of probing should be - done (probe_mode column): - - - - (0) - no probing at all; - - - (1) - probing only when the destination is - in disabled mode (disabling via MI command will competely stop the - probing also). The destination will be automatically re-enabled - when the probing will succeed next time; - - - (2) - probing all the time. If disabled, - the destination will be automatically re-enabled when the probing - will succeed next time; - - - - - A destination can become disabled in two ways: - - - script detection - by calling from script the - lb_disabled() function after try the destination. In this case, if - probing mode for the destination is (1) or (2), the destination will - be automatically re-enabled when the probing will succeed. - - - MI command - by calling the lb_status MI - command for disabling (on demand) the destination. If so, the probing - and re-enabling of this destination will be completly disabled until - you re-enable it again via MI command - this is designed to allow - controlled and complete disabling of some destination during - maintenance. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - Dialog - Dialog module - - - freeswitch. - only if - "fetch_freeswitch_stats" is enabled. - - - - - dialog - TM module (only if probing is - enabled) - - - - - clusterer - only if "cluster_id" - option is enabled. - - - - - database - one of the DB modules - - - - -
- - -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - The URL pointing to the database where the load-balancing rules - are stored. - - - - Default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("load_balancer", "db_url", "&exampledb;") -... - - -
- -
- <varname>db_table</varname> (string) - - The name of the DB table containing the load-balancing rules. - - - - Default value is load_balancer. - - - - Set <varname>db_table</varname> parameter - -... -modparam("load_balancer", "db_table", "lb") -... - - -
- -
- <varname>probing_interval</varname> (integer) - - How often (in seconds) the probing of a destination should be done. If - set to 0, the probing will be disabled as functionality (for all - destinations) - - - - Default value is 30. - - - - Set <varname>probing_interval</varname> parameter - -... -modparam("load_balancer", "probing_interval", 60) -... - - -
- -
- <varname>probing_method</varname> (string) - - The SIP method to be used for the probing requests. - - - - Default value is "OPTIONS". - - - - Set <varname>probing_method</varname> parameter - -... -modparam("load_balancer", "probing_method", "INFO") -... - - -
- -
- <varname>probing_from</varname> (string) - - The FROM SIP URI to be advertised in the SIP probing requests. - - - - Default value is "sip:prober@localhost". - - - - Set <varname>probing_from</varname> parameter - -... -modparam("load_balancer", "probing_from", "sip:pinger@192.168.2.10") -... - - -
- -
- <varname>probing_reply_codes</varname> (string) - - A comma separted list of SIP reply codes. The codes defined here - will be considered as valid reply codes for probing messages, - apart for 200. - - - - Default value is NULL. - - - - Set <varname>probing_reply_codes</varname> parameter - -... -modparam("load_balancer", "probing_reply_codes", "501, 403") -... - - -
- -
- <varname>probing_verbose</varname> (number) - - A boolean option to enable extra logging related to the - enabling or disabling of the destinations based on probing - replies and MI commands. - - - A 0 value means disabled, anything else means enabled. - - - The extra logging will be done on INFO level. - - - - Default value is 0 (disabled). - - - - Set <varname>probing_verbose</varname> parameter - -... -modparam("load_balancer", "probing_verbose", 1) -... - - -
- - -
- <varname>lb_define_blacklist</varname> (string) - - Defines a blacklist based on a lb group. This list will contain the IPs - (no port, all protocols) of the destinations matching the given group. - - - Multiple instances of this param are allowed. - - - - Default value is NULL. - - - - Set the <varname>lb_define_blacklist</varname> parameter - -... -modparam("load_balancer", "lb_define_blacklist", "list= 1,4,3") -modparam("load_balancer", "lb_define_blacklist", "blist2= 2,10,6") -... - - -
- -
- <varname>fetch_freeswitch_stats</varname> (integer) - - If enabled, the maximum value of a resource may also consist of - FreeSWITCH Event Socket Layer URLs, e.g. "channels=fs://:password@freeswitch.example.com" - or "channels=fs://user:password@127.0.0.1:8021". The default ESL port is 8021. - - - OpenSIPS will establish a connection with the given socket and - periodically update the internal maximum value of the given resource - using statistics pushed by the FreeSWITCH box. - - - The max value of a resource is updated every event_heartbeat_interval - seconds (see the "freeswitch" OpenSIPS module for more details - regarding this setting), as the stats arrive from FreeSWITCH. - - - Given the following format for FreeSWITCH heartbeat messages: - -{ - ... - "FreeSWITCH-Hostname": "pbx2", - "FreeSWITCH-IPv4": "172.17.0.3", - "Idle-CPU": "78.400000", - "Max-Sessions": "1000", - "Session-Count": "0", - ... -} - - , the load balancer uses the following formula in order to periodically - update its "max_load" values for each FreeSWITCH box (FreeSWITCH data - is highlighted in bold): - - - max_load = (Idle-CPU / 100) - * (Max-Sessions - - (Session-Count - - current_load)) - - - - Default value is 0 (disabled). - - - - Set the <varname>fetch_freeswitch_load</varname> parameter - -... -modparam("load_balancer", "fetch_freeswitch_stats", 1) -... - - -
- -
- <varname>initial_freeswitch_load</varname> (integer) - - This parameter is only relevant for some seconds after module startup/reload, - when no statistics from newly loaded FreeSWITCH ESL sockets have arrived, yet the - routing of calls must remain unaffected. Any FreeSWITCH-enabled resource will - inherit this value for the entire interval mentioned above (up to 20 seconds!). - - - - Default value is 1000. - - - - Set the <varname>initial_freeswitch_load</varname> parameter - -... -modparam("load_balancer", "initial_freeswitch_load", 200) -... - - -
- -
- <varname>cluster_id</varname> (integer) - - The ID of the cluster the module is part of. The clustering support is - used in load-balancer module for two purposes: for sharing the status - of the destinations and for controlling the pinging to destinations. - - - If clustering enbled, the module will automatically share changes - over the status of the destinations with the other - OpenSIPS instances that are part of a cluster. Whenever such a status - changes (following an MI command, a probing result, a script command), - the module will replicate this status change to all the nodes in this - given cluster. - - - The clustering with sharing tag support may be used to control which - node in the cluster will perform the pinging/probing to - destinations. See the - option. - - - &clusterer_sync_cap_para; - - - For more info on how to define and populate a cluster (with OpenSIPS - nodes) see the "clusterer" module. - - - - Default value is 0 (none). - - - - Set <varname>cluster_id</varname> parameter - -... -# replicate destination status with all OpenSIPS in cluster ID 9 -modparam("load_balancer", "cluster_id", 9) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (string) - - The name of the sharing tag (as defined per clusterer modules) to - control which node is responsible for perform the self-triggered - actions in the module. Such actions may be the destination probing or - sharing the changes in the destination status. - If defined, only the node with active status of this tag will - perform the actions (pinging and sharing status). - - - The must be defined for this option - to work. - - - This is an optional parameter. If not set, all the nodes in the cluster - will individually do the probing and share the status changes. - - - - Default value is empty (none). - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -# and broadcast the status changes -modparam("load_balancer", "cluster_id", 9) -modparam("load_balancer", "cluster_sharing_tag", "vip") -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">lb_start(grp,resources[,flags],[attrs])</function> - - - The function starts a new load-balancing session over the available - destinations. This translates into finding the less loaded destination - that can provide the requested resources and belong to a requested - group. - - Meaning of the parameters is as follows: - - - grp (int) - group id for the destinations; - the destination may be grouped in several groups you can you for - differnet scenarios. - - - - resources (string) - a - semi-colon separated list of resources required by the current - call. - - - - flags (string, optional) - various flags - to controll the LB algorithm ( or computing the available load on - the system): - - - - n - Negative availability - use - destinations with negative availability (exceeded capacity); - do not ignore resources with negative availability, and thus - able to select for load balancing destinations with exceeded - capacity. This might be needed in scenarios where we want to - limit generic calls volume and always pass - important/high-priority calls. - - - - r - Relative value - the relative - available load (how many percentages are free) is used in - computing the load of each pear/resource; Without this flag, - the Absolute value is assumed - the effective - available load ( maximum_load - current_load) is used in - computing the load of each pear/resource. - - - - s - Pick a random destination if - multiple destinations with the same load are found, instead - of always picking first matched destination. - This could help to offload an excessive load from the first - destination and distribute load in situations when failed - calls always routed to first destination, since they almost - does not affect load counters of destinations. - - - - - - attrs (var, optional) - a writable variable - to be populated with the attributes of the selected destination. - - - - - The function may return: - - - - 1 (true) - if a new destination URI is - set, pointing to the selected destination. NOTE that the RURI will - not be changed by this function. - - - -1 (false) - generic internal error - (memory allocation, parsing) - - - -2 (false) - no capacity available - (detinations are up and available, but they do not have any - availabe channels) - - - -3 (false) - no destinations available - (the requested resources did not match any active destination) - - - - -4 (false) - bad resources - (requested resources do not exist) - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>lb_start</function> usage - -... -if (lb_start(1,"trascoding;conference")) { - # dst URI points to the new destination - xlog("sending call to $du\n"); - t_relay(); - exit; -} -... - - -
- -
- - <function moreinfo="none">lb_next([attrs])</function> - - - Function to be used to pull the next available (and less loaded) - destination. You need to have an ongoing LB session (started with - lb_start()). - - - This function is mainly used for implementing failover for the LB - destinations. - - Meaning of the parameters is as follows: - - - attrs (var, optional) - a writable variable - to be populated with the attributes of the selected destination. - - - - - The function may return: - - - - 1 (true) - if a new destination URI is - set, pointing to the selected destination. NOTE that the RURI will - not be changed by this function. - - - -1 (false) - generic internal error - (memory allocation, parsing) - - - -2 (false) - no capacity available - (detinations are up and available, but they do not have any - availabe channels) - - - -3 (false) - no more destinations - available (the requested resources did not match any active - destination) - - - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>lb_next()</function> usage - -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - /* check next available LB destination */ - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - exit; - } -} - -... - - -
- - -
- - <function moreinfo="none">lb_start_or_next(grp,resources[,flags],[attrs])</function> - - - This is just a wrapper function to simplify scripting. If there is no - ongoing LB session, it acts as lb_start(); If there is an ongoing LB - session, it acts as lb_next(). - -
- - -
- - <function moreinfo="none">load_balance(grp,resources[,flags],[attrs])</function> - - - Old name of the lb_start_or_next() function. - - - Take care, this will become obsolete. - -
- - -
- - <function moreinfo="none">lb_reset()</function> - - - Function to stop and flush a current LB session. To be used in - failure route, if you want to stop the current LB session (not to try - any other destinations from this session) and to start a completly new - one. - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>lb_next()</function> usage - -... -if (t_check_status("(5[0-9][0-9])")) { - /* check next available LB destination */ - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - exit; - } -} else if (t_check_status("(408)")) { - lb_reset(); - if (lb_start(1,"conference")) { - t_relay(); - exit; - } -} -... - - -
- -
- - <function moreinfo="none">lb_is_started()</function> - - - Function to check if there is any ongoing LB session. Returns true if - so. - - - This function can be used in any type of route. - -
- - -
- - <function moreinfo="none">lb_disable_dst()</function> - - - Marks as disabled the last destination that was used for the current - call. The disabling done via this function will prevent the - destination to be used for usage from now on. The probing mechanism - can re-enable this peer (see the probing section in the beginning) - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>lb_disable_dst()</function> usage - -... -if (t_check_status("(408)|(5[0-9][0-9])")) { - lb_disable_dst(); - if ( lb_next() ) { - t_on_failure("1"); - xlog("-----------new dst is $du\n"); - t_relay(); - } else { - t_reply(500,"Error"); - } -} - -... - - -
- - -
- - <function moreinfo="none">lb_is_destination(ip,port,[group],[active],[attrs]])</function> - - - Checks if the given IP and PORT belongs to a destination configured in - the load-balancer's list. Returns true if found and active (see the - "active" parameter). - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Meaning of the parameters is as follows: - - - ip (string) - IP to be checked - - - - port (int) - PORT to be checked. - A value 0 means "any" - will match any port. - - - - group (int, optional) - in what LB group - the destination should be looked for; If not specified, the search - will be in all groups. - - - - active (int, optional)- if "1", the search will be - performed only over "active" (not disabled) destinations. If - missing, the search will consider any kind of destinations. - - - - attrs (var, optional) - a writable variable - to be populated with the attributes of the identified destination. - - - - - - - <function>lb_is_destination</function> usage - -... -if (lb_is_destination($si,$sp) ) { - # request from a LB destination -} -... - - -
- -
- - <function moreinfo="none">lb_count_call(ip,port,grp,resources[,undo])</function> - - - The function counts the current call as load for a given destination - with some given resources. Note that this call is not going through - the load-balancing logic (there are not routing decision taken for the - call); it is simply counted by LB as ongoing call for a destination; - - Meaning of the parameters is as follows: - - - ip (string) - IP to identify the destination - the call has to be counted for. - - - - port (int) - PORT to identify the destination - the call has to be counted for. - - - - grp (int) - group id for the destinations; if - no knows, "-1" will mean all groups. - - - - resources - (string) a semi-colon separated - list of resources required by the current call. - - - - undo - (int, optional) if set to a non zero - value, it will force the function to un-count - - actually it will undo the counting of this call as load in the - current LB session; this might be needed if we count call for - particular resources and then need to un-count it. - - - - - Function returns true if the call was properly taken into consideration - for estimating the load on the destination. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>lb_count_call</function> usage - -... -# count as load also the calls orgininated by lb destinations -if (lb_is_destination($si,$sp) ) { - # inbound call from destination - lb_count_call($si,$sp,-1,"conference"); -} else { - # outbound call to destinations - if ( !load_balance(1,"conference") ) { - send_reply(503,"unavailable"); - exit(); - } - # dst URI points to the new destination - xlog("sending call to $du\n"); - t_relay(); - exit; -} -... - - -
- - -
- -
- Exported MI Functions - -
- <function moreinfo="none">lb_reload</function> - - Trigers the reload of the load balancing data from the DB. - - - MI FIFO Command Format: - - - opensips-cli -x mi lb_reload - -
- -
- <function moreinfo="none">lb_resize</function> - - Changes the capacity for a resource of a destination. - - Parameters: - - - destination_id - the ID (as per DB) of the destination. - - - res_name - name of the resource you want to resize. - - - new_capacity - new resource capacity. - - - - MI FIFO Command Format: - - - opensips-cli -x mi lb_resize 11 voicemail 56 - -
- -
- <function moreinfo="none">lb_list</function> - - Lists all the destinations and the maximum and current load for each - resource of the destination. - - - <function>lb_list</function> usage - -$ opensips-cli -x mi lb_list -Destination:: sip:127.0.0.1:5100 id=1 enabled=yes auto-re=on - Resource:: pstn max=3 load=0 - Resource:: transc max=5 load=1 - Resource:: vm max=5 load=2 -Destination:: sip:127.0.0.1:5200 id=2 enabled=no auto-re=on - Resource:: pstn max=6 load=0 - Resource:: trans max=57 load=0 - Resource:: vm max=5 load=0 - - -
- -
- <function moreinfo="none">lb_status</function> - - Gets or sets the status (enabled or disabled) of a destination. - - Parameters: - - - destination_id - the ID (as per DB) of the destination. - - - new_status (optional) - If no new status is given, the - function will return the current status. If a new status is given - (0 - disable, 1 - enable), this status will be forced for the - destination. - - - - <function>lb_status</function> usage - -$ opensips-cli -x mi lb_status 2 -enable:: no -$ opensips-cli -x mi lb_status 2 1 -$ opensips-cli -x mi lb_status 2 -enable:: yes - - -
-
- - -
- Exported Events -
- - <function moreinfo="none">E_LOAD_BALANCER_STATUS</function> - - - This event is raised when the module changes the state of a destination, - either through MI or probing. - - Parameters: - - - group - the group of the destination. - - - uri - the URI of the destination. - - - status - disabled if - the destination was disabled or enabled if - the destination is being used. - - -
-
- - -
- diff --git a/modules/load_balancer/doc/load_balancer_devel.xml b/modules/load_balancer/doc/load_balancer_devel.xml deleted file mode 100644 index b96223d7dd6..00000000000 --- a/modules/load_balancer/doc/load_balancer_devel.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - &develguide; -
- Available Functions - - NONE - -
- -
- diff --git a/modules/load_balancer/doc/load_balancer_faq.xml b/modules/load_balancer/doc/load_balancer_faq.xml deleted file mode 100644 index 4b1c4df9306..00000000000 --- a/modules/load_balancer/doc/load_balancer_faq.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - &faqguide; - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/lua/README b/modules/lua/README deleted file mode 100644 index cd96a3353f7..00000000000 --- a/modules/lua/README +++ /dev/null @@ -1,417 +0,0 @@ -lua Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Installing the module - 1.3. Using the module - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. luafilename (string) - 1.5.2. lua_auto_reload (int) - 1.5.3. warn_missing_free_fixup (int) - 1.5.4. lua_allocator (string) - - 1.6. Exported Functions - - 1.6.1. lua_exec(func, [param]) - 1.6.2. lua_meminfo() - - 1.7. Exported MI Functions - - 1.7.1. watch - - 2. OpenSIPS Lua API - - 2.1. Available functions - - 2.1.1. xdbg(message) - 2.1.2. xlog([level],message) - 2.1.3. WarnMissingFreeFixup - 2.1.4. getpid - 2.1.5. getmem - 2.1.6. getmeminfo - 2.1.7. gethostname - 2.1.8. getType(msg) - 2.1.9. isMyself(host, port) - 2.1.10. grepSockInfo(host, port) - 2.1.11. getURI_User(msg) - 2.1.12. getExpires(msg) - 2.1.13. getHeader(msg, header) - 2.1.14. getContact(msg) - 2.1.15. getRoute(msg) - 2.1.16. moduleFunc(msg, function, args1, args2, ...) - 2.1.17. getStatus(msg) - 2.1.18. getMethod(msg) - 2.1.19. getSrcIp(msg) - 2.1.20. getDstIp(msg) - 2.1.21. AVP_get(name) - 2.1.22. AVP_set(name, value) - 2.1.23. AVP_destroy(name) - 2.1.24. pseudoVar(msg, variable) - 2.1.25. pseudoVarSet(msg, variable, value) - 2.1.26. scriptVarGet(variable) - 2.1.27. scriptVarSet(variable, value) - 2.1.28. add_lump_rpl(msg, header) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set luafilename parameter - 1.2. lua_exec() usage - -Chapter 1. Admin Guide - -1.1. Overview - - The time needed when writing a new OpenSIPS module - unfortunately is quite high, while the options provided by the - configuration file are limited to the features implemented in - the modules. - - With this Lua module, you can easily implement your own - OpenSIPS extensions in Lua. - -1.2. Installing the module - - This Lua module is loaded in opensips.cfg (just like all the - other modules) with loadmodule("/path/to/lua.so");. - - For the Lua module to compile, you need a recent version of Lua - (tested with 5.1) linked dynamically. The default version of - your favorite Linux distribution should work fine. - -1.3. Using the module - - With the Lua module, you can access to lua function on the - OpenSIPS side. You need to define a file to load and call a - function from it. Write a function "mongo_alias" and then write - in your opensips.cfg -... -if (lua_exec("mongo_alias")) { - ... -} -... - - On the Lua side, you have access to opensips functions and - variables (AVP, pseudoVar, ...). Read the documentation below - for further informations. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - None ;-) - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * Lua 5.1.x or later - * memcached - - This module has been developed and tested with Lua 5.1.?, but - should work with any 5.1.x release. Earlier versions do not - work. - - On current Debian systems, at least the following packages - should be installed: - * lua5.1 - * liblua5.1-0-dev - * libmemcached-dev - * libmysqlclient-dev - - It was reported that other Debian-style distributions (such as - Ubuntu) need the same packages. - - On OpenBSD systems, at least the following packages should be - installed: - * Lua - -1.5. Exported Parameters - -1.5.1. luafilename (string) - - This is the file name of your script. This may be set once - only, but it may include an arbitary number of functions and - "use" as many Lua module as necessary. - - The default value is "/etc/opensips/opensips.lua" - - Example 1.1. Set luafilename parameter -... -modparam("lua", "luafilename", "/etc/opensips/opensips.lua") -... - -1.5.2. lua_auto_reload (int) - - Define this value to 1 if you want to reload automatically the - lua script. Disabled by default. - -1.5.3. warn_missing_free_fixup (int) - - When you call a function via moduleFunc() you could have a - memleak. Enable this warns you when you're doing it. Enabled by - default. - -1.5.4. lua_allocator (string) - - Change the default memory allocator for the lua module. - Possible values are : - * opensips (default) - * malloc - -1.6. Exported Functions - -1.6.1. lua_exec(func, [param]) - - Calls a Lua function with passing it the current SIP message. - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE and BRANCH_ROUTE. - - Parameters: - * func (string) - Lua function name - * param (string, optional) - Parameter to be passed to the - Lua function. - - Example 1.2. lua_exec() usage -... -if (lua_exec("mongo_alias")) { - ... -} -... - -1.6.2. lua_meminfo() - - Logs informations about memory. - -1.7. Exported MI Functions - -1.7.1. watch - - Name: watch - - Parameters: none - * action (optional) - 'add' or 'delete' - * extension (optional) - required if action is provided - - MI FIFO Command Format: - opensips-cli -x mi watch - -Chapter 2. OpenSIPS Lua API - -2.1. Available functions - - This module provides access to a limited number of OpenSIPS - core functions. - -2.1.1. xdbg(message) - - An alias for xlog(DBG, message) - -2.1.2. xlog([level],message) - - Logs the message with OpenSIPS's logging facility. The logging - level is one of the following: - * ALERT - * CRIT - * ERR - * WARN - * NOTICE - * INFO - * DBG - -2.1.3. WarnMissingFreeFixup - - Dynamically change the variable warn_missing_free_fixup. - -2.1.4. getpid - - Returns the current pid. - -2.1.5. getmem - - Returns a table with the size of allocated memory and the - fragmentation. - -2.1.6. getmeminfo - - Returns a table with memory infos. - -2.1.7. gethostname - - Returns the value of the current hostname. - -2.1.8. getType(msg) - - Returns "SIP_REQUEST" or "SIP_REPLY". - -2.1.9. isMyself(host, port) - - Test if the host and optionally the port represent one of the - addresses that OpenSIPS listens on. - -2.1.10. grepSockInfo(host, port) - - Similar to isMyself(), but without taking a look into the - aliases. - -2.1.11. getURI_User(msg) - - Returns the user of the To URI. - -2.1.12. getExpires(msg) - - Returns the expires header of the current message. - -2.1.13. getHeader(msg, header) - - Returns the value of the specified header. - -2.1.14. getContact(msg) - - Returns a table with the contact header. - -2.1.15. getRoute(msg) - - Returns a table with the Route header. - -2.1.16. moduleFunc(msg, function, args1, args2, ...) - - You can pass arguments to this function. - -2.1.17. getStatus(msg) - - Returns the current status if the SIP message is a SIP_REPLY. - -2.1.18. getMethod(msg) - - Returns the current method. - -2.1.19. getSrcIp(msg) - - Returns the IP address of the source. - -2.1.20. getDstIp(msg) - - Returns the IP address of the destination. - -2.1.21. AVP_get(name) - - Returns an AVP variable. - -2.1.22. AVP_set(name, value) - - Defines an AVP variable. - -2.1.23. AVP_destroy(name) - - Destroys an AVP variable. - -2.1.24. pseudoVar(msg, variable) - - Returns a pseudoVar. - -2.1.25. pseudoVarSet(msg, variable, value) - - Sets the value of a pseudoVar. - -2.1.26. scriptVarGet(variable) - - Returns a script variable. - -2.1.27. scriptVarSet(variable, value) - - Sets the value of a script variable. - -2.1.28. add_lump_rpl(msg, header) - - Add header to the reply. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Arnaud Chong + Eric Gouyer 38 1 4335 0 - 2. Razvan Crainea (@razvancrainea) 34 27 274 230 - 3. Vlad Patrascu (@rvlad-patrascu) 25 17 319 276 - 4. Liviu Chircu (@liviuchircu) 13 10 15 63 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 9 3 - 6. Maksym Sobolyev (@sobomax) 7 5 16 13 - 7. Vlad Paiu (@vladpaiu) 5 3 7 9 - 8. Ken Rice 3 1 4 4 - 9. Julián Moreno Patiño 3 1 1 1 - 10. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jun 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Feb 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) May 2014 - Jan 2020 - 6. Liviu Chircu (@liviuchircu) Mar 2014 - Mar 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Vlad Paiu (@vladpaiu) Feb 2012 - Jun 2012 - 10. Arnaud Chong + Eric Gouyer Dec 2011 - Dec 2011 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Vlad Paiu (@vladpaiu), Arnaud Chong + Eric - Gouyer. - - Documentation Copyrights: - - Copyright © 2006-2011 Arnaud Chong, Eric Gouyer diff --git a/modules/lua/README.md b/modules/lua/README.md new file mode 100644 index 00000000000..89e7265317d --- /dev/null +++ b/modules/lua/README.md @@ -0,0 +1,399 @@ +--- +title: "lua Module" +description: "The time needed when writing a new OpenSIPS module unfortunately is quite high, while the options provided by the configuration file are limited to the features implemented in the modules." +--- + +## Admin Guide + + +### Overview + + +The time needed when writing a new OpenSIPS module +unfortunately is quite high, while the options provided by the +configuration file are limited to the features implemented in +the modules. + + +With this Lua module, you can easily implement your own +OpenSIPS extensions in Lua. + + +### Installing the module + + +This Lua module is loaded in opensips.cfg (just like all the +other modules) with loadmodule("/path/to/lua.so");. + + +For the Lua module to compile, you need a recent version of +Lua (tested with 5.1) linked dynamically. The default version +of your favorite Linux distribution should work fine. + + +### Using the module + + +With the Lua module, you can access to lua function on the +OpenSIPS side. You need to define a file to load and call +a function from it. Write a function "mongo_alias" and then +write in your opensips.cfg + + +```opensips +... +if (lua_exec("mongo_alias")) { + ... +} +... +``` + + +On the Lua side, you have access to opensips functions and +variables (AVP, pseudoVar, ...). Read the documentation below +for further informations. + + +### Dependencies + + +#### OpenSIPS Modules + + +None ;-) + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- Lua 5.1.x or later +- memcached + + +This module has been developed and tested with Lua 5.1.?, but +should work with any 5.1.x release. Earlier versions do not work. + + +On current Debian systems, at least the following packages +should be installed: + + +- lua5.1 +- liblua5.1-0-dev +- libmemcached-dev +- libmysqlclient-dev + + +It was reported that other Debian-style distributions (such as Ubuntu) need the same packages. + + +On OpenBSD systems, at least the following packages should be +installed: + + +- Lua + + +### Exported Parameters + + +#### luafilename (string) + + +This is the file name of your script. This may be set once +only, but it may include an arbitary number of functions and +"use" as many Lua module as necessary. + + +The default value is "/etc/opensips/opensips.lua" + + +```opensips title="Set luafilename parameter" +... +modparam("lua", "luafilename", "/etc/opensips/opensips.lua") +... + +``` + + +#### lua_auto_reload (int) + + +Define this value to 1 if you want to reload automatically +the lua script. +Disabled by default. + + +#### warn_missing_free_fixup (int) + + +When you call a function via moduleFunc() you could have a memleak. +Enable this warns you when you're doing it. +Enabled by default. + + +#### lua_allocator (string) + + +Change the default memory allocator for the lua module. +Possible values are : + + +- opensips (default) +- malloc + + +### Exported Functions + + +#### lua_exec(func, [param]) + + +Calls a Lua function with passing it the current SIP message. +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +ONREPLY_ROUTE and BRANCH_ROUTE. + + +Parameters: + + +- *func* (string) - Lua function name +- *param* (string, optional) - Parameter to be passed to the Lua function. + + +```opensips title="lua_exec() usage" +... +if (lua_exec("mongo_alias")) { + ... +} +... +``` + + +#### lua_meminfo() + + +Logs informations about memory. + + +### Exported MI Functions + + +#### watch + + +Name: *watch* + + +Parameters: *none* + + +- *action* (optional) - 'add' or 'delete' +- *extension* (optional) - required if +*action* is provided + + +MI FIFO Command Format: + + +```bash +$ opensips-cli -x mi watch +``` + + +## OpenSIPS Lua API + + +### Available functions + + +This module provides access to a limited number of OpenSIPS +core functions. + + +#### xdbg(message) + + +An alias for xlog(DBG, message) + + +#### xlog([level],message) + + +Logs the message with OpenSIPS's logging facility. The logging +level is one of the following: + + +- ALERT +- CRIT +- ERR +- WARN +- NOTICE +- INFO +- DBG + + +#### WarnMissingFreeFixup + + +Dynamically change the variable warn_missing_free_fixup. + + +#### getpid + + +Returns the current pid. + + +#### getmem + + +Returns a table with the size of allocated memory and the fragmentation. + + +#### getmeminfo + + +Returns a table with memory infos. + + +#### gethostname + + +Returns the value of the current hostname. + + +#### getType(msg) + + +Returns "SIP_REQUEST" or "SIP_REPLY". + + +#### isMyself(host, port) + + +Test if the host and optionally the port represent one of the addresses +that OpenSIPS listens on. + + +#### grepSockInfo(host, port) + + +Similar to isMyself(), but without taking a look into the aliases. + + +#### getURI_User(msg) + + +Returns the user of the To URI. + + +#### getExpires(msg) + + +Returns the expires header of the current message. + + +#### getHeader(msg, header) + + +Returns the value of the specified header. + + +#### getContact(msg) + + +Returns a table with the contact header. + + +#### getRoute(msg) + + +Returns a table with the Route header. + + +#### moduleFunc(msg, function, args1, args2, ...) + + +You can pass arguments to this function. + + +#### getStatus(msg) + + +Returns the current status if the SIP message is a SIP_REPLY. + + +#### getMethod(msg) + + +Returns the current method. + + +#### getSrcIp(msg) + + +Returns the IP address of the source. + + +#### getDstIp(msg) + + +Returns the IP address of the destination. + + +#### AVP_get(name) + + +Returns an AVP variable. + + +#### AVP_set(name, value) + + +Defines an AVP variable. + + +#### AVP_destroy(name) + + +Destroys an AVP variable. + + +#### pseudoVar(msg, variable) + + +Returns a pseudoVar. + + +#### pseudoVarSet(msg, variable, value) + + +Sets the value of a pseudoVar. + + +#### scriptVarGet(variable) + + +Returns a script variable. + + +#### scriptVarSet(variable, value) + + +Sets the value of a script variable. + + +#### add_lump_rpl(msg, header) + + +Add header to the reply. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/lua/doc/contributors.xml b/modules/lua/doc/contributors.xml deleted file mode 100644 index 3ab013a1e68..00000000000 --- a/modules/lua/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Arnaud Chong + Eric Gouyer - 38 - 1 - 4335 - 0 - - - 2. - Razvan Crainea (@razvancrainea) - 34 - 27 - 274 - 230 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 25 - 17 - 319 - 276 - - - 4. - Liviu Chircu (@liviuchircu) - 13 - 10 - 15 - 63 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 9 - 3 - - - 6. - Maksym Sobolyev (@sobomax) - 7 - 5 - 16 - 13 - - - 7. - Vlad Paiu (@vladpaiu) - 5 - 3 - 7 - 9 - - - 8. - Ken Rice - 3 - 1 - 4 - 4 - - - 9. - Julián Moreno Patiño - 3 - 1 - 1 - 1 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jun 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Feb 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2014 - Jan 2020 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2014 - Mar 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Vlad Paiu (@vladpaiu) - Feb 2012 - Jun 2012 - - - 10. - Arnaud Chong + Eric Gouyer - Dec 2011 - Dec 2011 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Paiu (@vladpaiu), Arnaud Chong + Eric Gouyer. -
- -
diff --git a/modules/lua/doc/lua.xml b/modules/lua/doc/lua.xml deleted file mode 100644 index 65c73154a75..00000000000 --- a/modules/lua/doc/lua.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - lua Module - &osipsname; - - - - &admin; - &api; - &contrib; - - &docCopyrights; - ©right; 2006-2011 Arnaud Chong, Eric Gouyer - diff --git a/modules/lua/doc/lua_admin.xml b/modules/lua/doc/lua_admin.xml deleted file mode 100644 index 2abdf8499f1..00000000000 --- a/modules/lua/doc/lua_admin.xml +++ /dev/null @@ -1,209 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The time needed when writing a new OpenSIPS module - unfortunately is quite high, while the options provided by the - configuration file are limited to the features implemented in - the modules. - - - With this Lua module, you can easily implement your own - OpenSIPS extensions in Lua. - -
-
- Installing the module - - This Lua module is loaded in opensips.cfg (just like all the - other modules) with loadmodule("/path/to/lua.so");. - - - For the Lua module to compile, you need a recent version of - Lua (tested with 5.1) linked dynamically. The default version - of your favorite Linux distribution should work fine. - -
-
- Using the module - - With the Lua module, you can access to lua function on the - OpenSIPS side. You need to define a file to load and call - a function from it. Write a function "mongo_alias" and then - write in your opensips.cfg -... -if (lua_exec("mongo_alias")) { - ... -} -... - - - On the Lua side, you have access to opensips functions and - variables (AVP, pseudoVar, ...). Read the documentation below - for further informations. - -
-
- Dependencies -
- OpenSIPS Modules - - None ;-) - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - - Lua 5.1.x or later - memcached - - - - This module has been developed and tested with Lua 5.1.?, but - should work with any 5.1.x release. Earlier versions do not work. - - - On current Debian systems, at least the following packages - should be installed: - - lua5.1 - liblua5.1-0-dev - libmemcached-dev - libmysqlclient-dev - - - - It was reported that other Debian-style distributions (such as Ubuntu) need the same packages. - - - On OpenBSD systems, at least the following packages should be - installed: - - Lua - - -
-
-
- Exported Parameters -
- luafilename (string) - - This is the file name of your script. This may be set once - only, but it may include an arbitary number of functions and - "use" as many Lua module as necessary. - - - The default value is "/etc/opensips/opensips.lua" - - - Set luafilename parameter - -... -modparam("lua", "luafilename", "/etc/opensips/opensips.lua") -... - - -
-
- lua_auto_reload (int) - - Define this value to 1 if you want to reload automatically - the lua script. - Disabled by default. - -
-
- warn_missing_free_fixup (int) - - When you call a function via moduleFunc() you could have a memleak. - Enable this warns you when you're doing it. - Enabled by default. - -
-
- lua_allocator (string) - - Change the default memory allocator for the lua module. - Possible values are : - - opensips (default) - malloc - - -
-
-
- Exported Functions -
- lua_exec(func, [param]) - - Calls a Lua function with passing it the current SIP message. - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE and BRANCH_ROUTE. - - Parameters: - - - func (string) - Lua function name - - - param (string, optional) - Parameter to be passed to the Lua function. - - - - lua_exec() usage - -... -if (lua_exec("mongo_alias")) { - ... -} -... - - -
-
- lua_meminfo() - - Logs informations about memory. - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">watch</function> - - - Name: watch - - Parameters: none - - - action (optional) - 'add' or 'delete' - - - extension (optional) - required if - action is provided - - - MI FIFO Command Format: - - opensips-cli -x mi watch - -
- -
- -
- diff --git a/modules/lua/doc/lua_api.xml b/modules/lua/doc/lua_api.xml deleted file mode 100644 index a79444785b7..00000000000 --- a/modules/lua/doc/lua_api.xml +++ /dev/null @@ -1,189 +0,0 @@ - - OpenSIPS Lua API -
- Available functions - - This module provides access to a limited number of OpenSIPS - core functions. - -
- xdbg(message) - - An alias for xlog(DBG, message) - -
-
- xlog([level],message) - - Logs the message with OpenSIPS's logging facility. The logging - level is one of the following: - - ALERT - CRIT - ERR - WARN - NOTICE - INFO - DBG - - -
-
- WarnMissingFreeFixup - - Dynamically change the variable warn_missing_free_fixup. - -
-
- getpid - - Returns the current pid. - -
-
- getmem - - Returns a table with the size of allocated memory and the fragmentation. - -
-
- getmeminfo - - Returns a table with memory infos. - -
-
- gethostname - - Returns the value of the current hostname. - -
-
- getType(msg) - - Returns "SIP_REQUEST" or "SIP_REPLY". - -
-
- isMyself(host, port) - - Test if the host and optionally the port represent one of the addresses - that OpenSIPS listens on. - -
-
- grepSockInfo(host, port) - - Similar to isMyself(), but without taking a look into the aliases. - -
-
- getURI_User(msg) - - Returns the user of the To URI. - -
-
- getExpires(msg) - - Returns the expires header of the current message. - -
-
- getHeader(msg, header) - - Returns the value of the specified header. - -
-
- getContact(msg) - - Returns a table with the contact header. - -
-
- getRoute(msg) - - Returns a table with the Route header. - -
-
- moduleFunc(msg, function, args1, args2, ...) - - You can pass arguments to this function. - -
-
- getStatus(msg) - - Returns the current status if the SIP message is a SIP_REPLY. - -
-
- getMethod(msg) - - Returns the current method. - -
-
- getSrcIp(msg) - - Returns the IP address of the source. - -
-
- getDstIp(msg) - - Returns the IP address of the destination. - -
-
- AVP_get(name) - - Returns an AVP variable. - -
-
- AVP_set(name, value) - - Defines an AVP variable. - -
-
- AVP_destroy(name) - - Destroys an AVP variable. - -
-
- pseudoVar(msg, variable) - - Returns a pseudoVar. - -
-
- pseudoVarSet(msg, variable, value) - - Sets the value of a pseudoVar. - -
-
- scriptVarGet(variable) - - Returns a script variable. - -
-
- scriptVarSet(variable, value) - - Sets the value of a script variable. - -
-
- add_lump_rpl(msg, header) - - Add header to the reply. - -
-
-
diff --git a/modules/lua/sipmysql.c b/modules/lua/sipmysql.c index f58e9c231d8..10922ecc495 100644 --- a/modules/lua/sipmysql.c +++ b/modules/lua/sipmysql.c @@ -301,7 +301,7 @@ static int l_sipmysql_escape(lua_State *L) to = pkg_malloc(2 * len + 1); if (!to) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", 2 * len + 1); + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", 2 * len + 1); lua_pushnil(L); return 1; } @@ -369,7 +369,7 @@ static int l_sipmysql_prepare(lua_State *L) o_stmt->bind = pkg_malloc(o_stmt->param_count * sizeof(MYSQL_BIND)); if (!o_stmt->bind) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", o_stmt->param_count * sizeof(MYSQL_BIND)); lua_remove(L, -1); lua_pushnil(L); @@ -379,7 +379,7 @@ static int l_sipmysql_prepare(lua_State *L) o_stmt->is_null = pkg_malloc(o_stmt->param_count * sizeof(my_bool)); if (!o_stmt->is_null) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", o_stmt->param_count * sizeof(my_bool)); lua_remove(L, -1); lua_pushnil(L); @@ -389,7 +389,7 @@ static int l_sipmysql_prepare(lua_State *L) o_stmt->length = pkg_malloc(o_stmt->param_count * sizeof(unsigned long)); if (!o_stmt->length) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", o_stmt->param_count * sizeof(unsigned long)); lua_remove(L, -1); lua_pushnil(L); @@ -411,7 +411,7 @@ static int l_sipmysql_prepare(lua_State *L) o_stmt->result = pkg_malloc(o_stmt->num_fields * sizeof(MYSQL_BIND)); if (!o_stmt->result) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", o_stmt->num_fields * sizeof(MYSQL_BIND)); lua_remove(L, -1); lua_pushnil(L); @@ -421,7 +421,7 @@ static int l_sipmysql_prepare(lua_State *L) o_stmt->real_length = pkg_malloc(o_stmt->num_fields * sizeof(unsigned long)); if (!o_stmt->real_length) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", o_stmt->num_fields * sizeof(unsigned long)); lua_remove(L, -1); lua_pushnil(L); @@ -578,7 +578,7 @@ static int sipmysql_stmt_bind(struct sipmysql_stmt *o, lua_State *L, int n, int o->bind[n].buffer = pkg_malloc(sizeof(number)); if (!o->bind[n].buffer) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", sizeof(number)); + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", sizeof(number)); lua_pushnil(L); return 1; } @@ -597,7 +597,7 @@ static int sipmysql_stmt_bind(struct sipmysql_stmt *o, lua_State *L, int n, int o->bind[n].buffer = pkg_malloc(len); if (!o->bind[n].buffer) { - siplua_log(L_CRIT, "malloc of %lu bytes failed\n", len); + siplua_log(L_CRIT, "malloc of %zu bytes failed\n", len); lua_pushnil(L); return 1; } diff --git a/modules/mangler/README b/modules/mangler/README deleted file mode 100644 index 56874fb1623..00000000000 --- a/modules/mangler/README +++ /dev/null @@ -1,279 +0,0 @@ -mangler Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. contact_flds_separator (string) - - 1.4. Exported Functions - - 1.4.1. sdp_mangle_ip(pattern, newip) - 1.4.2. sdp_mangle_port(offset) - 1.4.3. encode_contact(encoding_prefix, public_ip) - 1.4.4. decode_contact() - 1.4.5. decode_contact_header() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. sdp_mangle_ip usage - 1.3. sdp_mangle_port usage - 1.4. encode_contact usage - 1.5. decode_contact usage - 1.6. decode_contact_header usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module to help with SDP mangling. Note: This module - is obselete and will be removed for the 1.5.0 release. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. contact_flds_separator (string) - - First char of this parameter is used as separator for - encoding/decoding Contact header. - -Warning - - First char of this field must be set to a value which is not - used inside username,password or other fields of contact. - Otherwise it is possible for the decoding step to fail/produce - wrong results. - - Default value is “*”. - - Example 1.1. Set db_url parameter -... -modparam("mangler", "contact_flds_separator", "-") -... - - then an encoded uri might look - sip:user-password-ip-port-protocol@PublicIP - -1.4. Exported Functions - -1.4.1. sdp_mangle_ip(pattern, newip) - - Changes IP addresses inside SDP package in lines describing - connections like c=IN IP4 Currently in only changes IP4 - addresses since IP6 probably will not need to traverse NAT :) - - The function returns negative on error, or number of - replacements + 1. - - Meaning of the parameters is as follows: - * pattern (string) - A pair ip/mask used to match IP's - located inside SDP package in lines c=IN IP4 ip. This lines - will only be mangled if located IP is in the network - described by this pattern. Examples of valid patterns are - “10.0.0.0/255.0.0.0” or “10.0.0.0/8” etc. - * newip (string) - the new IP to be put inside SDP package if - old IP address matches pattern. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.2. sdp_mangle_ip usage -... -sdp_mangle_ip("10.0.0.0/8","193.175.135.38"); -... - -1.4.2. sdp_mangle_port(offset) - - Changes ports inside SDP package in lines describing media like - m=audio 13451. - - The function returns negative on error, or number of - replacements + 1. - - Meaning of the parameters is as follows: - * offset (int) - an integer which will be added/subtracted - from the located port. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.3. sdp_mangle_port usage -... -sdp_mangle_port(-12000); -... - -1.4.3. encode_contact(encoding_prefix, public_ip) - - This function will encode uri-s inside Contact header in the - following manner - sip:username:password@ip:port;transport=protocol goes - sip:enc_pref*username*ip*port*protocol@public_ip * is the - default separator. - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - * encoding_prefix (string) - Something to allow us to - determine that a contact is encoded publicip--a routable - IP, most probably you should put your external IP of your - NAT box. - public_ip (string) - The public IP which will be used in - the encoded contact, as described by the example above. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.4. encode_contact usage -... -if ($si == 10.0.0.0/8) encode_contact("enc_prefix","193.175.135.38"); -... - -1.4.4. decode_contact() - - This function will decode the URI in first line in packets - which come with encoded URI in the following manner - sip:enc_pref*username*ip*port*protocol@public_ip goes to - sip:username:password@ip:port;transport=protocol It uses the - default set parameter for contact encoding separator. - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - - This function can be used from REQUEST_ROUTE. - - Example 1.5. decode_contact usage -... -if ($ru =~ "^enc*") { decode_contact(); } -... - -1.4.5. decode_contact_header() - - This function will decode URIs inside Contact header in the - following manner - sip:enc_pref*username*ip*port*protocol@public_ip goes to - sip:username:password@ip:port;transport=protocol. It uses the - default set parameter for contact encoding separator. - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.6. decode_contact_header usage -... -if ($ru =~ "^enc*") { decode_contact_header(); } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Gabriel Vasile 52 13 3118 674 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 26 20 195 198 - 3. Razvan Crainea (@razvancrainea) 14 12 39 27 - 4. Daniel-Constantin Mierla (@miconda) 13 11 25 49 - 5. Andrei Pelinescu-Onciul 12 9 71 72 - 6. Liviu Chircu (@liviuchircu) 9 7 17 60 - 7. Vlad Patrascu (@rvlad-patrascu) 9 6 102 108 - 8. Jan Janak (@janakj) 9 4 428 48 - 9. Henning Westerholt (@henningw) 8 5 13 104 - 10. Peter Lemenkov (@lemenkov) 4 2 5 6 - - All remaining contributors: Maksym Sobolyev (@sobomax), Jiri - Kuthan (@jiriatipteldotorg), Walter Doekes (@wdoekes), - Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona - Modroiu, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2023 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2005 - Apr 2020 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 6. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Walter Doekes (@wdoekes) Jun 2014 - Jun 2014 - 9. Henning Westerholt (@henningw) May 2007 - Jun 2008 - 10. Daniel-Constantin Mierla (@miconda) Sep 2003 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei - Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg), Gabriel - Vasile. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona - Modroiu, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/mangler/README.md b/modules/mangler/README.md new file mode 100644 index 00000000000..f9f9a213e4c --- /dev/null +++ b/modules/mangler/README.md @@ -0,0 +1,220 @@ +--- +title: "mangler Module" +description: "This is a module to help with SDP mangling." +--- + +## Admin Guide + + +### Overview + + +This is a module to help with SDP mangling. +Note: This module is obselete and will be removed for the 1.5.0 release. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### contact_flds_separator (string) + + +First char of this parameter is used as separator for encoding/decoding +Contact header. + + +> [!WARNING] +> First char of this field must be set to a value which is not used +inside username,password or other fields of contact. Otherwise it +is possible for the decoding step to fail/produce wrong results. + + +*Default value is "*".* + + +```opensips title="Set db_url parameter" +... +modparam("mangler", "contact_flds_separator", "-") +... +``` + + +then an encoded uri might look +sip:user-password-ip-port-protocol@PublicIP + + +### Exported Functions + + +#### sdp_mangle_ip(pattern, newip) + + +Changes IP addresses inside SDP package in lines describing +connections like c=IN IP4 Currently in only changes IP4 addresses +since IP6 probably will not need to traverse NAT :) + + +The function returns negative on error, or number of replacements + 1. + + +Meaning of the parameters is as follows: + + +- *pattern* (string) - A pair ip/mask used to match +IP's located inside SDP package in lines c=IN IP4 ip. This +lines will only be mangled if located IP is in the network +described by this pattern. Examples of +valid patterns are "10.0.0.0/255.0.0.0" or +"10.0.0.0/8" etc. +- *newip* (string) - the new +IP to be put inside SDP package if old IP address matches +pattern. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="sdp_mangle_ip usage" +... +sdp_mangle_ip("10.0.0.0/8","193.175.135.38"); +... +``` + + +#### sdp_mangle_port(offset) + + +Changes ports inside SDP package in lines describing media like +m=audio 13451. + + +The function returns negative on error, or number of replacements + 1. + + +Meaning of the parameters is as follows: + + +- *offset* (int) - an integer which will +be added/subtracted from the located port. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="sdp_mangle_port usage" +... +sdp_mangle_port(-12000); +... +``` + + +#### encode_contact(encoding_prefix, public_ip) + + +This function will encode uri-s inside Contact header in the following +manner +sip:username:password@ip:port;transport=protocol goes +sip:enc_pref*username*ip*port*protocol@public_ip * is the default +separator. + + +The function returns negative on error, 1 on success. + + +Meaning of the parameters is as follows: + + +- *encoding_prefix* (string) - Something to allow us +to determine that a contact is encoded publicip--a routable IP, +most probably you should +put your external IP of your NAT box. +*public_ip* (string) - The public IP which will be +used in the encoded contact, as described by the example above. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="encode_contact usage" +... +if ($si == 10.0.0.0/8) encode_contact("enc_prefix","193.175.135.38"); +... +``` + + +#### decode_contact() + + +This function will decode the URI in first line in packets which +come with encoded URI in the following manner +sip:enc_pref*username*ip*port*protocol@public_ip goes to +sip:username:password@ip:port;transport=protocol It uses the default +set parameter for contact encoding separator. + + +The function returns negative on error, 1 on success. + + +Meaning of the parameters is as follows: + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="decode_contact usage" +... +if ($ru =~ "^enc*") { decode_contact(); } +... +``` + + +#### decode_contact_header() + + +This function will decode URIs inside Contact header in the +following manner sip:enc_pref*username*ip*port*protocol@public_ip goes +to sip:username:password@ip:port;transport=protocol. It uses the +default set parameter for contact encoding separator. + + +The function returns negative on error, 1 on success. + + +Meaning of the parameters is as follows: + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="decode_contact_header usage" +... +if ($ru =~ "^enc*") { decode_contact_header(); } +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mangler/doc/contributors.xml b/modules/mangler/doc/contributors.xml deleted file mode 100644 index 31c69590e59..00000000000 --- a/modules/mangler/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Gabriel Vasile - 52 - 13 - 3118 - 674 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 26 - 20 - 195 - 198 - - - 3. - Razvan Crainea (@razvancrainea) - 14 - 12 - 39 - 27 - - - 4. - Daniel-Constantin Mierla (@miconda) - 13 - 11 - 25 - 49 - - - 5. - Andrei Pelinescu-Onciul - 12 - 9 - 71 - 72 - - - 6. - Liviu Chircu (@liviuchircu) - 9 - 7 - 17 - 60 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 9 - 6 - 102 - 108 - - - 8. - Jan Janak (@janakj) - 9 - 4 - 428 - 48 - - - 9. - Henning Westerholt (@henningw) - 8 - 5 - 13 - 104 - - - 10. - Peter Lemenkov (@lemenkov) - 4 - 2 - 5 - 6 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Jiri Kuthan (@jiriatipteldotorg), Walter Doekes (@wdoekes), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Alexandra Titoc. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2005 - Apr 2020 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 6. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Walter Doekes (@wdoekes) - Jun 2014 - Jun 2014 - - - 9. - Henning Westerholt (@henningw) - May 2007 - Jun 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Sep 2003 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg), Gabriel Vasile. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/mangler/doc/mangler.xml b/modules/mangler/doc/mangler.xml deleted file mode 100644 index 89905c6ce3d..00000000000 --- a/modules/mangler/doc/mangler.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mangler Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - diff --git a/modules/mangler/doc/mangler_admin.xml b/modules/mangler/doc/mangler_admin.xml deleted file mode 100644 index c846ea8fc92..00000000000 --- a/modules/mangler/doc/mangler_admin.xml +++ /dev/null @@ -1,253 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module to help with &sdp; mangling. - Note: This module is obselete and will be removed for the 1.5.0 release. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters - -
- <varname>contact_flds_separator</varname> (string) - - First char of this parameter is used as separator for encoding/decoding - Contact header. - - - - First char of this field must be set to a value which is not used - inside username,password or other fields of contact. Otherwise it - is possible for the decoding step to fail/produce wrong results. - - - - - Default value is *. - - - - Set <varname>db_url</varname> parameter - -... -modparam("mangler", "contact_flds_separator", "-") -... - - - - then an encoded uri might look - sip:user-password-ip-port-protocol@PublicIP - -
- -
-
- Exported Functions -
- - <function moreinfo="none">sdp_mangle_ip(pattern, newip)</function> - - - Changes &ip; addresses inside &sdp; package in lines describing - connections like c=IN IP4 Currently in only changes IP4 addresses - since IP6 probably will not need to traverse NAT :) - - - The function returns negative on error, or number of replacements + 1. - - Meaning of the parameters is as follows: - - - pattern (string) - A pair ip/mask used to match - &ip;'s located inside &sdp; package in lines c=IN IP4 ip. This - lines will only be mangled if located &ip; is in the network - described by this pattern. Examples of - valid patterns are 10.0.0.0/255.0.0.0 or - 10.0.0.0/8 etc. - - - - newip (string) - the new - &ip; to be put inside &sdp; package if old &ip; address matches - pattern. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function>sdp_mangle_ip</function> usage - -... -sdp_mangle_ip("10.0.0.0/8","193.175.135.38"); -... - - -
- -
- - <function moreinfo="none">sdp_mangle_port(offset)</function> - - - Changes ports inside &sdp; package in lines describing media like - m=audio 13451. - - - The function returns negative on error, or number of replacements + 1. - - Meaning of the parameters is as follows: - - - offset (int) - an integer which will - be added/subtracted from the located port. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function>sdp_mangle_port</function> usage - -... -sdp_mangle_port(-12000); -... - - -
- -
- - <function moreinfo="none">encode_contact(encoding_prefix, public_ip)</function> - - - This function will encode uri-s inside Contact header in the following - manner - sip:username:password@ip:port;transport=protocol goes - sip:enc_pref*username*ip*port*protocol@public_ip * is the default - separator. - - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - - - encoding_prefix (string) - Something to allow us - to determine that a contact is encoded publicip--a routable &ip;, - most probably you should - put your external &ip; of your &nat; box. - - public_ip (string) - The public IP which will be - used in the encoded contact, as described by the example above. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function>encode_contact</function> usage - -... -if ($si == 10.0.0.0/8) encode_contact("enc_prefix","193.175.135.38"); -... - - -
- -
- - <function moreinfo="none">decode_contact()</function> - - - This function will decode the &uri; in first line in packets which - come with encoded &uri; in the following manner - sip:enc_pref*username*ip*port*protocol@public_ip goes to - sip:username:password@ip:port;transport=protocol It uses the default - set parameter for contact encoding separator. - - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - - This function can be used from REQUEST_ROUTE. - - - <function>decode_contact</function> usage - -... -if ($ru =~ "^enc*") { decode_contact(); } -... - - -
- -
- - <function moreinfo="none">decode_contact_header()</function> - - - This function will decode &uri;s inside Contact header in the - following manner sip:enc_pref*username*ip*port*protocol@public_ip goes - to sip:username:password@ip:port;transport=protocol. It uses the - default set parameter for contact encoding separator. - - - The function returns negative on error, 1 on success. - - Meaning of the parameters is as follows: - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function>decode_contact_header</function> usage - -... -if ($ru =~ "^enc*") { decode_contact_header(); } -... - - -
-
-
- diff --git a/modules/mathops/README b/modules/mathops/README deleted file mode 100644 index cf4e35af584..00000000000 --- a/modules/mathops/README +++ /dev/null @@ -1,429 +0,0 @@ -mathops Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. decimal_digits (integer) - - 1.4. Exported Functions - - 1.4.1. math_eval(expression, result_var) - 1.4.2. math_rpn(expression, result_var) - 1.4.3. math_trunc(number, result_var) - 1.4.4. math_floor(number, result_var) - 1.4.5. math_ceil(number, result_var) - 1.4.6. math_round(number, result_var[, decimals]) - 1.4.7. math_round_sf(number, result_var, figures) - 1.4.8. math_compare(exp1, exp2, result_var) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the decimal_digits module parameter - 1.2. math_eval usage - 1.3. math_rpn usage - 1.4. math_trunc usage - 1.5. math_floor usage - 1.6. math_ceil usage - 1.7. math_round usage - 1.8. math_round_sf usage - 1.9. math_compare usage - -Chapter 1. Admin Guide - -1.1. Overview - - The mathops module provides a series of functions which enable - various floating point operations at OpenSIPS script level. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules.. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. decimal_digits (integer) - - The precision of the results returned by all the module - functions. The higher the “decimal_digits” value, the more - decimal digits the results will have. - - Default value is “6”. - - Example 1.1. Setting the decimal_digits module parameter -modparam("mathops", "decimal_digits", 10) - -1.4. Exported Functions - -1.4.1. math_eval(expression, result_var) - - The function evaluates a given expression and writes the result - in the output pseudo-variable. Evaluation uses tinyexpr (see - https://github.com/codeplea/tinyexpr). - - Currently allowed syntax for specifying an expression: - * Nested parentheses - * addition (+), subtraction/negation (-), multiplication (*), - division (/), exponentiation (^) and modulus (%) with the - normal operator precedence (the one exception being that - exponentiation is evaluated left-to-right) - * C math functions: abs (calls to fabs), acos, asin, atan, - ceil, cos, cosh, exp, floor, ln (calls to log), log (calls - to log10), sin, sinh, sqrt, tan, tanh - - Meaning of the parameters is as follows: - * expression (string) - a mathematical expression. - * result_var (var) - variable which will hold the result of - the evaluation. - - This function can be used from any route. - - Example 1.2. math_eval usage -... -# Compute some random math expression - -$avp(1) = "3.141592"; -$avp(2) = "2.71828"; -$avp(3) = "123.45678"; - -if (math_eval("$avp(1) * ($avp(3) - ($avp(1) - $avp(2))) / $avp(3)", $av -p(result))) { - xlog("Result of expression: $avp(result)\n"); -} else { - xlog("Math eval failed!\n"); -} - -... - -1.4.2. math_rpn(expression, result_var) - - The function evaluates a given RPN expression and writes the - result in the output variable. - - The expression is specified in Reverse Polish Notation. Values - are pushed onto a stack, while operations are executed on that - stack. The following operations are supported: - * binary operators: + - / * mod pow - * unary functions: neg exp ln log10 abs sqrt cbrt floor ceil - round nearbyint trunc - neg will change the sign of the top of the stack - ln is natural logarithm; abs is absolute value; other - functions are standard C functions - * constants: e pi - * stack manipulations commands: drop dup swap - - Meaning of the parameters is as follows: - * expression (string) - a RPN expression. - * result_var (var) - variable which will hold the result of - the evaluation. - - This function can be used from any route. - - Example 1.3. math_rpn usage -$avp(1) = "3"; - -if (math_rpn("1 $avp(1) swap swap dup drop / exp ln 1 swap /", $avp(resu -lt))) { - xlog("Result of expression: $avp(result)\n"); -} else { - xlog("RPN eval failed!\n"); -} - -/* This example RPN script will push 1 then 3 onto the stack, then do a -couple no-ops -(exchange the two values twice, duplicate one of them then drop the dupl -icate), -compute the division of 1 by 3, then do another no-op (exponentiation th -en logarithm), and -finally compute 1 divided by the result, giving 3 as the result. */ - -1.4.3. math_trunc(number, result_var) - - Truncation of a number towards zero. This means that trunc(3.7) - = 3.0 and trunc(-2.9) = -2.0. - - Meaning of the parameters is as follows: - * number (string) - Number to be truncated. - * result_var (var) - variable which will hold the result of - the evaluation. - - This function can be used from any route. - - Example 1.4. math_trunc usage -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_trunc($avp(1), $avp(result))) { - xlog("Truncate result: $avp(result)\n"); -} else { - xlog("Truncate failed!\n"); -} -... - -1.4.4. math_floor(number, result_var) - - Truncates a number, always towards -infinity. This means that - floor(3.7) = 3.0 and floor(-2.9) = -3.0 - - Meaning of the parameters is as follows: - * number (string) - Number to be truncated. - * result_var (var) - variable which will hold the result of - the evaluation. - - This function can be used from any route. - - Example 1.5. math_floor usage -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_floor($avp(1), $avp(result))) { - xlog("Floor result: $avp(result)\n"); -} else { - xlog("Floor operation failed!\n"); -} -... - -1.4.5. math_ceil(number, result_var) - - Truncates a number, always towards +infinity. This means that - ceil(3.2) = 4.0 and ceil(-2.9) = -2.0 - - Meaning of the parameters is as follows: - * number (string) - Number to be truncated. - * result_var (var) - variable which will hold the result of - the evaluation. - - This function can be used from any route. - - Example 1.6. math_ceil usage -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_ceil($avp(1), $avp(result))) { - xlog("Ceil result: $avp(result)\n"); -} else { - xlog("Ceil operation failed!\n"); -} -... - -1.4.6. math_round(number, result_var[, decimals]) - - The round function returns the nearest integer, and - tie-breaking is done away from zero. Examples: round(1.2) = - 1.0, round(0.5) = 1.0, round(-0.5) = -1.0 - - By default, the function returns an integer. An additional - parameter controls the number of decimal digits of the initial - number which will be kept. The rounding will then be done using - the remaining decimal digits, and the result will be a float - value, represented as a string. - - Meaning of the parameters is as follows: - * number (string) - Number to be rounded. - * result_var - variable which will hold the result of the - evaluation. - * decimals (int, optional) - further improves the precision - of the rounding. - - This function can be used from any route. - - Example 1.7. math_round usage -... -# Rounding PI - -$avp(1) = "3.141492"; - -if (math_round($avp(1), $avp(result))) { - - # result should be: 3 - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} - -... - -if (math_round($avp(1), $avp(result), 4)) { - - # result should be: "3.1415" - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} -... - -1.4.7. math_round_sf(number, result_var, figures) - - To give a simple explanation, rounding to N significant figures - is done by first obtaining the number resulted from keeping N - significant figures (0 padded if necessary), then adjusting it - if the N+1'th digit is greater or equal to 5. - - Some examples: - * round_sf(17892.987, 1) = 20000 - round_sf(17892.987, 2) = 18000 - round_sf(17892.987, 3) = 17900 - round_sf(17892.987, 4) = 17890 - round_sf(17892.987, 5) = 17893 - round_sf(17892.987, 6) = 17893.0 - round_sf(17892.987, 7) = 17892.99 - - Meaning of the parameters is as follows: - * number (string) - Number to be rounded. - * result_var (var) - variable which will hold the result of - the evaluation. - * figures - further improves the precision of the rounding. - - This function can be used from any route. - - Example 1.8. math_round_sf usage -... -# Rounding PI - -$avp(1) = "3.141492"; - -if (math_round_sf($avp(1), $avp(result), 4)) { - - # result should be: "3.141" - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} - -... - -1.4.8. math_compare(exp1, exp2, result_var) - - Compare exp1 with exp2 and returns the comparison result in the - result_var. Standard comparison return codes used : If exp1 > - exp2, result_var = 1. Else if exp2 > exp1, result_var = -1, - else (in case they are equal), 0 is populated in the result_var - - Meaning of the parameters is as follows: - * exp1 (string) - First expression to be evaluated and used - for comparison. - * exp2 (string) - Second expression to be evaluated and used - for comparison. - * result_var (var) - variable which will hold the result of - the comparison. - - This function can be used from any route. - - Example 1.9. math_compare usage -... -# Rounding PI - -$var(exp1) = "1 + 8"; -$var(exp2) = "7/2"; - -if (math_compare($var(exp1), $var(exp2), $var(result))) { - - # $var(result) will be 1, since 9 > 3.5 -} - -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 26 12 1355 66 - 2. Razvan Crainea (@razvancrainea) 10 8 39 44 - 3. Vlad Patrascu (@rvlad-patrascu) 9 3 96 302 - 4. Ryan Bullock (@rrb3942) 9 1 552 160 - 5. Stephane Alnet 6 2 327 36 - 6. Maksym Sobolyev (@sobomax) 5 3 3 3 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 3 1 - 8. Julián Moreno Patiño 3 1 3 3 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - 10. Vlad Paiu (@vladpaiu) 2 1 88 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 2. Vlad Paiu (@vladpaiu) Jan 2022 - Jan 2022 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Oct 2019 - 4. Liviu Chircu (@liviuchircu) Feb 2013 - Jun 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ryan Bullock (@rrb3942) Feb 2016 - Feb 2016 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Stephane Alnet Nov 2013 - Nov 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Ryan Bullock (@rrb3942), Julián Moreno Patiño, - Stephane Alnet. - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/mathops/README.md b/modules/mathops/README.md new file mode 100644 index 00000000000..de59bae67e3 --- /dev/null +++ b/modules/mathops/README.md @@ -0,0 +1,394 @@ +--- +title: "mathops Module" +description: "The mathops module provides a series of functions which enable various floating point operations at OpenSIPS script level." +--- + +## Admin Guide + + +### Overview + + +The mathops module provides a series of functions which enable various +floating point operations at OpenSIPS script level. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules.*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### decimal_digits (integer) + + +The precision of the results returned by all the module functions. +The higher the "decimal_digits" value, the more decimal +digits the results will have. + + +Default value is "6". + + +```opensips title="Setting the decimal_digits module parameter" +modparam("mathops", "decimal_digits", 10) +``` + + +### Exported Functions + + +#### math_eval(expression, result_var) + + +The function evaluates a given expression and writes the result in the +output pseudo-variable. Evaluation uses tinyexpr (see https://github.com/codeplea/tinyexpr). + + +Currently allowed syntax for specifying an expression: + + +- Nested parentheses +- addition (+), subtraction/negation (-), multiplication (*), division (/), exponentiation (^) and modulus (%) with the normal operator precedence (the one exception being that exponentiation is evaluated left-to-right) +- C math functions: abs (calls to fabs), acos, asin, atan, ceil, cos, cosh, exp, floor, ln (calls to log), log (calls to log10), sin, sinh, sqrt, tan, tanh + + +Meaning of the parameters is as follows: + + +- *expression* (string) - a mathematical expression. +- *result_var* (var) - variable which will +hold the result of the evaluation. + + +This function can be used from any route. + + +```opensips title="math_eval usage" +... +# Compute some random math expression + +$avp(1) = "3.141592"; +$avp(2) = "2.71828"; +$avp(3) = "123.45678"; + +if (math_eval("$avp(1) * ($avp(3) - ($avp(1) - $avp(2))) / $avp(3)", $avp(result))) { + xlog("Result of expression: $avp(result)\n"); +} else { + xlog("Math eval failed!\n"); +} + +... +``` + + +#### math_rpn(expression, result_var) + + +The function evaluates a given RPN expression and writes the result in the +output variable. + + +The expression is specified in Reverse Polish Notation. Values are pushed +onto a stack, while operations are executed on that stack. The following operations +are supported: + + +- binary operators: + - / * mod pow +- unary functions: neg exp ln log10 abs sqrt cbrt floor ceil round nearbyint trunc +neg will change the sign of the top of the stack +ln is natural logarithm; abs is absolute value; other functions are standard C functions +- constants: e pi +- stack manipulations commands: drop dup swap + + +Meaning of the parameters is as follows: + + +- *expression* (string) - a RPN expression. +- *result_var* (var) - variable which will +hold the result of the evaluation. + + +This function can be used from any route. + + +```opensips title="math_rpn usage" +$avp(1) = "3"; + +if (math_rpn("1 $avp(1) swap swap dup drop / exp ln 1 swap /", $avp(result))) { + xlog("Result of expression: $avp(result)\n"); +} else { + xlog("RPN eval failed!\n"); +} + +/* This example RPN script will push 1 then 3 onto the stack, then do a couple no-ops +(exchange the two values twice, duplicate one of them then drop the duplicate), +compute the division of 1 by 3, then do another no-op (exponentiation then logarithm), and +finally compute 1 divided by the result, giving 3 as the result. */ +``` + + +#### math_trunc(number, result_var) + + +Truncation of a number towards zero. This means that trunc(3.7) = 3.0 and +trunc(-2.9) = -2.0. + + +Meaning of the parameters is as follows: + + +- *number* (string) - Number to be truncated. +- *result_var* (var) - variable which will +hold the result of the evaluation. + + +This function can be used from any route. + + +```opensips title="math_trunc usage" +... +# Truncate a random number + +$avp(1) = "3.141492"; + +if (math_trunc($avp(1), $avp(result))) { + xlog("Truncate result: $avp(result)\n"); +} else { + xlog("Truncate failed!\n"); +} +... +``` + + +#### math_floor(number, result_var) + + +Truncates a number, always towards -infinity. This means that floor(3.7) = 3.0 +and floor(-2.9) = -3.0 + + +Meaning of the parameters is as follows: + + +- *number* (string) - Number to be truncated. +- *result_var* (var) - variable which will +hold the result of the evaluation. + + +This function can be used from any route. + + +```opensips title="math_floor usage" +... +# Truncate a random number + +$avp(1) = "3.141492"; + +if (math_floor($avp(1), $avp(result))) { + xlog("Floor result: $avp(result)\n"); +} else { + xlog("Floor operation failed!\n"); +} +... +``` + + +#### math_ceil(number, result_var) + + +Truncates a number, always towards +infinity. This means that ceil(3.2) = 4.0 +and ceil(-2.9) = -2.0 + + +Meaning of the parameters is as follows: + + +- *number* (string) - Number to be truncated. +- *result_var* (var) - variable which will +hold the result of the evaluation. + + +This function can be used from any route. + + +```opensips title="math_ceil usage" +... +# Truncate a random number + +$avp(1) = "3.141492"; + +if (math_ceil($avp(1), $avp(result))) { + xlog("Ceil result: $avp(result)\n"); +} else { + xlog("Ceil operation failed!\n"); +} +... +``` + + +#### math_round(number, result_var[, decimals]) + + +The round function returns the nearest integer, and tie-breaking is done away +from zero. Examples: round(1.2) = 1.0, round(0.5) = 1.0, round(-0.5) = -1.0 + + +By default, the function returns an integer. An additional parameter controls +the number of decimal digits of the initial number which will be kept. The +rounding will then be done using the remaining decimal digits, and the result +will be a float value, represented as a string. + + +Meaning of the parameters is as follows: + + +- *number* (string) - Number to be rounded. +- *result_var* - variable which will +hold the result of the evaluation. +- *decimals* (int, optional) - +further improves the precision of the rounding. + + +This function can be used from any route. + + +```opensips title="math_round usage" +... +# Rounding PI + +$avp(1) = "3.141492"; + +if (math_round($avp(1), $avp(result))) { + + # result should be: 3 + xlog("Round result: $avp(result)\n"); +} else { + xlog("Round operation failed!\n"); +} + +... + +if (math_round($avp(1), $avp(result), 4)) { + + # result should be: "3.1415" + xlog("Round result: $avp(result)\n"); +} else { + xlog("Round operation failed!\n"); +} +... +``` + + +#### math_round_sf(number, result_var, figures) + + +To give a simple explanation, rounding to N significant figures is done by +first obtaining the number resulted from keeping N significant figures +(0 padded if necessary), then adjusting it if the N+1'th digit is greater +or equal to 5. + + +Some examples: + + +- round_sf(17892.987, 1) = 20000 +round_sf(17892.987, 2) = 18000 +round_sf(17892.987, 3) = 17900 +round_sf(17892.987, 4) = 17890 +round_sf(17892.987, 5) = 17893 +round_sf(17892.987, 6) = 17893.0 +round_sf(17892.987, 7) = 17892.99 + + +Meaning of the parameters is as follows: + + +- *number* (string) - Number to be rounded. +- *result_var* (var) - variable which will +hold the result of the evaluation. +- *figures* - +further improves the precision of the rounding. + + +This function can be used from any route. + + +```opensips title="math_round_sf usage" +... +# Rounding PI + +$avp(1) = "3.141492"; + +if (math_round_sf($avp(1), $avp(result), 4)) { + + # result should be: "3.141" + xlog("Round result: $avp(result)\n"); +} else { + xlog("Round operation failed!\n"); +} + +... +``` + + +#### math_compare(exp1, exp2, result_var) + + +Compare exp1 with exp2 and returns the comparison result in the result_var. +Standard comparison return codes used : If exp1 > exp2, result_var = 1. +Else if exp2 > exp1, result_var = -1, else (in case they are equal), +0 is populated in the result_var + + +Meaning of the parameters is as follows: + + +- *exp1* (string) - First expression to be evaluated and used for comparison. +- *exp2* (string) - Second expression to be evaluated and used for comparison. +- *result_var* (var) - variable which will +hold the result of the comparison. + + +This function can be used from any route. + + +```opensips title="math_compare usage" +... +# Rounding PI + +$var(exp1) = "1 + 8"; +$var(exp2) = "7/2"; + +if (math_compare($var(exp1), $var(exp2), $var(result))) { + + # $var(result) will be 1, since 9 > 3.5 +} + +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mathops/doc/contributors.xml b/modules/mathops/doc/contributors.xml deleted file mode 100644 index 9b2e819e3be..00000000000 --- a/modules/mathops/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 26 - 12 - 1355 - 66 - - - 2. - Razvan Crainea (@razvancrainea) - 10 - 8 - 39 - 44 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 9 - 3 - 96 - 302 - - - 4. - Ryan Bullock (@rrb3942) - 9 - 1 - 552 - 160 - - - 5. - Stephane Alnet - 6 - 2 - 327 - 36 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 3 - 3 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 3 - 1 - - - 8. - Julián Moreno Patiño - 3 - 1 - 3 - 3 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 10. - Vlad Paiu (@vladpaiu) - 2 - 1 - 88 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 2. - Vlad Paiu (@vladpaiu) - Jan 2022 - Jan 2022 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Oct 2019 - - - 4. - Liviu Chircu (@liviuchircu) - Feb 2013 - Jun 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ryan Bullock (@rrb3942) - Feb 2016 - Feb 2016 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Stephane Alnet - Nov 2013 - Nov 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ryan Bullock (@rrb3942), Julián Moreno Patiño, Stephane Alnet. -
- -
diff --git a/modules/mathops/doc/mathops.xml b/modules/mathops/doc/mathops.xml deleted file mode 100644 index dfde61b549f..00000000000 --- a/modules/mathops/doc/mathops.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - mathops Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - diff --git a/modules/mathops/doc/mathops_admin.xml b/modules/mathops/doc/mathops_admin.xml deleted file mode 100644 index 642460b59bd..00000000000 --- a/modules/mathops/doc/mathops_admin.xml +++ /dev/null @@ -1,486 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The mathops module provides a series of functions which enable various - floating point operations at &osips; script level. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules.. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>decimal_digits</varname> (integer) - - The precision of the results returned by all the module functions. - The higher the decimal_digits value, the more decimal - digits the results will have. - - - Default value is 6. - - - Setting the decimal_digits module parameter - -modparam("mathops", "decimal_digits", 10) - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">math_eval(expression, result_var)</function> - - - The function evaluates a given expression and writes the result in the - output pseudo-variable. Evaluation uses tinyexpr (see https://github.com/codeplea/tinyexpr). - - - Currently allowed syntax for specifying an expression: - - - Nested parentheses - - - addition (+), subtraction/negation (-), multiplication (*), division (/), exponentiation (^) and modulus (%) with the normal operator precedence (the one exception being that exponentiation is evaluated left-to-right) - - - C math functions: abs (calls to fabs), acos, asin, atan, ceil, cos, cosh, exp, floor, ln (calls to log), log (calls to log10), sin, sinh, sqrt, tan, tanh - - - - Meaning of the parameters is as follows: - - - expression (string) - a mathematical expression. - - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_eval</function> usage - -... -# Compute some random math expression - -$avp(1) = "3.141592"; -$avp(2) = "2.71828"; -$avp(3) = "123.45678"; - -if (math_eval("$avp(1) * ($avp(3) - ($avp(1) - $avp(2))) / $avp(3)", $avp(result))) { - xlog("Result of expression: $avp(result)\n"); -} else { - xlog("Math eval failed!\n"); -} - -... - - -
- -
- - <function moreinfo="none">math_rpn(expression, result_var)</function> - - - The function evaluates a given RPN expression and writes the result in the - output variable. - - - The expression is specified in Reverse Polish Notation. Values are pushed - onto a stack, while operations are executed on that stack. The following operations - are supported: - - - binary operators: + - / * mod pow - - - unary functions: neg exp ln log10 abs sqrt cbrt floor ceil round nearbyint trunc - neg will change the sign of the top of the stack - ln is natural logarithm; abs is absolute value; other functions are standard C functions - - - constants: e pi - - - stack manipulations commands: drop dup swap - - - - Meaning of the parameters is as follows: - - - expression (string) - a RPN expression. - - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_rpn</function> usage - -$avp(1) = "3"; - -if (math_rpn("1 $avp(1) swap swap dup drop / exp ln 1 swap /", $avp(result))) { - xlog("Result of expression: $avp(result)\n"); -} else { - xlog("RPN eval failed!\n"); -} - -/* This example RPN script will push 1 then 3 onto the stack, then do a couple no-ops -(exchange the two values twice, duplicate one of them then drop the duplicate), -compute the division of 1 by 3, then do another no-op (exponentiation then logarithm), and -finally compute 1 divided by the result, giving 3 as the result. */ - - -
- - -
- - <function moreinfo="none">math_trunc(number, result_var)</function> - - - Truncation of a number towards zero. This means that trunc(3.7) = 3.0 and - trunc(-2.9) = -2.0. - - Meaning of the parameters is as follows: - - - number (string) - Number to be truncated. - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_trunc</function> usage - -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_trunc($avp(1), $avp(result))) { - xlog("Truncate result: $avp(result)\n"); -} else { - xlog("Truncate failed!\n"); -} -... - - -
- -
- - <function moreinfo="none">math_floor(number, result_var)</function> - - - Truncates a number, always towards -infinity. This means that floor(3.7) = 3.0 - and floor(-2.9) = -3.0 - - Meaning of the parameters is as follows: - - - number (string) - Number to be truncated. - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_floor</function> usage - -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_floor($avp(1), $avp(result))) { - xlog("Floor result: $avp(result)\n"); -} else { - xlog("Floor operation failed!\n"); -} -... - - -
- -
- - <function moreinfo="none">math_ceil(number, result_var)</function> - - - Truncates a number, always towards +infinity. This means that ceil(3.2) = 4.0 - and ceil(-2.9) = -2.0 - - Meaning of the parameters is as follows: - - - number (string) - Number to be truncated. - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_ceil</function> usage - -... -# Truncate a random number - -$avp(1) = "3.141492"; - -if (math_ceil($avp(1), $avp(result))) { - xlog("Ceil result: $avp(result)\n"); -} else { - xlog("Ceil operation failed!\n"); -} -... - - -
- -
- - <function moreinfo="none">math_round(number, result_var[, decimals])</function> - - - The round function returns the nearest integer, and tie-breaking is done away - from zero. Examples: round(1.2) = 1.0, round(0.5) = 1.0, round(-0.5) = -1.0 - - - By default, the function returns an integer. An additional parameter controls - the number of decimal digits of the initial number which will be kept. The - rounding will then be done using the remaining decimal digits, and the result - will be a float value, represented as a string. - - Meaning of the parameters is as follows: - - - number (string) - Number to be rounded. - - - result_var - variable which will - hold the result of the evaluation. - - - - decimals (int, optional) - - further improves the precision of the rounding. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_round</function> usage - -... -# Rounding PI - -$avp(1) = "3.141492"; - -if (math_round($avp(1), $avp(result))) { - - # result should be: 3 - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} - -... - -if (math_round($avp(1), $avp(result), 4)) { - - # result should be: "3.1415" - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} -... - - -
- -
- - <function moreinfo="none">math_round_sf(number, result_var, figures)</function> - - - To give a simple explanation, rounding to N significant figures is done by - first obtaining the number resulted from keeping N significant figures - (0 padded if necessary), then adjusting it if the N+1'th digit is greater - or equal to 5. - - - Some examples: - - - round_sf(17892.987, 1) = 20000 - round_sf(17892.987, 2) = 18000 - round_sf(17892.987, 3) = 17900 - round_sf(17892.987, 4) = 17890 - round_sf(17892.987, 5) = 17893 - round_sf(17892.987, 6) = 17893.0 - round_sf(17892.987, 7) = 17892.99 - - - - Meaning of the parameters is as follows: - - - number (string) - Number to be rounded. - - - result_var (var) - variable which will - hold the result of the evaluation. - - - - figures - - further improves the precision of the rounding. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_round_sf</function> usage - -... -# Rounding PI - -$avp(1) = "3.141492"; - -if (math_round_sf($avp(1), $avp(result), 4)) { - - # result should be: "3.141" - xlog("Round result: $avp(result)\n"); -} else { - xlog("Round operation failed!\n"); -} - -... - - -
- -
- - <function moreinfo="none">math_compare(exp1, exp2, result_var)</function> - - - Compare exp1 with exp2 and returns the comparison result in the result_var. - Standard comparison return codes used : If exp1 > exp2, result_var = 1. - Else if exp2 > exp1, result_var = -1, else (in case they are equal), - 0 is populated in the result_var - - Meaning of the parameters is as follows: - - - exp1 (string) - First expression to be evaluated and used for comparison. - - - exp2 (string) - Second expression to be evaluated and used for comparison. - - - result_var (var) - variable which will - hold the result of the comparison. - - - - - This function can be used from any route. - - - <function moreinfo="none">math_compare</function> usage - -... -# Rounding PI - -$var(exp1) = "1 + 8"; -$var(exp2) = "7/2"; - -if (math_compare($var(exp1), $var(exp2), $var(result))) { - - # $var(result) will be 1, since 9 > 3.5 -} - -... - - -
-
-
- diff --git a/modules/maxfwd/README b/modules/maxfwd/README deleted file mode 100644 index 606061b7b48..00000000000 --- a/modules/maxfwd/README +++ /dev/null @@ -1,231 +0,0 @@ -maxfwd Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. max_limit (integer) - - 1.4. Exported Functions - - 1.4.1. mf_process_maxfwd_header(max_value) - 1.4.2. is_maxfwd_lt(max_value) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set max_limit parameter - 1.2. mx_process_maxfwd_header usage - 1.3. is_maxfwd_lt usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements all the operations regarding MaX-Forward - header field, like adding it (if not present) or decrementing - and checking the value of the existent one. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. max_limit (integer) - - Set an upper limit for the max-forward value in the outgoing - requests. If the header is present, the decremented value is - not allowed to exceed this max_limits - if it does, the header - value will by decreased to “max_limit”. - - Note: This check is done when calling the - mf_process_maxfwd_header() header. - - The range of values stretches from 1 to 256, which is the - maximum MAX-FORWARDS value allowed by RFC 3261. - - Default value is “256”. - - Example 1.1. Set max_limit parameter -... -modparam("maxfwd", "max_limit", 32) -... - -1.4. Exported Functions - -1.4.1. mf_process_maxfwd_header(max_value) - - If no Max-Forward header is present in the received request, a - header will be added having the original value equal with - “max_value”. If a Max-Forward header is already present, its - value will be decremented (if not 0). - - Retuning codes: - * 2 (true) - header was not found and a new header was - successfully added. - * 1 (true) - header was found and its value was successfully - decremented (had a non-0 value). - * -1 (false) - the header was found and its value is 0 - (cannot be decremented). - * -2 (false) - error during processing. - - The return code may be extensivly tested via script variable - “retcode” (or “$?”). - - Meaning of the parameters is as follows: - * max_value (int) - Value to be added if there is no - Max-Forwards header field in the message. - - This function can be used from REQUEST_ROUTE. - - Example 1.2. mx_process_maxfwd_header usage -... -# initial sanity checks -- messages with -# max_forwards==0, or excessively long requests -if (!mf_process_maxfwd_header(10) && $retcode==-1) { - sl_send_reply(483,"Too Many Hops"); - exit; -}; -... - -1.4.2. is_maxfwd_lt(max_value) - - Checks if the Max-Forward header value is less then the - “max_value” parameter value. It considers also the value of the - new inserted header (if locally added). - - Retuning codes: - * 1 (true) - header was found or set and its value is - strictly less than “max_value”. - * -1 (false) - the header was found or set and its value is - greater or equal to “max_value”. - * -2 (false) - header was not found or not set. - * -3 (false) - error during processing. - - The return code may be extensivly tested via script variable - “retcode” (or “$?”). - - Meaning of the parameters is as follows: - * max_value (int) - value to check the Max-Forward.value - against (as less than). - - Example 1.3. is_maxfwd_lt usage -... -# next hope is a gateway, so make no sens to -# forward if MF is 0 (after decrement) -if ( is_maxfwd_lt(1) ) { - sl_send_reply(483,"Too Many Hops"); - exit; -}; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 46 30 864 484 - 2. Liviu Chircu (@liviuchircu) 12 10 17 44 - 3. Jan Janak (@janakj) 11 9 58 38 - 4. Daniel-Constantin Mierla (@miconda) 11 9 23 19 - 5. Andrei Pelinescu-Onciul 10 8 31 26 - 6. Jiri Kuthan (@jiriatipteldotorg) 9 7 93 7 - 7. Razvan Crainea (@razvancrainea) 8 6 9 8 - 8. Vlad Patrascu (@rvlad-patrascu) 6 4 34 43 - 9. Henning Westerholt (@henningw) 4 2 3 3 - 10. Maksym Sobolyev (@sobomax) 4 2 2 3 - - All remaining contributors: Aron Podrigal (@ar45), Konstantin - Bokarius, Andreas Heise, Peter Lemenkov (@lemenkov), Edson - Gellert Schubert, Nils Ohlmeier, Elena-Ramona Modroiu, Klaus - Darilion, Alexandra Titoc, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Aron Podrigal (@ar45) Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Jan 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2002 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Walter Doekes (@wdoekes) May 2014 - May 2014 - 10. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw), Klaus Darilion, - Andreas Heise, Elena-Ramona Modroiu, Jan Janak (@janakj), - Andrei Pelinescu-Onciul, Nils Ohlmeier, Jiri Kuthan - (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu - (@liviuchircu), Peter Lemenkov (@lemenkov), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Klaus Darilion, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/maxfwd/README.md b/modules/maxfwd/README.md new file mode 100644 index 00000000000..c0a1df6d642 --- /dev/null +++ b/modules/maxfwd/README.md @@ -0,0 +1,164 @@ +--- +title: "maxfwd Module" +description: "The module implements all the operations regarding MaX-Forward header field, like adding it (if not present) or decrementing and checking the value of the existent one." +--- + +## Admin Guide + + +### Overview + + +The module implements all the operations regarding MaX-Forward header +field, like adding it (if not present) or decrementing and checking +the value of the existent one. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### max_limit (integer) + + +Set an upper limit for the max-forward value in the outgoing requests. +If the header is present, the decremented value is not allowed to +exceed this max_limits - if it does, the header value will by +decreased to "max_limit". + + +Note: This check is done when calling the +mf_process_maxfwd_header() header. + + +The range of values stretches from 1 to 256, which is the maximum +MAX-FORWARDS value allowed by RFC 3261. + + +*Default value is "256".* + + +```opensips title="Set max_limit parameter" +... +modparam("maxfwd", "max_limit", 32) +... +``` + + +### Exported Functions + + +#### mf_process_maxfwd_header(max_value) + + +If no Max-Forward header is present in the received request, a header +will be added having the original value equal with +"max_value". If a Max-Forward header is already present, +its value will be decremented (if not 0). + + +Retuning codes: + + +- *2 (true)* - header was not found and +a new header was successfully added. +- *1 (true)* - header was found and its +value was successfully decremented (had a non-0 value). +- *-1 (false)* - the header was found and +its value is 0 (cannot be decremented). +- *-2 (false)* - error during processing. + + +The return code may be extensivly tested via script variable +"retcode" (or "$?"). + + +Meaning of the parameters is as follows: + + +- *max_value* (int) - Value to be added if +there is no Max-Forwards header field in the message. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="mx_process_maxfwd_header usage" +... +# initial sanity checks -- messages with +# max_forwards==0, or excessively long requests +if (!mf_process_maxfwd_header(10) && $retcode==-1) { + sl_send_reply(483,"Too Many Hops"); + exit; +}; +... +``` + + +#### is_maxfwd_lt(max_value) + + +Checks if the Max-Forward header value is less then the +"max_value" parameter value. It considers also the value +of the new inserted header (if locally added). + + +Retuning codes: + + +- *1 (true)* - header was found or set and +its value is strictly less than "max_value". +- *-1 (false)* - the header was found or +set and its value is greater or equal to "max_value". +- *-2 (false)* - header was not found or +not set. +- *-3 (false)* - error during processing. + + +The return code may be extensivly tested via script variable +"retcode" (or "$?"). + + +Meaning of the parameters is as follows: + + +- *max_value* (int) - value to check the +Max-Forward.value against (as less than). + + +```opensips title="is_maxfwd_lt usage" +... +# next hope is a gateway, so make no sens to +# forward if MF is 0 (after decrement) +if ( is_maxfwd_lt(1) ) { + sl_send_reply(483,"Too Many Hops"); + exit; +}; +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/maxfwd/doc/contributors.xml b/modules/maxfwd/doc/contributors.xml deleted file mode 100644 index 0cbf0c8f21e..00000000000 --- a/modules/maxfwd/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 46 - 30 - 864 - 484 - - - 2. - Liviu Chircu (@liviuchircu) - 12 - 10 - 17 - 44 - - - 3. - Jan Janak (@janakj) - 11 - 9 - 58 - 38 - - - 4. - Daniel-Constantin Mierla (@miconda) - 11 - 9 - 23 - 19 - - - 5. - Andrei Pelinescu-Onciul - 10 - 8 - 31 - 26 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 9 - 7 - 93 - 7 - - - 7. - Razvan Crainea (@razvancrainea) - 8 - 6 - 9 - 8 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 34 - 43 - - - 9. - Henning Westerholt (@henningw) - 4 - 2 - 3 - 3 - - - 10. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - -
-All remaining contributors: Aron Podrigal (@ar45), Konstantin Bokarius, Andreas Heise, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Nils Ohlmeier, Elena-Ramona Modroiu, Klaus Darilion, Alexandra Titoc, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Aron Podrigal (@ar45) - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Jan 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2002 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - 10. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Klaus Darilion, Andreas Heise, Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Nils Ohlmeier, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Klaus Darilion, Elena-Ramona Modroiu. -
- -
diff --git a/modules/maxfwd/doc/maxfwd.xml b/modules/maxfwd/doc/maxfwd.xml deleted file mode 100644 index 56eb9b5b1d4..00000000000 --- a/modules/maxfwd/doc/maxfwd.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - maxfwd Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/maxfwd/doc/maxfwd_admin.xml b/modules/maxfwd/doc/maxfwd_admin.xml deleted file mode 100644 index 91f797aefc0..00000000000 --- a/modules/maxfwd/doc/maxfwd_admin.xml +++ /dev/null @@ -1,204 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module implements all the operations regarding MaX-Forward header - field, like adding it (if not present) or decrementing and checking - the value of the existent one. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>max_limit</varname> (integer) - - Set an upper limit for the max-forward value in the outgoing requests. - If the header is present, the decremented value is not allowed to - exceed this max_limits - if it does, the header value will by - decreased to max_limit. - - Note: This check is done when calling the - mf_process_maxfwd_header() header. - - - The range of values stretches from 1 to 256, which is the maximum - MAX-FORWARDS value allowed by RFC 3261. - - - - Default value is 256. - - - - Set <varname>max_limit</varname> parameter - -... -modparam("maxfwd", "max_limit", 32) -... - - -
-
- - -
- Exported Functions -
- - <function moreinfo="none">mf_process_maxfwd_header(max_value)</function> - - - If no Max-Forward header is present in the received request, a header - will be added having the original value equal with - max_value. If a Max-Forward header is already present, - its value will be decremented (if not 0). - - Retuning codes: - - - 2 (true) - header was not found and - a new header was successfully added. - - - - 1 (true) - header was found and its - value was successfully decremented (had a non-0 value). - - - - -1 (false) - the header was found and - its value is 0 (cannot be decremented). - - - - -2 (false) - error during processing. - - - - - The return code may be extensivly tested via script variable - retcode (or $?). - - Meaning of the parameters is as follows: - - - max_value (int) - Value to be added if - there is no Max-Forwards header field in the message. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>mx_process_maxfwd_header</function> usage - -... -# initial sanity checks -- messages with -# max_forwards==0, or excessively long requests -if (!mf_process_maxfwd_header(10) && $retcode==-1) { - sl_send_reply(483,"Too Many Hops"); - exit; -}; -... - - -
- -
- - <function moreinfo="none">is_maxfwd_lt(max_value)</function> - - - Checks if the Max-Forward header value is less then the - max_value parameter value. It considers also the value - of the new inserted header (if locally added). - - Retuning codes: - - - 1 (true) - header was found or set and - its value is strictly less than max_value. - - - - -1 (false) - the header was found or - set and its value is greater or equal to max_value. - - - - -2 (false) - header was not found or - not set. - - - - -3 (false) - error during processing. - - - - - The return code may be extensivly tested via script variable - retcode (or $?). - - Meaning of the parameters is as follows: - - - max_value (int) - value to check the - Max-Forward.value against (as less than). - - - - - <function>is_maxfwd_lt</function> usage - -... -# next hope is a gateway, so make no sens to -# forward if MF is 0 (after decrement) -if ( is_maxfwd_lt(1) ) { - sl_send_reply(483,"Too Many Hops"); - exit; -}; -... - - -
- -
-
- diff --git a/modules/media_exchange/README b/modules/media_exchange/README deleted file mode 100644 index 005e3f1266e..00000000000 --- a/modules/media_exchange/README +++ /dev/null @@ -1,593 +0,0 @@ -Media Exchange Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Functions - - 1.3.1. media_fork_to_uri(URI[, leg][, headers][, - medianum][, instance]) - - 1.3.2. media_fork_from_call(callid[, leg][, - medianum][, instance]) - - 1.3.3. media_fork_pause([leg][, medianum][, - instance]) - - 1.3.4. media_fork_resume([leg][, medianum][, - instance]) - - 1.3.5. media_exchange_from_uri(URI[, leg][, body][, - headers][, nohold]) - - 1.3.6. media_exchange_to_call(callid[, leg][, - nohold]) - - 1.3.7. media_terminate([leg][, nohold][, instance]) - 1.3.8. media_handle_indialog() - - 1.4. Exported MI Functions - - 1.4.1. media_fork_from_call_to_uri - 1.4.2. media_exchange_from_call_to_uri - 1.4.3. media_exchange_from_call_to_uri_body - 1.4.4. media_terminate - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Use media_fork_to_uri() function to fork media to a Media - Server - - 1.2. Use media_fork_from_call() function to fork all media - streams of a call - - 1.3. Use media_fork_from_call() function to fork only the first - caller's stream - - 1.4. Use media_fork_pause() function to temporarily stop the - entire media stream of the call - - 1.5. Use media_fork_resume() function to resume a forking - previously stopped - - 1.6. Use media_exchange_from_uri() function to fetch media from - a Media Server's call - - 1.7. Use media_exchange_to_call() function to make an - announcement - - 1.8. Use media_terminate() function to terminate an - announcement - - 1.9. Use media_terminate() function to terminate an - announcement - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides the means to exchange media SDP between - different SIP proxied calls, and calls started or received from - a Media Server. The module itself does not have any media - capabilities, it simply exposes primitives to exchange the SDP - body between two or more different calls. - - The module can both originate calls, pushing an existing SDP to - a media server, to playback, or simply record an existing RTP, - as well as take the SDP of a new call and inject the SDP into - an existing, proxied sip call. In order to manipulate the new - calls, either generated, or terminated, the module behaves as a - back-to-back user agent with the aim of the OpenSIPS B2B - entities module. - - In terms of the SDP media exchanged, the module can have two - different modes: - * Two way Media - in this mode, the media of a new call will - be pushed towards one of the legs of an existing call. This - will result in a party of the call talking with the Media - Server. By default, the other participant of the call will - be put on hold, but this behavior can be tuned when the new - leg is originated. - * Fork Media - the new B2B call, either originated or - terminated, will just have a copy of the RTP forked by the - media proxy engine. In this mode, the proxied call should - have had the RTP relay engaged path before the forked call - starts. One can fork only one media leg, or both legs. - NOTE: RTPProxy currently does not support stopping media - streaming, therefore if the streaming call terminates, - RTPProxy will continue streaming, even if there is no one - listening on the other end. - - This module can provide different functionalities and can be - used in various use cases, such as: - * Call Recording - similar to the OpenSIPS SIPREC module, it - can be used to fork the RTP media to a new SIP destination, - but without the SIPREC payload. - * Call Listening - one might want to call into OpenSIPS and - start listening an existing call. - * Call Announcements - inject an announcement from a Media - Server to the participants of an ongoing call. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction module. - * Dialog - Dialog module for keeping track of the proxied - calls. - * RTP Relay - optional, when the initial call either uses RTP - Relay, or when using the media forking mode. - * B2B_ENTITIES - Back-2-Back module used form manipulating - calls with the Media Server. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Functions - -1.3.1. media_fork_to_uri(URI[, leg][, headers][, medianum][, -instance]) - - Behaves as a B2B user agent client to initiate a call to a SIP - URI and then stream the media to the SDP received in the 200 OK - response. - - Can be called multiple times, and will create a new call for - each invocation. The generated calls can be identified using - the instance parameter. - - Parameters: - * URI (string) - destination where to push the current call's - media - * leg (string, optional) - the leg that will be streamed. - Possible values are caller, callee and both. If missing, - the direction of the indialog request is used. - * headers (string, optional) - optional headers added to the - generated request. - * medianum (integer, optional) - the media stream that will - be forked within the call. First index is 0. If missing, - all media streams of that leg(s) are streamed. - * instance (string, optional) - a unique name for identifying - the forking instance. If missing, the default name is - assumed. - - This function can be used from any route. - - Example 1.1. Use media_fork_to_uri() function to fork media to - a Media Server -... -if (!has_totag() && is_method("INVITE")) - media_fork_to_uri("sip:record@127.0.0.1:5080"); -... - -1.3.2. media_fork_from_call(callid[, leg][, medianum][, instance]) - - Starts streaming the media of an existing proxied call, - identified by the callid parameter to the SDP in the request's - body. - - Can be called multiple times, and will accept a new call for - each invocation. The calls can be identified using the instance - parameter. - - Parameters: - * callid (string) - the identifier of the callid to - stream/fork media from - * leg (string, optional) - the leg that will be streamed. - Possible values are caller, callee and both. If missing, - both legs will be streamed. - * medianum (integer, optional) - the media stream that will - be forked within the call. First index is 0. If missing, - all media streams of that leg(s) are streamed, as long as - the body has enough streams. - Note: RTPProxy does not do any media mixing, therefore you - need to make sure that the INVITE has enough SDP streams to - handle all the media streams selected to fork. - * instance (string, optional) - a unique name for identifying - the forking instance. If missing, the default name is - assumed. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - NOTE: the request of this call is completely handled by the B2B - engine. Therefore, after running this function, please make - sure you do not relay the message further, otherwise you will - run into an unexpected behavior. Best thing to do is to exit - the processing after running the function. - - Example 1.2. Use media_fork_from_call() function to fork all - media streams of a call -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_fork_from_call($hdr(X-CallID)); -... - - Example 1.3. Use media_fork_from_call() function to fork only - the first caller's stream -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_fork_from_call($hdr(X-CallID), "caller", 0); -... - -1.3.3. media_fork_pause([leg][, medianum][, instance]) - - Pauses an existing RTP media streaming session. This function - does not terminate the forking call, but only stops sending the - RTP. It also re-invites the Media Server to inform about the - change. - - Parameters: - * leg (string, optional) - the leg that will be paused. - Possible values are caller, callee and both. If missing, - all ongoing media sessions will be paused. - * medianum (integer, optional) - the media stream to be - paused. First index is 0. If missing, all ongoing media - streams associated to the selected leg will be paused. - * instance (string, optional) - the forking instance to be - paused. If missing, all instances are paused. - - This function can be used from any route. - - Example 1.4. Use media_fork_pause() function to temporarily - stop the entire media stream of the call -... -if (has_totag() && is_method("INVITE")) - media_fork_pause(); -... - -1.3.4. media_fork_resume([leg][, medianum][, instance]) - - Resumes the RTP media stream of an existing session/call. This - function relies on the fact that a media fork session has been - previously started. - - Parameters: - * leg (string, optional) - the leg that will be resumed. - Possible values are caller, callee and both. If missing, - all existing media legs that are stopped will be started. - * medianum (integer, optional) - the media stream to be - paused. First index is 0. If missing, all ongoing media - streams associated to the selected leg will be paused. - * instance (string, optional) - the forking instance to be - resumed. If missing, all instances are resumed. - - This function can be used from any route. - - Example 1.5. Use media_fork_resume() function to resume a - forking previously stopped -... -if (has_totag() && is_method("INVITE")) - media_fork_resume(); -... - -1.3.5. media_exchange_from_uri(URI[, leg][, body][, headers][, -nohold]) - - Originates a call to the specified URI. The SDP in the response - is fetched and pushed towards one of the call's legs, resulting - in two way audio between the participant of the ongoing call, - and the new call. By default, the other participant leg is put - on hold. - - Can be called for an in-dialog request, such as a re-INVITE - (for example when putting an entity on hold), or for an INFO - request (triggered for example by a DTMF). - - Parameters: - * URI (string) - destination used to originate the new call. - * leg (string, optional) - the leg where the new media SDP - will be pushed. Possible values are caller and callee. If - missing, the module considers it is an hold re-INVITE, and - exchanges the media SDP of the other leg. - * body (string, optional) - custom body used for the - generated INVITE. If missing, the body stored in the dialog - associated with the involved leg will be used. - * headers (string, optional) - optional headers added to the - generated request. - * nohold (integer, optional) - if set to true, the other - participant will not be put on hold. This is useful when a - new call will be generated for the other leg as well. - - This function can be used from any route. - - Example 1.6. Use media_exchange_from_uri() function to fetch - media from a Media Server's call -... -if (has_totag() && is_method("INVITE") && is_audio_on_hold()) - media_exchange_from_uri("sip:moh@127.0.0.1:5080"); -... - -1.3.6. media_exchange_to_call(callid[, leg][, nohold]) - - Pushes the SDP of a new call received in an existing proxied - call, resulting in two-way audio between a Media Server that - originated the call, and the existing participant of the - ongoing proxied call. - - Parameters: - * callid (string) - the identifier of the callid to exchange - media. - * leg (string) - the leg that will be streamed. Possible - values are caller and callee. - * nohold (integer, optional) - if set to true, the other - participant will not be put on hold. This is useful when a - new call will be generated for the other leg as well. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - NOTE: the request of this call is completely handled by the B2B - engine. Therefore, after running this function, please make - sure you do not relay the message further, otherwise you will - run into an unexpected behavior. Best thing to do is to exit - the processing after running the function. - - Example 1.7. Use media_exchange_to_call() function to make an - announcement -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_exchange_to_call($hdr(X-CallID), "caller"); -... - -1.3.7. media_terminate([leg][, nohold][, instance]) - - Terminates an ongoing media session exchange, whether the media - is only streamed, or two way audio is flowing. If the - participant leg is involved in a different media exchange, the - current leg is put on hold. - - Parameters: - * leg (string, optional) - the leg to terminate the media - exchange. Possible values are caller and callee. If - missing, the direction of the indialog request is used. - * nohold (integer, optional) - if set to true, and the other - participant is involved in a different media exchange, the - current leg is no longer put on hold. Note: if the request - that terminates the media exchange is a re-INVITE within - the dialog, this function will not un-hold the other leg, - as the re-INVITE itself should be relayed further to do - that. This behavior can be changed by explicitly setting - the nohold parameter - * instance (string, optional) - should only be used when - terminating a forking instance, and represents the instance - to terminate. It must be ommitted when terminating an - streaming session. However, for fallback compatibility, if - the parameter is missing, and no streaming session is - found, the command terminates the default forking instance, - if it exists. - - This function can be used from any route. - - Example 1.8. Use media_terminate() function to terminate an - announcement -... -if (has_totag() && is_method("INVITE") && !is_audio_on_hold()) - media_terminate(); -... - -1.3.8. media_handle_indialog() - - Searches for an existing media session started for any leg, and - if there is ongoing session found, it performs additional logic - for handling that request. For example, if media has been - started in forking mode, and the INVITE is for activating - on-hold, then the function will also pause the forked stream. - - Depending on the return code of this function, one has to - perform additional logic in the script. Possible return codes - are: - * 1 - indicates that the message has been handled, but - there's no additional tasks to be performed in the script. - * -1 - indicates that there is no ongoing media exchange or - fork happening for that call, or that there was no - additional logic to do for that request. - * -2 - indicates that all additional handling of the request - was performed, and that the request should not be forwarded - to the user agent, but instead it should be dropped. - * -3 - signals an internal error. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - ONREPLY_ROUTE. - - Example 1.9. Use media_terminate() function to terminate an - announcement -... -if (has_totag() && loose_route()) { - # handling sequential - media_handle_indialog(); - switch ($rc) { - case -2: - drop; - case -1: - xlog("no ongoing media session for $ci!\n"); - case 1: - break; -} -... - -1.4. Exported MI Functions - -1.4.1. media_fork_from_call_to_uri - - MI command that has the same behavior as media_fork_to_uri(), - only that the triggering is not script driven, but exterior - driven. Useful for starting listening a call. - - Name: media_fork_from_call_to_uri - - Parameters - * callid (string) - the callid of the dialog that will have - its RTP streamed to the new call towards the Media Server - * uri (string) - the destination URI of the new call - * leg (string, optional) - indicates the participant leg that - will have its RTP streamed in the new call. Possible values - are “caller”, “callee” or “both”. If missing, both media - streams are forked - * headers (string, optional) - extra headers to add to the - outgoing request - * medianum (integer, optional) - the media stream that will - be forked within the call. First index is 0. If missing, - all media streams of that leg(s) are streamed. - * instance (string, optional) - the unique name of the - forking instance. If missing, the default name is assumed. - - MI FIFO Command Format: -# start streaming a callid to record media server -opensips-cli -x mi media_fork_from_call_to_uri \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - uri=sip:record@127.0.0.1:5080 - -1.4.2. media_exchange_from_call_to_uri - - MI command that has the same behavior as - media_exchange_from_uri(), only that the triggering is not - script driven, but exterior driven. Useful for injecting media - announcements during a call. - - Name: media_exchange_from_call_to_uri - - Parameters - * callid (string) - the callid of the dialog that will have - it's leg mixed with the new call to the Media Server - * uri (string) - the destination URI of the new call - * leg (string) - indicates the participant that will have its - media pined into the new call. Possible values are “caller” - and “callee”. - * headers (string, optional) - extra headers to add to the - outgoing request - * nohold (integer, optional) - if set to a non-zero value, - the module avoids putting the other participant on hold - when the media exchanging starts - - MI FIFO Command Format: -# start playing back an annoucement to caller -opensips-cli -x mi media_exchange_from_call_to_uri \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - uri=sip:announcement@127.0.0.1:5080 \ - leg=caller - -1.4.3. media_exchange_from_call_to_uri_body - - MI command that does the same thing as the - media_exchange_from_call_to_uri MI function, but also allows - you to specify a custom body in the outgoing request. The body - has to be specified in the mandatory body parameter, all the - other parameters being the same as the ones of - media_exchange_from_call_to_uri. - -1.4.4. media_terminate - - MI command to terminate an ongoing media exchange. - - Name: media_terminate - - Parameters - * callid (string) - the callid of the dialog that will have - the media exchange terminated. - * leg (string, optional) - the leg for whom to terminate the - media exchange. Accepted values are caller, callee and - both. If missing, all media sessions are terminated. - * nohold (integer, optional) - if specified and has a - non-zero value, the leg that is being terminated is not put - on hold if the other participant still has an ongoing media - session. - * instance (string, optional) - should only be used when - terminating a forking instance, and represents the instance - to terminate. It must be ommitted when terminating an - streaming session. However, for fallback compatibility, if - the parameter is missing, and no streaming session is - found, the command terminates the default forking instance, - if it exists. - - MI FIFO Command Format: -# terminate a caller announcement -opensips-cli -x mi media_terminate \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - leg=caller - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 170 71 6539 2618 - 2. Vlad Patrascu (@rvlad-patrascu) 6 4 19 11 - 3. Maksym Sobolyev (@sobomax) 4 2 12 12 - 4. Alexandra Titoc 4 2 6 4 - 5. Liviu Chircu (@liviuchircu) 4 2 6 3 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 4 4 - 7. Norman Brandinger (@NormB) 3 1 1 1 - 8. Zero King (@l2dy) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Feb 2020 - May 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Jul 2022 - Jul 2024 - 4. Norman Brandinger (@NormB) Jun 2024 - Jun 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 6. Vlad Patrascu (@rvlad-patrascu) Mar 2020 - Jul 2021 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2021 - Apr 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2020 www.opensips-solutions.com diff --git a/modules/media_exchange/README.md b/modules/media_exchange/README.md new file mode 100644 index 00000000000..2e896446bae --- /dev/null +++ b/modules/media_exchange/README.md @@ -0,0 +1,598 @@ +--- +title: "Media Exchange Module" +description: "This module provides the means to exchange media SDP between different SIP proxied calls, and calls started or received from a Media Server." +--- + +## Admin Guide + + +### Overview + + +This module provides the means to exchange media SDP between different +SIP proxied calls, and calls started or received from a Media Server. +The module itself does not have any media capabilities, it simply +exposes primitives to exchange the SDP body between two or more different +calls. + + +The module can both originate calls, pushing an existing SDP to a +media server, to playback, or simply record an existing RTP, as well +as take the SDP of a new call and inject the SDP into an existing, +proxied sip call. In order to manipulate the new calls, either generated, +or terminated, the module behaves as a back-to-back user agent with the +aim of the [OpenSIPS B2B entities module](../b2b_entities). + + +In terms of the SDP media exchanged, the module can have two different +modes: + + +- *Two way Media* - in this mode, the media of a new +call will be pushed towards one of the legs of an existing call. This +will result in a party of the call talking with the Media Server. By +default, the other participant of the call will be put on hold, but this +behavior can be tuned when the new leg is originated. +- *Fork Media* - the new B2B call, either originated +or terminated, will just have a copy of the RTP forked by the media +proxy engine. In this mode, the proxied call should have had the RTP +relay engaged path before the forked call starts. One can fork only one +media leg, or both legs. *NOTE:* RTPProxy currently +does not support stopping media streaming, therefore if the streaming +call terminates, RTPProxy will continue streaming, even if there is no +one listening on the other end. + + +This module can provide different functionalities and can be used in various +use cases, such as: + + +- *Call Recording* - similar to the [OpenSIPS SIPREC](../siprec) module, it can be used to fork the +RTP media to a new SIP destination, but without the SIPREC payload. +- *Call Listening* - one might want to call into +OpenSIPS and start listening an existing call. +- *Call Announcements* - inject an announcement from a +Media Server to the participants of an ongoing call. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM* - Transaction module. +- *Dialog* - Dialog module for keeping track of the proxied calls. +- *RTP Relay* - optional, when the initial +call either uses RTP Relay, or when using the media forking mode. +- *B2B_ENTITIES* - Back-2-Back module used form +manipulating calls with the Media Server. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Functions + + +#### media_fork_to_uri(URI[, leg][, headers][, medianum][, instance]) + + +Behaves as a B2B user agent client to initiate a call to a SIP +URI and then stream the media to the SDP received in the 200 +OK response. + + +Can be called multiple times, and will create a new call for +each invocation. The generated calls can be identified using +the *instance* parameter. + + +Parameters: + + +- *URI* (string) - destination where to push +the current call's media +- *leg* (string, optional) - the leg that will +be streamed. Possible values are *caller*, +*callee* and *both*. If +missing, the direction of the indialog request is used. +- *headers* (string, optional) - optional +headers added to the generated request. +- *medianum* (integer, optional) - the media +stream that will be forked within the call. First index is 0. +If missing, all media streams of that leg(s) are streamed. +- *instance* (string, optional) - a unique name +for identifying the forking instance. If missing, the +*default* name is assumed. + + +This function can be used from any route. + + +```opensips title="Use media_fork_to_uri() function to fork media to a Media Server" +... +if (!has_totag() && is_method("INVITE")) + media_fork_to_uri("sip:record@127.0.0.1:5080"); +... + +``` + + +#### media_fork_from_call(callid[, leg][, medianum][, instance]) + + +Starts streaming the media of an existing proxied call, identified +by the *callid* parameter to the SDP in the +request's body. + + +Can be called multiple times, and will accept a new call for +each invocation. The calls can be identified using +the *instance* parameter. + + +Parameters: + + +- *callid* (string) - the identifier of the callid +to stream/fork media from +- *leg* (string, optional) - the leg that will +be streamed. Possible values are *caller*, +*callee* and *both*. If +missing, both legs will be streamed. +- *medianum* (integer, optional) - the media +stream that will be forked within the call. First index is 0. +If missing, all media streams of that leg(s) are streamed, +as long as the body has enough streams. +*Note:* RTPProxy does not do any media mixing, +therefore you need to make sure that the INVITE has enough SDP +streams to handle all the media streams selected to fork. +- *instance* (string, optional) - a unique name +for identifying the forking instance. If missing, the +*default* name is assumed. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +> [!NOTE] +> The request of this call is completely +> handled by the B2B engine. Therefore, after running this function, +> please make sure you do not relay the message further, otherwise +> you will run into an unexpected behavior. Best thing to do is to +> exit the processing after running the function. + + +```opensips title="Use media_fork_from_call() function to fork all media streams of a call" +... +if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) + media_fork_from_call($hdr(X-CallID)); +... + +``` + + +```opensips title="Use media_fork_from_call() function to fork only the first caller's stream" +... +if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) + media_fork_from_call($hdr(X-CallID), "caller", 0); +... + +``` + + +#### media_fork_pause([leg][, medianum][, instance]) + + +Pauses an existing RTP media streaming session. This function does +not terminate the forking call, but only stops sending the RTP. +It also re-invites the Media Server to inform about the change. + + +Parameters: + + +- *leg* (string, optional) - the leg that will +be paused. Possible values are *caller*, +*callee* and *both*. If +missing, all ongoing media sessions will be paused. +- *medianum* (integer, optional) - the media +stream to be paused. First index is 0. +If missing, all ongoing media streams associated to the +selected leg will be paused. +- *instance* (string, optional) - the forking +instance to be paused. If missing, all instances are paused. + + +This function can be used from any route. + + +```opensips title="Use media_fork_pause() function to temporarily stop the entire media stream of the call" +... +if (has_totag() && is_method("INVITE")) + media_fork_pause(); +... + +``` + + +#### media_fork_resume([leg][, medianum][, instance]) + + +Resumes the RTP media stream of an existing session/call. This function +relies on the fact that a media fork session has been previously started. + + +Parameters: + + +- *leg* (string, optional) - the leg that will +be resumed. Possible values are *caller*, +*callee* and *both*. If +missing, all existing media legs that are stopped will be started. +- *medianum* (integer, optional) - the media +stream to be paused. First index is 0. +If missing, all ongoing media streams associated to the +selected leg will be paused. +- *instance* (string, optional) - the forking +instance to be resumed. If missing, all instances are resumed. + + +This function can be used from any route. + + +```opensips title="Use media_fork_resume() function to resume a forking previously stopped" +... +if (has_totag() && is_method("INVITE")) + media_fork_resume(); +... + +``` + + +#### media_exchange_from_uri(URI[, leg][, body][, headers][, nohold]) + + +Originates a call to the specified URI. The SDP in the response is +fetched and pushed towards one of the call's legs, resulting in two +way audio between the participant of the ongoing call, and the new +call. By default, the other participant leg is put on hold. + + +Can be called for an in-dialog request, such as a re-INVITE (for +example when putting an entity on hold), or for an INFO request +(triggered for example by a DTMF). + + +Parameters: + + +- *URI* (string) - destination used to +originate the new call. +- *leg* (string, optional) - the leg where the +new media SDP will be pushed. Possible values are +*caller* and *callee*. +If missing, the module considers it is an hold re-INVITE, +and exchanges the media SDP of the other leg. +- *body* (string, optional) - custom body used +for the generated INVITE. If missing, the body stored in the +dialog associated with the involved leg will be used. +- *headers* (string, optional) - optional +headers added to the generated request. +- *nohold* (integer, optional) - if set to true, +the other participant will not be put on hold. This is useful +when a new call will be generated for the other leg as well. + + +This function can be used from any route. + + +```opensips title="Use media_exchange_from_uri() function to fetch media from a Media Server's call" +... +if (has_totag() && is_method("INVITE") && is_audio_on_hold()) + media_exchange_from_uri("sip:moh@127.0.0.1:5080"); +... + +``` + + +#### media_exchange_to_call(callid[, leg][, nohold]) + + +Pushes the SDP of a new call received in an existing proxied +call, resulting in two-way audio between a Media Server that +originated the call, and the existing participant of the ongoing +proxied call. + + +Parameters: + + +- *callid* (string) - the identifier of the callid +to exchange media. +- *leg* (string) - the leg that will +be streamed. Possible values are *caller* +and *callee*. +- *nohold* (integer, optional) - if set to true, +the other participant will not be put on hold. This is useful +when a new call will be generated for the other leg as well. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +> [!NOTE] +> The request of this call is completely +> handled by the B2B engine. Therefore, after running this function, +> please make sure you do not relay the message further, otherwise +> you will run into an unexpected behavior. Best thing to do is to +> exit the processing after running the function. + + +```opensips title="Use media_exchange_to_call() function to make an announcement" +... +if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) + media_exchange_to_call($hdr(X-CallID), "caller"); +... + +``` + + +#### media_terminate([leg][, nohold][, instance]) + + +Terminates an ongoing media session exchange, whether the media is +only streamed, or two way audio is flowing. If the participant leg +is involved in a different media exchange, the current leg is put on +hold. + + +Parameters: + + +- *leg* (string, optional) - the leg to terminate +the media exchange. Possible values are +*caller* and *callee*. +If missing, the direction of the indialog request is used. +- *nohold* (integer, optional) - if set to true, +and the other participant is involved in a different media +exchange, the current leg is no longer put on hold. +*Note:* if the request that terminates +the media exchange is a re-INVITE within the dialog, this +function will not un-hold the other leg, as the re-INVITE +itself should be relayed further to do that. This behavior +can be changed by explicitly setting the +*nohold* parameter +- *instance* (string, optional) - should only be +used when terminating a forking instance, and represents the +instance to terminate. It must be ommitted when terminating an +streaming session. However, for fallback compatibility, if the +parameter is missing, and no streaming session is found, the +command terminates the *default* forking +instance, if it exists. + + +This function can be used from any route. + + +```opensips title="Use media_terminate() function to terminate an announcement" +... +if (has_totag() && is_method("INVITE") && !is_audio_on_hold()) + media_terminate(); +... + +``` + + +#### media_handle_indialog() + + +Searches for an existing media session started for any leg, +and if there is ongoing session found, it performs additional +logic for handling that request. For example, if media has been +started in forking mode, and the INVITE is for activating on-hold, +then the function will also pause the forked stream. + + +Depending on the return code of this function, one has to +perform additional logic in the script. Possible return codes are: + + +- *1* - indicates that the message has been +handled, but there's no additional tasks to be performed in +the script. +- *-1* - indicates that there is no ongoing +media exchange or fork happening for that call, or that there +was no additional logic to do for that request. +- *-2* - indicates that all additional +handling of the request was performed, and that the request +should not be forwarded to the user agent, but instead it +should be dropped. +- *-3* - signals an internal error. + + +This function can be used from REQUEST_ROUTE, +BRANCH_ROUTE and ONREPLY_ROUTE. + + +```opensips title="Use media_terminate() function to terminate an announcement" +... +if (has_totag() && loose_route()) { + # handling sequential + media_handle_indialog(); + switch ($rc) { + case -2: + drop; + case -1: + xlog("no ongoing media session for $ci!\n"); + case 1: + break; +} +... + +``` + + +### Exported MI Functions + + +#### media_fork_from_call_to_uri + + +MI command that has the same behavior as +[media fork to uri](#func_media_fork_to_uri), only that the triggering +is not script driven, but exterior driven. Useful for starting +listening a call. + + +Name: *media_fork_from_call_to_uri* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that will have its RTP streamed to the new call +towards the Media Server +- *uri* (string) - the destination URI of +the new call +- *leg* (string, optional) - indicates the +participant leg that will have its RTP streamed in the +new call. Possible values are "caller", +"callee" or "both". If missing, +both media streams are forked +- *headers* (string, optional) - extra +headers to add to the outgoing request +- *medianum* (integer, optional) - the media +stream that will be forked within the call. First index is 0. +If missing, all media streams of that leg(s) are streamed. +- *instance* (string, optional) - the unique +name of the forking instance. If missing, the +*default* name is assumed. + + +MI FIFO Command Format: + + +```bash +# start streaming a callid to record media server +opensips-cli -x mi media_fork_from_call_to_uri \ + callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ + uri=sip:record@127.0.0.1:5080 + +``` + + +#### media_exchange_from_call_to_uri + + +MI command that has the same behavior as +[media exchange from uri](#func_media_exchange_from_uri), only that the triggering +is not script driven, but exterior driven. Useful for injecting media +announcements during a call. + + +Name: *media_exchange_from_call_to_uri* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that will have it's leg mixed with the new call +to the Media Server +- *uri* (string) - the destination URI of +the new call +- *leg* (string) - indicates the participant +that will have its media pined into the new call. Possible +values are "caller" and "callee". +- *headers* (string, optional) - extra headers +to add to the outgoing request +- *nohold* (integer, optional) - if set to a +non-zero value, the module avoids putting the other participant +on hold when the media exchanging starts + + +MI FIFO Command Format: + + +```bash +# start playing back an annoucement to caller +opensips-cli -x mi media_exchange_from_call_to_uri \ + callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ + uri=sip:announcement@127.0.0.1:5080 \ + leg=caller + +``` + + +#### media_exchange_from_call_to_uri_body + + +MI command that does the same thing as the +[mi media exchange from call to uri](#mi_media_exchange_from_call_to_uri) MI function, but +also allows you to specify a custom body in the outgoing request. +The body has to be specified in the mandatory *body* +parameter, all the other parameters being the same as the ones of +[mi media exchange from call to uri](#mi_media_exchange_from_call_to_uri). + + +#### media_terminate + + +MI command to terminate an ongoing media exchange. + + +Name: *media_terminate* + + +Parameters + + +- *callid* (string) - the callid of the +dialog that will have the media exchange terminated. +- *leg* (string, optional) - the leg for +whom to terminate the media exchange. Accepted values are +*caller*, *callee* +and *both*. If missing, all media +sessions are terminated. +- *nohold* (integer, optional) - if specified +and has a non-zero value, the leg that is being terminated +is not put on hold if the other participant still has an +ongoing media session. +- *instance* (string, optional) - should only be +used when terminating a forking instance, and represents the +instance to terminate. It must be ommitted when terminating an +streaming session. However, for fallback compatibility, if the +parameter is missing, and no streaming session is found, the +command terminates the *default* forking +instance, if it exists. + + +MI FIFO Command Format: + + +```bash +# terminate a caller announcement +opensips-cli -x mi media_terminate \ + callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ + leg=caller +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/media_exchange/doc/contributors.xml b/modules/media_exchange/doc/contributors.xml deleted file mode 100644 index 3b3ac0959b5..00000000000 --- a/modules/media_exchange/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 170 - 71 - 6539 - 2618 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 19 - 11 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 12 - 12 - - - 4. - Alexandra Titoc - 4 - 2 - 6 - 4 - - - 5. - Liviu Chircu (@liviuchircu) - 4 - 2 - 6 - 3 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 4 - 4 - - - 7. - Norman Brandinger (@NormB) - 3 - 1 - 1 - 1 - - - 8. - Zero King (@l2dy) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Feb 2020 - May 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Jul 2022 - Jul 2024 - - - 4. - Norman Brandinger (@NormB) - Jun 2024 - Jun 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - Mar 2020 - Jul 2021 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2021 - Apr 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/media_exchange/doc/media_exchange.xml b/modules/media_exchange/doc/media_exchange.xml deleted file mode 100644 index 5652aaf75bf..00000000000 --- a/modules/media_exchange/doc/media_exchange.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Media Exchange Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2020 &osipssol; - diff --git a/modules/media_exchange/doc/media_exchange_admin.xml b/modules/media_exchange/doc/media_exchange_admin.xml deleted file mode 100644 index 2330bb69637..00000000000 --- a/modules/media_exchange/doc/media_exchange_admin.xml +++ /dev/null @@ -1,755 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides the means to exchange media SDP between different - SIP proxied calls, and calls started or received from a Media Server. - The module itself does not have any media capabilities, it simply - exposes primitives to exchange the SDP body between two or more different - calls. - - - The module can both originate calls, pushing an existing SDP to a - media server, to playback, or simply record an existing RTP, as well - as take the SDP of a new call and inject the SDP into an existing, - proxied sip call. In order to manipulate the new calls, either generated, - or terminated, the module behaves as a back-to-back user agent with the - aim of the &osips; B2B entities module. - - - In terms of the SDP media exchanged, the module can have two different - modes: - - - - Two way Media - in this mode, the media of a new - call will be pushed towards one of the legs of an existing call. This - will result in a party of the call talking with the Media Server. By - default, the other participant of the call will be put on hold, but this - behavior can be tuned when the new leg is originated. - - - - - Fork Media - the new B2B call, either originated - or terminated, will just have a copy of the RTP forked by the media - proxy engine. In this mode, the proxied call should have had the RTP - relay engaged path before the forked call starts. One can fork only one - media leg, or both legs. NOTE: RTPProxy currently - does not support stopping media streaming, therefore if the streaming - call terminates, RTPProxy will continue streaming, even if there is no - one listening on the other end. - - - - - - This module can provide different functionalities and can be used in various - use cases, such as: - - - - Call Recording - similar to the &osips; SIPREC module, it can be used to fork the - RTP media to a new SIP destination, but without the SIPREC payload. - - - - - Call Listening - one might want to call into - &osips; and start listening an existing call. - - - - - Call Announcements - inject an announcement from a - Media Server to the participants of an ongoing call. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction module. - - - - - Dialog - Dialog module for keeping track of the proxied calls. - - - - - RTP Relay - optional, when the initial - call either uses RTP Relay, or when using the media forking mode. - - - - - B2B_ENTITIES - Back-2-Back module used form - manipulating calls with the Media Server. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">media_fork_to_uri(URI[, leg][, headers][, medianum][, instance])</function> - - - Behaves as a B2B user agent client to initiate a call to a SIP - URI and then stream the media to the SDP received in the 200 - OK response. - - - Can be called multiple times, and will create a new call for - each invocation. The generated calls can be identified using - the instance parameter. - - - Parameters: - - - URI (string) - destination where to push - the current call's media - - - leg (string, optional) - the leg that will - be streamed. Possible values are caller, - callee and both. If - missing, the direction of the indialog request is used. - - - headers (string, optional) - optional - headers added to the generated request. - - - medianum (integer, optional) - the media - stream that will be forked within the call. First index is 0. - If missing, all media streams of that leg(s) are streamed. - - - instance (string, optional) - a unique name - for identifying the forking instance. If missing, the - default name is assumed. - - - - - This function can be used from any route. - - - Use <function>media_fork_to_uri()</function> function to fork - media to a Media Server - -... -if (!has_totag() && is_method("INVITE")) - media_fork_to_uri("sip:record@127.0.0.1:5080"); -... - - -
-
- - <function moreinfo="none">media_fork_from_call(callid[, leg][, medianum][, instance])</function> - - - Starts streaming the media of an existing proxied call, identified - by the callid parameter to the SDP in the - request's body. - - - Can be called multiple times, and will accept a new call for - each invocation. The calls can be identified using - the instance parameter. - - - Parameters: - - - callid (string) - the identifier of the callid - to stream/fork media from - - - leg (string, optional) - the leg that will - be streamed. Possible values are caller, - callee and both. If - missing, both legs will be streamed. - - - medianum (integer, optional) - the media - stream that will be forked within the call. First index is 0. - If missing, all media streams of that leg(s) are streamed, - as long as the body has enough streams. - - Note: RTPProxy does not do any media mixing, - therefore you need to make sure that the INVITE has enough SDP - streams to handle all the media streams selected to fork. - - - - instance (string, optional) - a unique name - for identifying the forking instance. If missing, the - default name is assumed. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - NOTE: the request of this call is completely - handled by the B2B engine. Therefore, after running this function, - please make sure you do not relay the message further, otherwise - you will run into an unexpected behavior. Best thing to do is to - exit the processing after running the function. - - - Use <function>media_fork_from_call()</function> function to fork - all media streams of a call - -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_fork_from_call($hdr(X-CallID)); -... - - - - Use <function>media_fork_from_call()</function> function to fork - only the first caller's stream - -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_fork_from_call($hdr(X-CallID), "caller", 0); -... - - -
-
- - <function moreinfo="none">media_fork_pause([leg][, medianum][, instance])</function> - - - Pauses an existing RTP media streaming session. This function does - not terminate the forking call, but only stops sending the RTP. - It also re-invites the Media Server to inform about the change. - - - Parameters: - - - leg (string, optional) - the leg that will - be paused. Possible values are caller, - callee and both. If - missing, all ongoing media sessions will be paused. - - - medianum (integer, optional) - the media - stream to be paused. First index is 0. - If missing, all ongoing media streams associated to the - selected leg will be paused. - - - instance (string, optional) - the forking - instance to be paused. If missing, all instances are paused. - - - - - This function can be used from any route. - - - Use <function>media_fork_pause()</function> function to temporarily - stop the entire media stream of the call - -... -if (has_totag() && is_method("INVITE")) - media_fork_pause(); -... - - -
-
- - <function moreinfo="none">media_fork_resume([leg][, medianum][, instance])</function> - - - Resumes the RTP media stream of an existing session/call. This function - relies on the fact that a media fork session has been previously started. - - - Parameters: - - - leg (string, optional) - the leg that will - be resumed. Possible values are caller, - callee and both. If - missing, all existing media legs that are stopped will be started. - - - medianum (integer, optional) - the media - stream to be paused. First index is 0. - If missing, all ongoing media streams associated to the - selected leg will be paused. - - - instance (string, optional) - the forking - instance to be resumed. If missing, all instances are resumed. - - - - - This function can be used from any route. - - - Use <function>media_fork_resume()</function> function to resume - a forking previously stopped - -... -if (has_totag() && is_method("INVITE")) - media_fork_resume(); -... - - -
-
- - <function moreinfo="none">media_exchange_from_uri(URI[, leg][, body][, headers][, nohold])</function> - - - Originates a call to the specified URI. The SDP in the response is - fetched and pushed towards one of the call's legs, resulting in two - way audio between the participant of the ongoing call, and the new - call. By default, the other participant leg is put on hold. - - - Can be called for an in-dialog request, such as a re-INVITE (for - example when putting an entity on hold), or for an INFO request - (triggered for example by a DTMF). - - - Parameters: - - - URI (string) - destination used to - originate the new call. - - - leg (string, optional) - the leg where the - new media SDP will be pushed. Possible values are - caller and callee. - If missing, the module considers it is an hold re-INVITE, - and exchanges the media SDP of the other leg. - - - body (string, optional) - custom body used - for the generated INVITE. If missing, the body stored in the - dialog associated with the involved leg will be used. - - - headers (string, optional) - optional - headers added to the generated request. - - - nohold (integer, optional) - if set to true, - the other participant will not be put on hold. This is useful - when a new call will be generated for the other leg as well. - - - - - This function can be used from any route. - - - Use <function>media_exchange_from_uri()</function> function to - fetch media from a Media Server's call - -... -if (has_totag() && is_method("INVITE") && is_audio_on_hold()) - media_exchange_from_uri("sip:moh@127.0.0.1:5080"); -... - - -
-
- - <function moreinfo="none">media_exchange_to_call(callid[, leg][, nohold])</function> - - - Pushes the SDP of a new call received in an existing proxied - call, resulting in two-way audio between a Media Server that - originated the call, and the existing participant of the ongoing - proxied call. - - - Parameters: - - - callid (string) - the identifier of the callid - to exchange media. - - - leg (string) - the leg that will - be streamed. Possible values are caller - and callee. - - - nohold (integer, optional) - if set to true, - the other participant will not be put on hold. This is useful - when a new call will be generated for the other leg as well. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - NOTE: the request of this call is completely - handled by the B2B engine. Therefore, after running this function, - please make sure you do not relay the message further, otherwise - you will run into an unexpected behavior. Best thing to do is to - exit the processing after running the function. - - - Use <function>media_exchange_to_call()</function> function to make - an announcement - -... -if (!has_totag() && is_method("INVITE") && $hdr(X-CallID) != NULL) - media_exchange_to_call($hdr(X-CallID), "caller"); -... - - -
-
- - <function moreinfo="none">media_terminate([leg][, nohold][, instance])</function> - - - Terminates an ongoing media session exchange, whether the media is - only streamed, or two way audio is flowing. If the participant leg - is involved in a different media exchange, the current leg is put on - hold. - - - Parameters: - - - leg (string, optional) - the leg to terminate - the media exchange. Possible values are - caller and callee. - If missing, the direction of the indialog request is used. - - - nohold (integer, optional) - if set to true, - and the other participant is involved in a different media - exchange, the current leg is no longer put on hold. - Note: if the request that terminates - the media exchange is a re-INVITE within the dialog, this - function will not un-hold the other leg, as the re-INVITE - itself should be relayed further to do that. This behavior - can be changed by explicitly setting the - nohold parameter - - - instance (string, optional) - should only be - used when terminating a forking instance, and represents the - instance to terminate. It must be ommitted when terminating an - streaming session. However, for fallback compatibility, if the - parameter is missing, and no streaming session is found, the - command terminates the default forking - instance, if it exists. - - - - - This function can be used from any route. - - - Use <function>media_terminate()</function> function to - terminate an announcement - -... -if (has_totag() && is_method("INVITE") && !is_audio_on_hold()) - media_terminate(); -... - - -
- -
- - <function moreinfo="none">media_handle_indialog()</function> - - - Searches for an existing media session started for any leg, - and if there is ongoing session found, it performs additional - logic for handling that request. For example, if media has been - started in forking mode, and the INVITE is for activating on-hold, - then the function will also pause the forked stream. - - - Depending on the return code of this function, one has to - perform additional logic in the script. Possible return codes are: - - - 1 - indicates that the message has been - handled, but there's no additional tasks to be performed in - the script. - - - -1 - indicates that there is no ongoing - media exchange or fork happening for that call, or that there - was no additional logic to do for that request. - - - -2 - indicates that all additional - handling of the request was performed, and that the request - should not be forwarded to the user agent, but instead it - should be dropped. - - - -3 - signals an internal error. - - - - - This function can be used from REQUEST_ROUTE, - BRANCH_ROUTE and ONREPLY_ROUTE. - - - Use <function>media_terminate()</function> function to - terminate an announcement - -... -if (has_totag() && loose_route()) { - # handling sequential - media_handle_indialog(); - switch ($rc) { - case -2: - drop; - case -1: - xlog("no ongoing media session for $ci!\n"); - case 1: - break; -} -... - - -
-
- -
- Exported MI Functions - -
- - <function moreinfo="none">media_fork_from_call_to_uri</function> - - - MI command that has the same behavior as - , only that the triggering - is not script driven, but exterior driven. Useful for starting - listening a call. - - - Name: media_fork_from_call_to_uri - - Parameters - - - callid (string) - the callid of the - dialog that will have its RTP streamed to the new call - towards the Media Server - - - uri (string) - the destination URI of - the new call - - - leg (string, optional) - indicates the - participant leg that will have its RTP streamed in the - new call. Possible values are caller, - callee or both. If missing, - both media streams are forked - - - headers (string, optional) - extra - headers to add to the outgoing request - - - medianum (integer, optional) - the media - stream that will be forked within the call. First index is 0. - If missing, all media streams of that leg(s) are streamed. - - - instance (string, optional) - the unique - name of the forking instance. If missing, the - default name is assumed. - - - - MI FIFO Command Format: - - -# start streaming a callid to record media server -opensips-cli -x mi media_fork_from_call_to_uri \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - uri=sip:record@127.0.0.1:5080 - -
-
- - <function moreinfo="none">media_exchange_from_call_to_uri</function> - - - MI command that has the same behavior as - , only that the triggering - is not script driven, but exterior driven. Useful for injecting media - announcements during a call. - - - Name: media_exchange_from_call_to_uri - - Parameters - - - callid (string) - the callid of the - dialog that will have it's leg mixed with the new call - to the Media Server - - - uri (string) - the destination URI of - the new call - - - leg (string) - indicates the participant - that will have its media pined into the new call. Possible - values are caller and callee. - - - headers (string, optional) - extra headers - to add to the outgoing request - - - nohold (integer, optional) - if set to a - non-zero value, the module avoids putting the other participant - on hold when the media exchanging starts - - - - MI FIFO Command Format: - - -# start playing back an annoucement to caller -opensips-cli -x mi media_exchange_from_call_to_uri \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - uri=sip:announcement@127.0.0.1:5080 \ - leg=caller - -
-
- - <function moreinfo="none">media_exchange_from_call_to_uri_body</function> - - - MI command that does the same thing as the - MI function, but - also allows you to specify a custom body in the outgoing request. - The body has to be specified in the mandatory body - parameter, all the other parameters being the same as the ones of - . - -
-
- - <function moreinfo="none">media_terminate</function> - - - MI command to terminate an ongoing media exchange. - - - Name: media_terminate - - Parameters - - - callid (string) - the callid of the - dialog that will have the media exchange terminated. - - - leg (string, optional) - the leg for - whom to terminate the media exchange. Accepted values are - caller, callee - and both. If missing, all media - sessions are terminated. - - - nohold (integer, optional) - if specified - and has a non-zero value, the leg that is being terminated - is not put on hold if the other participant still has an - ongoing media session. - - - instance (string, optional) - should only be - used when terminating a forking instance, and represents the - instance to terminate. It must be ommitted when terminating an - streaming session. However, for fallback compatibility, if the - parameter is missing, and no streaming session is found, the - command terminates the default forking - instance, if it exists. - - - - MI FIFO Command Format: - - -# terminate a caller announcement -opensips-cli -x mi media_terminate \ - callid=c6fdb0f9-47dc-495d-8d38-0f37e836a531 \ - leg=caller - -
-
- -
diff --git a/modules/mediaproxy/README b/modules/mediaproxy/README deleted file mode 100644 index 1cc8fedee3a..00000000000 --- a/modules/mediaproxy/README +++ /dev/null @@ -1,428 +0,0 @@ -Mediaproxy Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Principle of operation - 1.3. Features - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported parameters - - 1.5.1. disable (int) - 1.5.2. mediaproxy_socket (string) - 1.5.3. mediaproxy_timeout (int) - 1.5.4. signaling_ip_avp (string) - 1.5.5. media_relay_avp (string) - 1.5.6. ice_candidate (string) - 1.5.7. ice_candidate_avp (string) - - 1.6. Exported Functions - - 1.6.1. engage_media_proxy() - 1.6.2. use_media_proxy() - 1.6.3. end_media_session() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the disable parameter - 1.2. Setting the mediaproxy_socket parameter - 1.3. Setting the mediaproxy_timeout parameter - 1.4. Setting the signaling_ip_avp parameter - 1.5. Setting the media_relay_avp parameter - 1.6. Setting the ice_candidate parameter - 1.7. Setting the ice_candidate_avp parameter - 1.8. Using the engage_media_proxy function - 1.9. Using the use_media_proxy function - 1.10. Using the end_media_session function - -Chapter 1. Admin Guide - -1.1. Overview - - Mediaproxy is an OpenSIPS module that is designed to allow - automatic NAT traversal for the majority of existing SIP - clients. This means that there will be no need to configure - anything in particular on the NAT box to allow these clients to - work behind NAT when using the mediaproxy module. - -1.2. Principle of operation - - This NAT traversal solution operates by placing a media relay - in the middle between 2 SIP user-agents. It mangles the SDP - messages for both of them in a way that will make the parties - talk with the relay while they think they talk directly with - each other. - - Mediaproxy consists of 2 components: - * The OpenSIPS mediaproxy module - * An external application called MediaProxy which employs a - dispatcher and multiple distributed media relays. This is - available from http://ag-projects.com/MediaProxy.html - (version 2.0.0 or newer is required by this module). - - The mediaproxy dispatcher runs on the same machine as OpenSIPS - and its purpose is to select a media relay for a call. The - media relay may run on the same machine as the dispatcher or on - multiple remote hosts and its purpose is to forward the streams - between the calling parties. To find out more about the - architecture of MediaProxy please read the documentation that - comes with it. - - To be able to act as a relay between the 2 user agents, the - machine(s) running the module/proxy server must have a public - IP address. - - OpenSIPS will ask the media relay to allocate as many ports as - there are media streams in the SDP offer and answer. The media - relay will send back to OpenSIPS the IP address and port(s) for - them. Then OpenSIPS will replace the original contact IP and - RTP ports from the SDP messages with the ones provided by the - media relay. By doing this, both user agents will try to - contact the media relay instead of communicating directly with - each other. Once the user agents contact the media relay, it - will record the addresses they came from and will know where to - forward packets received from the other endpoint. This is - needed because the address/port the NAT box will allocate for - the media streams is not known before they actually leave the - NAT box. However the address of the media relay is always known - (being a public IP) so the 2 endpoints know where to connect. - After they do so, the relay learns their addresses and can - forward packets between them. - - The SIP clients that will work transparently behind NAT when - using mediaproxy, are the so-called symmetric clients. The - symmetric clients have the particularity that use the same port - to send and receive data. This must be true for both signaling - and media for a client to work transparently with mediaproxy - without any configuration on the NAT box. - -1.3. Features - - * make symmetric clients work behind NAT transparently, with - no configuration needed on the client's NAT box. - * have the ability to distribute RTP traffic on multiple - media relays running on multiple hosts. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog module - if engage_media_proxy is used (see below - the description of engage_media_proxy). - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported parameters - -1.5.1. disable (int) - - Boolean flag that specifies if mediaproxy should be disabled. - This is useful when you want to use the same OpenSIPS - configuration in two different context, one using mediaproxy, - the other not. In the case mediaproxy is disabled, calls to its - functions will have no effect, allowing you to use the same - configuration without changes. - - Default value is “0”. - - Example 1.1. Setting the disable parameter -... -modparam("mediaproxy", "disable", 1) -... - -1.5.2. mediaproxy_socket (string) - - It is the path to the filesystem socket where the mediaproxy - dispatcher listens for commands from the module. - - Default value is “/run/mediaproxy/dispatcher.sock”. - - Example 1.2. Setting the mediaproxy_socket parameter -... -modparam("mediaproxy", "mediaproxy_socket", "/run/mediaproxy/dispatcher. -sock") -... - -1.5.3. mediaproxy_timeout (int) - - How much time (in milliseconds) to wait for an answer from the - mediaproxy dispatcher. - - Default value is “500”. - - Example 1.3. Setting the mediaproxy_timeout parameter -... -modparam("mediaproxy", "mediaproxy_timeout", 500) -... - -1.5.4. signaling_ip_avp (string) - - Specification of the AVP which holds the IP address from where - the SIP signaling originated. If this AVP is set it will be - used to get the signaling IP address, else the source IP - address from where the SIP message was received will be used. - This AVP is meant to be used in cases where there are more than - one proxy in the call setup path and the proxy that actually - starts mediaproxy doesn't receive the SIP messages directly - from the UA and it cannot determine the NAT IP address from - where the signaling originated. In such a case attaching a SIP - header at the first proxy and then copying that header's value - into the signaling_ip_avp on the proxy that starts mediaproxy - will allow it to get the correct NAT IP address from where the - SIP signaling originated. - - Default value is “$avp(signaling_ip)”. - - Example 1.4. Setting the signaling_ip_avp parameter -... -modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)") -... - -1.5.5. media_relay_avp (string) - - Specification of the AVP which holds an optional application - defined media relay IP address of a particular media relay that - is preferred to be used for the current call. If an IP address - is written to this AVP before calling use_media_proxy(), it - will be preferred by the dispatcher over the normal selection - algorithm. - - Default value is “$avp(media_relay)”. - - Example 1.5. Setting the media_relay_avp parameter -... -modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)") -... - -1.5.6. ice_candidate (string) - - Indicates the type of ICE candidate that will be added to the - SDP. It can take 3 values: 'none', 'low-priority' or - 'high-priority'. If 'none' is selected no candidate will be - added to the SDP. If 'low-priority' is selected then a low - priority candidate will be added and if 'high-priority' is - selected a high priority one. - - Default value is “none”. - - Example 1.6. Setting the ice_candidate parameter -... -modparam("mediaproxy", "ice_candidate", "low-priority") -... - -1.5.7. ice_candidate_avp (string) - - Specification of the AVP which holds the ICE candidate that - will be inserted in the SDP. The value specified in this AVP - will override the value in ice_candidate module parameter. Note - that if use_media_proxy() and end_media_session() functions are - being used, the AVP will not be available in the reply route - unless you set onreply_avp_mode from the tm module to '1', and - if the AVP is not set, the default value will be used. - - Default value is “$avp(ice_candidate)”. - - Example 1.7. Setting the ice_candidate_avp parameter -... -modparam("mediaproxy", "ice_candidate_avp", "$avp(ice_candidate)") -... - -1.6. Exported Functions - -1.6.1. engage_media_proxy() - - Trigger the use of MediaProxy for all the dialog requests and - replies that have an SDP body. This needs to be called only - once for the first INVITE in a dialog. After that it will use - the dialog module to trace the dialog and automatically call - use_media_proxy() on every request and reply that belongs to - the dialog and has an SDP body. When the dialog ends it will - also call automatically end_media_session(). All of these are - called internally on dialog callbacks, so for this function to - work, the dialog module must be loaded and configured. - - This function is an advanced mechanism to use a media relay - without having to manually call a function on each message that - belongs to the dialog. However this method is less flexible, - because once things were set in motion by calling this function - on the first INVITE, it cannot be stopped, not even by calling - end_media_session(). It will only stop when the dialog ends. - Until then it will modify the SDP content of every in-dialog - message to make it use a media relay. If one needs more control - over the process, like starting to use mediaproxy only later in - the failure route, or stopping to use mediaproxy in the failure - route, then the use_media_proxy and end_media_session functions - should be used, and manually called as appropriate. Using this - function should NOT be mixed with either of use_media_proxy() - or end_media_session(). - - This function can be used from REQUEST_ROUTE. - - Example 1.8. Using the engage_media_proxy function -... -if (is_method("INVITE") && !has_totag()) { - # We can also use a specific media relay if we need to - #$avp(media_relay) = "1.2.3.4"; - engage_media_proxy(); -} -... - -1.6.2. use_media_proxy() - - Will make a call to the dispatcher and replace the IPs and - ports in the SDP body with the ones returned by the media relay - for each supported media stream in the SDP body. This will - force the media streams to be routed through the media relay. - If a mix of supported and unsupported streams are present in - the SDP, only the supported streams will be modified, while the - unsupported streams will be left alone. - - This function should NOT be mixed with engage_media_proxy(). - - This function has the following return codes: - - * +1 - successfully modified message (true value) - * -1 - error in processing message (false value) - * -2 - missing SDP body, nothing to process (false value) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.9. Using the use_media_proxy function -... -if (is_method("INVITE")) { - # We can also use a specific media relay if we need to - #$avp(media_relay) = "1.2.3.4"; - use_media_proxy(); -} -... - -1.6.3. end_media_session() - - Will call on the dispatcher to inform the media relay to end - the media session. This is done when a call ends, to instruct - the media relay to release the resources allocated to that call - as well as to save logging information about the media session. - Called on BYE, CANCEL or failures. - - This function should NOT be mixed with engage_media_proxy(). - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.10. Using the end_media_session function -... -if (is_method("BYE")) { - end_media_session(); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Dan Pascu (@danpascu) 131 55 4241 2404 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 39 31 688 88 - 3. Saúl Ibarra Corretgé (@saghul) 21 14 504 71 - 4. Liviu Chircu (@liviuchircu) 14 12 41 49 - 5. Daniel-Constantin Mierla (@miconda) 13 11 37 33 - 6. Razvan Crainea (@razvancrainea) 9 7 22 41 - 7. Vlad Patrascu (@rvlad-patrascu) 4 2 8 4 - 8. Vlad Paiu (@vladpaiu) 4 2 7 12 - 9. Henning Westerholt (@henningw) 4 2 6 31 - 10. Andrei Pelinescu-Onciul 4 2 4 4 - - All remaining contributors: Maksym Sobolyev (@sobomax), - Alexandra Titoc, Eric Tamme (@etamme), Marcus Hunger, Sergio - Gutierrez, Alexey Vasilyev (@vasilevalex), Jan Janak (@janakj), - Konstantin Bokarius, Julián Moreno Patiño, Klaus Darilion, - Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Adrian - Georgescu, Elena-Ramona Modroiu, Sergio Gutierrez. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Alexey Vasilyev (@vasilevalex) Mar 2022 - Mar 2022 - 5. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 6. Dan Pascu (@danpascu) Mar 2004 - Aug 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2005 - Apr 2019 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Eric Tamme (@etamme), Saúl Ibarra - Corretgé (@saghul), Vlad Paiu (@vladpaiu), Sergio Gutierrez, - Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Marcus Hunger, Klaus Darilion, Elena-Ramona - Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Adrian - Georgescu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Alexey Vasilyev (@vasilevalex), Liviu Chircu - (@liviuchircu), Dan Pascu (@danpascu), Peter Lemenkov - (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), Saúl Ibarra Corretgé (@saghul), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2004 Dan Pascu diff --git a/modules/mediaproxy/README.md b/modules/mediaproxy/README.md new file mode 100644 index 00000000000..193959ac946 --- /dev/null +++ b/modules/mediaproxy/README.md @@ -0,0 +1,376 @@ +--- +title: "Mediaproxy Module" +description: "Mediaproxy is an OpenSIPS module that is designed to allow automatic NAT traversal for the majority of existing SIP clients." +--- + +## Admin Guide + + +### Overview + + +Mediaproxy is an OpenSIPS module that is designed to allow automatic +NAT traversal for the majority of existing SIP clients. This means +that there will be no need to configure anything in particular on +the NAT box to allow these clients to work behind NAT when using +the mediaproxy module. + + +### Principle of operation + + +This NAT traversal solution operates by placing a media relay in the +middle between 2 SIP user-agents. It mangles the SDP messages for both +of them in a way that will make the parties talk with the relay while +they think they talk directly with each other. + + +Mediaproxy consists of 2 components: + + +- The OpenSIPS mediaproxy module +- An external application called MediaProxy which employs a +dispatcher and multiple distributed media relays. This is +available from http://ag-projects.com/MediaProxy.html +(version 2.0.0 or newer is required by this module). + + +The mediaproxy dispatcher runs on the same machine as OpenSIPS +and its purpose is to select a media relay for a call. The media +relay may run on the same machine as the dispatcher or on multiple +remote hosts and its purpose is to forward the streams between the +calling parties. To find out more about the architecture of MediaProxy +please read the documentation that comes with it. + + +To be able to act as a relay between the 2 user agents, the machine(s) +running the module/proxy server must have a public IP address. + + +OpenSIPS will ask the media relay to allocate as many ports as there are +media streams in the SDP offer and answer. The media relay will send back +to OpenSIPS the IP address and port(s) for them. Then OpenSIPS will +replace the original contact IP and RTP ports from the SDP messages with +the ones provided by the media relay. By doing this, both user agents will +try to contact the media relay instead of communicating directly with each +other. Once the user agents contact the media relay, it will record the +addresses they came from and will know where to forward packets received +from the other endpoint. This is needed because the address/port the NAT +box will allocate for the media streams is not known before they actually +leave the NAT box. However the address of the media relay is always known +(being a public IP) so the 2 endpoints know where to connect. After they +do so, the relay learns their addresses and can forward packets between +them. + + +The SIP clients that will work transparently behind NAT when using +mediaproxy, are the so-called symmetric clients. The symmetric clients +have the particularity that use the same port to send and receive data. +This must be true for both signaling and media for a client to work +transparently with mediaproxy without any configuration on the NAT box. + + +### Features + + +- make symmetric clients work behind NAT transparently, with no +configuration needed on the client's NAT box. +- have the ability to distribute RTP traffic on multiple media relays +running on multiple hosts. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog* module - if engage_media_proxy is used +(see below the description of engage_media_proxy). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### disable (int) + + +Boolean flag that specifies if mediaproxy should be disabled. This +is useful when you want to use the same OpenSIPS configuration in +two different context, one using mediaproxy, the other not. In the +case mediaproxy is disabled, calls to its functions will have no +effect, allowing you to use the same configuration without changes. + + +*Default value is "0".* + + +```opensips title="Setting the disable parameter" +... +modparam("mediaproxy", "disable", 1) +... + +``` + + +#### mediaproxy_socket (string) + + +It is the path to the filesystem socket where the mediaproxy dispatcher +listens for commands from the module. + + +*Default value is +"/run/mediaproxy/dispatcher.sock".* + + +```opensips title="Setting the mediaproxy_socket parameter" +... +modparam("mediaproxy", "mediaproxy_socket", "/run/mediaproxy/dispatcher.sock") +... + +``` + + +#### mediaproxy_timeout (int) + + +How much time (in milliseconds) to wait for an answer from the +mediaproxy dispatcher. + + +*Default value is "500".* + + +```opensips title="Setting the mediaproxy_timeout parameter" +... +modparam("mediaproxy", "mediaproxy_timeout", 500) +... + +``` + + +#### signaling_ip_avp (string) + + +Specification of the AVP which holds the IP address from where +the SIP signaling originated. If this AVP is set it will be used +to get the signaling IP address, else the source IP address +from where the SIP message was received will be used. +This AVP is meant to be used in cases where there are more than +one proxy in the call setup path and the proxy that actually +starts mediaproxy doesn't receive the SIP messages directly +from the UA and it cannot determine the NAT IP address from +where the signaling originated. In such a case attaching a +SIP header at the first proxy and then copying that header's +value into the signaling_ip_avp on the proxy that starts +mediaproxy will allow it to get the correct NAT IP address +from where the SIP signaling originated. + + +*Default value is "$avp(signaling_ip)".* + + +```opensips title="Setting the signaling_ip_avp parameter" +... +modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)") +... + +``` + + +#### media_relay_avp (string) + + +Specification of the AVP which holds an optional application +defined media relay IP address of a particular media relay that +is preferred to be used for the current call. If an IP address +is written to this AVP before calling use_media_proxy(), it +will be preferred by the dispatcher over the normal selection +algorithm. + + +*Default value is "$avp(media_relay)".* + + +```opensips title="Setting the media_relay_avp parameter" +... +modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)") +... + +``` + + +#### ice_candidate (string) + + +Indicates the type of ICE candidate that will be added to the SDP. +It can take 3 values: 'none', 'low-priority' or 'high-priority'. +If 'none' is selected no candidate will be added to the SDP. If +'low-priority' is selected then a low priority candidate will be +added and if 'high-priority' is selected a high priority one. + + +*Default value is "none".* + + +```opensips title="Setting the ice_candidate parameter" +... +modparam("mediaproxy", "ice_candidate", "low-priority") +... + +``` + + +#### ice_candidate_avp (string) + + +Specification of the AVP which holds the ICE candidate that will be +inserted in the SDP. The value specified in this AVP will override +the value in ice_candidate module parameter. + +Note that if use_media_proxy() and end_media_session() functions are +being used, the AVP will not be available in the reply route unless +you set onreply_avp_mode from the tm module to '1', and if the AVP +is not set, the default value will be used. + + +*Default value is "$avp(ice_candidate)".* + + +```opensips title="Setting the ice_candidate_avp parameter" +... +modparam("mediaproxy", "ice_candidate_avp", "$avp(ice_candidate)") +... + +``` + + +### Exported Functions + + +#### engage_media_proxy() + + +Trigger the use of MediaProxy for all the dialog requests and +replies that have an SDP body. This needs to be called only +once for the first INVITE in a dialog. After that it will use +the dialog module to trace the dialog and automatically call +use_media_proxy() on every request and reply that belongs to +the dialog and has an SDP body. When the dialog ends it will +also call automatically end_media_session(). All of these are +called internally on dialog callbacks, so for this function to +work, the dialog module must be loaded and configured. + + +This function is an advanced mechanism to use a media relay +without having to manually call a function on each message that +belongs to the dialog. However this method is less flexible, +because once things were set in motion by calling this function +on the first INVITE, it cannot be stopped, not even by calling +end_media_session(). It will only stop when the dialog ends. +Until then it will modify the SDP content of every in-dialog +message to make it use a media relay. If one needs more control +over the process, like starting to use mediaproxy only later in +the failure route, or stopping to use mediaproxy in the failure +route, then the use_media_proxy and end_media_session functions +should be used, and manually called as appropriate. Using this +function should NOT be mixed with either of use_media_proxy() +or end_media_session(). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Using the engage_media_proxy function" +... +if (is_method("INVITE") && !has_totag()) { + # We can also use a specific media relay if we need to + #$avp(media_relay) = "1.2.3.4"; + engage_media_proxy(); +} +... + +``` + + +#### use_media_proxy() + + +Will make a call to the dispatcher and replace the IPs and ports +in the SDP body with the ones returned by the media relay for +each supported media stream in the SDP body. This will force the +media streams to be routed through the media relay. If a mix of +supported and unsupported streams are present in the SDP, only +the supported streams will be modified, while the unsupported +streams will be left alone. + + +This function should NOT be mixed with engage_media_proxy(). + + +This function has the following return codes: + + +- +1 - successfully modified message (true value) +- -1 - error in processing message (false value) +- -2 - missing SDP body, nothing to process (false value) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="Using the use_media_proxy function" +... +if (is_method("INVITE")) { + # We can also use a specific media relay if we need to + #$avp(media_relay) = "1.2.3.4"; + use_media_proxy(); +} +... + +``` + + +#### end_media_session() + + +Will call on the dispatcher to inform the media relay to end the +media session. This is done when a call ends, to instruct the media +relay to release the resources allocated to that call as well as +to save logging information about the media session. Called on BYE, +CANCEL or failures. + + +This function should NOT be mixed with engage_media_proxy(). + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="Using the end_media_session function" +... +if (is_method("BYE")) { + end_media_session(); +} +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mediaproxy/doc/contributors.xml b/modules/mediaproxy/doc/contributors.xml deleted file mode 100644 index d0721a8f3a2..00000000000 --- a/modules/mediaproxy/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Dan Pascu (@danpascu) - 131 - 55 - 4241 - 2404 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 39 - 31 - 688 - 88 - - - 3. - Saúl Ibarra Corretgé (@saghul) - 21 - 14 - 504 - 71 - - - 4. - Liviu Chircu (@liviuchircu) - 14 - 12 - 41 - 49 - - - 5. - Daniel-Constantin Mierla (@miconda) - 13 - 11 - 37 - 33 - - - 6. - Razvan Crainea (@razvancrainea) - 9 - 7 - 22 - 41 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 8 - 4 - - - 8. - Vlad Paiu (@vladpaiu) - 4 - 2 - 7 - 12 - - - 9. - Henning Westerholt (@henningw) - 4 - 2 - 6 - 31 - - - 10. - Andrei Pelinescu-Onciul - 4 - 2 - 4 - 4 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Alexandra Titoc, Eric Tamme (@etamme), Marcus Hunger, Sergio Gutierrez, Alexey Vasilyev (@vasilevalex), Jan Janak (@janakj), Konstantin Bokarius, Julián Moreno Patiño, Klaus Darilion, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Adrian Georgescu, Elena-Ramona Modroiu, Sergio Gutierrez. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Alexey Vasilyev (@vasilevalex) - Mar 2022 - Mar 2022 - - - 5. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 6. - Dan Pascu (@danpascu) - Mar 2004 - Aug 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2005 - Apr 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Eric Tamme (@etamme), Saúl Ibarra Corretgé (@saghul), Vlad Paiu (@vladpaiu), Sergio Gutierrez, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Marcus Hunger, Klaus Darilion, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Adrian Georgescu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Alexey Vasilyev (@vasilevalex), Liviu Chircu (@liviuchircu), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Saúl Ibarra Corretgé (@saghul), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu. -
- -
diff --git a/modules/mediaproxy/doc/mediaproxy.xml b/modules/mediaproxy/doc/mediaproxy.xml deleted file mode 100644 index eb9c468ab18..00000000000 --- a/modules/mediaproxy/doc/mediaproxy.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Mediaproxy Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2004 Dan Pascu - diff --git a/modules/mediaproxy/doc/mediaproxy_admin.xml b/modules/mediaproxy/doc/mediaproxy_admin.xml deleted file mode 100644 index 6f6794b8f96..00000000000 --- a/modules/mediaproxy/doc/mediaproxy_admin.xml +++ /dev/null @@ -1,462 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Mediaproxy is an &osips; module that is designed to allow automatic - NAT traversal for the majority of existing SIP clients. This means - that there will be no need to configure anything in particular on - the NAT box to allow these clients to work behind NAT when using - the mediaproxy module. - -
- -
- Principle of operation - - This NAT traversal solution operates by placing a media relay in the - middle between 2 SIP user-agents. It mangles the SDP messages for both - of them in a way that will make the parties talk with the relay while - they think they talk directly with each other. - - - - Mediaproxy consists of 2 components: - - - The &osips; mediaproxy module - - - - An external application called MediaProxy which employs a - dispatcher and multiple distributed media relays. This is - available from http://ag-projects.com/MediaProxy.html - (version 2.0.0 or newer is required by this module). - - - - - - - The mediaproxy dispatcher runs on the same machine as &osips; - and its purpose is to select a media relay for a call. The media - relay may run on the same machine as the dispatcher or on multiple - remote hosts and its purpose is to forward the streams between the - calling parties. To find out more about the architecture of MediaProxy - please read the documentation that comes with it. - - - - To be able to act as a relay between the 2 user agents, the machine(s) - running the module/proxy server must have a public IP address. - - - - &osips; will ask the media relay to allocate as many ports as there are - media streams in the SDP offer and answer. The media relay will send back - to &osips; the IP address and port(s) for them. Then &osips; will - replace the original contact IP and RTP ports from the SDP messages with - the ones provided by the media relay. By doing this, both user agents will - try to contact the media relay instead of communicating directly with each - other. Once the user agents contact the media relay, it will record the - addresses they came from and will know where to forward packets received - from the other endpoint. This is needed because the address/port the NAT - box will allocate for the media streams is not known before they actually - leave the NAT box. However the address of the media relay is always known - (being a public IP) so the 2 endpoints know where to connect. After they - do so, the relay learns their addresses and can forward packets between - them. - - - - The SIP clients that will work transparently behind NAT when using - mediaproxy, are the so-called symmetric clients. The symmetric clients - have the particularity that use the same port to send and receive data. - This must be true for both signaling and media for a client to work - transparently with mediaproxy without any configuration on the NAT box. - -
- -
- Features - - - - - make symmetric clients work behind NAT transparently, with no - configuration needed on the client's NAT box. - - - - - - have the ability to distribute RTP traffic on multiple media relays - running on multiple hosts. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog module - if engage_media_proxy is used - (see below the description of engage_media_proxy). - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported parameters -
- <varname>disable</varname> (int) - - Boolean flag that specifies if mediaproxy should be disabled. This - is useful when you want to use the same &osips; configuration in - two different context, one using mediaproxy, the other not. In the - case mediaproxy is disabled, calls to its functions will have no - effect, allowing you to use the same configuration without changes. - - - - - Default value is 0. - - - - - Setting the <varname>disable</varname> parameter - -... -modparam("mediaproxy", "disable", 1) -... - - -
- -
- <varname>mediaproxy_socket</varname> (string) - - It is the path to the filesystem socket where the mediaproxy dispatcher - listens for commands from the module. - - - - - Default value is - /run/mediaproxy/dispatcher.sock. - - - - - Setting the <varname>mediaproxy_socket</varname> parameter - -... -modparam("mediaproxy", "mediaproxy_socket", "/run/mediaproxy/dispatcher.sock") -... - - -
- -
- <varname>mediaproxy_timeout</varname> (int) - - How much time (in milliseconds) to wait for an answer from the - mediaproxy dispatcher. - - - - - Default value is 500. - - - - - Setting the <varname>mediaproxy_timeout</varname> parameter - -... -modparam("mediaproxy", "mediaproxy_timeout", 500) -... - - -
- -
- <varname>signaling_ip_avp</varname> (string) - - Specification of the AVP which holds the IP address from where - the SIP signaling originated. If this AVP is set it will be used - to get the signaling IP address, else the source IP address - from where the SIP message was received will be used. - This AVP is meant to be used in cases where there are more than - one proxy in the call setup path and the proxy that actually - starts mediaproxy doesn't receive the SIP messages directly - from the UA and it cannot determine the NAT IP address from - where the signaling originated. In such a case attaching a - SIP header at the first proxy and then copying that header's - value into the signaling_ip_avp on the proxy that starts - mediaproxy will allow it to get the correct NAT IP address - from where the SIP signaling originated. - - - - - Default value is $avp(signaling_ip). - - - - - Setting the <varname>signaling_ip_avp</varname> parameter - -... -modparam("mediaproxy", "signaling_ip_avp", "$avp(nat_ip)") -... - - -
- -
- <varname>media_relay_avp</varname> (string) - - Specification of the AVP which holds an optional application - defined media relay IP address of a particular media relay that - is preferred to be used for the current call. If an IP address - is written to this AVP before calling use_media_proxy(), it - will be preferred by the dispatcher over the normal selection - algorithm. - - - - - Default value is $avp(media_relay). - - - - - Setting the <varname>media_relay_avp</varname> parameter - -... -modparam("mediaproxy", "media_relay_avp", "$avp(media_relay)") -... - - -
- -
- <varname>ice_candidate</varname> (string) - - Indicates the type of ICE candidate that will be added to the SDP. - It can take 3 values: 'none', 'low-priority' or 'high-priority'. - If 'none' is selected no candidate will be added to the SDP. If - 'low-priority' is selected then a low priority candidate will be - added and if 'high-priority' is selected a high priority one. - - - - - Default value is none. - - - - - Setting the <varname>ice_candidate</varname> parameter - -... -modparam("mediaproxy", "ice_candidate", "low-priority") -... - - -
- -
- <varname>ice_candidate_avp</varname> (string) - - Specification of the AVP which holds the ICE candidate that will be - inserted in the SDP. The value specified in this AVP will override - the value in ice_candidate module parameter. - - Note that if use_media_proxy() and end_media_session() functions are - being used, the AVP will not be available in the reply route unless - you set onreply_avp_mode from the tm module to '1', and if the AVP - is not set, the default value will be used. - - - - - Default value is $avp(ice_candidate). - - - - - Setting the <varname>ice_candidate_avp</varname> parameter - -... -modparam("mediaproxy", "ice_candidate_avp", "$avp(ice_candidate)") -... - - -
-
- -
- Exported Functions -
- <function moreinfo="none">engage_media_proxy()</function> - - Trigger the use of MediaProxy for all the dialog requests and - replies that have an SDP body. This needs to be called only - once for the first INVITE in a dialog. After that it will use - the dialog module to trace the dialog and automatically call - use_media_proxy() on every request and reply that belongs to - the dialog and has an SDP body. When the dialog ends it will - also call automatically end_media_session(). All of these are - called internally on dialog callbacks, so for this function to - work, the dialog module must be loaded and configured. - - - - This function is an advanced mechanism to use a media relay - without having to manually call a function on each message that - belongs to the dialog. However this method is less flexible, - because once things were set in motion by calling this function - on the first INVITE, it cannot be stopped, not even by calling - end_media_session(). It will only stop when the dialog ends. - Until then it will modify the SDP content of every in-dialog - message to make it use a media relay. If one needs more control - over the process, like starting to use mediaproxy only later in - the failure route, or stopping to use mediaproxy in the failure - route, then the use_media_proxy and end_media_session functions - should be used, and manually called as appropriate. Using this - function should NOT be mixed with either of use_media_proxy() - or end_media_session(). - - - - This function can be used from REQUEST_ROUTE. - - - - Using the <function>engage_media_proxy</function> function - -... -if (is_method("INVITE") && !has_totag()) { - # We can also use a specific media relay if we need to - #$avp(media_relay) = "1.2.3.4"; - engage_media_proxy(); -} -... - - -
- -
- <function moreinfo="none">use_media_proxy()</function> - - Will make a call to the dispatcher and replace the IPs and ports - in the SDP body with the ones returned by the media relay for - each supported media stream in the SDP body. This will force the - media streams to be routed through the media relay. If a mix of - supported and unsupported streams are present in the SDP, only - the supported streams will be modified, while the unsupported - streams will be left alone. - - - - This function should NOT be mixed with engage_media_proxy(). - - - This function has the following return codes: - - - - +1 - successfully modified message (true value) - - - -1 - error in processing message (false value) - - - -2 - missing SDP body, nothing to process (false value) - - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - - Using the <function>use_media_proxy</function> function - -... -if (is_method("INVITE")) { - # We can also use a specific media relay if we need to - #$avp(media_relay) = "1.2.3.4"; - use_media_proxy(); -} -... - - -
- -
- <function moreinfo="none">end_media_session()</function> - - Will call on the dispatcher to inform the media relay to end the - media session. This is done when a call ends, to instruct the media - relay to release the resources allocated to that call as well as - to save logging information about the media session. Called on BYE, - CANCEL or failures. - - - - This function should NOT be mixed with engage_media_proxy(). - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - - Using the <function>end_media_session</function> function - -... -if (is_method("BYE")) { - end_media_session(); -} -... - - -
-
- -
- diff --git a/modules/mi_datagram/README b/modules/mi_datagram/README deleted file mode 100644 index 95c0d00a105..00000000000 --- a/modules/mi_datagram/README +++ /dev/null @@ -1,369 +0,0 @@ -mi_datagram Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. DATAGRAM command syntax - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. socket_name (string) - 1.4.2. children_count (string) - 1.4.3. unix_socket_mode (integer) - 1.4.4. unix_socket_group (integer) unix_socket_group - (string) - - 1.4.5. unix_socket_user (integer) unix_socket_group - (string) - - 1.4.6. socket_timeout (integer) - 1.4.7. trace_destination (string) - 1.4.8. trace_bwlist (string) - 1.4.9. pretty_printing (int) - - 1.5. Exported Functions - 1.6. Example - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set socket_name parameter - 1.2. Set children_count parameter - 1.3. Set unix_socket_mode parameter - 1.4. Set unix_socket_group parameter - 1.5. Set unix_socket_user parameter - 1.6. Set socket_timeout parameter - 1.7. Set trace_destination parameter - 1.8. Set trace_destination parameter - 1.9. Set pretty_printing parameter - 1.10. DATAGRAM request - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides a UNIX/UDP SOCKET transport - layer implementation for the Management Interface. - -1.2. DATAGRAM command syntax - - The MI requests and replies follow the JSON-RPC syntax. - - If case of an error generated by the MI engine, mostly internal - errors, an error message in plain text is sent back in the - datagram. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. socket_name (string) - - The name of a UNIX SOCKET or an IP address. The UNIX datagram - or UDP socket will be created using this parameter in order to - read the external commands. Both IPv4 and IPv6 are supported. - - Default value is NONE. - - Example 1.1. Set socket_name parameter -... -modparam("mi_datagram", "socket_name", "/tmp/opensips.sock") -... -modparam("mi_datagram", "socket_name", "udp:192.168.2.133:8080") -... - -1.4.2. children_count (string) - - The number of child processes to be created. Each child process - will be a datagram server. - - Default value is 1. - - Example 1.2. Set children_count parameter -... -modparam("mi_datagram", "children_count", 3) -... - -1.4.3. unix_socket_mode (integer) - - Permission to be used for creating the listening UNIX datagram - socket. Not necessary for a UDP socket. It follows the UNIX - conventions. - - Default value is 0660 (rw-rw----). - - Example 1.3. Set unix_socket_mode parameter -... -modparam("mi_datagram", "unix_socket_mode", 0600) -... - -1.4.4. unix_socket_group (integer) unix_socket_group (string) - - Group to be used for creating the listening UNIX socket. - - Default value is the inherited one. - - Example 1.4. Set unix_socket_group parameter -... -modparam("mi_datagram", "unix_socket_group", 0) -modparam("mi_datagram", "unix_socket_group", "root") -... - -1.4.5. unix_socket_user (integer) unix_socket_group (string) - - User to be used for creating the listening UNIX socket. - - Default value is the inherited one. - - Example 1.5. Set unix_socket_user parameter -... -modparam("mi_datagram", "unix_socket_user", 0) -modparam("mi_datagram", "unix_socket_user", "root") -... - -1.4.6. socket_timeout (integer) - - The reply will expire after trying to sent it for - socket_timeout milliseconds. - - Default value is 2000. - - Example 1.6. Set socket_timeout parameter -... -modparam("mi_datagram", "socket_timeout", 2000) -... - -1.4.7. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.7. Set trace_destination parameter -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport -=tcp;version=3") - -modparam("mi_datagram", "trace_destination", "hep_dest") -... - -1.4.8. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.8. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_datagram", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_datagram", "trace_bwlist", "w: sip_trace") -... - -1.4.9. pretty_printing (int) - - Indicates whether the JSONRPC responses sent through MI should - be pretty-printed or not. - - Default value is “0 - no pretty-printing”. - - Example 1.9. Set pretty_printing parameter -... -modparam("mi_fifo", "pretty_printing", 1) -... - -1.5. Exported Functions - - No function exported to be used from configuration file. - -1.6. Example - - This is an example showing the DATAGRAM format for the - “get_statistics dialog: tm:” MI commad: request. - - Example 1.10. DATAGRAM request - -{"jsonrpc":"2.0","method":"get_statistics","id":"1065","params":[["dialo -g:","tm:"]]} - - -Chapter 2. Frequently Asked Questions - - 2.1. - - Both UNIX and UDP type of socket can be created simultaneusly? - - This version supports only one kind of socket at a time. If - there are more than one value set for socket_name the last one - will take effect. - - 2.2. - - Is there a limit in the datagram request's size? - - The maximum length of a datagram request or reply is 65457 - bytes. - - 2.3. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.4. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.5. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 43 34 355 308 - 2. Ancuta Onofrei 28 2 2423 252 - 3. Vlad Patrascu (@rvlad-patrascu) 22 2 189 1049 - 4. Liviu Chircu (@liviuchircu) 14 11 31 67 - 5. Razvan Crainea (@razvancrainea) 12 10 50 34 - 6. Daniel-Constantin Mierla (@miconda) 9 7 18 16 - 7. Ionut Ionita (@ionutrazvanionita) 8 4 252 25 - 8. Henning Westerholt (@henningw) 5 3 9 11 - 9. Maksym Sobolyev (@sobomax) 4 2 1 2 - 10. Klaus Darilion 3 1 4 4 - - All remaining contributors: Walter Doekes (@wdoekes), Julián - Moreno Patiño, Konstantin Bokarius, Dusan Klinec (@ph4r05), - Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2007 - Apr 2021 - 4. Razvan Crainea (@razvancrainea) Oct 2011 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jan 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Ionut Ionita (@ionutrazvanionita) Jan 2017 - Feb 2017 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 10. Walter Doekes (@wdoekes) May 2014 - May 2014 - - All remaining contributors: Henning Westerholt (@henningw), - Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Ancuta Onofrei. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), Julián Moreno Patiño, Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Klaus - Darilion, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Ancuta Onofrei. - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/mi_datagram/README.md b/modules/mi_datagram/README.md new file mode 100644 index 00000000000..15c7e1e6f54 --- /dev/null +++ b/modules/mi_datagram/README.md @@ -0,0 +1,307 @@ +--- +title: "mi_datagram Module" +description: "This is a module which provides a UNIX/UDP SOCKET transport layer implementation for the Management Interface." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides a UNIX/UDP SOCKET transport layer +implementation for the Management Interface. + + +### DATAGRAM command syntax + + +The MI requests and replies follow the +[JSON-RPC](http://www.jsonrpc.org/specification) syntax. + + +If case of an error generated by the MI engine, mostly internal +errors, an error message in plain text is sent back in the datagram. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### socket_name (string) + + +The name of a UNIX SOCKET or an IP address. +The UNIX datagram or UDP socket will be created using this parameter +in order to read the external commands. +Both IPv4 and IPv6 are supported. + + +*Default value is NONE.* + + +```opensips title="Set socket_name parameter" +... +modparam("mi_datagram", "socket_name", "/tmp/opensips.sock") +... +modparam("mi_datagram", "socket_name", "udp:192.168.2.133:8080") +... +``` + + +#### children_count (string) + + +The number of child processes to be created. Each child process +will be a datagram server. + + +*Default value is 1.* + + +```opensips title="Set children_count parameter" +... +modparam("mi_datagram", "children_count", 3) +... +``` + + +#### unix_socket_mode (integer) + + +Permission to be used for creating the listening UNIX datagram socket. +Not necessary for a UDP socket. +It follows the UNIX conventions. + + +*Default value is 0660 (rw-rw----).* + + +```opensips title="Set unix_socket_mode parameter" +... +modparam("mi_datagram", "unix_socket_mode", 0600) +... +``` + + +#### unix_socket_group (integer) unix_socket_group (string) + + +Group to be used for creating the listening UNIX socket. + + +*Default value is the inherited one.* + + +```opensips title="Set unix_socket_group parameter" +... +modparam("mi_datagram", "unix_socket_group", 0) +modparam("mi_datagram", "unix_socket_group", "root") +... +``` + + +#### unix_socket_user (integer) unix_socket_group (string) + + +User to be used for creating the listening UNIX socket. + + +*Default value is the inherited one.* + + +```opensips title="Set unix_socket_user parameter" +... +modparam("mi_datagram", "unix_socket_user", 0) +modparam("mi_datagram", "unix_socket_user", "root") +... +``` + + +#### socket_timeout (integer) + + +The reply will expire after trying to sent it for socket_timeout +milliseconds. + + +*Default value is 2000.* + + +```opensips title="Set socket_timeout parameter" +... +modparam("mi_datagram", "socket_timeout", 2000) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_datagram", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. +**WARNING:** One can't define both +a whitelist and a blacklist. Only one of them is allowed. Defining +the parameter a second time will just overwrite the first one. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep)**. + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_datagram", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_datagram", "trace_bwlist", "w: sip_trace") +... +``` + + +#### pretty_printing (int) + + +Indicates whether the JSONRPC responses sent through MI should +be pretty-printed or not. + + +*Default value is "0 - no pretty-printing".* + + +```opensips title="Set pretty_printing parameter" +... +modparam("mi_fifo", "pretty_printing", 1) +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Example + + +This is an example showing the DATAGRAM format for the +"get_statistics dialog: tm:" MI commad: +request. + + +```json title="DATAGRAM request" +{"jsonrpc":"2.0","method":"get_statistics","id":"1065","params":[["dialog:","tm:"]]} +``` + + +## Frequently Asked Questions + + +**Q: Both UNIX and UDP type of socket can be created +simultaneusly?** + + +This version supports only one kind of socket at a time. +If there are more than one value set for socket_name the last one +will take effect. + + +**Q: Is there a limit in the datagram request's size?** + + +The maximum length of a datagram request or reply is 65457 bytes. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_datagram/datagram_fnc.c b/modules/mi_datagram/datagram_fnc.c index 66692d7a52a..21811eb5f64 100644 --- a/modules/mi_datagram/datagram_fnc.c +++ b/modules/mi_datagram/datagram_fnc.c @@ -582,8 +582,7 @@ int mi_datagram_callback(int rx_sock, void *_tx_sock, int was_timeout) free_async_handler(async_hdl); if (response) free_mi_response(response); - } else - return 0; + } free_req: free_mi_request_parsed(&request); return 0; diff --git a/modules/mi_datagram/doc/contributors.xml b/modules/mi_datagram/doc/contributors.xml deleted file mode 100644 index 30c51e1022d..00000000000 --- a/modules/mi_datagram/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 43 - 34 - 355 - 308 - - - 2. - Ancuta Onofrei - 28 - 2 - 2423 - 252 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 22 - 2 - 189 - 1049 - - - 4. - Liviu Chircu (@liviuchircu) - 14 - 11 - 31 - 67 - - - 5. - Razvan Crainea (@razvancrainea) - 12 - 10 - 50 - 34 - - - 6. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 18 - 16 - - - 7. - Ionut Ionita (@ionutrazvanionita) - 8 - 4 - 252 - 25 - - - 8. - Henning Westerholt (@henningw) - 5 - 3 - 9 - 11 - - - 9. - Maksym Sobolyev (@sobomax) - 4 - 2 - 1 - 2 - - - 10. - Klaus Darilion - 3 - 1 - 4 - 4 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Julián Moreno Patiño, Konstantin Bokarius, Dusan Klinec (@ph4r05), Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2007 - Apr 2021 - - - 4. - Razvan Crainea (@razvancrainea) - Oct 2011 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jan 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Ionut Ionita (@ionutrazvanionita) - Jan 2017 - Feb 2017 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 10. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei. -
- -
diff --git a/modules/mi_datagram/doc/mi_datagram.xml b/modules/mi_datagram/doc/mi_datagram.xml deleted file mode 100644 index 019ef94052b..00000000000 --- a/modules/mi_datagram/doc/mi_datagram.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mi_datagram Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - diff --git a/modules/mi_datagram/doc/mi_datagram_faq.xml b/modules/mi_datagram/doc/mi_datagram_faq.xml deleted file mode 100644 index d95a190d3b8..00000000000 --- a/modules/mi_datagram/doc/mi_datagram_faq.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - &faqguide; - - - - Both UNIX and UDP type of socket can be created - simultaneusly? - - - - This version supports only one kind of socket at a time. - If there are more than one value set for socket_name the last one - will take effect. - - - - - - Is there a limit in the datagram request's size? - - - - The maximum length of a datagram request or reply is 65457 bytes. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/mi_fifo/README b/modules/mi_fifo/README deleted file mode 100644 index f7fedf2fda6..00000000000 --- a/modules/mi_fifo/README +++ /dev/null @@ -1,335 +0,0 @@ -mi_fifo Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. FIFO command syntax - 1.3. Values Returned - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. fifo_name (string) - 1.5.2. fifo_mode (integer) - 1.5.3. fifo_group (integer) fifo_group (string) - 1.5.4. fifo_user (integer) fifo_group (string) - 1.5.5. reply_dir (string) - 1.5.6. pretty_printing (int) - 1.5.7. trace_destination (string) - 1.5.8. trace_bwlist (string) - - 1.6. Exported Functions - 1.7. Example - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set fifo_name parameter - 1.2. Set fifo_mode parameter - 1.3. Set fifo_group parameter - 1.4. Set fifo_user parameter - 1.5. Set reply_dir parameter - 1.6. Set pretty_printing parameter - 1.7. Set trace_destination parameter - 1.8. Set trace_destination parameter - 1.9. FIFO request - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides a FIFO transport layer - implementation for Management Interface. It receives the - command over a FIFO file and returns the output through the - reply_fifo specified. - - The module checks every 30 seconds if the FIFO file exists, and - if it was deleted, it recreates it. If one wants to force the - fifo file recreation, it should send a SIGHUP signal to the MI - process PID. - -1.2. FIFO command syntax - - The external commands issued via FIFO interface must follow the - following syntax: - - request = ':'(reply_fifo)?':'jsonrpc_command - - If the reply_fifo is missing, the MI FIFO module will not send - any reply back. A similar behavior happens when the - jsonrpc_command does not contain the id element, and the - command is considered a JSON-RPC notification. - -1.3. Values Returned - - In case of success, a valid JSON-RPC response is replied back - on the fifo file, containing a successful JSON-RPC response. - - In case of failure of the MI command, a JSON-RPC reply error is - sent back over the reply fifo file. - - If case of an error generated by the MI engine, mostly internal - errors, an error cause is sent back over the reply FIFO in - plain text. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.5. Exported Parameters - -1.5.1. fifo_name (string) - - The name of the FIFO file to be created for listening and - reading external commands. - - NOTE:Starting with Linux kernel 4.19, processes can no longer - read from FIFO files that are saved in directories with sticky - bits (such as /tmp) and are not owned by the same user the - process runs with. This prevents external tools (such as - opensips-cli) from running MI commands using a different user - (a Permissions denied error is triggered). If you are getting - this error while trying to use opensips-cli, you can fix it by - either store the fifo file in a non-sticky bit directory (such - as /run/opensips), or disable the fifo protection using sysctl - fs.protected_fifos = 0 (NOT RECOMMENDED). - - Default value is "/tmp/opensips_fifo". - - Example 1.1. Set fifo_name parameter -... -modparam("mi_fifo", "fifo_name", "/tmp/opensips_b2b_fifo") -... - -1.5.2. fifo_mode (integer) - - Permission to be used for creating the listening FIFO file. It - follows the UNIX conventions. - - Default value is 0660 (rw-rw----). - - Example 1.2. Set fifo_mode parameter -... -modparam("mi_fifo", "fifo_mode", 0600) -... - -1.5.3. fifo_group (integer) fifo_group (string) - - Group to be used for creating the listening FIFO file. - - Default value is the inherited one. - - Example 1.3. Set fifo_group parameter -... -modparam("mi_fifo", "fifo_group", 0) -modparam("mi_fifo", "fifo_group", "root") -... - -1.5.4. fifo_user (integer) fifo_group (string) - - User to be used for creating the listening FIFO file. - - Default value is the inherited one. - - Example 1.4. Set fifo_user parameter -... -modparam("mi_fifo", "fifo_user", 0) -modparam("mi_fifo", "fifo_user", "root") -... - -1.5.5. reply_dir (string) - - Directory to be used for creating the reply FIFO files. - - Default value is “/tmp/” - - Example 1.5. Set reply_dir parameter -... -modparam("mi_fifo", "reply_dir", "/home/opensips/tmp/") -... - -1.5.6. pretty_printing (int) - - Indicates whether the JSONRPC responses sent through MI should - be pretty-printed or not. - - Default value is “0 - no pretty-printing”. - - Example 1.6. Set pretty_printing parameter -... -modparam("mi_fifo", "pretty_printing", 1) -... - -1.5.7. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.7. Set trace_destination parameter -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport -=tcp;version=3") - -modparam("mi_fifo", "trace_destination", "hep_dest") -... - -1.5.8. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.8. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_fifo", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_fifo", "trace_bwlist", "w: sip_trace") -... - -1.6. Exported Functions - - No function exported to be used from configuration file. - -1.7. Example - - This is an example showing the FIFO format for the - “get_statistics dialog: tm:” MI commad: response. - - Example 1.9. FIFO request - -:reply_fifo:{"jsonrpc":"2.0","method":"get_statistics","id":"5672","para -ms":[["dialog:","tm:"]]} - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 62 37 2289 248 - 2. Razvan Crainea (@razvancrainea) 42 19 582 1072 - 3. Liviu Chircu (@liviuchircu) 17 14 33 72 - 4. Daniel-Constantin Mierla (@miconda) 12 10 20 22 - 5. Ionut Ionita (@ionutrazvanionita) 7 4 211 22 - 6. Maksym Sobolyev (@sobomax) 5 3 16 18 - 7. Henning Westerholt (@henningw) 5 2 62 109 - 8. Zero King (@l2dy) 3 1 5 3 - 9. Jerome Martin 3 1 3 3 - 10. Konstantin Bokarius 3 1 2 5 - - All remaining contributors: Ovidiu Sas (@ovidiusas), Alexey - Vasilyev (@vasilevalex), Julián Moreno Patiño, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Dusan Klinec (@ph4r05), - Alexandra Titoc, Vlad Patrascu (@rvlad-patrascu), Walter Doekes - (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2021 - Feb 2023 - 4. Alexey Vasilyev (@vasilevalex) Mar 2022 - Mar 2022 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2021 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - Apr 2021 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 10. Ionut Ionita (@ionutrazvanionita) Jan 2017 - Feb 2017 - - All remaining contributors: Julián Moreno Patiño, Dusan Klinec - (@ph4r05), Walter Doekes (@wdoekes), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ovidiu - Sas (@ovidiusas), Henning Westerholt (@henningw), Jerome - Martin. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Alexey Vasilyev (@vasilevalex), Razvan Crainea - (@razvancrainea), Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei - Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Jerome Martin. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/mi_fifo/README.md b/modules/mi_fifo/README.md new file mode 100644 index 00000000000..023536eb830 --- /dev/null +++ b/modules/mi_fifo/README.md @@ -0,0 +1,286 @@ +--- +title: "mi_fifo Module" +description: "This is a module which provides a FIFO transport layer implementation for Management Interface." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides a FIFO transport layer +implementation for Management Interface. It receives the +command over a FIFO file and returns the output through the +reply_fifo specified. + + +The module checks every 30 seconds if the FIFO file exists, +and if it was deleted, it recreates it. If one wants to force +the fifo file recreation, it should send a SIGHUP signal to +the MI process PID. + + +### FIFO command syntax + + +The external commands issued via FIFO interface must follow the +following syntax: +*request = ':'(reply_fifo)?':'jsonrpc_command* + + +If the *reply_fifo* is missing, the MI FIFO +module will not send any reply back. A similar behavior happens +when the *jsonrpc_command* does not contain +the *id* element, and the command is considered +a JSON-RPC notification. + + +### Values Returned + + +In case of success, a valid +[JSON-RPC](http://www.jsonrpc.org/specification) +response is replied back on the fifo file, containing a successful +JSON-RPC response. + + +In case of failure of the MI command, a JSON-RPC reply error is +sent back over the reply fifo file. + + +If case of an error generated by the MI engine, mostly internal +errors, an error cause is sent back over the reply FIFO in +plain text. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### fifo_name (string) + + +The name of the FIFO file to be created for listening and +reading external commands. + + +> [!NOTE] +> Starting with Linux kernel 4.19, +> processes can no longer read from FIFO files that are saved +> in directories with sticky bits (such as */tmp*) +> and are not owned by the same user the process runs with. This +> prevents external tools (such as *opensips-cli*) +> from running MI commands using a different user (a +> *Permissions denied* error is triggered). If +> you are getting this error while trying to use +> *opensips-cli*, you can fix it by either store +> the fifo file in a non-sticky bit directory (such as +> */run/opensips*), or disable the fifo +> protection using *sysctl fs.protected_fifos = 0* +> (NOT RECOMMENDED). + + +*Default value is "/tmp/opensips_fifo".* + + +```opensips title="Set fifo_name parameter" +... +modparam("mi_fifo", "fifo_name", "/tmp/opensips_b2b_fifo") +... +``` + + +#### fifo_mode (integer) + + +Permission to be used for creating the listening FIFO file. It +follows the UNIX conventions. + + +*Default value is 0660 (rw-rw----).* + + +```opensips title="Set fifo_mode parameter" +... +modparam("mi_fifo", "fifo_mode", 0600) +... +``` + + +#### fifo_group (integer) fifo_group (string) + + +Group to be used for creating the listening FIFO file. + + +*Default value is the inherited one.* + + +```opensips title="Set fifo_group parameter" +... +modparam("mi_fifo", "fifo_group", 0) +modparam("mi_fifo", "fifo_group", "root") +... +``` + + +#### fifo_user (integer) fifo_group (string) + + +User to be used for creating the listening FIFO file. + + +*Default value is the inherited one.* + + +```opensips title="Set fifo_user parameter" +... +modparam("mi_fifo", "fifo_user", 0) +modparam("mi_fifo", "fifo_user", "root") +... +``` + + +#### reply_dir (string) + + +Directory to be used for creating the reply FIFO files. + + +*Default value is "/tmp/"* + + +```opensips title="Set reply_dir parameter" +... +modparam("mi_fifo", "reply_dir", "/home/opensips/tmp/") +... +``` + + +#### pretty_printing (int) + + +Indicates whether the JSONRPC responses sent through MI should +be pretty-printed or not. + + +*Default value is "0 - no pretty-printing".* + + +```opensips title="Set pretty_printing parameter" +... +modparam("mi_fifo", "pretty_printing", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_fifo", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. +**WARNING:** One can't define both +a whitelist and a blacklist. Only one of them is allowed. Defining +the parameter a second time will just overwrite the first one. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_fifo", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_fifo", "trace_bwlist", "w: sip_trace") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Example + + +This is an example showing the FIFO format for the +"get_statistics dialog: tm:" MI commad: +response. + + +```c title="FIFO request" +:reply_fifo:{"jsonrpc":"2.0","method":"get_statistics","id":"5672","params":[["dialog:","tm:"]]} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_fifo/doc/contributors.xml b/modules/mi_fifo/doc/contributors.xml deleted file mode 100644 index b4cf873a119..00000000000 --- a/modules/mi_fifo/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 62 - 37 - 2289 - 248 - - - 2. - Razvan Crainea (@razvancrainea) - 42 - 19 - 582 - 1072 - - - 3. - Liviu Chircu (@liviuchircu) - 17 - 14 - 33 - 72 - - - 4. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 20 - 22 - - - 5. - Ionut Ionita (@ionutrazvanionita) - 7 - 4 - 211 - 22 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 16 - 18 - - - 7. - Henning Westerholt (@henningw) - 5 - 2 - 62 - 109 - - - 8. - Zero King (@l2dy) - 3 - 1 - 5 - 3 - - - 9. - Jerome Martin - 3 - 1 - 3 - 3 - - - 10. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas), Alexey Vasilyev (@vasilevalex), Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Dusan Klinec (@ph4r05), Alexandra Titoc, Vlad Patrascu (@rvlad-patrascu), Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2021 - Feb 2023 - - - 4. - Alexey Vasilyev (@vasilevalex) - Mar 2022 - Mar 2022 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2021 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - Apr 2021 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Jan 2017 - Feb 2017 - - - -
-All remaining contributors: Julián Moreno Patiño, Dusan Klinec (@ph4r05), Walter Doekes (@wdoekes), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ovidiu Sas (@ovidiusas), Henning Westerholt (@henningw), Jerome Martin. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Alexey Vasilyev (@vasilevalex), Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jerome Martin. -
- -
diff --git a/modules/mi_fifo/doc/mi_fifo.xml b/modules/mi_fifo/doc/mi_fifo.xml deleted file mode 100644 index fdb2e1c2818..00000000000 --- a/modules/mi_fifo/doc/mi_fifo.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mi_fifo Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - diff --git a/modules/mi_fifo/doc/mi_fifo_admin.xml b/modules/mi_fifo/doc/mi_fifo_admin.xml deleted file mode 100644 index 743869d768c..00000000000 --- a/modules/mi_fifo/doc/mi_fifo_admin.xml +++ /dev/null @@ -1,336 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module which provides a FIFO transport layer - implementation for Management Interface. It receives the - command over a FIFO file and returns the output through the - reply_fifo specified. - - - The module checks every 30 seconds if the FIFO file exists, - and if it was deleted, it recreates it. If one wants to force - the fifo file recreation, it should send a SIGHUP signal to - the MI process PID. - -
- -
- FIFO command syntax - - The external commands issued via FIFO interface must follow the - following syntax: - request = ':'(reply_fifo)?':'jsonrpc_command - - - If the reply_fifo is missing, the MI FIFO - module will not send any reply back. A similar behavior happens - when the jsonrpc_command does not contain - the id element, and the command is considered - a JSON-RPC notification. - -
- -
- Values Returned - - In case of success, a valid - JSON-RPC - response is replied back on the fifo file, containing a successful - JSON-RPC response. - - - In case of failure of the MI command, a JSON-RPC reply error is - sent back over the reply fifo file. - - - If case of an error generated by the MI engine, mostly internal - errors, an error cause is sent back over the reply FIFO in - plain text. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters -
- <varname>fifo_name</varname> (string) - - The name of the FIFO file to be created for listening and - reading external commands. - - - NOTE:Starting with Linux kernel 4.19, - processes can no longer read from FIFO files that are saved - in directories with sticky bits (such as /tmp) - and are not owned by the same user the process runs with. This - prevents external tools (such as opensips-cli) - from running MI commands using a different user (a - Permissions denied error is triggered). If - you are getting this error while trying to use - opensips-cli, you can fix it by either store - the fifo file in a non-sticky bit directory (such as - /run/opensips), or disable the fifo - protection using sysctl fs.protected_fifos = 0 - (NOT RECOMMENDED). - - - - Default value is "/tmp/opensips_fifo". - - - - Set <varname>fifo_name</varname> parameter - -... -modparam("mi_fifo", "fifo_name", "/tmp/opensips_b2b_fifo") -... - - -
- -
- <varname>fifo_mode</varname> (integer) - - Permission to be used for creating the listening FIFO file. It - follows the UNIX conventions. - - - - Default value is 0660 (rw-rw----). - - - - Set <varname>fifo_mode</varname> parameter - -... -modparam("mi_fifo", "fifo_mode", 0600) -... - - -
- -
- <varname>fifo_group</varname> (integer) - <varname>fifo_group</varname> (string) - - Group to be used for creating the listening FIFO file. - - - - Default value is the inherited one. - - - - Set <varname>fifo_group</varname> parameter - -... -modparam("mi_fifo", "fifo_group", 0) -modparam("mi_fifo", "fifo_group", "root") -... - - -
- -
- <varname>fifo_user</varname> (integer) - <varname>fifo_group</varname> (string) - - User to be used for creating the listening FIFO file. - - - - Default value is the inherited one. - - - - Set <varname>fifo_user</varname> parameter - -... -modparam("mi_fifo", "fifo_user", 0) -modparam("mi_fifo", "fifo_user", "root") -... - - -
- -
- <varname>reply_dir</varname> (string) - - Directory to be used for creating the reply FIFO files. - - - - Default value is /tmp/ - - - - Set <varname>reply_dir</varname> parameter - -... -modparam("mi_fifo", "reply_dir", "/home/opensips/tmp/") -... - - -
- -
- <varname>pretty_printing</varname> (int) - - Indicates whether the JSONRPC responses sent through MI should - be pretty-printed or not. - - - - Default value is 0 - no pretty-printing. - - - - Set <varname>pretty_printing</varname> parameter - -... -modparam("mi_fifo", "pretty_printing", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - This is where traced mi messages will go. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("mi_fifo", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_bwlist</varname> (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for - this parameter to have any purpose. Whitelists can be defined using - 'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the - actual blacklist by ':'. The mi commands in the list must be separated - by ','. - - - Defining a blacklists means all the commands that are not blacklisted - will be traced. Defining a whitelist means all the commands that are - not whitelisted will not be traced. - WARNING: One can't define both - a whitelist and a blacklist. Only one of them is allowed. Defining - the parameter a second time will just overwrite the first one. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_fifo", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_fifo", "trace_bwlist", "w: sip_trace") -... - - -
- -
- -
- - Exported Functions - - No function exported to be used from configuration file. - -
- -
- Example - - This is an example showing the FIFO format for the - get_statistics dialog: tm: MI commad: - response. - - - FIFO request - - -:reply_fifo:{"jsonrpc":"2.0","method":"get_statistics","id":"5672","params":[["dialog:","tm:"]]} - - - - -
- - -
- diff --git a/modules/mi_html/README b/modules/mi_html/README deleted file mode 100644 index c0f8f4ffc14..00000000000 --- a/modules/mi_html/README +++ /dev/null @@ -1,225 +0,0 @@ -mi_html Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. To-do - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - - 1.4. Exported Parameters - - 1.4.1. root(string) - 1.4.2. http_method(integer) - 1.4.3. trace_destination (string) - 1.4.4. trace_bwlist (string) - - 1.5. Exported Functions - 1.6. Known issues - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set root parameter - 1.2. Set http_method parameter - 1.3. Set trace_destination parameter - 1.4. Set trace_destination parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a minimal web user interface for the - OpenSIPS's Management Interface. - - Parameters for mi commands must be given in a json array - format. For example, to get all statistics, the param is to be - given as [["all"]]. To get only dialog and tm statistics, the - param is to be given as [["dialog:","tm:"]]. - -1.2. To-do - - Features to be added in the future: - * possibility to authenticate connections. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * httpd module. - -1.4. Exported Parameters - -1.4.1. root(string) - - Specifies the root path for the HTTP requests. The link to the - mi web interface must be constructed using the following - patern: http://[opensips_IP]:[opensips_mi_port]/[root] - - The default value is "mi". - - Example 1.1. Set root parameter -... -modparam("mi_html", "root", "opensips_mi") -... - -1.4.2. http_method(integer) - - Specifies the HTTP request method to be used: - * 0 - use GET HTTP request - * 1 - use POST HTTP request - - The default value is 0. - - Example 1.2. Set http_method parameter -... -modparam("mi_html", "http_method", 1) -... - -1.4.3. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.3. Set trace_destination parameter -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport -=tcp;version=3") - -modparam("mi_html", "trace_destination", "hep_dest") -... - -1.4.4. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.4. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_html", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_html", "trace_bwlist", "w: sip_trace") -... - -1.5. Exported Functions - - No function exported to be used from configuration file. - -1.6. Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there - isn't enough pkg memory configured). - - Future realeases of the httpd module will address this issue. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 63 32 2249 697 - 2. Vlad Patrascu (@rvlad-patrascu) 14 3 167 493 - 3. Liviu Chircu (@liviuchircu) 10 8 31 44 - 4. Razvan Crainea (@razvancrainea) 10 8 27 18 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 109 44 - 6. Ionut Ionita (@ionutrazvanionita) 8 5 217 10 - 7. Maksym Sobolyev (@sobomax) 5 3 3 4 - 8. Zero King (@l2dy) 3 1 2 2 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - 10. Vlad Paiu (@vladpaiu) 2 1 0 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jul 2014 - Mar 2024 - 2. Maksym Sobolyev (@sobomax) Oct 2020 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Mar 2015 - Jul 2020 - 4. Ovidiu Sas (@ovidiusas) Oct 2011 - Mar 2020 - 5. Zero King (@l2dy) Mar 2020 - Mar 2020 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2011 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ionut Ionita (@ionutrazvanionita) Jan 2017 - Feb 2017 - 10. Vlad Paiu (@vladpaiu) Jan 2016 - Jan 2016 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ovidiu Sas (@ovidiusas), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Ionut Ionita (@ionutrazvanionita), - Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2011-2013 VoIP Embedded, Inc. diff --git a/modules/mi_html/README.md b/modules/mi_html/README.md new file mode 100644 index 00000000000..09373e8c8dc --- /dev/null +++ b/modules/mi_html/README.md @@ -0,0 +1,169 @@ +--- +title: "mi_html Module" +description: "This module provides a minimal web user interface for the OpenSIPS's Management Interface." +--- + +## Admin Guide + + +### Overview + + +This module provides a minimal web user interface for the OpenSIPS's +Management Interface. + + +Parameters for mi commands must be given in a json array format. +For example, to get all statistics, the param is to be given as [["all"]]. +To get only dialog and tm statistics, the param is to be given as [["dialog:","tm:"]]. + + +### To-do + + +Features to be added in the future: + + +- possibility to authenticate connections. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *httpd* module. + + +### Exported Parameters + + +#### root(string) + + +Specifies the root path for the HTTP requests. +The link to the mi web interface must be constructed +using the following patern: +http://[opensips_IP]:[opensips_mi_port]/[root] + + +*The default value is "mi".* + + +```opensips title="Set root parameter" +... +modparam("mi_html", "root", "opensips_mi") +... +``` + + +#### http_method(integer) + + +Specifies the HTTP request method to be used: + + +- 0 - use GET HTTP request +- 1 - use POST HTTP request + + +*The default value is 0.* + + +```opensips title="Set http_method parameter" +... +modparam("mi_html", "http_method", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_html", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. +**WARNING:** One can't define both +a whitelist and a blacklist. Only one of them is allowed. Defining +the parameter a second time will just overwrite the first one. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep)**. + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_html", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_html", "trace_bwlist", "w: sip_trace") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Known Issues + + +Commands with large responses (like ul_dump) will fail if the +configured size of the httpd buffer is to small (or if there isn't +enough pkg memory configured). + + +Future realeases of the httpd module will address this issue. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_html/doc/contributors.xml b/modules/mi_html/doc/contributors.xml deleted file mode 100644 index f8784d581fe..00000000000 --- a/modules/mi_html/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 63 - 32 - 2249 - 697 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 14 - 3 - 167 - 493 - - - 3. - Liviu Chircu (@liviuchircu) - 10 - 8 - 31 - 44 - - - 4. - Razvan Crainea (@razvancrainea) - 10 - 8 - 27 - 18 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 109 - 44 - - - 6. - Ionut Ionita (@ionutrazvanionita) - 8 - 5 - 217 - 10 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 3 - 4 - - - 8. - Zero King (@l2dy) - 3 - 1 - 2 - 2 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 10. - Vlad Paiu (@vladpaiu) - 2 - 1 - 0 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jul 2014 - Mar 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Oct 2020 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Mar 2015 - Jul 2020 - - - 4. - Ovidiu Sas (@ovidiusas) - Oct 2011 - Mar 2020 - - - 5. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2011 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Jan 2017 - Feb 2017 - - - 10. - Vlad Paiu (@vladpaiu) - Jan 2016 - Jan 2016 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/mi_html/doc/mi_html.xml b/modules/mi_html/doc/mi_html.xml deleted file mode 100644 index 138fc49b73d..00000000000 --- a/modules/mi_html/doc/mi_html.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mi_html Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011-2013 VoIP Embedded, Inc. - - - - diff --git a/modules/mi_html/doc/mi_html_admin.xml b/modules/mi_html/doc/mi_html_admin.xml deleted file mode 100644 index 7e79b380cf7..00000000000 --- a/modules/mi_html/doc/mi_html_admin.xml +++ /dev/null @@ -1,191 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a minimal web user interface for the &osips;'s - Management Interface. - - - Parameters for mi commands must be given in a json array format. - For example, to get all statistics, the param is to be given as [["all"]]. - To get only dialog and tm statistics, the param is to be given as [["dialog:","tm:"]]. - - -
- -
- To-do - - Features to be added in the future: - - - - possibility to authenticate connections. - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - httpd module. - - - - -
-
- -
- Exported Parameters -
- <varname>root</varname>(string) - - Specifies the root path for the HTTP requests. - The link to the mi web interface must be constructed - using the following patern: - http://[opensips_IP]:[opensips_mi_port]/[root] - - - The default value is "mi". - - - Set <varname>root</varname> parameter - -... -modparam("mi_html", "root", "opensips_mi") -... - - -
-
- <varname>http_method</varname>(integer) - - Specifies the HTTP request method to be used: - - 0 - use GET HTTP request - 1 - use POST HTTP request - - - - The default value is 0. - - - Set <varname>http_method</varname> parameter - -... -modparam("mi_html", "http_method", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - This is where traced mi messages will go. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("mi_html", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_bwlist</varname> (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for - this parameter to have any purpose. Whitelists can be defined using - 'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the - actual blacklist by ':'. The mi commands in the list must be separated - by ','. - - - Defining a blacklists means all the commands that are not blacklisted - will be traced. Defining a whitelist means all the commands that are - not whitelisted will not be traced. - WARNING: One can't define both - a whitelist and a blacklist. Only one of them is allowed. Defining - the parameter a second time will just overwrite the first one. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_html", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_html", "trace_bwlist", "w: sip_trace") -... - - -
- - - -
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there isn't - enough pkg memory configured). - - - Future realeases of the httpd module will address this issue. - -
- -
- diff --git a/modules/mi_http/README b/modules/mi_http/README deleted file mode 100644 index 29935dc0ebb..00000000000 --- a/modules/mi_http/README +++ /dev/null @@ -1,262 +0,0 @@ -mi_http Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. External Libraries or Applications - 1.2.2. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. root(string) - 1.3.2. trace_destination (string) - 1.3.3. trace_bwlist (string) - - 1.4. Exported Functions - 1.5. Known issues - 1.6. Examples - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set root parameter - 1.2. Set trace_destination parameter - 1.3. Set trace_destination parameter - 1.4. JSON-RPC request - 1.5. JSON-RPC request with params - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a HTTP transport layer implementation for - OpenSIPS's Management Interface. - -1.2. Dependencies - -1.2.1. External Libraries or Applications - - None - -1.2.2. OpenSIPS Modules - - The following modules must be loaded before this module: - * httpd module. - -1.3. Exported Parameters - -1.3.1. root(string) - - Specifies the root path for HTTP requests: - http://[opensips_IP]:[opensips_httpd_port]/[root] - - The default value is "mi". - - Example 1.1. Set root parameter -... -modparam("mi_http", "root", "opensips_mi") -... - -1.3.2. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.2. Set trace_destination parameter -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport -=tcp;version=3") - -modparam("mi_http", "trace_destination", "hep_dest") -... - -1.3.3. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.3. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_http", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_http", "trace_bwlist", "w: sip_trace") -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there - isn't enough pkg memory configured). - - Future realeases of the httpd module will address this issue. - -1.6. Examples - - This is an example showing the JSON-RPC request and reply over - HTTP for the “ps” MI command. - - Example 1.4. JSON-RPC request - -POST /mi HTTP/1.1 -Accept: application/json -Content-Type: application/json -Host: example.net - -{"jsonrpc":"2.0","method":"ps","id":10} - -HTTP/1.1 200 OK -Content-Length: 317 -Content-Type: application/json -Date: Fri, 01 Nov 2013 12:00:00 GMT - -{"jsonrpc":"2.0","result":{"Processes":[{"ID":0,"PID":9467,"Type":"atten -dant"},{"ID":1,"PID":9468,"Type":"HTTPD127.0.0.1:8008"},{"ID":3,"PID":94 -70,"Type":"time_keeper"},{"ID":4,"PID":9471,"Type":"timer"},{"ID":5,"PID -":9472,"Type":"SIPreceiverudp:127.0.0.1:5060"},{"ID":7,"PID":9483,"Type" -:"Timerhandler"},]},"id":10} - - - This is an example showing the JSON-RPC request with params and - reply over HTTP for the “get_statistics” MI command. - - Example 1.5. JSON-RPC request with params - -POST /mi HTTP/1.1 -Accept: application/json -Content-Type: application/json -Host: example.net - -{"jsonrpc":"2.0","method":"get_statistics","params":[["dialog:","tm:"]], -"id":10} - -HTTP/1.1 200 OK -Content-Length: 317 -Content-Type: application/json -Date: Fri, 01 Nov 2013 12:00:00 GMT - -{"jsonrpc":"2.0","result":{"dialog:active_dialogs":0,"dialog:early_dialo -gs":0,"dialog:processed_dialogs":2,"dialog:expired_dialogs":0,"dialog:fa -iled_dialogs":2,"dialog:create_sent":0,"dialog:update_sent":0,"dialog:de -lete_sent":0,"dialog:create_recv":0,"dialog:update_recv":0,"dialog:delet -e_recv":0,"tm:received_replies":49252,"tm:relayed_replies":49220,"tm:loc -al_replies":370,"tm:UAS_transactions":49584,"tm:UAC_transactions":0,"tm: -2xx_transactions":12004,"tm:3xx_transactions":0,"tm:4xx_transactions":37 -580,"tm:5xx_transactions":0,"tm:6xx_transactions":0,"tm:inuse_transactio -ns":60},"id":10} - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Stephane Alnet 20 5 1265 233 - 2. Vlad Patrascu (@rvlad-patrascu) 19 3 170 814 - 3. Razvan Crainea (@razvancrainea) 15 12 171 34 - 4. Ionut Ionita (@ionutrazvanionita) 14 10 273 52 - 5. Liviu Chircu (@liviuchircu) 10 8 32 39 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 102 36 - 7. Vlad Paiu (@vladpaiu) 5 3 8 3 - 8. Maksym Sobolyev (@sobomax) 4 2 2 3 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - 10. Ovidiu Sas (@ovidiusas) 2 1 24 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jul 2014 - Mar 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Ovidiu Sas (@ovidiusas) Mar 2020 - Mar 2020 - 4. Razvan Crainea (@razvancrainea) Dec 2013 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2014 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionut Ionita (@ionutrazvanionita) May 2016 - Feb 2017 - 9. Vlad Paiu (@vladpaiu) Nov 2013 - Jan 2016 - 10. Stephane Alnet Oct 2013 - Nov 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ovidiu Sas (@ovidiusas), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Razvan Crainea (@razvancrainea), Ionut Ionita - (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), - Stephane Alnet. - - Documentation Copyrights: - - Copyright © 2013 shimaore.net diff --git a/modules/mi_http/README.md b/modules/mi_http/README.md new file mode 100644 index 00000000000..cab4917f801 --- /dev/null +++ b/modules/mi_http/README.md @@ -0,0 +1,184 @@ +--- +title: "mi_http Module" +description: "This module provides a HTTP transport layer implementation for OpenSIPS's Management Interface." +--- + +## Admin Guide + + +### Overview + + +This module provides a HTTP transport layer implementation +for OpenSIPS's Management Interface. + + +### Dependencies + + +#### External Libraries or Applications + + +None + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *httpd* module. + + +### Exported Parameters + + +#### root(string) + + +Specifies the root path for HTTP requests: +http://[opensips_IP]:[opensips_httpd_port]/[root] + + +*The default value is "mi".* + + +```opensips title="Set root parameter" +... +modparam("mi_http", "root", "opensips_mi") +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_http", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. +**WARNING:** One can't define both +a whitelist and a blacklist. Only one of them is allowed. Defining +the parameter a second time will just overwrite the first one. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep)**. + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_http", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_http", "trace_bwlist", "w: sip_trace") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Known Issues + + +Commands with large responses (like ul_dump) will fail if the +configured size of the httpd buffer is to small (or if there +isn't enough pkg memory configured). + + +Future realeases of the httpd module will address this issue. + + +### Examples + + +This is an example showing the JSON-RPC request and reply over HTTP +for the "ps" MI command. + + +```c title="JSON-RPC request" +POST /mi HTTP/1.1 +Accept: application/json +Content-Type: application/json +Host: example.net + +{"jsonrpc":"2.0","method":"ps","id":10} + +HTTP/1.1 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Fri, 01 Nov 2013 12:00:00 GMT + +{"jsonrpc":"2.0","result":{"Processes":[{"ID":0,"PID":9467,"Type":"attendant"},{"ID":1,"PID":9468,"Type":"HTTPD127.0.0.1:8008"},{"ID":3,"PID":9470,"Type":"time_keeper"},{"ID":4,"PID":9471,"Type":"timer"},{"ID":5,"PID":9472,"Type":"SIPreceiverudp:127.0.0.1:5060"},{"ID":7,"PID":9483,"Type":"Timerhandler"},]},"id":10} +``` + + +This is an example showing the JSON-RPC request with params and reply over HTTP +for the "get_statistics" MI command. + + +```c title="JSON-RPC request with params" +POST /mi HTTP/1.1 +Accept: application/json +Content-Type: application/json +Host: example.net + +{"jsonrpc":"2.0","method":"get_statistics","params":[["dialog:","tm:"]],"id":10} + +HTTP/1.1 200 OK +Content-Length: 317 +Content-Type: application/json +Date: Fri, 01 Nov 2013 12:00:00 GMT + +{"jsonrpc":"2.0","result":{"dialog:active_dialogs":0,"dialog:early_dialogs":0,"dialog:processed_dialogs":2,"dialog:expired_dialogs":0,"dialog:failed_dialogs":2,"dialog:create_sent":0,"dialog:update_sent":0,"dialog:delete_sent":0,"dialog:create_recv":0,"dialog:update_recv":0,"dialog:delete_recv":0,"tm:received_replies":49252,"tm:relayed_replies":49220,"tm:local_replies":370,"tm:UAS_transactions":49584,"tm:UAC_transactions":0,"tm:2xx_transactions":12004,"tm:3xx_transactions":0,"tm:4xx_transactions":37580,"tm:5xx_transactions":0,"tm:6xx_transactions":0,"tm:inuse_transactions":60},"id":10} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_http/doc/contributors.xml b/modules/mi_http/doc/contributors.xml deleted file mode 100644 index 447498672aa..00000000000 --- a/modules/mi_http/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Stephane Alnet - 20 - 5 - 1265 - 233 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 19 - 3 - 170 - 814 - - - 3. - Razvan Crainea (@razvancrainea) - 15 - 12 - 171 - 34 - - - 4. - Ionut Ionita (@ionutrazvanionita) - 14 - 10 - 273 - 52 - - - 5. - Liviu Chircu (@liviuchircu) - 10 - 8 - 32 - 39 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 102 - 36 - - - 7. - Vlad Paiu (@vladpaiu) - 5 - 3 - 8 - 3 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 10. - Ovidiu Sas (@ovidiusas) - 2 - 1 - 24 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jul 2014 - Mar 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Ovidiu Sas (@ovidiusas) - Mar 2020 - Mar 2020 - - - 4. - Razvan Crainea (@razvancrainea) - Dec 2013 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2014 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionut Ionita (@ionutrazvanionita) - May 2016 - Feb 2017 - - - 9. - Vlad Paiu (@vladpaiu) - Nov 2013 - Jan 2016 - - - 10. - Stephane Alnet - Oct 2013 - Nov 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Stephane Alnet. -
- -
diff --git a/modules/mi_http/doc/mi_http.xml b/modules/mi_http/doc/mi_http.xml deleted file mode 100644 index 298d2f515a5..00000000000 --- a/modules/mi_http/doc/mi_http.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mi_http Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2013 shimaore.net - - - - diff --git a/modules/mi_http/doc/mi_http_admin.xml b/modules/mi_http/doc/mi_http_admin.xml deleted file mode 100644 index cbc508a6fea..00000000000 --- a/modules/mi_http/doc/mi_http_admin.xml +++ /dev/null @@ -1,205 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a HTTP transport layer implementation - for &osips;'s Management Interface. - -
- -
- Dependencies -
- External Libraries or Applications - None - -
-
- &osips; Modules - - The following modules must be loaded before this module: - - - httpd module. - - - -
-
- -
- Exported Parameters -
- <varname>root</varname>(string) - - Specifies the root path for HTTP requests: - http://[opensips_IP]:[opensips_httpd_port]/[root] - - - The default value is "mi". - - - Set <varname>root</varname> parameter - -... -modparam("mi_http", "root", "opensips_mi") -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - This is where traced mi messages will go. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("mi_http", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_bwlist</varname> (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for - this parameter to have any purpose. Whitelists can be defined using - 'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the - actual blacklist by ':'. The mi commands in the list must be separated - by ','. - - - Defining a blacklists means all the commands that are not blacklisted - will be traced. Defining a whitelist means all the commands that are - not whitelisted will not be traced. - WARNING: One can't define both - a whitelist and a blacklist. Only one of them is allowed. Defining - the parameter a second time will just overwrite the first one. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_http", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_http", "trace_bwlist", "w: sip_trace") -... - - -
- - - -
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there - isn't enough pkg memory configured). - - - Future realeases of the httpd module will address this issue. - -
- -
- Examples - - This is an example showing the JSON-RPC request and reply over HTTP - for the ps MI command. - - - JSON-RPC request - - - - - - This is an example showing the JSON-RPC request with params and reply over HTTP - for the get_statistics MI command. - - - JSON-RPC request with params - - - - -
- -
- diff --git a/modules/mi_script/README b/modules/mi_script/README deleted file mode 100644 index c41207f3593..00000000000 --- a/modules/mi_script/README +++ /dev/null @@ -1,327 +0,0 @@ -MI script Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Values Returned - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. pretty_printing (int) - 1.4.2. trace_destination (string) - 1.4.3. trace_bwlist (string) - - 1.5. Exported Functions - - 1.5.1. mi(command, [ret_var [,params_avp[, - vals_avp]]]) - - 1.6. Exported Asyncronous Functions - - 1.6.1. mi(command, [ret_var [,params_avp[, - vals_avp]]]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set pretty_printing parameter - 1.2. Set trace_destination parameter - 1.3. Set trace_destination parameter - 1.4. mi without params - 1.5. mi with params in command - 1.6. mi with return - 1.7. mi without return but with indexed params - 1.8. mi with return and named parameters - 1.9. mi without return, with an array parameter value - 1.10. async mi call usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides multiple hooks to run Management Interface - commands directly from OpenSIPS script. It supports running - both synchronous and asynchronous commands. Depending on the - nature of the command (asynchronous or not), and on the way the - mi command is run from script, the returned result is - different. - -1.2. Values Returned - - In case of success, the MI command returns with success. If a - return variable is provided as parameter, a JSON is also stored - in the variable provided. - - In case of failure of the MI command, JSON-RPC reply error code - is stored in the $rc variable, as a negative number. Lower - values, such as -1,-2,-3 can also be returned to indicate an - internal error. If a return variable is provided, it is stored - to the error description. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * proto_hep module, in case MI tracing is used. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.4. Exported Parameters - -1.4.1. pretty_printing (int) - - Indicates whether the JSON responses stored in the return - variable should be pretty-printed or not. - - Default value is “0 - no pretty-printing”. - - Example 1.1. Set pretty_printing parameter -... -modparam("mi_script", "pretty_printing", 1) -... - -1.4.2. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.2. Set trace_destination parameter -... -modparam("proto_hep", "trace_id", "[hep_dest]10.0.0.2;transport=tcp;vers -ion=3") - -modparam("mi_script", "trace_destination", "hep_dest") -... - -1.4.3. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.3. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_script", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_script", "trace_bwlist", "w: sip_trace") -... - -1.5. Exported Functions - -1.5.1. mi(command, [ret_var [,params_avp[, vals_avp]]]) - - Runs an MI command in synchronous mode, blocking until a - response is available. - - IMPORTANT: it is highly recommended to prevent using this - function for tasks that take long time, such as reloads, as the - function would block until the command ends. Moreover, if the - running MI command is configured to run in asynchronous mode - (such as t_uac_dlg the command blocks in a busy waiting manner - until the response is received. - - This function can be used in any route. - - The function can receive the following parameters: - * command(string) - the MI command to be run. This can be a - single token, representing the MI command to run (without - parameters), or can be followed by several space separated - parameters (no escaping is handled). Each space separated - parameter will be passed to the MI command as an indexed - parameter. - NOTE: named parameters can not be specified using this - parameter, and you will have to use the params_avp and/or - the vals_avp parameters to specify named commands, in which - case this parameter will only consist of the MI command. - * ret_var(var, optional) - a variable used to store the - return of the MI command execution. In case of success, a - JSON is stored, otherwise an erorr message. - * params_avp(avp, optional) - an AVP consisting of all the - parameters names that will be sent to the MI command. If - this parameter is used without the vals_avp, all the values - inside the AVP will be passed to the MI command as indexed - parameters, otherwise as named parameters. - NOTE: if this parameter is used, the parameters specified - in the command parameter are ignored. - NOTE: the order the parameters are passed to the command is - the same as the one you populate the AVPs (thus somehow - reversed compared to the way AVPs are stored in memory - - the first AVP added is the first parameter) - * vals_avp(avp, optional) - an AVP consisting of all the - parameters values that will be sent to the MI command. This - parameter only makes sense if the params_avp is set, and - has to contain the same number of values as there are - parameters. - To specify array values, enclose your space-separated array - elements in the __array() pseudo-function call. For - example: "__array(HEARTBEAT BACKGROUND_JOB)" - - Example 1.4. mi without params -... -mi("shm_check"); -... - - Example 1.5. mi with params in command -... -# this command is similar to the above -mi("cache_remove local password_user1"); -... - - Example 1.6. mi with return -... -mi("ds_list", $var(ret)); -... - - Example 1.7. mi without return but with indexed params -... -$avp(params) = "local"; -$avp(params) = "password_user1"; -mi("cache_remove",,$avp(params)); - -# the following command is similar to the above -mi("cache_remove local password_user1"); -... - - Example 1.8. mi with return and named parameters -... -$avp(params) = "callid"; -$avp(vals) = "SEARCH_FOR_THIS_CALLID"; -$avp(params) = "from_tag"; -$avp(vals) = "SEARCH_FOR_THIS_FROM_TAG"; -mi("dlg_list", $var(dlg), $avp(params), $avp(vals)); -... - - Example 1.9. mi without return, with an array parameter value -... -$avp(params) = "freeswitch_url"; -$avp(vals) = "fs://:ClueCon@192.168.20.8:8021"; -$avp(params) = "events"; -$avp(vals) = "__array(HEARTBEAT BACKGROUND_JOB)"; -mi("fs_subscribe", , $avp(params), $avp(vals)); -... - -1.6. Exported Asyncronous Functions - -1.6.1. mi(command, [ret_var [,params_avp[, vals_avp]]]) - - The function works is more or less the same as its synchronous - corespondent, except that the MI command is run in an - asynchronous manner - the process does not block to wait for - the response, but it continues its execution and the MI command - is run in an asynchronous context. - - NOTE: currently MI commands run asynchronously cannot be traced - through hep. - - Example 1.10. async mi call usage -... -xlog("reload starting\n"); -async(mi("dr_reload"), after_reload); -... - -route[after_reload] { - xlog("reload completed\n"); -} - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 18 7 1116 17 - 2. Liviu Chircu (@liviuchircu) 5 3 69 8 - 3. Maksym Sobolyev (@sobomax) 5 3 7 8 - 4. Alexandra Titoc 3 1 4 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2021 - Jul 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Jun 2022 - Aug 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu - (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2021 OpenSIPS Solutions diff --git a/modules/mi_script/README.md b/modules/mi_script/README.md new file mode 100644 index 00000000000..d3c9acda8f4 --- /dev/null +++ b/modules/mi_script/README.md @@ -0,0 +1,307 @@ +--- +title: "MI script Module" +description: "This module provides multiple hooks to run Management Interface commands directly from OpenSIPS script." +--- + +## Admin Guide + + +### Overview + + +This module provides multiple hooks to run Management Interface +commands directly from OpenSIPS script. It supports running +both synchronous and asynchronous commands. Depending on the +nature of the command (asynchronous or not), and on the way +the *mi* command is run from script, +the returned result is different. + + +### Values Returned + + +In case of success, the MI command returns with success. +If a return variable is provided as parameter, +a JSON is also stored in the variable provided. + + +In case of failure of the MI command, JSON-RPC reply error code +is stored in the *$rc* variable, as a negative +number. Lower values, such as *-1,-2,-3* can also +be returned to indicate an internal error. If a return variable is +provided, it is stored to the error description. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *proto_hep module*, in case MI +tracing is used. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### pretty_printing (int) + + +Indicates whether the JSON responses stored in the return +variable should be pretty-printed or not. + + +*Default value is "0 - no pretty-printing".* + + +```opensips title="Set pretty_printing parameter" +... +modparam("mi_script", "pretty_printing", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_script", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. +> [!WARNING] +> One can't define both +> a whitelist and a blacklist. Only one of them is allowed. Defining +> the parameter a second time will just overwrite the first one. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep)**. + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_script", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_script", "trace_bwlist", "w: sip_trace") +... +``` + + +### Exported Functions + + +#### mi(command, [ret_var [,params_avp[, vals_avp]]]) + + +Runs an MI command in synchronous mode, blocking +until a response is available. + + +> [!IMPORTANT] +> It is highly recommended +> to prevent using this function for tasks that take long +> time, such as reloads, as the function would block until +> the command ends. Moreover, if the running MI +> *command* is configured to run in +> asynchronous mode (such as *t_uac_dlg* +> the command blocks in a busy waiting manner until +> the response is received. + + +This function can be used in any route. + + +The function can receive the following parameters: + + +- *command(string)* - the MI command +to be run. This can be a single token, representing +the MI command to run (without parameters), or +can be followed by several space separated +parameters (no escaping is handled). Each space +separated parameter will be passed to the MI +command as an indexed parameter. +*NOTE:* named parameters can +not be specified using this parameter, and you +will have to use the *params_avp* +and/or the *vals_avp* parameters +to specify named commands, in which case this +parameter will only consist of the MI command. +- *ret_var(var, optional)* - a +variable used to store the return of the +MI command execution. In case of success, +a JSON is stored, otherwise an erorr message. +- *params_avp(avp, optional)* - an +AVP consisting of all the parameters names that +will be sent to the MI command. If this parameter +is used without the *vals_avp*, +all the values inside the AVP will be passed to the +MI command as indexed parameters, otherwise as +named parameters. +*NOTE:* if this parameter +is used, the parameters specified in the +*command* parameter are ignored. +*NOTE:* the order the +parameters are passed to the command is the +same as the one you populate the AVPs (thus +somehow reversed compared to the way AVPs are +stored in memory - the first AVP added is the +first parameter) +- *vals_avp(avp, optional)* - an +AVP consisting of all the parameters values that +will be sent to the MI command. This parameter +only makes sense if the *params_avp* +is set, and has to contain the same number +of values as there are parameters. +To specify *array values*, enclose your +space-separated array elements in the *__array()* +pseudo-function call. For example: +*"__array(HEARTBEAT BACKGROUND_JOB)"* + + +```opensips title="mi without params" +... +mi("shm_check"); +... +``` + + +```opensips title="mi with params in command" +... +# this command is similar to the above +mi("cache_remove local password_user1"); +... +``` + + +```opensips title="mi with return" +... +mi("ds_list", $var(ret)); +... +``` + + +```opensips title="mi without return but with indexed params" +... +$avp(params) = "local"; +$avp(params) = "password_user1"; +mi("cache_remove",,$avp(params)); + +# the following command is similar to the above +mi("cache_remove local password_user1"); +... +``` + + +```opensips title="mi with return and named parameters" +... +$avp(params) = "callid"; +$avp(vals) = "SEARCH_FOR_THIS_CALLID"; +$avp(params) = "from_tag"; +$avp(vals) = "SEARCH_FOR_THIS_FROM_TAG"; +mi("dlg_list", $var(dlg), $avp(params), $avp(vals)); +... +``` + + +```opensips title="mi without return, with an array parameter value" +... +$avp(params) = "freeswitch_url"; +$avp(vals) = "fs://:ClueCon@192.168.20.8:8021"; +$avp(params) = "events"; +$avp(vals) = "__array(HEARTBEAT BACKGROUND_JOB)"; +mi("fs_subscribe", , $avp(params), $avp(vals)); +... +``` + + +### Exported Asynchronous Functions + + +#### mi(command, [ret_var [,params_avp[, vals_avp]]]) + + +The function works is more or less the same as its +synchronous corespondent, except that the MI command +is run in an asynchronous manner - the process does +not block to wait for the response, but it continues +its execution and the MI command is run in an +asynchronous context. + + +> [!NOTE] +> Currently MI commands run +> asynchronously cannot be traced through hep. + + +```opensips title="async mi call usage" +... +xlog("reload starting\n"); +async(mi("dr_reload"), after_reload); +... + +route[after_reload] { + xlog("reload completed\n"); +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_script/doc/contributors.xml b/modules/mi_script/doc/contributors.xml deleted file mode 100644 index d6e29e5145f..00000000000 --- a/modules/mi_script/doc/contributors.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 18 - 7 - 1116 - 17 - - - 2. - Liviu Chircu (@liviuchircu) - 5 - 3 - 69 - 8 - - - 3. - Maksym Sobolyev (@sobomax) - 5 - 3 - 7 - 8 - - - 4. - Alexandra Titoc - 3 - 1 - 4 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2021 - Jul 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Jun 2022 - Aug 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/mi_script/doc/mi_script.xml b/modules/mi_script/doc/mi_script.xml deleted file mode 100644 index a9c1fde3120..00000000000 --- a/modules/mi_script/doc/mi_script.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - MI script Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2021 OpenSIPS Solutions - - diff --git a/modules/mi_script/doc/mi_script_admin.xml b/modules/mi_script/doc/mi_script_admin.xml deleted file mode 100644 index 8f47b1a28b4..00000000000 --- a/modules/mi_script/doc/mi_script_admin.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides multiple hooks to run Management Interface - commands directly from OpenSIPS script. It supports running - both synchronous and asynchronous commands. Depending on the - nature of the command (asynchronous or not), and on the way - the mi command is run from script, - the returned result is different. - -
- -
- Values Returned - - In case of success, the MI command returns with success. - If a return variable is provided as parameter, - a JSON is also stored in the variable provided. - - - In case of failure of the MI command, JSON-RPC reply error code - is stored in the $rc variable, as a negative - number. Lower values, such as -1,-2,-3 can also - be returned to indicate an internal error. If a return variable is - provided, it is stored to the error description. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - proto_hep module, in case MI - tracing is used. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - none - - - - -
-
- -
- Exported Parameters - -
- <varname>pretty_printing</varname> (int) - - Indicates whether the JSON responses stored in the return - variable should be pretty-printed or not. - - - - Default value is 0 - no pretty-printing. - - - - Set <varname>pretty_printing</varname> parameter - -... -modparam("mi_script", "pretty_printing", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - This is where traced mi messages will go. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "trace_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("mi_script", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_bwlist</varname> (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for - this parameter to have any purpose. Whitelists can be defined using - 'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the - actual blacklist by ':'. The mi commands in the list must be separated - by ','. - - - Defining a blacklists means all the commands that are not blacklisted - will be traced. Defining a whitelist means all the commands that are - not whitelisted will not be traced. - WARNING: One can't define both - a whitelist and a blacklist. Only one of them is allowed. Defining - the parameter a second time will just overwrite the first one. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_script", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_script", "trace_bwlist", "w: sip_trace") -... - - -
- -
- -
- - Exported Functions -
- - <function moreinfo="none">mi(command, [ret_var [,params_avp[, vals_avp]]])</function> - - - Runs an MI command in synchronous mode, blocking - until a response is available. - - - IMPORTANT: it is highly recommended - to prevent using this function for tasks that take long - time, such as reloads, as the function would block until - the command ends. Moreover, if the running MI - command is configured to run in - asynchronous mode (such as t_uac_dlg - the command blocks in a busy waiting manner until - the response is received. - - - This function can be used in any route. - - - The function can receive the following parameters: - - - command(string) - the MI command - to be run. This can be a single token, representing - the MI command to run (without parameters), or - can be followed by several space separated - parameters (no escaping is handled). Each space - separated parameter will be passed to the MI - command as an indexed parameter. - NOTE: named parameters can - not be specified using this parameter, and you - will have to use the params_avp - and/or the vals_avp parameters - to specify named commands, in which case this - parameter will only consist of the MI command. - - - - ret_var(var, optional) - a - variable used to store the return of the - MI command execution. In case of success, - a JSON is stored, otherwise an erorr message. - - - params_avp(avp, optional) - an - AVP consisting of all the parameters names that - will be sent to the MI command. If this parameter - is used without the vals_avp, - all the values inside the AVP will be passed to the - MI command as indexed parameters, otherwise as - named parameters. - NOTE: if this parameter - is used, the parameters specified in the - command parameter are ignored. - - NOTE: the order the - parameters are passed to the command is the - same as the one you populate the AVPs (thus - somehow reversed compared to the way AVPs are - stored in memory - the first AVP added is the - first parameter) - - - - vals_avp(avp, optional) - an - AVP consisting of all the parameters values that - will be sent to the MI command. This parameter - only makes sense if the params_avp - is set, and has to contain the same number - of values as there are parameters. - - - To specify array values, enclose your - space-separated array elements in the __array() - pseudo-function call. For example: - "__array(HEARTBEAT BACKGROUND_JOB)" - - - - - - - <function>mi</function> without params - -... -mi("shm_check"); -... - - - - <function>mi</function> with params in command - -... -# this command is similar to the above -mi("cache_remove local password_user1"); -... - - - - <function>mi</function> with return - -... -mi("ds_list", $var(ret)); -... - - - - <function>mi</function> without return but with indexed params - -... -$avp(params) = "local"; -$avp(params) = "password_user1"; -mi("cache_remove",,$avp(params)); - -# the following command is similar to the above -mi("cache_remove local password_user1"); -... - - - - <function>mi</function> with return and named parameters - -... -$avp(params) = "callid"; -$avp(vals) = "SEARCH_FOR_THIS_CALLID"; -$avp(params) = "from_tag"; -$avp(vals) = "SEARCH_FOR_THIS_FROM_TAG"; -mi("dlg_list", $var(dlg), $avp(params), $avp(vals)); -... - - - - <function>mi</function> without return, with an array parameter value - -... -$avp(params) = "freeswitch_url"; -$avp(vals) = "fs://:ClueCon@192.168.20.8:8021"; -$avp(params) = "events"; -$avp(vals) = "__array(HEARTBEAT BACKGROUND_JOB)"; -mi("fs_subscribe", , $avp(params), $avp(vals)); -... - - -
-
- -
- Exported Asyncronous Functions -
- - <function moreinfo="none">mi(command, [ret_var [,params_avp[, vals_avp]]])</function> - - - The function works is more or less the same as its - synchronous corespondent, except that the MI command - is run in an asynchronous manner - the process does - not block to wait for the response, but it continues - its execution and the MI command is run in an - asynchronous context. - - - NOTE: currently MI commands run - asynchronously cannot be traced through hep. - - - <function moreinfo="none">async mi call</function> usage - -... -xlog("reload starting\n"); -async(mi("dr_reload"), after_reload); -... - -route[after_reload] { - xlog("reload completed\n"); -} - - -
-
- -
- diff --git a/modules/mi_xmlrpc_ng/README b/modules/mi_xmlrpc_ng/README deleted file mode 100644 index c4b3d872019..00000000000 --- a/modules/mi_xmlrpc_ng/README +++ /dev/null @@ -1,284 +0,0 @@ -mi_xmlrpc_ng Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. External Libraries or Applications - 1.2.2. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. http_root(string) - 1.3.2. trace_destination (string) - 1.3.3. trace_bwlist (string) - - 1.4. Exported Functions - 1.5. Known issues - 1.6. Example - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set http_root parameter - 1.2. Set trace_destination parameter - 1.3. Set trace_destination parameter - 1.4. XMLRPC request - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements a xmlrpc server that handles xmlrpc - requests and generates xmlrpc responses. When a xmlrpc message - is received a default method is executed. - - At first, it looks up the MI command. If found it parses the - called procedure's parameters into a MI tree and the command is - executed. A MI reply tree is returned that is formatted back in - xmlrpc. The response is built in two ways - like a string that - contains the MI tree nodes information (name, values and - attributes) or like an array whose elements are consisted of - each MI tree node stored information. - -1.2. Dependencies - -1.2.1. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml2 - -1.2.2. OpenSIPS Modules - - The following modules must be loaded before this module: - * httpd module. - -1.3. Exported Parameters - -1.3.1. http_root(string) - - Specifies the root path for xmlrpc requests: - http://[opensips_IP]:[opensips_httpd_port]/[http_root] - - The default value is "RPC2". - - Example 1.1. Set http_root parameter -... -modparam("mi_xmlrpc_ng", "http_root", "opensips_mi_xmlrpc") -... - -1.3.2. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. This is where traced mi - messages will go. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.2. Set trace_destination parameter -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport -=tcp;version=3") - -modparam("mi_xmlrpc_ng", "trace_destination", "hep_dest") -... - -1.3.3. trace_bwlist (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for this parameter to have - any purpose. Whitelists can be defined using 'w' or 'W', - blacklists using 'b' or 'B'. The type is separate by the actual - blacklist by ':'. The mi commands in the list must be separated - by ','. - - Defining a blacklists means all the commands that are not - blacklisted will be traced. Defining a whitelist means all the - commands that are not whitelisted will not be traced. WARNING: - One can't define both a whitelist and a blacklist. Only one of - them is allowed. Defining the parameter a second time will just - overwrite the first one. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.3. Set trace_destination parameter -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_xmlrpc_ng", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_xmlrpc_ng", "trace_bwlist", "w: sip_trace") -... - -1.4. Exported Functions - - No function exported to be used from configuration file. - -1.5. Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there - isn't enough pkg memory configured). - - Future realeases of the httpd and mi_xmlrpc_ng modules will - address this issue. - -1.6. Example - - This is an example showing the xmlrpc format for the - “get_statistics net: shmem:” MI commad: response. - - Example 1.4. XMLRPC request - -POST /xmlrpc HTTP/1.0 -Host: my.host.com -User-Agent: My xmlrpc UA -Content-Type: text/xml -Content-Length: 216 - - - - get_statistics - - - - - - statistics - - - - shmem: - core: - - - - - - - - - - - -HTTP/1.0 200 OK -Content-Length: 236 -Content-Type: text/xml; charset=utf-8 -Date: Mon, 8 Mar 2013 12:00:00 GMT - -. - - -net:waiting_udp0net:waiting_tcp -0net:waiting_tls0shmem:total_size268435456shmem:used -_size40032 -shmem:real_used_size277112shmem:max_used_size277112 -shmem:free_size2681 -58344shmem:fragments194
-. - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 29 15 1375 101 - 2. Vlad Patrascu (@rvlad-patrascu) 27 3 614 1041 - 3. Ionut Ionita (@ionutrazvanionita) 15 9 383 68 - 4. Razvan Crainea (@razvancrainea) 14 12 49 33 - 5. Liviu Chircu (@liviuchircu) 14 12 46 55 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 12 9 126 55 - 7. Ionel Cerghit (@ionel-cerghit) 11 3 515 166 - 8. Maksym Sobolyev (@sobomax) 4 2 2 3 - 9. Vlad Paiu (@vladpaiu) 3 2 0 6 - 10. Ken Rice 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov), Zero - King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Jul 2014 - Mar 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Zero King (@l2dy) Mar 2020 - Mar 2020 - 5. Razvan Crainea (@razvancrainea) Nov 2014 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jan 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ionut Ionita (@ionutrazvanionita) May 2016 - Feb 2017 - 10. Vlad Paiu (@vladpaiu) Mar 2014 - Jan 2016 - - All remaining contributors: Ionel Cerghit (@ionel-cerghit), - Ovidiu Sas (@ovidiusas). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita - (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), - Ionel Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2013 VoIP Embedded, Inc. diff --git a/modules/mi_xmlrpc_ng/README.md b/modules/mi_xmlrpc_ng/README.md new file mode 100644 index 00000000000..de694dc644d --- /dev/null +++ b/modules/mi_xmlrpc_ng/README.md @@ -0,0 +1,211 @@ +--- +title: "mi_xmlrpc_ng Module" +description: "This module implements a xmlrpc server that handles xmlrpc requests and generates xmlrpc responses." +--- + +## Admin Guide + + +### Overview + + +This module implements a xmlrpc server that handles xmlrpc +requests and generates xmlrpc responses. +When a xmlrpc message is received a default method is executed. + + +At first, it looks up the MI command. +If found it parses the called procedure's parameters +into a MI tree and the command is executed. +A MI reply tree is returned that is formatted back in xmlrpc. +The response is built in two ways - like a string that +contains the MI tree nodes information (name, values and +attributes) or like an array whose elements are consisted +of each MI tree node stored information. + + +### Dependencies + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libxml2* + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *httpd* module. + + +### Exported Parameters + + +#### http_root(string) + + +Specifies the root path for xmlrpc requests: +http://[opensips_IP]:[opensips_httpd_port]/[http_root] + + +*The default value is "RPC2".* + + +```opensips title="Set http_root parameter" +... +modparam("mi_xmlrpc_ng", "http_root", "opensips_mi_xmlrpc") +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +This is where traced mi messages will go. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("mi_xmlrpc_ng", "trace_destination", "hep_dest") +... +``` + + +#### trace_bwlist (string) + + +Filter traced mi commands based on a blacklist or a whitelist. +**trace_destination** must be defined for +this parameter to have any purpose. Whitelists can be defined using +'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the +actual blacklist by ':'. The mi commands in the list must be separated +by ','. + + +Defining a blacklists means all the commands that are not blacklisted +will be traced. Defining a whitelist means all the commands that are +not whitelisted will not be traced. + +> [!WARNING] +> One can't define both +> a whitelist and a blacklist. Only one of them is allowed. Defining +> the parameter a second time will just overwrite the first one. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +## blacklist ps and which mi commands +## all the other commands shall be traced +modparam("mi_xmlrpc_ng", "trace_bwlist", "b: ps, which") +... +## allow only sip_trace mi command +## all the other commands will not be traced +modparam("mi_xmlrpc_ng", "trace_bwlist", "w: sip_trace") +... +``` + + +### Exported Functions + + +No function exported to be used from configuration file. + + +### Known Issues + + +Commands with large responses (like ul_dump) will fail if the +configured size of the httpd buffer is to small (or if there +isn't enough pkg memory configured). + + +Future realeases of the httpd and mi_xmlrpc_ng modules +will address this issue. + + +### Example + + +This is an example showing the xmlrpc format for the +"get_statistics net: shmem:" MI commad: +response. + + +```c title="XMLRPC request" +POST /xmlrpc HTTP/1.0 +Host: my.host.com +User-Agent: My xmlrpc UA +Content-Type: text/xml +Content-Length: 216 + + + + get_statistics + + + + + + statistics + + + + shmem: + core: + + + + + + + + + + + +HTTP/1.0 200 OK +Content-Length: 236 +Content-Type: text/xml; charset=utf-8 +Date: Mon, 8 Mar 2013 12:00:00 GMT + +. + + +net:waiting_udp0net:waiting_tcp0net:waiting_tls0shmem:total_size268435456shmem:used_size40032shmem:real_used_size277112shmem:max_used_size277112shmem:free_size268158344shmem:fragments194 +. +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mi_xmlrpc_ng/doc/contributors.xml b/modules/mi_xmlrpc_ng/doc/contributors.xml deleted file mode 100644 index a2c9146d1ae..00000000000 --- a/modules/mi_xmlrpc_ng/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 29 - 15 - 1375 - 101 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 27 - 3 - 614 - 1041 - - - 3. - Ionut Ionita (@ionutrazvanionita) - 15 - 9 - 383 - 68 - - - 4. - Razvan Crainea (@razvancrainea) - 14 - 12 - 49 - 33 - - - 5. - Liviu Chircu (@liviuchircu) - 14 - 12 - 46 - 55 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 12 - 9 - 126 - 55 - - - 7. - Ionel Cerghit (@ionel-cerghit) - 11 - 3 - 515 - 166 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - 9. - Vlad Paiu (@vladpaiu) - 3 - 2 - 0 - 6 - - - 10. - Ken Rice - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jul 2014 - Mar 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Nov 2014 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jan 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ionut Ionita (@ionutrazvanionita) - May 2016 - Feb 2017 - - - 10. - Vlad Paiu (@vladpaiu) - Mar 2014 - Jan 2016 - - - -
-All remaining contributors: Ionel Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Ionel Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng.xml b/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng.xml deleted file mode 100644 index 4fde930e976..00000000000 --- a/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mi_xmlrpc_ng Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2013 VoIP Embedded, Inc. - - - - diff --git a/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng_admin.xml b/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng_admin.xml deleted file mode 100644 index 0bae8059dab..00000000000 --- a/modules/mi_xmlrpc_ng/doc/mi_xmlrpc_ng_admin.xml +++ /dev/null @@ -1,228 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements a xmlrpc server that handles xmlrpc - requests and generates xmlrpc responses. - When a xmlrpc message is received a default method is executed. - - - At first, it looks up the MI command. - If found it parses the called procedure's parameters - into a MI tree and the command is executed. - A MI reply tree is returned that is formatted back in xmlrpc. - The response is built in two ways - like a string that - contains the MI tree nodes information (name, values and - attributes) or like an array whose elements are consisted - of each MI tree node stored information. - -
- -
- Dependencies -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - libxml2 - - - -
-
- &osips; Modules - - The following modules must be loaded before this module: - - - httpd module. - - - -
-
- -
- Exported Parameters -
- <varname>http_root</varname>(string) - - Specifies the root path for xmlrpc requests: - http://[opensips_IP]:[opensips_httpd_port]/[http_root] - - - The default value is "RPC2". - - - Set <varname>http_root</varname> parameter - -... -modparam("mi_xmlrpc_ng", "http_root", "opensips_mi_xmlrpc") -... - - -
-
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - This is where traced mi messages will go. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "trace_destination", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("mi_xmlrpc_ng", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_bwlist</varname> (string) - - Filter traced mi commands based on a blacklist or a whitelist. - trace_destination must be defined for - this parameter to have any purpose. Whitelists can be defined using - 'w' or 'W', blacklists using 'b' or 'B'. The type is separate by the - actual blacklist by ':'. The mi commands in the list must be separated - by ','. - - - Defining a blacklists means all the commands that are not blacklisted - will be traced. Defining a whitelist means all the commands that are - not whitelisted will not be traced. - WARNING: One can't define both - a whitelist and a blacklist. Only one of them is allowed. Defining - the parameter a second time will just overwrite the first one. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -## blacklist ps and which mi commands -## all the other commands shall be traced -modparam("mi_xmlrpc_ng", "trace_bwlist", "b: ps, which") -... -## allow only sip_trace mi command -## all the other commands will not be traced -modparam("mi_xmlrpc_ng", "trace_bwlist", "w: sip_trace") -... - - -
- - - -
- -
- Exported Functions - - No function exported to be used from configuration file. - -
- -
- Known issues - - Commands with large responses (like ul_dump) will fail if the - configured size of the httpd buffer is to small (or if there - isn't enough pkg memory configured). - - - Future realeases of the httpd and mi_xmlrpc_ng modules - will address this issue. - -
- -
- Example - - This is an example showing the xmlrpc format for the - get_statistics net: shmem: MI commad: - response. - - - XMLRPC request - - - - get_statistics - - - - - - statistics - - - - shmem: - core: - - - - - - - - - - - -HTTP/1.0 200 OK -Content-Length: 236 -Content-Type: text/xml; charset=utf-8 -Date: Mon, 8 Mar 2013 12:00:00 GMT - -. - - -net:waiting_udp0net:waiting_tcp0net:waiting_tls0shmem:total_size268435456shmem:used_size40032shmem:real_used_size277112shmem:max_used_size277112shmem:free_size268158344shmem:fragments194 -. -]]> - - -
- -
- diff --git a/modules/mid_registrar/README b/modules/mid_registrar/README deleted file mode 100644 index 2d6d158d27e..00000000000 --- a/modules/mid_registrar/README +++ /dev/null @@ -1,1417 +0,0 @@ -mid_registrar Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Path Support (RFC 3327) - 1.1.2. GRUU Support (RFC 5627) - 1.1.3. SIP Push Notification Support (RFC 8599) - - 1.2. Working modes - - 1.2.1. Contact mirroring (default) - 1.2.2. Contact throttling - 1.2.3. AOR throttling - - 1.3. Auto-Insertion Into Future SIP Flows - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. mode (integer) - 1.5.2. contact_id_insertion (integer) - 1.5.3. contact_id_param (string) - 1.5.4. at_escape_str (string) - 1.5.5. outgoing_expires (integer) - 1.5.6. received_avp (string) - 1.5.7. received_param (string) - 1.5.8. extra_contact_params_avp (string) - 1.5.9. attr_avp (string) - 1.5.10. min_expires (integer) - 1.5.11. default_expires (integer) - 1.5.12. max_expires (integer) - 1.5.13. default_q (integer) - 1.5.14. tcp_persistent_flag (string) - 1.5.15. realm_prefix (string) - 1.5.16. case_sensitive (integer) - 1.5.17. expires_max_deviation (integer) - 1.5.18. max_contacts (integer) - 1.5.19. max_username_len (integer) - 1.5.20. max_domain_len (integer) - 1.5.21. max_aor_len (integer) - 1.5.22. max_contact_len (integer) - 1.5.23. retry_after (integer) - 1.5.24. disable_gruu (integer) - 1.5.25. gruu_secret (string) - 1.5.26. pn_enable (boolean) - 1.5.27. pn_providers (string) - 1.5.28. pn_ct_match_params (string) - 1.5.29. pn_pnsreg_interval (integer) - 1.5.30. pn_trigger_interval (integer) - 1.5.31. pn_skip_pn_interval (integer) - 1.5.32. pn_refresh_timeout (integer) - 1.5.33. pn_enable_purr (boolean) - - 1.6. Exported Functions - - 1.6.1. mid_registrar_save(domain[, flags[, aor[, - outgoing_expires[, ownership_tag]]]]) - - 1.6.2. mid_registrar_lookup(domain[, [flags][, - [aor]]]) - - 1.7. Exported Asynchronous Functions - - 1.7.1. pn_process_purr(domain) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the mode module parameter - 1.2. Setting the contact_id_insertion module parameter - 1.3. Setting the contact_id_param module parameter - 1.4. Setting the at_escape_str module parameter - 1.5. Setting the outgoing_expires module parameter - 1.6. Setting the received_avp module parameter - 1.7. Setting the received_param module parameter - 1.8. Setting the extra_contact_params_avp module parameter - 1.9. Set attr_avp parameter - 1.10. Setting the min_expires module parameter - 1.11. Setting the default_expires module parameter - 1.12. Setting the max_expires module parameter - 1.13. Setting the default_q module parameter - 1.14. Setting the tcp_persistent_flag module parameter - 1.15. Setting the realm_prefix module parameter - 1.16. Setting the case_sensitive module parameter - 1.17. Setting the expires_max_deviation parameter - 1.18. Set max_contacts parameter - 1.19. Setting the max_username_len module parameter - 1.20. Setting the max_domain_len module parameter - 1.21. Setting the max_aor_len module parameter - 1.22. Setting the max_contact_len module parameter - 1.23. Setting the retry_after module parameter - 1.24. Setting the gruu_secret module parameter - 1.25. Setting the gruu_secret module parameter - 1.26. Setting the pn_enable parameter - 1.27. Setting the pn_providers parameter - 1.28. Setting the pn_ct_match_params parameter - 1.29. Setting the pn_pnsreg_interval parameter - 1.30. Setting the pn_trigger_interval parameter - 1.31. Setting the pn_skip_pn_interval parameter - 1.32. Setting the pn_refresh_timeout parameter - 1.33. Setting the pn_enable_purr parameter - 1.34. mid_registrar_save usage - 1.35. mid_registrar_lookup usage - 1.36. async pn_process_purr() usage - -Chapter 1. Admin Guide - -1.1. Overview - - The mid_registrar is a mid-component of a SIP platform, - designed to work between end users and the platform's main - registration component. It opens up new possibilities for - leveraging existing infrastructure in order to continue to grow - (as subscribers and as registration traffic) while keeping an - existing low-resources registrar server. - - Acting as a registration front-end to the main SIP registrar, - the mid-registrar is able to: - * convert incoming high-rate registration traffic into a - low-rate variant, towards the main registrar layer. With - proper configuration, it can absorb over 90% of existing - registration traffic while correctly managing the - back-end's user location state, effectively reducing - resource usage at the respective layer. - * stay synchronized with the main registrar (from a user - location perspective), by properly accepting the contact - states and expirations it decides. - -1.1.1. Path Support (RFC 3327) - - The mid_registrar module includes SIP Path header field support - according to RFC 3327, for usage in registrars and - home-proxies. - - A call to mid_registrar_save() stores, if path support is - enabled in the mid_registrar module, the values of the Path - Header(s) along with the Contact information into usrloc. There - are three modes for building the reply to a REGISTER message - which includes one or more Path header fields: - * off - stores the value of the Path headers into usrloc - without passing it back to the UAC in the reply. - * lazy - stores the Path header and passes it back to the UAC - if Path-support is indicated by the “path” param in the - Supported HF. - * strict - rejects the registration with “420 Bad Extension” - if there's a Path header but no support for it is indicated - by the UAC. Otherwise it's stored and passed back to the - UAC. - - A call to mid_registrar_lookup() always uses the Path header if - found, and inserts it as Route HF either in front of the first - Route HF, or after the last Via HF if no Route is present. It - also sets the destination URI to the first Path URI, thus - overwriting the received-URI, because NAT has to be handled at - the outbound-proxy of the UAC (the first hop after client's - NAT). - - The whole process is transparent to the user, so no config - changes are required besides enabling one of the "p0" / "p1" / - "p2" flags when calling mid_registrar_save(). - -1.1.2. GRUU Support (RFC 5627) - - The mid_registrar module includes support for Globally Routable - User Agent URIs according to RFC 5627. - - A call to mid_registrar_save() stores, if the phone supports - GRUU, the values of the SIP Instance along with the contact - into usrloc. The module will generate two types of GRUUs: - * public - exposes the underlying AOR, constructed just by - attaching the SIP Instance as the ;gr parameter value. - These are persistent, valid as long as the contact - registration is valid. - * temporary - hides the underlying AOR Each new Register - request leads to the construction of a new temporary GRUU, - while Register requests with a different Call-ID lead to - the invalidation of all the previous generated temporary - GRUUs. - - A call to mid_registrar_lookup() will try to detect if the - R-URI contains a GRUU. If it does, it will route the request - just for the Contact that the specific AOR belongs to, without - appending any other branches. - - Even if the the GRUU handling during the registration process - is transparent to the user, so no config changes are required, - you need to take care of the GRUU specifics when handling - mid-dialog requests. - - As the GRUU will be present in the contact header of the - initial requests generated byt GRUU enabled devices, you will - have to also do a lookup() when receiving a mid-dialog request - with the GRUU indication in the RURI. - -1.1.3. SIP Push Notification Support (RFC 8599) - - The mid_registrar module includes support for standards-based - SIP Push Notifications, per RFC 8599. Support for the basic - version of the draft can be enabled by switching pn_enable to - true. The module also includes optional support for sending - Push Notifications during long-lived dialogs (see RFC section - 6), through the pn_enable_purr switch. - - Essential mechanics behind the Push Notification (PN) support: - * the PN support is fully compatible with the existing logic - and enabling it does not impose any limitations, as the - mid_registrar can simultaneously handle both SIP PN - compliant and standard SIP User Agents - * OpenSIPS will raise a E_UL_CONTACT_REFRESH event any time a - Push Notification needs to be sent to a PN-enabled contact. - The event includes the PN coordinates of the contact -- - they may be found in the Contact URI ('uri' event - parameter) and may be extracted using the {uri.param,name} - transformation. From here onwards, it is up to the script - developer to trigger the Push Notification (e.g. possibly - by sending an HTTP POST with the rest_client module), thus - forcing a re-registration from the device. - * REGISTER processing is unchanged -- PN-enabled UAs are - saved just as regular UAs, with the former ones - additionally having the 4 bitflag set in the "Flags" field - of any MI listing of contacts, for differentiation purposes - * initial INVITE processing is barely changed, with the - mid_registrar_lookup() function now additionally returning - a value of 2 if the only found contacts were PN-enabled - contacts, all which required a Push Notification. This - means that PNs have been triggered for each of them and - t_relay() is not required, since they are not reachable - until they re-register! - Using the event_routing module, OpenSIPS will transparently - fork a new branch from the current INVITE on each - re-registration from these contacts within the accepted - pn_refresh_timeout - * mid-dialog requests: In some cases (e.g. long-lived - dialogs), a PN may be required before being able to route a - mid-dialog request to a SIP UA. The pn_process_purr() async - function will take care of triggering the PN event and - resuming the script as soon as a re-registration from the - concerned contact is received. - - For more information or examples, refer to the documentation of - the "pn_xxx" module parameters or the OpenSIPS blog posts - around the "SIP Push Notification" topic. - -1.2. Working modes - - The mid_registrar may function in one of several modes: - -1.2.1. Contact mirroring (default) - - In "contact mirroring" mode, the mid-registrar will only insert - itself in the SIP traffic flow between end user and main - registrar by altering the Contact header field values. See - section Section 1.3, “Auto-Insertion Into Future SIP Flows” for - a detailed description of possible Contact-based insertion - modes. The incoming REGISTER requests will be proxied further - to the main registrar; the registered contact will be stored in - the mid-registrar only on 2xx replies, according to the - information returned by the main registrar. - - A possible usage of this mode, for example, would be to clone - registrations on a SIP front-end that extends the main platform - with new services (like adding IM/messaging routing). - -1.2.2. Contact throttling - - In "contact throttling" mode, the mid-registrar can - significantly reduce the registration rate on the main - registrar side (between mid-registrar and main registrar), - while coping with a high registration rate on the end-user side - (between end-user and mid-registrar). This is useful in - scenarios were the end-users are very dynamic and short-lived - (e.g. mobile devices), but the main registrar cannot cope with - large amounts of registration traffic. - - Traffic conversion is done in a "per-device" manner, according - to each unique SIP Contact header field value. It is achieved - by increasing the "expires" parameter value of each contact, - when relaying registrations to the main registrar. Once such a - registration is completed, subsequent registrations for the - same SIP Contact header field value will be continuously - absorbed by the mid-registrar until, eventually, the lifetime - of the remote registration will have decreased enough that a - refresh (i.e. simply forwarding the next REGISTER request) is - mandatory. - - A common occurence is for some SIP User Agents to lose their - network connection (especially when dealing with mobile - devices), hence they do not properly de-register from the - mid-registrar. In this case, in order to avoid stale - registrations on the main registrar (which contains SIP - contacts with greatly extended lifetimes!), the mid-registrar - will appropriately generate De-REGISTER requests and remove - these contacts from the main registrar's location service as - soon as it considers them to have expired. - - The main practical use for this mode is registration traffic - conversion. By minimizing the strain of processing - registrations on the main registrar, we allow it to dedicate - more system resources to critical areas of the platform, such - as advanced SIP calling features and/or media handling. - -1.2.3. AOR throttling - - In "AOR throttling" mode, the mid-registrar helps with handling - multiple registrations per user/AOR. This is done by - aggregating all the end-user registered contacts from a single - AOR under a single registration into the main registrar. This - can dramatically reduce the incoming rate of registrations (to - a single registration per AOR), but also helps in dealing with - registrar servers which are not able to implement parallel - forking/ringing. - - Traffic conversion is done in a "per-user" manner, according to - each unique SIP AOR. It is achieved by providing a contact with - a large "expires" parameter value, when relaying registrations - to the main registrar. Once such a registration is completed, - subsequent registrations to the same Address-of-record will be - continuously absorbed by the mid-registrar until, eventually, - the lifetime of the remote registration will have decreased - enough that a refresh (i.e. simply forwarding the next REGISTER - request) is mandatory. - - A common occurence is for some SIP User Agents to lose their - network connection (especially when dealing with mobile - devices), hence they do not properly de-register from the - mid-registrar. In this case, in order to avoid stale - registrations on the main registrar (which contains SIP AORs - with greatly extended lifetimes!), the mid-registrar will - appropriately generate De-REGISTER requests and remove these - contacts from the main registrar's location service as soon as - it considers them to have expired. - - Of all three modes, "AOR throttling" potentially offers the - best reduction in traffic on the way to the main registrar. By - aggregating contacts, it also has the added benefit of reducing - the number of contacts that the main registrar must handle. - - Regarding SIP request mangling in this mode, the module will - always replace all Contact header field values with a single - Contact header field value when proxying registrations to the - main registrar, indicating that the AOR is local to the - front-end, and its contacts can be found there. - - The main practical uses for this mode are registration traffic - conversion towards the main registrar, as well as taking over - its call forking duties. By minimizing the strain of processing - registrations / forking calls on the main registrar, we allow - it to dedicate more system resources to critical areas of the - platform, such as advanced SIP calling features and/or media - handling. - -1.3. Auto-Insertion Into Future SIP Flows - - A defining feature of the mid-registrar is that it must be easy - to integrate, ideally a "plug-and-play" SIP component. It - should not impose any "outbound-proxy" configurations on any of - the platform's layers and automatically insert itself on the - call flows which follow successful registrations. - - Regardless of its configured working mode, the mid-registrar - will mangle the Contact header field URIs of all forwarded - REGISTER requests and replace the original "hostname" and - "port" parts of a Contact URI with one of its listening - interfaces. - - Additionally, in modes "0" and "1", each Contact will be - assigned an unique identifier, which will be utilized in future - contact-based lookup operations. This information will be - included in each forwarded Contact URI. The - contact_id_insertion modparam controls how this information is - included. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * usrloc - * signaling - * tm - * event_routing, if pn_enable is set to true. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.5. Exported Parameters - -1.5.1. mode (integer) - - Working mode of the module. Refer to Section 1.2, “Working - modes” for more details. - - The following is true for all working modes: - * when a REGISTER is received, the script writer must call - mid_registrar_save() - * the mid-registrar will insert itself on the call flow of - all registrations according to the contact_id_insertion. - * registrations forwarded by the mid-registrar will - transparently result in a user location update only if the - reply status code from the downstream registrar is 2xx. - - Each working mode behaves differently, as follows: - * 0 (Contact mirroring mode) - The module will only insert itself on the call flow. - Contact expirations are left unchanged. - * 1 (Contact throttling mode) - Contact throttling is a first step in lowering registration - traffic rates. This is possible through the use of the - outgoing_expires module parameter or the corresponding - parameter to mid_registrar_save(), which allow the script - writer to prolong the life of the registrations on the way - to the main registrar. - In this mode, the mid-registrar may alter Expires header - field values or "expires" Contact header field parameters - found in the initial request when forwarding registrations, - according to outgoing_expires - * 2 (AOR throttling mode) - AOR throttling is a step beyond "Contact throttling", as - the main registrar is only made aware of the network - presence of AORs, rather than Contacts. This behaviour is - also made possible through the outgoing_expires module - parameter or the corresponding parameter to - mid_registrar_save(), which allow the script writer to - prolong the life of the registrations on the way to the - main registrar. - In this mode, the mid-registrar will fully replace the - Contact set of all forwarded registrations with a single - Contact, advertising that the AOR is available to the main - registrar. The expiration value for this Contact is given - by outgoing_expires. - - Default value is 0 (contact mirroring mode) - - Example 1.1. Setting the mode module parameter -modparam("mid_registrar", "mode", 2) - -1.5.2. contact_id_insertion (integer) - - Only relevant in a "mirroring" or "contact throttling" mode. - Controls where the additional unique Contact identification - information (64-bit, hex-encoded integer) will be placed within - outgoing Contact header field URIs. Refer to Section 1.3, - “Auto-Insertion Into Future SIP Flows” for more details. - - Possible values are: - * "ct-param" (default) - the contact IDs shall be appended to - outgoing Contact URIs as ";ctid=" parameters. - * "ct-username" - the contact IDs will substitute the - "username" parts of outgoing Contact URIs - - Example 1.2. Setting the contact_id_insertion module parameter -modparam("mid_registrar", "contact_id_insertion", "ct-username") - -1.5.3. contact_id_param (string) - - Only relevant in a "mirroring" or "contact throttling" mode. - Specifies the name of the Contact URI parameter which is used - by the module in order to match contacts and route SIP - requests. - - Default value is “ctid” - - Example 1.3. Setting the contact_id_param module parameter -modparam("mid_registrar", "contact_id_param", "ctid") - -# Example resulting Contact header field: -# Contact: ;expires=18 -0. - -1.5.4. at_escape_str (string) - - Only relevant when in "AoR throttling" mode and with the usrloc - use_domain setting enabled. This string represents the escape - sequence for the "@" character, which must be included, in one - way or another, in mid-registrar's generated Contact URI - usernames. - - Setting this parameter to a different value may be useful in - situations where the backend registrar is incompatible with the - default escape string. - - Default value is “%40” - - Example 1.4. Setting the at_escape_str module parameter -modparam("mid_registrar", "at_escape_str", "___") - -# Example Contact header field generated by mid-registrar: -# Contact: ;expires=120 - -1.5.5. outgoing_expires (integer) - - Only relevant in Contact/AOR throttling modes. Sets a minimal - value for the expiration intervals of egressing contacts. - - Default value is 3600 (seconds) - - Example 1.5. Setting the outgoing_expires module parameter -modparam("mid_registrar", "outgoing_expires", 3600) - -1.5.6. received_avp (string) - - The module will store the value of the AVP configured by this - parameter in the received column of the user location table. It - will leave the column empty if the AVP is empty. The AVP should - contain a SIP URI consisting of the source IP, port, and - protocol of the REGISTER message being processed. - -Note - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - Default value is "NULL" (disabled) - - Example 1.6. Setting the received_avp module parameter -modparam("mid_registrar", "received_avp", "$avp(rcv)") - -1.5.7. received_param (string) - - The name of the parameter that will be appended to Contacts of - 200 OK replies if the received URI is set by nathelper module. - -Note - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - Default value is "received" - - Example 1.7. Setting the received_param module parameter -modparam("mid_registrar", "received_param", "rcv") - -1.5.8. extra_contact_params_avp (string) - - An AVP specification. This AVP is evaluated during - mid_registrar_save(): if it holds a valid string, its content - will be appended to each new Contact URI built by the - mid-registrar, for the outgoing request. - - Default value is None (not used) - - Example 1.8. Setting the extra_contact_params_avp module - parameter -# NB: AVPs are cleared with every new SIP request -modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_par -ams)") - -# setting the AVP during SIP message processing -$avp(extra_ct_params) = ";transport=tls"; - -1.5.9. attr_avp (string) - - AVP to store specific additional information for each - registration. This information is read from the AVP and stored - (in memory, DB or both) at mid_registrar_save(). When the - mid_registrar_lookup() or 'is_registered()' (registrar) - functions are called, the attr_avp will be populated with the - value saved at [re]registration. - - When doing call forking, the AVP will hold multiple values. The - position of the corresponding attribute information in attr_avp - is equal to the branch index. An example scenario is given - below. - - Default value is NULL. - - Example 1.9. Set attr_avp parameter -# reading attributes from the attr_pvar when doing parallel forking -... -modparam("mid_registrar", "attr_avp", "$avp(attr)") - -... -if (is_method("REGISTER")) { - $avp(attr) = "contact_info"; - mid_registrar_save("location"); - exit; -} -... -mid_registrar_lookup("location"); -t_on_branch("parallel_fork"); -... -branch_route [parallel_fork] { - xlog("Attributes for branch $T_branch_idx: $(avp(attr)[$T_branch -_idx])\n"); -} - - -1.5.10. min_expires (integer) - - The minimum expires value of a Contact, values lower than this - minimum will be automatically set to the minimum. Value 0 - disables the checking. - - Default value is 10 (seconds) - - Example 1.10. Setting the min_expires module parameter -modparam("mid_registrar", "min_expires", 600) - -1.5.11. default_expires (integer) - - If the processed message contains neither Expires HFs nor - expires contact parameters, this value will be used as the - expiration interval of any newly created usrloc records. - - Default value is 3600 (seconds) - - Example 1.11. Setting the default_expires module parameter -modparam("mid_registrar", "default_expires", 1800) - -1.5.12. max_expires (integer) - - The maximum expires value of a Contact, values higher than this - maximum will be automatically set to the maximum. Value 0 - disables the checking. - - Default value is 3600 (seconds) - - Example 1.12. Setting the max_expires module parameter -modparam("mid_registrar", "max_expires", 7200) - -1.5.13. default_q (integer) - - Sets the default "q" value for new contacts. Because OpenSIPS - does not support floating point module parameters, the supplied - "q" value must be multiplied by 1000. For example, if you want - default_q to be 0.38, set this parameter to 380. - - Default value is 0 - - Example 1.13. Setting the default_q module parameter -modparam("mid_registrar", "default_q", 380) - -1.5.14. tcp_persistent_flag (string) - - Specifies the message flag to be used to control the module - behaviour regarding TCP connections. If the flag is set for a - REGISTER via TCP containing a TCP contact, the module, via the - mid_registrar_save() function, will set the lifetime of the TCP - connection to the contact expire value. By doing this, the TCP - connection will stay up as long as its contacts are valid. - - Default value is -1 (not set) - - Example 1.14. Setting the tcp_persistent_flag module parameter -modparam("mid_registrar", "tcp_persistent_flag", "TCP_PERSIST_REGISTRATI -ONS") - -1.5.15. realm_prefix (string) - - In multi-domain user location scenarios ("use_domain" usrloc - module parameter set to "1"), this parameter denotes a prefix - to be automatically stripped from the hostname part of To - header field URIs when doing a save, or Request-URIs when doing - a lookup. - - It is meant as an alternative to DNS SRV records (not all SIP - clients support SRV lookups), a subdomain of the master domain - can be defined for SIP purposes (like "sip.mydomain.net" - pointing to same IP address as the SRV record for - "mydomain.net"). By ignoring the realm_prefix "sip.", at - registration, "sip.mydomain.net" will be translated to - "mydomain.net". - - Default value is NULL (none) - - Example 1.15. Setting the realm_prefix module parameter -modparam("mid_registrar", "realm_prefix", "sip.") - -1.5.16. case_sensitive (integer) - - If set to 1, then AOR comparison will be case sensitive (as - RFC3261 instructs), if set to 0 then AOR comparison will be - case insensitive. - - Default value is 1 (true) - - Example 1.16. Setting the case_sensitive module parameter -modparam("mid_registrar", "case_sensitive", 0) - -1.5.17. expires_max_deviation (integer) - - Set this parameter in order to add a random +/- deviation up to - and including the given value to the expiration interval of a - newly registered contact. For example, if this parameter is set - to 100 and a phone registers for 1800 sec, the final expiry - will be a random number in the [1700, 1900] interval. - - By randomizing the registration lifetimes of the contacts, the - server is better equipped to deal with a post-restart - registration storm, when all TCP connections are lost and a - significant portion of UAs will re-register at the same time. - Thanks to the contact lifetime randomization, the registration - storm will only happen once rather than, e.g., every 1800 - seconds following the restart. - - Default value is 0 (no deviation). - - Example 1.17. Setting the expires_max_deviation parameter -... -# add a random +/- 0-100 seconds to each registration lifetime -modparam("mid_registrar", "expires_max_deviation", 100) -... - -1.5.18. max_contacts (integer) - - The parameter can be used to limit the number of contacts per - AOR (Address of Record) in the user location database. Value 0 - disables the check. - - This is the default value and will be used only if no other - value (for max_contacts) is passed as parameter to the save() - function. That's it - the function parameter overwride this - global parameter. - - Default value is 0. - - Example 1.18. Set max_contacts parameter -... -# Allow no more than 10 contacts per AOR -modparam("mid_registrar", "max_contacts", 10) -... - -1.5.19. max_username_len (integer) - - The maximum length of the "username" part of an - Address-of-Record SIP URI. - - Default value is 64. - - Example 1.19. Setting the max_username_len module parameter -modparam("mid_registrar", "max_username_len", 128) - -1.5.20. max_domain_len (integer) - - The maximum length of the "domain" part of an Address-of-Record - SIP URI. - - Default value is 64. - - Example 1.20. Setting the max_domain_len module parameter -modparam("mid_registrar", "max_domain_len", 128) - -1.5.21. max_aor_len (integer) - - The maximum length of an Address-of-Record SIP URI. - - Default value is 256. - - Example 1.21. Setting the max_aor_len module parameter -modparam("mid_registrar", "max_aor_len", 512) - -1.5.22. max_contact_len (integer) - - The maximum length of a Contact header field SIP URI. - - Default value is 255. - - Example 1.22. Setting the max_contact_len module parameter -modparam("mid_registrar", "max_contact_len", 512) - -1.5.23. retry_after (integer) - - The mid-registrar can generate 5xx replies to registrations in - various situations. It could, for example, happen when the - max_contacts parameter is set and the processing of REGISTER - request would exceed the limit. In this case, OpenSIPS would - respond with "503 Service Unavailable". - - If you want to add the Retry-After header field in 5xx replies, - set this parameter to a value greater than zero (0 means: do - not add the header field). See section 20.33 of RFC3261 for - more details. - - Default value is 0 (disabled) - - Example 1.23. Setting the retry_after module parameter -modparam("mid_registrar", "retry_after", 30) - -1.5.24. disable_gruu (integer) - - Globally disable GRUU handling. - - Default value is 1 (GRUUs will not be handled) - - Example 1.24. Setting the gruu_secret module parameter -modparam("mid_registrar", "disable_gruu", 0) - -1.5.25. gruu_secret (string) - - The string that will be used in XORing when generating - temporary GRUUs. - - Default value is "0p3nS1pS" - - Example 1.25. Setting the gruu_secret module parameter -modparam("mid_registrar", "gruu_secret", "my_secret") - -1.5.26. pn_enable (boolean) - - Enable SIP Push Notification support (RFC 8599). If enabled, - Contact header field URIs which include all pn_ct_match_params - will be matched against existing bindings using only these - parameters. Otherwise, the module will attempt to match them as - usual, using the current usrloc matching_mode. - - Default value is false. - - Example 1.26. Setting the pn_enable parameter -... -modparam("mid_registrar", "pn_enable", true) -... - -1.5.27. pn_providers (string) - - A list of supported Push Notification providers. While only - three possible values are defined by RFC 8599 ("apns", "fcm" - and "webpush"), non-standard values may be specified as well. - - Default value is NULL (not set). - - Example 1.27. Setting the pn_providers parameter -... -modparam("mid_registrar", "pn_providers", "apns, fcm, webpush") -... - -1.5.28. pn_ct_match_params (string) - - The minimally required list of RFC 8599 parameters (custom ones - are accepted as well) which must be present in a Contact URI - and identically match an existing binding in order for the - binding to be refreshed during a SIP re-REGISTER. If at least - one such parameter is missing from a Contact header field URI, - the module will fall back to performing regular contact - matching. - - Note that if all above PN Contact URI parameters match an - existing binding, the match is considered to be successful - regardless if other parts of the SIP URI do not match (e.g. - hostname, port, other URI parameters, etc.). - - After calling mid_registrar_lookup() or pn_process_purr(), the - above PN-related parameters will be automatically stripped from - the resulting Request and Contact URI event parameter, - respectively. - - Default value is "pn-provider, pn-prid, pn-param". - - Example 1.28. Setting the pn_ct_match_params parameter -... -modparam("mid_registrar", "pn_ct_match_params", "pn-provider, pn-prid") -... - -1.5.29. pn_pnsreg_interval (integer) - - For devices capable of waking up and refreshing their binding - on their own (signified by the ";+sip.pnsreg" Contact header - field parameter), this setting denotes the prior-to-expiration - interval advertised by the server at which the device should - issue its binding refresh request. - - Default value is 130 (seconds before expiry). - - Example 1.29. Setting the pn_pnsreg_interval parameter -... -modparam("mid_registrar", "pn_pnsreg_interval", 140) -... - -1.5.30. pn_trigger_interval (integer) - - If a binding refresh REGISTER request from a given SIP endpoint - does not arrive within at least pn_trigger_interval seconds - prior to expiration (e.g. because the device does not support - ";+sip.pnsreg" or because of other error conditions), the - E_UL_CONTACT_REFRESH usrloc event will be triggered. - - Once E_UL_CONTACT_REFRESH is triggered, the script writer - should use the RFC 8599 parameters from the Contact URI in - order to generate a Push Notification request to the PN - provider of the device, in order to cause the device to wake up - and re-register. - - Default value is 120 (seconds before expiry). - - Example 1.30. Setting the pn_trigger_interval parameter -... -modparam("mid_registrar", "pn_trigger_interval", 130) -... - -1.5.31. pn_skip_pn_interval (integer) - - Following a successful (re)registration of a contact, this - setting denotes a time interval, in seconds, during which the - contact is assumed to be reachable, so any Push Notifications - will be skipped. - - Default value is 0 seconds (always generate Push - Notifications). - - Example 1.31. Setting the pn_skip_pn_interval parameter -... -modparam("mid_registrar", "pn_skip_pn_interval", 10) -... - -1.5.32. pn_refresh_timeout (integer) - - This timeout starts counting following a mid_registrar_lookup() - or a pn_process_purr() which triggers a Push Notification. The - value represents the maximum allowed sum of the duration - required for the Push Notification to be sent and the duration - required for the corresponding re-registration from the device - to arrive. - - Once this timeout is exceeded for an initial or a mid-dialog - request, any further re-registrations which match the pending - Push Notification will no longer cause the desired effects. For - example: - * pending initial INVITE transactions will complete and will - no longer auto-fork an additional branch for each REGISTER - sent by the callee side - * pending BYE messages will time out and OpenSIPS will - attempt to route them despite not having received a - confirmation that the target device is actually reachable - - Default value is 6 seconds. - - Example 1.32. Setting the pn_refresh_timeout parameter -... -modparam("mid_registrar", "pn_refresh_timeout", 10) -... - -1.5.33. pn_enable_purr (boolean) - - Enable the SIP Push Notification mechanism for long-lived - dialogs. If enabled, the mid_registrar will include a - "+sip.pnspurr" Feature-Caps header field tag in 200 OK replies - to REGISTER requests. This tag represents a unique identifier - for the registration (PURR - Proxy Unique Registration - Reference). - - During dialog setup, each UA may include, in its Contact - header, the PURR value returned by OpenSIPS during - registration. By including the PURR (e.g. ";pn-purr=XXX"), an - agent indicates that it expects to be first awoken by a PN - before being able to receive a mid-dialog request sent by the - other party. - - When enabling this parameter, make sure to also add logic for - pn_process_purr(). - - Default value is false. - - Example 1.33. Setting the pn_enable_purr parameter -... -modparam("mid_registrar", "pn_enable_purr", true) -... - -1.6. Exported Functions - -1.6.1. mid_registrar_save(domain[, flags[, aor[, outgoing_expires[, -ownership_tag]]]]) - - Function to be called when handling REGISTER requests. This - function decides if a REGISTER should be forwarded to the main - registrar and performs all the necessary changes over the - registered contacts. The function is also covering the handling - of the 2xx REGISTER replies - the contacts confirmed by the - main registrar will be automatically saved in the local user - location (without any additional scripting). - - In Contact/AOR throttling modes (more info about working modes - in Section 1.2, “Working modes”), the return value of this - function indicates whether the script writer must forward the - REGISTER request to the main registrar, or just wrap up any - left-over processing and exit script execution, as the current - REGISTER request has been answered with 200 OK (absorbed at - mid-registrar level). - - Depending on the current working mode and contact_id_insertion, - the function may additionally perform the following series of - transformations when relaying REGISTER requests: - - * in "Contact throttling" mode - + change the value of the Expires header field to the - value of outgoing_expires, if given, otherwise the - value given by the outgoing_expires module parameter. - The same applies to any ";expires" Contact URI - parameter. - + replace the "host:port" part of all Contact URIs of - the incoming REGISTER request with an OpenSIPS - listening interface - + append a parameter to each Contact URI, which will - allow the module to match the reply contacts and also - route calls. The name of this URI parameter is - configurable via contact_id_param - * in "AOR throttling" mode - + change the value of the Expires header field to the - value of outgoing_expires, if given, otherwise the - value given by the outgoing_expires module parameter. - + replace all Contact header fields of the request with - a single Contact header field, which will contain the - following SIP URI: - "sip:address-of-record@proxy_ip:proxy_port" - - Meaning of the parameters is as follows: - * domain (static string) - logical domain within the - registrar. If a database is used, then this must be name of - the usrloc table which stores the contacts - * flags (string, optional) - string composed of one or more - of the following flags, comma-separated: - + 'memory-only' - (old m flag) save the contacts only in - memory cache without no DB operation; - + 'no-reply' - (old r flag) do not generate a SIP reply - to the current REGISTER request. - + 'max-contacts=[int]' - (old c flag) this flag can be - used to limit the number of contacts for this AOR - (Address of Record) in the user location database. - Value 0 disables the check. This parameter overrides - the global "max_contacts" module parameter. - + 'force-registration' - (old f flag) this flag can be - used to force the registration of NEW contacts even if - the maximum number of contacts is reached. In such a - case, older contacts will be removed to make space to - the new ones, without exceeding the maximum allowed - number. This flag makes sense only if "max-contacts" - is used. - + 'matching-mode=[val]' - (old M flag) How the matching - should be performed between the uploaded contacts (by - the currently handled REGISTER) and the already know - contacts (in memory or DB). This options will be used - only for the current operation and can be: - o '0' - contact URI matching only - o '1' - contact URI and SIP Call-ID matching - o '' - only the value of the given URI - param will be used for matching (for example - ) - + 'path-off' - (old p0 flag) (Path support - 'off' mode) - - The Path header is saved into usrloc, but is never - included in the reply. - + 'path-lazy' - (old p1 flag) (Path support - lazy mode) - The Path header is saved into usrloc, but is only - included in the reply if path support is indicated in - the registration request by the “path” option of the - “Supported” header. - + 'path-strict' - (old p2 flag) (Path support - strict - mode) - The path header is only saved into usrloc, if - path support is indicated in the registration request - by the “path” option of the “Supported” header. If no - path support is indicated, the request is rejected - with “420 - Bad Extension” and the header - “Unsupported: path” is included in the reply along - with the received “Path” header. This mode is the one - recommended by RFC-3327. - + 'path-received' - (old v flag) if set, the “received” - parameter of the first Path URI of a registration is - set as received-uri and the NAT branch flag is set for - this contact. This is useful if the registrar is - placed behind a SIP loadbalancer, which passes the - nat'ed UAC address as “received” parameter in it's - Path uri. - + 'only-request-contacts' - (old o flag) Only include - the REGISTER request's Contacts in the 200 OK reply, - in case the registration is successful. While this is - against RFC 3261, it may be useful in certain - scenarios. - * aor (string, optional) - a custom Address-of-Record. If not - given, the AOR will be taken from the To header URI - * outgoing_expires (int, optional) - only relevant in - Contact/AOR throttling modes, this is a custom value for - the contact expiration interval of the outgoing REGISTER - request, which overrides the default outgoing_expires - module parameter. - * ownership_tag (string, optional) - a cluster-shared tag - (see the clusterer module documentation for more details) - which will be attached to each contact saved from the - current request. This tag is only relevant in clustered - user location scenarios and helps determine the current - logical owner node of a contact. This, in turn, is useful - in order to restrict nodes which are not currently - responsible for this contact from performing certain - actions (for example: incorrectly originating pings from a - non-owned virtual IP address in highly-available setups). - - Return value - * 1 (success) - current REGISTER request must be dispatched - by the script writer over to the main registrar - * 2 (success) - current REGISTER request has been absorbed by - the mid-registrar; a 200 OK reply has been sent upstream - * -1 (error) - generic error code; the logs should provide - more help - - This function can only be used from the request route. - - Example 1.34. mid_registrar_save usage -... -if (is_method("REGISTER")) { - mid_registrar_save("location"); - switch ($retcode) { - case 1: - xlog("L_INFO", "forwarding REGISTER to main registrar... -\n"); - $ru = "sip:10.0.0.3:5070"; - if (!t_relay()) { - send_reply(500, "Server Internal Error 1"); - } - - break; - case 2: - xlog("L_INFO", "REGISTER has been absorbed!\n"); - break; - default: - xlog("L_ERR", "mid-registrar error!\n"); - send_reply(500, "Server Internal Error 2"); - } - - exit; -} -... - -1.6.2. mid_registrar_lookup(domain[, [flags][, [aor]]]) - - Function to be called when receiving requests from the main - registrar (to be routed to the end-user). It performs the local - lookup (in user location) and the necessary RURI processing in - order to route the requests further to the end-user registered - contacts (note that multiple branches/destinations may result - after the lookup). - - Depending on the current working mode, the function will behave - as follows: - - * in "mirror" mode - + extract the username (Address-of-Record) from the - Request-URI and look up all of its contact bindings - stored in the user location. The Request-URI ($ru - variable) will be overwritten with the highest q-value - contact, with additional branches for each contact - being optionally created. (depending on the flags - parameter) - * in "Contact throttling" mode - + extract the contact_id_param from the Request-URI, - derive the actual SIP URI of the destination from it - and set it as the new Request-URI of the INVITE ($ru - variable). - * in "AOR throttling" mode - + extract the username (Address-of-Record) from the - Request-URI and look up all of its contact bindings - stored in the user location. The Request-URI ($ru - variable) will be overwritten with the highest q-value - contact, with additional branches for each contact - being optionally created. (depending on the flags - parameter) - - Meaning of the parameters is as follows: - * domain (static string) - logical domain within the - registrar. If a database is used, then this must be name of - the usrloc table which stores the contacts - * flags (string, optional) - string composed of one or more - of the following flags, comma-separated: - + 'no-branches' - (old b flag) this flag controls how - the mid_registrar_lookup() function processes multiple - contacts. If there are multiple contacts for the given - username in usrloc and this flag is not set, - Request-URI will be overwritten with the highest-q - rated contact and the rest will be appended to sip_msg - structure and can be later used by tm for forking. If - the flag is set, only Request-URI will be overwritten - with the highest-q rated contact and the rest will be - left unprocessed. - + 'to-branches-only' - (old B flag) this flags forces - all found contacts to be uploaded only as branches (in - the destination set) and not at all in the R-URI of - the current message. Using this option allows the - mid_registrar_lookup() function to also be used in the - context of a SIP reply. - + 'branch' - (old r flag) this flag enables searching - through existing branches for aor's and expanding them - to contacts. For example, you have got AOR A in your - ruri but you also want to forward your calls to AOR B. - In order to do this, you must put AOR B in a branch, - and if this flag enabled, the function will also - expand AOR B to contacts, which will be put back into - the branches. The AOR's that were in branches before - the function call shall be removed. - WARNING: if you want this flag activated, the - 'no-branches' flag must not be set, because by setting - that flag you won't allow mid_registrar_lookup() to - write in a branch. - + 'method-filtering' - (old m flag) setting this flag - will enable contact filtering based on the supported - methods listed in the "Allow" header field during - registration. Contacts which did not present an - "Allow" header field during registration are assumed - to support all standard SIP methods. - + 'ua-filtering=[val]' (old u flag) (User-Agent - filtering) - this flag enables regexp filtering by - user-agent. It's useful with enabled append_branches - parameter. The value must use the format '/regexp/'. - + 'case-insensitive' (old i flag) - this flag enables - case insensitive filtering for the 'ua-filtering' - flag. - + 'extended-regexp' - (old e flag) this flag enables - using of extended regexp format for the 'ua-filtering' - flag. - + 'global' (old g flag) (Global lookup) - this flag is - only relevant with federated user location clustering. - If set, the mid_registrar_lookup() function will not - only perform the classic in-memory - "search-AoR-and-push-branches" operation, but will - also perform a metadata lookup and append an - additional branch for each returned result. The - "in-memory branches" correspond to local contacts - (current location), while the "metadata branches" - correspond to contacts available on one or more of the - remaining locations of the platform. - The AoR metadata consists of the minimally required - information in order for one of the VoIP platform's - locations (data centers) to advertise the presence of - a locally registered AoR for the global platform. - Specifically, this consists of two pieces of - information: - o the AoR (e.g. "vladimir@federation-cluster") - o the home IP (e.g. "10.0.0.223") - + 'max-ping-latency=[int]' - (old y flag) maximally - accepted contact pinging latency (microseconds). - Contacts of an AoR with a higher latency will be - discarded during mid_registrar_lookup(). - + 'sort-by-latency' - (old Y flag) contacts will be - picked in ascending order of their last successful - pinging latency (fastest ping -> slowest ping). This - flag may work together with the "max-ping-latency" - flag. - * aor (string, optional) - a custom Address-of-Record. If not - given, the AOR will be taken from the Request-URI - - Return codes: - * 1 - contacts found and successfully pushed as branches. - Contacts which required awakening prior to being reachable - are being notified via async Push Notifications. - * 2 - successfully started at least one async Push - Notification for the found contacts, however no extra - branches were populated (i.e. there is no need to call - t_relay()). - * -1 - no contact found. - * -2 - contacts found, but neither of them supports the - current SIP method. - * -3 - internal error during processing. - - This function can only be used from the request route. - - Example 1.35. mid_registrar_lookup usage -... - # initial invites from the main registrar - need to look them up -! - if (is_method("INVITE") and $si == "10.0.0.3" and $sp == 5070) { - if (!mid_registrar_lookup("location")) { - t_reply(404, "Not Found"); - exit; - } - - if (!t_relay()) - send_reply(500, "Server Internal Error 3"); - - exit; - } -... - -1.7. Exported Asynchronous Functions - -1.7.1. pn_process_purr(domain) - - Perform mid-dialog request processing, according to RFC 8599. - For such requests, search the R-URI and topmost Route header - field URI for a ";pn-purr" parameter value that both matches - the OpenSIPS PURR format and corresponds to an usrloc - registration. Once a usrloc contact is located, trigger an - E_UL_CONTACT_REFRESH event and place the request on async hold - for at most pn_refresh_timeout seconds, until a matching - REGISTER request arrives. - - If processing ends before triggering the Push Notification, the - request will no longer be put on async hold, with the resume - route being immediately called. - - Meaning of the parameters is as follows: - * domain (static string) - Logical domain within registrar. - If a database is used, then this must be name of the table - which stores the contacts. - - Return Codes - * 1 - Success, PN was launched. - * 2 - Success, but PN was not launched (due to missing PURR, - foreign PURR or offline contact) - * -1 - Internal Error - - Example 1.36. async pn_process_purr() usage -route { - ... - if (has_totag()) { - if (is_method("ACK") && t_check_trans()) { - t_relay(); - exit; - } - - if (!loose_route()) { - send_reply(404, "Not Found"); - exit; - } - - if (!is_method("ACK")) - async (pn_process_purr("location"), resume_route -); - - route(relay); - exit; - } -} - -route [resume_route] { - $var(rc) = $rc; - xlog("pn_process_purr() finished with $var(rc)\n"); - - ... -} - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 511 204 16339 10237 - 2. Vlad Patrascu (@rvlad-patrascu) 14 7 127 248 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 10 7 103 111 - 4. Razvan Crainea (@razvancrainea) 9 7 23 18 - 5. Chad Attermann (@attermann) 7 5 19 5 - 6. Maksym Sobolyev (@sobomax) 5 3 14 14 - 7. Alexandra Titoc 5 3 7 7 - 8. Dan Pascu (@danpascu) 4 2 4 4 - 9. Alexey Vasilyev (@vasilevalex) 3 1 2 5 - 10. Peter Lemenkov (@lemenkov) 3 1 1 1 - - All remaining contributors: Italo Rossi (@italorossi). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jul 2016 - Sep 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2020 - Nov 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 5. Razvan Crainea (@razvancrainea) Mar 2017 - Jan 2023 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2017 - Feb 2022 - 7. Alexey Vasilyev (@vasilevalex) Jan 2022 - Jan 2022 - 8. Dan Pascu (@danpascu) May 2019 - May 2019 - 9. Italo Rossi (@italorossi) Jul 2018 - Jul 2018 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Chad Attermann (@attermann). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov). - - Documentation Copyrights: - - Copyright © 2016-2020 OpenSIPS Solutions diff --git a/modules/mid_registrar/README.md b/modules/mid_registrar/README.md new file mode 100644 index 00000000000..3630194638d --- /dev/null +++ b/modules/mid_registrar/README.md @@ -0,0 +1,1512 @@ +--- +title: "mid_registrar Module" +description: "The *mid_registrar* is a mid-component of a SIP platform, designed to work between end users and the platform's main registration component." +--- + +## Admin Guide + + +### Overview + + +The *mid_registrar* is a mid-component of a SIP +platform, designed to work between end users and the platform's main +registration component. + +It opens up new possibilities for leveraging existing infrastructure in +order to continue to grow (as subscribers and as registration traffic) +while keeping an existing low-resources registrar server. + + +Acting as a registration front-end to the main SIP registrar, the +mid-registrar is able to: + + +- convert incoming high-rate registration traffic into a low-rate +variant, towards the main registrar layer. With proper +configuration, it can absorb over 90% of existing registration +traffic while correctly managing the back-end's user location +state, effectively reducing resource usage at the respective layer. +- stay synchronized with the main registrar (from a user +location perspective), by properly +accepting the contact states and expirations it decides. + + +#### Path Support (RFC 3327) + + +The mid_registrar module includes SIP Path header field support +according to +[RFC 3327](https://tools.ietf.org/html/rfc3327), +for usage in registrars and home-proxies. + + +A call to *mid_registrar_save()* stores, if path support is enabled +in the mid_registrar module, the values of the Path +Header(s) along with the Contact information into usrloc. There are +three modes for building the reply to a REGISTER message which +includes one or more Path header fields: + + +- *off* - stores the value of the +Path headers into usrloc without passing it back to +the UAC in the reply. +- *lazy* - stores the Path header and +passes it back to the UAC if Path-support is indicated +by the "path" param in the Supported HF. +- *strict* - rejects the registration +with "420 Bad Extension" if there's a Path +header but no support for it is indicated by the UAC. +Otherwise it's stored and passed back to the UAC. + + +A call to *mid_registrar_lookup()* always uses the Path header if +found, and inserts it as Route HF either in front of +the first Route HF, or after the last Via HF if no +Route is present. It also sets the destination URI to +the first Path URI, thus overwriting the received-URI, +because NAT has to be handled at the outbound-proxy of +the UAC (the first hop after client's NAT). + + +The whole process is transparent to the user, so no +config changes are required besides enabling one of the +"p0" / "p1" / "p2" flags when calling *mid_registrar_save()*. + + +#### GRUU Support (RFC 5627) + + +The mid_registrar module includes support for Globally Routable User +Agent URIs according to [RFC 5627](https://tools.ietf.org/html/rfc5627). + + +A call to *mid_registrar_save()* stores, if the phone supports GRUU, +the values of the SIP Instance along with the contact into usrloc. +The module will generate two types of GRUUs: + + +- *public* - exposes the underlying AOR, +constructed just by attaching the SIP Instance as the ;gr +parameter value. These are persistent, valid as long as the +contact registration is valid. +- *temporary* - hides the underlying AOR +Each new Register request leads to the construction of a +new temporary GRUU, while Register requests with a different +Call-ID lead to the invalidation of all the previous generated +temporary GRUUs. + + +A call to *mid_registrar_lookup()* will try to detect if the R-URI contains a +GRUU. If it does, it will route the request just for the Contact +that the specific AOR belongs to, without appending any other branches. + + +Even if the the GRUU handling during the registration process is +transparent to the user, so no config changes are required, you need +to take care of the GRUU specifics when handling mid-dialog requests. + + +As the GRUU will be present in the contact header of the initial +requests generated byt GRUU enabled devices, you will have to also +do a lookup() when receiving a mid-dialog request with the GRUU +indication in the RURI. + + +#### SIP Push Notification Support (RFC 8599) + + +The mid_registrar module includes support for standards-based SIP Push +Notifications, per +[RFC 8599](https://tools.ietf.org/html/rfc8599). +Support for the basic version of the draft can be enabled by switching +[pn enable](#param_pn_enable) to *true*. The +module also includes optional support for sending Push Notifications +during long-lived dialogs ([see RFC section 6](https://tools.ietf.org/html/rfc8599#page-23)), +through the [pn enable purr](#param_pn_enable_purr) switch. + + +Essential mechanics behind the Push Notification (PN) support: + + +- the PN support is fully compatible with the existing logic and +enabling it does not impose any limitations, as the +mid_registrar can simultaneously handle both SIP PN compliant +and standard SIP User Agents +- OpenSIPS will raise a +[E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +event any time a Push Notification needs to be sent to a +PN-enabled contact. The event includes the PN coordinates of +the contact -- they may be found in the Contact URI ('uri' +event parameter) and may be extracted using the {uri.param,name} +transformation. From here onwards, it is up to the script +developer to trigger the Push Notification (e.g. possibly by +sending an HTTP POST with the +[rest_client](../rest_client) module), thus forcing +a re-registration from the device. +- REGISTER processing is unchanged -- PN-enabled UAs are saved +just as regular UAs, with the former ones additionally having +the *4* bitflag set in the "Flags" field of +any MI listing of contacts, for differentiation purposes +- initial INVITE processing is barely changed, with the *mid_registrar_lookup()* +function now additionally returning a value of +**2** if the only +found contacts were PN-enabled contacts, all which required a +Push Notification. This means that PNs have been triggered for +each of them and t_relay() is not required, since they are not +reachable until they re-register! +Using the event_routing module, OpenSIPS will transparently +fork a new branch from the current INVITE on each +re-registration from these contacts within the accepted +[pn refresh timeout](#param_pn_refresh_timeout) +- mid-dialog requests: In some cases (e.g. long-lived dialogs), +a PN may be required before being able to route a mid-dialog +request to a SIP UA. The [afunc pn process purr](#afunc_pn_process_purr) +async function will take care of triggering the PN event and +resuming the script as soon as a re-registration from the +concerned contact is received. + + +For more information or examples, refer to the documentation of the +"pn_xxx" module parameters or the OpenSIPS blog posts around the +"SIP Push Notification" topic. + + +### Working modes + + +The mid_registrar may function in one of several modes: + + +#### Contact mirroring (default) + + +In "contact mirroring" mode, the mid-registrar will only insert itself +in the SIP traffic flow between end user and main registrar by +altering the Contact header field values. See section +[sip flow insertion](#auto_insertion_into_future_sip_flows) for a detailed description of +possible Contact-based insertion modes. The incoming REGISTER requests +will be proxied further to the main registrar; the registered contact +will be stored in the mid-registrar only on 2xx replies, according to +the information returned by the main registrar. + + +A possible usage of this mode, for example, would be to clone +registrations on a SIP front-end that extends the main platform with +new services (like adding IM/messaging routing). + + +#### Contact throttling + + +In "contact throttling" mode, the mid-registrar can significantly +reduce the registration rate on the main registrar side (between +mid-registrar and main registrar), while coping with a high registration +rate on the end-user side (between end-user and mid-registrar). This +is useful in scenarios were the end-users are very dynamic and +short-lived (e.g. mobile devices), but the main registrar cannot cope +with large amounts of registration traffic. + + +Traffic conversion is done in a *"per-device"* +manner, according to each unique SIP Contact header field value. It is +achieved by increasing the "expires" parameter value of each contact, +when relaying registrations to the main registrar. +Once such a registration is completed, subsequent registrations for the +same SIP Contact header field value will be continuously absorbed by +the mid-registrar until, eventually, the lifetime of the remote +registration will have decreased enough that a refresh (i.e. simply +forwarding the next REGISTER request) is mandatory. + + +A common occurence is for some SIP User Agents to lose their network +connection (especially when dealing with mobile devices), hence they do +not properly de-register from the mid-registrar. In this case, in order +to avoid stale registrations on the main registrar (which contains SIP +contacts with greatly extended lifetimes!), the mid-registrar will +appropriately generate De-REGISTER requests and remove these contacts +from the main registrar's location service as soon as it considers +them to have expired. + + +The main practical use for this mode is registration traffic conversion. +By minimizing the strain of processing registrations on the main +registrar, we allow it to dedicate more system resources to critical +areas of the platform, such as advanced SIP calling features and/or +media handling. + + +#### AOR throttling + + +In "AOR throttling" mode, the mid-registrar helps with handling multiple +registrations per user/AOR. This is done by aggregating all the end-user +registered contacts from a single AOR under a single registration into +the main registrar. This can dramatically reduce the incoming rate of +registrations (to a single registration per AOR), but also helps in dealing +with registrar servers which are not able to implement parallel forking/ringing. + + +Traffic conversion is done in a *"per-user"* +manner, according to each unique SIP AOR. It is achieved by +providing a contact with a large "expires" parameter value, +when relaying registrations to the main registrar. +Once such a registration is completed, subsequent registrations to the same +Address-of-record will be continuously absorbed by the mid-registrar until, +eventually, the lifetime of the remote registration will have decreased enough +that a refresh (i.e. simply forwarding the next REGISTER request) is mandatory. + + +A common occurence is for some SIP User Agents to lose their network connection +(especially when dealing with mobile devices), hence they do not properly de-register +from the mid-registrar. In this case, in order to avoid stale registrations on the +main registrar (which contains SIP AORs with greatly extended lifetimes!), +the mid-registrar will appropriately generate De-REGISTER requests and remove +these contacts from the main registrar's location service as soon as it considers +them to have expired. + + +Of all three modes, "AOR throttling" potentially offers the best reduction in +traffic on the way to the main registrar. By aggregating contacts, it also +has the added benefit of reducing the number of contacts that the main registrar +must handle. + + +Regarding SIP request mangling in this mode, the module will always +replace all Contact header field values with a single Contact header +field value when proxying registrations to the main registrar, indicating +that the AOR is local to the front-end, and its contacts can be found there. + + +The main practical uses for this mode are registration traffic conversion +towards the main registrar, as well as taking over its call forking +duties. By minimizing the +strain of processing registrations / forking calls on the main registrar, +we allow it to dedicate more system resources to critical areas of the +platform, such as advanced SIP calling features and/or media handling. + + +### Auto-Insertion Into Future SIP Flows + + +A defining feature of the mid-registrar is that it must be easy to +integrate, ideally a "plug-and-play" SIP component. It should not +impose any "outbound-proxy" configurations on any of the platform's +layers and automatically insert itself on the call flows which follow +successful registrations. + + +Regardless of its configured working [mode](#param_mode), the +mid-registrar will mangle the Contact header field URIs of all +forwarded REGISTER requests and replace the original "hostname" and +"port" parts of a Contact URI with one of its listening interfaces. + + +Additionally, in modes "0" and "1", each Contact will be assigned an +unique identifier, which will be utilized in future contact-based +lookup operations. This information will be included in each forwarded +Contact URI. The [contact id insertion](#param_contact_id_insertion) modparam +controls how this information is included. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *usrloc* +- *signaling* +- *tm* +- *event_routing*, +if [pn enable](#param_pn_enable) is set to *true*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### mode (integer) + + +Working mode of the module. +Refer to [sec working modes](#working_modes) for +more details. + + +The following is true for **all** working modes: + + +- when a REGISTER is received, the script writer must call +*[mid registrar save](#func_mid_registrar_save)* +- the mid-registrar will insert itself on the call flow of +all registrations according to the +*[contact id insertion](#param_contact_id_insertion)*. +- registrations forwarded by the mid-registrar will transparently +result in a user location update only if the reply status code from +the downstream registrar is 2xx. + + +Each working mode behaves differently, as follows: + + +- *0 (Contact mirroring mode)* +The module will only insert itself on the call flow. +Contact expirations are left unchanged. +- *1 (Contact throttling mode)* +Contact throttling is a first step in lowering registration traffic rates. This +is possible through the use of the +*[outgoing expires](#param_outgoing_expires)* module +parameter or the corresponding parameter to +*[mid registrar save](#func_mid_registrar_save)*, +which allow the script writer to prolong the life of the registrations on the way +to the main registrar. + + In this mode, the + mid-registrar may alter Expires header field values or "expires" Contact + header field parameters found in the initial request when forwarding registrations, according to + *[outgoing expires](#param_outgoing_expires)* +- *2 (AOR throttling mode)* +AOR throttling is a step beyond "Contact throttling", as the main registrar +is only made aware of the network presence of AORs, rather than +Contacts. This behaviour is also made possible through the +*[outgoing expires](#param_outgoing_expires)* module +parameter or the corresponding parameter to +*[mid registrar save](#func_mid_registrar_save)*, +which allow the script writer to prolong the life of the registrations on the way +to the main registrar. +In this mode, the mid-registrar will fully replace the Contact +set of all forwarded registrations with a single Contact, advertising +that the AOR is available to the main registrar. The expiration value +for this Contact is given by +*[outgoing expires](#param_outgoing_expires)*. + + +Default value is **0** (contact mirroring mode) + + +```opensips title="Setting the *mode* module parameter" +modparam("mid_registrar", "mode", 2) +``` + + +#### contact_id_insertion (integer) + + +Only relevant in a "mirroring" or "contact throttling" +[mode](#param_mode). Controls where the additional +unique Contact identification information (64-bit, hex-encoded integer) +will be placed within outgoing Contact header field URIs. Refer to +[sip flow insertion](#auto_insertion_into_future_sip_flows) for more details. + + +Possible values are: + + +- *"ct-param" (default)* - the contact IDs shall +be appended to outgoing Contact URIs as ";ctid=" parameters. +- *"ct-username"* - the contact IDs will +substitute the "username" parts of outgoing Contact URIs + + +```opensips title="Setting the *contact_id_insertion* module parameter" +modparam("mid_registrar", "contact_id_insertion", "ct-username") +``` + + +#### contact_id_param (string) + + +Only relevant in a "mirroring" or "contact throttling" +[mode](#param_mode). Specifies the name of the +Contact URI parameter which is used by the module in order to +match contacts and route SIP requests. + + +Default value is **"ctid"** + + +```opensips title="Setting the *contact_id_param* module parameter" +modparam("mid_registrar", "contact_id_param", "ctid") + +# Example resulting Contact header field: +# Contact: ;expires=180. +``` + + +#### at_escape_str (string) + + +Only relevant when in "AoR throttling" [mode](#param_mode) +and with the usrloc [use_domain](../usrloc#param_use_domain) +setting enabled. This string represents the escape sequence for +the "@" character, which must be included, in one way or another, +in mid-registrar's generated Contact URI usernames. + + +Setting this parameter to a different value may be useful in +situations where the backend registrar is incompatible with the +default escape string. + + +Default value is **"%40"** + + +```opensips title="Setting the *at_escape_str* module parameter" +modparam("mid_registrar", "at_escape_str", "___") + +# Example Contact header field generated by mid-registrar: +# Contact: ;expires=120 +``` + + +#### outgoing_expires (integer) + + +Only relevant in Contact/AOR throttling modes. Sets a minimal +value for the expiration intervals of egressing contacts. + + +Default value is **3600** (seconds) + + +```opensips title="Setting the *outgoing_expires* module parameter" +modparam("mid_registrar", "outgoing_expires", 3600) +``` + + +#### received_avp (string) + + +The module will store the value of the AVP configured by this +parameter in the *received* column of the user +location table. It will leave the column empty if the AVP is empty. +The AVP should contain a SIP URI consisting of the source IP, port, +and protocol of the REGISTER message being processed. + + +> [!NOTE] +> The value of this parameter should be the same as the value of +corresponding parameter of nathelper module. + + +Default value is **"NULL"** (disabled) + + +```opensips title="Setting the *received_avp* module parameter" +modparam("mid_registrar", "received_avp", "$avp(rcv)") +``` + + +#### received_param (string) + + +The name of the parameter that will be appended to Contacts of +200 OK replies if the received URI is set by nathelper module. + + +> [!NOTE] +> The value of this parameter should be the same as the value of +corresponding parameter of nathelper module. + + +Default value is **"received"** + + +```opensips title="Setting the *received_param* module parameter" +modparam("mid_registrar", "received_param", "rcv") +``` + + +#### extra_contact_params_avp (string) + + +An AVP specification. This AVP is evaluated during +*[mid registrar save](#func_mid_registrar_save)*: +if it holds a valid string, its content will be appended to +*each* new Contact URI built by the mid-registrar, +for the outgoing request. + + +Default value is **None** (not used) + + +```opensips title="Setting the *extra_contact_params_avp* module parameter" +# NB: AVPs are cleared with every new SIP request +modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_params)") + +# setting the AVP during SIP message processing +$avp(extra_ct_params) = ";transport=tls"; +``` + + +#### attr_avp (string) + + +AVP to store specific additional information for each registration. +This information is read from the AVP and stored (in memory, DB or both) +at [mid registrar save](#func_mid_registrar_save). When the +[mid registrar lookup](#func_mid_registrar_lookup) or 'is_registered()' (registrar) +functions are called, the *attr_avp* will be +populated with the value saved at [re]registration. + + +When doing call forking, the AVP will hold multiple values. The position of +the corresponding attribute information in *attr_avp* is +equal to the branch index. An example scenario is given below. + + +*Default value is NULL.* + + +```opensips title="Set attr_avp parameter" +# reading attributes from the attr_pvar when doing parallel forking +... +modparam("mid_registrar", "attr_avp", "$avp(attr)") + +... +if (is_method("REGISTER")) { + $avp(attr) = "contact_info"; + mid_registrar_save("location"); + exit; +} +... +mid_registrar_lookup("location"); +t_on_branch("parallel_fork"); +... +branch_route [parallel_fork] { + xlog("Attributes for branch $T_branch_idx: $(avp(attr)[$T_branch_idx])\n"); +} + + +``` + + +#### min_expires (integer) + + +The minimum expires value of a Contact, values lower than this +minimum will be automatically set to the minimum. Value 0 disables the checking. + + +Default value is **10** (seconds) + + +```opensips title="Setting the *min_expires* module parameter" +modparam("mid_registrar", "min_expires", 600) +``` + + +#### default_expires (integer) + + +If the processed message contains neither Expires HFs nor expires +contact parameters, this value will be used as the expiration +interval of any newly created usrloc records. + + +Default value is **3600** (seconds) + + +```opensips title="Setting the *default_expires* module parameter" +modparam("mid_registrar", "default_expires", 1800) +``` + + +#### max_expires (integer) + + +The maximum expires value of a Contact, values higher than this +maximum will be automatically set to the maximum. Value 0 disables the checking. + + +Default value is **3600** (seconds) + + +```opensips title="Setting the *max_expires* module parameter" +modparam("mid_registrar", "max_expires", 7200) +``` + + +#### default_q (integer) + + +Sets the default *"q"* value for new contacts. +Because OpenSIPS does not support floating point module parameters, +the supplied *"q"* value must be multiplied by 1000. +For example, if you want +*[default q](#param_default_q)* +to be 0.38, set this parameter to 380. + + +Default value is **0** + + +```opensips title="Setting the *default_q* module parameter" +modparam("mid_registrar", "default_q", 380) +``` + + +#### tcp_persistent_flag (string) + + +Specifies the message flag to be used to control the +module behaviour regarding TCP connections. If the flag is set for a +REGISTER via TCP containing a TCP contact, the module, via the +*[mid registrar save](#func_mid_registrar_save)* +function, will set the lifetime of the TCP +connection to the contact expire value. By doing this, the TCP +connection will stay up as long as its contacts are valid. + + +Default value is **-1** (not set) + + +```opensips title="Setting the *tcp_persistent_flag* module parameter" +modparam("mid_registrar", "tcp_persistent_flag", "TCP_PERSIST_REGISTRATIONS") +``` + + +#### realm_prefix (string) + + +In multi-domain user location scenarios +(**"use_domain"** usrloc module parameter +set to *"1"*), +this parameter denotes a prefix to be automatically stripped from the +hostname part of *To* header field URIs when doing +a save, or *Request-URIs* when doing a lookup. + + +It is meant as an alternative to DNS SRV records (not all SIP clients +support SRV lookups), a subdomain of +the master domain can be defined for SIP purposes (like +"sip.mydomain.net" pointing to same IP address as the SRV record for +"mydomain.net"). By ignoring the realm_prefix "sip.", at registration, +"sip.mydomain.net" will be translated to "mydomain.net". + + +Default value is **NULL** (none) + + +```opensips title="Setting the *realm_prefix* module parameter" +modparam("mid_registrar", "realm_prefix", "sip.") +``` + + +#### case_sensitive (integer) + + +If set to 1, then AOR comparison will be case +sensitive (as RFC3261 instructs), if set to 0 then +AOR comparison will be case insensitive. + + +Default value is **1** (true) + + +```opensips title="Setting the *case_sensitive* module parameter" +modparam("mid_registrar", "case_sensitive", 0) +``` + + +#### allow_dup_cseq (boolean) + + +Some SIP stacks will re-REGISTER using the same Call-ID and CSeq values. +While rejecting such requests is consistent with RFC 3261 § 10.3.7, enabling +this parameter instructs the mid_registrar to accept them instead, +improving interoperability. + + +*Default value is *false* (duplicate CSeq is rejected).* + + +```opensips title="Setting the allow_dup_cseq parameter" +... +# loose RFC 3261 compliance: allow REGISTER requests with duplicate CSeq +modparam(" +``` + + +#### expires_max_deviation (integer) + + +Set this parameter in order to add a random +/- deviation up to +and including the given value to the expiration interval of a +newly registered contact. For example, if this parameter is set to +*100* and a phone registers for 1800 sec, the final +expiry will be a random number in the [1700, 1900] interval. +By randomizing the registration lifetimes of the contacts, the +server is better equipped to deal with a post-restart *registration +storm*, when all TCP connections are lost and a significant portion of +UAs will re-register at the same time. Thanks to the contact lifetime +randomization, the registration storm will only happen once rather +than, e.g., every 1800 seconds following the restart. + + +*Default value is 0 (no deviation).* + + +```opensips title="Setting the expires_max_deviation parameter" +... +# add a random +/- 0-100 seconds to each registration lifetime +modparam(" +``` + + +#### max_contacts (integer) + + +The parameter can be used to limit the number of contacts per +AOR (Address of Record) in the user location database. Value 0 +disables the check. +This is the default value and will be used only if no other value +(for max_contacts) is passed as parameter to the save() function. +That's it - the function parameter overwride this global parameter. + + +*Default value is 0.* + + +```opensips title="Set max_contacts parameter" +... +# Allow no more than 10 contacts per AOR +modparam(" +``` + + +#### max_username_len (integer) + + +The maximum length of the "username" part of an Address-of-Record SIP URI. + + +Default value is **64**. + + +```opensips title="Setting the *max_username_len* module parameter" +modparam(" +``` + + +#### max_domain_len (integer) + + +The maximum length of the "domain" part of an Address-of-Record SIP URI. + + +Default value is **64**. + + +```opensips title="Setting the *max_domain_len* module parameter" +modparam(" +``` + + +#### max_aor_len (integer) + + +The maximum length of an Address-of-Record SIP URI. + + +Default value is **256**. + + +```opensips title="Setting the *max_aor_len* module parameter" +modparam(" +``` + + +#### max_contact_len (integer) + + +The maximum length of a Contact header field SIP URI. + + +Default value is **255**. + + +```opensips title="Setting the *max_contact_len* module parameter" +modparam(" +``` + + +#### retry_after (integer) + + +The mid-registrar can generate 5xx replies to registrations in various +situations. It could, for example, happen when the +*[max contacts](#param_max_contacts)* parameter +is set and the processing of REGISTER request would exceed the limit. +In this case, OpenSIPS would respond with "503 Service Unavailable". + + +If you want to add the Retry-After header field in 5xx replies, set +this parameter to a value greater than zero (0 means: do not add the +header field). See section 20.33 of RFC3261 for more details. + + +Default value is **0** (disabled) + + +```opensips title="Setting the *retry_after* module parameter" +modparam("mid_registrar", "retry_after", 30) +``` + + +#### disable_gruu (integer) + + +Globally disable GRUU handling. + + +Default value is **1** (GRUUs will not be handled) + + +```opensips title="Setting the *gruu_secret* module parameter" +modparam("mid_registrar", "disable_gruu", 0) +``` + + +#### gruu_secret (string) + + +The string that will be used in XORing when generating +temporary GRUUs. + + +Default value is **"0p3nS1pS"** + + +```opensips title="Setting the *gruu_secret* module parameter" +modparam("mid_registrar", "gruu_secret", "my_secret") +``` + + +#### pn_enable (boolean) + + +Enable SIP Push Notification support ([RFC 8599](https://tools.ietf.org/html/rfc8599)). +If enabled, Contact header field URIs which include all +[pn ct match params](#param_pn_ct_match_params) will be matched against +existing bindings using only these parameters. Otherwise, +the module will attempt to match them as usual, using the current +usrloc [matching_mode](../usrloc#param_matching_mode). + + +*Default value is **false**.* + + +```opensips title="Setting the pn_enable parameter" +... +modparam("mid_registrar", "pn_enable", true) +... +``` + + +#### pn_providers (string) + + +A list of supported Push Notification providers. While only three +possible values are defined by RFC 8599 ("apns", "fcm" and "webpush"), +non-standard values may be specified as well. + + +*Default value is **NULL** +(not set).* + + +```opensips title="Setting the pn_providers parameter" +... +modparam("mid_registrar", "pn_providers", "apns, fcm, webpush") +... +``` + + +#### pn_ct_match_params (string) + + +The minimally required list of RFC 8599 parameters (custom ones are +accepted as well) which must be present in a Contact URI and +identically match an existing binding in order for the binding +to be refreshed during a SIP re-REGISTER. If at least one such +parameter is missing from a Contact header field URI, the module +will fall back to performing regular contact matching. + + +Note that if all above PN Contact URI parameters match an existing +binding, the match is considered to be successful regardless if +other parts of the SIP URI do not match (e.g. hostname, port, +other URI parameters, etc.). + + +After calling *mid_registrar_lookup()* or +[afunc pn process purr](#afunc_pn_process_purr), the above PN-related +parameters will be automatically stripped from the resulting +Request and Contact URI event parameter, respectively. + + +*Default value is **"pn-provider, pn-prid, pn-param"**.* + + +```opensips title="Setting the pn_ct_match_params parameter" +... +modparam("mid_registrar", "pn_ct_match_params", "pn-provider, pn-prid") +... +``` + + +#### pn_pnsreg_interval (integer) + + +For devices capable of waking up and refreshing their binding on +their own (signified by the *";+sip.pnsreg"* +Contact header field parameter), this setting denotes the +prior-to-expiration interval advertised by the server at which the +device should issue its binding refresh request. + + +*Default value is **130** +(seconds before expiry).* + + +```opensips title="Setting the pn_pnsreg_interval parameter" +... +modparam("mid_registrar", "pn_pnsreg_interval", 140) +... +``` + + +#### pn_trigger_interval (integer) + + +If a binding refresh REGISTER request from a given SIP endpoint does +not arrive within at least [pn trigger interval](#param_pn_trigger_interval) +seconds prior to expiration (e.g. because the device does not +support *";+sip.pnsreg"* or because of other +error conditions), the [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +usrloc event will be triggered. + + +Once [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +is triggered, the script writer should use +the RFC 8599 parameters from the Contact URI in order to generate a +Push Notification request to the PN provider of the device, in +order to cause the device to wake up and re-register. + + +*Default value is **120** +(seconds before expiry).* + + +```opensips title="Setting the pn_trigger_interval parameter" +... +modparam("mid_registrar", "pn_trigger_interval", 130) +... +``` + + +#### pn_skip_pn_interval (integer) + + +Following a successful (re)registration of a contact, this setting +denotes a time interval, in seconds, during which the contact is +assumed to be reachable, so any Push Notifications will be skipped. + + +*Default value is **0** seconds +(always generate Push Notifications).* + + +```opensips title="Setting the pn_skip_pn_interval parameter" +... +modparam("mid_registrar", "pn_skip_pn_interval", 10) +... +``` + + +#### pn_refresh_timeout (integer) + + +This timeout starts counting following a *mid_registrar_lookup()* or a +[afunc pn process purr](#afunc_pn_process_purr) which +triggers a Push Notification. The value represents the maximum +allowed sum of the duration required for the Push Notification to +be sent and the duration required for the corresponding +re-registration from the device to arrive. + + +Once this timeout is exceeded for an initial or a mid-dialog +request, any further re-registrations which match the pending Push +Notification will no longer cause the desired effects. For example: + + +- pending initial INVITE transactions will complete and will no +longer auto-fork an additional branch for each REGISTER +sent by the callee side +- pending BYE messages will time out and OpenSIPS will attempt to +route them despite not having received a confirmation that the +target device is actually reachable + + +*Default value is **6** seconds.* + + +```opensips title="Setting the pn_refresh_timeout parameter" +... +modparam("mid_registrar", "pn_refresh_timeout", 10) +... +``` + + +#### pn_enable_purr (boolean) + + +Enable the SIP Push Notification mechanism for long-lived dialogs. +If enabled, the mid_registrar will include a +*"+sip.pnspurr"* +Feature-Caps header field tag in 200 OK replies to REGISTER +requests. This tag represents a unique identifier for the +registration (PURR - Proxy Unique Registration Reference). + + +During dialog setup, each UA may include, in its Contact header, +the PURR value returned by OpenSIPS during registration. By +including the PURR (e.g. ";pn-purr=XXX"), an agent indicates that +it expects to be first awoken by a PN before being able to receive +a mid-dialog request sent by the other party. + + +When enabling this parameter, make sure to also add logic for +[afunc pn process purr](#afunc_pn_process_purr). + + +*Default value is **false**.* + + +```opensips title="Setting the pn_enable_purr parameter" +... +modparam("mid_registrar", "pn_enable_purr", true) +... +``` + + +### Exported Functions + + +#### mid_registrar_save(domain[, flags[, aor[, outgoing_expires[, ownership_tag]]]]) + + +Function to be called when handling REGISTER requests. This function +decides if a REGISTER should be forwarded to the main registrar and +performs all the necessary changes over the registered contacts. The +function is also covering the handling of the 2xx REGISTER replies - +the contacts confirmed by the main registrar will be automatically +saved in the local user location (without any additional scripting). + + +In Contact/AOR throttling modes (more info about working modes in [sec working modes](#working_modes)), +the return value of this function indicates whether the script +writer must forward the REGISTER request to the main registrar, +or just wrap up any left-over processing and exit script execution, as +the current REGISTER request has been answered with 200 OK +(absorbed at mid-registrar level). + + +Depending on the current working +*[mode](#param_mode)* and +*[contact id insertion](#param_contact_id_insertion)*, +the function may additionally perform +the following series of transformations when relaying REGISTER requests: + + +- in *"Contact throttling"* mode + + - change the value of the *Expires* +header field to the value of +*outgoing_expires*, if given, +otherwise the value given by the +*[outgoing expires](#param_outgoing_expires)* +module parameter. +The same applies to any *";expires"* +Contact URI parameter. + - replace the "host:port" part of all Contact URIs of the +incoming REGISTER request with an OpenSIPS listening interface + - append a parameter to each +*Contact* URI, which will +allow the module to match the reply contacts +and also route calls. The name of this URI +parameter is configurable via +*[contact id param](#param_contact_id_param)* +- in *"AOR throttling"* mode + + - change the value of the *Expires* +header field to the value of +*outgoing_expires*, if given, +otherwise the value given by the +*[outgoing expires](#param_outgoing_expires)* +module parameter. + - replace all *Contact* header +fields of the request with a single *Contact* header field, +which will contain the following SIP URI: "sip:address-of-record@proxy_ip:proxy_port" + + +Meaning of the parameters is as follows: + + +- *domain* (static string) - logical domain within the registrar. +If a database is used, then this must be name of the *usrloc* +table which stores the contacts +- *flags* (string, optional) - string composed of +one or more of the following flags, comma-separated: + + - *'memory-only'* - (old *m* flag) +save the contacts only in memory cache without no DB operation; + - *'no-reply'* - (old *r* flag) +do not generate a SIP reply to the current REGISTER request. + - *'max-contacts=[int]'* - (old *c* +flag) this flag can be used to limit the number of contacts for this +AOR (Address of Record) in the user location database. +Value 0 disables the check. This parameter overrides the +global "max_contacts" module parameter. + - *'force-registration'* - (old *f* +flag) this flag can be used to force the registration of NEW contacts +even if the maximum number of contacts is reached. In such +a case, older contacts will be removed to make space to the +new ones, without exceeding the maximum allowed number. +This flag makes sense only if "max-contacts" is used. + - *'matching-mode=[val]'* - (old *M* +flag) How the matching should be performed between the uploaded +contacts (by the currently handled REGISTER) and the +already know contacts (in memory or DB). This options will +be used only for the current operation and can be: + - *'0'* - contact URI matching + only + - *'1'* - contact URI and + SIP Call-ID matching + - *''* - only + the value of the given URI param will be used for + matching (for example ) + - *'path-off'* - (old *p0* flag) +(Path support - 'off' mode) - The Path header is saved into usrloc, +but is never included in the reply. + - *'path-lazy'* - (old *p1* flag) +(Path support - lazy mode) The Path header is saved into usrloc, but is only +included in the reply if path support is indicated in the +registration request by the "path" option +of the "Supported" header. + - *'path-strict'* - (old *p2* flag) +(Path support - strict mode) - The path header is only saved into usrloc, +if path support is indicated in the registration request by the +"path" option of the "Supported" +header. If no path support is indicated, the request is +rejected with "420 - Bad Extension" and the +header "Unsupported: path" is included in +the reply along with the received "Path" +header. This mode is the one recommended by RFC-3327. + - *'path-received'* - (old *v* flag) +if set, the "received" parameter of the first Path +URI of a registration is set as received-uri and the NAT +branch flag is set for this contact. This is useful if +the registrar is placed behind a SIP loadbalancer, which +passes the nat'ed UAC address as "received" +parameter in it's Path uri. + - *'only-request-contacts'* - (old *o* +flag) Only include the REGISTER request's Contacts in the 200 OK +reply, in case the registration is successful. While this +is against RFC 3261, it may be useful in certain scenarios. +- *aor (string, optional)* - a custom Address-of-Record. +If not given, the AOR will be taken from the *To* header URI +- *outgoing_expires (int, optional)* - only relevant +in Contact/AOR throttling modes, this is a custom value +for the contact expiration interval of the outgoing REGISTER +request, which overrides the default +*[outgoing expires](#param_outgoing_expires)* module parameter. +- *ownership_tag* (string, optional) - a cluster-shared +tag (see the clusterer module documentation for more details) which +will be attached to each contact saved from the current request. +This tag is only relevant in clustered user location scenarios and +helps determine the current logical owner node of a contact. This, +in turn, is useful in order to restrict nodes which are not +currently responsible for this contact from performing certain +actions (for example: incorrectly originating pings from a +non-owned virtual IP address in highly-available setups). + + +**Return value** + + +- 1 (success) - current REGISTER request must be dispatched by the +script writer over to the main registrar +- 2 (success) - current REGISTER request has been absorbed by the +mid-registrar; a 200 OK reply has been sent upstream +- -1 (error) - generic error code; the logs should provide more help + + +This function can only be used from the request route. + + +```opensips title="*mid_registrar_save* usage" +... +if (is_method("REGISTER")) { + mid_registrar_save("location"); + switch ($retcode) { + case 1: + xlog("L_INFO", "forwarding REGISTER to main registrar...\n"); + $ru = "sip:10.0.0.3:5070"; + if (!t_relay()) { + send_reply(500, "Server Internal Error 1"); + } + + break; + case 2: + xlog("L_INFO", "REGISTER has been absorbed!\n"); + break; + default: + xlog("L_ERR", "mid-registrar error!\n"); + send_reply(500, "Server Internal Error 2"); + } + + exit; +} +... +``` + + +#### mid_registrar_lookup(domain[, [flags][, [aor]]]) + + +Function to be called when receiving requests from the main registrar +(to be routed to the end-user). It performs the local lookup +(in user location) and the necessary RURI processing in order to route +the requests further to the end-user registered contacts (note that +multiple branches/destinations may result after the lookup). + + +Depending on the current working +*[mode](#param_mode)*, +the function will behave as follows: + + +- in *"mirror"* mode + + - extract the username (Address-of-Record) from the Request-URI +and look up all of its contact bindings stored in the user +location. The Request-URI (**$ru** +variable) will be overwritten with the highest q-value contact, +with additional branches for each contact being optionally +created. (depending on the *flags* parameter) +- in *"Contact throttling"* mode + + - extract the *[contact id param](#param_contact_id_param)* +from the Request-URI, derive the actual SIP URI of the destination +from it and set it as the new Request-URI of the INVITE +(**$ru** variable). +- in *"AOR throttling"* mode + + - extract the username (Address-of-Record) from the Request-URI +and look up all of its contact bindings stored in the user +location. The Request-URI (**$ru** +variable) will be overwritten with the highest q-value contact, +with additional branches for each contact being optionally +created. (depending on the *flags* parameter) + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - logical domain within the registrar. +If a database is used, then this must be name of the *usrloc* +table which stores the contacts +- *flags (string, optional) - string composed of one or more of +the following flags, comma-separated:* + + - *'no-branches'* - (old *b* flag) this +flag controls how the *mid_registrar_lookup()* function processes multiple contacts. +If there are +multiple contacts for the given username in usrloc and this +flag is not set, Request-URI will be overwritten with the +highest-q rated contact and the rest will be appended to +sip_msg structure and can be later used by tm for forking. If +the flag is set, only Request-URI will be overwritten +with the highest-q rated contact and the rest will be left +unprocessed. + - *'to-branches-only'* - (old *B* flag) +this flags forces all found contacts to be uploaded only as branches (in the +destination set) and not at all in the R-URI of the +current message. Using this option allows the *mid_registrar_lookup()* function to +also be used in the context of a SIP reply. + - *'branch'* - (old *r* flag) this flag +enables searching through existing branches for aor's and expanding +them to contacts. For example, you have got AOR A in your +ruri but you also want to forward your calls to AOR B. In order +to do this, you must put AOR B in a branch, and if this flag +enabled, the function will also expand AOR B to contacts, +which will be put back into the branches. The AOR's that were +in branches before the function call shall be removed. +**WARNING:** +*if you want this flag activated, +the 'no-branches' flag must not be set, because by setting +that flag you won't allow *mid_registrar_lookup()* to write in a branch.* + - *'method-filtering'* - (old *m* flag) +setting this flag will enable contact filtering based on the supported methods +listed in the "Allow" header field during registration. +Contacts which did not present an "Allow" header field during +registration are assumed to support all standard SIP methods. + - *'ua-filtering=[val]'* (old *u* flag) +(User-Agent filtering) - this flag enables regexp filtering by user-agent. +It's useful with enabled append_branches parameter. The value must use the +format '/regexp/'. + - *'case-insensitive'* (old *i* flag) - +this flag enables case insensitive filtering for the 'ua-filtering' flag. + - *'extended-regexp'* - (old *e* flag) +this flag enables using of extended regexp format for the 'ua-filtering' flag. + - *'global'* (old *g* flag) (Global +lookup) - this flag is only relevant with federated user location clustering. +If set, the *mid_registrar_lookup()* function will not only perform the classic +in-memory "search-AoR-and-push-branches" operation, but will +also perform a metadata lookup and append an additional branch +for each returned result. The "in-memory branches" correspond +to local contacts (current location), while the "metadata +branches" correspond to contacts available on one or more of +the remaining locations of the platform. +The AoR metadata consists of the minimally required information +in order for one of the VoIP platform's locations (data +centers) to advertise the presence of a locally registered AoR +for the global platform. Specifically, this consists of two +pieces of information: + - the AoR (e.g. "vladimir@federation-cluster") + - the home IP (e.g. "10.0.0.223") + - *'max-ping-latency=[int]'* - (old *y* +flag) maximally accepted contact pinging latency (microseconds). Contacts of an +AoR with a higher latency will be discarded during *mid_registrar_lookup()*. + - *'sort-by-latency'* - (old *Y* flag) +contacts will be picked in ascending order of their last successful +pinging latency (fastest ping -> slowest ping). This flag may +work together with the "max-ping-latency" flag. +- *aor (string, optional)* - a custom Address-of-Record. +If not given, the AOR will be taken from the *Request-URI* + + +Return codes: + + +- **1** - contacts found and successfully +pushed as branches. Contacts which required awakening prior to being +reachable are being notified via async Push Notifications. +- **2** - successfully started at least one +async Push Notification for the found contacts, however no extra branches +were populated (i.e. there is no need to call t_relay()). +- **-1** - no contact found. +- **-2** - contacts found, but neither of them +supports the current SIP method. +- **-3** - internal error during processing. + + +This function can only be used from the request route. + + +```opensips title="*mid_registrar_lookup* usage" +... + # initial invites from the main registrar - need to look them up! + if (is_method("INVITE") and $si == "10.0.0.3" and $sp == 5070) { + if (!mid_registrar_lookup("location")) { + t_reply(404, "Not Found"); + exit; + } + + if (!t_relay()) + send_reply(500, "Server Internal Error 3"); + + exit; + } +... +``` + + +### Exported Asynchronous Functions + + +#### pn_process_purr(domain) + + +Perform mid-dialog request processing, according to RFC 8599. For +such requests, search the R-URI and topmost Route header field URI for +a *";pn-purr"* parameter value that both matches the +OpenSIPS PURR format and corresponds to an usrloc registration. Once a +usrloc contact is located, trigger an [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +event and place the request on async hold for at most +[pn refresh timeout](#param_pn_refresh_timeout) seconds, until a matching +REGISTER request arrives. + + +If processing ends before triggering the Push Notification, the request +will no longer be put on async hold, with the resume route being +immediately called. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Logical domain within +registrar. If a database is used, then this must be name of the +table which stores the contacts. + + +**Return Codes** + + +- **1** - Success, PN was launched. +- **2** - Success, +but PN was not launched (due to missing PURR, foreign PURR or +offline contact) +- **-1** - Internal Error + + +```opensips title="async pn_process_purr() usage" +route { + ... + if (has_totag()) { + if (is_method("ACK") && t_check_trans()) { + t_relay(); + exit; + } + + if (!loose_route()) { + send_reply(404, "Not Found"); + exit; + } + + if (!is_method("ACK")) + async (pn_process_purr("location"), resume_route); + + route(relay); + exit; + } +} + +route [resume_route] { + $var(rc) = $rc; + xlog("pn_process_purr() finished with $var(rc)\n"); + + ... +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mid_registrar/doc/contributors.xml b/modules/mid_registrar/doc/contributors.xml deleted file mode 100644 index 319f41c30d2..00000000000 --- a/modules/mid_registrar/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 511 - 204 - 16339 - 10237 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 14 - 7 - 127 - 248 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 10 - 7 - 103 - 111 - - - 4. - Razvan Crainea (@razvancrainea) - 9 - 7 - 23 - 18 - - - 5. - Chad Attermann (@attermann) - 7 - 5 - 19 - 5 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 14 - 14 - - - 7. - Alexandra Titoc - 5 - 3 - 7 - 7 - - - 8. - Dan Pascu (@danpascu) - 4 - 2 - 4 - 4 - - - 9. - Alexey Vasilyev (@vasilevalex) - 3 - 1 - 2 - 5 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Italo Rossi (@italorossi). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jul 2016 - Sep 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2020 - Nov 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Mar 2017 - Jan 2023 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2017 - Feb 2022 - - - 7. - Alexey Vasilyev (@vasilevalex) - Jan 2022 - Jan 2022 - - - 8. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 9. - Italo Rossi (@italorossi) - Jul 2018 - Jul 2018 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Chad Attermann (@attermann). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov). -
- -
diff --git a/modules/mid_registrar/doc/mid_registrar.xml b/modules/mid_registrar/doc/mid_registrar.xml deleted file mode 100644 index fd5a2b91c52..00000000000 --- a/modules/mid_registrar/doc/mid_registrar.xml +++ /dev/null @@ -1,38 +0,0 @@ - -mid_registrar"> -mid_registrar_save()"> -mid_registrar_lookup()"> - - - - - - - - - - - - - - - -%docentities; - -]> - - - - mid_registrar Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2016-2020 &OSS; - diff --git a/modules/mid_registrar/doc/mid_registrar_admin.xml b/modules/mid_registrar/doc/mid_registrar_admin.xml deleted file mode 100644 index d27ea5761bb..00000000000 --- a/modules/mid_registrar/doc/mid_registrar_admin.xml +++ /dev/null @@ -1,1068 +0,0 @@ - - - - &adminguide; - -
- Overview - - The mid_registrar is a mid-component of a SIP - platform, designed to work between end users and the platform's main - registration component. - - It opens up new possibilities for leveraging existing infrastructure in - order to continue to grow (as subscribers and as registration traffic) - while keeping an existing low-resources registrar server. - - - Acting as a registration front-end to the main SIP registrar, the - mid-registrar is able to: - - - - convert incoming high-rate registration traffic into a low-rate - variant, towards the main registrar layer. With proper - configuration, it can absorb over 90% of existing registration - traffic while correctly managing the back-end's user location - state, effectively reducing resource usage at the respective layer. - - - - - stay synchronized with the main registrar (from a user - location perspective), by properly - accepting the contact states and expirations it decides. - - - - - - &supported_rfc; - -
- -
- Working modes - - The mid_registrar may function in one of several modes: - - -
- Contact mirroring (default) - - In "contact mirroring" mode, the mid-registrar will only insert itself - in the SIP traffic flow between end user and main registrar by - altering the Contact header field values. See section - for a detailed description of - possible Contact-based insertion modes. The incoming REGISTER requests - will be proxied further to the main registrar; the registered contact - will be stored in the mid-registrar only on 2xx replies, according to - the information returned by the main registrar. - - - A possible usage of this mode, for example, would be to clone - registrations on a SIP front-end that extends the main platform with - new services (like adding IM/messaging routing). - -
- -
- Contact throttling - - In "contact throttling" mode, the mid-registrar can significantly - reduce the registration rate on the main registrar side (between - mid-registrar and main registrar), while coping with a high registration - rate on the end-user side (between end-user and mid-registrar). This - is useful in scenarios were the end-users are very dynamic and - short-lived (e.g. mobile devices), but the main registrar cannot cope - with large amounts of registration traffic. - - - Traffic conversion is done in a "per-device" - manner, according to each unique SIP Contact header field value. It is - achieved by increasing the "expires" parameter value of each contact, - when relaying registrations to the main registrar. - Once such a registration is completed, subsequent registrations for the - same SIP Contact header field value will be continuously absorbed by - the mid-registrar until, eventually, the lifetime of the remote - registration will have decreased enough that a refresh (i.e. simply - forwarding the next REGISTER request) is mandatory. - - - A common occurence is for some SIP User Agents to lose their network - connection (especially when dealing with mobile devices), hence they do - not properly de-register from the mid-registrar. In this case, in order - to avoid stale registrations on the main registrar (which contains SIP - contacts with greatly extended lifetimes!), the mid-registrar will - appropriately generate De-REGISTER requests and remove these contacts - from the main registrar's location service as soon as it considers - them to have expired. - - - The main practical use for this mode is registration traffic conversion. - By minimizing the strain of processing registrations on the main - registrar, we allow it to dedicate more system resources to critical - areas of the platform, such as advanced SIP calling features and/or - media handling. - -
- -
- AOR throttling - - In "AOR throttling" mode, the mid-registrar helps with handling multiple - registrations per user/AOR. This is done by aggregating all the end-user - registered contacts from a single AOR under a single registration into - the main registrar. This can dramatically reduce the incoming rate of - registrations (to a single registration per AOR), but also helps in dealing - with registrar servers which are not able to implement parallel forking/ringing. - - - Traffic conversion is done in a "per-user" - manner, according to each unique SIP AOR. It is achieved by - providing a contact with a large "expires" parameter value, - when relaying registrations to the main registrar. - Once such a registration is completed, subsequent registrations to the same - Address-of-record will be continuously absorbed by the mid-registrar until, - eventually, the lifetime of the remote registration will have decreased enough - that a refresh (i.e. simply forwarding the next REGISTER request) is mandatory. - - - A common occurence is for some SIP User Agents to lose their network connection - (especially when dealing with mobile devices), hence they do not properly de-register - from the mid-registrar. In this case, in order to avoid stale registrations on the - main registrar (which contains SIP AORs with greatly extended lifetimes!), - the mid-registrar will appropriately generate De-REGISTER requests and remove - these contacts from the main registrar's location service as soon as it considers - them to have expired. - - - Of all three modes, "AOR throttling" potentially offers the best reduction in - traffic on the way to the main registrar. By aggregating contacts, it also - has the added benefit of reducing the number of contacts that the main registrar - must handle. - - - Regarding SIP request mangling in this mode, the module will always - replace all Contact header field values with a single Contact header - field value when proxying registrations to the main registrar, indicating - that the AOR is local to the front-end, and its contacts can be found there. - - - The main practical uses for this mode are registration traffic conversion - towards the main registrar, as well as taking over its call forking - duties. By minimizing the - strain of processing registrations / forking calls on the main registrar, - we allow it to dedicate more system resources to critical areas of the - platform, such as advanced SIP calling features and/or media handling. - -
-
- -
- Auto-Insertion Into Future SIP Flows - - A defining feature of the mid-registrar is that it must be easy to - integrate, ideally a "plug-and-play" SIP component. It should not - impose any "outbound-proxy" configurations on any of the platform's - layers and automatically insert itself on the call flows which follow - successful registrations. - - - Regardless of its configured working , the - mid-registrar will mangle the Contact header field URIs of all - forwarded REGISTER requests and replace the original "hostname" and - "port" parts of a Contact URI with one of its listening interfaces. - - - Additionally, in modes "0" and "1", each Contact will be assigned an - unique identifier, which will be utilized in future contact-based - lookup operations. This information will be included in each forwarded - Contact URI. The modparam - controls how this information is included. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - usrloc - - - - - signaling - - - - - tm - - - - - event_routing, - if is set to true. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters - -
- <varname>mode</varname> (integer) - - - Working mode of the module. - Refer to for - more details. - - - - The following is true for all working modes: - - - - when a REGISTER is received, the script writer must call - - - - - - the mid-registrar will insert itself on the call flow of - all registrations according to the - . - - - - - registrations forwarded by the mid-registrar will transparently - result in a user location update only if the reply status code from - the downstream registrar is 2xx. - - - - - - - Each working mode behaves differently, as follows: - - - - - - 0 (Contact mirroring mode) - - The module will only insert itself on the call flow. - Contact expirations are left unchanged. - - - - - - 1 (Contact throttling mode) - - Contact throttling is a first step in lowering registration traffic rates. This - is possible through the use of the - module - parameter or the corresponding parameter to - , - which allow the script writer to prolong the life of the registrations on the way - to the main registrar. - - - - In this mode, the - mid-registrar may alter Expires header field values or "expires" Contact - header field parameters found in the initial request when forwarding registrations, according to - - - - - - - 2 (AOR throttling mode) - - AOR throttling is a step beyond "Contact throttling", as the main registrar - is only made aware of the network presence of AORs, rather than - Contacts. This behaviour is also made possible through the - module - parameter or the corresponding parameter to - , - which allow the script writer to prolong the life of the registrations on the way - to the main registrar. - - - In this mode, the mid-registrar will fully replace the Contact - set of all forwarded registrations with a single Contact, advertising - that the AOR is available to the main registrar. The expiration value - for this Contact is given by - . - - - - - - - - Default value is 0 (contact mirroring mode) - - - Setting the <emphasis>mode</emphasis> module parameter - -modparam("mid_registrar", "mode", 2) - - -
-
- <varname>contact_id_insertion</varname> (integer) - - Only relevant in a "mirroring" or "contact throttling" - . Controls where the additional - unique Contact identification information (64-bit, hex-encoded integer) - will be placed within outgoing Contact header field URIs. Refer to - for more details. - - - Possible values are: - - - - - "ct-param" (default) - the contact IDs shall - be appended to outgoing Contact URIs as ";ctid=" parameters. - - - - - "ct-username" - the contact IDs will - substitute the "username" parts of outgoing Contact URIs - - - - - Setting the <emphasis>contact_id_insertion</emphasis> module parameter - -modparam("mid_registrar", "contact_id_insertion", "ct-username") - - -
- -
- <varname>contact_id_param</varname> (string) - - Only relevant in a "mirroring" or "contact throttling" - . Specifies the name of the - Contact URI parameter which is used by the module in order to - match contacts and route SIP requests. - - - - Default value is ctid - - - Setting the <emphasis>contact_id_param</emphasis> module parameter - -modparam("mid_registrar", "contact_id_param", "ctid") - -# Example resulting Contact header field: -# Contact: <sip:liviu@10.0.0.10:5060;ctid=619244948763447138>;expires=180. - - -
- -
- <varname>at_escape_str</varname> (string) - - Only relevant when in "AoR throttling" - and with the usrloc use_domain - setting enabled. This string represents the escape sequence for - the "@" character, which must be included, in one way or another, - in mid-registrar's generated Contact URI usernames. - - - - Setting this parameter to a different value may be useful in - situations where the backend registrar is incompatible with the - default escape string. - - - - Default value is %40 - - - Setting the <emphasis>at_escape_str</emphasis> module parameter - -modparam("mid_registrar", "at_escape_str", "___") - -# Example Contact header field generated by mid-registrar: -# Contact: <sip:zach%40sipdomain.invalid@127.0.0.1:5060>;expires=120 - - -
- -
- <varname>outgoing_expires</varname> (integer) - - Only relevant in Contact/AOR throttling modes. Sets a minimal - value for the expiration intervals of egressing contacts. - - - - Default value is 3600 (seconds) - - - Setting the <emphasis>outgoing_expires</emphasis> module parameter - -modparam("mid_registrar", "outgoing_expires", 3600) - - -
-
- <varname>received_avp</varname> (string) - - The module will store the value of the AVP configured by this - parameter in the received column of the user - location table. It will leave the column empty if the AVP is empty. - The AVP should contain a SIP URI consisting of the source IP, port, - and protocol of the REGISTER message being processed. - - - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - - - Default value is "NULL" (disabled) - - - Setting the <emphasis>received_avp</emphasis> module parameter - -modparam("mid_registrar", "received_avp", "$avp(rcv)") - - -
-
- <varname>received_param</varname> (string) - - The name of the parameter that will be appended to Contacts of - 200 OK replies if the received URI is set by nathelper module. - - - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - - - Default value is "received" - - - Setting the <emphasis>received_param</emphasis> module parameter - -modparam("mid_registrar", "received_param", "rcv") - - -
-
- <varname>extra_contact_params_avp</varname> (string) - - An AVP specification. This AVP is evaluated during - : - if it holds a valid string, its content will be appended to - each new Contact URI built by the mid-registrar, - for the outgoing request. - - - Default value is None (not used) - - - Setting the <emphasis>extra_contact_params_avp</emphasis> module parameter - -# NB: AVPs are cleared with every new SIP request -modparam("mid_registrar", "extra_contact_params_avp", "$avp(extra_ct_params)") - -# setting the AVP during SIP message processing -$avp(extra_ct_params) = ";transport=tls"; - - -
- -
- <varname>attr_avp</varname> (string) - - AVP to store specific additional information for each registration. - This information is read from the AVP and stored (in memory, DB or both) - at . When the - or 'is_registered()' (registrar) - functions are called, the attr_avp will be - populated with the value saved at [re]registration. - - - When doing call forking, the AVP will hold multiple values. The position of - the corresponding attribute information in attr_avp is - equal to the branch index. An example scenario is given below. - - - - Default value is NULL. - - - - Set <varname>attr_avp</varname> parameter - -# reading attributes from the attr_pvar when doing parallel forking -... -modparam("mid_registrar", "attr_avp", "$avp(attr)") - -... -if (is_method("REGISTER")) { - $avp(attr) = "contact_info"; - mid_registrar_save("location"); - exit; -} -... -mid_registrar_lookup("location"); -t_on_branch("parallel_fork"); -... -branch_route [parallel_fork] { - xlog("Attributes for branch $T_branch_idx: $(avp(attr)[$T_branch_idx])\n"); -} - - - -
- -
- <varname>min_expires</varname> (integer) - - The minimum expires value of a Contact, values lower than this - minimum will be automatically set to the minimum. Value 0 disables the checking. - - - Default value is 10 (seconds) - - - Setting the <emphasis>min_expires</emphasis> module parameter - -modparam("mid_registrar", "min_expires", 600) - - -
-
- <varname>default_expires</varname> (integer) - - If the processed message contains neither Expires HFs nor expires - contact parameters, this value will be used as the expiration - interval of any newly created usrloc records. - - - Default value is 3600 (seconds) - - - Setting the <emphasis>default_expires</emphasis> module parameter - -modparam("mid_registrar", "default_expires", 1800) - - -
-
- <varname>max_expires</varname> (integer) - - The maximum expires value of a Contact, values higher than this - maximum will be automatically set to the maximum. Value 0 disables the checking. - - - Default value is 3600 (seconds) - - - Setting the <emphasis>max_expires</emphasis> module parameter - -modparam("mid_registrar", "max_expires", 7200) - - -
-
- <varname>default_q</varname> (integer) - - Sets the default "q" value for new contacts. - Because &osips; does not support floating point module parameters, - the supplied "q" value must be multiplied by 1000. - For example, if you want - - to be 0.38, set this parameter to 380. - - - - Default value is 0 - - - Setting the <emphasis>default_q</emphasis> module parameter - -modparam("mid_registrar", "default_q", 380) - - -
-
- <varname>tcp_persistent_flag</varname> (string) - - Specifies the message flag to be used to control the - module behaviour regarding TCP connections. If the flag is set for a - REGISTER via TCP containing a TCP contact, the module, via the - - function, will set the lifetime of the TCP - connection to the contact expire value. By doing this, the TCP - connection will stay up as long as its contacts are valid. - - - - Default value is -1 (not set) - - - Setting the <emphasis>tcp_persistent_flag</emphasis> module parameter - -modparam("mid_registrar", "tcp_persistent_flag", "TCP_PERSIST_REGISTRATIONS") - - -
-
- <varname>realm_prefix</varname> (string) - - In multi-domain user location scenarios - ("use_domain" usrloc module parameter - set to "1"), - this parameter denotes a prefix to be automatically stripped from the - hostname part of To header field URIs when doing - a save, or Request-URIs when doing a lookup. - - - It is meant as an alternative to DNS SRV records (not all SIP clients - support SRV lookups), a subdomain of - the master domain can be defined for SIP purposes (like - "sip.mydomain.net" pointing to same IP address as the SRV record for - "mydomain.net"). By ignoring the realm_prefix "sip.", at registration, - "sip.mydomain.net" will be translated to "mydomain.net". - - - - Default value is NULL (none) - - - Setting the <emphasis>realm_prefix</emphasis> module parameter - -modparam("mid_registrar", "realm_prefix", "sip.") - - -
-
- <varname>case_sensitive</varname> (integer) - - If set to 1, then AOR comparison will be case - sensitive (as RFC3261 instructs), if set to 0 then - AOR comparison will be case insensitive. - - - Default value is 1 (true) - - - Setting the <emphasis>case_sensitive</emphasis> module parameter - -modparam("mid_registrar", "case_sensitive", 0) - - -
- - ®_modparams; - -
- <varname>retry_after</varname> (integer) - - The mid-registrar can generate 5xx replies to registrations in various - situations. It could, for example, happen when the - parameter - is set and the processing of REGISTER request would exceed the limit. - In this case, OpenSIPS would respond with "503 Service Unavailable". - - - If you want to add the Retry-After header field in 5xx replies, set - this parameter to a value greater than zero (0 means: do not add the - header field). See section 20.33 of RFC3261 for more details. - - - Default value is 0 (disabled) - - - Setting the <emphasis>retry_after</emphasis> module parameter - -modparam("mid_registrar", "retry_after", 30) - - -
-
- <varname>disable_gruu</varname> (integer) - - Globally disable GRUU handling. - - - Default value is 1 (GRUUs will not be handled) - - - Setting the <emphasis>gruu_secret</emphasis> module parameter - -modparam("mid_registrar", "disable_gruu", 0) - - -
-
- <varname>gruu_secret</varname> (string) - - The string that will be used in XORing when generating - temporary GRUUs. - - - Default value is "0p3nS1pS" - - - Setting the <emphasis>gruu_secret</emphasis> module parameter - -modparam("mid_registrar", "gruu_secret", "my_secret") - - -
- - &pn_modparams; - -
- -
- Exported Functions -
- - <function moreinfo="none">mid_registrar_save(domain[, flags[, aor[, outgoing_expires[, ownership_tag]]]])</function> - - - Function to be called when handling REGISTER requests. This function - decides if a REGISTER should be forwarded to the main registrar and - performs all the necessary changes over the registered contacts. The - function is also covering the handling of the 2xx REGISTER replies - - the contacts confirmed by the main registrar will be automatically - saved in the local user location (without any additional scripting). - - - In Contact/AOR throttling modes (more info about working modes in ), - the return value of this function indicates whether the script - writer must forward the REGISTER request to the main registrar, - or just wrap up any left-over processing and exit script execution, as - the current REGISTER request has been answered with 200 OK - (absorbed at mid-registrar level). - - - Depending on the current working - and - , - the function may additionally perform - the following series of transformations when relaying REGISTER requests: - - - - - in "Contact throttling" mode - - - - change the value of the Expires - header field to the value of - outgoing_expires, if given, - otherwise the value given by the - - module parameter. - The same applies to any ";expires" - Contact URI parameter. - - - - - replace the "host:port" part of all Contact URIs of the - incoming REGISTER request with an OpenSIPS listening interface - - - - - append a parameter to each - Contact URI, which will - allow the module to match the reply contacts - and also route calls. The name of this URI - parameter is configurable via - - - - - - - in "AOR throttling" mode - - - - change the value of the Expires - header field to the value of - outgoing_expires, if given, - otherwise the value given by the - - module parameter. - - - - - replace all Contact header - fields of the request with a single Contact header field, - which will contain the following SIP URI: "sip:address-of-record@proxy_ip:proxy_port" - - - - - - - - Meaning of the parameters is as follows: - - - domain (static string) - logical domain within the registrar. - If a database is used, then this must be name of the usrloc - table which stores the contacts - - - - - flags (string, optional) - string composed of - one or more of the following flags, comma-separated: - - - &save_common_flags; - - - - aor (string, optional) - a custom Address-of-Record. - If not given, the AOR will be taken from the To header URI - - - - outgoing_expires (int, optional) - only relevant - in Contact/AOR throttling modes, this is a custom value - for the contact expiration interval of the outgoing REGISTER - request, which overrides the default - module parameter. - - - - - ownership_tag (string, optional) - a cluster-shared - tag (see the clusterer module documentation for more details) which - will be attached to each contact saved from the current request. - This tag is only relevant in clustered user location scenarios and - helps determine the current logical owner node of a contact. This, - in turn, is useful in order to restrict nodes which are not - currently responsible for this contact from performing certain - actions (for example: incorrectly originating pings from a - non-owned virtual IP address in highly-available setups). - - - - Return value - - - - 1 (success) - current REGISTER request must be dispatched by the - script writer over to the main registrar - - - - - 2 (success) - current REGISTER request has been absorbed by the - mid-registrar; a 200 OK reply has been sent upstream - - - - - -1 (error) - generic error code; the logs should provide more help - - - - - This function can only be used from the request route. - - - <function moreinfo="none"><emphasis>mid_registrar_save</emphasis></function> usage - -... -if (is_method("REGISTER")) { - mid_registrar_save("location"); - switch ($retcode) { - case 1: - xlog("L_INFO", "forwarding REGISTER to main registrar...\n"); - $ru = "sip:10.0.0.3:5070"; - if (!t_relay()) { - send_reply(500, "Server Internal Error 1"); - } - - break; - case 2: - xlog("L_INFO", "REGISTER has been absorbed!\n"); - break; - default: - xlog("L_ERR", "mid-registrar error!\n"); - send_reply(500, "Server Internal Error 2"); - } - - exit; -} -... - - -
- -
- - <function moreinfo="none">mid_registrar_lookup(domain[, [flags][, [aor]]])</function> - - - Function to be called when receiving requests from the main registrar - (to be routed to the end-user). It performs the local lookup - (in user location) and the necessary RURI processing in order to route - the requests further to the end-user registered contacts (note that - multiple branches/destinations may result after the lookup). - - - Depending on the current working - , - the function will behave as follows: - - - - - - in "mirror" mode - - - - extract the username (Address-of-Record) from the Request-URI - and look up all of its contact bindings stored in the user - location. The Request-URI ($ru - variable) will be overwritten with the highest q-value contact, - with additional branches for each contact being optionally - created. (depending on the flags parameter) - - - - - - in "Contact throttling" mode - - - - extract the - from the Request-URI, derive the actual SIP URI of the destination - from it and set it as the new Request-URI of the INVITE - ($ru variable). - - - - - - in "AOR throttling" mode - - - - extract the username (Address-of-Record) from the Request-URI - and look up all of its contact bindings stored in the user - location. The Request-URI ($ru - variable) will be overwritten with the highest q-value contact, - with additional branches for each contact being optionally - created. (depending on the flags parameter) - - - - - - - - Meaning of the parameters is as follows: - - - domain (static string) - logical domain within the registrar. - If a database is used, then this must be name of the usrloc - table which stores the contacts - - - - &lookup_flags; - - - aor (string, optional) - a custom Address-of-Record. - If not given, the AOR will be taken from the Request-URI - - - - &lookup_retcodes; - - This function can only be used from the request route. - - - <function moreinfo="none"><emphasis>mid_registrar_lookup</emphasis></function> usage - -... - # initial invites from the main registrar - need to look them up! - if (is_method("INVITE") and $si == "10.0.0.3" and $sp == 5070) { - if (!mid_registrar_lookup("location")) { - t_reply(404, "Not Found"); - exit; - } - - if (!t_relay()) - send_reply(500, "Server Internal Error 3"); - - exit; - } -... - - -
- -
- - -
- Exported Asynchronous Functions - - &pn_async_func; - -
- - -
- diff --git a/modules/mid_registrar/gruu.c b/modules/mid_registrar/gruu.c index 4946ab198b5..ed8303fd365 100644 --- a/modules/mid_registrar/gruu.c +++ b/modules/mid_registrar/gruu.c @@ -36,22 +36,33 @@ #include "gruu.h" -#define MAX_TGRUU_SIZE 255 #define GR_MAGIC 73 str default_gruu_secret=str_init("0p3nS1pS"); +static inline int calc_temp_gruu_raw_len(str* aor,str* instance,str *callid, + int time_len) +{ + if (instance->len < 2) { + LM_WARN("invalid +sip.instance value for GRUU contact\n"); + return -1; + } + + return time_len + aor->len + instance->len - 2 + callid->len + 3; /* and blank spaces */ +} + int calc_temp_gruu_len(str* aor,str* instance,str *callid) { int time_len,temp_gr_len; int2str((unsigned long)get_act_time(),&time_len); - temp_gr_len = time_len + aor->len + instance->len - 2 + callid->len + 3; /* and blank spaces */ + temp_gr_len = calc_temp_gruu_raw_len(aor, instance, callid, time_len); + if (temp_gr_len < 0) + return -1; temp_gr_len = (temp_gr_len/3 + (temp_gr_len%3?1:0))*4; /* base64 encoding */ return temp_gr_len; } -#define MAX_TEMP_GRUU_SIZE 255 -static char temp_gruu_buf[MAX_TEMP_GRUU_SIZE]; +static str temp_gruu_buf; char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) { int time_len,i; @@ -59,8 +70,14 @@ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) char *time_str = int2str((unsigned long)get_act_time(),&time_len); str *magic; - *len = time_len + aor->len + instance->len + callid->len + 3 - 2; /* +3 blank spaces, -2 discarded chars of instance in memcpy below */ - p = temp_gruu_buf; + *len = calc_temp_gruu_raw_len(aor, instance, callid, time_len); + if (*len < 0) + return NULL; + + if (pkg_str_extend(&temp_gruu_buf, *len) < 0) + return NULL; + + p = temp_gruu_buf.s; memcpy(p,time_str,time_len); p+=time_len; @@ -76,14 +93,13 @@ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) memcpy(p,callid->s,callid->len); - LM_DBG("build temp gruu [%.*s]\n",*len,temp_gruu_buf); + LM_DBG("build temp gruu [%.*s]\n",*len,temp_gruu_buf.s); if (gruu_secret.s != NULL) magic = &gruu_secret; else magic = &default_gruu_secret; for (i=0;i<*len;i++) - temp_gruu_buf[i] ^= magic->s[i%magic->len]; - return temp_gruu_buf; + temp_gruu_buf.s[i] ^= magic->s[i%magic->len]; + return temp_gruu_buf.s; } - diff --git a/modules/mid_registrar/lookup.c b/modules/mid_registrar/lookup.c index d2fa84339bd..cb384714cc4 100644 --- a/modules/mid_registrar/lookup.c +++ b/modules/mid_registrar/lookup.c @@ -54,6 +54,7 @@ int mid_reg_lookup(struct sip_msg *req, udomain_t *d, struct sip_uri puri; unsigned int flags = 0; int ret = LOOKUP_ERROR, pos, ruri_is_pushed = 0; + unsigned int dst_branches = 0; uint64_t contact_id; str aor; ucontact_t *ct; @@ -65,7 +66,13 @@ int mid_reg_lookup(struct sip_msg *req, udomain_t *d, if (lookup_flags) flags = lookup_flags->flags; - ruri_is_pushed = flags & REG_LOOKUP_NO_RURI_FLAG; + dst_branches = get_dset_size(); + + if (flags & REG_LOOKUP_NO_RURI_FLAG) { + ruri_is_pushed = 1; + if (req->first_line.type == SIP_REQUEST) + dst_branches++; + } if (!uri) uri = GET_RURI(req); @@ -128,7 +135,7 @@ int mid_reg_lookup(struct sip_msg *req, udomain_t *d, break; case 2: - switch (pn_awake_pn_contacts(req, &ct, 1)) { + switch (pn_awake_pn_contacts(req, &ct, 1, dst_branches + 1)) { case 1: ret = LOOKUP_PN_SENT; break; diff --git a/modules/mid_registrar/save.c b/modules/mid_registrar/save.c index 043f35bb1a1..28c798b9d1d 100644 --- a/modules/mid_registrar/save.c +++ b/modules/mid_registrar/save.c @@ -237,6 +237,14 @@ struct mr_ct_data { int last_cseq; }; +struct mr_aor_data { + struct mid_reg_info *mri; + const str *ct_uri; + int expires_out; + int last_reg_ts; + int last_cseq; +}; + static int mid_reg_store_ct_data(ucontact_t *c, void *info) { struct mr_ct_data *data = (struct mr_ct_data *)info; @@ -250,6 +258,19 @@ static int mid_reg_store_ct_data(ucontact_t *c, void *info) return rc; } +static int mid_reg_store_aor_data(urecord_t *r, void *info) +{ + struct mr_aor_data *data = (struct mr_aor_data *)info; + int rc; + + rc = store_urecord_data(r, data->mri, data->ct_uri, data->expires_out, + data->last_reg_ts, data->last_cseq); + if (rc != 0) + LM_ERR("failed to attach urecord data - oom?\n"); + + return rc; +} + static int mid_reg_update_ct_data(ucontact_t *c, void *info) { struct mr_ct_data *data = (struct mr_ct_data *)info; @@ -289,7 +310,7 @@ static int overwrite_req_contacts(struct sip_msg *req, ul.lock_udomain(mri->dom, &mri->aor); ul.get_urecord(mri->dom, &mri->aor, &r); - if (!r && ul.insert_urecord(mri->dom, &mri->aor, &r, 0) < 0) { + if (!r && ul.insert_urecord(mri->dom, &mri->aor, &r, 0, NULL, NULL) < 0) { rerrno = R_UL_NEW_R; LM_ERR("failed to insert new record structure\n"); goto out_err; @@ -741,6 +762,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, { unsigned int len; int qlen; + int gruu_len; const struct socket_info *sock; len = 0; @@ -760,7 +782,9 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, + 1 /* dquote */ ; } - if (build_gruu && c->instance.s) { + if (build_gruu && c->instance.s && + (gruu_len = calc_temp_gruu_len(c->aor, &c->instance, + &c->callid)) >= 0) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); /* pub gruu */ len += PUB_GRUU_SIZE @@ -777,7 +801,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, + 1 /* quote */ + SIP_PROTO_SIZE + TEMP_GRUU_HEADER_SIZE - + calc_temp_gruu_len(c->aor,&c->instance,&c->callid) + + gruu_len + 1 /* @ */ + sock->name.len + 1 /* : */ @@ -804,7 +828,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, int build_contact(ucontact_t* c,struct sip_msg *_m) { char *p, *cp, *tmpgr; - int fl, len,grlen; + int fl, len, grlen, gruu_len; int build_gruu = 0; const struct socket_info *sock; @@ -875,8 +899,17 @@ int build_contact(ucontact_t* c,struct sip_msg *_m) *p++ = '\"'; } - if (build_gruu && c->instance.s) { + if (build_gruu && c->instance.s && + (gruu_len = calc_temp_gruu_len(c->aor, &c->instance, + &c->callid)) >= 0) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); + tmpgr = build_temp_gruu(c->aor, &c->instance, &c->callid, + &grlen); + if (!tmpgr) { + contact.data_len = 0; + return -1; + } + /* build pub GRUU */ memcpy(p,PUB_GRUU,PUB_GRUU_SIZE); p += PUB_GRUU_SIZE; @@ -908,10 +941,9 @@ int build_contact(ucontact_t* c,struct sip_msg *_m) memcpy(p,TEMP_GRUU_HEADER,TEMP_GRUU_HEADER_SIZE); p += TEMP_GRUU_HEADER_SIZE; - tmpgr = build_temp_gruu(c->aor,&c->instance,&c->callid,&grlen); base64encode((unsigned char *)p, (unsigned char *)tmpgr,grlen); - p += calc_temp_gruu_len(c->aor,&c->instance,&c->callid); + p += gruu_len; *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; @@ -1033,12 +1065,16 @@ int append_contacts(ucontact_t *contacts, struct sip_msg *msg) return 0; } -int trim_contacts(urecord_t *r, int trims, const struct ct_match *match) +static int trim_contacts(urecord_t *r, int trims, const struct ct_match *match, + ucontact_t *excl_ct) { - ucontact_t *uc; + ucontact_t *uc, *uc_next; + + for (uc = r->contacts; uc && trims > 0; uc = uc_next) { + uc_next = uc->next; - for (uc = r->contacts; uc && trims > 0; uc = uc->next) { - if (!VALID_CONTACT(uc, get_act_time())) + if ((excl_ct && uc == excl_ct) + || !VALID_CONTACT(uc, get_act_time())) continue; LM_DBG("overflow on inserting new contact -> removing <%.*s>\n", @@ -1383,7 +1419,7 @@ static inline int save_restore_rpl_contacts(struct sip_msg *req, goto error; } - if (trim_contacts(r, vct - mri->max_contacts + 1, &mri->cmatch)) + if (trim_contacts(r, vct - mri->max_contacts + 1, &mri->cmatch, NULL)) goto error; } @@ -1441,7 +1477,7 @@ static inline int save_restore_rpl_contacts(struct sip_msg *req, goto error; } - if (trim_contacts(r, vct - mri->max_contacts, &mri->cmatch)) + if (trim_contacts(r, vct - mri->max_contacts, &mri->cmatch, c)) goto error; } @@ -1471,12 +1507,11 @@ static inline int save_restore_rpl_contacts(struct sip_msg *req, LM_ERR("failed to parse contact <%.*s>\n", ctmap->req_ct_uri.len, redact_pii(ctmap->req_ct_uri.s)); } else if ( is_tcp_based_proto(uri.proto) ) { - if (e_max) { + if (e_max) LM_WARN("multiple TCP contacts on single REGISTER\n"); - if (e_out>e_max) e_max = e_out; - } else { - e_max = e_out; - } + + if (ctmap->expires > e_max) + e_max = ctmap->expires; } } } @@ -1505,7 +1540,7 @@ static inline int save_restore_rpl_contacts(struct sip_msg *req, remove_expires_hf(rpl); if ( tcp_check && e_max>0 ) { - e_max -= get_act_time(); + LM_DBG("ensure TCP conn lifetime of at least %d sec\n", (e_max + 10)); trans_set_dst_attr( &req->rcv, DST_FCNTL_SET_LIFETIME, (void*)(long)(e_max + 10) ); } @@ -1572,7 +1607,16 @@ static inline int save_restore_req_contacts(struct sip_msg *req, if (!_c) goto out; - if (ul.insert_urecord(mri->dom, _a, &r, 0) < 0) { + /* populate kv_storage before cluster replication so peers receive + * a populated AoR INSERT packet (otherwise unregister_record() on + * peers fails to find the 'from' key when the AoR later expires) */ + struct mr_aor_data aor_data = { + mri, &_c->uri, e_out, + (int)(unsigned long)get_act_time(), cseq + }; + + if (ul.insert_urecord(mri->dom, _a, &r, 0, + mid_reg_store_aor_data, &aor_data) < 0) { rerrno = R_UL_NEW_R; LM_ERR("failed to insert new record structure\n"); goto out_err; @@ -1652,7 +1696,7 @@ static inline int save_restore_req_contacts(struct sip_msg *req, goto out_clear_err; } - if (trim_contacts(r, vct - mri->max_contacts + 1, &mri->cmatch)) + if (trim_contacts(r, vct - mri->max_contacts + 1, &mri->cmatch, NULL)) goto out_clear_err; } @@ -1701,7 +1745,7 @@ static inline int save_restore_req_contacts(struct sip_msg *req, goto out_clear_err; } - if (trim_contacts(r, vct - mri->max_contacts, &mri->cmatch)) + if (trim_contacts(r, vct - mri->max_contacts, &mri->cmatch, c)) goto out_clear_err; } @@ -1730,12 +1774,11 @@ static inline int save_restore_req_contacts(struct sip_msg *req, LM_ERR("failed to parse contact <%.*s>\n", ctmap->req_ct_uri.len, redact_pii(ctmap->req_ct_uri.s)); } else if ( is_tcp_based_proto(uri.proto) ) { - if (e_max) { + if (e_max) LM_WARN("multiple TCP contacts on single REGISTER\n"); - if (e_out>e_max) e_max = e_out; - } else { - e_max = e_out; - } + + if (ctmap->expires > e_max) + e_max = ctmap->expires; } } } @@ -1759,7 +1802,7 @@ static inline int save_restore_req_contacts(struct sip_msg *req, } if ( tcp_check && e_max>0 ) { - e_max -= get_act_time(); + LM_DBG("ensure TCP conn lifetime of at least %d sec\n", (e_max + 10)); trans_set_dst_attr( &req->rcv, DST_FCNTL_SET_LIFETIME, (void*)(long)(e_max + 10) ); } @@ -2215,7 +2258,7 @@ static int process_contacts_by_ct(struct sip_msg *msg, urecord_t *urec, return 1; } - ret = ul.get_ucontact(urec, &ct->uri, ci->callid, ci->cseq, + ret = ul.get_ucontact(urec, &ct->uri, ci->callid, REG_CSEQ_ADJUST(ci->cseq), &_sctx->cmatch, &c); if (ret == -1) { LM_ERR("invalid cseq for aor <%.*s>\n",urec->aor.len,urec->aor.s); @@ -2401,7 +2444,8 @@ static int process_contacts_by_aor(struct sip_msg *req, urecord_t *urec, e = e_out; } - ret = ul.get_ucontact(urec, &ct->uri, ci->callid, ci->cseq, + + ret = ul.get_ucontact(urec, &ct->uri, ci->callid, REG_CSEQ_ADJUST(ci->cseq), &_sctx->cmatch, &c); if (ret == -1) { LM_ERR("invalid cseq for aor <%.*s>\n",urec->aor.len,urec->aor.s); @@ -2438,7 +2482,7 @@ static int process_contacts_by_aor(struct sip_msg *req, urecord_t *urec, return -1; } - if (trim_contacts(urec, vct - _sctx->max_contacts, &_sctx->cmatch)) + if (trim_contacts(urec, vct - _sctx->max_contacts, &_sctx->cmatch, c)) return -1; } @@ -2478,7 +2522,7 @@ static int process_contacts_by_aor(struct sip_msg *req, urecord_t *urec, return -1; } - if (trim_contacts(urec, vct - _sctx->max_contacts + 1, &_sctx->cmatch)) + if (trim_contacts(urec, vct - _sctx->max_contacts + 1, &_sctx->cmatch, NULL)) return -1; } diff --git a/modules/mmgeoip/README b/modules/mmgeoip/README deleted file mode 100644 index c5c98d80cc0..00000000000 --- a/modules/mmgeoip/README +++ /dev/null @@ -1,258 +0,0 @@ -mmgeoip Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. mmgeoip_city_db_path (string) - 1.3.2. cache_type (string) - - 1.4. Exported Functions - - 1.4.1. mmg_lookup([fields,]src,dst) - - 1.5. Known Issues - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “mmgeoip_city_db_path” parameter - 1.2. Set “cache_type” parameter - 1.3. mmg_lookup usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is a lightweight wrapper for the MaxMind GeoIP API. - It adds IP address-to-location lookup capability to OpenSIPS - scripts. - - Lookups are executed against the freely-available GeoLite City - database; and the non-free GeoIP City database is drop-in - compatible. All lookup fields provided by the API are - accessible by the script. Visit the MaxMind website for more - information on the location databases. - - The module is compatible with both legacy GeoIP and the newer - GeoIP2 APIs and databases. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libGeoIP - for the legacy GeoIP API and database; - * libmaxminddb - for the GeoIP2 API and database. - - You can select which GeoIP library to use by setting the GEOIP - environment variable, before compiling the module, to one of - the following values: - * GEOIPLEGACY *** libGeoIP library shall be used - * GEOIP2 *** libmaxminddb library shall be used; - - IMPORTANT: If the selected library is not installed the module - won't compile. - - NOTE: If GEOIP env is not set, the module will try to find - which GeoIP library is installed, prioritizing libmaxminddb. - -1.3. Exported Parameters - -1.3.1. mmgeoip_city_db_path (string) - - Path to either a GeoLite or GeoIP City database file. - - Mandatory parameter. - - Example 1.1. Set “mmgeoip_city_db_path” parameter -... -modparam("mmgeoip", "mmgeoip_city_db_path", - "/usr/share/GeoIP/GeoLiteCity.dat") -... - -1.3.2. cache_type (string) - - Databse memory caching options. The following options are - available: - * STANDARD - Read database from file system; least memory - used; - * MMAP_CACHE - Load database into mmap allocated memory; - WARNING: this option will cause a segmentation fault if - database file is changed at runtime! - * MEM_CACHE_CHECK - Load database into memory; this mode - checks for database updates; if database was modified, the - file will be reloaded after 60 seconds; it will be slower - than MMAP_CACHE but it will allow reloads; - - Default value for this parameter is MMAP_CACHE. - - NOTE: If libmaxminddb is used, this parameter will be ignored - as the library only supports loading the database into mmap - allocated memory. - - Example 1.2. Set “cache_type” parameter -... -modparam("mmgeoip", "cache_type","MEM_CACHE_CHECK") -... - -1.4. Exported Functions - -1.4.1. mmg_lookup([fields,]src,dst) - - Looks up information specified by field associated with the IP - address src. The resulting data is loaded in reverse order into - the dst AVP. - - Parameters: - * fields (string, optional) - a list of elements delimited by - one of these separators: ':', '|', ',', '/' or ' '(space). - Accepts the following tokens: - + lat - Latitude - + lon - Longitude - + cont - Continent - + cc - Country Code - + reg - Region - + city - City - + pc - Postal Code - + dma - DMA Code - + ac - Area Code, only available in the legacy GeoIP - database - + tz - Time Zone - * src (string) - IP address - * dst (var) - AVP to return the information associated with - the IP in. - - When using the GeoIP2 library, each token from the list given - in the fields parameter can be provided as a path to a specific - key in the data structure associated with an IP. Thus, the - token format is 'key_name.key_name[.key_name]*'. If a key's - value is an array, instead of a subkey name, an index should be - provided in order to select the appropriate value. - - Example tokens: 'country.names.en', 'continent.names.en ', - 'subdivisions.0.iso_code'. For more details about the available - fields in the database and the key names that should be used to - retrieve them, check the MaxMind GeoIP2 documentation. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE,ERROR_ROUTE, and LOCAL_ROUTE. - - Example 1.3. mmg_lookup usage -... -if(mmg_lookup("lon:lat",$si,$avp(lat_lon))) { - xlog("L_INFO","Source IP latitude:$(avp(lat_lon)[0])\n"); - xlog("L_INFO","Source IP longitude:$(avp(lat_lon)[1])\n"); -}; -... -# fields format only supported for GeoIP2 -if(mmg_lookup("continent.names.en:country.iso_code,",$si,$avp(geodata))) - { - xlog("L_INFO","Source IP country code:$(avp(geodata)[0])\n"); - xlog("L_INFO","Source IP continent:$(avp(geodata)[1])\n"); -}; -... - -1.5. Known Issues - - It is not currently possible to load an updated location - database without first stalling the server. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 15 5 653 238 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 10 8 32 24 - 3. Razvan Crainea (@razvancrainea) 10 8 18 9 - 4. Liviu Chircu (@liviuchircu) 10 8 16 38 - 5. Kobi Eshun (@ekobi) 9 3 480 4 - 6. Maksym Sobolyev (@sobomax) 6 4 6 6 - 7. Sergio Gutierrez 4 2 5 3 - 8. Ionut Ionita (@ionutrazvanionita) 3 1 84 1 - 9. Anca Vamanu 3 1 6 2 - 10. Ken Rice 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Jun 2011 - Apr 2021 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Jan 2021 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2009 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionut Ionita (@ionutrazvanionita) May 2016 - May 2016 - 9. Kobi Eshun (@ekobi) Nov 2008 - Dec 2009 - 10. Anca Vamanu Sep 2009 - Sep 2009 - - All remaining contributors: Sergio Gutierrez. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita - (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Kobi - Eshun (@ekobi). - - Documentation Copyrights: - - Copyright © 2008 SightSpeed, Inc. diff --git a/modules/mmgeoip/README.md b/modules/mmgeoip/README.md new file mode 100644 index 00000000000..c0121ba137d --- /dev/null +++ b/modules/mmgeoip/README.md @@ -0,0 +1,193 @@ +--- +title: "mmgeoip Module" +description: "This module is a lightweight wrapper for the MaxMind GeoIP API." +--- + +## Admin Guide + + +### Overview + + +This module is a lightweight wrapper for the MaxMind GeoIP +API. It adds IP address-to-location lookup capability to +OpenSIPS scripts. + + +Lookups are executed against the freely-available GeoLite City +database; and the non-free GeoIP City database is drop-in +compatible. All lookup fields provided by the API are accessible +by the script. Visit the +[MaxMind +website](https://dev.maxmind.com/geoip/) for more information on the location +databases. + + +The module is compatible with both legacy GeoIP and the +newer GeoIP2 APIs and databases. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libGeoIP* - for the legacy GeoIP API and database; +- *libmaxminddb* - for the GeoIP2 API and database. + + +You can select which GeoIP library to use by setting the GEOIP environment variable, +before compiling the module, to one of the following values: + + +- *GEOIPLEGACY **** libGeoIP library shall be used +- *GEOIP2 **** libmaxminddb library shall be used; + + +> [!IMPORTANT] +> If the selected library is not installed the module won't compile. +> NOTE: If GEOIP env is not set, the module will try to find which GeoIP library is installed, +> prioritizing libmaxminddb. + +### Exported Parameters + + +#### mmgeoip_city_db_path (string) + + +Path to either a GeoLite or GeoIP City database file. + + +*Mandatory parameter.* + + +```opensips title="Set 'mmgeoip_city_db_path' parameter" +... +modparam("mmgeoip", "mmgeoip_city_db_path", + "/usr/share/GeoIP/GeoLiteCity.dat") +... + +``` + + +#### cache_type (string) + + +Databse memory caching options. The following options are available: + + +- *STANDARD* - Read database from file system; +least memory used; +- *MMAP_CACHE* - Load database into mmap allocated +memory; +*WARNING: this option will cause a segmentation +fault if database file is changed at runtime!* +- *MEM_CACHE_CHECK* - Load database into memory; +this mode checks for database updates; if database was modified, +the file will be reloaded after 60 seconds; it will be slower than +*MMAP_CACHE* but it will allow reloads; + + +Default value for this parameter is *MMAP_CACHE*. + + +> [!NOTE] +> If libmaxminddb is used, this parameter will be ignored as the library only +> supports loading the database into mmap allocated memory. + + +```opensips title="Set 'cache_type' parameter" +... +modparam("mmgeoip", "cache_type","MEM_CACHE_CHECK") +... + +``` + + +### Exported Functions + + +#### mmg_lookup([fields,]src,dst) + + +Looks up information specified by `field` associated with +the IP address `src`. The resulting data is loaded in +*reverse* order into the `dst` AVP. + + +Parameters: + + +- *fields* (string, optional) - a list of elements delimited by +one of these separators: ':', '|', ',', '/' or ' '(space). Accepts the following tokens: + - *lat* - Latitude + - *lon* - Longitude + - *cont* - Continent + - *cc* - Country Code + - *reg* - Region + - *city* - City + - *pc* - Postal Code + - *dma* - DMA Code + - *ac* - Area Code, only available in the legacy GeoIP database + - *tz* - Time Zone +- *src* (string) - IP address +- *dst* (var) - AVP to return the information associated with the IP in. + + +When using the GeoIP2 library, each token from the list given in the `fields` +parameter can be provided as a path to a specific key in the data structure associated with an +IP. Thus, the token format is '*key_name*.*key_name*[*.key_name*]*'. If a key's value is an array, instead of a subkey name, an index should be +provided in order to select the appropriate value. + + +Example tokens: '*country.names.en*', '*continent.names.en*', '*subdivisions.0.iso_code*'. For more details about +the available fields in the database and the key names that should be used to +retrieve them, check the [MaxMind +GeoIP2 documentation](https://dev.maxmind.com/geoip/geoip2/). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +ONREPLY_ROUTE, BRANCH_ROUTE,ERROR_ROUTE, and LOCAL_ROUTE. + + +```opensips title="mmg_lookup usage" +... +if(mmg_lookup("lon:lat",$si,$avp(lat_lon))) { + xlog("L_INFO","Source IP latitude:$(avp(lat_lon)[0])\n"); + xlog("L_INFO","Source IP longitude:$(avp(lat_lon)[1])\n"); +}; +... +# fields format only supported for GeoIP2 +if(mmg_lookup("continent.names.en:country.iso_code,",$si,$avp(geodata))) { + xlog("L_INFO","Source IP country code:$(avp(geodata)[0])\n"); + xlog("L_INFO","Source IP continent:$(avp(geodata)[1])\n"); +}; +... + +``` + + +### Known Issues + + +It is not currently possible to load an updated location +database without first stalling the server. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mmgeoip/doc/contributors.xml b/modules/mmgeoip/doc/contributors.xml deleted file mode 100644 index 7b2d2dc77de..00000000000 --- a/modules/mmgeoip/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 15 - 5 - 653 - 238 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 10 - 8 - 32 - 24 - - - 3. - Razvan Crainea (@razvancrainea) - 10 - 8 - 18 - 9 - - - 4. - Liviu Chircu (@liviuchircu) - 10 - 8 - 16 - 38 - - - 5. - Kobi Eshun (@ekobi) - 9 - 3 - 480 - 4 - - - 6. - Maksym Sobolyev (@sobomax) - 6 - 4 - 6 - 6 - - - 7. - Sergio Gutierrez - 4 - 2 - 5 - 3 - - - 8. - Ionut Ionita (@ionutrazvanionita) - 3 - 1 - 84 - 1 - - - 9. - Anca Vamanu - 3 - 1 - 6 - 2 - - - 10. - Ken Rice - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Jun 2011 - Apr 2021 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jan 2021 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2009 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionut Ionita (@ionutrazvanionita) - May 2016 - May 2016 - - - 9. - Kobi Eshun (@ekobi) - Nov 2008 - Dec 2009 - - - 10. - Anca Vamanu - Sep 2009 - Sep 2009 - - - -
-All remaining contributors: Sergio Gutierrez. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Kobi Eshun (@ekobi). -
- -
diff --git a/modules/mmgeoip/doc/mmgeoip.xml b/modules/mmgeoip/doc/mmgeoip.xml deleted file mode 100644 index 0b80a64e216..00000000000 --- a/modules/mmgeoip/doc/mmgeoip.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - mmgeoip Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 SightSpeed, Inc. - - diff --git a/modules/mmgeoip/doc/mmgeoip_admin.xml b/modules/mmgeoip/doc/mmgeoip_admin.xml deleted file mode 100644 index 014d1ba9d38..00000000000 --- a/modules/mmgeoip/doc/mmgeoip_admin.xml +++ /dev/null @@ -1,242 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is a lightweight wrapper for the MaxMind GeoIP - API. It adds IP address-to-location lookup capability to - &osips; scripts. - - - Lookups are executed against the freely-available GeoLite City - database; and the non-free GeoIP City database is drop-in - compatible. All lookup fields provided by the API are accessible - by the script. Visit the - MaxMind - website for more information on the location - databases. - - - The module is compatible with both legacy GeoIP and the - newer GeoIP2 APIs and databases. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libGeoIP - for the legacy GeoIP API and database; - - - - - libmaxminddb - for the GeoIP2 API and database. - - - - - - You can select which GeoIP library to use by setting the GEOIP environment variable, - before compiling the module, to one of the following values: - - - GEOIPLEGACY *** libGeoIP library shall be used - - - - GEOIP2 *** libmaxminddb library shall be used; - - - - IMPORTANT: If the selected library is not installed the module won't compile. - NOTE: If GEOIP env is not set, the module will try to find which GeoIP library is installed, - prioritizing libmaxminddb. - -
-
- -
- Exported Parameters - -
- <varname>mmgeoip_city_db_path</varname> (string) - - Path to either a GeoLite or GeoIP City database file. - - - - Mandatory parameter. - - - - Set <quote>mmgeoip_city_db_path</quote> parameter - -... -modparam("mmgeoip", "mmgeoip_city_db_path", - "/usr/share/GeoIP/GeoLiteCity.dat") -... - - -
- -
- <varname>cache_type</varname> (string) - - Databse memory caching options. The following options are available: - - - - - STANDARD - Read database from file system; - least memory used; - - - - - - MMAP_CACHE - Load database into mmap allocated - memory; - WARNING: this option will cause a segmentation - fault if database file is changed at runtime! - - - - - - MEM_CACHE_CHECK - Load database into memory; - this mode checks for database updates; if database was modified, - the file will be reloaded after 60 seconds; it will be slower than - MMAP_CACHE but it will allow reloads; - - - - - - - Default value for this parameter is MMAP_CACHE. - - - NOTE: If libmaxminddb is used, this parameter will be ignored as the library only - supports loading the database into mmap allocated memory. - - - Set <quote>cache_type</quote> parameter - -... -modparam("mmgeoip", "cache_type","MEM_CACHE_CHECK") -... - - -
- -
-
- Exported Functions -
- - <function moreinfo="none">mmg_lookup([fields,]src,dst)</function> - - - Looks up information specified by field associated with - the IP address src. The resulting data is loaded in - reverse order into the dst AVP. - - Parameters: - - - fields (string, optional) - a list of elements delimited by - one of these separators: ':', '|', ',', '/' or ' '(space). Accepts the following tokens: - - lat - Latitude - lon - Longitude - cont - Continent - cc - Country Code - reg - Region - city - City - pc - Postal Code - dma - DMA Code - ac - Area Code, only available in the legacy GeoIP - database - tz - Time Zone - - - - src (string) - IP address - - - dst (var) - AVP to return the information associated with the IP in. - - - - When using the GeoIP2 library, each token from the list given in the fields - parameter can be provided as a path to a specific key in the data structure associated with an - IP. Thus, the token format is 'key_name.key_name[.key_name]*'. If a key's value is an array, instead of a subkey name, an index should be - provided in order to select the appropriate value. - - - Example tokens: 'country.names.en', 'continent.names.en - ', 'subdivisions.0.iso_code'. For more details about - the available fields in the database and the key names that should be used to - retrieve them, check the MaxMind - GeoIP2 documentation. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE,ERROR_ROUTE, and LOCAL_ROUTE. - - - - <function moreinfo="none">mmg_lookup</function> usage - -... -if(mmg_lookup("lon:lat",$si,$avp(lat_lon))) { - xlog("L_INFO","Source IP latitude:$(avp(lat_lon)[0])\n"); - xlog("L_INFO","Source IP longitude:$(avp(lat_lon)[1])\n"); -}; -... -# fields format only supported for GeoIP2 -if(mmg_lookup("continent.names.en:country.iso_code,",$si,$avp(geodata))) { - xlog("L_INFO","Source IP country code:$(avp(geodata)[0])\n"); - xlog("L_INFO","Source IP continent:$(avp(geodata)[1])\n"); -}; -... - - -
-
- -
- Known Issues - - It is not currently possible to load an updated location - database without first stalling the server. - -
- -
- diff --git a/modules/mqueue/README b/modules/mqueue/README deleted file mode 100644 index 8738fb0e914..00000000000 --- a/modules/mqueue/README +++ /dev/null @@ -1,314 +0,0 @@ -mqueue Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (str) - 1.3.2. mqueue (string) - - 1.4. Exported Functions - - 1.4.1. mq_add(queue, key, value) - 1.4.2. mq_fetch(queue) - 1.4.3. mq_pv_free(queue) - 1.4.4. mq_size(queue) - - 1.5. Exported MI Functions - - 1.5.1. mq_get_size - 1.5.2. mq_fetch - 1.5.3. mq_get_sizes - - 1.6. Exported Pseudo-Variables - - 1.6.1. $mqk(mqueue) - 1.6.2. $mqv(mqueue) - 1.6.3. $mq_size(mqueue) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set mqueue parameter - 1.3. mq_add usage - 1.4. mq_fetch usage - 1.5. mq_pv_free usage - 1.6. mq_size usage - 1.7. mq_get_size usage - 1.8. mq_fetch usage - 1.9. mq_get_sizes usage - -Chapter 1. Admin Guide - -1.1. Overview - - The mqueue module offers a generic message queue system in - shared memory for inter-process communication using the config - file. One example of usage is to send time consuming operations - to one or several timer processes that consumes items in the - queue, without affecting SIP message handling in the - socket-listening process. - - There can be many defined queues. Access to queued values is - done via pseudo variables. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (str) - - The URL to connect to database for loading values in mqueue - table at start up and/or saving values at shutdown. - - Default value is NULL (do not connect). - - Example 1.1. Set db_url parameter -... -modparam("mqueue", "db_url", "mysql://opensips:opensipsrw@localhost/open -sips") - -# Example of table in sqlite, -# you have the set the fields to support the length according -# to the data that will be present in the mqueue -CREATE TABLE mqueue_name ( -id INTEGER PRIMARY KEY AUTOINCREMENT, -key character varying(64) DEFAULT "" NOT NULL, -val character varying(4096) DEFAULT "" NOT NULL -); -... - -1.3.2. mqueue (string) - - Definition of a memory queue - - Default value is “none”. - - Value must be a list of parameters: attr=value;... - * Mandatory attributes: - + name: name of the queue. - * Optional attributes: - + size: size of the queue. Specifies the maximum number - of items in queue. If exceeded the oldest one is - removed. If not set the queue will be limitless. - + dbmode: If set to 1, the content of the queue is - written to database table when the SIP server is - stopped (i.e., ensure persistency over restarts). If - set to 2, it is written at shutdown but not read at - startup. If set to 3, it is read at sartup but not - written at shutdown. Default value is 0 (no db table - interaction). - + addmode: how to add new (key,value) pairs. - o 0: Will push all new (key,value) pairs at the end - of the queue. (default) - o 1: Will keep oldest (key,value) pair in the - queue, based on the key. - o 2: Will keep newest (key,value) pair in the - queue, based on the key. - - The parameter can be set many times, each holding the - definition of one queue. - - Example 1.2. Set mqueue parameter -... -modparam("mqueue", "mqueue", "name=myq;size=20;") -modparam("mqueue", "mqueue", "name=myq;size=10000;addmode=2") -modparam("mqueue", "mqueue", "name=qaz") -modparam("mqueue", "mqueue", "name=qaz;addmode=1") -... - -1.4. Exported Functions - -1.4.1. mq_add(queue, key, value) - - Add a new item (key, value) in the queue. If max size of queue - is exceeded, the oldest one is removed. - - Example 1.3. mq_add usage -... -mq_add("myq", "$rU", "call from $fU"); -... - -1.4.2. mq_fetch(queue) - - Take oldest item from queue and fill $mqk(queue) and - $mqv(queue) pseudo variables. - - Return: true on success (1); false on failure (-1) or no item - fetched (-2). - - Example 1.4. mq_fetch usage -... -while(mq_fetch("myq")) -{ - xlog("$mqk(myq) - $mqv(myq)\n"); -} -... - -1.4.3. mq_pv_free(queue) - - Free the item fetched in pseudo-variables. It is optional, a - new fetch frees the previous values. - - Example 1.5. mq_pv_free usage -... -mq_pv_free("myq"); -... - -1.4.4. mq_size(queue) - - Returns the current number of elements in the mqueue. - - If the mqueue is empty, the function returns -1. If the mqueue - is not found, the function returns -2. - - Example 1.6. mq_size usage -... -$var(q_size) = mq_size("queue"); -xlog("L_INFO", "Size of queue is: $var(q_size)\n"); -... - -1.5. Exported MI Functions - -1.5.1. mq_get_size - - Get the size of a memory queue. - - Parameters: - * name - the name of memory queue - - Example 1.7. mq_get_size usage -... -opensips-cli -x mq_get_size xyz -... - -1.5.2. mq_fetch - - Fetch one (or up to limit) key-value pair from a memory queue. - - Parameters: - * name - the name of memory queue - * limit (optional) - if used, an array with up to limit - records are being returned. - - Example 1.8. mq_fetch usage -... -opensips-cli -x mq_fetch xyz -... - -1.5.3. mq_get_sizes - - Get the size for all memory queues. - - Parameters: none - - Example 1.9. mq_get_sizes usage -... -opensips-cli -x mq_get_sizes -... - -1.6. Exported Pseudo-Variables - -1.6.1. $mqk(mqueue) - - The variable is read-only and returns the most recent item key - fetched from the specified mqueue. - -1.6.2. $mqv(mqueue) - - The variable is read-only and returns the most recent item - value fetched from the specified mqueue. - -1.6.3. $mq_size(mqueue) - - The variable is read-only and returns the size of the specified - mqueue. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 19 2 1843 34 - 2. Razvan Crainea (@razvancrainea) 3 1 75 16 - 3. Alexandra Titoc 3 1 13 9 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Feb 2025 - Feb 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Ovidiu Sas (@ovidiusas) Feb 2024 - Feb 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Ovidiu Sas - (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2010 Elena-Ramona Modroiu - - Copyright © 2018-2020 Julien chavanton, Flowroute - - Copyright © 2024 Ovidiu Sas, VoIP Embedded, Inc. diff --git a/modules/mqueue/README.md b/modules/mqueue/README.md new file mode 100644 index 00000000000..e041fee19e8 --- /dev/null +++ b/modules/mqueue/README.md @@ -0,0 +1,282 @@ +--- +title: "mqueue Module" +description: "The mqueue module offers a generic message queue system in shared memory for inter-process communication using the config file." +--- + +## Admin Guide + + +### Overview + + +The mqueue module offers a generic message queue system in shared +memory for inter-process communication using the config file. +One example of usage is to send time consuming operations to one or +several timer processes that consumes items in the queue, without +affecting SIP message handling in the socket-listening process. + + +There can be many defined queues. Access to queued values is done via +pseudo variables. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (str) + + +The URL to connect to database for loading values +in mqueue table at start up and/or saving values at shutdown. + + +*Default value is NULL (do not connect).* + + +```opensips title="Set db_url parameter" +... +modparam("mqueue", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") + +# Example of table in sqlite, +# you have the set the fields to support the length according +# to the data that will be present in the mqueue +CREATE TABLE mqueue_name ( +id INTEGER PRIMARY KEY AUTOINCREMENT, +key character varying(64) DEFAULT "" NOT NULL, +val character varying(4096) DEFAULT "" NOT NULL +); +... +``` + + +#### mqueue (string) + + +Definition of a memory queue + + +*Default value is "none".* + + +Value must be a list of parameters: attr=value;... + + +- Mandatory attributes: + + - *name*: name of the queue. +- Optional attributes: + + - *size*: size of the queue. +Specifies the maximum number of items in queue. +If exceeded the oldest one is removed. +If not set the queue will be limitless. + - *dbmode*: If set to 1, the content of the +queue is written to database table when the SIP server is +stopped (i.e., ensure persistency over restarts). +If set to 2, it is written at shutdown but not read at startup. +If set to 3, it is read at sartup but not written at shutdown. +Default value is 0 (no db table interaction). + - *addmode*: how to add new (key,value) pairs. + - *0*: + Will push all new (key,value) pairs at the end of + the queue. (default) + - *1*: + Will keep oldest (key,value) pair in the queue, + based on the key. + - *2*: + Will keep newest (key,value) pair in the queue, + based on the key. + + +The parameter can be set many times, each holding the +definition of one queue. + + +```opensips title="Set mqueue parameter" +... +modparam("mqueue", "mqueue", "name=myq;size=20;") +modparam("mqueue", "mqueue", "name=myq;size=10000;addmode=2") +modparam("mqueue", "mqueue", "name=qaz") +modparam("mqueue", "mqueue", "name=qaz;addmode=1") +... +``` + + +### Exported Functions + + +#### mq_add(queue, key, value) + + +Add a new item (key, value) in the queue. If max size of queue is +exceeded, the oldest one is removed. + + +```opensips title="mq_add usage" +... +mq_add("myq", "$rU", "call from $fU"); +... +``` + + +#### mq_fetch(queue) + + +Take oldest item from queue and fill $mqk(queue) and +$mqv(queue) pseudo variables. + + +Return: true on success (1); false on failure (-1) or +no item fetched (-2). + + +```opensips title="mq_fetch usage" +... +while(mq_fetch("myq")) +{ + xlog("$mqk(myq) - $mqv(myq)\n"); +} +... +``` + + +#### mq_pv_free(queue) + + +Free the item fetched in pseudo-variables. It is optional, +a new fetch frees the previous values. + + +```opensips title="mq_pv_free usage" +... +mq_pv_free("myq"); +... +``` + + +#### mq_size(queue) + + +Returns the current number of elements in the mqueue. + + +If the mqueue is empty, the function returns -1. If the +mqueue is not found, the function returns -2. + + +```opensips title="mq_size usage" +... +$var(q_size) = mq_size("queue"); +xlog("L_INFO", "Size of queue is: $var(q_size)\n"); +... +``` + + +### Exported MI Functions + + +#### mq_get_size + + +Get the size of a memory queue. + + +Parameters: + + +- name + + +```bash title="mq_get_size usage" +... +opensips-cli -x mq_get_size xyz +... +``` + + +#### mq_fetch + + +Fetch one (or up to limit) key-value pair from a memory queue. + + +Parameters: + + +- name +- limit +limit + + +```bash title="mq_fetch usage" +... +opensips-cli -x mq_fetch xyz +... +``` + + +#### mq_get_sizes + + +Get the size for all memory queues. + + +Parameters: none + + +```bash title="mq_get_sizes usage" +... +opensips-cli -x mq_get_sizes +... +``` + + +### Exported Pseudo-Variables + + +#### $mqk(mqueue) + + +The variable is read-only and returns the most recent item key +fetched from the specified mqueue. + + +#### $mqv(mqueue) + + +The variable is read-only and returns the most recent item value +fetched from the specified mqueue. + + +#### $mq_size(mqueue) + + +The variable is read-only and returns the size of the specified +mqueue. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/mqueue/doc/contributors.xml b/modules/mqueue/doc/contributors.xml deleted file mode 100644 index f5d0cd2c69c..00000000000 --- a/modules/mqueue/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 19 - 2 - 1843 - 34 - - - 2. - Razvan Crainea (@razvancrainea) - 3 - 1 - 75 - 16 - - - 3. - Alexandra Titoc - 3 - 1 - 13 - 9 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Feb 2025 - Feb 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Ovidiu Sas (@ovidiusas) - Feb 2024 - Feb 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/mqueue/doc/mqueue.xml b/modules/mqueue/doc/mqueue.xml deleted file mode 100644 index 964bd0d0e0c..00000000000 --- a/modules/mqueue/doc/mqueue.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -%docentities; - -]> - - - - mqueue Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2010 Elena-Ramona Modroiu - ©right; 2018-2020 Julien chavanton, Flowroute - ©right; 2024 Ovidiu Sas, VoIP Embedded, Inc. - diff --git a/modules/mqueue/doc/mqueue_admin.xml b/modules/mqueue/doc/mqueue_admin.xml deleted file mode 100644 index 65a5f86db4f..00000000000 --- a/modules/mqueue/doc/mqueue_admin.xml +++ /dev/null @@ -1,342 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The mqueue module offers a generic message queue system in shared - memory for inter-process communication using the config file. - One example of usage is to send time consuming operations to one or - several timer processes that consumes items in the queue, without - affecting SIP message handling in the socket-listening process. - - - There can be many defined queues. Access to queued values is done via - pseudo variables. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - None. - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - None. - - - -
-
- - -
- Exported Parameters - -
- <varname>db_url</varname> (str) - - The URL to connect to database for loading values - in mqueue table at start up and/or saving values at shutdown. - - - Default value is NULL (do not connect). - - - Set <varname>db_url</varname> parameter - -... -modparam("mqueue", "db_url", "&defaultdb;") - -# Example of table in sqlite, -# you have the set the fields to support the length according -# to the data that will be present in the mqueue -CREATE TABLE mqueue_name ( -id INTEGER PRIMARY KEY AUTOINCREMENT, -key character varying(64) DEFAULT "" NOT NULL, -val character varying(4096) DEFAULT "" NOT NULL -); -... - - -
-
- <varname>mqueue</varname> (string) - Definition of a memory queue - - - Default value is none. - - - - Value must be a list of parameters: attr=value;... - - - Mandatory attributes: - - - - name: name of the queue. - - - - - - Optional attributes: - - - - size: size of the queue. - Specifies the maximum number of items in queue. - If exceeded the oldest one is removed. - If not set the queue will be limitless. - - - - - dbmode: If set to 1, the content of the - queue is written to database table when the SIP server is - stopped (i.e., ensure persistency over restarts). - If set to 2, it is written at shutdown but not read at startup. - If set to 3, it is read at sartup but not written at shutdown. - Default value is 0 (no db table interaction). - - - - - addmode: how to add new (key,value) pairs. - - - - 0: - Will push all new (key,value) pairs at the end of - the queue. (default) - - - - - 1: - Will keep oldest (key,value) pair in the queue, - based on the key. - - - - - 2: - Will keep newest (key,value) pair in the queue, - based on the key. - - - - - - - - - - - The parameter can be set many times, each holding the - definition of one queue. - - - Set <varname>mqueue</varname> parameter - -... -modparam("mqueue", "mqueue", "name=myq;size=20;") -modparam("mqueue", "mqueue", "name=myq;size=10000;addmode=2") -modparam("mqueue", "mqueue", "name=qaz") -modparam("mqueue", "mqueue", "name=qaz;addmode=1") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">mq_add(queue, key, value)</function> - - - Add a new item (key, value) in the queue. If max size of queue is - exceeded, the oldest one is removed. - - - <function>mq_add</function> usage - -... -mq_add("myq", "$rU", "call from $fU"); -... - - -
- -
- - <function moreinfo="none">mq_fetch(queue)</function> - - - Take oldest item from queue and fill $mqk(queue) and - $mqv(queue) pseudo variables. - - - Return: true on success (1); false on failure (-1) or - no item fetched (-2). - - - <function>mq_fetch</function> usage - -... -while(mq_fetch("myq")) -{ - xlog("$mqk(myq) - $mqv(myq)\n"); -} -... - - -
- -
- - <function moreinfo="none">mq_pv_free(queue)</function> - - - Free the item fetched in pseudo-variables. It is optional, - a new fetch frees the previous values. - - - <function>mq_pv_free</function> usage - -... -mq_pv_free("myq"); -... - - -
- -
- - <function moreinfo="none">mq_size(queue)</function> - - - Returns the current number of elements in the mqueue. - - - If the mqueue is empty, the function returns -1. If the - mqueue is not found, the function returns -2. - - - <function>mq_size</function> usage - -... -$var(q_size) = mq_size("queue"); -xlog("L_INFO", "Size of queue is: $var(q_size)\n"); -... - - -
-
- - -
- Exported MI Functions -
- mq_get_size - Get the size of a memory queue. - Parameters: - - - name - the name of memory queue - - - - <function>mq_get_size</function> usage - -... -opensips-cli -x mq_get_size xyz -... - - -
-
- mq_fetch - Fetch one (or up to limit) key-value pair from a memory queue. - Parameters: - - - name - the name of memory queue - - - limit (optional) - if used, an array - with up to limit records are being returned. - - - - <function>mq_fetch</function> usage - -... -opensips-cli -x mq_fetch xyz -... - - -
- -
- mq_get_sizes - Get the size for all memory queues. - Parameters: none - - <function>mq_get_sizes</function> usage - -... -opensips-cli -x mq_get_sizes -... - - -
-
- - -
- Exported Pseudo-Variables -
- <varname>$mqk(mqueue)</varname> - - The variable is read-only and returns the most recent item key - fetched from the specified mqueue. - -
-
- <varname>$mqv(mqueue)</varname> - - The variable is read-only and returns the most recent item value - fetched from the specified mqueue. - -
-
- <varname>$mq_size(mqueue)</varname> - - The variable is read-only and returns the size of the specified - mqueue. - -
-
- -
diff --git a/modules/msilo/README b/modules/msilo/README deleted file mode 100644 index 8c4feec67c2..00000000000 --- a/modules/msilo/README +++ /dev/null @@ -1,800 +0,0 @@ -MSILO Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS modules - 1.2.2. External libraries or applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. from_address (string) - 1.3.4. contact_hdr (string) - 1.3.5. offline_message (string) - 1.3.6. content_type_hdr (string) - 1.3.7. reminder (string) - 1.3.8. outbound_proxy (string) - 1.3.9. expire_time (int) - 1.3.10. check_time (int) - 1.3.11. send_time (int) - 1.3.12. clean_period (int) - 1.3.13. use_contact (int) - 1.3.14. sc_mid (string) - 1.3.15. sc_from (string) - 1.3.16. sc_to (string) - 1.3.17. sc_uri_user (string) - 1.3.18. sc_uri_host (string) - 1.3.19. sc_body (string) - 1.3.20. sc_ctype (string) - 1.3.21. sc_exp_time (string) - 1.3.22. sc_inc_time (string) - 1.3.23. sc_snd_time (string) - 1.3.24. snd_time_avp (str) - 1.3.25. add_date (int) - 1.3.26. max_messages (int) - - 1.4. Exported Functions - - 1.4.1. m_store([owner]) - 1.4.2. m_dump([owner], [maxmsg]) - - 1.5. Exported Statistics - - 1.5.1. stored_messages - 1.5.2. dumped_messages - 1.5.3. failed_messages - 1.5.4. dumped_reminders - 1.5.5. failed_reminders - - 1.6. Installation and Running - - 1.6.1. OpenSIPS config file - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set the “db_url” parameter - 1.2. Set the “db_table” parameter - 1.3. Set the “from_address” parameter - 1.4. Set the “contact_hdr” parameter - 1.5. Set the “offline_message” parameter - 1.6. Set the “content_type_hdr” parameter - 1.7. Set the “reminder” parameter - 1.8. Set the “outbound_proxy” parameter - 1.9. Set the “expire_time” parameter - 1.10. Set the “check_time” parameter - 1.11. Set the “send_time” parameter - 1.12. Set the “clean_period” parameter - 1.13. Set the “use_contact” parameter - 1.14. Set the “sc_mid” parameter - 1.15. Set the “sc_from” parameter - 1.16. Set the “sc_to” parameter - 1.17. Set the “sc_uri_user” parameter - 1.18. Set the “sc_uri_host” parameter - 1.19. Set the “sc_body” parameter - 1.20. Set the “sc_ctype” parameter - 1.21. Set the “sc_exp_time” parameter - 1.22. Set the “sc_inc_time” parameter - 1.23. Set the “sc_snd_time” parameter - 1.24. Set the “snd_time_avp” parameter - 1.25. Set the “add_date” parameter - 1.26. Set the “max_messages” parameter - 1.27. m_store usage - 1.28. m_dump usage - 1.29. OpenSIPS config script - sample msilo usage - -Chapter 1. Admin Guide - -1.1. Overview - - This modules provides offline message storage for the Open SIP - Server. It stores received messages for an offline user and - sends them when the user becomes online. - - For each message, the modules stores “Request-URI” (“R-URI”) - only if it is a complete address of record - (“username@hostname”), URI from “To” header, URI from “From” - header, incoming time, expiration time, content type and body - of the message. If “R-URI” is not an address of record (it - might be the contact address for current SIP session) the URI - from “To” header will be used as R-URI. - - When the expiration time passed, the message is discarded from - database. Expiration time is computed based on incoming time - and one of the module's parameters. - - Every time when a user registers with OpenSIPS, the module is - looking in database for offline messages intended for that - user. All of them will be sent to contact address provided in - REGISTER request. - - It may happen the SIP user to be registered but his SIP User - Agent to have no support for MESSAGE request. In this case it - should be used the “failure_route” to store the undelivered - requests. - - Another functionality provided by the modules is to send - messages at a certain time -- the reminder functionality. Using - config logic, a received message can be stored and delivered at - a time specified while storing with the 'snd_time_avp'. - -1.2. Dependencies - -1.2.1. OpenSIPS modules - - The following modules must be loaded before this module: - * database module - mysql, dbtext or other module that - implements the “db” interface and provides support for - storing/receiving data to/from a database system. - * TM--transaction module--is used to send SIP requests. - -1.2.2. External libraries or applications - - The following libraries or applications must be installed - before running OpenSIPS with this module: - * none. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Database URL. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set the “db_url” parameter -... -modparam("msilo", "db_url", "mysql://user:passwd@host.com/dbname") -... - -1.3.2. db_table (string) - - The name of table where to store the messages. - - Default value is “silo”. - - Example 1.2. Set the “db_table” parameter -... -modparam("msilo", "db_table", "silo") -... - -1.3.3. from_address (string) - - The SIP address used to inform users that destination of their - message is not online and the message will be delivered next - time when that user goes online. If the parameter is not set, - the module will not send any notification. It can contain - pseudo-variables. - - Default value is “NULL”. - - Example 1.3. Set the “from_address” parameter -... -modparam("msilo", "from_address", "sip:registrar@example.org") -modparam("msilo", "from_address", "sip:$rU@example.org") -... - -1.3.4. contact_hdr (string) - - The value of the Contact header (including header name and - ending \r\n) to be added in notification messages. It can - contain pseudo-variables. - - Default value is “NULL”. - - Example 1.4. Set the “contact_hdr” parameter -... -modparam("msilo", "contact_hdr", "Contact: \r\n") -... - -1.3.5. offline_message (string) - - The body of the notification message. It can contain - pseudo-variables. - - Default value is “NULL”. - - Example 1.5. Set the “offline_message” parameter -... -modparam("msilo", "offline_message", "*** User $rU is offline!") -modparam("msilo", "offline_message", "I am offline!") -... - -1.3.6. content_type_hdr (string) - - The value of the Content-Type header (including header name and - ending \r\n) to be added in notification messages. It must - reflect what the 'offline_message' contains. It can contain - pseudo-variables. - - Default value is “NULL”. - - Example 1.6. Set the “content_type_hdr” parameter -... -modparam("msilo", "content_type_hdr", "Content-Type: text/plain\r\n") -modparam("msilo", "content_type_hdr", "Content-Type: text/html\r\n") -... - -1.3.7. reminder (string) - - The SIP address used to send reminder messages. If this value - is not set, the reminder feature is disabled. - - Default value is “NULL”. - - Example 1.7. Set the “reminder” parameter -... -modparam("msilo", "reminder", "sip:registrar@example.org") -... - -1.3.8. outbound_proxy (string) - - The SIP address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or - when using a separate OpenSIPS instance for msilo processing. - If not set, the message will be sent to the address in - destination URI. - - Default value is “NULL”. - - Example 1.8. Set the “outbound_proxy” parameter -... -modparam("msilo", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - -1.3.9. expire_time (int) - - Expire time of stored messages - seconds. When this time - passed, the message is silently discarded from database. - - Default value is “259200 (72 hours = 3 days)”. - - Example 1.9. Set the “expire_time” parameter -... -modparam("msilo", "expire_time", 36000) -... - -1.3.10. check_time (int) - - Timer interval to check if dumped messages are sent OK - - seconds. The module keeps each request send by itself for a new - online user and if the reply is 2xx then the message is deleted - from database. - - Default value is “30”. - - Example 1.10. Set the “check_time” parameter -... -modparam("msilo", "check_time", 10) -... - -1.3.11. send_time (int) - - Timer interval in seconds to check if there are reminder - messages. The module takes all reminder messages that must be - sent at that moment or before that moment. - - If the value is 0, the reminder feature is disabled. - - Default value is “0”. - - Example 1.11. Set the “send_time” parameter -... -modparam("msilo", "send_time", 60) -... - -1.3.12. clean_period (int) - - Number of “check_time” cycles when to check if there are - expired messages in database. - - Default value is “5”. - - Example 1.12. Set the “clean_period” parameter -... -modparam("msilo", "clean_period", 3) -... - -1.3.13. use_contact (int) - - Turns on/off the usage of the Contact address to send - notification back to sender whose message is stored by MSILO. - - Default value is “1 (0 = off, 1 = on)”. - - Example 1.13. Set the “use_contact” parameter -... -modparam("msilo", "use_contact", 0) -... - -1.3.14. sc_mid (string) - - The name of the column in silo table, storing message id. - - Default value is “mid”. - - Example 1.14. Set the “sc_mid” parameter -... -modparam("msilo", "sc_mid", "other_mid") -... - -1.3.15. sc_from (string) - - The name of the column in silo table, storing the source - address. - - Default value is “src_addr”. - - Example 1.15. Set the “sc_from” parameter -... -modparam("msilo", "sc_from", "source_address") -... - -1.3.16. sc_to (string) - - The name of the column in silo table, storing the destination - address. - - Default value is “dst_addr”. - - Example 1.16. Set the “sc_to” parameter -... -modparam("msilo", "sc_to", "destination_address") -... - -1.3.17. sc_uri_user (string) - - The name of the column in silo table, storing the user name. - - Default value is “username”. - - Example 1.17. Set the “sc_uri_user” parameter -... -modparam("msilo", "sc_uri_user", "user") -... - -1.3.18. sc_uri_host (string) - - The name of the column in silo table, storing the domain. - - Default value is “domain”. - - Example 1.18. Set the “sc_uri_host” parameter -... -modparam("msilo", "sc_uri_host", "domain") -... - -1.3.19. sc_body (string) - - The name of the column storing the message body in silo table. - - Default value is “body”. - - Example 1.19. Set the “sc_body” parameter -... -modparam("msilo", "sc_body", "message_body") -... - -1.3.20. sc_ctype (string) - - The name of the column in silo table, storing content type. - - Default value is “ctype”. - - Example 1.20. Set the “sc_ctype” parameter -... -modparam("msilo", "sc_ctype", "content_type") -... - -1.3.21. sc_exp_time (string) - - The name of the column in silo table, storing the expire time - of the message. - - Default value is “exp_time”. - - Example 1.21. Set the “sc_exp_time” parameter -... -modparam("msilo", "sc_exp_time", "expire_time") -... - -1.3.22. sc_inc_time (string) - - The name of the column in silo table, storing the incoming time - of the message. - - Default value is “inc_time”. - - Example 1.22. Set the “sc_inc_time” parameter -... -modparam("msilo", "sc_inc_time", "incoming_time") -... - -1.3.23. sc_snd_time (string) - - The name of the column in silo table, storing the send time for - the reminder. - - Default value is “snd_time”. - - Example 1.23. Set the “sc_snd_time” parameter -... -modparam("msilo", "sc_snd_time", "send_reminder_time") -... - -1.3.24. snd_time_avp (str) - - The name of an AVP which may contain the time when to sent the - received message as reminder.The AVP is used ony by m_store(). - - If the parameter is not set, the module does not look for this - AVP. If the value is set to a valid AVP name, then the module - expects in the AVP to be a time value in format YYYYMMDDHHMMSS - (e.g., 20060101201500). - - Default value is “null”. - - Example 1.24. Set the “snd_time_avp” parameter -... -modparam("msilo", "snd_time_avp", "$avp(snd_time)") -... - -1.3.25. add_date (int) - - Wheter to add as prefix the date when the message was stored. - - Default value is “1” (1==on/0==off). - - Example 1.25. Set the “add_date” parameter -... -modparam("msilo", "add_date", 0) -... - -1.3.26. max_messages (int) - - Maximum number of stored message for an AoR. Value 0 equals to - no limit. - - Default value is 0. - - Example 1.26. Set the “max_messages” parameter -... -modparam("msilo", "max_messages", 0) -... - -1.4. Exported Functions - -1.4.1. m_store([owner]) - - The method stores certain parts of the current SIP request (it - should be called when the request type is MESSAGE and the - destination user is offline or his UA does not support MESSAGE - requests). If the user is registered with a UA which does not - support MESSAGE requests you should not use mode=“0” if you - have changed the request uri with the contact address of user's - UA. - - Meaning of the parameters is as follows: - * owner (string, optional) - a SIP URI in whose inbox the - message will be stored. If "owner" is missing, the SIP - address is taken from R-URI. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.27. m_store usage -... -m_store(); -m_store($tu); -... - -1.4.2. m_dump([owner], [maxmsg]) - - The method sends stored messages for the SIP user that is going - to register to his actual contact address. The method should be - called when a REGISTER request is received and the “Expire” - header has a value greater than zero. - - Meaning of the parameters is as follows: - * owner (string, optional) - a SIP URI whose inbox will be - dumped. If "owner" is missing, the SIP address is taken - from To URI. - * maxmsg (int, optional) - is a maximum number of messages to - be dumped. - - This function can be used from REQUEST_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE, EVENT_ROUTE - - Example 1.28. m_dump usage -... -m_dump(); -m_dump($fu); -m_dump($fu, 10); -... - -1.5. Exported Statistics - -1.5.1. stored_messages - - The number of messages stored by msilo. - -1.5.2. dumped_messages - - The number of dumped messages. - -1.5.3. failed_messages - - The number of failed dumped messages. - -1.5.4. dumped_reminders - - The number of dumped reminder messages. - -1.5.5. failed_reminders - - The number of failed reminder messages. - -1.6. Installation and Running - -1.6.1. OpenSIPS config file - - Next picture displays a sample usage of msilo. - - Example 1.29. OpenSIPS config script - sample msilo usage -... -# -# MSILO usage example -# -# - - -# running in debug mode (log level 4, log to stderr, stay in foreground) -debug_mode=yes - -check_via=no # (cmd. line: -v) -dns=off # (cmd. line: -r) -rev_dns=off # (cmd. line: -R) -port=5060 - -socket=10.0.0.2 # listen address - -# ------------------ module loading ---------------------------------- -mpath="/usr/local/lib/opensips/modules/" - -loadmodule "textops.so" - -loadmodule "sl.so" -loadmodule "mysql.so" -loadmodule "maxfwd.so" -loadmodule "msilo.so" -loadmodule "tm.so" -loadmodule "registrar.so" -loadmodule "usrloc.so" - -# ----------------- setting module-specific parameters --------------- - -# -- registrar params -- - -modparam("registrar", "default_expires", 120) - -# -- registrar params -- - -modparam("usrloc", "db_mode", 0) - -# -- msilo params -- - -modparam("msilo","db_url","mysql://opensips:opensipsrw@localhost/opensip -s") -modparam("msilo","from_address","sip:registrar@opensips.org") -modparam("msilo","contact_hdr","Contact: registrar@192.168.1.2:5060;msil -o=yes\r\n") -modparam("msilo","content_type_hdr","Content-Type: text/plain\r\n") -modparam("msilo","offline_message","*** User $rU is offline!") - -# -- tm params -- - -modparam("tm", "fr_timer", 10 ) -modparam("tm", "fr_inv_timer", 15 ) -modparam("tm", "wt_timer", 10 ) - - -route{ - if ( !mf_process_maxfwd_header(10) ) - { - sl_send_reply(483, "Too Many Hops"); - exit; - }; - - - if (is_myself("$rd")) { - { - # for testing purposes, simply okay all REGISTERs - if ($rm=="REGISTER") - { - save("location"); - log("REGISTER received -> dumping messages with MSILO\n"); - - # MSILO - dumping user's offline messages - if (m_dump()) - { - log("MSILO: offline messages dumped - if they were\n"); - }else{ - log("MSILO: no offline messages dumped\n"); - }; - exit; - }; - - # domestic SIP destinations are handled using our USRLOC DB - - if(!lookup("location")) - { - if (! t_newtran()) - { - sl_reply_error(); - exit; - }; - # we do not care about anything else but MESSAGEs - if (!$rm=="MESSAGE") - { - if (!t_reply(404, "Not found")) - { - sl_reply_error(); - }; - exit; - }; - log("MESSAGE received -> storing using MSILO\n"); - # MSILO - storing as offline message - if (m_store("$ru")) - { - log("MSILO: offline message stored\n"); - if (!t_reply(202, "Accepted")) - { - sl_reply_error(); - }; - }else{ - log("MSILO: offline message NOT stored\n"); - if (!t_reply(503, "Service Unavailable")) - { - sl_reply_error(); - }; - }; - exit; - }; - # if the downstream UA does not support MESSAGE requests - # go to failure_route[1] - t_on_failure("1"); - t_relay(); - exit; - }; - - # forward anything else - t_relay(); -} - -failure_route[1] { - # forwarding failed -- check if the request was a MESSAGE - if (!$rm=="MESSAGE") - { - exit; - }; - - log(1,"MSILO:the downstream UA doesn't support MESSAGEs\n"); - # we have changed the R-URI with the contact address, ignore it now - if (m_store("$ou")) - { - log("MSILO: offline message stored\n"); - t_reply(202, "Accepted"); - }else{ - log("MSILO: offline message NOT stored\n"); - t_reply(503, "Service Unavailable"); - }; -} - - - -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 125 66 4163 1410 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 45 38 191 277 - 3. Andrei Pelinescu-Onciul 18 10 115 382 - 4. Liviu Chircu (@liviuchircu) 17 14 73 89 - 5. Jan Janak (@janakj) 16 11 126 168 - 6. Razvan Crainea (@razvancrainea) 12 10 33 28 - 7. Jiri Kuthan (@jiriatipteldotorg) 9 6 180 33 - 8. Henning Westerholt (@henningw) 9 6 114 110 - 9. Vlad Patrascu (@rvlad-patrascu) 9 5 69 123 - 10. Vlad Paiu (@vladpaiu) 7 4 90 80 - - All remaining contributors: Juha Heinanen (@juha-h), Andrea - Giordana, Ancuta Onofrei, Elena-Ramona Modroiu, Maksym Sobolyev - (@sobomax), Aron Rosenberg, John Riordan, Alexandra Titoc, - Konstantin Bokarius, Ovidiu Sas (@ovidiusas), Julián Moreno - Patiño, Peter Lemenkov (@lemenkov), Sergio Gutierrez, UnixDev, - Zero King (@l2dy), Edson Gellert Schubert, Stanislaw Pitucha. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Ovidiu Sas (@ovidiusas) Apr 2022 - Apr 2022 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Sep 2002 - Oct 2021 - 6. Razvan Crainea (@razvancrainea) Jun 2011 - Jan 2021 - 7. Zero King (@l2dy) Mar 2020 - Mar 2020 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Vlad Paiu (@vladpaiu), Stanislaw - Pitucha, John Riordan, UnixDev, Sergio Gutierrez, Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei, - Aron Rosenberg, Elena-Ramona Modroiu, Juha Heinanen (@juha-h), - Andrea Giordana, Andrei Pelinescu-Onciul, Jan Janak (@janakj), - Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Vlad Paiu (@vladpaiu), Razvan Crainea - (@razvancrainea), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona - Modroiu, Juha Heinanen (@juha-h), Andrea Giordana, Jan Janak - (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/msilo/README.md b/modules/msilo/README.md new file mode 100644 index 00000000000..fae1fcbbad0 --- /dev/null +++ b/modules/msilo/README.md @@ -0,0 +1,633 @@ +--- +title: "MSILO Module" +description: "This modules provides offline message storage for the Open SIP Server." +--- + +## Admin Guide + + +### Overview + + +This modules provides offline message storage for the Open SIP Server. It +stores received messages for an offline user and sends them when the +user becomes online. + + +For each message, the modules stores "Request-URI" +("R-URI") only if it is a complete address of record +("username@hostname"), URI from "To" +header, URI from "From" header, incoming time, +expiration time, content type and body of the message. If +"R-URI" is not an address of record (it might be the +contact address for current SIP session) the URI +from "To" header will be used as R-URI. + + +When the expiration time passed, the message is discarded from +database. Expiration time is computed based on incoming time and +one of the module's parameters. + + +Every time when a user registers with OpenSIPS, the module is looking in +database for offline messages intended for that user. All of them will +be sent to contact address provided in REGISTER request. + + +It may happen the SIP user to be registered but his SIP User Agent +to have no support for MESSAGE request. In this case it should be used +the "failure_route" to store the undelivered requests. + + +Another functionality provided by the modules is to send messages at +a certain time -- the reminder functionality. Using config logic, a +received message can be stored and delivered at a time specified while +storing with the 'snd_time_avp'. + + +### Dependencies + + +#### OpenSIPS modules + + +The following modules must be loaded before this module: + + +- *database module* - mysql, dbtext or other +module that implements the "db" interface and +provides support for storing/receiving data to/from a +database system. +- *TM*--transaction module--is used to +send SIP requests. + + +#### External libraries or applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module: + + +- *none*. + + +### Exported Parameters + + +#### db_url (string) + + +Database URL. + + +*Default value is +"mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set the 'db_url' parameter" +... +modparam("msilo", "db_url", "mysql://user:passwd@host.com/dbname") +... +``` + + +#### db_table (string) + + +The name of table where to store the messages. + + +*Default value is "silo".* + + +```opensips title="Set the 'db_table' parameter" +... +modparam("msilo", "db_table", "silo") +... +``` + + +#### from_address (string) + + +The SIP address used to inform users that destination of their +message is not online and the message will be delivered next time +when that user goes online. If the parameter is not set, the module +will not send any notification. It can contain pseudo-variables. + + +*Default value is "NULL".* + + +```opensips title="Set the 'from_address' parameter" +... +modparam("msilo", "from_address", "sip:registrar@example.org") +modparam("msilo", "from_address", "sip:$rU@example.org") +... +``` + + +#### contact_hdr (string) + + +The value of the Contact header (including header name and ending +\r\n) to be added in notification messages. +It can contain pseudo-variables. + + +*Default value is "NULL".* + + +```opensips title="Set the 'contact_hdr' parameter" +... +modparam("msilo", "contact_hdr", "Contact: \r\n") +... +``` + + +#### offline_message (string) + + +The body of the notification message. +It can contain pseudo-variables. + + +*Default value is "NULL".* + + +```opensips title="Set the 'offline_message' parameter" +... +modparam("msilo", "offline_message", "*** User $rU is offline!") +modparam("msilo", "offline_message", "I am offline!") +... +``` + + +#### content_type_hdr (string) + + +The value of the Content-Type header (including header name and ending +\r\n) to be added in notification messages. It must reflect what the +'offline_message' contains. +It can contain pseudo-variables. + + +*Default value is "NULL".* + + +```opensips title="Set the 'content_type_hdr' parameter" +... +modparam("msilo", "content_type_hdr", "Content-Type: text/plain\r\n") +modparam("msilo", "content_type_hdr", "Content-Type: text/html\r\n") +... +``` + + +#### reminder (string) + + +The SIP address used to send reminder messages. If this value +is not set, the reminder feature is disabled. + + +*Default value is "NULL".* + + +```opensips title="Set the 'reminder' parameter" +... +modparam("msilo", "reminder", "sip:registrar@example.org") +... +``` + + +#### outbound_proxy (string) + + +The SIP address used as next hop when sending the message. Very +useful when using OpenSIPS with a domain name not in DNS, or when +using a separate OpenSIPS instance for msilo processing. If not set, +the message will be sent to the address in destination URI. + + +*Default value is "NULL".* + + +```opensips title="Set the 'outbound_proxy' parameter" +... +modparam("msilo", "outbound_proxy", "sip:opensips.org;transport=tcp") +... +``` + + +#### expire_time (int) + + +Expire time of stored messages - seconds. When this time passed, the message is +silently discarded from database. + + +*Default value is "259200 (72 hours = 3 days)".* + + +```opensips title="Set the 'expire_time' parameter" +... +modparam("msilo", "expire_time", 36000) +... +``` + + +#### check_time (int) + + +Timer interval to check if dumped messages are sent OK - seconds. The module keeps +each request send by itself for a new online user and if the reply is 2xx then the +message is deleted from database. + + +*Default value is "30".* + + +```opensips title="Set the 'check_time' parameter" +... +modparam("msilo", "check_time", 10) +... +``` + + +#### send_time (int) + + +Timer interval in seconds to check if there are reminder messages. +The module takes all reminder messages that must be sent at that moment +or before that moment. + + +If the value is 0, the reminder feature is disabled. + + +*Default value is "0".* + + +```opensips title="Set the 'send_time' parameter" +... +modparam("msilo", "send_time", 60) +... +``` + + +#### clean_period (int) + + +Number of "check_time" cycles when to check if +there are expired messages in database. + + +*Default value is "5".* + + +```opensips title="Set the 'clean_period' parameter" +... +modparam("msilo", "clean_period", 3) +... +``` + + +#### use_contact (int) + + +Turns on/off the usage of the Contact address to send notification +back to sender whose message is stored by MSILO. + + +*Default value is "1 (0 = off, 1 = on)".* + + +```opensips title="Set the 'use_contact' parameter" +... +modparam("msilo", "use_contact", 0) +... +``` + + +#### sc_mid (string) + + +The name of the column in silo table, storing message id. + + +Default value is "mid". + + +```opensips title="Set the 'sc_mid' parameter" +... +modparam("msilo", "sc_mid", "other_mid") +... +``` + + +#### sc_from (string) + + +The name of the column in silo table, storing the source address. + + +Default value is "src_addr". + + +```opensips title="Set the 'sc_from' parameter" +... +modparam("msilo", "sc_from", "source_address") +... +``` + + +#### sc_to (string) + + +The name of the column in silo table, storing the destination address. + + +Default value is "dst_addr". + + +```opensips title="Set the 'sc_to' parameter" +... +modparam("msilo", "sc_to", "destination_address") +... +``` + + +#### sc_uri_user (string) + + +The name of the column in silo table, storing the user name. + + +Default value is "username". + + +```opensips title="Set the 'sc_uri_user' parameter" +... +modparam("msilo", "sc_uri_user", "user") +... +``` + + +#### sc_uri_host (string) + + +The name of the column in silo table, storing the domain. + + +Default value is "domain". + + +```opensips title="Set the 'sc_uri_host' parameter" +... +modparam("msilo", "sc_uri_host", "domain") +... +``` + + +#### sc_body (string) + + +The name of the column storing the message body in silo table. + + +Default value is "body". + + +```opensips title="Set the 'sc_body' parameter" +... +modparam("msilo", "sc_body", "message_body") +... +``` + + +#### sc_ctype (string) + + +The name of the column in silo table, storing content type. + + +Default value is "ctype". + + +```opensips title="Set the 'sc_ctype' parameter" +... +modparam("msilo", "sc_ctype", "content_type") +... +``` + + +#### sc_exp_time (string) + + +The name of the column in silo table, storing the expire time of the message. + + +Default value is "exp_time". + + +```opensips title="Set the 'sc_exp_time' parameter" +... +modparam("msilo", "sc_exp_time", "expire_time") +... +``` + + +#### sc_inc_time (string) + + +The name of the column in silo table, storing the incoming time of the message. + + +Default value is "inc_time". + + +```opensips title="Set the 'sc_inc_time' parameter" +... +modparam("msilo", "sc_inc_time", "incoming_time") +... +``` + + +#### sc_snd_time (string) + + +The name of the column in silo table, storing the send time for the reminder. + + +Default value is "snd_time". + + +```opensips title="Set the 'sc_snd_time' parameter" +... +modparam("msilo", "sc_snd_time", "send_reminder_time") +... +``` + + +#### snd_time_avp (str) + + +The name of an AVP which may contain the time when to sent +the received message as reminder.The AVP is used ony by m_store(). + + +If the parameter is not set, the module does not look for this AVP. If +the value is set to a valid AVP name, then the module expects in the AVP +to be a time value in format YYYYMMDDHHMMSS (e.g., 20060101201500). + + +*Default value is "null".* + + +```opensips title="Set the 'snd_time_avp' parameter" +... +modparam("msilo", "snd_time_avp", "$avp(snd_time)") +... +``` + + +#### add_date (int) + + +Wheter to add as prefix the date when the message was stored. + + +*Default value is "1" (1==on/0==off).* + + +```opensips title="Set the 'add_date' parameter" +... +modparam("msilo", "add_date", 0) +... +``` + + +#### max_messages (int) + + +Maximum number of stored message for an AoR. Value 0 +equals to no limit. + + +*Default value is 0.* + + +```opensips title="Set the 'max_messages' parameter" +... +modparam("msilo", "max_messages", 0) +... +``` + + +### Exported Functions + + +#### m_store([owner]) + + +The method stores certain parts of the current SIP request (it +should be called when the request type is MESSAGE and the destination +user is offline or his UA does not support MESSAGE requests). If the +user is registered with a UA which does not support MESSAGE requests +you should not use mode="0" if you have +changed the request uri with the contact address of user's UA. + + +Meaning of the parameters is as follows: + + +- *owner* (string, optional) - a SIP URI in whose +inbox the message will be stored. If "owner" is missing, +the SIP address is taken from R-URI. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="m_store usage" +... +m_store(); +m_store($tu); +... +``` + + +#### m_dump([owner], [maxmsg]) + + +The method sends stored messages for the SIP user that is going to +register to his actual contact address. The method should be called +when a REGISTER request is received and the "Expire" +header has a value greater than zero. + + +Meaning of the parameters is as follows: + + +- *owner* (string, optional) - +a SIP URI whose inbox will be dumped. If "owner" is missing, +the SIP address is taken from To URI. +- *maxmsg* (int, optional) - is a maximum number of messages +to be dumped. + + +This function can be used from REQUEST_ROUTE, STARTUP_ROUTE, +TIMER_ROUTE, EVENT_ROUTE + + +```opensips title="m_dump usage" +... +m_dump(); +m_dump($fu); +m_dump($fu, 10); +... +``` + + +### Exported Statistics + + +#### stored_messages + + +The number of messages stored by msilo. + + +#### dumped_messages + + +The number of dumped messages. + + +#### failed_messages + + +The number of failed dumped messages. + + +#### dumped_reminders + + +The number of dumped reminder messages. + + +#### failed_reminders + + +The number of failed reminder messages. + + +## Samples + +[samples](./samples/samples.md "include") + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/msilo/doc/contributors.xml b/modules/msilo/doc/contributors.xml deleted file mode 100644 index 58cab1793f3..00000000000 --- a/modules/msilo/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 125 - 66 - 4163 - 1410 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 45 - 38 - 191 - 277 - - - 3. - Andrei Pelinescu-Onciul - 18 - 10 - 115 - 382 - - - 4. - Liviu Chircu (@liviuchircu) - 17 - 14 - 73 - 89 - - - 5. - Jan Janak (@janakj) - 16 - 11 - 126 - 168 - - - 6. - Razvan Crainea (@razvancrainea) - 12 - 10 - 33 - 28 - - - 7. - Jiri Kuthan (@jiriatipteldotorg) - 9 - 6 - 180 - 33 - - - 8. - Henning Westerholt (@henningw) - 9 - 6 - 114 - 110 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 9 - 5 - 69 - 123 - - - 10. - Vlad Paiu (@vladpaiu) - 7 - 4 - 90 - 80 - - - -
-All remaining contributors: Juha Heinanen (@juha-h), Andrea Giordana, Ancuta Onofrei, Elena-Ramona Modroiu, Maksym Sobolyev (@sobomax), Aron Rosenberg, John Riordan, Alexandra Titoc, Konstantin Bokarius, Ovidiu Sas (@ovidiusas), Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Sergio Gutierrez, UnixDev, Zero King (@l2dy), Edson Gellert Schubert, Stanislaw Pitucha. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Ovidiu Sas (@ovidiusas) - Apr 2022 - Apr 2022 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Sep 2002 - Oct 2021 - - - 6. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jan 2021 - - - 7. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Stanislaw Pitucha, John Riordan, UnixDev, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei, Aron Rosenberg, Elena-Ramona Modroiu, Juha Heinanen (@juha-h), Andrea Giordana, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Vlad Paiu (@vladpaiu), Razvan Crainea (@razvancrainea), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Juha Heinanen (@juha-h), Andrea Giordana, Jan Janak (@janakj). -
- -
diff --git a/modules/msilo/doc/msilo.xml b/modules/msilo/doc/msilo.xml deleted file mode 100644 index 7fae38b8734..00000000000 --- a/modules/msilo/doc/msilo.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - MSILO Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/msilo/doc/msilo_admin.xml b/modules/msilo/doc/msilo_admin.xml deleted file mode 100644 index 9419e7117af..00000000000 --- a/modules/msilo/doc/msilo_admin.xml +++ /dev/null @@ -1,709 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This modules provides offline message storage for the &osipsname;. It - stores received messages for an offline user and sends them when the - user becomes online. - - - For each message, the modules stores Request-URI - (R-URI) only if it is a complete address of record - (username@hostname), &uri; from To - header, &uri; from From header, incoming time, - expiration time, content type and body of the message. If - R-URI is not an address of record (it might be the - contact address for current &sip; session) the &uri; - from To header will be used as R-URI. - - - When the expiration time passed, the message is discarded from - database. Expiration time is computed based on incoming time and - one of the module's parameters. - - - Every time when a user registers with &osips;, the module is looking in - database for offline messages intended for that user. All of them will - be sent to contact address provided in REGISTER request. - - - It may happen the &sip; user to be registered but his &sip; User Agent - to have no support for MESSAGE request. In this case it should be used - the failure_route to store the undelivered requests. - - - Another functionality provided by the modules is to send messages at - a certain time -- the reminder functionality. Using config logic, a - received message can be stored and delivered at a time specified while - storing with the 'snd_time_avp'. - -
-
- Dependencies -
- &osips; modules - - The following modules must be loaded before this module: - - - - database module - mysql, dbtext or other - module that implements the db interface and - provides support for storing/receiving data to/from a - database system. - - - - - TM--transaction module--is used to - send &sip; requests. - - - - -
-
- External libraries or applications - - The following libraries or applications must be installed before - running &osips; with this module: - - - - none. - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (string) - - Database &url;. - - - - Default value is - &defaultdb;. - - - - Set the <quote>db_url</quote> parameter - -... -modparam("msilo", "db_url", "mysql://user:passwd@host.com/dbname") -... - - -
-
- <varname>db_table</varname> (string) - - The name of table where to store the messages. - - - - Default value is silo. - - - - Set the <quote>db_table</quote> parameter - -... -modparam("msilo", "db_table", "silo") -... - - -
-
- <varname>from_address</varname> (string) - - The &sip; address used to inform users that destination of their - message is not online and the message will be delivered next time - when that user goes online. If the parameter is not set, the module - will not send any notification. It can contain pseudo-variables. - - - - Default value is NULL. - - - - Set the <quote>from_address</quote> parameter - -... -modparam("msilo", "from_address", "sip:registrar@example.org") -modparam("msilo", "from_address", "sip:$rU@example.org") -... - - -
-
- <varname>contact_hdr</varname> (string) - - The value of the Contact header (including header name and ending - \r\n) to be added in notification messages. - It can contain pseudo-variables. - - - - Default value is NULL. - - - - Set the <quote>contact_hdr</quote> parameter - -... -modparam("msilo", "contact_hdr", "Contact: <sip:null@example.com>\r\n") -... - - -
-
- <varname>offline_message</varname> (string) - - The body of the notification message. - It can contain pseudo-variables. - - - - Default value is NULL. - - - - Set the <quote>offline_message</quote> parameter - -... -modparam("msilo", "offline_message", "*** User $rU is offline!") -modparam("msilo", "offline_message", "<em>I am offline!</em>") -... - - -
-
- <varname>content_type_hdr</varname> (string) - - The value of the Content-Type header (including header name and ending - \r\n) to be added in notification messages. It must reflect what the - 'offline_message' contains. - It can contain pseudo-variables. - - - - Default value is NULL. - - - - Set the <quote>content_type_hdr</quote> parameter - -... -modparam("msilo", "content_type_hdr", "Content-Type: text/plain\r\n") -modparam("msilo", "content_type_hdr", "Content-Type: text/html\r\n") -... - - -
-
- <varname>reminder</varname> (string) - - The &sip; address used to send reminder messages. If this value - is not set, the reminder feature is disabled. - - - - Default value is NULL. - - - - Set the <quote>reminder</quote> parameter - -... -modparam("msilo", "reminder", "sip:registrar@example.org") -... - - -
-
- <varname>outbound_proxy</varname> (string) - - The &sip; address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or when - using a separate OpenSIPS instance for msilo processing. If not set, - the message will be sent to the address in destination URI. - - - - Default value is NULL. - - - - Set the <quote>outbound_proxy</quote> parameter - -... -modparam("msilo", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - - -
-
- <varname>expire_time</varname> (int) - - Expire time of stored messages - seconds. When this time passed, the message is - silently discarded from database. - - - - Default value is 259200 (72 hours = 3 days). - - - - Set the <quote>expire_time</quote> parameter - -... -modparam("msilo", "expire_time", 36000) -... - - -
-
- <varname>check_time</varname> (int) - - Timer interval to check if dumped messages are sent OK - seconds. The module keeps - each request send by itself for a new online user and if the reply is 2xx then the - message is deleted from database. - - - - Default value is 30. - - - - Set the <quote>check_time</quote> parameter - -... -modparam("msilo", "check_time", 10) -... - - -
-
- <varname>send_time</varname> (int) - - Timer interval in seconds to check if there are reminder messages. - The module takes all reminder messages that must be sent at that moment - or before that moment. - - - If the value is 0, the reminder feature is disabled. - - - - Default value is 0. - - - - Set the <quote>send_time</quote> parameter - -... -modparam("msilo", "send_time", 60) -... - - -
-
- <varname>clean_period</varname> (int) - - Number of check_time cycles when to check if - there are expired messages in database. - - - - Default value is 5. - - - - Set the <quote>clean_period</quote> parameter - -... -modparam("msilo", "clean_period", 3) -... - - -
-
- <varname>use_contact</varname> (int) - - Turns on/off the usage of the Contact address to send notification - back to sender whose message is stored by MSILO. - - - - Default value is 1 (0 = off, 1 = on). - - - - Set the <quote>use_contact</quote> parameter - -... -modparam("msilo", "use_contact", 0) -... - - -
- -
- <varname>sc_mid</varname> (string) - - The name of the column in silo table, storing message id. - - Default value is mid. - - Set the <quote>sc_mid</quote> parameter - -... -modparam("msilo", "sc_mid", "other_mid") -... - - -
- -
- <varname>sc_from</varname> (string) - - The name of the column in silo table, storing the source address. - - Default value is src_addr. - - Set the <quote>sc_from</quote> parameter - -... -modparam("msilo", "sc_from", "source_address") -... - - -
-
- <varname>sc_to</varname> (string) - - The name of the column in silo table, storing the destination address. - - Default value is dst_addr. - - Set the <quote>sc_to</quote> parameter - -... -modparam("msilo", "sc_to", "destination_address") -... - - -
-
- <varname>sc_uri_user</varname> (string) - - The name of the column in silo table, storing the user name. - - Default value is username. - - Set the <quote>sc_uri_user</quote> parameter - -... -modparam("msilo", "sc_uri_user", "user") -... - - -
-
- <varname>sc_uri_host</varname> (string) - - The name of the column in silo table, storing the domain. - - Default value is domain. - - Set the <quote>sc_uri_host</quote> parameter - -... -modparam("msilo", "sc_uri_host", "domain") -... - - -
-
- <varname>sc_body</varname> (string) - - The name of the column storing the message body in silo table. - - Default value is body. - - Set the <quote>sc_body</quote> parameter - -... -modparam("msilo", "sc_body", "message_body") -... - - -
-
- <varname>sc_ctype</varname> (string) - - The name of the column in silo table, storing content type. - - Default value is ctype. - - Set the <quote>sc_ctype</quote> parameter - -... -modparam("msilo", "sc_ctype", "content_type") -... - - -
-
- <varname>sc_exp_time</varname> (string) - - The name of the column in silo table, storing the expire time of the message. - - Default value is exp_time. - - Set the <quote>sc_exp_time</quote> parameter - -... -modparam("msilo", "sc_exp_time", "expire_time") -... - - -
-
- <varname>sc_inc_time</varname> (string) - - The name of the column in silo table, storing the incoming time of the message. - - Default value is inc_time. - - Set the <quote>sc_inc_time</quote> parameter - -... -modparam("msilo", "sc_inc_time", "incoming_time") -... - - -
-
- <varname>sc_snd_time</varname> (string) - - The name of the column in silo table, storing the send time for the reminder. - - Default value is snd_time. - - Set the <quote>sc_snd_time</quote> parameter - -... -modparam("msilo", "sc_snd_time", "send_reminder_time") -... - - -
- -
- <varname>snd_time_avp</varname> (str) - - The name of an AVP which may contain the time when to sent - the received message as reminder.The AVP is used ony by m_store(). - - - If the parameter is not set, the module does not look for this AVP. If - the value is set to a valid AVP name, then the module expects in the AVP - to be a time value in format YYYYMMDDHHMMSS (e.g., 20060101201500). - - - - Default value is null. - - - - Set the <quote>snd_time_avp</quote> parameter - -... -modparam("msilo", "snd_time_avp", "$avp(snd_time)") -... - - -
-
- <varname>add_date</varname> (int) - - Wheter to add as prefix the date when the message was stored. - - - - Default value is 1 (1==on/0==off). - - - - Set the <quote>add_date</quote> parameter - -... -modparam("msilo", "add_date", 0) -... - - -
-
- <varname>max_messages</varname> (int) - - Maximum number of stored message for an AoR. Value 0 - equals to no limit. - - - - Default value is 0. - - - - Set the <quote>max_messages</quote> parameter - -... -modparam("msilo", "max_messages", 0) -... - - -
-
- -
- Exported Functions -
- <function moreinfo="none">m_store([owner])</function> - - The method stores certain parts of the current &sip; request (it - should be called when the request type is MESSAGE and the destination - user is offline or his UA does not support MESSAGE requests). If the - user is registered with a UA which does not support MESSAGE requests - you should not use mode=0 if you have - changed the request uri with the contact address of user's &ua;. - - Meaning of the parameters is as follows: - - - - owner (string, optional) - a SIP URI in whose - inbox the message will be stored. If "owner" is missing, - the SIP address is taken from R-URI. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>m_store</function> usage - -... -m_store(); -m_store($tu); -... - - -
-
- <function moreinfo="none">m_dump([owner], [maxmsg])</function> - - The method sends stored messages for the &sip; user that is going to - register to his actual contact address. The method should be called - when a REGISTER request is received and the Expire - header has a value greater than zero. - - Meaning of the parameters is as follows: - - - - owner (string, optional) - - a SIP URI whose inbox will be dumped. If "owner" is missing, - the SIP address is taken from To URI. - - - - - maxmsg (int, optional) - is a maximum number of messages - to be dumped. - - - - - This function can be used from REQUEST_ROUTE, STARTUP_ROUTE, - TIMER_ROUTE, EVENT_ROUTE - - - <function>m_dump</function> usage - -... -m_dump(); -m_dump($fu); -m_dump($fu, 10); -... - - -
-
- -
- Exported Statistics -
- stored_messages - - The number of messages stored by msilo. - -
-
- dumped_messages - - The number of dumped messages. - -
-
- failed_messages - - The number of failed dumped messages. - -
-
- dumped_reminders - - The number of dumped reminder messages. - -
-
- failed_reminders - - The number of failed reminder messages. - -
-
- - -
- Installation and Running -
- &osips; config file - - Next picture displays a sample usage of msilo. - - - &osips; config script - sample msilo usage - -... -&msilocfg; -... - - -
-
-
- diff --git a/modules/msilo/msilo.c b/modules/msilo/msilo.c index 5b2e1cd0cbe..08f53bb9dfa 100644 --- a/modules/msilo/msilo.c +++ b/modules/msilo/msilo.c @@ -774,9 +774,11 @@ static int m_dump(struct sip_msg* msg, str* owner, int* maxmsg) int i, db_no_cols = 6, db_no_keys = 3, mid, n; unsigned int sent_cnt = 0; unsigned int maxmsg_i = 0; + unsigned int mime; static char hdr_buf[1024]; static char body_buf[1024]; struct sip_uri puri; + char *p; str str_vals[4], hdr_str , body_str; time_t rtime; @@ -935,12 +937,26 @@ static int m_dump(struct sip_msg* msg, str* owner, int* maxmsg) goto error; } - LM_DBG("msg [%d-%d] for: %.*s@%.*s\n", i+1, mid, puri.user.len, puri.user.s, puri.host.len, puri.host.s); + LM_DBG("msg [%d-%d] for: %.*s@%.*s\n", i+1, mid, + puri.user.len, puri.user.s, puri.host.len, puri.host.s); + + /* build special body (with extra info) only if text/plain */ + p = decode_mime_type( str_vals[3].s , str_vals[3].s+str_vals[3].len, + &mime, NULL); + if (p==NULL || p!=str_vals[3].s+str_vals[3].len) { + LM_ERR("failed to parse content type [%.*s], assuming unknown\n", + str_vals[3].len, str_vals[3].s); + n = -1; + } else + if ((mime&0x00ff)==SUBTYPE_PLAIN && (mime>>16)==TYPE_TEXT) { + body_str.len = 1024; + n = m_build_body(&body_str, rtime, str_vals[2/*body*/], + rtime /*Date*/, 0 /*not a reminder*/); + } else { + n = -1; + } /** sending using TM function: t_uac */ - body_str.len = 1024; - n = m_build_body(&body_str, rtime, str_vals[2/*body*/], - rtime /*Date*/, 0 /*not a reminder*/); if(n<0) LM_DBG("sending simple body\n"); else @@ -1108,7 +1124,8 @@ void m_send_ontimer(unsigned int ticks, void *param) static char hdr_buf[1024]; static char uri_buf[1024]; static char body_buf[1024]; - char cbuf[26]; + unsigned int mime; + char cbuf[26], *p; str puri; time_t ttime; @@ -1202,12 +1219,25 @@ void m_send_ontimer(unsigned int ticks, void *param) LM_DBG("msg [%d-%d] for: %.*s\n", i+1, mid, puri.len, puri.s); + /* build special body (with extra info) only if text/plain */ + p = decode_mime_type( str_vals[3].s , str_vals[3].s+str_vals[3].len, + &mime, NULL); + if (p==NULL || p!=str_vals[3].s+str_vals[3].len) { + LM_ERR("failed to parse content type [%.*s], assuming unknown\n", + str_vals[3].len, str_vals[3].s); + n = -1; + } else + if ((mime&0x00ff)==SUBTYPE_PLAIN && (mime>>16)==TYPE_TEXT) { + body_str.len = 1024; + stime = + (time_t)RES_ROWS(db_res)[i].values[5/*snd time*/].val.int_val; + n = m_build_body(&body_str, 0, str_vals[2/*body*/], stime, + 1 /*is a reminder*/); + } else { + n = -1; + } + /** sending using TM function: t_uac */ - body_str.len = 1024; - stime = - (time_t)RES_ROWS(db_res)[i].values[5/*snd time*/].val.int_val; - n = m_build_body(&body_str, 0, str_vals[2/*body*/], stime, - 1 /*is a reminder*/); if(n<0) LM_DBG("sending simple body\n"); else diff --git a/modules/msilo/doc/msilo.cfg b/modules/msilo/samples/msilo.cfg similarity index 100% rename from modules/msilo/doc/msilo.cfg rename to modules/msilo/samples/msilo.cfg diff --git a/modules/msilo/samples/samples.md b/modules/msilo/samples/samples.md new file mode 100644 index 00000000000..b35f7d13876 --- /dev/null +++ b/modules/msilo/samples/samples.md @@ -0,0 +1,4 @@ +### OpenSIPS Config Script - Msilo Usage + +[msilo.cfg](./msilo.cfg "include") + diff --git a/modules/msrp_gateway/README b/modules/msrp_gateway/README deleted file mode 100644 index 0be8e3a6b23..00000000000 --- a/modules/msrp_gateway/README +++ /dev/null @@ -1,304 +0,0 @@ -MSRP Gateway Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. hash_size (int) - 1.3.2. cleanup_interval (int) - 1.3.3. session_timeout (int) - 1.3.4. message_timeout (int) - - 1.4. Exported Functions - - 1.4.1. msrp_gw_answer(key, content_types, from, to, - ruri) - - 1.4.2. msg_to_msrp(key, content_types) - - 1.5. Exported MI Functions - - 1.5.1. msrp_gw_list_sessions - 1.5.2. msrp_gw_end_session - - 1.6. Exported Events - - 1.6.1. E_MSRP_GW_SETUP_FAILED - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hash_size parameter - 1.2. Set cleanup_interval parameter - 1.3. Set session_timeout parameter - 1.4. Set message_timeout parameter - 1.5. msrp_gw_answer() usage - 1.6. msg_to_msrp() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements a Gateway for translating between Page - Mode (SIP MESSAGE method) and Session Mode (MSRP) Instant - Messaging. - - The module makes use of the msrp_ua module's API for the MSRP - UAC/UAS functionalities. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tm - * msrp_ua - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. hash_size (int) - - The size of the hash table that stores the gateway session - information. It is the 2 logarithmic value of the real size. - - Default value is “10” (1024 records). - - Example 1.1. Set hash_size parameter -... -modparam("msrp_gateway", "hash_size", 16) -... - -1.3.2. cleanup_interval (int) - - The interval between full iterations of the sessions table in - order to clean up lingering sessions. - - Default value is “60”. (seconds) - - Example 1.2. Set cleanup_interval parameter -... -modparam("msrp_gateway", "cleanup_interval", 60) -... - -1.3.3. session_timeout (int) - - Amount of time (in seconds) since last message has been - received from either side, after which a session should be - terminated. - - The default value is 12 * 3600 seconds (12 hours). - - Example 1.3. Set session_timeout parameter -... -modparam("msrp_gateway", "session_timeout", 7200) -... - -1.3.4. message_timeout (int) - - Amount of time (in seconds) since last MESSAGE has been - received after which a session should be terminated. - - The default value is 2 * 3600 seconds (2 hours). - - Example 1.4. Set message_timeout parameter -... -modparam("msrp_gateway", "message_timeout", 3600) -... - -1.4. Exported Functions - -1.4.1. msrp_gw_answer(key, content_types, from, to, ruri) - - This functions initializes a new gateway session by answering - an initial INVITE from the MSRP side SIP session. After running - this function the call will be completely handled by the MSRP - UA engine and MSRP SEND requests will be automatically - translated to SIP MESSAGE requests. - - The SIP From, To, and RURI coordinates for building MESSAGE - requests are passed as parameters to the function. - - Parameters: - * key (string) - gateway session key to be used to correlate - the MESSAGE requests with the MSRP side SIP session. A - simple example would be to build this key based on the From - and To URIs from both sides(from the initial MSRP leg - INVITE and SIP MESSAGE requests respectively). - * content_types (string) - content types adevertised in the - SDP offer on the MSRP side SIP session. - * from (string) - From URI to be used for building SIP - MESSAGE requests. - * to (string) - To URI to be used for building SIP MESSAGE - requests. - * ruri (string) - Request-URI to be used for building SIP - MESSAGE requests. - - This function can be used only from a request route. - - Example 1.5. msrp_gw_answer() usage -... -if (!has_totag() && is_method("INVITE")) { - msrp_gw_answer($var(corr_key), "text/plain", $fu, $tu, $ru); - exit; -} -... - -1.4.2. msg_to_msrp(key, content_types) - - This functions translates a SIP MESSAGE request into a MSRP - SEND request. The function will initialize a new gateway - session and establish the MSRP side SIP session if it is not - done so already by a previous call. - - The SIP From, To, and RURI coordinates for the new MSRP side - session are taken from the MESSAGE request and mirrored back - when translating a MSRP SEND to SIP MESSAGE with - msrp_gw_answer. - - Parameters: - * key (string) - gateway session key to be used to correlate - the MESSAGE requests with the MSRP side SIP session. A - simple example would be to build this key based on the From - and To URIs from both sides(from the initial MSRP leg - INVITE and SIP MESSAGE requests respectively). - * content_types (string) - content types adevertised in the - SDP offer on the MSRP side SIP session. - - This function can be used only from a request route. - - Example 1.6. msg_to_msrp() usage -... -if (is_method("MESSAGE")) { - msg_to_msrp($var(corr_key), "text/plain"); - exit; -} -... - -1.5. Exported MI Functions - -1.5.1. msrp_gw_list_sessions - - Lists information about ongoing sessions. - - Name: msrp_gw_list_sessions - - Parameters - * None. - - MI FIFO Command Format: -opensips-cli -x mi msrp_gw_list_sessions - -1.5.2. msrp_gw_end_session - - Terminate an ongoing session. - - Name: msrp_gw_end_session - - Parameters - * key (string) - session key - - MI FIFO Command Format: -opensips-cli -x mi msrp_gw_end_session alice@opensips.org-bob@opensips.o -rg - -1.6. Exported Events - -1.6.1. E_MSRP_GW_SETUP_FAILED - - This event is triggered when the MSRP side SIP session fails to - set up, when using the msg_to_msrp() function. - - The event can be used to generate a message with the failure - description, back on the MESSAGE side. - - Parameters: - * key - The session key. - * from_uri - The URI in the SIP From header to use on the - MESSAGE side. - * to_uri - The URI in the SIP To header to use on the MESSAGE - side. - * ruri - The SIP Request URI to use on the MESSAGE side. - * code - The SIP error code in the negative reply received on - the MSRP side. Might be NULL if the MSRP UA session expired - before receiving a negative reply. - * reason - The SIP reason string in the negative reply - received on the MSRP side. Might be NULL if the MSRP UA - session expired before receiving a negative reply. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 21 9 1219 19 - 2. Maksym Sobolyev (@sobomax) 3 1 4 4 - 3. Alexandra Titoc 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Vlad Patrascu (@rvlad-patrascu) May 2022 - Jan 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2022 www.opensips-solutions.com diff --git a/modules/msrp_gateway/README.md b/modules/msrp_gateway/README.md new file mode 100644 index 00000000000..3032cbb4b23 --- /dev/null +++ b/modules/msrp_gateway/README.md @@ -0,0 +1,289 @@ +--- +title: "MSRP Gateway Module" +description: "This module implements a Gateway for translating between Page Mode (SIP MESSAGE method) and Session Mode (MSRP) Instant Messaging." +--- + +## Admin Guide + + +### Overview + + +This module implements a Gateway for translating between Page Mode +(SIP MESSAGE method) and Session Mode (MSRP) Instant Messaging. + + +The module makes use of the *msrp_ua* module's API for +the MSRP UAC/UAS functionalities. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tm* +- *msrp_ua* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### hash_size (int) + + +The size of the hash table that stores the gateway session +information. It is the 2 logarithmic value of the real size. + + +*Default value is "10"* +(1024 records). + + +```opensips title="Set hash_size parameter" +... +modparam("msrp_gateway", "hash_size", 16) +... + +``` + + +#### cleanup_interval (int) + + +The interval between full iterations of the sessions table +in order to clean up lingering sessions. + + +*Default value is "60". (seconds)* + + +```opensips title="Set cleanup_interval parameter" +... +modparam("msrp_gateway", "cleanup_interval", 60) +... + +``` + + +#### session_timeout (int) + + +Amount of time (in seconds) since last message has been received +from either side, after which a session should be terminated. + + +*The default value is 12 * 3600 seconds (12 hours).* + + +```opensips title="Set session_timeout parameter" +... +modparam("msrp_gateway", "session_timeout", 7200) +... + +``` + + +#### message_timeout (int) + + +Amount of time (in seconds) since last MESSAGE has been received +after which a session should be terminated. + + +*The default value is 2 * 3600 seconds (2 hours).* + + +```opensips title="Set message_timeout parameter" +... +modparam("msrp_gateway", "message_timeout", 3600) +... + +``` + + +### Exported Functions + + +#### msrp_gw_answer(key, content_types, from, to, ruri) + + +This functions initializes a new gateway session by answering an initial +INVITE from the MSRP side SIP session. After running this function the +call will be completely handled by the MSRP UA engine and MSRP SEND +requests will be automatically translated to SIP MESSAGE requests. + + +The SIP From, To, and RURI coordinates for building MESSAGE requests +are passed as parameters to the function. + + +Parameters: + + +- *key* (string) - gateway session key to be used +to correlate the MESSAGE requests with the MSRP side SIP session. +A simple example would be to build this key based on the From and To +URIs from both sides(from the initial MSRP leg INVITE and SIP MESSAGE +requests respectively). +- *content_types* (string) - content types +adevertised in the SDP offer on the MSRP side SIP session. +- *from* (string) - From URI to be used for building +SIP MESSAGE requests. +- *to* (string) - To URI to be used for building +SIP MESSAGE requests. +- *ruri* (string) - Request-URI to be used for building +SIP MESSAGE requests. + + +This function can be used only from a request route. + + +```opensips title="msrp_gw_answer() usage" +... +if (!has_totag() && is_method("INVITE")) { + msrp_gw_answer($var(corr_key), "text/plain", $fu, $tu, $ru); + exit; +} +... +``` + + +#### msg_to_msrp(key, content_types) + + +This functions translates a SIP MESSAGE request into a MSRP SEND request. +The function will initialize a new gateway session and establish the MSRP +side SIP session if it is not done so already by a previous call. + + +The SIP From, To, and RURI coordinates for the new MSRP side session are +taken from the MESSAGE request and mirrored back when translating a MSRP +SEND to SIP MESSAGE with *msrp_gw_answer*. + + +Parameters: + + +- *key* (string) - gateway session key to be used +to correlate the MESSAGE requests with the MSRP side SIP session. +A simple example would be to build this key based on the From and To +URIs from both sides(from the initial MSRP leg INVITE and SIP MESSAGE +requests respectively). +- *content_types* (string) - content types +adevertised in the SDP offer on the MSRP side SIP session. + + +This function can be used only from a request route. + + +```opensips title="msg_to_msrp() usage" +... +if (is_method("MESSAGE")) { + msg_to_msrp($var(corr_key), "text/plain"); + exit; +} +... +``` + + +### Exported MI Functions + + +#### msrp_gw_list_sessions + + +Lists information about ongoing sessions. + + +Name: *msrp_gw_list_sessions* + + +Parameters + + +- *None*. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_gw_list_sessions + +``` + + +#### msrp_gw_end_session + + +Terminate an ongoing session. + + +Name: *msrp_gw_end_session* + + +Parameters + + +- *key* (string) - session key + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_gw_end_session alice@opensips.org-bob@opensips.org + +``` + + +### Exported Events + + +#### E_MSRP_GW_SETUP_FAILED + + +This event is triggered when the MSRP side SIP session fails to set up, +when using the *msg_to_msrp()* function. + + +The event can be used to generate a message with the failure description, +back on the MESSAGE side. + + +Parameters: + + +- *key* - The session key. +- *from_uri* - The URI in the SIP From header +to use on the MESSAGE side. +- *to_uri* - The URI in the SIP To header +to use on the MESSAGE side. +- *ruri* - The SIP Request URI to use on the +MESSAGE side. +- *code* - The SIP error code in the negative reply +received on the MSRP side. Might be NULL if the MSRP UA session expired +before receiving a negative reply. +- *reason* - The SIP reason string in the negative reply +received on the MSRP side. Might be NULL if the MSRP UA session expired +before receiving a negative reply. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/msrp_gateway/doc/contributors.xml b/modules/msrp_gateway/doc/contributors.xml deleted file mode 100644 index 618744b204f..00000000000 --- a/modules/msrp_gateway/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 21 - 9 - 1219 - 19 - - - 2. - Maksym Sobolyev (@sobomax) - 3 - 1 - 4 - 4 - - - 3. - Alexandra Titoc - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - May 2022 - Jan 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/msrp_gateway/doc/msrp_gateway.xml b/modules/msrp_gateway/doc/msrp_gateway.xml deleted file mode 100644 index 2d4e946fa37..00000000000 --- a/modules/msrp_gateway/doc/msrp_gateway.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - MSRP Gateway Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssol; - diff --git a/modules/msrp_gateway/doc/msrp_gateway_admin.xml b/modules/msrp_gateway/doc/msrp_gateway_admin.xml deleted file mode 100644 index 8ef1cc0e0b8..00000000000 --- a/modules/msrp_gateway/doc/msrp_gateway_admin.xml +++ /dev/null @@ -1,342 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements a Gateway for translating between Page Mode - (SIP MESSAGE method) and Session Mode (MSRP) Instant Messaging. - - - The module makes use of the msrp_ua module's API for - the MSRP UAC/UAS functionalities. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - tm - - - msrp_ua - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None. - - - -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (int) - - The size of the hash table that stores the gateway session - information. It is the 2 logarithmic value of the real size. - - - Default value is 10 - - (1024 records). - - - Set <varname>hash_size</varname> parameter - -... -modparam("msrp_gateway", "hash_size", 16) -... - - -
- -
- <varname>cleanup_interval</varname> (int) - - The interval between full iterations of the sessions table - in order to clean up lingering sessions. - - - Default value is 60. (seconds) - - - Set <varname>cleanup_interval</varname> parameter - -... -modparam("msrp_gateway", "cleanup_interval", 60) -... - - -
- -
- <varname>session_timeout</varname> (int) - - Amount of time (in seconds) since last message has been received - from either side, after which a session should be terminated. - - - The default value is 12 * 3600 seconds (12 hours). - - - Set <varname>session_timeout</varname> parameter - -... -modparam("msrp_gateway", "session_timeout", 7200) -... - - -
- -
- <varname>message_timeout</varname> (int) - - Amount of time (in seconds) since last MESSAGE has been received - after which a session should be terminated. - - - The default value is 2 * 3600 seconds (2 hours). - - - Set <varname>message_timeout</varname> parameter - -... -modparam("msrp_gateway", "message_timeout", 3600) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">msrp_gw_answer(key, content_types, from, to, ruri)</function> - - - This functions initializes a new gateway session by answering an initial - INVITE from the MSRP side SIP session. After running this function the - call will be completely handled by the MSRP UA engine and MSRP SEND - requests will be automatically translated to SIP MESSAGE requests. - - - The SIP From, To, and RURI coordinates for building MESSAGE requests - are passed as parameters to the function. - - - Parameters: - - - key (string) - gateway session key to be used - to correlate the MESSAGE requests with the MSRP side SIP session. - A simple example would be to build this key based on the From and To - URIs from both sides(from the initial MSRP leg INVITE and SIP MESSAGE - requests respectively). - - - content_types (string) - content types - adevertised in the SDP offer on the MSRP side SIP session. - - - from (string) - From URI to be used for building - SIP MESSAGE requests. - - - to (string) - To URI to be used for building - SIP MESSAGE requests. - - - ruri (string) - Request-URI to be used for building - SIP MESSAGE requests. - - - - - This function can be used only from a request route. - - - <function>msrp_gw_answer()</function> usage - -... -if (!has_totag() && is_method("INVITE")) { - msrp_gw_answer($var(corr_key), "text/plain", $fu, $tu, $ru); - exit; -} -... - - -
-
- - <function moreinfo="none">msg_to_msrp(key, content_types)</function> - - - This functions translates a SIP MESSAGE request into a MSRP SEND request. - The function will initialize a new gateway session and establish the MSRP - side SIP session if it is not done so already by a previous call. - - - The SIP From, To, and RURI coordinates for the new MSRP side session are - taken from the MESSAGE request and mirrored back when translating a MSRP - SEND to SIP MESSAGE with msrp_gw_answer. - - - Parameters: - - - key (string) - gateway session key to be used - to correlate the MESSAGE requests with the MSRP side SIP session. - A simple example would be to build this key based on the From and To - URIs from both sides(from the initial MSRP leg INVITE and SIP MESSAGE - requests respectively). - - - content_types (string) - content types - adevertised in the SDP offer on the MSRP side SIP session. - - - - - This function can be used only from a request route. - - - <function>msg_to_msrp()</function> usage - -... -if (is_method("MESSAGE")) { - msg_to_msrp($var(corr_key), "text/plain"); - exit; -} -... - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">msrp_gw_list_sessions</function> - - - Lists information about ongoing sessions. - - - Name: msrp_gw_list_sessions - - Parameters - - - None. - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_gw_list_sessions - -
- -
- - <function moreinfo="none">msrp_gw_end_session</function> - - - Terminate an ongoing session. - - - Name: msrp_gw_end_session - - Parameters - - - key (string) - session key - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_gw_end_session alice@opensips.org-bob@opensips.org - -
- -
- -
- Exported Events - -
- - <function moreinfo="none">E_MSRP_GW_SETUP_FAILED</function> - - - This event is triggered when the MSRP side SIP session fails to set up, - when using the msg_to_msrp() function. - - - The event can be used to generate a message with the failure description, - back on the MESSAGE side. - - Parameters: - - - key - The session key. - - - from_uri - The URI in the SIP From header - to use on the MESSAGE side. - - - to_uri - The URI in the SIP To header - to use on the MESSAGE side. - - - ruri - The SIP Request URI to use on the - MESSAGE side. - - - code - The SIP error code in the negative reply - received on the MSRP side. Might be NULL if the MSRP UA session expired - before receiving a negative reply. - - - reason - The SIP reason string in the negative reply - received on the MSRP side. Might be NULL if the MSRP UA session expired - before receiving a negative reply. - - -
- -
- -
- diff --git a/modules/msrp_relay/README b/modules/msrp_relay/README deleted file mode 100644 index daffb66e6b5..00000000000 --- a/modules/msrp_relay/README +++ /dev/null @@ -1,370 +0,0 @@ -MSRP Relay Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. hash_size (int) - 1.3.2. cleanup_interval (int) - 1.3.3. auth_route (str) - 1.3.4. username_var (string) - 1.3.5. realm_var (string) - 1.3.6. password_var (string) - 1.3.7. calculate_ha1 (integer) - 1.3.8. socket_route (str) - 1.3.9. dst_schema_var (string) - 1.3.10. dst_host_var (string) - 1.3.11. auth_realm (string) - 1.3.12. auth_expires (int) - 1.3.13. auth_min_expires (int) - 1.3.14. auth_max_expires (int) - 1.3.15. nonce_expire (integer) - 1.3.16. my_uri (string) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set server_hsize parameter - 1.2. Set cleanup_interval parameter - 1.3. Set auth_route parameter - 1.4. username_var parameter usage - 1.5. realm_var parameter usage - 1.6. password_var parameter usage - 1.7. calculate_ha1 parameter usage - 1.8. Set socket_route parameter - 1.9. auth_realm parameter usage - 1.10. Set server_hsize parameter - 1.11. Set auth_min_expires parameter - 1.12. Set auth_max_expires parameter - 1.13. nonce_expire parameter example - 1.14. my_uri parameter usage - -Chapter 1. Admin Guide - -1.1. Overview - - This modules implements a Relay for the MSRP protocol, - according to the specifications of RFC 4976. Once loaded, the - module will automatically forward messages and manage MSRP - sessions for the MSRP listeners defined in the script. - - For authenticating MSRP clients, a dedicated script route is - run in order to check the Digest credentials via - pseudo-variables. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * proto_msrp - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * openssl or libssl - * openssl-dev or libssl-dev - -1.3. Exported Parameters - -1.3.1. hash_size (int) - - The size of the hash table that stores the MSRP sessions. It is - the 2 logarithmic value of the real size. - - Default value is “10” (1024 records). - - Example 1.1. Set server_hsize parameter -... -modparam("msrp_relay", "hash_size", 10) -... - -1.3.2. cleanup_interval (int) - - The interval between full iterations of the sessions table in - order to clean up expired MSRP sessions. Note that a session - will be kept in memory as long as the Expires value provided in - the 200 OK response to the AUTH request indicates. - - Default value is “60”. - - Example 1.2. Set cleanup_interval parameter -... -modparam("msrp_relay", "cleanup_interval", 30) -... - -1.3.3. auth_route (str) - - The name of the script route to be called when authorizing MSRP - clients (receiving an AUTH request with an Authorization - header). Here you should provide the appropriate password (or - pre-calculated HA1 string) for the credentials via the - password_var pseudo-variable, in order for the relay to check - the client response. - - No default value; this parameter is mandatory. - - Example 1.3. Set auth_route parameter -... -modparam("msrp_relay", "auth_route", "auth") -... - -1.3.4. username_var (string) - - This name of the pseudo-variable that holds the authentication - username. - - Default value is “$var(username)”. - - Example 1.4. username_var parameter usage -modparam("msrp_relay", "username_var", "$var(msrp_auth_user)") - -1.3.5. realm_var (string) - - This name of the pseudo-variable that hols the authentication - Realm. - - Default value is “$var(realm)”. - - Example 1.5. realm_var parameter usage -modparam("msrp_relay", "realm_var", "$var(msrp_auth_realm)") - -1.3.6. password_var (string) - - This name of the pseudo-variable that should be set in the - auth_route script route in order to check the client response - when authenticating. The value to be set can be either the - plaintext password or pre-calculated HA1 string, based on the - parameter. - - Default value is “$var(password)”. - - Example 1.6. password_var parameter usage -modparam("msrp_relay", "password_var", "$var(msrp_auth_password)") - -1.3.7. calculate_ha1 (integer) - - This parameter configures whether the value of the password_var - pseudo-variable should be treated as a plaintext password or a - pre-calculated HA1 string. - - Default value of this parameter is 0 (HA1 string). - - Example 1.7. calculate_ha1 parameter usage -modparam("msrp_relay", "calculate_ha1", 1) - -1.3.8. socket_route (str) - - The optional name of the script route to be called when start - relaying a new MSRP session (upon the first SEND). The purpose - of this route is to allow you to select the appropriate - outbound socket to be be used for sending out the MSRP request. - - Inside the route, the following information from the received - request will be exposed: - * source network information via the $si, $sp, $sP and - $socket_in variables. - * destination URL schema via the dst_schema_var variable - * destination URL host via the dst_host_var variable - - In this route you should optionally set the desired MSRP(S) - outbound socket via the $socket_out variable. If none is set, - the inbound interface will also be used as outbound if the - schema (MSRP versus MSRPS) is the same. If the schema changes, - the first socket (matching the out schema) will be used. - - Default value is “NULL” (none). - - Example 1.8. Set socket_route parameter -... -modparam("msrp_relay", "socket_route", "msrp_routing") - -route[msrp_routing] { - xlog("MSRP request comming from $si:$sp on $socket_in socket\n") -; - xlog("trying to go to $var(dst_schema)://$var(dst_host)\n"); - - $socket_out = "msrp:1.2.3.4:9999"; -} -... - -1.3.9. dst_schema_var (string) - - This name of the variable to provide the schema ("msrp" or - "msrps") of the destination URL in the socket route. See more - on param_socket_route parameter. - - Default value is “$var(dst_schema)”. - -1.3.10. dst_host_var (string) - - This name of the variable to provide the host of the - destination URL in the socket route. See more on - param_socket_route parameter. - - Default value is “$var(dst_host)”. - -1.3.11. auth_realm (string) - - The realm to be provided in the WWW-Authenticate header when - the relay automatically challanges an MSRP client. - - If this parameter is not set, the realm chose by the relay is - the domain part of the top MSRP URI in the To-Path header of - the AUTH request. - - Example 1.9. auth_realm parameter usage -modparam("msrp_relay", "auth_realm", "opensips.org") - -1.3.12. auth_expires (int) - - The Expires header value to be provided in the 200 OK response - to an AUTH request, if the client does not explicitly request - one. This represents how long the MSRP URI provided by the - relay in the Use-Path header is valid. - - Default value is “1800” (1024 records). - - Example 1.10. Set server_hsize parameter -... -modparam("msrp_relay", "auth_expires", 600) -... - -1.3.13. auth_min_expires (int) - - The minimum value accepted by the relay in the Expires header, - if the client provides it in the AUTH request. If the requested - value is lower that this parameter, the relay will include a - Min-Expires header with the configured value, in the 423 - Interval Out-of-Bounds response. - - If not set, the relay will accept any value. - - Example 1.11. Set auth_min_expires parameter -... -modparam("msrp_relay", "auth_min_expires", 60) -... - -1.3.14. auth_max_expires (int) - - The maximum value accepted by the relay in the Expires header, - if the client provides it in the AUTH request. If the requested - value is higher that this parameter, the relay will include a - Max-Expires header with the configured value, in the 423 - Interval Out-of-Bounds response. - - If not set, the relay will accept any value. - - Example 1.12. Set auth_max_expires parameter -... -modparam("msrp_relay", "auth_max_expires", 60) -... - -1.3.15. nonce_expire (integer) - - Nonces have limited lifetime. After a given period of time - nonces will be considered invalid. This is to protect replay - attacks. Credentials containing a stale nonce will be not - authorized, but the user agent will be challenged again. This - time the challenge will contain stale parameter which will - indicate to the client that it doesn't have to disturb user by - asking for username and password, it can recalculate - credentials using existing username and password. - - The value is in seconds and default value is 30 seconds. - - Example 1.13. nonce_expire parameter example -modparam("msrp_relay", "nonce_expire", 15) # Set nonce_expire to 15s - -1.3.16. my_uri (string) - - MSRP URI of this relay, that will be matched against the first - URI in the To-Path header of any request or response received. - Messages that are not addressed to this relay will be dropped. - - The MSRP URI provided by the relay in the Use-Path header, will - be chosen based on the URI in the To-Path header of the AUTH - request. - - This parameter can be set multiple times - - If the port is not set explicitly, the default value of 2855 - wil be assumed. The session-id part of the URI should not be - set - - Example 1.14. my_uri parameter usage -modparam("msrp_relay", "my_uri", "msrp://opensips.org:2855;tcp") - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 22 7 1646 16 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 7 4 200 20 - 3. Maksym Sobolyev (@sobomax) 4 2 3 3 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 2. Vlad Patrascu (@rvlad-patrascu) Mar 2022 - May 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2022 - May 2023 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2022 www.opensips-solutions.com diff --git a/modules/msrp_relay/README.md b/modules/msrp_relay/README.md new file mode 100644 index 00000000000..aa8f27ab604 --- /dev/null +++ b/modules/msrp_relay/README.md @@ -0,0 +1,371 @@ +--- +title: "MSRP Relay Module" +description: "This modules implements a Relay for the MSRP protocol, according to the specifications of RFC 4976." +--- + +## Admin Guide + + +### Overview + + +This modules implements a Relay for the MSRP protocol, according to +the specifications of RFC 4976. Once loaded, the module will +automatically forward messages and manage MSRP sessions for the MSRP +listeners defined in the script. + + +For authenticating MSRP clients, a dedicated script route is run in order +to check the Digest credentials via pseudo-variables. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *proto_msrp* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *openssl* or +*libssl* +- *openssl-dev* or +*libssl-dev* + + +### Exported Parameters + + +#### hash_size (int) + + +The size of the hash table that stores the MSRP sessions. +It is the 2 logarithmic value of the real size. + + +*Default value is "10"* +(1024 records). + + +```opensips title="Set server_hsize parameter" +... +modparam("msrp_relay", "hash_size", 10) +... + +``` + + +#### cleanup_interval (int) + + +The interval between full iterations of the sessions table +in order to clean up expired MSRP sessions. Note that a session +will be kept in memory as long as the *Expires* +value provided in the 200 OK response to the AUTH request indicates. + + +*Default value is "60".* + + +```opensips title="Set cleanup_interval parameter" +... +modparam("msrp_relay", "cleanup_interval", 30) +... + +``` + + +#### auth_route (str) + + +The name of the script route to be called when authorizing +MSRP clients (receiving an AUTH request with an Authorization header). +Here you should provide the appropriate password (or pre-calculated HA1 +string) for the credentials via the [password var](#param_password_var) +pseudo-variable, in order for the relay to check the client response. + + +*No default value; this parameter is mandatory.* + + +```opensips title="Set auth_route parameter" +... +modparam("msrp_relay", "auth_route", "auth") +... + +``` + + +#### username_var (string) + + +This name of the pseudo-variable that holds the authentication +username. + + +Default value is "$var(username)". + + +```opensips title="username_var parameter usage" +modparam("msrp_relay", "username_var", "$var(msrp_auth_user)") +``` + + +#### realm_var (string) + + +This name of the pseudo-variable that hols the authentication +Realm. + + +Default value is "$var(realm)". + + +```opensips title="realm_var parameter usage" +modparam("msrp_relay", "realm_var", "$var(msrp_auth_realm)") +``` + + +#### password_var (string) + + +This name of the pseudo-variable that should be set in the +[auth route](#param_auth_route) script route in order to check +the client response when authenticating. The value to be set can be +either the plaintext password or pre-calculated HA1 string, based on +the parameter. + + +Default value is "$var(password)". + + +```opensips title="password_var parameter usage" +modparam("msrp_relay", "password_var", "$var(msrp_auth_password)") +``` + + +#### calculate_ha1 (integer) + + +This parameter configures whether the value of the +[password var](#param_password_var) pseudo-variable should be +treated as a plaintext password or a pre-calculated HA1 string. + + +Default value of this parameter is 0 (HA1 string). + + +```opensips title="calculate_ha1 parameter usage" +modparam("msrp_relay", "calculate_ha1", 1) +``` + + +#### socket_route (str) + + +The optional name of the script route to be called when +start relaying a new MSRP session (upon the first SEND). The +purpose of this route is to allow you to select the appropriate +outbound socket to be be used for sending out the MSRP request. + + +Inside the route, the following information from the received +request will be exposed: + + +- *source network information* via the +`$si`, `$sp`, +`$sP` and `$socket_in` +variables. +- *destination URL schema* via the +[dst schema var](#param_dst_schema_var) variable +- *destination URL host* via the +[dst host var](#param_dst_host_var) variable + + +In this route you should optionally set the desired MSRP(S) +outbound socket via the `$socket_out` variable. +If none is set, the inbound interface will also be used as +outbound if the schema (MSRP versus MSRPS) is the same. If the +schema changes, the first socket (matching the out schema) will +be used. + + +Default value is "NULL" (none). + + +```opensips title="Set socket_route parameter" +... +modparam("msrp_relay", "socket_route", "msrp_routing") + +route[msrp_routing] { + xlog("MSRP request comming from $si:$sp on $socket_in socket\n"); + xlog("trying to go to $var(dst_schema)://$var(dst_host)\n"); + + $socket_out = "msrp:1.2.3.4:9999"; +} +... + +``` + + +#### dst_schema_var (string) + + +This name of the variable to provide the schema ("msrp" or "msrps") +of the destination URL in the socket route. See more on +[socket route](#param_socket_route) parameter. + + +Default value is "$var(dst_schema)". + + +#### dst_host_var (string) + + +This name of the variable to provide the host of the +destination URL in the socket route. See more on +[socket route](#param_socket_route) parameter. + + +Default value is "$var(dst_host)". + + +#### auth_realm (string) + + +The realm to be provided in the WWW-Authenticate header when the relay +automatically challanges an MSRP client. + + +If this parameter is not set, the realm chose by the relay is the +domain part of the top MSRP URI in the To-Path header of the AUTH request. + + +```opensips title="auth_realm parameter usage" +modparam("msrp_relay", "auth_realm", "opensips.org") +``` + + +#### auth_expires (int) + + +The *Expires* header value to be provided in the 200 OK +response to an AUTH request, if the client does not explicitly request +one. This represents how long the MSRP URI provided by the relay in the +Use-Path header is valid. + + +*Default value is "1800"* +(1024 records). + + +```opensips title="Set server_hsize parameter" +... +modparam("msrp_relay", "auth_expires", 600) +... + +``` + + +#### auth_min_expires (int) + + +The minimum value accepted by the relay in the *Expires* +header, if the client provides it in the AUTH request. If the requested value +is lower that this parameter, the relay will include a +*Min-Expires* header with the configured value, in the +423 Interval Out-of-Bounds response. + + +If not set, the relay will accept any value. + + +```opensips title="Set auth_min_expires parameter" +... +modparam("msrp_relay", "auth_min_expires", 60) +... + +``` + + +#### auth_max_expires (int) + + +The maximum value accepted by the relay in the *Expires* +header, if the client provides it in the AUTH request. If the requested value +is higher that this parameter, the relay will include a +*Max-Expires* header with the configured value, in the +423 Interval Out-of-Bounds response. + + +If not set, the relay will accept any value. + + +```opensips title="Set auth_max_expires parameter" +... +modparam("msrp_relay", "auth_max_expires", 60) +... + +``` + + +#### nonce_expire (integer) + + +Nonces have limited lifetime. After a given period of time nonces +will be considered invalid. This is to protect replay attacks. +Credentials containing a stale nonce will be not authorized, but the +user agent will be challenged again. This time the challenge will +contain `stale` parameter which will indicate to the +client that it doesn't have to disturb user by asking for username +and password, it can recalculate credentials using existing username +and password. + + +The value is in seconds and default value is 30 seconds. + + +```opensips title="nonce_expire parameter example" +modparam("msrp_relay", "nonce_expire", 15) # Set nonce_expire to 15s +``` + + +#### my_uri (string) + + +MSRP URI of this relay, that will be matched against the first URI in +the To-Path header of any request or response received. Messages that +are not addressed to this relay will be dropped. + + +The MSRP URI provided by the relay in the Use-Path header, will be +chosen based on the URI in the To-Path header of the AUTH request. + + +This parameter can be set multiple times + + +If the port is not set explicitly, the default value of 2855 wil +be assumed. The session-id part of the URI should not be set + + +```opensips title="my_uri parameter usage" +modparam("msrp_relay", "my_uri", "msrp://opensips.org:2855;tcp") +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/msrp_relay/doc/contributors.xml b/modules/msrp_relay/doc/contributors.xml deleted file mode 100644 index a5ff5abed08..00000000000 --- a/modules/msrp_relay/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 22 - 7 - 1646 - 16 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 4 - 200 - 20 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 3 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - Mar 2022 - May 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2022 - May 2023 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/msrp_relay/doc/msrp_relay.xml b/modules/msrp_relay/doc/msrp_relay.xml deleted file mode 100644 index 8513fc5943b..00000000000 --- a/modules/msrp_relay/doc/msrp_relay.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - MSRP Relay Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssol; - diff --git a/modules/msrp_relay/doc/msrp_relay_admin.xml b/modules/msrp_relay/doc/msrp_relay_admin.xml deleted file mode 100644 index 6edfdebd5f9..00000000000 --- a/modules/msrp_relay/doc/msrp_relay_admin.xml +++ /dev/null @@ -1,406 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This modules implements a Relay for the MSRP protocol, according to - the specifications of RFC 4976. Once loaded, the module will - automatically forward messages and manage MSRP sessions for the MSRP - listeners defined in the script. - - - For authenticating MSRP clients, a dedicated script route is run in order - to check the Digest credentials via pseudo-variables. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - proto_msrp - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - openssl or - libssl - - - openssl-dev or - libssl-dev - - - -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (int) - - The size of the hash table that stores the MSRP sessions. - It is the 2 logarithmic value of the real size. - - - Default value is 10 - - (1024 records). - - - Set <varname>server_hsize</varname> parameter - -... -modparam("msrp_relay", "hash_size", 10) -... - - -
- -
- <varname>cleanup_interval</varname> (int) - - The interval between full iterations of the sessions table - in order to clean up expired MSRP sessions. Note that a session - will be kept in memory as long as the Expires - value provided in the 200 OK response to the AUTH request indicates. - - - Default value is 60. - - - Set <varname>cleanup_interval</varname> parameter - -... -modparam("msrp_relay", "cleanup_interval", 30) -... - - -
- -
- <varname>auth_route</varname> (str) - - The name of the script route to be called when authorizing - MSRP clients (receiving an AUTH request with an Authorization header). - Here you should provide the appropriate password (or pre-calculated HA1 - string) for the credentials via the - pseudo-variable, in order for the relay to check the client response. - - - No default value; this parameter is mandatory. - - - Set <varname>auth_route</varname> parameter - -... -modparam("msrp_relay", "auth_route", "auth") -... - - -
- -
- <varname>username_var</varname> (string) - - This name of the pseudo-variable that holds the authentication - username. - - - Default value is $var(username). - - - <varname>username_var</varname> parameter usage - -modparam("msrp_relay", "username_var", "$var(msrp_auth_user)") - - -
- -
- <varname>realm_var</varname> (string) - - This name of the pseudo-variable that hols the authentication - Realm. - - - Default value is $var(realm). - - - <varname>realm_var</varname> parameter usage - -modparam("msrp_relay", "realm_var", "$var(msrp_auth_realm)") - - -
- -
- <varname>password_var</varname> (string) - - This name of the pseudo-variable that should be set in the - script route in order to check - the client response when authenticating. The value to be set can be - either the plaintext password or pre-calculated HA1 string, based on - the parameter. - - - Default value is $var(password). - - - <varname>password_var</varname> parameter usage - -modparam("msrp_relay", "password_var", "$var(msrp_auth_password)") - - -
- -
- <varname>calculate_ha1</varname> (integer) - - This parameter configures whether the value of the - pseudo-variable should be - treated as a plaintext password or a pre-calculated HA1 string. - - - Default value of this parameter is 0 (HA1 string). - - - <varname>calculate_ha1</varname> parameter usage - -modparam("msrp_relay", "calculate_ha1", 1) - - -
- -
- <varname>socket_route</varname> (str) - - The optional name of the script route to be called when - start relaying a new MSRP session (upon the first SEND). The - purpose of this route is to allow you to select the appropriate - outbound socket to be be used for sending out the MSRP request. - - - Inside the route, the following information from the received - request will be exposed: - - - - source network information via the - $si, $sp, - $sP and $socket_in - variables. - - - - destination URL schema via the - variable - - - - destination URL host via the - variable - - - - - In this route you should optionally set the desired MSRP(S) - outbound socket via the $socket_out variable. - If none is set, the inbound interface will also be used as - outbound if the schema (MSRP versus MSRPS) is the same. If the - schema changes, the first socket (matching the out schema) will - be used. - - - Default value is NULL (none). - - - Set <varname>socket_route</varname> parameter - -... -modparam("msrp_relay", "socket_route", "msrp_routing") - -route[msrp_routing] { - xlog("MSRP request comming from $si:$sp on $socket_in socket\n"); - xlog("trying to go to $var(dst_schema)://$var(dst_host)\n"); - - $socket_out = "msrp:1.2.3.4:9999"; -} -... - - -
- -
- <varname>dst_schema_var</varname> (string) - - This name of the variable to provide the schema ("msrp" or "msrps") - of the destination URL in the socket route. See more on - parameter. - - - Default value is $var(dst_schema). - -
- -
- <varname>dst_host_var</varname> (string) - - This name of the variable to provide the host of the - destination URL in the socket route. See more on - parameter. - - - Default value is $var(dst_host). - -
- -
- <varname>auth_realm</varname> (string) - - The realm to be provided in the WWW-Authenticate header when the relay - automatically challanges an MSRP client. - - If this parameter is not set, the realm chose by the relay is the - domain part of the top MSRP URI in the To-Path header of the AUTH request. - - - <varname>auth_realm</varname> parameter usage - -modparam("msrp_relay", "auth_realm", "opensips.org") - - -
- -
- <varname>auth_expires</varname> (int) - - The Expires header value to be provided in the 200 OK - response to an AUTH request, if the client does not explicitly request - one. This represents how long the MSRP URI provided by the relay in the - Use-Path header is valid. - - - Default value is 1800 - - (1024 records). - - - Set <varname>server_hsize</varname> parameter - -... -modparam("msrp_relay", "auth_expires", 600) -... - - -
- -
- <varname>auth_min_expires</varname> (int) - - The minimum value accepted by the relay in the Expires - header, if the client provides it in the AUTH request. If the requested value - is lower that this parameter, the relay will include a - Min-Expires header with the configured value, in the - 423 Interval Out-of-Bounds response. - - - If not set, the relay will accept any value. - - - Set <varname>auth_min_expires</varname> parameter - -... -modparam("msrp_relay", "auth_min_expires", 60) -... - - -
- -
- <varname>auth_max_expires</varname> (int) - - The maximum value accepted by the relay in the Expires - header, if the client provides it in the AUTH request. If the requested value - is higher that this parameter, the relay will include a - Max-Expires header with the configured value, in the - 423 Interval Out-of-Bounds response. - - - If not set, the relay will accept any value. - - - Set <varname>auth_max_expires</varname> parameter - -... -modparam("msrp_relay", "auth_max_expires", 60) -... - - -
- -
- <varname>nonce_expire</varname> (integer) - - Nonces have limited lifetime. After a given period of time nonces - will be considered invalid. This is to protect replay attacks. - Credentials containing a stale nonce will be not authorized, but the - user agent will be challenged again. This time the challenge will - contain stale parameter which will indicate to the - client that it doesn't have to disturb user by asking for username - and password, it can recalculate credentials using existing username - and password. - - - The value is in seconds and default value is 30 seconds. - - - nonce_expire parameter example - -modparam("msrp_relay", "nonce_expire", 15) # Set nonce_expire to 15s - - -
- -
- <varname>my_uri</varname> (string) - - MSRP URI of this relay, that will be matched against the first URI in - the To-Path header of any request or response received. Messages that - are not addressed to this relay will be dropped. - - - The MSRP URI provided by the relay in the Use-Path header, will be - chosen based on the URI in the To-Path header of the AUTH request. - - This parameter can be set multiple times - If the port is not set explicitly, the default value of 2855 wil - be assumed. The session-id part of the URI should not be set - - <varname>my_uri</varname> parameter usage - -modparam("msrp_relay", "my_uri", "msrp://opensips.org:2855;tcp") - - -
- -
-
- diff --git a/modules/msrp_ua/README b/modules/msrp_ua/README deleted file mode 100644 index 7d99a23d36f..00000000000 --- a/modules/msrp_ua/README +++ /dev/null @@ -1,569 +0,0 @@ -MSRP UA Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Usage from Script and External API - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. hash_size (int) - 1.4.2. cleanup_interval (int) - 1.4.3. max_duration (integer) - 1.4.4. my_uri (string) - 1.4.5. advertised_contact (string) - 1.4.6. relay_uri (string) - - 1.5. Exported Functions - - 1.5.1. msrp_ua_answer(content_types) - - 1.6. Exported MI Functions - - 1.6.1. msrp_ua_send_message - 1.6.2. msrp_ua_start_session - 1.6.3. msrp_ua_list_sessions - 1.6.4. msrp_ua_end_session - - 1.7. Exported Events - - 1.7.1. E_MSRP_SESSION_NEW - 1.7.2. E_MSRP_SESSION_END - 1.7.3. E_MSRP_MSG_RECEIVED - 1.7.4. E_MSRP_REPORT_RECEIVED - - 2. Developer Guide - - 2.1. Overview - 2.2. Available Functions - - 2.2.1. init_uas(msg, accept_types, hdl) - 2.2.2. init_uac(accept_types, from_uri, to_uri, - ruri, hdl) - - 2.2.3. end_session(session_id) - 2.2.4. send_message(session_id, mime, body, - failure_report, success_report) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hash_size parameter - 1.2. Set cleanup_interval parameter - 1.3. max_duration parameter example - 1.4. my_uri parameter usage - 1.5. advertised_contact parameter usage - 1.6. relay_uri parameter usage - 1.7. msrp_ua_answer() usage - 2.1. struct msrp_ua_handler structure - 2.2. msrp_ua_notify_cb_f prototype - 2.3. struct msrp_ua_notify_params structure - 2.4. enum msrp_ua_event_type - 2.5. msrp_ua_req_cb_f prototype - 2.6. msrp_ua_rpl_cb_f prototype - 2.7. enum msrp_failure_report_type - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements an User Agent capable of establishing - messaging sessions using the MSRP(RFC 4976) protocol. - - Through an internal API and exported script and MI functions, - the module allows OpenSIPS to set up MSRP sessions via SIP and - exchange messages as an MSRP endpoint. - - The module makes use of the proto_msrp module for the MSRP - protocol stack and the b2b_entities module for the SIP UAC/UAS - functionalities. - -1.2. Usage from Script and External API - - In order to start a SIP call carying MSRP from OpenSIPS you can - use the msrp_ua_start_session MI function. Alternatively, to - answer a SIP session with MSRP you can use the msrp_ua_answer() - script function. - - When a UAC or UAS session is successfully established(ACK - sent/received) the E_MSRP_SESSION_NEW event is triggered. After - this point, you may receive MSRP messages or Reports, signaled - by the E_MSRP_MSG_RECEIVED and E_MSRP_REPORT_RECEIVED events. - - Note that the E_MSRP_REPORT_RECEIVED event covers both actual - MSRP REPORT requests as well as negative MSRP transaction - responses and local send timeouts(which should be treated the - same as a received timeout transaction response). - - You can send MSRP messages to the peer with the - msrp_ua_send_message MI function. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * proto_msrp - * b2b_entities - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. hash_size (int) - - The size of the hash table that stores the MSRP session - information. It is the 2 logarithmic value of the real size. - - Default value is “10” (1024 records). - - Example 1.1. Set hash_size parameter -... -modparam("msrp_ua", "hash_size", 16) -... - -1.4.2. cleanup_interval (int) - - The interval between full iterations of the sessions table in - order to clean up expired MSRP sessions. - - Default value is “60”. - - Example 1.2. Set cleanup_interval parameter -... -modparam("msrp_ua", "cleanup_interval", 30) -... - -1.4.3. max_duration (integer) - - The maximum duration of a call. If set to 0, there will be no - limitation. - - The default value is 12 * 3600 seconds (12 hours). - - Example 1.3. max_duration parameter example -... -modparam("msrp_ua", "max_duration", 7200) -... - -1.4.4. my_uri (string) - - The MSRP URI of the OpenSIPS endpoint. This URI will be - advertised in the SDP offer provided to peers when setting up a - session and should match one of the MSRP listeners defined in - the script. - - The session-id part of the URI should be ommited. - - If the port is not set explicitly, the default value of 2855 - wil be assumed - - Example 1.4. my_uri parameter usage -... -modparam("msrp_ua", "my_uri", "msrp://opensips.org:2855;tcp") -... - -1.4.5. advertised_contact (string) - - Contact to be used in the generated SIP requests. For sessions - answered by OpenSIPS, if it is not set, it is constructed - dynamically from the socket where the initiating request was - received. - - This parameter is mandatory when using the - msrp_ua_start_session MI function. - - Example 1.5. advertised_contact parameter usage -... -modparam("msrp_ua", "advertised_contact", "sip:oss@opensips.org") -... - -1.4.6. relay_uri (string) - - URI of an MSRP relay to use for both accepted and initiated - sessions. - - Credentials for the MSRP client are provided via the uac_auth - module by setting the credential module parameter. - - If not set, no relay will be used. - - Example 1.6. relay_uri parameter usage -... -modparam("msrp_ua", "relay_uri", "msrp://opensips.org:2856;tcp") -... - -1.5. Exported Functions - -1.5.1. msrp_ua_answer(content_types) - - This functions answers an initial INVITE offering a new MSRP - messaging session. After this function is used to initialize - the session, the call will be completely handled by the B2B - engine. - - Parameters: - * content_types (string) - content types adevertised in the - accept-types SDP attribute. At least one of the content - types in this list must match the types offered by the peer - in its SDP offer. - - This function can be used only from a request route. - - Example 1.7. msrp_ua_answer() usage -... -if (!has_totag() && is_method("INVITE")) { - msrp_ua_answer("text/plain"); - exit; -} -... - -1.6. Exported MI Functions - -1.6.1. msrp_ua_send_message - - Sends a new MSRP message to the peer. - - Name: msrp_ua_send_message - - Parameters - * session_id (string) - the MSRP session identifier - ("session-id" part of the MSRP URI). - * mime (string, optional) - MIME content type of this - message. If missing, an empty message will be sent. - * body (string, optional) - actual message body. If missing, - an empty message will be sent. - * success_report (string, optional) - string indicating - whether to request an MSRP Success Report. Possible values - are yes or no. If the parameter is missing or is set to - "no" the SEND request will not include a Success-Report - header. - * failure_report (string, optional) - string indicating - whether to request an MSRP Failure Report. Possible values - are yes, no or partial, as specified in MSRP. If the - parameter is missing or is set to "yes" the SEND request - will not include a Failure-Report header. Note that if the - header field is not present, the receving MSRP endpoint - must treat it the same as a Failure-Report header with a - value of "yes". - - MI FIFO Command Format: -opensips-cli -x mi msrp_ua_send_message \ - session_id=5addd9e7b74fa44fbace68a4fc562293 \ - mime=text/plain body=Hello success_report=yes - -1.6.2. msrp_ua_start_session - - Starts a MSRP session. - - The advertised_contact is mandatory if this function is used. - - Name: msrp_ua_start_session - - Parameters - * content_types (string) - content types adevertised in the - accept-types SDP attribute. - * from_uri (string) - From URI to be used in the INVITE. - * to_uri (string) - To URI to be used in the INVITE. - * ruri (string) - Request URI and destination of the INVITE. - - MI FIFO Command Format: -opensips-cli -x mi msrp_ua_start_session \ - text/plain sip:oss@opensips.org \ - sip:alice@opensips.org sip:alice@opensips.org - -1.6.3. msrp_ua_list_sessions - - Lists information about ongoing MSRP sessions. - - Name: msrp_ua_list_sessions - - Parameters - * None. - - MI FIFO Command Format: -opensips-cli -x mi msrp_ua_list_sessions - -1.6.4. msrp_ua_end_session - - Terminate an ongoing MSRP session. - - Name: msrp_ua_end_session - - Parameters - * session_id (string) - the MSRP session identifier - ("session-id" part of the MSRP URI). - - MI FIFO Command Format: -opensips-cli -x mi msrp_ua_end_session \ - 5addd9e7b74fa44fbace68a4fc562293 - -1.7. Exported Events - -1.7.1. E_MSRP_SESSION_NEW - - This event is triggered when a new MSRP session is successfully - established(ACK sent/received). - - Parameters: - * from_uri - The URI in the SIP From header of the answered - INVITE. - * to_uri - The URI in the SIP To header of the answered - INVITE. - * ruri - The SIP Request URI of the answered INVITE. - * session_id - The MSRP session identifier ("session-id" part - of the MSRP URI). - * content_types - The content types offered by the peer in - the accept-types SDP attribute. - -1.7.2. E_MSRP_SESSION_END - - This event is triggered when an ongoing MSRP session is - terminted (session expires or BYE is received; terminating a - session via the msrp_ua_end_session MI function is not - included). - - Parameters: - * session_id - The MSRP session identifier ("session-id" part - of the MSRP URI). - -1.7.3. E_MSRP_MSG_RECEIVED - - This event is triggered when receiving a new, non-empty MSRP - SEND request from the peer. - - Parameters: - * session_id - The MSRP session identifier ("session-id" part - of the MSRP URI). - * content_type - The content type of this message. - * body - The actual message body. - -1.7.4. E_MSRP_REPORT_RECEIVED - - This event is triggered when: - * a MSRP REPORT request is received - * a failure transaction response is received - * a local timeout for a SEND request occured. - - Parameters: - * session_id - The MSRP session identifier ("session-id" part - of the MSRP URI). - * message_id - The value of the Message-ID header field. - * status - The value of the Status header field. - * byte_range - The value of the Byte-Range header field. - -Chapter 2. Developer Guide - -2.1. Overview - - In order to answer a SIP session carying MSRP the init_uas() - function should be used. Conversely for starting a MSRP call as - a UAC, one can use the init_uac() function. - - After initializing the session with either of the above - functions, the SIP call will be further handled by the module - and notifications regarding significant SIP level events and - received MSRP requests and responses will be delivered via - registering callback functions. - - MSRP SEND requests can be sent with the send_message() function - after the sessions is established, which will be signaled by - the msrp_ua_notify_cb_f callback with the - MSRP_UA_SESS_ESTABLISHED event. - - Received MSRP requests, transaction responses and local send - timeouts will be signaled via the msrp_ua_req_cb_f and - msrp_ua_rpl_cb_f callbacks. - -2.2. Available Functions - -2.2.1. init_uas(msg, accept_types, hdl) - - This function will intialize a MSRP UA session based on a - received SIP INVITE. - - Meaning of the parameters is as follows: - * struct sip_msg *msg - the SIP message - * str *accept_types - the value of the "accept-types" - attribute to include in the SDP offer. - * struct msrp_ua_handler *hdl - handler structure used to - register the callbacks for SIP level and MSRP level - notifications. - - Example 2.1. struct msrp_ua_handler structure -struct msrp_ua_handler { - /* name of this registration */ - str *name; - /* parameter to be passed to msrp_req_cb and msrp_rpl_cb callbac -ks */ - void *param; - /* callback for SIP level notifications */ - msrp_ua_notify_cb_f notify_cb; - /* callback for receving MSRP requests */ - msrp_ua_req_cb_f msrp_req_cb; - /* callback for receving MSRP responses */ - msrp_ua_rpl_cb_f msrp_rpl_cb; -}; - - Example 2.2. msrp_ua_notify_cb_f prototype -typedef int (*msrp_ua_notify_cb_f)(struct msrp_ua_notify_params *params, - void *hdl_param); - - Example 2.3. struct msrp_ua_notify_params structure -struct msrp_ua_notify_params { - /* event type */ - enum msrp_ua_event_type event; - /* SIP message */ - struct sip_msg *msg; - /* SDP "accept-types" attribute in case of MSRP_UA_SESS_ESTABLIS -HED event */ - str *accept_types; - /* MSRP UA session ID */ - str *session_id; -}; - - Example 2.4. enum msrp_ua_event_type -enum msrp_ua_event_type { - /* session established (ACK sent/received) */ - MSRP_UA_SESS_ESTABLISHED = 1, - /* failed to establish session (negative reply/timeout etc.) */ - MSRP_UA_SESS_FAILED, - /* BYE received/sent(in case of session timeout) */ - MSRP_UA_SESS_TERMINATED -}; - - Example 2.5. msrp_ua_req_cb_f prototype -typedef int (*msrp_ua_req_cb_f)(struct msrp_msg *req, void *hdl_param); - - Example 2.6. msrp_ua_rpl_cb_f prototype -/* an MSRP transaction timeout will be signaled by calling this callback - * with a NULL rpl parameter */ -typedef int (*msrp_ua_rpl_cb_f)(struct msrp_msg *rpl, void *hdl_param); - -2.2.2. init_uac(accept_types, from_uri, to_uri, ruri, hdl) - - This function will intialize a MSRP UA session by sending a SIP - INVITE to a destination. - - Meaning of the parameters is as follows: - * str *accept_types - the value of the "accept-types" - attribute to include in the SDP offer. - * str *from_uri - URI to use in the From header of the - INVITE. - * str *to_uri - URI to use in the To header of the INVITE. - * str *ruri - Request URI to use in the for the INVITE. - * struct msrp_ua_handler *hdl - handler structure used to - register the callbacks for SIP level and MSRP level - notifications. - -2.2.3. end_session(session_id) - - This function terminates an MSRP session. - - Meaning of the parameters is as follows: - * str *session_id - MSRP UA session ID. - -2.2.4. send_message(session_id, mime, body, failure_report, -success_report) - - This functions sends an MSRP SEND request to the peer. - - Meaning of the parameters is as follows: - * str *session_id - MSRP UA session ID. - * str *mime - MIME content type of this message. If NULL, an - empty message will be sent. - * str *body - actual message body. If NULL, an empty message - will be sent. - * enum msrp_failure_report_type failure_report - MSRP Failure - Report type - yes, no or partial. - * int success_report - indication whether to request an MSRP - Failure Report or not. - - Example 2.7. enum msrp_failure_report_type -enum msrp_failure_report_type { - MSRP_FAILURE_REPORT_YES, - MSRP_FAILURE_REPORT_PARTIAL, - MSRP_FAILURE_REPORT_NO -}; - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 55 16 4038 293 - 2. Maksym Sobolyev (@sobomax) 5 3 6 6 - 3. Razvan Crainea (@razvancrainea) 3 1 11 1 - 4. Liviu Chircu (@liviuchircu) 3 1 8 8 - 5. Norman Brandinger (@NormB) 3 1 2 2 - 6. Alexandra Titoc 3 1 1 1 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Norman Brandinger (@NormB) Jun 2024 - Jun 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2022 - Jan 2023 - 5. Razvan Crainea (@razvancrainea) Aug 2022 - Aug 2022 - 6. Liviu Chircu (@liviuchircu) Jul 2022 - Jul 2022 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) May 2022 - May 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2022 www.opensips-solutions.com diff --git a/modules/msrp_ua/README.md b/modules/msrp_ua/README.md new file mode 100644 index 00000000000..62c5f1c5964 --- /dev/null +++ b/modules/msrp_ua/README.md @@ -0,0 +1,616 @@ +--- +title: "MSRP UA Module" +description: "This module implements an User Agent capable of establishing messaging sessions using the MSRP(RFC 4976) protocol." +--- + +## Admin Guide + + +### Overview + + +This module implements an User Agent capable of establishing messaging +sessions using the MSRP(RFC 4976) protocol. + + +Through an internal API and exported script and MI functions, the module +allows OpenSIPS to set up MSRP sessions via SIP and exchange messages as +an MSRP endpoint. + + +The module makes use of the *proto_msrp* module for +the MSRP protocol stack and the *b2b_entities* module +for the SIP UAC/UAS functionalities. + + +### Usage from Script and External API + + +In order to start a SIP call carying MSRP from OpenSIPS you can use the +[mi msrp ua start session](#mi_msrp_ua_start_session) MI function. Alternatively, to +answer a SIP session with MSRP you can use the +[msrp ua answer](#func_msrp_ua_answer) script function. + + +When a UAC or UAS session is successfully established(ACK sent/received) the +[E MSRP SESSION NEW](#event_e_msrp_session_new) event is triggered. After this point, +you may receive MSRP messages or Reports, signaled by the +[E MSRP MSG RECEIVED](#event_e_msrp_msg_received) and +[E MSRP REPORT RECEIVED](#event_e_msrp_report_received) events. + + +Note that the *E_MSRP_REPORT_RECEIVED* event covers both actual MSRP +REPORT requests as well as negative MSRP transaction responses and local send +timeouts(which should be treated the same as a received timeout transaction +response). + + +You can send MSRP messages to the peer with the +[mi msrp ua send message](#mi_msrp_ua_send_message) MI function. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *proto_msrp* +- *b2b_entities* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### hash_size (int) + + +The size of the hash table that stores the MSRP session +information. It is the 2 logarithmic value of the real size. + + +*Default value is "10"* +(1024 records). + + +```opensips title="Set hash_size parameter" +... +modparam("msrp_ua", "hash_size", 16) +... + +``` + + +#### cleanup_interval (int) + + +The interval between full iterations of the sessions table +in order to clean up expired MSRP sessions. + + +*Default value is "60".* + + +```opensips title="Set cleanup_interval parameter" +... +modparam("msrp_ua", "cleanup_interval", 30) +... + +``` + + +#### max_duration (integer) + + +The maximum duration of a call. If set to 0, there will be no limitation. + + +The default value is 12 * 3600 seconds (12 hours). + + +```opensips title="max_duration parameter example" +... +modparam("msrp_ua", "max_duration", 7200) +... +``` + + +#### my_uri (string) + + +The MSRP URI of the OpenSIPS endpoint. This URI will be advertised in the SDP +offer provided to peers when setting up a session and should match one +of the MSRP listeners defined in the script. + + +The *session-id* part of the URI should be ommited. + + +If the port is not set explicitly, the default value of 2855 wil +be assumed + + +```opensips title="my_uri parameter usage" +... +modparam("msrp_ua", "my_uri", "msrp://opensips.org:2855;tcp") +... +``` + + +#### advertised_contact (string) + + +Contact to be used in the generated SIP requests. For sessions answered +by OpenSIPS, if it is not set, it is constructed dynamically from the +socket where the initiating request was received. + + +This parameter is mandatory when using the +[mi msrp ua start session](#mi_msrp_ua_start_session) MI function. + + +```opensips title="advertised_contact parameter usage" +... +modparam("msrp_ua", "advertised_contact", "sip:oss@opensips.org") +... +``` + + +#### relay_uri (string) + + +URI of an MSRP relay to use for both accepted and initiated +sessions. + + +Credentials for the MSRP client are provided via the +*uac_auth* module by setting the +*credential* module parameter. + + +If not set, no relay will be used. + + +```opensips title="relay_uri parameter usage" +... +modparam("msrp_ua", "relay_uri", "msrp://opensips.org:2856;tcp") +... +``` + + +### Exported Functions + + +#### msrp_ua_answer(content_types) + + +This functions answers an initial INVITE offering a new MSRP +messaging session. After this function is used to initialize the +session, the call will be completely handled by the B2B engine. + + +Parameters: + + +- *content_types* (string) - content types +adevertised in the *accept-types* SDP +attribute. At least one of the content types in this list must +match the types offered by the peer in its SDP offer. + + +This function can be used only from a request route. + + +```opensips title="msrp_ua_answer() usage" +... +if (!has_totag() && is_method("INVITE")) { + msrp_ua_answer("text/plain"); + exit; +} +... +``` + + +### Exported MI Functions + + +#### msrp_ua_send_message + + +Sends a new MSRP message to the peer. + + +Name: *msrp_ua_send_message* + + +Parameters + + +- *session_id* (string) - the MSRP session +identifier ("session-id" part of the MSRP URI). +- *mime* (string, optional) - MIME content +type of this message. If missing, an empty message will be sent. +- *body* (string, optional) - actual message +body. If missing, an empty message will be sent. +- *success_report* (string, optional) - string +indicating whether to request an MSRP Success Report. Possible +values are *yes* or *no*. +If the parameter is missing or is set to "no" the SEND request +will not include a Success-Report header. +- *failure_report* (string, optional) - string +indicating whether to request an MSRP Failure Report. Possible +values are *yes*, *no* or +*partial*, as specified in MSRP. +If the parameter is missing or is set to "yes" the SEND request +will not include a Failure-Report header. Note that if the header +field is not present, the receving MSRP endpoint must treat it the +same as a Failure-Report header with a value of "yes". + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_ua_send_message \ + session_id=5addd9e7b74fa44fbace68a4fc562293 \ + mime=text/plain body=Hello success_report=yes + +``` + + +#### msrp_ua_start_session + + +Starts a MSRP session. + + +The [advertised contact](#param_advertised_contact) is mandatory if this +function is used. + + +Name: *msrp_ua_start_session* + + +Parameters + + +- *content_types* (string) - content types +adevertised in the *accept-types* SDP +attribute. +- *from_uri* (string) - From URI to be used +in the INVITE. +- *to_uri* (string) - To URI to be used +in the INVITE. +- *ruri* (string) - Request URI and destination +of the INVITE. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_ua_start_session \ + text/plain sip:oss@opensips.org \ + sip:alice@opensips.org sip:alice@opensips.org + +``` + + +#### msrp_ua_list_sessions + + +Lists information about ongoing MSRP sessions. + + +Name: *msrp_ua_list_sessions* + + +Parameters + + +- *None*. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_ua_list_sessions + +``` + + +#### msrp_ua_end_session + + +Terminate an ongoing MSRP session. + + +Name: *msrp_ua_end_session* + + +Parameters + + +- *session_id* (string) - the MSRP session +identifier ("session-id" part of the MSRP URI). + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi msrp_ua_end_session \ + 5addd9e7b74fa44fbace68a4fc562293 + +``` + + +### Exported Events + + +#### E_MSRP_SESSION_NEW + + +This event is triggered when a new MSRP session is successfully +established(ACK sent/received). + + +Parameters: + + +- *from_uri* - The URI in the SIP From header +of the answered INVITE. +- *to_uri* - The URI in the SIP To header +of the answered INVITE. +- *ruri* - The SIP Request URI of the answered +INVITE. +- *session_id* - The MSRP session identifier +("session-id" part of the MSRP URI). +- *content_types* - The content types offered +by the peer in the *accept-types* SDP attribute. + + +#### E_MSRP_SESSION_END + + +This event is triggered when an ongoing MSRP session is terminted (session +expires or BYE is received; terminating a session via the +*msrp_ua_end_session* MI function is not included). + + +Parameters: + + +- *session_id* - The MSRP session identifier +("session-id" part of the MSRP URI). + + +#### E_MSRP_MSG_RECEIVED + + +This event is triggered when receiving a new, non-empty MSRP SEND +request from the peer. + + +Parameters: + + +- *session_id* - The MSRP session identifier +("session-id" part of the MSRP URI). +- *content_type* - The content type of this message. +- *body* - The actual message body. + + +#### E_MSRP_REPORT_RECEIVED + + +This event is triggered when: + + +- a MSRP REPORT request is received +- a failure transaction response is received +- a local timeout for a SEND request occured. + + +Parameters: + + +- *session_id* - The MSRP session identifier +("session-id" part of the MSRP URI). +- *message_id* - The value of the Message-ID +header field. +- *status* - The value of the Status header field. +- *byte_range* - The value of the Byte-Range header +field. + + +## Developer Guide + + +### Overview + + +In order to answer a SIP session carying MSRP the [init uas](#dev_init_uas) +function should be used. Conversely for starting a MSRP call as a UAC, one +can use the [init uac](#dev_init_uac) function. + + +After initializing the session with either of the above functions, the SIP call +will be further handled by the module and notifications regarding significant SIP +level events and received MSRP requests and responses will be delivered via +registering callback functions. + + +MSRP SEND requests can be sent with the [send message](#dev_send_message) function +after the sessions is established, which will be signaled by the +*msrp_ua_notify_cb_f* callback with the +*MSRP_UA_SESS_ESTABLISHED* event. + + +Received MSRP requests, transaction responses and local send timeouts will be +signaled via the *msrp_ua_req_cb_f* and +*msrp_ua_rpl_cb_f* callbacks. + + +### Available Functions + + +#### init_uas(msg, accept_types, hdl) + + +This function will intialize a MSRP UA session based on a received SIP +INVITE. + + +Meaning of the parameters is as follows: + + +- *struct sip_msg *msg* - the SIP message +- *str *accept_types* - the value of the +"accept-types" attribute to include in the SDP offer. +- *struct msrp_ua_handler *hdl* - handler +structure used to register the callbacks for SIP level and MSRP +level notifications. + + +```c title="struct msrp_ua_handler structure" +struct msrp_ua_handler { + /* name of this registration */ + str *name; + /* parameter to be passed to msrp_req_cb and msrp_rpl_cb callbacks */ + void *param; + /* callback for SIP level notifications */ + msrp_ua_notify_cb_f notify_cb; + /* callback for receving MSRP requests */ + msrp_ua_req_cb_f msrp_req_cb; + /* callback for receving MSRP responses */ + msrp_ua_rpl_cb_f msrp_rpl_cb; +}; +``` + + +```c title="msrp_ua_notify_cb_f prototype" +typedef int (*msrp_ua_notify_cb_f)(struct msrp_ua_notify_params *params, + void *hdl_param); +``` + + +```c title="struct msrp_ua_notify_params structure" +struct msrp_ua_notify_params { + /* event type */ + enum msrp_ua_event_type event; + /* SIP message */ + struct sip_msg *msg; + /* SDP "accept-types" attribute in case of MSRP_UA_SESS_ESTABLISHED event */ + str *accept_types; + /* MSRP UA session ID */ + str *session_id; +}; +``` + + +```c title="enum msrp_ua_event_type" +enum msrp_ua_event_type { + /* session established (ACK sent/received) */ + MSRP_UA_SESS_ESTABLISHED = 1, + /* failed to establish session (negative reply/timeout etc.) */ + MSRP_UA_SESS_FAILED, + /* BYE received/sent(in case of session timeout) */ + MSRP_UA_SESS_TERMINATED +}; +``` + + +```c title="msrp_ua_req_cb_f prototype" +typedef int (*msrp_ua_req_cb_f)(struct msrp_msg *req, void *hdl_param); +``` + + +```c title="msrp_ua_rpl_cb_f prototype" +/* an MSRP transaction timeout will be signaled by calling this callback + * with a NULL rpl parameter */ +typedef int (*msrp_ua_rpl_cb_f)(struct msrp_msg *rpl, void *hdl_param); +``` + + +#### init_uac(accept_types, from_uri, to_uri, ruri, hdl) + + +This function will intialize a MSRP UA session by sending a SIP INVITE to +a destination. + + +Meaning of the parameters is as follows: + + +- *str *accept_types* - the value of the +"accept-types" attribute to include in the SDP offer. +- *str *from_uri* - URI to use in the From +header of the INVITE. +- *str *to_uri* - URI to use in the To +header of the INVITE. +- *str *ruri* - Request URI to use in the for +the INVITE. +- *struct msrp_ua_handler *hdl* - handler +structure used to register the callbacks for SIP level and MSRP +level notifications. + + +#### end_session(session_id) + + +This function terminates an MSRP session. + + +Meaning of the parameters is as follows: + + +- *str *session_id* - MSRP UA session ID. + + +#### send_message(session_id, mime, body, failure_report, success_report) + + +This functions sends an MSRP SEND request to the peer. + + +Meaning of the parameters is as follows: + + +- *str *session_id* - MSRP UA session ID. +- *str *mime* - MIME content +type of this message. If NULL, an empty message will be sent. +- *str *body* - actual message +body. If NULL, an empty message will be sent. +- *enum msrp_failure_report_type failure_report* - +MSRP Failure Report type - yes, no or partial. +- *int success_report* - indication whether to +request an MSRP Failure Report or not. + + +```c title="enum msrp_failure_report_type" +enum msrp_failure_report_type { + MSRP_FAILURE_REPORT_YES, + MSRP_FAILURE_REPORT_PARTIAL, + MSRP_FAILURE_REPORT_NO +}; +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/msrp_ua/doc/contributors.xml b/modules/msrp_ua/doc/contributors.xml deleted file mode 100644 index 30b4ab85dfd..00000000000 --- a/modules/msrp_ua/doc/contributors.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 55 - 16 - 4038 - 293 - - - 2. - Maksym Sobolyev (@sobomax) - 5 - 3 - 6 - 6 - - - 3. - Razvan Crainea (@razvancrainea) - 3 - 1 - 11 - 1 - - - 4. - Liviu Chircu (@liviuchircu) - 3 - 1 - 8 - 8 - - - 5. - Norman Brandinger (@NormB) - 3 - 1 - 2 - 2 - - - 6. - Alexandra Titoc - 3 - 1 - 1 - 1 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Norman Brandinger (@NormB) - Jun 2024 - Jun 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2022 - Jan 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Aug 2022 - Aug 2022 - - - 6. - Liviu Chircu (@liviuchircu) - Jul 2022 - Jul 2022 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2022 - May 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/msrp_ua/doc/msrp_ua.xml b/modules/msrp_ua/doc/msrp_ua.xml deleted file mode 100644 index 4a31c62e426..00000000000 --- a/modules/msrp_ua/doc/msrp_ua.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - MSRP UA Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssol; - diff --git a/modules/msrp_ua/doc/msrp_ua_admin.xml b/modules/msrp_ua/doc/msrp_ua_admin.xml deleted file mode 100644 index d0c30c2dc34..00000000000 --- a/modules/msrp_ua/doc/msrp_ua_admin.xml +++ /dev/null @@ -1,524 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements an User Agent capable of establishing messaging - sessions using the MSRP(RFC 4976) protocol. - - - Through an internal API and exported script and MI functions, the module - allows OpenSIPS to set up MSRP sessions via SIP and exchange messages as - an MSRP endpoint. - - - The module makes use of the proto_msrp module for - the MSRP protocol stack and the b2b_entities module - for the SIP UAC/UAS functionalities. - -
- -
- Usage from Script and External API - - In order to start a SIP call carying MSRP from OpenSIPS you can use the - MI function. Alternatively, to - answer a SIP session with MSRP you can use the - script function. - - - When a UAC or UAS session is successfully established(ACK sent/received) the - event is triggered. After this point, - you may receive MSRP messages or Reports, signaled by the - and - events. - - - Note that the E_MSRP_REPORT_RECEIVED event covers both actual MSRP - REPORT requests as well as negative MSRP transaction responses and local send - timeouts(which should be treated the same as a received timeout transaction - response). - - - You can send MSRP messages to the peer with the - MI function. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - proto_msrp - - - b2b_entities - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None. - - - -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (int) - - The size of the hash table that stores the MSRP session - information. It is the 2 logarithmic value of the real size. - - - Default value is 10 - - (1024 records). - - - Set <varname>hash_size</varname> parameter - -... -modparam("msrp_ua", "hash_size", 16) -... - - -
- -
- <varname>cleanup_interval</varname> (int) - - The interval between full iterations of the sessions table - in order to clean up expired MSRP sessions. - - - Default value is 60. - - - Set <varname>cleanup_interval</varname> parameter - -... -modparam("msrp_ua", "cleanup_interval", 30) -... - - -
- -
- <varname>max_duration</varname> (integer) - - The maximum duration of a call. If set to 0, there will be no limitation. - - - The default value is 12 * 3600 seconds (12 hours). - - - max_duration parameter example - -... -modparam("msrp_ua", "max_duration", 7200) -... - - -
- -
- <varname>my_uri</varname> (string) - - The MSRP URI of the OpenSIPS endpoint. This URI will be advertised in the SDP - offer provided to peers when setting up a session and should match one - of the MSRP listeners defined in the script. - - - The session-id part of the URI should be ommited. - - If the port is not set explicitly, the default value of 2855 wil - be assumed - - <varname>my_uri</varname> parameter usage - -... -modparam("msrp_ua", "my_uri", "msrp://opensips.org:2855;tcp") -... - - -
- -
- <varname>advertised_contact</varname> (string) - - Contact to be used in the generated SIP requests. For sessions answered - by OpenSIPS, if it is not set, it is constructed dynamically from the - socket where the initiating request was received. - - - This parameter is mandatory when using the - MI function. - - - <varname>advertised_contact</varname> parameter usage - -... -modparam("msrp_ua", "advertised_contact", "sip:oss@opensips.org") -... - - -
- -
- <varname>relay_uri</varname> (string) - - URI of an MSRP relay to use for both accepted and initiated - sessions. - - - Credentials for the MSRP client are provided via the - uac_auth module by setting the - credential module parameter. - - - If not set, no relay will be used. - - - <varname>relay_uri</varname> parameter usage - -... -modparam("msrp_ua", "relay_uri", "msrp://opensips.org:2856;tcp") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">msrp_ua_answer(content_types)</function> - - - This functions answers an initial INVITE offering a new MSRP - messaging session. After this function is used to initialize the - session, the call will be completely handled by the B2B engine. - - - Parameters: - - - content_types (string) - content types - adevertised in the accept-types SDP - attribute. At least one of the content types in this list must - match the types offered by the peer in its SDP offer. - - - - - This function can be used only from a request route. - - - <function>msrp_ua_answer()</function> usage - -... -if (!has_totag() && is_method("INVITE")) { - msrp_ua_answer("text/plain"); - exit; -} -... - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">msrp_ua_send_message</function> - - - Sends a new MSRP message to the peer. - - - Name: msrp_ua_send_message - - Parameters - - - session_id (string) - the MSRP session - identifier ("session-id" part of the MSRP URI). - - - mime (string, optional) - MIME content - type of this message. If missing, an empty message will be sent. - - - body (string, optional) - actual message - body. If missing, an empty message will be sent. - - - success_report (string, optional) - string - indicating whether to request an MSRP Success Report. Possible - values are yes or no. - If the parameter is missing or is set to "no" the SEND request - will not include a Success-Report header. - - - failure_report (string, optional) - string - indicating whether to request an MSRP Failure Report. Possible - values are yes, no or - partial, as specified in MSRP. - If the parameter is missing or is set to "yes" the SEND request - will not include a Failure-Report header. Note that if the header - field is not present, the receving MSRP endpoint must treat it the - same as a Failure-Report header with a value of "yes". - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_ua_send_message \ - session_id=5addd9e7b74fa44fbace68a4fc562293 \ - mime=text/plain body=Hello success_report=yes - -
- -
- - <function moreinfo="none">msrp_ua_start_session</function> - - - Starts a MSRP session. - - - The is mandatory if this - function is used. - - - Name: msrp_ua_start_session - - Parameters - - - content_types (string) - content types - adevertised in the accept-types SDP - attribute. - - - from_uri (string) - From URI to be used - in the INVITE. - - - to_uri (string) - To URI to be used - in the INVITE. - - - ruri (string) - Request URI and destination - of the INVITE. - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_ua_start_session \ - text/plain sip:oss@opensips.org \ - sip:alice@opensips.org sip:alice@opensips.org - -
- -
- - <function moreinfo="none">msrp_ua_list_sessions</function> - - - Lists information about ongoing MSRP sessions. - - - Name: msrp_ua_list_sessions - - Parameters - - - None. - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_ua_list_sessions - -
- -
- - <function moreinfo="none">msrp_ua_end_session</function> - - - Terminate an ongoing MSRP session. - - - Name: msrp_ua_end_session - - Parameters - - - session_id (string) - the MSRP session - identifier ("session-id" part of the MSRP URI). - - - - MI FIFO Command Format: - - -opensips-cli -x mi msrp_ua_end_session \ - 5addd9e7b74fa44fbace68a4fc562293 - -
- -
- -
- Exported Events -
- - <function moreinfo="none">E_MSRP_SESSION_NEW</function> - - - This event is triggered when a new MSRP session is successfully - established(ACK sent/received). - - Parameters: - - - from_uri - The URI in the SIP From header - of the answered INVITE. - - - to_uri - The URI in the SIP To header - of the answered INVITE. - - - ruri - The SIP Request URI of the answered - INVITE. - - - session_id - The MSRP session identifier - ("session-id" part of the MSRP URI). - - - content_types - The content types offered - by the peer in the accept-types SDP attribute. - - -
- -
- - <function moreinfo="none">E_MSRP_SESSION_END</function> - - - This event is triggered when an ongoing MSRP session is terminted (session - expires or BYE is received; terminating a session via the - msrp_ua_end_session MI function is not included). - - Parameters: - - - session_id - The MSRP session identifier - ("session-id" part of the MSRP URI). - - -
- -
- - <function moreinfo="none">E_MSRP_MSG_RECEIVED</function> - - - This event is triggered when receiving a new, non-empty MSRP SEND - request from the peer. - - Parameters: - - - session_id - The MSRP session identifier - ("session-id" part of the MSRP URI). - - - content_type - The content type of this message. - - - body - The actual message body. - - -
- -
- - <function moreinfo="none">E_MSRP_REPORT_RECEIVED</function> - - - This event is triggered when: - - - a MSRP REPORT request is received - - - a failure transaction response is received - - - a local timeout for a SEND request occured. - - - - Parameters: - - - session_id - The MSRP session identifier - ("session-id" part of the MSRP URI). - - - message_id - The value of the Message-ID - header field. - - - status - The value of the Status header field. - - - byte_range - The value of the Byte-Range header - field. - - -
- -
- -
- diff --git a/modules/msrp_ua/doc/msrp_ua_devel.xml b/modules/msrp_ua/doc/msrp_ua_devel.xml deleted file mode 100644 index a7ff2513113..00000000000 --- a/modules/msrp_ua/doc/msrp_ua_devel.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - &develguide; - -
- Overview - - In order to answer a SIP session carying MSRP the - function should be used. Conversely for starting a MSRP call as a UAC, one - can use the function. - - - After initializing the session with either of the above functions, the SIP call - will be further handled by the module and notifications regarding significant SIP - level events and received MSRP requests and responses will be delivered via - registering callback functions. - - - MSRP SEND requests can be sent with the function - after the sessions is established, which will be signaled by the - msrp_ua_notify_cb_f callback with the - MSRP_UA_SESS_ESTABLISHED event. - - - Received MSRP requests, transaction responses and local send timeouts will be - signaled via the msrp_ua_req_cb_f and - msrp_ua_rpl_cb_f callbacks. - -
- -
- Available Functions - -
- - <function moreinfo="none">init_uas(msg, accept_types, hdl)</function> - - - This function will intialize a MSRP UA session based on a received SIP - INVITE. - - Meaning of the parameters is as follows: - - - struct sip_msg *msg - the SIP message - - - - str *accept_types - the value of the - "accept-types" attribute to include in the SDP offer. - - - - struct msrp_ua_handler *hdl - handler - structure used to register the callbacks for SIP level and MSRP - level notifications. - - - - - <function>struct msrp_ua_handler</function> structure - -struct msrp_ua_handler { - /* name of this registration */ - str *name; - /* parameter to be passed to msrp_req_cb and msrp_rpl_cb callbacks */ - void *param; - /* callback for SIP level notifications */ - msrp_ua_notify_cb_f notify_cb; - /* callback for receving MSRP requests */ - msrp_ua_req_cb_f msrp_req_cb; - /* callback for receving MSRP responses */ - msrp_ua_rpl_cb_f msrp_rpl_cb; -}; - - - - <function>msrp_ua_notify_cb_f</function> prototype - -typedef int (*msrp_ua_notify_cb_f)(struct msrp_ua_notify_params *params, - void *hdl_param); - - - - <function>struct msrp_ua_notify_params</function> structure - -struct msrp_ua_notify_params { - /* event type */ - enum msrp_ua_event_type event; - /* SIP message */ - struct sip_msg *msg; - /* SDP "accept-types" attribute in case of MSRP_UA_SESS_ESTABLISHED event */ - str *accept_types; - /* MSRP UA session ID */ - str *session_id; -}; - - - - <function>enum msrp_ua_event_type</function> - -enum msrp_ua_event_type { - /* session established (ACK sent/received) */ - MSRP_UA_SESS_ESTABLISHED = 1, - /* failed to establish session (negative reply/timeout etc.) */ - MSRP_UA_SESS_FAILED, - /* BYE received/sent(in case of session timeout) */ - MSRP_UA_SESS_TERMINATED -}; - - - - <function>msrp_ua_req_cb_f</function> prototype - -typedef int (*msrp_ua_req_cb_f)(struct msrp_msg *req, void *hdl_param); - - - - <function>msrp_ua_rpl_cb_f</function> prototype - -/* an MSRP transaction timeout will be signaled by calling this callback - * with a NULL rpl parameter */ -typedef int (*msrp_ua_rpl_cb_f)(struct msrp_msg *rpl, void *hdl_param); - - -
- -
- - <function moreinfo="none">init_uac(accept_types, from_uri, to_uri, ruri, hdl)</function> - - - This function will intialize a MSRP UA session by sending a SIP INVITE to - a destination. - - Meaning of the parameters is as follows: - - - str *accept_types - the value of the - "accept-types" attribute to include in the SDP offer. - - - - str *from_uri - URI to use in the From - header of the INVITE. - - - - str *to_uri - URI to use in the To - header of the INVITE. - - - - str *ruri - Request URI to use in the for - the INVITE. - - - - struct msrp_ua_handler *hdl - handler - structure used to register the callbacks for SIP level and MSRP - level notifications. - - - -
- -
- - <function moreinfo="none">end_session(session_id)</function> - - - This function terminates an MSRP session. - - Meaning of the parameters is as follows: - - - str *session_id - MSRP UA session ID. - - - -
- -
- - <function moreinfo="none">send_message(session_id, mime, body, failure_report, success_report)</function> - - - This functions sends an MSRP SEND request to the peer. - - Meaning of the parameters is as follows: - - - str *session_id - MSRP UA session ID. - - - - str *mime - MIME content - type of this message. If NULL, an empty message will be sent. - - - - str *body - actual message - body. If NULL, an empty message will be sent. - - - - enum msrp_failure_report_type failure_report - - MSRP Failure Report type - yes, no or partial. - - - - int success_report - indication whether to - request an MSRP Failure Report or not. - - - - - <function>enum msrp_failure_report_type</function> - -enum msrp_failure_report_type { - MSRP_FAILURE_REPORT_YES, - MSRP_FAILURE_REPORT_PARTIAL, - MSRP_FAILURE_REPORT_NO -}; - - -
- -
-
diff --git a/modules/nat_traversal/README b/modules/nat_traversal/README deleted file mode 100644 index 589ddb29910..00000000000 --- a/modules/nat_traversal/README +++ /dev/null @@ -1,929 +0,0 @@ -NAT Traversal Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Keepalive functionality - - 1.2.1. Overview - 1.2.2. Background - 1.2.3. Implementation - - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. keepalive_interval (integer) - 1.4.2. keepalive_method (string) - 1.4.3. keepalive_from (string) - 1.4.4. keepalive_extra_headers (string) - 1.4.5. keepalive_state_file (string) - 1.4.6. cluster_id (integer) - 1.4.7. cluster_sharing_tag (string) - - 1.5. Exported Functions - - 1.5.1. client_nat_test(type) - 1.5.2. fix_contact() - 1.5.3. nat_keepalive() - - 1.6. Exported Statistics - - 1.6.1. keepalive_endpoints - 1.6.2. registered_endpoints - 1.6.3. subscribed_endpoints - 1.6.4. dialog_endpoints - - 1.7. Exported Pseudo-Variables - - 1.7.1. $keepalive.socket(nat_endpoint) - 1.7.2. $source_uri - 1.7.3. $nat_traversal.track_dialog - - 1.8. Keepalive use cases - - 1.8.1. Single proxy environments - 1.8.2. Registration in multi-proxy environments - 1.8.3. Subscription in multi-proxy environments - 1.8.4. Outgoing INVITEs in multi-proxy environments - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the keepalive_interval parameter - 1.2. Setting the keepalive_method parameter - 1.3. Setting the keepalive_from parameter - 1.4. Setting the keepalive_extra_headers parameter - 1.5. Setting the keepalive_state_file parameter - 1.6. Set cluster_id parameter - 1.7. Set cluster_sharing_tag parameter - 1.8. Using the client_nat_test function - 1.9. Using the fix_contact function - 1.10. Using the nat_keepalive function - 1.11. Using $keepalive.socket in multi-proxy environments - 1.12. Using $source_uri to set the received AVP on registrars - 1.13. Using $source_uri in multi-proxy environments - -Chapter 1. Admin Guide - -1.1. Overview - - The nat_traversal module provides support for handling far-end - NAT traversal for SIP signaling. The module includes - functionality to detect user agents behind NAT, to modify SIP - headers to allow user agents to work transparently behind NAT - and to send keepalive messages to user agents behind NAT in - order to preserve their visibility in the network. The module - can handle user agents behind multiple cascaded NAT boxes as - easily as user agents behind a single level of NAT. - - The module is designed to work in complex environments where - multiple SIP proxies may be involved in handling registration - and routing and where the incoming and outgoing paths may not - necessarily be the same, or where the routing path may even - change between consecutive dialogs. - -1.2. Keepalive functionality - -1.2.1. Overview - - The nat_traversal module implements a very sophisticated - keepalive mechanism, that is able to handle the most complex - environments and use cases, including distributed environments - with multiple proxies. Unlike existing keepalive solutions that - only send keepalive messages to user agents that have - registered (during their registration), the nat_traversal - module can keepalive an user agent based on multiple - conditions, making it not only more flexible and more - efficient, but also able to work in environments and with use - cases where a simple keepalive implementation based on keeping - alive registrations alone cannot work. - - The keepalive mechanism works by sending a SIP request to a - user agent behind NAT to make that user agent send back a - reply. The purpose is to have packets sent from inside the NAT - to the proxy often enough to prevent the NAT box from timing - out the connection. Many NAT boxes do not consider packets that - travel from the outside to the inside of the NAT to reset the - connection expiration timer, thus to keepalive a user agent we - need to trigger an answer from it. - -1.2.2. Background - - One of the major limitations of an implementation that only - sends keepalive messages to registered user agents, is that it - creates an artificial association between the concept of - network visibility with the concept of user registration. The - registration process only creates network visibility for - incoming INVITE requests, in other words for incoming calls. - However, there are other cases where a user agent needs to - preserve its network visibility when behind NAT, that have - nothing to do with receiving incoming calls. One of them is the - ability of the user agent to keep receiving NOTIFY requests for - a presence subscription it has made. Another situation is where - the user agent should be able to receive all messages within a - dialog it has initiated, even if it is not registered. In the - first case, a presence agent is required to register to be able - to receive notifications for its subscriptions and it has to - keep the registration active the whole time. In the second case - a user agent that wants to make an outgoing call has to - register and keep the registration active during the call, - otherwise it may not be able to receive future in-dialog - messages, including the BYE that closes the dialog. - - Not only we have this forced association shown above, that - requires a user agent to register to be able to do anything, - but a simple keepalive implementation based on sending - keepalive messages only to registered user agents, will also - fail to work in common cases, exactly because of this - artificial association. For example lets assume that we have an - user agent that is registered. If during an outgoing call - initiated by this user agent, the agent stops registering, then - it will not be able to receive further in-dialog messages after - the NAT binding expires. The same is true for a presence agent, - receiving notifications for its subscriptions. - - In environments with multiple proxies handling the same - domains, the problem gets even more acute. In this case the - incoming and outgoing paths for a call may be completely - different: the user agent may register using one proxy as an - entry point to the network, but may make an outgoing call using - a different proxy as the network entry point. Even more a - registration may use a different proxy as the entry point to - the network with each renewal of the registration, making it - volatile and unreliable for anything else except incoming - calls. A keepalive implementation that only sends keepalive - messages to registered user agents will not be able to - guarantee the delivery of in-dialog messages for outgoing calls - even if it requires the user agent to register before making a - call. In this case, even if we assume that the user agent would - pick the same proxy for an outgoing call as the one it has used - for the last registration, at the next registration it may pick - another one (as returned by DNS), and will dissociate the - incoming and outgoing paths rendering the outgoing path - unusable (assuming the outgoing call takes longer than the - registration period). - - All this leads to the conclusion that a keepalive - implementation based solely on sending keepalive messages to - registered user agents can only work in single proxy - environments and then only work reliably if it requires the - user agent to register before doing anything else, even though - some actions would not require a user agent to register. - -1.2.3. Implementation - - To avoid the above mentioned issues, this implementation - introduces the concept of network visibility for a given - condition. This way we can keepalive a user agent for multiple - independent conditions, thus avoiding all the problems - presented above. - - The conditions for which the module will send keepalive - messages are: - * Registration - for user agents that have registered to - preserve their visibility for incoming calls. This is the - result of triggering keepalive for a REGISTER request. - * Subscription - for presence agents that have subscribed to - some events to preserve their visibility for receiving back - notifications. This is the result of triggering keepalive - for a SUBSCRIBE request. - * Dialogs - for user agents that have initiated an outgoing - call to preserve their visibility for receiving further - in-dialog messages. This is the result of triggering - keepalive for an outgoing INVITE request. - - A user agent's NAT entry point may be kept alive for one or - multiple of the conditions listed above. Even when a NAT - endpoint is kept alive for more than one condition, only one - keepalive message is sent to that NAT endpoint. The presence of - multiple conditions for a NAT endpoint, only guarantees that - the network visibility for a user agent based on a certain - condition will be available while that condition is true, - independently of the other conditions. When all the conditions - to keepalive a NAT endpoint will disappear, that endpoint will - be removed from the list with the NAT endpoints that need to be - kept alive. - - The user interface for the keepalive functionality is very - simple. It consists of a single function called nat_keepalive() - that needs to be called only once for the requests that trigger - the need for network visibility. These requests are: REGISTER, - SUBSCRIBE and outgoing INVITEs. After such a request arrives it - makes the user agent visible for the purpose of receiving back - other messages. Thus, after a REGISTER the user agent may - receive back incoming calls, after a SUBSCRIBE it may receive - back notifications and after an outgoing INVITE it may receive - back further in-dialog messages including the BYE that ends the - dialog. The nat_keepalive() function needs to be called on the - proxy that directly receives the request from the user agent, - if it determines that the user agent making the request is - behind NAT. The function needs to be called before the request - gets either a stateless reply or it is relayed with t_relay(). - Calling the nat_keepalive() function has no effect if the - request gets no stateless reply or it is not relayed. - - For environments with multiple proxies, where the proxy that - acts as an entry point to the network for a given request is - not the one that actually handles the request, then the - nat_keepalive() function needs to be called on the proxy that - is the entry point and after that the request must be sent to - the proxy that actually handles the request using t_relay(). - This is needed because the keepalive functionality detects from - the stateless replies or the TM relayed replies if the NAT - endpoint needs to be kept alive for the condition triggered by - the request for which the nat_keepalive() function was called. - For example assume a network where a proxy P1 receives a - REGISTER from an user agent behind NAT. P1 will determine that - the user agent is behind NAT so it needs keepalive - functionality, but another proxy called P2 is actually handling - the subscriber registrations. In this case P1 has to call - nat_keepalive() even though it doesn't yet know the answer P2 - will give to the REGISTER request (which may even be a negative - reply) or if P2 will restrict the proposed expiration time in - any way. Thus P1 calls nat_keepalive() after which it calls - t_relay(). When the reply from P2 arrives, a callback is - triggered which will determine if the request did get a - positive reply, and if so it will extract the registration - expiration time and enable the keepalive functionality for that - endpoint for the registration condition for the time given by - the registration expiration. For single proxy environments, or - if P1 is the same as P2, then t_relay() is not called, instead - save_location() is called if the registration is accepted. Then - the same process described above happens only this time - triggered by a stateless reply callback. In both cases, calling - nat_keepalive() when the REGISTER is received has no other - effect that to trigger some callbacks that will determine from - the reply if the caller endpoint should be kept alive or not. - - Below is described how nat_keepalive() should be called and - what it does for each of the requests that need keepalive - functionality (the function should only be called if it is - determined that the user agent that generated the request is - behind NAT): - * REGISTER - called before save_location() or t_relay() - (depending on whether the proxy that received the REGISTER - is also handling registration for that subscriber or not). - It will determine from either the stateless reply generated - by save_location() or the TM relayed reply if the - registration was successful and what is its expiration - time. If the registration was successful it will mark the - given NAT endpoint for keepalive for the registration - condition using the detected expiration time. If the - REGISTER request is discarded after nat_keepalive() was - called or if it intercepts a negative reply it will have no - effect and the registration condition will not be activated - for that endpoint. - * SUBSCRIBE - called before handle_subscribe() or t_relay() - (depending on whether the proxy that received the SUBSCRIBE - is also handling subscriptions for that subscriber or not). - It will determine from either the stateless reply generated - by handle_subscribe() or the TM relayed reply if the - subscription was successful and what is its expiration - time. If the subscription was successful it will mark the - given NAT endpoint for keepalive for the subscription - condition using the detected expiration time. If the - SUBSCRIBE request is discarded after nat_keepalive() was - called or if it intercepts a negative reply it will have no - effect and the subscription condition will not be activated - for that endpoint. It should be called for every SUBSCRIBE - received, not only the ones that start a subscription (do - not have a to tag), because it needs to update (extend) the - expiration time for the subscription. - * INVITE - called before t_relay() for the first INVITE in a - dialog. It will automatically trigger dialog tracing for - that dialog and will use the dialog callbacks to detect - changes in the dialog state. It will add a keepalive entry - with the dialog condition for the caller NAT endpoint as - soon as the dialog is created (this happens when t_relay() - is called). It will then keep that condition for the given - endpoint until the dialog is destroyed (either terminated, - failed or expired). If the INVITE request cannot be relayed - after nat_keepalive() was called it will have no effect and - the dialog condition will not be activated for that - endpoint. - In addition an INVITE that starts a dialog will - automatically trigger keepalive functionality for the - destination endpoints if they are behind NAT. This is done - by detecting if any of the destination endpoints already - has a keepalive entry for the register condition. If so, a - dialog condition will be added to that entry thus - preserving that endpoint visibility even if the - registration expires during the dialog or is moved to - another proxy. During the call setup stage, multiple - entries for the callee may be added with the dialog - condition if parallel forking is used, however only the - destination endpoints behind NAT will have the extra dialog - condition set. Later when the dialog is confirmed, only the - endpoint that answered the call will keep the dialog - condition activated (if present), while all the endpoints - from the unanswered branches will have it removed. This is - done automatically without any need to call any function. - - Considering the elements presented in this section, we can say - that the nat_traversal module provides a flexible and efficient - keepalive functionality that is very easy to use. Because only - the border proxies send keepalive messages, the network traffic - is minimized. For the same reason, message processing in the - proxies is also minimized, as border proxies generate keepalive - messages themselves and send them stateless, instead of having - to relay messages generated by the registrars. Network traffic - is also minimized by only sending a single keepalive message - for an endpoint no matter for how many reasons the endpoint is - kept alive. Keepalive messages are also distributed over the - keepalive interval to avoid overloading the proxy by generating - too many messages at a time. The nat_traversal module keeps its - internal state about endpoints that need keepalive, state that - is build while messages are processed by the proxy and thus it - doesn't need to transfer any information from the usrloc - module, which should also improve its efficiency. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * sl module - if keepalive is enabled. - * tm module - if keepalive is enabled. - * dialog module - if keepalive is enabled and keeping alive - INVITE dialogs is needed. - * clusterer - only if "cluster_id" option is enabled. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. keepalive_interval (integer) - - The time interval (in seconds) required to send a keepalive - message to all the endpoints that need being kept alive. During - this interval, each endpoint will receive exactly one keepalive - message. A negative value or zero will disable the keepalive - functionality. - - Default value is “60”. - - Example 1.1. Setting the keepalive_interval parameter -... -modparam("nat_traversal", "keepalive_interval", 90) -... - -1.4.2. keepalive_method (string) - - What SIP method to use to send keepalive messages. Typical - methods used for this purpose are NOTIFY and OPTIONS. NOTIFY - generates smaller replies from user agents, but they are almost - entirely negative replies. Apparently almost none of the user - agents understand that the purpose of the NOTIFY with a - “keep-alive” event is to keep NAT open, even though many user - agents send such NOTIFY requests themselves. However this does - not affect the result at all, since the purpose is to trigger a - response from the user agent behind NAT, positive or negative - replies having little relevance as they are discarded anyway. - The OPTIONS method on the other hand has a much higher rate of - positive replies, but at the same time those positive replies - are much bigger, mostly because the OPTIONS method is used to - inform about the user agent capabilities and thus it includes a - lot of extra headers to indicate those capabilities. Many user - agents also include a SDP body with a bogus media session, - probably to indicate media capabilities. All of this makes that - positive replies to OPTIONS requests are 2 to 3 times bigger - than negative replies or replies to NOTIFY requests. For this - reason the default value for the used method is NOTIFY. - - Default value is “NOTIFY”. - - Example 1.2. Setting the keepalive_method parameter -... -modparam("nat_traversal", "keepalive_method", "OPTIONS") -... - -1.4.3. keepalive_from (string) - - Indicates what SIP URI to use in the From header of the - keepalive requests. If not specified it will use - sip:keepalive@proxy_ip, where proxy_ip is the IP address of the - outgoing interface used to send the keepalive message, which is - the same interface on which the request that triggered - keepalive functionality arrived. - - Default value is “sip:keepalive@proxy_ip” with proxy_ip being - the actual IP of the outgoing interface. - - Example 1.3. Setting the keepalive_from parameter -... -modparam("nat_traversal", "keepalive_from", "sip:keepalive@my-domain.com -") -... - -1.4.4. keepalive_extra_headers (string) - - Specifies extra headers that should be added to the keepalive - messages that are sent by the proxy. The header specification - must also include the CRLF (\r\n) line separator. Multiple - headers can be specified by concatenating them and each of them - must include the \r\n separator. - - Default value is undefined (send no extra headers). - - Example 1.4. Setting the keepalive_extra_headers parameter -... -modparam("nat_traversal", "keepalive_extra_headers", "User-Agent: OpenSI -PS\r\nX-MyHeader: some_value\r\n") -... - -1.4.5. keepalive_state_file (string) - - Specifies a filename where information about the NAT endpoints - and the conditions for which they are being kept alive is saved - when OpenSIPS exits. The information in this file is then used - when OpenSIPS starts to restore its internal state and continue - to send keepalive messages to the NAT endpoints that have not - expired in the meantime. This is useful when restarting - OpenSIPS to avoid losing keepalive state information about the - NAT endpoints. The internal keepalive state is guaranteed to be - saved in this file on exit, even when OpenSIPS crashes. - - The value of this parameter can be either a relative path, in - which case it will store it in the OpenSIPS working directory, - or an absolute path. - - Default value is undefined “keepalive_state”. - - Example 1.5. Setting the keepalive_state_file parameter -... -modparam("nat_traversal", "keepalive_state_file", "/run/opensips/keepali -ve_state") -... - -1.4.6. cluster_id (integer) - - The ID of the cluster the module is part of. The clustering - support is used by the nat_traversal module for controlling the - pinging process. When part of a cluster of multiple nodes, the - nodes can agree upon which node is the one responsible for - pinging. - - The clustering with sharing tag support may be used to control - which node in the cluster will perform the pinging/probing to - the contacts. See the cluster_sharing_tag option. - - For more info on how to define and populate a cluster (with - OpenSIPS nodes) see the "clusterer" module. - - Default value is “0 (none)”. - - Example 1.6. Set cluster_id parameter -... -# Be part of cluster ID 9 -modparam("nat_traversal", "cluster_id", 9) -... - -1.4.7. cluster_sharing_tag (string) - - The name of the sharing tag (as defined per clusterer modules) - to control which node is responsible for perform pinging of the - contacts. If defined, only the node with active status of this - tag will perform the pinging. - - The cluster_id must be defined for this option to work. - - This is an optional parameter. If not set, all the nodes in the - cluster will individually do the pinging. - - Default value is “empty (none)”. - - Example 1.7. Set cluster_sharing_tag parameter -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("nat_traversal", "cluster_id", 9) -modparam("nat_traversal", "cluster_sharing_tag", "vip") -... - -1.5. Exported Functions - -1.5.1. client_nat_test(type) - - Check if the client is behind NAT. What tests are performed is - specified by the type parameter which is an integer given by - the sum of the numbers corresponding to the tests that one - wishes to perform. The numbers corresponding to individual - tests are shown below: - - * 1 - tests if client has a private IP address (as defined by - RFC1918) in the Contact field of the SIP message. - * 2 - tests if client has contacted OpenSIPS from an address - that is different from the one in the Via field. Both the - IP and port are compared by this test. - * 4 - tests if client has a private IP address (as defined by - RFC1918) in the top Via field of the SIP message. - * 8 - tests if client has contacted OpenSIPS from an address - that is different from the one in the Contact field. Only - IP is compared by this test. - - For example calling client_nat_test(3) will perform test 1 and - test 2 and return true if at least one succeeds, otherwise - false. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.8. Using the client_nat_test function -... -if (client_nat_test(3)) { - ..... -} -... - -1.5.2. fix_contact() - - Will replace the IP and port in the Contact header with the IP - and port the SIP message was received from. Usually called - after a successful call to client_nat_test(type) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE. - - Example 1.9. Using the fix_contact function -... -if (client_nat_test(3)) { - fix_contact(); -} -... - -1.5.3. nat_keepalive() - - Trigger keepalive functionality for the source address of the - request. When called it only sets some internal flags, which - will trigger later the addition of the endpoint to the - keepalive list if a positive reply is generated/received (for - REGISTER and SUBSCRIBE) or when the dialog is started/replied - (for INVITEs). For this reason, it can be called early or late - in the script. The only condition is to call it before replying - to the request or before sending it to another proxy. If the - request needs to be sent to another proxy, t_relay() must be - used to be able to intercept replies via TM or dialog - callbacks. If stateless forwarding is used, the keepalive - functionality will not work. Also for outgoing INVITEs, - record_route() should also be used to make sure the proxy that - keeps the caller endpoint alive stays in the path. For - multi-proxy setups, this function should always be called on - the border proxies (the ones that received the request directly - from the user agent). For more details about this function, see - the Implementation subsection from the Keepalive functionality - section. - - This function can be used from REQUEST_ROUTE. - - Example 1.10. Using the nat_keepalive function -... -if (($rm=="REGISTER" || $rm=="SUBSCRIBE" || - ($rm=="INVITE" && !has_totag())) && client_nat_test(3)) -{ - nat_keepalive(); -} -... - -1.6. Exported Statistics - -1.6.1. keepalive_endpoints - - Indicates the total number of NAT endpoints that are being kept - alive. - -1.6.2. registered_endpoints - - Indicates how many of the NAT endpoints are kept alive for - registrations. - -1.6.3. subscribed_endpoints - - Indicates how many of the NAT endpoints are kept alive for - subscriptions. - -1.6.4. dialog_endpoints - - Indicates how many of the NAT endpoints are kept alive for - taking part in an INVITE dialog. - -1.7. Exported Pseudo-Variables - -1.7.1. $keepalive.socket(nat_endpoint) - - Returns the local socket used to send messages to the given NAT - endpoint URI. The socket has the form proto:ip:port. The NAT - endpoint URI is in the form: sip:ip:port[;transport=xxx] with - transport missing if UDP. If the requested NAT endpoint URI is - present in the internal keepalive table for any condition, it - will return its associated local socket, else it will return - null. The nat_endpoint can be a string or another - pseudo-variable. - - This can be useful to restore the sending socket when relaying - messages to a given user agent in multi-proxy environments. - Consider an example where 2 proxies are involved, P1 and P2. A - user agent registers by sending a REGISTER request to P1. P1 - will call nat_keepalive() but because it determines that P2 - should actually handle the user registration will forward the - request to P2. Now assume P2 receives an incoming INVITE for - this user. It will determine that the registration came through - P1 and will forward the request to P1. P2 should also include - the NAT endpoint URI where this request is to be relayed. This - information should have been provided by P1 when it relayed the - REGISTER request to P2. The means to do this is out of the - scope of this example, but one can either use the path - extension or custom headers to do this. When P1 receives the - INVITE it will use the NAT endpoint URI it has received along - with the request to determine the socket to send out the - request, which should be the same as the one where the - registration request was originally received. In the example - below lets assume that P2 provided the original NAT endpoint - address in a custom header called X-NAT-URI and that it also - provides a custom header called X-Scope to indicate that the - message is sent to P1 for being relayed back to the user agent - by P1 which has the NAT open with it. - - Example 1.11. Using $keepalive.socket in multi-proxy - environments -... -# This code runs on P1 which has received an INVITE from P2 to forward -# it to the user agent behind NAT (because P1 has the NAT open with it). -if ($rm=="INVITE" && $hdr(X-Scope)=="nat-relay") { - $du = $hdr(X-NAT-URI); - $fs = $keepalive.socket($du); - t_relay(); - exit; -} -... - -1.7.2. $source_uri - - Returns the URI specification from where a request was received - in the form sip:ip:port[;transport=xxx] with transport missing - if UDP. - - This pseudo-variable can be used to set the received AVP for - the registrar module to indicate that a user agent is behind - NAT. This is meant as a more flexible replacement for the - fix_nated_register() function, because it allows one to modify - the source uri by appending some extra parameters before saving - it to the received AVP. - - Another use for this pseudo-variable is in multi-proxy - environments to indicate the NAT endpoint URI to the next proxy - (if needed). Consider the previous example with two proxies P1 - and P2. P1 receives the REGISTER request from a user agent and - forwards it to P2 which does the actual registration. P1 needs - to indicate the NAT endpoint URI to P2, so that P2 can include - it later for incoming INVITE requests to this user agent. - - Example 1.12. Using $source_uri to set the received AVP on - registrars -... -modparam("registrar", "received_avp", "$avp(received_uri)") -modparam("registrar", "tcp_persistent_flag", 10) -... -# This code runs on the registrar, assuming it has received the -# REGISTER request directly from the user agent. -if ($rm=="REGISTER") { - if (client_nat_test(3)) { - if ($socket_in(proto)==UDP) { - nat_keepalive(); - } else { - # Keep TCP/TLS connections open until the registration - # expires, by setting the tcp_persistent_flag - setflag(10); - } - force_rport(); - $avp(received_uri) = $source_uri; - # or we could add some extra parameters to it if needed - # $avp(received_uri) = $source_uri + ";relayed=false" - } - if (!www_authorize("", "subscriber")) { - www_challenge("", "0"); - return; - } else if ($au!=$tU) { - sl_send_reply("403", "Username!=To not allowed ($au!=$tU)"); - return; - } - - if (!save("location")) { - sl_reply_error(); - } - exit; -} -... - - Example 1.13. Using $source_uri in multi-proxy environments -... -# This code runs on P1 which received the REGISTER request and has to -# forward it to the registrar P2. -if ($rm=="REGISTER") { - if (client_nat_test(3)) { - force_rport(); - nat_keepalive(); - append_hf("X-NAT-URI: $source_uri\r\n"); - } - $du = "sip:P2_ip:P2_port"; - t_relay(); - exit; -} -... - -1.7.3. $nat_traversal.track_dialog - - Returns a boolean value (0 or 1) indicating if dialog tracking - will be enabled by the nat_traversal module. The nat_traversal - module will always track the dialog (by calling create_dialog - internally) unless told otherwise. - - This is an advanced setting which is only meant to be used by - multi-proxy setups where a proxy doesn't want to keep track of - a dialog, that is, if it won't stay in the signaling path. - - By setting this pv to 0 the nat_traversal module will not - attempt to create the dialog. - -1.8. Keepalive use cases - -1.8.1. Single proxy environments - - In this case the usage is straight forward. The nat_keepalive() - function needs to be called before save_location() for REGISTER - requests, before handle_subscribe() for SUBSCRIBE requests and - before t_relay() for the first INVITE of a dialog. - -1.8.2. Registration in multi-proxy environments - - If the proxy receiving the REGISTER request is the same as the - proxy handling it, then the case is reduced to the single proxy - case. For this example, lets assume they are different. We have - a user agent UA1 for which the registration is handled by the - proxy P1. However UA1 sends the REGISTER to P0 which in turn - forwards it to P1 like this: UA1 --> P0 --> P1. In this case P0 - calls nat_keepalive(), adds the NAT endpoint URI to the request - (for example using a custom header) and forwards the request to - P1. P1 will save the user in the user location together with - the NAT endpoint URI. - - When an incoming INVITE request arrives on P1 for UA1, P1, will - lookup the location and determine that it has to relay it to P0 - because P0 has the NAT open with UA1. P1 will include the - original NAT endpoint URI in the request and an indication that - the only role P0 has in this transaction is to relay it to UA1. - P0 will receive this request and determine that is has to act - as a relay for it. It will extract the NAT endpoint URI, then - based on it the corresponding local socket using - $keepalive.socket(endpoint_uri). It will then set both $du and - $fs to the values it has found, call record_route() to stay in - the path and call t_relay() to send it to UA1. - - Handling other type of requests (like for example SUBSCRIBE or - MESSAGE) that arrive on P1 for UA1 is done the same way as with - the first INVITE, on both P1 and P0. - -1.8.3. Subscription in multi-proxy environments - - If the proxy receiving the SUBSCRIBE request is the same as the - proxy handling it, then the case is reduced to the single proxy - case. For this example, lets assume they are different. We have - a user agent UA1 for which subscriptions are handled by the - proxy P1. However UA1 sends the SUBSCRIBE to P0 which in turn - forwards it to P1 like this: UA1 --> P0 --> P1. In this case P0 - calls nat_keepalive(), then calls record_route() to stay in the - path and forwards the request to P1 using t_relay(). Further - SUBSCRIBE and NOTIFY requests will follow the record route and - use P0 as a NAT entry point to have access to UA1. Further - in-dialog SUBSCRIBE requests should also call record_route(). - -1.8.4. Outgoing INVITEs in multi-proxy environments - - If the proxy receiving the INVITE request is the same as the - proxy handling it, then the case is reduced to the single proxy - case. For this example, lets assume they are different. We have - a user agent UA1 which is handled by the proxy P1 and UA2 which - is handled by P2. UA2 has registered with P2 going through P3, - while UA1 calls UA2 by sending the first INVITE to P0. The call - flow for the first INVITE looks like this: UA1 --> P0 --> P1 - --> P2 --> P3 --> UA2. In this case P0 calls nat_keepalive(), - then calls record_route() to stay in the path and forwards the - request to P1. P1 authenticates UA1 then forwards the request - to P2, which is the home proxy for UA2. P1 doesn't have to use - record_route to stay in the path, but it can do that if needed - for other purposes. P2 will lookup UA2 and find out that it is - reachable through P3. It will take the original NAT endpoint - URI that is has saved in the user location when UA2 has - registered and include it in the message along with an - indication that P3 only has to relay the message to UA2. If P2 - does accounting or starts a media relay, it should also call - record_route() to stay in the path. Then it forwards the - request to P3 using t_relay(). P3 will detect that it only has - to relay the request to UA2 because it has the NAT open with - it. It will extract the NAT endpoint URI from the message and - the local sending socket using $keepalive.socket(endpoint_uri) - and will set both $du and $fs. After that it will call - record_route() to stay in the path, and forward the request to - UA2 using t_relay(). Further in-dialog requests will follow the - recorded route and use P0 and P3 as access points to UA1 - respectively UA2. All the proxies that have used record_route() - during the first INVITE should also call record_route() during - further in-dialog requests to keep staying in the path. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Dan Pascu (@danpascu) 54 26 3085 115 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 37 31 306 128 - 3. Liviu Chircu (@liviuchircu) 19 16 61 84 - 4. Razvan Crainea (@razvancrainea) 9 7 11 6 - 5. Saúl Ibarra Corretgé (@saghul) 9 5 188 102 - 6. Vlad Patrascu (@rvlad-patrascu) 7 5 27 16 - 7. Maksym Sobolyev (@sobomax) 7 5 15 16 - 8. Vlad Paiu (@vladpaiu) 5 3 12 14 - 9. Anca Vamanu 4 2 12 1 - 10. Alexandra Titoc 4 2 6 2 - - All remaining contributors: Peter Lemenkov (@lemenkov), David - Sanders, Stéphane Alnet (@shimaore), okhowang, Sergio - Gutierrez, Alexey Vasilyev (@vasilevalex). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2023 - 5. okhowang Mar 2023 - Mar 2023 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Apr 2022 - 7. Alexey Vasilyev (@vasilevalex) Mar 2022 - Mar 2022 - 8. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2008 - Apr 2020 - 9. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 10. Dan Pascu (@danpascu) May 2008 - Aug 2019 - - All remaining contributors: Saúl Ibarra Corretgé (@saghul), - David Sanders, Vlad Paiu (@vladpaiu), Anca Vamanu, Stéphane - Alnet (@shimaore), Sergio Gutierrez. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Alexey Vasilyev (@vasilevalex), Bogdan-Andrei - Iancu (@bogdan-iancu), Dan Pascu (@danpascu), Liviu Chircu - (@liviuchircu), Peter Lemenkov (@lemenkov), Vlad Patrascu - (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Saúl Ibarra - Corretgé (@saghul). - - Documentation Copyrights: - - Copyright © 2008 Dan Pascu diff --git a/modules/nat_traversal/README.md b/modules/nat_traversal/README.md new file mode 100644 index 00000000000..37fabc34303 --- /dev/null +++ b/modules/nat_traversal/README.md @@ -0,0 +1,869 @@ +--- +title: "NAT Traversal Module" +description: "The nat_traversal module provides support for handling far-end NAT traversal for SIP signaling." +--- + +## Admin Guide + + +### Overview + + +The nat_traversal module provides support for handling far-end NAT +traversal for SIP signaling. The module includes functionality to +detect user agents behind NAT, to modify SIP headers to allow user +agents to work transparently behind NAT and to send keepalive messages +to user agents behind NAT in order to preserve their visibility in the +network. The module can handle user agents behind multiple cascaded +NAT boxes as easily as user agents behind a single level of NAT. + + +The module is designed to work in complex environments where multiple +SIP proxies may be involved in handling registration and routing and +where the incoming and outgoing paths may not necessarily be the same, +or where the routing path may even change between consecutive dialogs. + + +### Keepalive functionality + + +#### Overview + + +The nat_traversal module implements a very sophisticated keepalive +mechanism, that is able to handle the most complex environments and +use cases, including distributed environments with multiple proxies. +Unlike existing keepalive solutions that only send keepalive messages +to user agents that have registered (during their registration), the +nat_traversal module can keepalive an user agent based on multiple +conditions, making it not only more flexible and more efficient, but +also able to work in environments and with use cases where a simple +keepalive implementation based on keeping alive registrations alone +cannot work. + + +The keepalive mechanism works by sending a SIP request to a user agent +behind NAT to make that user agent send back a reply. The purpose is +to have packets sent from inside the NAT to the proxy often enough to +prevent the NAT box from timing out the connection. Many NAT boxes do +not consider packets that travel from the outside to the inside of the +NAT to reset the connection expiration timer, thus to keepalive a user +agent we need to trigger an answer from it. + + +#### Background + + +One of the major limitations of an implementation that only sends +keepalive messages to registered user agents, is that it creates an +artificial association between the concept of network visibility with +the concept of user registration. The registration process only creates +network visibility for incoming INVITE requests, in other words for +incoming calls. However, there are other cases where a user agent needs +to preserve its network visibility when behind NAT, that have nothing +to do with receiving incoming calls. One of them is the ability of the +user agent to keep receiving NOTIFY requests for a presence subscription +it has made. Another situation is where the user agent should be able +to receive all messages within a dialog it has initiated, even if it is +not registered. In the first case, a presence agent is required to +register to be able to receive notifications for its subscriptions and +it has to keep the registration active the whole time. In the second +case a user agent that wants to make an outgoing call has to register +and keep the registration active during the call, otherwise it may +not be able to receive future in-dialog messages, including the BYE +that closes the dialog. + + +Not only we have this forced association shown above, that requires a +user agent to register to be able to do anything, but a simple keepalive +implementation based on sending keepalive messages only to registered +user agents, will also fail to work in common cases, exactly because of +this artificial association. For example lets assume that we have an +user agent that is registered. If during an outgoing call initiated by +this user agent, the agent stops registering, then it will not be able +to receive further in-dialog messages after the NAT binding expires. +The same is true for a presence agent, receiving notifications for its +subscriptions. + + +In environments with multiple proxies handling the same domains, the +problem gets even more acute. In this case the incoming and outgoing +paths for a call may be completely different: the user agent may +register using one proxy as an entry point to the network, but may +make an outgoing call using a different proxy as the network entry +point. Even more a registration may use a different proxy as the entry +point to the network with each renewal of the registration, making it +volatile and unreliable for anything else except incoming calls. +A keepalive implementation that only sends keepalive messages to +registered user agents will not be able to guarantee the delivery of +in-dialog messages for outgoing calls even if it requires the user +agent to register before making a call. In this case, even if we +assume that the user agent would pick the same proxy for an outgoing +call as the one it has used for the last registration, at the next +registration it may pick another one (as returned by DNS), and will +dissociate the incoming and outgoing paths rendering the outgoing +path unusable (assuming the outgoing call takes longer than the +registration period). + + +All this leads to the conclusion that a keepalive implementation based +solely on sending keepalive messages to registered user agents can only +work in single proxy environments and then only work reliably if it +requires the user agent to register before doing anything else, even +though some actions would not require a user agent to register. + + +#### Implementation + + +To avoid the above mentioned issues, this implementation introduces +the concept of network visibility for a given condition. This way we +can keepalive a user agent for multiple independent conditions, thus +avoiding all the problems presented above. + + +The conditions for which the module will send keepalive messages are: + + +- *Registration* - for user agents that have +registered to preserve their visibility for incoming calls. This +is the result of triggering keepalive for a REGISTER request. +- *Subscription* - for presence agents that +have subscribed to some events to preserve their visibility for +receiving back notifications. This is the result of triggering +keepalive for a SUBSCRIBE request. +- *Dialogs* - for user agents that have +initiated an outgoing call to preserve their visibility for +receiving further in-dialog messages. This is the result of +triggering keepalive for an outgoing INVITE request. + + +A user agent's NAT entry point may be kept alive for one or multiple +of the conditions listed above. Even when a NAT endpoint is kept alive +for more than one condition, only one keepalive message is sent to +that NAT endpoint. The presence of multiple conditions for a NAT +endpoint, only guarantees that the network visibility for a user agent +based on a certain condition will be available while that condition is +true, independently of the other conditions. When all the conditions +to keepalive a NAT endpoint will disappear, that endpoint will be +removed from the list with the NAT endpoints that need to be kept +alive. + + +The user interface for the keepalive functionality is very simple. It +consists of a single function called nat_keepalive() that needs to be +called only once for the requests that trigger the need for network +visibility. These requests are: REGISTER, SUBSCRIBE and outgoing +INVITEs. After such a request arrives it makes the user agent visible +for the purpose of receiving back other messages. Thus, after a +REGISTER the user agent may receive back incoming calls, after a +SUBSCRIBE it may receive back notifications and after an outgoing +INVITE it may receive back further in-dialog messages including the +BYE that ends the dialog. The nat_keepalive() function needs to be +called on the proxy that directly receives the request from the user +agent, if it determines that the user agent making the request is +behind NAT. The function needs to be called before the request gets +either a stateless reply or it is relayed with t_relay(). Calling the +nat_keepalive() function has no effect if the request gets no stateless +reply or it is not relayed. + + +For environments with multiple proxies, where the proxy that acts as +an entry point to the network for a given request is not the one that +actually handles the request, then the nat_keepalive() function needs +to be called on the proxy that is the entry point and after that the +request must be sent to the proxy that actually handles the request +using t_relay(). This is needed because the keepalive functionality +detects from the stateless replies or the TM relayed replies if the +NAT endpoint needs to be kept alive for the condition triggered by +the request for which the nat_keepalive() function was called. +For example assume a network where a proxy P1 receives a REGISTER +from an user agent behind NAT. P1 will determine that the user agent +is behind NAT so it needs keepalive functionality, but another proxy +called P2 is actually handling the subscriber registrations. In this +case P1 has to call nat_keepalive() even though it doesn't yet know +the answer P2 will give to the REGISTER request (which may even be a +negative reply) or if P2 will restrict the proposed expiration time +in any way. Thus P1 calls nat_keepalive() after which it calls +t_relay(). When the reply from P2 arrives, a callback is triggered +which will determine if the request did get a positive reply, and if +so it will extract the registration expiration time and enable the +keepalive functionality for that endpoint for the registration +condition for the time given by the registration expiration. +For single proxy environments, or if P1 is the same as P2, then +t_relay() is not called, instead save_location() is called if the +registration is accepted. Then the same process described above +happens only this time triggered by a stateless reply callback. +In both cases, calling nat_keepalive() when the REGISTER is received +has no other effect that to trigger some callbacks that will determine +from the reply if the caller endpoint should be kept alive or not. + + +Below is described how nat_keepalive() should be called and what it +does for each of the requests that need keepalive functionality (the +function should only be called if it is determined that the user agent +that generated the request is behind NAT): + + +- *REGISTER* - called before save_location() or +t_relay() (depending on whether the proxy that received the +REGISTER is also handling registration for that subscriber or +not). It will determine from either the stateless reply +generated by save_location() or the TM relayed reply if the +registration was successful and what is its expiration time. If +the registration was successful it will mark the given NAT +endpoint for keepalive for the registration condition using the +detected expiration time. If the REGISTER request is discarded +after nat_keepalive() was called or if it intercepts a negative +reply it will have no effect and the registration condition will +not be activated for that endpoint. +- *SUBSCRIBE* - called before handle_subscribe() +or t_relay() (depending on whether the proxy that received the +SUBSCRIBE is also handling subscriptions for that subscriber or +not). It will determine from either the stateless reply +generated by handle_subscribe() or the TM relayed reply if the +subscription was successful and what is its expiration time. If +the subscription was successful it will mark the given NAT +endpoint for keepalive for the subscription condition using the +detected expiration time. If the SUBSCRIBE request is discarded +after nat_keepalive() was called or if it intercepts a negative +reply it will have no effect and the subscription condition will +not be activated for that endpoint. It should be called for +every SUBSCRIBE received, not only the ones that start a +subscription (do not have a to tag), because it needs to update +(extend) the expiration time for the subscription. +- *INVITE* - called before t_relay() for the +first INVITE in a dialog. It will automatically trigger dialog +tracing for that dialog and will use the dialog callbacks to +detect changes in the dialog state. It will add a keepalive +entry with the dialog condition for the caller NAT endpoint as +soon as the dialog is created (this happens when t_relay() is +called). It will then keep that condition for the given endpoint +until the dialog is destroyed (either terminated, failed or +expired). If the INVITE request cannot be relayed after +nat_keepalive() was called it will have no effect and the +dialog condition will not be activated for that endpoint. +In addition an INVITE that starts a dialog will automatically +trigger keepalive functionality for the destination endpoints +if they are behind NAT. This is done by detecting if any of the +destination endpoints already has a keepalive entry for the +register condition. If so, a dialog condition will be added to +that entry thus preserving that endpoint visibility even if the +registration expires during the dialog or is moved to another +proxy. During the call setup stage, multiple entries for the +callee may be added with the dialog condition if parallel +forking is used, however only the destination endpoints behind +NAT will have the extra dialog condition set. Later when the +dialog is confirmed, only the endpoint that answered the call +will keep the dialog condition activated (if present), while all +the endpoints from the unanswered branches will have it removed. +This is done automatically without any need to call any function. + + +Considering the elements presented in this section, we can say that +the nat_traversal module provides a flexible and efficient keepalive +functionality that is very easy to use. Because only the border +proxies send keepalive messages, the network traffic is minimized. +For the same reason, message processing in the proxies is also +minimized, as border proxies generate keepalive messages themselves +and send them stateless, instead of having to relay messages +generated by the registrars. Network traffic is also minimized by only +sending a single keepalive message for an endpoint no matter for how +many reasons the endpoint is kept alive. Keepalive messages are also +distributed over the keepalive interval to avoid overloading the +proxy by generating too many messages at a time. The nat_traversal +module keeps its internal state about endpoints that need keepalive, +state that is build while messages are processed by the proxy and +thus it doesn't need to transfer any information from the usrloc +module, which should also improve its efficiency. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *sl* module - if keepalive is enabled. +- *tm* module - if keepalive is enabled. +- *dialog* module - if keepalive is enabled +and keeping alive INVITE dialogs is needed. +- *clusterer* - only if "cluster_id" +option is enabled. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### keepalive_interval (integer) + + +The time interval (in seconds) required to send a keepalive message to +all the endpoints that need being kept alive. During this interval, +each endpoint will receive exactly one keepalive message. A negative +value or zero will disable the keepalive functionality. + + +*Default value is "60".* + + +```opensips title="Setting the keepalive_interval parameter" +... +modparam("nat_traversal", "keepalive_interval", 90) +... + +``` + + +#### keepalive_method (string) + + +What SIP method to use to send keepalive messages. Typical methods +used for this purpose are NOTIFY and OPTIONS. NOTIFY generates smaller +replies from user agents, but they are almost entirely negative replies. +Apparently almost none of the user agents understand that the purpose +of the NOTIFY with a "keep-alive" event is to keep NAT +open, even though many user agents send such NOTIFY requests themselves. +However this does not affect the result at all, since the purpose is +to trigger a response from the user agent behind NAT, positive or +negative replies having little relevance as they are discarded anyway. +The OPTIONS method on the other hand has a much higher rate of positive +replies, but at the same time those positive replies are much bigger, +mostly because the OPTIONS method is used to inform about the user +agent capabilities and thus it includes a lot of extra headers to +indicate those capabilities. Many user agents also include a SDP body +with a bogus media session, probably to indicate media capabilities. +All of this makes that positive replies to OPTIONS requests are 2 to +3 times bigger than negative replies or replies to NOTIFY requests. +For this reason the default value for the used method is NOTIFY. + + +*Default value is "NOTIFY".* + + +```opensips title="Setting the keepalive_method parameter" +... +modparam("nat_traversal", "keepalive_method", "OPTIONS") +... + +``` + + +#### keepalive_from (string) + + +Indicates what SIP URI to use in the From header of the keepalive +requests. If not specified it will use sip:keepalive@proxy_ip, where +proxy_ip is the IP address of the outgoing interface used to send the +keepalive message, which is the same interface on which the request +that triggered keepalive functionality arrived. + + +*Default value is "sip:keepalive@proxy_ip" with proxy_ip +being the actual IP of the outgoing interface.* + + +```opensips title="Setting the keepalive_from parameter" +... +modparam("nat_traversal", "keepalive_from", "sip:keepalive@my-domain.com") +... + +``` + + +#### keepalive_extra_headers (string) + + +Specifies extra headers that should be added to the keepalive messages +that are sent by the proxy. The header specification must also include +the CRLF (\r\n) line separator. Multiple headers can be specified by +concatenating them and each of them must include the \r\n separator. + + +*Default value is undefined (send no extra headers).* + + +```opensips title="Setting the keepalive_extra_headers parameter" +... +modparam("nat_traversal", "keepalive_extra_headers", "User-Agent: OpenSIPS\r\nX-MyHeader: some_value\r\n") +... + +``` + + +#### keepalive_state_file (string) + + +Specifies a filename where information about the NAT endpoints and the +conditions for which they are being kept alive is saved when OpenSIPS +exits. The information in this file is then used when OpenSIPS starts +to restore its internal state and continue to send keepalive messages +to the NAT endpoints that have not expired in the meantime. This is +useful when restarting OpenSIPS to avoid losing keepalive state +information about the NAT endpoints. The internal keepalive state is +guaranteed to be saved in this file on exit, even when OpenSIPS +crashes. + + +The value of this parameter can be either a relative path, in which +case it will store it in the OpenSIPS working directory, or an +absolute path. + + +*Default value is undefined "keepalive_state".* + + +```opensips title="Setting the keepalive_state_file parameter" +... +modparam("nat_traversal", "keepalive_state_file", "/run/opensips/keepalive_state") +... + +``` + + +#### cluster_id (integer) + + +The ID of the cluster the module is part of. The clustering support is +used by the nat_traversal module for controlling the pinging process. +When part of a cluster of multiple nodes, the nodes can agree upon which +node is the one responsible for pinging. + + +The clustering with sharing tag support may be used to control which +node in the cluster will perform the pinging/probing to the +contacts. See the +[cluster sharing tag](#param_cluster_sharing_tag) option. + + +For more info on how to define and populate a cluster (with OpenSIPS +nodes) see the "clusterer" module. + + +*Default value is "0 (none)".* + + +```opensips title="Set cluster_id parameter" +... +# Be part of cluster ID 9 +modparam("nat_traversal", "cluster_id", 9) +... +``` + + +#### cluster_sharing_tag (string) + + +The name of the sharing tag (as defined per clusterer modules) to +control which node is responsible for perform pinging of the +contacts. +If defined, only the node with active status of this tag will +perform the pinging. + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +This is an optional parameter. If not set, all the nodes in the cluster +will individually do the pinging. + + +*Default value is "empty (none)".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +modparam("nat_traversal", "cluster_id", 9) +modparam("nat_traversal", "cluster_sharing_tag", "vip") +... +``` + + +### Exported Functions + + +#### client_nat_test(type) + + +Check if the client is behind NAT. What tests are performed is +specified by the type parameter which is an integer given by the sum +of the numbers corresponding to the tests that one wishes to perform. +The numbers corresponding to individual tests are shown below: + + +- 1 - tests if client has a private IP address (as defined by RFC1918) +in the Contact field of the SIP message. +- 2 - tests if client has contacted OpenSIPS from an address that +is different from the one in the Via field. Both the IP and +port are compared by this test. +- 4 - tests if client has a private IP address (as defined by RFC1918) +in the top Via field of the SIP message. +- 8 - tests if client has contacted OpenSIPS from an address that +is different from the one in the Contact field. Only IP is +compared by this test. + + +For example calling client_nat_test(3) will perform test 1 and +test 2 and return true if at least one succeeds, otherwise false. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="Using the client_nat_test function" +... +if (client_nat_test(3)) { + ..... +} +... + +``` + + +#### fix_contact() + + +Will replace the IP and port in the Contact header with the +IP and port the SIP message was received from. Usually called +after a successful call to client_nat_test(type) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. + + +```opensips title="Using the fix_contact function" +... +if (client_nat_test(3)) { + fix_contact(); +} +... + +``` + + +#### nat_keepalive() + + +Trigger keepalive functionality for the source address of the request. +When called it only sets some internal flags, which will trigger +later the addition of the endpoint to the keepalive list if a +positive reply is generated/received (for REGISTER and SUBSCRIBE) +or when the dialog is started/replied (for INVITEs). +For this reason, it can be called early or late in the script. The +only condition is to call it before replying to the request or before +sending it to another proxy. If the request needs to be sent to +another proxy, t_relay() must be used to be able to intercept replies +via TM or dialog callbacks. If stateless forwarding is used, the +keepalive functionality will not work. Also for outgoing INVITEs, +record_route() should also be used to make sure the proxy that keeps +the caller endpoint alive stays in the path. For multi-proxy setups, +this function should always be called on the border proxies (the ones +that received the request directly from the user agent). For more +details about this function, see the *Implementation* +subsection from the *Keepalive functionality* section. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Using the nat_keepalive function" +... +if (($rm=="REGISTER" || $rm=="SUBSCRIBE" || + ($rm=="INVITE" && !has_totag())) && client_nat_test(3)) +{ + nat_keepalive(); +} +... + +``` + + +### Exported Statistics + + +#### keepalive_endpoints + + +Indicates the total number of NAT endpoints that are being kept alive. + + +#### registered_endpoints + + +Indicates how many of the NAT endpoints are kept alive for registrations. + + +#### subscribed_endpoints + + +Indicates how many of the NAT endpoints are kept alive for subscriptions. + + +#### dialog_endpoints + + +Indicates how many of the NAT endpoints are kept alive for taking part +in an INVITE dialog. + + +### Exported Pseudo-Variables + + +#### $keepalive.socket(nat_endpoint) + + +Returns the local socket used to send messages to the given NAT +endpoint URI. The socket has the form proto:ip:port. The NAT endpoint +URI is in the form: sip:ip:port[;transport=xxx] with transport missing +if UDP. If the requested NAT endpoint URI is present in the internal +keepalive table for any condition, it will return its associated local +socket, else it will return null. The nat_endpoint can be a string or +another pseudo-variable. + + +This can be useful to restore the sending socket when relaying messages +to a given user agent in multi-proxy environments. Consider an example +where 2 proxies are involved, P1 and P2. A user agent registers by +sending a REGISTER request to P1. P1 will call nat_keepalive() but +because it determines that P2 should actually handle the user +registration will forward the request to P2. Now assume P2 receives an +incoming INVITE for this user. It will determine that the registration +came through P1 and will forward the request to P1. P2 should also +include the NAT endpoint URI where this request is to be relayed. +This information should have been provided by P1 when it relayed the +REGISTER request to P2. The means to do this is out of the scope of +this example, but one can either use the path extension or custom +headers to do this. When P1 receives the INVITE it will use the NAT +endpoint URI it has received along with the request to determine the +socket to send out the request, which should be the same as the one +where the registration request was originally received. In the example +below lets assume that P2 provided the original NAT endpoint address +in a custom header called X-NAT-URI and that it also provides a custom +header called X-Scope to indicate that the message is sent to P1 for +being relayed back to the user agent by P1 which has the NAT open +with it. + + +```opensips title="Using $keepalive.socket in multi-proxy environments" +... +# This code runs on P1 which has received an INVITE from P2 to forward +# it to the user agent behind NAT (because P1 has the NAT open with it). +if ($rm=="INVITE" && $hdr(X-Scope)=="nat-relay") { + $du = $hdr(X-NAT-URI); + $fs = $keepalive.socket($du); + t_relay(); + exit; +} +... + +``` + + +#### $source_uri + + +Returns the URI specification from where a request was received in the +form sip:ip:port[;transport=xxx] with transport missing if UDP. + + +This pseudo-variable can be used to set the received AVP for the +registrar module to indicate that a user agent is behind NAT. This is +meant as a more flexible replacement for the fix_nated_register() +function, because it allows one to modify the source uri by appending +some extra parameters before saving it to the received AVP. + + +Another use for this pseudo-variable is in multi-proxy environments to +indicate the NAT endpoint URI to the next proxy (if needed). Consider +the previous example with two proxies P1 and P2. P1 receives the +REGISTER request from a user agent and forwards it to P2 which does +the actual registration. P1 needs to indicate the NAT endpoint URI to +P2, so that P2 can include it later for incoming INVITE requests to +this user agent. + + +```opensips title="Using $source_uri to set the received AVP on registrars" +... +modparam("registrar", "received_avp", "$avp(received_uri)") +modparam("registrar", "tcp_persistent_flag", 10) +... +# This code runs on the registrar, assuming it has received the +# REGISTER request directly from the user agent. +if ($rm=="REGISTER") { + if (client_nat_test(3)) { + if ($socket_in(proto)==UDP) { + nat_keepalive(); + } else { + # Keep TCP/TLS connections open until the registration + # expires, by setting the tcp_persistent_flag + setflag(10); + } + force_rport(); + $avp(received_uri) = $source_uri; + # or we could add some extra parameters to it if needed + # $avp(received_uri) = $source_uri + ";relayed=false" + } + if (!www_authorize("", "subscriber")) { + www_challenge("", "0"); + return; + } else if ($au!=$tU) { + sl_send_reply("403", "Username!=To not allowed ($au!=$tU)"); + return; + } + + if (!save("location")) { + sl_reply_error(); + } + exit; +} +... + +``` + + +```opensips title="Using $source_uri in multi-proxy environments" +... +# This code runs on P1 which received the REGISTER request and has to +# forward it to the registrar P2. +if ($rm=="REGISTER") { + if (client_nat_test(3)) { + force_rport(); + nat_keepalive(); + append_hf("X-NAT-URI: $source_uri\r\n"); + } + $du = "sip:P2_ip:P2_port"; + t_relay(); + exit; +} +... + +``` + + +#### $nat_traversal.track_dialog + + +Returns a boolean value (0 or 1) indicating if dialog tracking will +be enabled by the nat_traversal module. The nat_traversal module will +always track the dialog (by calling create_dialog internally) unless +told otherwise. + + +This is an advanced setting which is only meant to be used by multi-proxy +setups where a proxy doesn't want to keep track of a dialog, that is, if +it won't stay in the signaling path. + + +By setting this pv to 0 the nat_traversal module will not attempt to +create the dialog. + + +### Keepalive use cases + + +#### Single proxy environments + + +In this case the usage is straight forward. The nat_keepalive() function +needs to be called before save_location() for REGISTER requests, before +handle_subscribe() for SUBSCRIBE requests and before t_relay() for the +first INVITE of a dialog. + + +#### Registration in multi-proxy environments + + +If the proxy receiving the REGISTER request is the same as the proxy +handling it, then the case is reduced to the single proxy case. For +this example, lets assume they are different. We have a user agent UA1 +for which the registration is handled by the proxy P1. However UA1 +sends the REGISTER to P0 which in turn forwards it to P1 like this: +UA1 --> P0 --> P1. In this case P0 calls nat_keepalive(), adds the NAT +endpoint URI to the request (for example using a custom header) and +forwards the request to P1. P1 will save the user in the user location +together with the NAT endpoint URI. + + +When an incoming INVITE request arrives on P1 for UA1, P1, will lookup +the location and determine that it has to relay it to P0 because P0 +has the NAT open with UA1. P1 will include the original NAT endpoint +URI in the request and an indication that the only role P0 has in this +transaction is to relay it to UA1. P0 will receive this request and +determine that is has to act as a relay for it. It will extract the +NAT endpoint URI, then based on it the corresponding local socket +using $keepalive.socket(endpoint_uri). It will then set both $du and +$fs to the values it has found, call record_route() to stay in the +path and call t_relay() to send it to UA1. + + +Handling other type of requests (like for example SUBSCRIBE or +MESSAGE) that arrive on P1 for UA1 is done the same way as with the +first INVITE, on both P1 and P0. + + +#### Subscription in multi-proxy environments + + +If the proxy receiving the SUBSCRIBE request is the same as the proxy +handling it, then the case is reduced to the single proxy case. For +this example, lets assume they are different. We have a user agent UA1 +for which subscriptions are handled by the proxy P1. However UA1 +sends the SUBSCRIBE to P0 which in turn forwards it to P1 like this: +UA1 --> P0 --> P1. In this case P0 calls nat_keepalive(), then calls +record_route() to stay in the path and forwards the request to P1 +using t_relay(). Further SUBSCRIBE and NOTIFY requests will follow +the record route and use P0 as a NAT entry point to have access to UA1. +Further in-dialog SUBSCRIBE requests should also call record_route(). + + +#### Outgoing INVITEs in multi-proxy environments + + +If the proxy receiving the INVITE request is the same as the proxy +handling it, then the case is reduced to the single proxy case. For +this example, lets assume they are different. We have a user agent UA1 +which is handled by the proxy P1 and UA2 which is handled by P2. UA2 +has registered with P2 going through P3, while UA1 calls UA2 by sending +the first INVITE to P0. The call flow for the first INVITE looks like +this: UA1 --> P0 --> P1 --> P2 --> P3 --> UA2. +In this case P0 calls nat_keepalive(), then calls record_route() to +stay in the path and forwards the request to P1. P1 authenticates UA1 +then forwards the request to P2, which is the home proxy for UA2. P1 +doesn't have to use record_route to stay in the path, but it can do +that if needed for other purposes. P2 will lookup UA2 and find out +that it is reachable through P3. It will take the original NAT +endpoint URI that is has saved in the user location when UA2 has +registered and include it in the message along with an indication that +P3 only has to relay the message to UA2. If P2 does accounting or +starts a media relay, it should also call record_route() to stay in +the path. Then it forwards the request to P3 using t_relay(). P3 will +detect that it only has to relay the request to UA2 because it has the +NAT open with it. It will extract the NAT endpoint URI from the message +and the local sending socket using $keepalive.socket(endpoint_uri) and +will set both $du and $fs. After that it will call record_route() to +stay in the path, and forward the request to UA2 using t_relay(). +Further in-dialog requests will follow the recorded route and use +P0 and P3 as access points to UA1 respectively UA2. All the proxies +that have used record_route() during the first INVITE should also +call record_route() during further in-dialog requests to keep staying +in the path. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/nat_traversal/doc/contributors.xml b/modules/nat_traversal/doc/contributors.xml deleted file mode 100644 index 9670ba9f2c1..00000000000 --- a/modules/nat_traversal/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Dan Pascu (@danpascu) - 54 - 26 - 3085 - 115 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 37 - 31 - 306 - 128 - - - 3. - Liviu Chircu (@liviuchircu) - 19 - 16 - 61 - 84 - - - 4. - Razvan Crainea (@razvancrainea) - 9 - 7 - 11 - 6 - - - 5. - Saúl Ibarra Corretgé (@saghul) - 9 - 5 - 188 - 102 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 7 - 5 - 27 - 16 - - - 7. - Maksym Sobolyev (@sobomax) - 7 - 5 - 15 - 16 - - - 8. - Vlad Paiu (@vladpaiu) - 5 - 3 - 12 - 14 - - - 9. - Anca Vamanu - 4 - 2 - 12 - 1 - - - 10. - Alexandra Titoc - 4 - 2 - 6 - 2 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), David Sanders, Stéphane Alnet (@shimaore), okhowang, Sergio Gutierrez, Alexey Vasilyev (@vasilevalex). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2023 - - - 5. - okhowang - Mar 2023 - Mar 2023 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Apr 2022 - - - 7. - Alexey Vasilyev (@vasilevalex) - Mar 2022 - Mar 2022 - - - 8. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2008 - Apr 2020 - - - 9. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 10. - Dan Pascu (@danpascu) - May 2008 - Aug 2019 - - - -
-All remaining contributors: Saúl Ibarra Corretgé (@saghul), David Sanders, Vlad Paiu (@vladpaiu), Anca Vamanu, Stéphane Alnet (@shimaore), Sergio Gutierrez. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Alexey Vasilyev (@vasilevalex), Bogdan-Andrei Iancu (@bogdan-iancu), Dan Pascu (@danpascu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Saúl Ibarra Corretgé (@saghul). -
- -
diff --git a/modules/nat_traversal/doc/nat_traversal.xml b/modules/nat_traversal/doc/nat_traversal.xml deleted file mode 100644 index f09b0131daf..00000000000 --- a/modules/nat_traversal/doc/nat_traversal.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - NAT Traversal Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 Dan Pascu - - diff --git a/modules/nat_traversal/doc/nat_traversal_admin.xml b/modules/nat_traversal/doc/nat_traversal_admin.xml deleted file mode 100644 index f11583a3183..00000000000 --- a/modules/nat_traversal/doc/nat_traversal_admin.xml +++ /dev/null @@ -1,974 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The nat_traversal module provides support for handling far-end NAT - traversal for SIP signaling. The module includes functionality to - detect user agents behind NAT, to modify SIP headers to allow user - agents to work transparently behind NAT and to send keepalive messages - to user agents behind NAT in order to preserve their visibility in the - network. The module can handle user agents behind multiple cascaded - NAT boxes as easily as user agents behind a single level of NAT. - - - The module is designed to work in complex environments where multiple - SIP proxies may be involved in handling registration and routing and - where the incoming and outgoing paths may not necessarily be the same, - or where the routing path may even change between consecutive dialogs. - -
- -
- Keepalive functionality -
- Overview - - The nat_traversal module implements a very sophisticated keepalive - mechanism, that is able to handle the most complex environments and - use cases, including distributed environments with multiple proxies. - Unlike existing keepalive solutions that only send keepalive messages - to user agents that have registered (during their registration), the - nat_traversal module can keepalive an user agent based on multiple - conditions, making it not only more flexible and more efficient, but - also able to work in environments and with use cases where a simple - keepalive implementation based on keeping alive registrations alone - cannot work. - - - The keepalive mechanism works by sending a SIP request to a user agent - behind NAT to make that user agent send back a reply. The purpose is - to have packets sent from inside the NAT to the proxy often enough to - prevent the NAT box from timing out the connection. Many NAT boxes do - not consider packets that travel from the outside to the inside of the - NAT to reset the connection expiration timer, thus to keepalive a user - agent we need to trigger an answer from it. - -
-
- Background - - One of the major limitations of an implementation that only sends - keepalive messages to registered user agents, is that it creates an - artificial association between the concept of network visibility with - the concept of user registration. The registration process only creates - network visibility for incoming INVITE requests, in other words for - incoming calls. However, there are other cases where a user agent needs - to preserve its network visibility when behind NAT, that have nothing - to do with receiving incoming calls. One of them is the ability of the - user agent to keep receiving NOTIFY requests for a presence subscription - it has made. Another situation is where the user agent should be able - to receive all messages within a dialog it has initiated, even if it is - not registered. In the first case, a presence agent is required to - register to be able to receive notifications for its subscriptions and - it has to keep the registration active the whole time. In the second - case a user agent that wants to make an outgoing call has to register - and keep the registration active during the call, otherwise it may - not be able to receive future in-dialog messages, including the BYE - that closes the dialog. - - - Not only we have this forced association shown above, that requires a - user agent to register to be able to do anything, but a simple keepalive - implementation based on sending keepalive messages only to registered - user agents, will also fail to work in common cases, exactly because of - this artificial association. For example lets assume that we have an - user agent that is registered. If during an outgoing call initiated by - this user agent, the agent stops registering, then it will not be able - to receive further in-dialog messages after the NAT binding expires. - The same is true for a presence agent, receiving notifications for its - subscriptions. - - - In environments with multiple proxies handling the same domains, the - problem gets even more acute. In this case the incoming and outgoing - paths for a call may be completely different: the user agent may - register using one proxy as an entry point to the network, but may - make an outgoing call using a different proxy as the network entry - point. Even more a registration may use a different proxy as the entry - point to the network with each renewal of the registration, making it - volatile and unreliable for anything else except incoming calls. - A keepalive implementation that only sends keepalive messages to - registered user agents will not be able to guarantee the delivery of - in-dialog messages for outgoing calls even if it requires the user - agent to register before making a call. In this case, even if we - assume that the user agent would pick the same proxy for an outgoing - call as the one it has used for the last registration, at the next - registration it may pick another one (as returned by DNS), and will - dissociate the incoming and outgoing paths rendering the outgoing - path unusable (assuming the outgoing call takes longer than the - registration period). - - - All this leads to the conclusion that a keepalive implementation based - solely on sending keepalive messages to registered user agents can only - work in single proxy environments and then only work reliably if it - requires the user agent to register before doing anything else, even - though some actions would not require a user agent to register. - -
-
- Implementation - - To avoid the above mentioned issues, this implementation introduces - the concept of network visibility for a given condition. This way we - can keepalive a user agent for multiple independent conditions, thus - avoiding all the problems presented above. - - - The conditions for which the module will send keepalive messages are: - - - - Registration - for user agents that have - registered to preserve their visibility for incoming calls. This - is the result of triggering keepalive for a REGISTER request. - - - - - Subscription - for presence agents that - have subscribed to some events to preserve their visibility for - receiving back notifications. This is the result of triggering - keepalive for a SUBSCRIBE request. - - - - - Dialogs - for user agents that have - initiated an outgoing call to preserve their visibility for - receiving further in-dialog messages. This is the result of - triggering keepalive for an outgoing INVITE request. - - - - - - A user agent's NAT entry point may be kept alive for one or multiple - of the conditions listed above. Even when a NAT endpoint is kept alive - for more than one condition, only one keepalive message is sent to - that NAT endpoint. The presence of multiple conditions for a NAT - endpoint, only guarantees that the network visibility for a user agent - based on a certain condition will be available while that condition is - true, independently of the other conditions. When all the conditions - to keepalive a NAT endpoint will disappear, that endpoint will be - removed from the list with the NAT endpoints that need to be kept - alive. - - - The user interface for the keepalive functionality is very simple. It - consists of a single function called nat_keepalive() that needs to be - called only once for the requests that trigger the need for network - visibility. These requests are: REGISTER, SUBSCRIBE and outgoing - INVITEs. After such a request arrives it makes the user agent visible - for the purpose of receiving back other messages. Thus, after a - REGISTER the user agent may receive back incoming calls, after a - SUBSCRIBE it may receive back notifications and after an outgoing - INVITE it may receive back further in-dialog messages including the - BYE that ends the dialog. The nat_keepalive() function needs to be - called on the proxy that directly receives the request from the user - agent, if it determines that the user agent making the request is - behind NAT. The function needs to be called before the request gets - either a stateless reply or it is relayed with t_relay(). Calling the - nat_keepalive() function has no effect if the request gets no stateless - reply or it is not relayed. - - - For environments with multiple proxies, where the proxy that acts as - an entry point to the network for a given request is not the one that - actually handles the request, then the nat_keepalive() function needs - to be called on the proxy that is the entry point and after that the - request must be sent to the proxy that actually handles the request - using t_relay(). This is needed because the keepalive functionality - detects from the stateless replies or the TM relayed replies if the - NAT endpoint needs to be kept alive for the condition triggered by - the request for which the nat_keepalive() function was called. - For example assume a network where a proxy P1 receives a REGISTER - from an user agent behind NAT. P1 will determine that the user agent - is behind NAT so it needs keepalive functionality, but another proxy - called P2 is actually handling the subscriber registrations. In this - case P1 has to call nat_keepalive() even though it doesn't yet know - the answer P2 will give to the REGISTER request (which may even be a - negative reply) or if P2 will restrict the proposed expiration time - in any way. Thus P1 calls nat_keepalive() after which it calls - t_relay(). When the reply from P2 arrives, a callback is triggered - which will determine if the request did get a positive reply, and if - so it will extract the registration expiration time and enable the - keepalive functionality for that endpoint for the registration - condition for the time given by the registration expiration. - For single proxy environments, or if P1 is the same as P2, then - t_relay() is not called, instead save_location() is called if the - registration is accepted. Then the same process described above - happens only this time triggered by a stateless reply callback. - In both cases, calling nat_keepalive() when the REGISTER is received - has no other effect that to trigger some callbacks that will determine - from the reply if the caller endpoint should be kept alive or not. - - - Below is described how nat_keepalive() should be called and what it - does for each of the requests that need keepalive functionality (the - function should only be called if it is determined that the user agent - that generated the request is behind NAT): - - - - REGISTER - called before save_location() or - t_relay() (depending on whether the proxy that received the - REGISTER is also handling registration for that subscriber or - not). It will determine from either the stateless reply - generated by save_location() or the TM relayed reply if the - registration was successful and what is its expiration time. If - the registration was successful it will mark the given NAT - endpoint for keepalive for the registration condition using the - detected expiration time. If the REGISTER request is discarded - after nat_keepalive() was called or if it intercepts a negative - reply it will have no effect and the registration condition will - not be activated for that endpoint. - - - - - SUBSCRIBE - called before handle_subscribe() - or t_relay() (depending on whether the proxy that received the - SUBSCRIBE is also handling subscriptions for that subscriber or - not). It will determine from either the stateless reply - generated by handle_subscribe() or the TM relayed reply if the - subscription was successful and what is its expiration time. If - the subscription was successful it will mark the given NAT - endpoint for keepalive for the subscription condition using the - detected expiration time. If the SUBSCRIBE request is discarded - after nat_keepalive() was called or if it intercepts a negative - reply it will have no effect and the subscription condition will - not be activated for that endpoint. It should be called for - every SUBSCRIBE received, not only the ones that start a - subscription (do not have a to tag), because it needs to update - (extend) the expiration time for the subscription. - - - - - INVITE - called before t_relay() for the - first INVITE in a dialog. It will automatically trigger dialog - tracing for that dialog and will use the dialog callbacks to - detect changes in the dialog state. It will add a keepalive - entry with the dialog condition for the caller NAT endpoint as - soon as the dialog is created (this happens when t_relay() is - called). It will then keep that condition for the given endpoint - until the dialog is destroyed (either terminated, failed or - expired). If the INVITE request cannot be relayed after - nat_keepalive() was called it will have no effect and the - dialog condition will not be activated for that endpoint. - - - In addition an INVITE that starts a dialog will automatically - trigger keepalive functionality for the destination endpoints - if they are behind NAT. This is done by detecting if any of the - destination endpoints already has a keepalive entry for the - register condition. If so, a dialog condition will be added to - that entry thus preserving that endpoint visibility even if the - registration expires during the dialog or is moved to another - proxy. During the call setup stage, multiple entries for the - callee may be added with the dialog condition if parallel - forking is used, however only the destination endpoints behind - NAT will have the extra dialog condition set. Later when the - dialog is confirmed, only the endpoint that answered the call - will keep the dialog condition activated (if present), while all - the endpoints from the unanswered branches will have it removed. - This is done automatically without any need to call any function. - - - - - - Considering the elements presented in this section, we can say that - the nat_traversal module provides a flexible and efficient keepalive - functionality that is very easy to use. Because only the border - proxies send keepalive messages, the network traffic is minimized. - For the same reason, message processing in the proxies is also - minimized, as border proxies generate keepalive messages themselves - and send them stateless, instead of having to relay messages - generated by the registrars. Network traffic is also minimized by only - sending a single keepalive message for an endpoint no matter for how - many reasons the endpoint is kept alive. Keepalive messages are also - distributed over the keepalive interval to avoid overloading the - proxy by generating too many messages at a time. The nat_traversal - module keeps its internal state about endpoints that need keepalive, - state that is build while messages are processed by the proxy and - thus it doesn't need to transfer any information from the usrloc - module, which should also improve its efficiency. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - sl module - if keepalive is enabled. - - - - - tm module - if keepalive is enabled. - - - - - dialog module - if keepalive is enabled - and keeping alive INVITE dialogs is needed. - - - - - clusterer - only if "cluster_id" - option is enabled. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - None. - - - -
-
- -
- Exported Parameters -
- <varname>keepalive_interval</varname> (integer) - - The time interval (in seconds) required to send a keepalive message to - all the endpoints that need being kept alive. During this interval, - each endpoint will receive exactly one keepalive message. A negative - value or zero will disable the keepalive functionality. - - - - Default value is 60. - - - - Setting the <varname>keepalive_interval</varname> parameter - -... -modparam("nat_traversal", "keepalive_interval", 90) -... - - -
- -
- <varname>keepalive_method</varname> (string) - - What SIP method to use to send keepalive messages. Typical methods - used for this purpose are NOTIFY and OPTIONS. NOTIFY generates smaller - replies from user agents, but they are almost entirely negative replies. - Apparently almost none of the user agents understand that the purpose - of the NOTIFY with a keep-alive event is to keep NAT - open, even though many user agents send such NOTIFY requests themselves. - However this does not affect the result at all, since the purpose is - to trigger a response from the user agent behind NAT, positive or - negative replies having little relevance as they are discarded anyway. - The OPTIONS method on the other hand has a much higher rate of positive - replies, but at the same time those positive replies are much bigger, - mostly because the OPTIONS method is used to inform about the user - agent capabilities and thus it includes a lot of extra headers to - indicate those capabilities. Many user agents also include a SDP body - with a bogus media session, probably to indicate media capabilities. - All of this makes that positive replies to OPTIONS requests are 2 to - 3 times bigger than negative replies or replies to NOTIFY requests. - For this reason the default value for the used method is NOTIFY. - - - - Default value is NOTIFY. - - - - Setting the <varname>keepalive_method</varname> parameter - -... -modparam("nat_traversal", "keepalive_method", "OPTIONS") -... - - -
- -
- <varname>keepalive_from</varname> (string) - - Indicates what SIP URI to use in the From header of the keepalive - requests. If not specified it will use sip:keepalive@proxy_ip, where - proxy_ip is the IP address of the outgoing interface used to send the - keepalive message, which is the same interface on which the request - that triggered keepalive functionality arrived. - - - - Default value is sip:keepalive@proxy_ip with proxy_ip - being the actual IP of the outgoing interface. - - - - Setting the <varname>keepalive_from</varname> parameter - -... -modparam("nat_traversal", "keepalive_from", "sip:keepalive@my-domain.com") -... - - -
- -
- <varname>keepalive_extra_headers</varname> (string) - - Specifies extra headers that should be added to the keepalive messages - that are sent by the proxy. The header specification must also include - the CRLF (\r\n) line separator. Multiple headers can be specified by - concatenating them and each of them must include the \r\n separator. - - - - Default value is undefined (send no extra headers). - - - - Setting the <varname>keepalive_extra_headers</varname> parameter - -... -modparam("nat_traversal", "keepalive_extra_headers", "User-Agent: OpenSIPS\r\nX-MyHeader: some_value\r\n") -... - - -
- -
- <varname>keepalive_state_file</varname> (string) - - Specifies a filename where information about the NAT endpoints and the - conditions for which they are being kept alive is saved when &osips; - exits. The information in this file is then used when &osips; starts - to restore its internal state and continue to send keepalive messages - to the NAT endpoints that have not expired in the meantime. This is - useful when restarting &osips; to avoid losing keepalive state - information about the NAT endpoints. The internal keepalive state is - guaranteed to be saved in this file on exit, even when &osips; - crashes. - - - The value of this parameter can be either a relative path, in which - case it will store it in the &osips; working directory, or an - absolute path. - - - - Default value is undefined keepalive_state. - - - - Setting the <varname>keepalive_state_file</varname> parameter - -... -modparam("nat_traversal", "keepalive_state_file", "/run/opensips/keepalive_state") -... - - -
- -
- <varname>cluster_id</varname> (integer) - - The ID of the cluster the module is part of. The clustering support is - used by the nat_traversal module for controlling the pinging process. - When part of a cluster of multiple nodes, the nodes can agree upon which - node is the one responsible for pinging. - - - The clustering with sharing tag support may be used to control which - node in the cluster will perform the pinging/probing to the - contacts. See the - option. - - - For more info on how to define and populate a cluster (with OpenSIPS - nodes) see the "clusterer" module. - - - - Default value is 0 (none). - - - - Set <varname>cluster_id</varname> parameter - -... -# Be part of cluster ID 9 -modparam("nat_traversal", "cluster_id", 9) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (string) - - The name of the sharing tag (as defined per clusterer modules) to - control which node is responsible for perform pinging of the - contacts. - If defined, only the node with active status of this tag will - perform the pinging. - - - The must be defined for this option - to work. - - - This is an optional parameter. If not set, all the nodes in the cluster - will individually do the pinging. - - - - Default value is empty (none). - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("nat_traversal", "cluster_id", 9) -modparam("nat_traversal", "cluster_sharing_tag", "vip") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">client_nat_test(type)</function> - - - Check if the client is behind NAT. What tests are performed is - specified by the type parameter which is an integer given by the sum - of the numbers corresponding to the tests that one wishes to perform. - The numbers corresponding to individual tests are shown below: - - - - - - 1 - tests if client has a private IP address (as defined by RFC1918) - in the Contact field of the SIP message. - - - 2 - tests if client has contacted &osips; from an address that - is different from the one in the Via field. Both the IP and - port are compared by this test. - - - 4 - tests if client has a private IP address (as defined by RFC1918) - in the top Via field of the SIP message. - - - 8 - tests if client has contacted &osips; from an address that - is different from the one in the Contact field. Only IP is - compared by this test. - - - - - - For example calling client_nat_test(3) will perform test 1 and - test 2 and return true if at least one succeeds, otherwise false. - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - - Using the <function>client_nat_test</function> function - -... -if (client_nat_test(3)) { - ..... -} -... - - -
- -
- - <function moreinfo="none">fix_contact()</function> - - - Will replace the IP and port in the Contact header with the - IP and port the SIP message was received from. Usually called - after a successful call to client_nat_test(type) - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. - - - - Using the <function>fix_contact</function> function - -... -if (client_nat_test(3)) { - fix_contact(); -} -... - - -
- -
- - <function moreinfo="none">nat_keepalive()</function> - - - Trigger keepalive functionality for the source address of the request. - When called it only sets some internal flags, which will trigger - later the addition of the endpoint to the keepalive list if a - positive reply is generated/received (for REGISTER and SUBSCRIBE) - or when the dialog is started/replied (for INVITEs). - For this reason, it can be called early or late in the script. The - only condition is to call it before replying to the request or before - sending it to another proxy. If the request needs to be sent to - another proxy, t_relay() must be used to be able to intercept replies - via TM or dialog callbacks. If stateless forwarding is used, the - keepalive functionality will not work. Also for outgoing INVITEs, - record_route() should also be used to make sure the proxy that keeps - the caller endpoint alive stays in the path. For multi-proxy setups, - this function should always be called on the border proxies (the ones - that received the request directly from the user agent). For more - details about this function, see the Implementation - subsection from the Keepalive functionality section. - - - This function can be used from REQUEST_ROUTE. - - - Using the <function>nat_keepalive</function> function - -... -if (($rm=="REGISTER" || $rm=="SUBSCRIBE" || - ($rm=="INVITE" && !has_totag())) && client_nat_test(3)) -{ - nat_keepalive(); -} -... - - -
-
- -
- Exported Statistics -
- <varname>keepalive_endpoints</varname> - - Indicates the total number of NAT endpoints that are being kept alive. - -
-
- <varname>registered_endpoints</varname> - - Indicates how many of the NAT endpoints are kept alive for registrations. - -
-
- <varname>subscribed_endpoints</varname> - - Indicates how many of the NAT endpoints are kept alive for subscriptions. - -
-
- <varname>dialog_endpoints</varname> - - Indicates how many of the NAT endpoints are kept alive for taking part - in an INVITE dialog. - -
-
- -
- Exported Pseudo-Variables -
- <varname>$keepalive.socket(nat_endpoint)</varname> - - Returns the local socket used to send messages to the given NAT - endpoint URI. The socket has the form proto:ip:port. The NAT endpoint - URI is in the form: sip:ip:port[;transport=xxx] with transport missing - if UDP. If the requested NAT endpoint URI is present in the internal - keepalive table for any condition, it will return its associated local - socket, else it will return null. The nat_endpoint can be a string or - another pseudo-variable. - - - This can be useful to restore the sending socket when relaying messages - to a given user agent in multi-proxy environments. Consider an example - where 2 proxies are involved, P1 and P2. A user agent registers by - sending a REGISTER request to P1. P1 will call nat_keepalive() but - because it determines that P2 should actually handle the user - registration will forward the request to P2. Now assume P2 receives an - incoming INVITE for this user. It will determine that the registration - came through P1 and will forward the request to P1. P2 should also - include the NAT endpoint URI where this request is to be relayed. - This information should have been provided by P1 when it relayed the - REGISTER request to P2. The means to do this is out of the scope of - this example, but one can either use the path extension or custom - headers to do this. When P1 receives the INVITE it will use the NAT - endpoint URI it has received along with the request to determine the - socket to send out the request, which should be the same as the one - where the registration request was originally received. In the example - below lets assume that P2 provided the original NAT endpoint address - in a custom header called X-NAT-URI and that it also provides a custom - header called X-Scope to indicate that the message is sent to P1 for - being relayed back to the user agent by P1 which has the NAT open - with it. - - - Using <varname>$keepalive.socket</varname> in multi-proxy environments - -... -# This code runs on P1 which has received an INVITE from P2 to forward -# it to the user agent behind NAT (because P1 has the NAT open with it). -if ($rm=="INVITE" && $hdr(X-Scope)=="nat-relay") { - $du = $hdr(X-NAT-URI); - $fs = $keepalive.socket($du); - t_relay(); - exit; -} -... - - -
- -
- <varname>$source_uri</varname> - - Returns the URI specification from where a request was received in the - form sip:ip:port[;transport=xxx] with transport missing if UDP. - - - This pseudo-variable can be used to set the received AVP for the - registrar module to indicate that a user agent is behind NAT. This is - meant as a more flexible replacement for the fix_nated_register() - function, because it allows one to modify the source uri by appending - some extra parameters before saving it to the received AVP. - - - Another use for this pseudo-variable is in multi-proxy environments to - indicate the NAT endpoint URI to the next proxy (if needed). Consider - the previous example with two proxies P1 and P2. P1 receives the - REGISTER request from a user agent and forwards it to P2 which does - the actual registration. P1 needs to indicate the NAT endpoint URI to - P2, so that P2 can include it later for incoming INVITE requests to - this user agent. - - - - Using <varname>$source_uri</varname> to set the received AVP on registrars - -... -modparam("registrar", "received_avp", "$avp(received_uri)") -modparam("registrar", "tcp_persistent_flag", 10) -... -# This code runs on the registrar, assuming it has received the -# REGISTER request directly from the user agent. -if ($rm=="REGISTER") { - if (client_nat_test(3)) { - if ($socket_in(proto)==UDP) { - nat_keepalive(); - } else { - # Keep TCP/TLS connections open until the registration - # expires, by setting the tcp_persistent_flag - setflag(10); - } - force_rport(); - $avp(received_uri) = $source_uri; - # or we could add some extra parameters to it if needed - # $avp(received_uri) = $source_uri + ";relayed=false" - } - if (!www_authorize("", "subscriber")) { - www_challenge("", "0"); - return; - } else if ($au!=$tU) { - sl_send_reply("403", "Username!=To not allowed ($au!=$tU)"); - return; - } - - if (!save("location")) { - sl_reply_error(); - } - exit; -} -... - - - - - Using <varname>$source_uri</varname> in multi-proxy environments - -... -# This code runs on P1 which received the REGISTER request and has to -# forward it to the registrar P2. -if ($rm=="REGISTER") { - if (client_nat_test(3)) { - force_rport(); - nat_keepalive(); - append_hf("X-NAT-URI: $source_uri\r\n"); - } - $du = "sip:P2_ip:P2_port"; - t_relay(); - exit; -} -... - - - -
-
- <varname>$nat_traversal.track_dialog</varname> - - Returns a boolean value (0 or 1) indicating if dialog tracking will - be enabled by the nat_traversal module. The nat_traversal module will - always track the dialog (by calling create_dialog internally) unless - told otherwise. - - - This is an advanced setting which is only meant to be used by multi-proxy - setups where a proxy doesn't want to keep track of a dialog, that is, if - it won't stay in the signaling path. - - - By setting this pv to 0 the nat_traversal module will not attempt to - create the dialog. - -
- -
- -
- Keepalive use cases -
- Single proxy environments - - In this case the usage is straight forward. The nat_keepalive() function - needs to be called before save_location() for REGISTER requests, before - handle_subscribe() for SUBSCRIBE requests and before t_relay() for the - first INVITE of a dialog. - -
- -
- Registration in multi-proxy environments - - If the proxy receiving the REGISTER request is the same as the proxy - handling it, then the case is reduced to the single proxy case. For - this example, lets assume they are different. We have a user agent UA1 - for which the registration is handled by the proxy P1. However UA1 - sends the REGISTER to P0 which in turn forwards it to P1 like this: - UA1 --> P0 --> P1. In this case P0 calls nat_keepalive(), adds the NAT - endpoint URI to the request (for example using a custom header) and - forwards the request to P1. P1 will save the user in the user location - together with the NAT endpoint URI. - - - When an incoming INVITE request arrives on P1 for UA1, P1, will lookup - the location and determine that it has to relay it to P0 because P0 - has the NAT open with UA1. P1 will include the original NAT endpoint - URI in the request and an indication that the only role P0 has in this - transaction is to relay it to UA1. P0 will receive this request and - determine that is has to act as a relay for it. It will extract the - NAT endpoint URI, then based on it the corresponding local socket - using $keepalive.socket(endpoint_uri). It will then set both $du and - $fs to the values it has found, call record_route() to stay in the - path and call t_relay() to send it to UA1. - - - Handling other type of requests (like for example SUBSCRIBE or - MESSAGE) that arrive on P1 for UA1 is done the same way as with the - first INVITE, on both P1 and P0. - -
- -
- Subscription in multi-proxy environments - - If the proxy receiving the SUBSCRIBE request is the same as the proxy - handling it, then the case is reduced to the single proxy case. For - this example, lets assume they are different. We have a user agent UA1 - for which subscriptions are handled by the proxy P1. However UA1 - sends the SUBSCRIBE to P0 which in turn forwards it to P1 like this: - UA1 --> P0 --> P1. In this case P0 calls nat_keepalive(), then calls - record_route() to stay in the path and forwards the request to P1 - using t_relay(). Further SUBSCRIBE and NOTIFY requests will follow - the record route and use P0 as a NAT entry point to have access to UA1. - Further in-dialog SUBSCRIBE requests should also call record_route(). - -
- -
- Outgoing INVITEs in multi-proxy environments - - If the proxy receiving the INVITE request is the same as the proxy - handling it, then the case is reduced to the single proxy case. For - this example, lets assume they are different. We have a user agent UA1 - which is handled by the proxy P1 and UA2 which is handled by P2. UA2 - has registered with P2 going through P3, while UA1 calls UA2 by sending - the first INVITE to P0. The call flow for the first INVITE looks like - this: UA1 --> P0 --> P1 --> P2 --> P3 --> UA2. - In this case P0 calls nat_keepalive(), then calls record_route() to - stay in the path and forwards the request to P1. P1 authenticates UA1 - then forwards the request to P2, which is the home proxy for UA2. P1 - doesn't have to use record_route to stay in the path, but it can do - that if needed for other purposes. P2 will lookup UA2 and find out - that it is reachable through P3. It will take the original NAT - endpoint URI that is has saved in the user location when UA2 has - registered and include it in the message along with an indication that - P3 only has to relay the message to UA2. If P2 does accounting or - starts a media relay, it should also call record_route() to stay in - the path. Then it forwards the request to P3 using t_relay(). P3 will - detect that it only has to relay the request to UA2 because it has the - NAT open with it. It will extract the NAT endpoint URI from the message - and the local sending socket using $keepalive.socket(endpoint_uri) and - will set both $du and $fs. After that it will call record_route() to - stay in the path, and forward the request to UA2 using t_relay(). - Further in-dialog requests will follow the recorded route and use - P0 and P3 as access points to UA1 respectively UA2. All the proxies - that have used record_route() during the first INVITE should also - call record_route() during further in-dialog requests to keep staying - in the path. - -
- -
- -
- diff --git a/modules/nathelper/README b/modules/nathelper/README deleted file mode 100644 index d4f5b2b8739..00000000000 --- a/modules/nathelper/README +++ /dev/null @@ -1,753 +0,0 @@ -nathelper Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. NAT pinging types - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. natping_interval (integer) - 1.4.2. ping_nated_only (integer) - 1.4.3. natping_partitions (integer) - 1.4.4. natping_socket (string) - 1.4.5. received_avp (str) - 1.4.6. force_socket (string) - 1.4.7. sipping_bflag (string) - 1.4.8. remove_on_timeout_bflag (string) - 1.4.9. sipping_latency_flag (string) - 1.4.10. sipping_ignore_rpl_codes (CSV string) - 1.4.11. sipping_from (string) - 1.4.12. sipping_method (string) - 1.4.13. nortpproxy_str (string) - 1.4.14. natping_tcp (integer) - 1.4.15. oldip_skip (string) - 1.4.16. ping_threshold (int) - 1.4.17. max_pings_lost (int) - 1.4.18. cluster_id (integer) - 1.4.19. cluster_sharing_tag (string) - - 1.5. Exported Functions - - 1.5.1. fix_nated_contact([uri_params]) - 1.5.2. fix_nated_sdp(flags [, ip_address [, - sdp_fields]]) - - 1.5.3. add_rcv_param([flag]), - 1.5.4. fix_nated_register() - 1.5.5. nat_uac_test(flags) - - 1.6. Exported MI Functions - - 1.6.1. nh_enable_ping - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set natping_interval parameter - 1.2. Set ping_nated_only parameter - 1.3. Set natping_partitions parameter - 1.4. Set natping_socket parameter - 1.5. Set received_avp parameter - 1.6. Set force_socket parameter - 1.7. Set sipping_bflag parameter - 1.8. Set remove_on_timeout_bflag parameter - 1.9. Set sipping_latency_flag parameter - 1.10. Set sipping_ignore_rpl_codes parameter - 1.11. Set sipping_from parameter - 1.12. Set sipping_method parameter - 1.13. Set nortpproxy_str parameter - 1.14. Set natping_tcp parameter - 1.15. Set oldip_skip parameter - 1.16. Set ping_threshold parameter - 1.17. Set max_pings_lost parameter - 1.18. Set cluster_id parameter - 1.19. Set cluster_sharing_tag parameter - 1.20. fix_nated_contact usage - 1.21. fix_nated_sdp usage - 1.22. add_rcv_paramer usage - 1.23. fix_nated_register usage - 1.24. nat_uac_test usage - 1.25. nh_enable_ping usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module to help with NAT traversal. In particular, it - helps symmetric UAs that don't advertise they are symmetric and - are not able to determine their public address. - fix_nated_contact rewrites Contact header field with request's - source address:port pair. fix_nated_sdp adds the active - direction indication to SDP (flag 0x01) and updates source IP - address too (flag 0x02). - - Since version 2.2, stateful ping(only SIP Pings) for nathelper - is available. This allows you to remove contacts from usrloc - location table when max_pings_lost pings are not responded to, - each ping having a response timeout of ping_threshold seconds. - In order to have this functionality, contacts must have - remove_on_timeout_bflag flag set when inserted into the - location table. - - Works with multipart messages that contain an SDP part, but not - with multi-layered multipart messages. - -1.2. NAT pinging types - - Currently, the nathelper module supports two types of NAT - pings: - * UDP package - 4 bytes (zero filled) UDP packages are sent - to the contact address. - + Advantages: low bandwitdh traffic, easy to generate by - OpenSIPS; - + Disadvantages: unidirectional traffic through NAT - (inbound - from outside to inside); As many NATs do - update the bind timeout only on outbound traffic, the - bind may expire and closed. - * SIP request - a stateless SIP request is sent to the - contact address. - + Advantages: bidirectional traffic through NAT, since - each PING request from OpenSIPS (inbound traffic) will - force the SIP client to generate a SIP reply (outbound - traffic) - the NAT bind will be surely kept open. - Since version 2.2, one can also choose to remove - contacts from the location table if a certain - threshold is detected. - + Disadvantages: higher bandwitdh traffic, more - expensive (as time) to generate by OpenSIPS; - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * usrloc module - only if the NATed contacts are to be - pinged. - * clusterer - only if "cluster_id" option is enabled. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. natping_interval (integer) - - Period of time in seconds between sending the NAT pings to all - currently registered UAs to keep their NAT bindings alive. - Value of 0 disables this functionality. - -Note - - Enabling the NAT pinging functionality will force the module to - bind itself to USRLOC module. - - Default value is 0. - - Example 1.1. Set natping_interval parameter -... -modparam("nathelper", "natping_interval", 10) -... - -1.4.2. ping_nated_only (integer) - - If this variable is set then only contacts that have - “behind_NAT” flag in user location database set will get ping. - - Default value is 0. - - Example 1.2. Set ping_nated_only parameter -... -modparam("nathelper", "ping_nated_only", 1) -... - -1.4.3. natping_partitions (integer) - - How many partitions/chunks to be used for sending the pingings. - One partition means sending all pingings together. Two - partitions means to send half pings and second half at a time. - - Default value is 1. Maximum allowed value is 8. - - Example 1.3. Set natping_partitions parameter -... -modparam("nathelper", "natping_partitions", 4) -... - -1.4.4. natping_socket (string) - - Spoof the natping's source-ip to this address. Works only for - IPv4. - - Default value is NULL. - - Example 1.4. Set natping_socket parameter -... -modparam("nathelper", "natping_socket", "192.168.1.1:5006") -... - -1.4.5. received_avp (str) - - The name of the Attribute-Value-Pair (AVP) used to store the - URI containing the received IP, port and protocol. The URI is - created by the fix_nated_register() function and this data may - then be also picked up by the registrar module, which will - attach a "Received=" attribute to the registration. Do not - forget to change the value of corresponding parameter in the - registrar module whenever you change the value of this - parameter. - -Note - - You must set this parameter if you use fix_nated_register(). - Additionally, if you are using registrar, you must also set its - symmetric received_avp module parameter to the same value. - - Default value is "NULL" (disabled). - - Example 1.5. Set received_avp parameter -... -modparam("nathelper", "received_avp", "$avp(received)") -... - -1.4.6. force_socket (string) - - Sending socket to be used for pinging contacts without local - socket information (the local socket information may be lost - during a restart or contact replication). If no one specified, - OpenSIPS will choose the first listening interface matching the - destination protocol and AF family. - - Default value is “NULL”. - - Example 1.6. Set force_socket parameter -... -modparam("nathelper", "force_socket", "localhost:33333") -... - -1.4.7. sipping_bflag (string) - - What branch flag should be used by the module to identify NATed - contacts for which it should perform NAT ping via a SIP request - instead if dummy UDP package. - - Default value is NULL (disabled). - - Example 1.7. Set sipping_bflag parameter -... -modparam("nathelper", "sipping_bflag", "SIPPING_ENABLE") -... - -1.4.8. remove_on_timeout_bflag (string) - - What branch flag to be used in order to activate usrloc contact - removal when the ping_threshold is exceeded. - - Default value is NULL (disabled). - - Example 1.8. Set remove_on_timeout_bflag parameter -... -modparam("nathelper", "remove_on_timeout_bflag", "SIPPING_RTO") -... - -1.4.9. sipping_latency_flag (string) - - The branch flag which will be used in order to enable contact - pinging latency computation and reporting via the usrloc - E_UL_LATENCY_UPDATE event. - - Default value is NULL (disabled). - - Example 1.9. Set sipping_latency_flag parameter -... -modparam("nathelper", "sipping_latency_flag", "SIPPING_CALC_LATENCY") -... - -1.4.10. sipping_ignore_rpl_codes (CSV string) - - A comma-separated list of SIP reply status codes to contact - pings which are to be discarded. This may be useful for - "full-sharing" user location topologies, where the location - nodes are not directly facing the UAs, hence the intermediary - SIP component may generate replies to offline contact ping - attempts (e.g. 408 - Request Timeout) -- such ping replies - should be ignored. - - Default value is "NULL" (all reply status codes are accepted). - - Example 1.10. Set sipping_ignore_rpl_codes parameter -... -modparam("nathelper", "sipping_ignore_rpl_codes", "408, 480, 404") -... - -1.4.11. sipping_from (string) - - The parameter sets the SIP URI to be used in generating the SIP - requests for NAT ping purposes. To enable the SIP request - pinging feature, you have to set this parameter. The SIP - request pinging will be used only for requests marked so. - - Default value is “NULL”. - - Example 1.11. Set sipping_from parameter -... -modparam("nathelper", "sipping_from", "sip:pinger@siphub.net") -... - -1.4.12. sipping_method (string) - - The parameter sets the SIP method to be used in generating the - SIP requests for NAT ping purposes. - - Default value is “OPTIONS”. - - Example 1.12. Set sipping_method parameter -... -modparam("nathelper", "sipping_method", "INFO") -... - -1.4.13. nortpproxy_str (string) - - The parameter sets the SDP attribute used by nathelper to mark - the packet SDP informations have already been mangled. - - If empty string, no marker will be added or checked. - -Note - - The string must be a complete SDP line, including the EOH - (\r\n). - - Default value is “a=nortpproxy:yes\r\n”. - - Example 1.13. Set nortpproxy_str parameter -... -modparam("nathelper", "nortpproxy_str", "a=sdpmangled:yes\r\n") -... - -1.4.14. natping_tcp (integer) - - If the flag is set, TCP/TLS clients will also be pinged with - SIP OPTIONS messages. - - Default value is 0 (not set). - - Example 1.14. Set natping_tcp parameter -... -modparam("nathelper", "natping_tcp", 1) -... - -1.4.15. oldip_skip (string) - - Parameter which specifies whether old media ip and old origin - ip shall be put in the sdp body. The parameter has two values : - 'o' ("a=oldoip" field shall be skipped) and 'c' ("a=oldcip" - field shall be skipped). - - Default value is 0 (not set). - - Example 1.15. Set oldip_skip parameter -... -modparam("nathelper", "oldip_skip", "oc") -... - -1.4.16. ping_threshold (int) - - If a contact does not respond in ping_threshold seconds since - the ping has been sent, the contact shall be removed after - max_pings_lost unresponded pings. - - Default value is 3 (seconds). - - Example 1.16. Set ping_threshold parameter -... -modparam("nathelper", "ping_threshold", 10) -... - -1.4.17. max_pings_lost (int) - - Number of unresponded pings after which the contact shall be - removed from the location table. - - Default value is 3 (pings). - - Example 1.17. Set max_pings_lost parameter -... -modparam("nathelper", "max_pings_lost", 5) -... - -1.4.18. cluster_id (integer) - - The ID of the cluster the module is part of. The clustering - support is used by the nathelper module for controlling the - pinging process. When part of a cluster of multiple nodes, the - nodes can agree upon which node is the one responsible for - pinging. - - The clustering with sharing tag support may be used to control - which node in the cluster will perform the pinging/probing to - the contacts. See the cluster_sharing_tag option. - - For more info on how to define and populate a cluster (with - OpenSIPS nodes) see the "clusterer" module. - - Default value is “0 (none)”. - - Example 1.18. Set cluster_id parameter -... -# Be part of cluster ID 9 -modparam("nathelper", "cluster_id", 9) -... - -1.4.19. cluster_sharing_tag (string) - - The name of the sharing tag (as defined per clusterer modules) - to control which node is responsible for perform pinging of the - contacts. If defined, only the node with active status of this - tag will perform the pinging. - - The cluster_id must be defined for this option to work. - - This is an optional parameter. If not set, all the nodes in the - cluster will individually do the pinging. - - Default value is “empty (none)”. - - Example 1.19. Set cluster_sharing_tag parameter -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("nathelper", "cluster_id", 9) -modparam("nathelper", "cluster_sharing_tag", "vip") -... - -1.5. Exported Functions - -1.5.1. fix_nated_contact([uri_params]) - - Rewrites the URI Contact HF to contain request's source - address:port. If a list of URI parameter is provided, it will - be added to the modified contact; - - IMPORTANT NOTE: Changes made by this function shall not be seen - in the async resume route. So make sure you call it in all the - resume routes where you need the contact fixed. - - Parameters: - * uri_params (string, optional) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE. - - Example 1.20. fix_nated_contact usage -... -if (search("User-Agent: Cisco ATA.*") { - fix_nated_contact(";ata=cisco"); -} else { - fix_nated_contact(); -} -... - -1.5.2. fix_nated_sdp(flags [, ip_address [, sdp_fields]]) - - Alters the SDP information in orer to facilitate NAT traversal. - What changes to be performed may be controled via the “flags” - parameter. Since version 1.12 the name of the old ip fields are - "a=oldoip" for old origin ip and "a=oldcip" for old meda ip. - - Meaning of the parameters is as follows: - * flags (string) - the value may be a CSV of the following - flags: - + add-dir-active - (old 0x01 flag) adds - “a=direction:active” SDP line; - + rewrite-media-ip - (old 0x02 flag) rewrite media IP - address (c=) with source address of the message or the - provided IP address (the provided IP address takes - precedence over the source address). - + add-no-rtpproxy - (old 0x04 flag) adds - “a=nortpproxy:yes” SDP line; - + rewrite-origin-ip - (old 0x08 flag) rewrite IP from - origin description (o=) with source address of the - message or the provided IP address (the provided IP - address takes precedence over the source address). - + rewrite-null-ips - (old 0x10 flag) force rewrite of - null media IP and/or origin IP address. Without this - flag, null IPs are left untouched. - * ip_address (string, optional) - IP to be used for rewriting - SDP. If not specified, the received signalling IP will be - used. NOTE: For the IP to be used, you need to use 0x02 or - 0x08 flags, otherwise it will have no effect. - * sdp_fields (string, optional) - SDP field(s) to be appended - to SDP. Note: Each SDP field must be preceded by "\r\n". - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.21. fix_nated_sdp usage -... -# Add "a=direction:active" SDP line -# Rewrite media IP (c= line) -# Add extra "a=x-attr1" SDP line -# Add extra "a=x-attr2" SDP line -if (search("User-Agent: Cisco ATA.*") - {fix_nated_sdp(3,,"\r\na=x-attr1\r\na=x-attr2");}; -... - -1.5.3. add_rcv_param([flag]), - - Add received parameter to Contact header fields or Contact URI. - The parameter will contain URI created from the source IP, - port, and protocol of the packet containing the SIP message. - The parameter can be then processed by another registrar, this - is useful, for example, when replicating register messages - using t_replicate function to another registrar. - - Meaning of the parameters is as follows: - * flag (int, optional) - flags to indicate if the parameter - should be added to Contact URI or Contact header. If the - flag is non-zero, the parameter will be added to the - Contact URI. If not used or equal to zero, the parameter - will go to the Contact header. - - This function can be used from REQUEST_ROUTE. - - Example 1.22. add_rcv_paramer usage -... -add_rcv_param(); # add the parameter to the Contact header -.... -add_rcv_param(1); # add the parameter to the Contact URI -... - -1.5.4. fix_nated_register() - - The function creates a URI consisting of the source IP, port - and protocol and stores it in the received_avp AVP. The URI - will be appended as "received" parameter to Contact in 200 OK - and may also be stored in the user location database if the - same AVP is also configured for the registrar module. - - This function can be used from REQUEST_ROUTE. - - Example 1.23. fix_nated_register usage -... -fix_nated_register(); -... - -1.5.5. nat_uac_test(flags) - - Determines whether the received SIP message originated behind a - NAT, using one or more pre-defined checks. - - The flags (string) parameter denotes a comma-separated list of - checks to be performed, as follows: - * private-contact - (old 1 flag) Contact header field is - searched for occurrence of RFC1918 / RFC6598 addresses - * diff-ip-src-via - (old 2 flag) the "received" test is used: - address in Via is compared against source IP address of - signaling - * private-via - (old 4 flag) Top Most VIA is searched for - occurrence of RFC1918 / RFC6598 addresses - * private-sdp - (old 8 flag) SDP is searched for occurrence - of RFC1918 / RFC6598 addresses - * diff-port-src-via - (old 16 flag) test if the source port - is different from the port in Via - * diff-ip-src-contact - (old 32 flag) address in Contact is - compared against source IP address of signaling - * diff-port-src-contact - (old 64 flag) Port in Contact is - compared against source port of signaling - * carrier-grade-nat - (old 128 flag) also include RFC 6333 - addresses in the checks for Contact, Via and SDP - - Returns true if any of the tests passed. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.24. nat_uac_test usage -... -# check for private Contact or SDP media IP addresses -if (nat_uac_test("private-contact,private-sdp")) - xlog("SIP message is NAT'ed (Call-ID: $ci)\n"); -... - -1.6. Exported MI Functions - -1.6.1. nh_enable_ping - - Gets or sets the natpinging status. - - Parameters: - * status (optional) - if not provided the function returns - the current natping status. Otherwise, enables natping if - parameter value greater than 0 or disables natping if - parameter value is 0. - - Example 1.25. nh_enable_ping usage -... -$ opensips-cli -x mi nh_enable_ping -Status:: 1 -$ -$ opensips-cli -x mi nh_enable_ping 0 -$ -$ opensips-cli -x mi nh_enable_ping -Status:: 0 -$ -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.2. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.3. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 156 123 2050 873 - 2. Maksym Sobolyev (@sobomax) 155 45 3556 4790 - 3. Liviu Chircu (@liviuchircu) 50 40 452 324 - 4. Ionut Ionita (@ionutrazvanionita) 40 15 1598 627 - 5. Razvan Crainea (@razvancrainea) 33 27 158 240 - 6. Daniel-Constantin Mierla (@miconda) 22 17 142 124 - 7. Anca Vamanu 22 4 1602 185 - 8. Andrei Pelinescu-Onciul 21 17 121 110 - 9. Jan Janak (@janakj) 21 11 780 129 - 10. Vlad Patrascu (@rvlad-patrascu) 19 11 261 268 - - All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), - Ancuta Onofrei, Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), - Andrei Dragus, Henning Westerholt (@henningw), Dan Pascu - (@danpascu), Christophe Sollet (@csollet), Marcus Hunger, Klaus - Darilion, Sergio Gutierrez, Peter Lemenkov (@lemenkov), Nils - Ohlmeier, Emmanuel Buu, Carsten Bock, Shlomi Gutman, Jeremie Le - Hen, Bayan Towfiq, Laurent Schweizer, Jasper Hafkenscheid - (@hafkensite), Konstantin Bokarius, Alexandra Titoc, John - Riordan, Walter Doekes (@wdoekes), Elena-Ramona Modroiu, Nick - Altmann (@nikbyte), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2013 - Nov 2024 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Nov 2003 - Jun 2024 - 4. Maksym Sobolyev (@sobomax) May 2003 - Nov 2023 - 5. Vlad Paiu (@vladpaiu) Aug 2010 - Jul 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2023 - 7. Nick Altmann (@nikbyte) May 2022 - May 2022 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Apr 2022 - 9. Razvan Crainea (@razvancrainea) Dec 2010 - Jan 2021 - 10. Jasper Hafkenscheid (@hafkensite) Mar 2020 - Mar 2020 - - All remaining contributors: Dan Pascu (@danpascu), Shlomi - Gutman, Ovidiu Sas (@ovidiusas), Ionut Ionita - (@ionutrazvanionita), Walter Doekes (@wdoekes), Christophe - Sollet (@csollet), Anca Vamanu, John Riordan, Emmanuel Buu, - Andrei Dragus, Sergio Gutierrez, Klaus Darilion, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Ancuta - Onofrei, Marcus Hunger, Carsten Bock, Jeremie Le Hen, Laurent - Schweizer, Bayan Towfiq, Andrei Pelinescu-Onciul, Elena-Ramona - Modroiu, Jiri Kuthan (@jiriatipteldotorg), Jan Janak (@janakj), - Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Nick Altmann (@nikbyte), Jasper Hafkenscheid - (@hafkensite), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Ovidiu Sas - (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Walter Doekes - (@wdoekes), Christophe Sollet (@csollet), Vlad Paiu - (@vladpaiu), Maksym Sobolyev (@sobomax), Anca Vamanu, Andrei - Dragus, Sergio Gutierrez, Klaus Darilion, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Carsten Bock, Ancuta Onofrei, Marcus Hunger, Jeremie Le Hen, - Bayan Towfiq, Elena-Ramona Modroiu, Jan Janak (@janakj), Jiri - Kuthan (@jiriatipteldotorg). - - Documentation Copyrights: - - Copyright © 2018 VoIP Embedded, Inc. - - Copyright © 2003-2008 Sippy Software, Inc. - - Copyright © 2005 Voice Sistem SRL diff --git a/modules/nathelper/README.md b/modules/nathelper/README.md new file mode 100644 index 00000000000..540ba1ebbab --- /dev/null +++ b/modules/nathelper/README.md @@ -0,0 +1,743 @@ +--- +title: "nathelper Module" +description: "This is a module to help with NAT traversal." +--- + +## Admin Guide + + +### Overview + + +This is a module to help with NAT traversal. In particular, +it helps symmetric UAs that don't advertise they are symmetric +and are not able to determine their public address. fix_nated_contact +rewrites Contact header field with request's source address:port pair. +fix_nated_sdp adds the active direction indication to SDP (flag +0x01) and updates source IP address too (flag 0x02). + + +Since version 2.2, stateful ping(only SIP Pings) for nathelper is available. +This allows you to remove contacts from usrloc location table when +*max_pings_lost* pings are not responded to, each ping +having a response timeout of *ping_threshold* seconds. +In order to have this functionality, contacts must have +*remove_on_timeout_bflag* flag set when inserted into +the location table. + + +Works with multipart messages that contain an SDP part, +but not with multi-layered multipart messages. + + +### NAT pinging types + + +Currently, the nathelper module supports two types of NAT pings: + + +- *UDP package* - 4 bytes (zero filled) UDP +packages are sent to the contact address. + + - *Advantages:* low bandwitdh traffic, +easy to generate by OpenSIPS; + - *Disadvantages:* unidirectional +traffic through NAT (inbound - from outside to inside); As +many NATs do update the bind timeout only on outbound traffic, +the bind may expire and closed. +- *SIP request* - a stateless SIP request is +sent to the contact address. + + - *Advantages:* bidirectional traffic +through NAT, since each PING request from OpenSIPS (inbound +traffic) will force the SIP client to generate a SIP reply +(outbound traffic) - the NAT bind will be surely kept open. +Since version 2.2, one can also choose to remove contacts +from the location table if a certain threshold is detected. + - *Disadvantages:* higher bandwitdh +traffic, more expensive (as time) to generate by OpenSIPS; + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *usrloc* module - only if the NATed +contacts are to be pinged. +- *clusterer* - only if "cluster_id" +option is enabled. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### natping_interval (integer) + + +Period of time in seconds between sending the NAT pings to all +currently registered UAs to keep their NAT bindings alive. +Value of 0 disables this functionality. + + +> [!NOTE] +> Enabling the NAT pinging functionality will force the module to +bind itself to USRLOC module. + + +*Default value is 0.* + + +```opensips title="Set natping_interval parameter" +... +modparam("nathelper", "natping_interval", 10) +... +``` + + +#### ping_nated_only (integer) + + +If this variable is set then only contacts that have +"behind_NAT" flag in user location database set will +get ping. + + +*Default value is 0.* + + +```opensips title="Set ping_nated_only parameter" +... +modparam("nathelper", "ping_nated_only", 1) +... +``` + + +#### natping_partitions (integer) + + +How many partitions/chunks to be used for sending the pingings. +One partition means sending all pingings together. Two partitions +means to send half pings and second half at a time. + + +*Default value is 1.* +*Maximum allowed value is 8.* + + +```opensips title="Set natping_partitions parameter" +... +modparam("nathelper", "natping_partitions", 4) +... +``` + + +#### natping_socket (string) + + +Spoof the natping's source-ip to this address. Works only for IPv4. + + +*Default value is NULL.* + + +```opensips title="Set natping_socket parameter" +... +modparam("nathelper", "natping_socket", "192.168.1.1:5006") +... +``` + + +#### received_avp (str) + + +The name of the Attribute-Value-Pair (AVP) used to store the URI +containing the received IP, port and protocol. The URI is created +by the [fix nated register](#func_fix_nated_register) function and this data +may then be also picked up by the registrar module, which will attach a +"Received=" attribute to the registration. Do not forget to change the +value of corresponding parameter in the [registrar](../registrar) +module whenever you change the value of this parameter. + + +> [!NOTE] +> You must set this parameter if you use [fix nated register](#func_fix_nated_register). +Additionally, if you are using registrar, you must also set its symmetric +[received_avp](../registrar#received_avp) module parameter +to the **same value**. + + +*Default value is "NULL" (disabled).* + + +```opensips title="Set received_avp parameter" +... +modparam("nathelper", "received_avp", "$avp(received)") +... +``` + + +#### force_socket (string) + + +Sending socket to be used for pinging contacts without local socket +information (the local socket information may be lost during a restart +or contact replication). If no one specified, OpenSIPS will choose the +first listening interface matching the destination protocol and +AF family. + + +*Default value is "NULL".* + + +```opensips title="Set force_socket parameter" +... +modparam("nathelper", "force_socket", "localhost:33333") +... +``` + + +#### sipping_bflag (string) + + +What branch flag should be used by the module to identify NATed +contacts for which it should perform NAT ping via a SIP request +instead if dummy UDP package. + + +*Default value is NULL (disabled).* + + +```opensips title="Set sipping_bflag parameter" +... +modparam("nathelper", "sipping_bflag", "SIPPING_ENABLE") +... +``` + + +#### remove_on_timeout_bflag (string) + + +What branch flag to be used in order to activate usrloc contact removal when +the [ping threshold](#param_ping_threshold) is exceeded. + + +*Default value is NULL (disabled).* + + +```opensips title="Set remove_on_timeout_bflag parameter" +... +modparam("nathelper", "remove_on_timeout_bflag", "SIPPING_RTO") +... +``` + + +#### sipping_latency_flag (string) + + +The branch flag which will be used in order to enable contact pinging +latency computation and reporting via the usrloc E_UL_LATENCY_UPDATE +event. + + +*Default value is NULL (disabled).* + + +```opensips title="Set sipping_latency_flag parameter" +... +modparam("nathelper", "sipping_latency_flag", "SIPPING_CALC_LATENCY") +... +``` + + +#### sipping_ignore_rpl_codes (CSV string) + + +A comma-separated list of SIP reply status codes to contact pings which +are to be discarded. This may be useful for "full-sharing" user +location topologies, where the location nodes are not directly facing +the UAs, hence the intermediary SIP component may generate replies to +offline contact ping attempts (e.g. 408 - Request Timeout) -- such ping +replies should be ignored. + + +*Default value is "NULL" (all reply status codes are accepted).* + + +```opensips title="Set sipping_ignore_rpl_codes parameter" +... +modparam("nathelper", "sipping_ignore_rpl_codes", "408, 480, 404") +... +``` + + +#### sipping_from (string) + + +The parameter sets the SIP URI to be used in generating the SIP +requests for NAT ping purposes. To enable the SIP request pinging +feature, you have to set this parameter. The SIP request pinging +will be used only for requests marked so. + + +*Default value is "NULL".* + + +```opensips title="Set sipping_from parameter" +... +modparam("nathelper", "sipping_from", "sip:pinger@siphub.net") +... +``` + + +#### sipping_method (string) + + +The parameter sets the SIP method to be used in generating the SIP +requests for NAT ping purposes. + + +*Default value is "OPTIONS".* + + +```opensips title="Set sipping_method parameter" +... +modparam("nathelper", "sipping_method", "INFO") +... +``` + + +#### nortpproxy_str (string) + + +The parameter sets the SDP attribute used by nathelper to mark +the packet SDP informations have already been mangled. + + +If empty string, no marker will be added or checked. + + +> [!NOTE] +> The string must be a complete SDP line, including the EOH (\r\n). + + +*Default value is "a=nortpproxy:yes\r\n".* + + +```opensips title="Set nortpproxy_str parameter" +... +modparam("nathelper", "nortpproxy_str", "a=sdpmangled:yes\r\n") +... +``` + + +#### natping_tcp (integer) + + +If the flag is set, TCP/TLS clients will also be pinged with +SIP OPTIONS messages. + + +*Default value is 0 (not set).* + + +```opensips title="Set natping_tcp parameter" +... +modparam("nathelper", "natping_tcp", 1) +... +``` + + +#### oldip_skip (string) + + +Parameter which specifies whether old media ip and old origin ip +shall be put in the sdp body. The parameter has two values : +'o' ("a=oldoip" field shall be skipped) and 'c' ("a=oldcip" field +shall be skipped). + + +*Default value is 0 (not set).* + + +```opensips title="Set oldip_skip parameter" +... +modparam("nathelper", "oldip_skip", "oc") +... +``` + + +#### ping_threshold (int) + + +If a contact does not respond in *ping_threshold* +seconds since the ping has been sent, the contact shall be removed +after [max pings lost](#param_max_pings_lost) unresponded pings. + + +*Default value is 3 (seconds).* + + +```opensips title="Set ping_threshold parameter" +... +modparam("nathelper", "ping_threshold", 10) +... +``` + + +#### max_pings_lost (int) + + +Number of unresponded pings after which the contact shall be removed +from the location table. + + +*Default value is 3 (pings).* + + +```opensips title="Set max_pings_lost parameter" +... +modparam("nathelper", "max_pings_lost", 5) +... +``` + + +#### cluster_id (integer) + + +The ID of the cluster the module is part of. The clustering support is +used by the nathelper module for controlling the pinging process. When +part of a cluster of multiple nodes, the nodes can agree upon which node +is the one responsible for pinging. + + +The clustering with sharing tag support may be used to control which +node in the cluster will perform the pinging/probing to the +contacts. See the +[cluster sharing tag](#param_cluster_sharing_tag) option. + + +For more info on how to define and populate a cluster (with OpenSIPS +nodes) see the "clusterer" module. + + +*Default value is "0 (none)".* + + +```opensips title="Set cluster_id parameter" +... +# Be part of cluster ID 9 +modparam("nathelper", "cluster_id", 9) +... +``` + + +#### cluster_sharing_tag (string) + + +The name of the sharing tag (as defined per clusterer modules) to +control which node is responsible for perform pinging of the +contacts. +If defined, only the node with active status of this tag will +perform the pinging. + + +The [cluster id](#param_cluster_id) must be defined for this option +to work. + + +This is an optional parameter. If not set, all the nodes in the cluster +will individually do the pinging. + + +*Default value is "empty (none)".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +# only the node with the active "vip" sharing tag will perform pinging +modparam("nathelper", "cluster_id", 9) +modparam("nathelper", "cluster_sharing_tag", "vip") +... +``` + + +### Exported Functions + + +#### fix_nated_contact([uri_params]) + + +Rewrites the URI Contact HF to contain request's +source address:port. If a list of URI parameter is provided, it will +be added to the modified contact; + + +> [!IMPORTANT] +> Changes made by this function shall +> not be seen in the async resume route. So make sure you call it in all the +> resume routes where you need the contact fixed. + + +Parameters: + + +- *uri_params (string, optional)* + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. + + +```opensips title="fix_nated_contact usage" +... +if (search("User-Agent: Cisco ATA.*") { + fix_nated_contact(";ata=cisco"); +} else { + fix_nated_contact(); +} +... +``` + + +#### fix_nated_sdp(flags [, ip_address [, sdp_fields]]) + + +Alters the SDP information in orer to facilitate NAT traversal. What +changes to be performed may be controled via the +"flags" parameter. Since version 1.12 the name of the old +ip fields are "a=oldoip" for old origin ip and "a=oldcip" for old meda +ip. + + +Meaning of the parameters is as follows: + + +- *flags (string)* - the value may be a CSV of +the following flags: + + - *add-dir-active* - (old +*0x01* flag) adds +"a=direction:active" SDP line; + - *rewrite-media-ip* - (old +*0x02* flag) rewrite media +IP address (c=) with source address of the message +or the provided IP address (the provided IP address takes +precedence over the source address). + - *add-no-rtpproxy* - (old +*0x04* flag) adds +"a=nortpproxy:yes" SDP line; + - *rewrite-origin-ip* - (old +*0x08* flag) rewrite IP from +origin description (o=) with source address of the message +or the provided IP address (the provided IP address takes +precedence over the source address). + - *rewrite-null-ips* - (old +*0x10* flag) force rewrite of +null media IP and/or origin IP address. +Without this flag, null IPs are left untouched. +- *ip_address (string, optional)* - IP to be used for +rewriting SDP. If not specified, the received signalling IP will be used. +NOTE: For the IP to be used, you need to use 0x02 or 0x08 flags, +otherwise it will have no effect. +- *sdp_fields (string, optional)* - SDP field(s) to be appended to SDP. +Note: Each SDP field must be preceded by "\r\n". + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="fix_nated_sdp usage" +... +# Add "a=direction:active" SDP line +# Rewrite media IP (c= line) +# Add extra "a=x-attr1" SDP line +# Add extra "a=x-attr2" SDP line +if (search("User-Agent: Cisco ATA.*") + {fix_nated_sdp(3,,"\r\na=x-attr1\r\na=x-attr2");}; +... +``` + + +#### add_rcv_param([flag]), + + +Add received parameter to Contact header fields or Contact URI. +The parameter will +contain URI created from the source IP, port, and protocol of the +packet containing the SIP message. The parameter can be then +processed by another registrar, this is useful, for example, when +replicating register messages using t_replicate function to +another registrar. + + +Meaning of the parameters is as follows: + + +- *flag (int, optional)* - flags to indicate if +the parameter should be added to Contact URI or Contact header. +If the flag is non-zero, the parameter will be added to the Contact +URI. If not used or equal to zero, the parameter will go to the +Contact header. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="add_rcv_paramer usage" +... +add_rcv_param(); # add the parameter to the Contact header +.... +add_rcv_param(1); # add the parameter to the Contact URI +... +``` + + +#### fix_nated_register() + + +The function creates a URI consisting of the source IP, port and +protocol and stores it in the [received avp](#param_received_avp) AVP. The URI will +be appended as "received" parameter to Contact in 200 OK and +may also be stored in the user location database if the same AVP +is also configured for the [registrar](../registrar) module. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="fix_nated_register usage" +... +fix_nated_register(); +... +``` + + +#### nat_uac_test(flags) + + +Determines whether the received SIP message originated behind a NAT, +using one or more pre-defined checks. + + +The *flags* (string) parameter denotes a +comma-separated list of checks to be performed, as follows: + + +- *private-contact* - (old *1* flag) +Contact header field is searched for occurrence of RFC1918 / RFC6598 +addresses +- *diff-ip-src-via* - (old *2* flag) +the "received" test is used: address in Via is compared against source +IP address of signaling +- *private-via* - (old *4* flag) +Top Most VIA is searched for occurrence of RFC1918 / RFC6598 addresses +- *private-sdp* - (old *8* flag) +SDP is searched for occurrence of RFC1918 / RFC6598 addresses +- *diff-port-src-via* - (old *16* +flag) test if the source port is different from the port in Via +- *diff-ip-src-contact* - (old *32* +flag) address in Contact is compared against source IP address of +signaling +- *diff-port-src-contact* - (old *64* +flag) Port in Contact is compared against source port of signaling +- *carrier-grade-nat* - (old *128* +flag) also include RFC 6333 addresses in the checks for +*Contact*, *Via* and +*SDP* + + +**Returns true if any of the tests passed**. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="nat_uac_test usage" +... +# check for private Contact or SDP media IP addresses +if (nat_uac_test("private-contact,private-sdp")) + xlog("SIP message is NAT'ed (Call-ID: $ci)\n"); +... +``` + + +### Exported MI Functions + + +#### nh_enable_ping + + +Gets or sets the natpinging status. + + +Parameters: + + +- *status* (optional) - if not provided the function +returns the current natping status. Otherwise, enables natping if +parameter value greater than 0 or disables natping if parameter value is 0. + + +```bash title="nh_enable_ping usage" +... +$ opensips-cli -x mi nh_enable_ping +Status:: 1 +$ +$ opensips-cli -x mi nh_enable_ping 0 +$ +$ opensips-cli -x mi nh_enable_ping +Status:: 0 +$ +... + +``` + + +## Frequently Asked Questions + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/nathelper/doc/contributors.xml b/modules/nathelper/doc/contributors.xml deleted file mode 100644 index 97cec0a60a8..00000000000 --- a/modules/nathelper/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 156 - 123 - 2050 - 873 - - - 2. - Maksym Sobolyev (@sobomax) - 155 - 45 - 3556 - 4790 - - - 3. - Liviu Chircu (@liviuchircu) - 50 - 40 - 452 - 324 - - - 4. - Ionut Ionita (@ionutrazvanionita) - 40 - 15 - 1598 - 627 - - - 5. - Razvan Crainea (@razvancrainea) - 33 - 27 - 158 - 240 - - - 6. - Daniel-Constantin Mierla (@miconda) - 22 - 17 - 142 - 124 - - - 7. - Anca Vamanu - 22 - 4 - 1602 - 185 - - - 8. - Andrei Pelinescu-Onciul - 21 - 17 - 121 - 110 - - - 9. - Jan Janak (@janakj) - 21 - 11 - 780 - 129 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - 19 - 11 - 261 - 268 - - - -
-All remaining contributors: Jiri Kuthan (@jiriatipteldotorg), Ancuta Onofrei, Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Andrei Dragus, Henning Westerholt (@henningw), Dan Pascu (@danpascu), Christophe Sollet (@csollet), Marcus Hunger, Klaus Darilion, Sergio Gutierrez, Peter Lemenkov (@lemenkov), Nils Ohlmeier, Emmanuel Buu, Carsten Bock, Shlomi Gutman, Jeremie Le Hen, Bayan Towfiq, Laurent Schweizer, Jasper Hafkenscheid (@hafkensite), Konstantin Bokarius, Alexandra Titoc, John Riordan, Walter Doekes (@wdoekes), Elena-Ramona Modroiu, Nick Altmann (@nikbyte), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2013 - Nov 2024 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Nov 2003 - Jun 2024 - - - 4. - Maksym Sobolyev (@sobomax) - May 2003 - Nov 2023 - - - 5. - Vlad Paiu (@vladpaiu) - Aug 2010 - Jul 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2023 - - - 7. - Nick Altmann (@nikbyte) - May 2022 - May 2022 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Apr 2022 - - - 9. - Razvan Crainea (@razvancrainea) - Dec 2010 - Jan 2021 - - - 10. - Jasper Hafkenscheid (@hafkensite) - Mar 2020 - Mar 2020 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Shlomi Gutman, Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Walter Doekes (@wdoekes), Christophe Sollet (@csollet), Anca Vamanu, John Riordan, Emmanuel Buu, Andrei Dragus, Sergio Gutierrez, Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Ancuta Onofrei, Marcus Hunger, Carsten Bock, Jeremie Le Hen, Laurent Schweizer, Bayan Towfiq, Andrei Pelinescu-Onciul, Elena-Ramona Modroiu, Jiri Kuthan (@jiriatipteldotorg), Jan Janak (@janakj), Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Nick Altmann (@nikbyte), Jasper Hafkenscheid (@hafkensite), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Walter Doekes (@wdoekes), Christophe Sollet (@csollet), Vlad Paiu (@vladpaiu), Maksym Sobolyev (@sobomax), Anca Vamanu, Andrei Dragus, Sergio Gutierrez, Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Carsten Bock, Ancuta Onofrei, Marcus Hunger, Jeremie Le Hen, Bayan Towfiq, Elena-Ramona Modroiu, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). -
- -
diff --git a/modules/nathelper/doc/nathelper.xml b/modules/nathelper/doc/nathelper.xml deleted file mode 100644 index 6e1da5b35a1..00000000000 --- a/modules/nathelper/doc/nathelper.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - nathelper Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2018 VoIP Embedded, Inc. - ©right; 2003-2008 Sippy Software, Inc. - ©right; 2005 &voicesystem; - - diff --git a/modules/nathelper/doc/nathelper_admin.xml b/modules/nathelper/doc/nathelper_admin.xml deleted file mode 100644 index a24295bb1a6..00000000000 --- a/modules/nathelper/doc/nathelper_admin.xml +++ /dev/null @@ -1,876 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module to help with &nat; traversal. In particular, - it helps symmetric &ua;s that don't advertise they are symmetric - and are not able to determine their public address. fix_nated_contact - rewrites Contact header field with request's source address:port pair. - fix_nated_sdp adds the active direction indication to &sdp; (flag - 0x01) and updates source &ip; address too (flag 0x02). - - - Since version 2.2, stateful ping(only SIP Pings) for nathelper is available. - This allows you to remove contacts from usrloc location table when - max_pings_lost pings are not responded to, each ping - having a response timeout of ping_threshold seconds. - In order to have this functionality, contacts must have - remove_on_timeout_bflag flag set when inserted into - the location table. - - - Works with multipart messages that contain an SDP part, - but not with multi-layered multipart messages. - -
- -
- NAT pinging types - - Currently, the nathelper module supports two types of NAT pings: - - - - - UDP package - 4 bytes (zero filled) UDP - packages are sent to the contact address. - - - - Advantages: low bandwitdh traffic, - easy to generate by &osips;; - - - - Disadvantages: unidirectional - traffic through NAT (inbound - from outside to inside); As - many NATs do update the bind timeout only on outbound traffic, - the bind may expire and closed. - - - - - - - SIP request - a stateless SIP request is - sent to the contact address. - - - - Advantages: bidirectional traffic - through NAT, since each PING request from &osips; (inbound - traffic) will force the SIP client to generate a SIP reply - (outbound traffic) - the NAT bind will be surely kept open. - Since version 2.2, one can also choose to remove contacts - from the location table if a certain threshold is detected. - - - - Disadvantages: higher bandwitdh - traffic, more expensive (as time) to generate by &osips;; - - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - usrloc module - only if the NATed - contacts are to be pinged. - - - - - clusterer - only if "cluster_id" - option is enabled. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - -
- <varname>natping_interval</varname> (integer) - - Period of time in seconds between sending the NAT pings to all - currently registered &ua;s to keep their &nat; bindings alive. - Value of 0 disables this functionality. - - - Enabling the NAT pinging functionality will force the module to - bind itself to USRLOC module. - - - - Default value is 0. - - - - Set <varname>natping_interval</varname> parameter - -... -modparam("nathelper", "natping_interval", 10) -... - - -
- -
- <varname>ping_nated_only</varname> (integer) - - If this variable is set then only contacts that have - behind_NAT flag in user location database set will - get ping. - - - - Default value is 0. - - - - Set <varname>ping_nated_only</varname> parameter - -... -modparam("nathelper", "ping_nated_only", 1) -... - - -
- -
- <varname>natping_partitions</varname> (integer) - - How many partitions/chunks to be used for sending the pingings. - One partition means sending all pingings together. Two partitions - means to send half pings and second half at a time. - - - - Default value is 1. - - - Maximum allowed value is 8. - - - - Set <varname>natping_partitions</varname> parameter - -... -modparam("nathelper", "natping_partitions", 4) -... - - -
- -
- <varname>natping_socket</varname> (string) - - Spoof the natping's source-ip to this address. Works only for IPv4. - - - - Default value is NULL. - - - - Set <varname>natping_socket</varname> parameter - -... -modparam("nathelper", "natping_socket", "192.168.1.1:5006") -... - - -
- -
- <varname>received_avp</varname> (str) - - The name of the Attribute-Value-Pair (AVP) used to store the URI - containing the received IP, port and protocol. The URI is created - by the function and this data - may then be also picked up by the registrar module, which will attach a - "Received=" attribute to the registration. Do not forget to change the - value of corresponding parameter in the registrar - module whenever you change the value of this parameter. - - - - You must set this parameter if you use . - Additionally, if you are using registrar, you must also set its symmetric - received_avp module parameter - to the same value. - - - - - Default value is "NULL" (disabled). - - - - Set <varname>received_avp</varname> parameter - -... -modparam("nathelper", "received_avp", "$avp(received)") -... - - -
- -
- <varname>force_socket</varname> (string) - - Sending socket to be used for pinging contacts without local socket - information (the local socket information may be lost during a restart - or contact replication). If no one specified, OpenSIPS will choose the - first listening interface matching the destination protocol and - AF family. - - - - Default value is NULL. - - - - Set <varname>force_socket</varname> parameter - -... -modparam("nathelper", "force_socket", "localhost:33333") -... - - -
- -
- <varname>sipping_bflag</varname> (string) - - What branch flag should be used by the module to identify NATed - contacts for which it should perform NAT ping via a SIP request - instead if dummy UDP package. - - - - Default value is NULL (disabled). - - - - Set <varname>sipping_bflag</varname> parameter - -... -modparam("nathelper", "sipping_bflag", "SIPPING_ENABLE") -... - - -
- -
- <varname>remove_on_timeout_bflag</varname> (string) - - What branch flag to be used in order to activate usrloc contact removal when - the is exceeded. - - - - Default value is NULL (disabled). - - - - Set <varname>remove_on_timeout_bflag</varname> parameter - -... -modparam("nathelper", "remove_on_timeout_bflag", "SIPPING_RTO") -... - - -
- -
- <varname>sipping_latency_flag</varname> (string) - - The branch flag which will be used in order to enable contact pinging - latency computation and reporting via the usrloc E_UL_LATENCY_UPDATE - event. - - - - Default value is NULL (disabled). - - - - Set <varname>sipping_latency_flag</varname> parameter - -... -modparam("nathelper", "sipping_latency_flag", "SIPPING_CALC_LATENCY") -... - - -
- -
- <varname>sipping_ignore_rpl_codes</varname> (CSV string) - - A comma-separated list of SIP reply status codes to contact pings which - are to be discarded. This may be useful for "full-sharing" user - location topologies, where the location nodes are not directly facing - the UAs, hence the intermediary SIP component may generate replies to - offline contact ping attempts (e.g. 408 - Request Timeout) -- such ping - replies should be ignored. - - - - Default value is "NULL" (all reply status codes are accepted). - - - - Set <varname>sipping_ignore_rpl_codes</varname> parameter - -... -modparam("nathelper", "sipping_ignore_rpl_codes", "408, 480, 404") -... - - -
- -
- <varname>sipping_from</varname> (string) - - The parameter sets the SIP URI to be used in generating the SIP - requests for NAT ping purposes. To enable the SIP request pinging - feature, you have to set this parameter. The SIP request pinging - will be used only for requests marked so. - - - - Default value is NULL. - - - - Set <varname>sipping_from</varname> parameter - -... -modparam("nathelper", "sipping_from", "sip:pinger@siphub.net") -... - - -
- -
- <varname>sipping_method</varname> (string) - - The parameter sets the SIP method to be used in generating the SIP - requests for NAT ping purposes. - - - - Default value is OPTIONS. - - - - Set <varname>sipping_method</varname> parameter - -... -modparam("nathelper", "sipping_method", "INFO") -... - - -
- -
- <varname>nortpproxy_str</varname> (string) - - The parameter sets the SDP attribute used by nathelper to mark - the packet SDP informations have already been mangled. - - - If empty string, no marker will be added or checked. - - - The string must be a complete SDP line, including the EOH (\r\n). - - - - Default value is a=nortpproxy:yes\r\n. - - - - Set <varname>nortpproxy_str</varname> parameter - -... -modparam("nathelper", "nortpproxy_str", "a=sdpmangled:yes\r\n") -... - - -
- -
- <varname>natping_tcp</varname> (integer) - - If the flag is set, TCP/TLS clients will also be pinged with - SIP OPTIONS messages. - - - - Default value is 0 (not set). - - - - Set <varname>natping_tcp</varname> parameter - -... -modparam("nathelper", "natping_tcp", 1) -... - - -
- -
- <varname>oldip_skip</varname> (string) - - Parameter which specifies whether old media ip and old origin ip - shall be put in the sdp body. The parameter has two values : - 'o' ("a=oldoip" field shall be skipped) and 'c' ("a=oldcip" field - shall be skipped). - - - - Default value is 0 (not set). - - - - Set <varname>oldip_skip</varname> parameter - -... -modparam("nathelper", "oldip_skip", "oc") -... - - -
- -
- <varname>ping_threshold</varname> (int) - - If a contact does not respond in ping_threshold - seconds since the ping has been sent, the contact shall be removed - after unresponded pings. - - - - Default value is 3 (seconds). - - - - Set <varname>ping_threshold</varname> parameter - -... -modparam("nathelper", "ping_threshold", 10) -... - - -
- -
- <varname>max_pings_lost</varname> (int) - - Number of unresponded pings after which the contact shall be removed - from the location table. - - - - Default value is 3 (pings). - - - - Set <varname>max_pings_lost</varname> parameter - -... -modparam("nathelper", "max_pings_lost", 5) -... - - -
- -
- <varname>cluster_id</varname> (integer) - - The ID of the cluster the module is part of. The clustering support is - used by the nathelper module for controlling the pinging process. When - part of a cluster of multiple nodes, the nodes can agree upon which node - is the one responsible for pinging. - - - The clustering with sharing tag support may be used to control which - node in the cluster will perform the pinging/probing to the - contacts. See the - option. - - - For more info on how to define and populate a cluster (with OpenSIPS - nodes) see the "clusterer" module. - - - - Default value is 0 (none). - - - - Set <varname>cluster_id</varname> parameter - -... -# Be part of cluster ID 9 -modparam("nathelper", "cluster_id", 9) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (string) - - The name of the sharing tag (as defined per clusterer modules) to - control which node is responsible for perform pinging of the - contacts. - If defined, only the node with active status of this tag will - perform the pinging. - - - The must be defined for this option - to work. - - - This is an optional parameter. If not set, all the nodes in the cluster - will individually do the pinging. - - - - Default value is empty (none). - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -# only the node with the active "vip" sharing tag will perform pinging -modparam("nathelper", "cluster_id", 9) -modparam("nathelper", "cluster_sharing_tag", "vip") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">fix_nated_contact([uri_params])</function> - - - Rewrites the URI Contact HF to contain request's - source address:port. If a list of URI parameter is provided, it will - be added to the modified contact; - - - IMPORTANT NOTE: Changes made by this function shall - not be seen in the async resume route. So make sure you call it in all the - resume routes where you need the contact fixed. - - Parameters: - - - uri_params (string, optional) - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. - - - <function>fix_nated_contact</function> usage - -... -if (search("User-Agent: Cisco ATA.*") { - fix_nated_contact(";ata=cisco"); -} else { - fix_nated_contact(); -} -... - - -
-
- - <function moreinfo="none">fix_nated_sdp(flags [, ip_address [, sdp_fields]])</function> - - - Alters the SDP information in orer to facilitate NAT traversal. What - changes to be performed may be controled via the - flags parameter. Since version 1.12 the name of the old - ip fields are "a=oldoip" for old origin ip and "a=oldcip" for old meda - ip. - - Meaning of the parameters is as follows: - - - flags (string) - the value may be a CSV of - the following flags: - - - - add-dir-active - (old - 0x01 flag) adds - a=direction:active SDP line; - - - - rewrite-media-ip - (old - 0x02 flag) rewrite media - &ip; address (c=) with source address of the message - or the provided IP address (the provided IP address takes - precedence over the source address). - - - add-no-rtpproxy - (old - 0x04 flag) adds - a=nortpproxy:yes SDP line; - - - rewrite-origin-ip - (old - 0x08 flag) rewrite IP from - origin description (o=) with source address of the message - or the provided IP address (the provided IP address takes - precedence over the source address). - - - rewrite-null-ips - (old - 0x10 flag) force rewrite of - null media IP and/or origin IP address. - Without this flag, null IPs are left untouched. - - - - - ip_address (string, optional) - IP to be used for - rewriting SDP. If not specified, the received signalling IP will be used. - NOTE: For the IP to be used, you need to use 0x02 or 0x08 flags, - otherwise it will have no effect. - - - - sdp_fields (string, optional) - SDP field(s) to be appended to SDP. - Note: Each SDP field must be preceded by "\r\n". - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>fix_nated_sdp</function> usage - -... -# Add "a=direction:active" SDP line -# Rewrite media IP (c= line) -# Add extra "a=x-attr1" SDP line -# Add extra "a=x-attr2" SDP line -if (search("User-Agent: Cisco ATA.*") - {fix_nated_sdp(3,,"\r\na=x-attr1\r\na=x-attr2");}; -... - - -
-
- - <function moreinfo="none">add_rcv_param([flag])</function>, - - - Add received parameter to Contact header fields or Contact URI. - The parameter will - contain URI created from the source IP, port, and protocol of the - packet containing the SIP message. The parameter can be then - processed by another registrar, this is useful, for example, when - replicating register messages using t_replicate function to - another registrar. - - Meaning of the parameters is as follows: - - - flag (int, optional) - flags to indicate if - the parameter should be added to Contact URI or Contact header. - If the flag is non-zero, the parameter will be added to the Contact - URI. If not used or equal to zero, the parameter will go to the - Contact header. - - - - This function can be used from REQUEST_ROUTE. - - - <function>add_rcv_paramer</function> usage - -... -add_rcv_param(); # add the parameter to the Contact header -.... -add_rcv_param(1); # add the parameter to the Contact URI -... - - -
-
- - <function moreinfo="none">fix_nated_register()</function> - - - The function creates a URI consisting of the source IP, port and - protocol and stores it in the AVP. The URI will - be appended as "received" parameter to Contact in 200 OK and - may also be stored in the user location database if the same AVP - is also configured for the registrar module. - - - This function can be used from REQUEST_ROUTE. - - - <function>fix_nated_register</function> usage - -... -fix_nated_register(); -... - - -
-
- - <function>nat_uac_test(flags)</function> - - - Determines whether the received SIP message originated behind a NAT, - using one or more pre-defined checks. - - The flags (string) parameter denotes a - comma-separated list of checks to be performed, as follows: - - - private-contact - (old 1 flag) - Contact header field is searched for occurrence of RFC1918 / RFC6598 - addresses - - - diff-ip-src-via - (old 2 flag) - the "received" test is used: address in Via is compared against source - IP address of signaling - - - private-via - (old 4 flag) - Top Most VIA is searched for occurrence of RFC1918 / RFC6598 addresses - - - private-sdp - (old 8 flag) - SDP is searched for occurrence of RFC1918 / RFC6598 addresses - - - diff-port-src-via - (old 16 - flag) test if the source port is different from the port in Via - - - diff-ip-src-contact - (old 32 - flag) address in Contact is compared against source IP address of - signaling - - - diff-port-src-contact - (old 64 - flag) Port in Contact is compared against source port of signaling - - - carrier-grade-nat - (old 128 - flag) also include RFC 6333 addresses in the checks for - Contact, Via and - SDP - - - - Returns true if any of the tests passed. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>nat_uac_test</function> usage - -... -# check for private Contact or SDP media IP addresses -if (nat_uac_test("private-contact,private-sdp")) - xlog("SIP message is NAT'ed (Call-ID: $ci)\n"); -... - - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">nh_enable_ping</function> - - Gets or sets the natpinging status. - - Parameters: - - - status (optional) - if not provided the function - returns the current natping status. Otherwise, enables natping if - parameter value greater than 0 or disables natping if parameter value is 0. - - - - <function moreinfo="none">nh_enable_ping</function> usage - -... -$ opensips-cli -x mi nh_enable_ping -Status:: 1 -$ -$ opensips-cli -x mi nh_enable_ping 0 -$ -$ opensips-cli -x mi nh_enable_ping -Status:: 0 -$ -... - - -
- -
- -
- diff --git a/modules/nathelper/doc/nathelper_faq.xml b/modules/nathelper/doc/nathelper_faq.xml deleted file mode 100644 index 8d76f213036..00000000000 --- a/modules/nathelper/doc/nathelper_faq.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - &faqguide; - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/options/README b/modules/options/README deleted file mode 100644 index afc38cc2133..00000000000 --- a/modules/options/README +++ /dev/null @@ -1,240 +0,0 @@ -Options Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. accept (string) - 1.3.2. accept_encoding (string) - 1.3.3. accept_language (string) - 1.3.4. support (string) - - 1.4. Exported Functions - - 1.4.1. options_reply() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set accept parameter - 1.2. Set accept_encoding parameter - 1.3. Set accept_language parameter - 1.4. Set support parameter - 1.5. options_reply usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a function to answer OPTIONS requests - which are directed to the server itself. This means an OPTIONS - request which has the address of the server in the request URI, - and no username in the URI. The request will be answered with a - 200 OK which the capabilities of the server. - - To answer OPTIONS request directed to your server is the - easiest way for is-alive-tests on the SIP (application) layer - from remote (similar to ICMP echo requests, also known as - “ping”, on the network layer). - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * sl -- Stateless replies. - * signaling -- Stateless replies. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. accept (string) - - This parameter is the content of the Accept header field. If - “”, the header is not added in the reply. Note: it is not - clearly written in RFC3261 if a proxy should accept any content - (the default “*/*”) because it does not care about content. Or - if it does not accept any content, which is “”. - - Default value is “*/*”. - - Example 1.1. Set accept parameter -... -modparam("options", "accept", "application/*") -... - -1.3.2. accept_encoding (string) - - This parameter is the content of the Accept-Encoding header - field. If “”, the header is not added in the reply. Please do - not change the default value because OpenSIPS does not support - any encodings yet. - - Default value is “”. - - Example 1.2. Set accept_encoding parameter -... -modparam("options", "accept_encoding", "gzip") -... - -1.3.3. accept_language (string) - - This parameter is the content of the Accept-Language header - field. If “”, the header is not added in the reply. You can set - any language code which you prefer for error descriptions from - other devices, but presumably there are not much devices around - which support other languages then the default English. - - Default value is “en”. - - Example 1.3. Set accept_language parameter -... -modparam("options", "accept_language", "de") -... - -1.3.4. support (string) - - This parameter is the content of the Support header field. If - “”, the header is not added in the reply. Please do not change - the default value, because OpenSIPS currently does not support - any of the SIP extensions registered at the IANA. - - Default value is “”. - - Example 1.4. Set support parameter -... -modparam("options", "support", "100rel") -... - -1.4. Exported Functions - -1.4.1. options_reply() - - This function checks if the request method is OPTIONS and if - the request URI does not contain an username. If both is true - the request will be answered stateless with “200 OK” and the - capabilities from the modules parameters. - - It sends “500 Server Internal Error” for some errors and - returns false if it is called for a wrong request. - - The check for the request method and the missing username is - optional because it is also done by the function itself. But - you should not call this function outside the myself check - because in this case the function could answer OPTIONS requests - which are sent to you as outbound proxy but with an other - destination then your proxy (this check is currently missing in - the function). - - This function can be used from REQUEST_ROUTE. - - Example 1.5. options_reply usage -... -if (is_myself("$rd")) { - if (is_method("OPTIONS") && (! $ru=~"sip:.*[@]+.*")) { - options_reply(); - } -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 20 18 52 35 - 2. Daniel-Constantin Mierla (@miconda) 14 12 41 31 - 3. Liviu Chircu (@liviuchircu) 10 8 29 45 - 4. Nils Ohlmeier 10 3 630 4 - 5. Razvan Crainea (@razvancrainea) 8 5 85 88 - 6. Vlad Patrascu (@rvlad-patrascu) 5 3 9 6 - 7. Elena-Ramona Modroiu 4 2 4 4 - 8. Maksym Sobolyev (@sobomax) 4 2 3 4 - 9. Ancuta Onofrei 3 1 10 11 - 10. Jan Janak (@janakj) 3 1 7 7 - - All remaining contributors: Konstantin Bokarius, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jul 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Nov 2012 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Nov 2003 - Apr 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Daniel-Constantin Mierla (@miconda) Jul 2006 - Mar 2008 - 8. Konstantin Bokarius Mar 2008 - Mar 2008 - 9. Edson Gellert Schubert Feb 2008 - Feb 2008 - 10. Ancuta Onofrei Sep 2007 - Sep 2007 - - All remaining contributors: Elena-Ramona Modroiu, Jan Janak - (@janakj), Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad - Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), - Nils Ohlmeier. - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/options/README.md b/modules/options/README.md new file mode 100644 index 00000000000..14a2dbb5c9d --- /dev/null +++ b/modules/options/README.md @@ -0,0 +1,173 @@ +--- +title: "Options Module" +description: "This module provides a function to answer OPTIONS requests which are directed to the server itself." +--- + +## Admin Guide + + +### Overview + + +This module provides a function to answer OPTIONS requests which +are directed to the server itself. This means an OPTIONS request +which has the address of the server in the request URI, and no +username in the URI. The request will be answered with a 200 OK +which the capabilities of the server. + + +To answer OPTIONS request directed to your server is the easiest +way for is-alive-tests on the SIP (application) layer from remote +(similar to ICMP echo requests, also known as "ping", +on the network layer). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *sl* -- Stateless replies. +- *signaling* -- Stateless replies. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### accept (string) + + +This parameter is the content of the Accept header field. If +"", the header is not added in the reply. +Note: it is not clearly written in RFC3261 if a proxy should +accept any content (the default "*/*") because +it does not care about content. Or if it does not accept +any content, which is "". + + +*Default value is "*/*".* + + +```opensips title="Set accept parameter" +... +modparam("options", "accept", "application/*") +... +``` + + +#### accept_encoding (string) + + +This parameter is the content of the Accept-Encoding header field. +If "", the header is not added in the reply. +Please do not change the default value because OpenSIPS +does not support any encodings yet. + + +*Default value is "".* + + +```opensips title="Set accept_encoding parameter" +... +modparam("options", "accept_encoding", "gzip") +... +``` + + +#### accept_language (string) + + +This parameter is the content of the Accept-Language header field. +If "", the header is not added in the reply. +You can set any language code which you prefer for error +descriptions from other devices, but presumably there are not +much devices around which support other languages then the +default English. + + +*Default value is "en".* + + +```opensips title="Set accept_language parameter" +... +modparam("options", "accept_language", "de") +... +``` + + +#### support (string) + + +This parameter is the content of the Support header field. +If "", the header is not added in the reply. +Please do not change the default value, because OpenSIPS currently +does not support any of the SIP extensions registered at the IANA. + + +*Default value is "".* + + +```opensips title="Set support parameter" +... +modparam("options", "support", "100rel") +... +``` + + +### Exported Functions + + +#### options_reply() + + +This function checks if the request method is OPTIONS and +if the request URI does not contain an username. If both +is true the request will be answered stateless with +"200 OK" and the capabilities from the modules +parameters. + + +It sends "500 Server Internal Error" for some errors +and returns false if it is called for a wrong request. + + +The check for the request method and the missing username is +optional because it is also done by the function itself. But +you should not call this function outside the myself check +because in this case the function could answer OPTIONS requests +which are sent to you as outbound proxy but with an other +destination then your proxy (this check is currently missing +in the function). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="options_reply usage" +... +if (is_myself("$rd")) { + if (is_method("OPTIONS") && (! $ru=~"sip:.*[@]+.*")) { + options_reply(); + } +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/options/doc/contributors.xml b/modules/options/doc/contributors.xml deleted file mode 100644 index d4c58409edd..00000000000 --- a/modules/options/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 20 - 18 - 52 - 35 - - - 2. - Daniel-Constantin Mierla (@miconda) - 14 - 12 - 41 - 31 - - - 3. - Liviu Chircu (@liviuchircu) - 10 - 8 - 29 - 45 - - - 4. - Nils Ohlmeier - 10 - 3 - 630 - 4 - - - 5. - Razvan Crainea (@razvancrainea) - 8 - 5 - 85 - 88 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 9 - 6 - - - 7. - Elena-Ramona Modroiu - 4 - 2 - 4 - 4 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 9. - Ancuta Onofrei - 3 - 1 - 10 - 11 - - - 10. - Jan Janak (@janakj) - 3 - 1 - 7 - 7 - - - -
-All remaining contributors: Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jul 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Nov 2012 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Nov 2003 - Apr 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Daniel-Constantin Mierla (@miconda) - Jul 2006 - Mar 2008 - - - 8. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 9. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - 10. - Ancuta Onofrei - Sep 2007 - Sep 2007 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Jan Janak (@janakj), Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj), Nils Ohlmeier. -
- -
diff --git a/modules/options/doc/options.xml b/modules/options/doc/options.xml deleted file mode 100644 index f71efe34f79..00000000000 --- a/modules/options/doc/options.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Options Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/options/doc/options_admin.xml b/modules/options/doc/options_admin.xml deleted file mode 100644 index ef6aec2703d..00000000000 --- a/modules/options/doc/options_admin.xml +++ /dev/null @@ -1,199 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a function to answer OPTIONS requests which - are directed to the server itself. This means an OPTIONS request - which has the address of the server in the request URI, and no - username in the URI. The request will be answered with a 200 OK - which the capabilities of the server. - - - To answer OPTIONS request directed to your server is the easiest - way for is-alive-tests on the SIP (application) layer from remote - (similar to ICMP echo requests, also known as ping, - on the network layer). - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - sl -- Stateless replies. - - - - - signaling -- Stateless replies. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>accept</varname> (string) - - This parameter is the content of the Accept header field. If - , the header is not added in the reply. - Note: it is not clearly written in RFC3261 if a proxy should - accept any content (the default */*) because - it does not care about content. Or if it does not accept - any content, which is . - - - - Default value is */*. - - - - Set <varname>accept</varname> parameter - -... -modparam("options", "accept", "application/*") -... - - -
-
- <varname>accept_encoding</varname> (string) - - This parameter is the content of the Accept-Encoding header field. - If , the header is not added in the reply. - Please do not change the default value because &osips; - does not support any encodings yet. - - - - Default value is . - - - - Set <varname>accept_encoding</varname> parameter - -... -modparam("options", "accept_encoding", "gzip") -... - - -
-
- <varname>accept_language</varname> (string) - - This parameter is the content of the Accept-Language header field. - If , the header is not added in the reply. - You can set any language code which you prefer for error - descriptions from other devices, but presumably there are not - much devices around which support other languages then the - default English. - - - - Default value is en. - - - - Set <varname>accept_language</varname> parameter - -... -modparam("options", "accept_language", "de") -... - - -
-
- <varname>support</varname> (string) - - This parameter is the content of the Support header field. - If , the header is not added in the reply. - Please do not change the default value, because &osips; currently - does not support any of the SIP extensions registered at the IANA. - - - - Default value is . - - - - Set <varname>support</varname> parameter - -... -modparam("options", "support", "100rel") -... - - -
-
-
- Exported Functions -
- - <function moreinfo="none">options_reply()</function> - - - This function checks if the request method is OPTIONS and - if the request URI does not contain an username. If both - is true the request will be answered stateless with - 200 OK and the capabilities from the modules - parameters. - - - It sends 500 Server Internal Error for some errors - and returns false if it is called for a wrong request. - - - The check for the request method and the missing username is - optional because it is also done by the function itself. But - you should not call this function outside the myself check - because in this case the function could answer OPTIONS requests - which are sent to you as outbound proxy but with an other - destination then your proxy (this check is currently missing - in the function). - - - This function can be used from REQUEST_ROUTE. - - - <function>options_reply</function> usage - -... -if (is_myself("$rd")) { - if (is_method("OPTIONS") && (! $ru=~"sip:.*[@]+.*")) { - options_reply(); - } -} -... - - -
-
-
- diff --git a/modules/osp/README b/modules/osp/README deleted file mode 100644 index be5ae3c0a42..00000000000 --- a/modules/osp/README +++ /dev/null @@ -1,1045 +0,0 @@ -OSP Module for Secure, Multi-Lateral Peering - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. work_mode - 1.3.2. service_type - 1.3.3. sp1_uri, sp2_uri, ..., sp16_uri - 1.3.4. sp1_weight, sp2_weight, ..., sp16_weight - 1.3.5. device_ip - 1.3.6. use_security_features - 1.3.7. token_format - 1.3.8. private_key, local_certificate, - ca_certificates - - 1.3.9. enable_crypto_hardware_support - 1.3.10. ssl_lifetime - 1.3.11. persistence - 1.3.12. retry_delay - 1.3.13. retry_limit - 1.3.14. timeout - 1.3.15. support_nonsip_protocol - 1.3.16. max_destinations - 1.3.17. report_networkid - 1.3.18. validate_call_id - 1.3.19. use_number_portability - 1.3.20. append_userphone - 1.3.21. networkid_location - 1.3.22. networkid_parameter - 1.3.23. switchid_location - 1.3.24. switchid_parameter - 1.3.25. parameterstring_location - 1.3.26. parameterstring_value - 1.3.27. source_device_avp - 1.3.28. source_networkid_avp - 1.3.29. source_switchid_avp - 1.3.30. custom_info_avp - 1.3.31. cnam_avp - 1.3.32. extraheaders_value - 1.3.33. source_media_avp, destination_media_avp - 1.3.34. request_date_avp - 1.3.35. sdp_fingerprint_avp - 1.3.36. identity_signature_avp, - identity_algorithm_avp, - identity_information_avp, identity_type_avp, - identity_canon_avp - - 1.3.37. service_provider_avp - 1.3.38. user_group_avp - 1.3.39. user_id_avp - - 1.4. Exported Functions - - 1.4.1. checkospheader() - 1.4.2. validateospheader() - 1.4.3. getlocaladdress() - 1.4.4. setrequestdate() - 1.4.5. requestosprouting() - 1.4.6. checkosproute() - 1.4.7. prepareosproute() - 1.4.8. prepareospresponse() - 1.4.9. prepareallosproutes() - 1.4.10. checkcallingtranslation() - 1.4.11. reportospusage() - 1.4.12. processsubscribe([cachedcnamrecord]) - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Instructing the module to work in direct mode - 1.2. Instructing the module to provide normal voice service - 1.3. Setting the OSP servers - 1.4. Setting the OSP server weights - 1.5. Setting the device IP address - 1.6. Instructing the module not to use OSP security features - 1.7. Setting the token format - 1.8. Set authorization files - 1.9. Setting the hardware support - 1.10. Setting the ssl lifetime - 1.11. Setting the persistence - 1.12. Setting the retry delay - 1.13. Setting the retry limit - 1.14. Setting the timeout - 1.15. Setting support non-SIP destination devices - 1.16. Setting the number of destination - 1.17. Setting report network ID flag - 1.18. Instructing the module to validate call id - 1.19. Instructing the module to use number portability - parameters in Request URI - - 1.20. Append user=phone parameter - 1.21. Append networkid location - 1.22. Networkid parameter name - 1.23. Append switchid location - 1.24. Networkid parameter name - 1.25. Append parameter string location - 1.26. Parameter string value - 1.27. Setting the source device IP AVP - 1.28. Setting the source network ID AVP - 1.29. Setting the source switch ID AVP - 1.30. Setting the custom info AVP - 1.31. Setting the CNAM AVP - 1.32. Setting the NOTIFY extra headers - 1.33. Setting the media address AVPs - 1.34. Setting the request date AVP - 1.35. Setting the SDP finger print AVP - 1.36. Setting the Identity related AVPs - 1.37. Setting the source service provider AVP - 1.38. Setting the source user group AVP - 1.39. Setting the source user ID AVP - 1.40. checkospheader usage - 1.41. validateospheader usage - 1.42. getlocaladress usage - 1.43. setrequestdate usage - 1.44. requestosprouting usage - 1.45. checkosproute usage - 1.46. prepareosproute usage - 1.47. prepareospresponse usage - 1.48. prepareallosproutes usage - 1.49. checkcallingtranslation usage - 1.50. reportospusage usage - 1.51. processsubscribe usage - -Chapter 1. Admin Guide - -1.1. Overview - - The OSP module enables OpenSIPS to support secure, - multi-lateral peering using the OSP standard defined by ETSI - (TS 101 321 V4.1.1). This module will enable your OpenSIPS to: - * Send a peering authorization request to a peering server. - * Validate a digitally signed peering authorization token - received in a SIP INVITE message. - * Report usage information to a peering server. - -1.2. Dependencies - - The OSP module depends on the following modules which must be - loaded before the OSP module. - * auth -- Authentication Framework module - * sqlops -- SQL operation module - * maxfwd -- Max-Forward processor module - * mi_fifo -- FIFO support for Management Interface - * options -- OPTIONS server replier module - * proto_udp -- UDP protocol module - implements UDP-plain - transport for SIP - * registrar -- SIP Registrar implementation module - * rr -- Record-Route and Route module - * signaling -- SIP signaling module - * sipmsgops -- SIP operations module - * sl -- Stateless replier module - * tm -- Transaction (stateful) module - * uac -- UAC functionalies (FROM mangling and UAC auth) - * uac_auth -- UAC Authentication functionality - * usrloc -- User location implementation module - * OSP Toolkit -- The OSP Toolkit, available from - https://github.com/TransNexus/osptoolkit, must be built - before building OpenSIPS with the OSP module. For - instructions on building OpenSIPS with the OSP Toolkit, see - http://www.http://transnexus.com/wp-content/uploads/OSP-Rou - ting-and-CDR-Collection-Server-with-OpenSIPS-1.7.2.pdf. For - OpenSIPS 2.4.0, OSP Toolkit 4.16.0 or later versions should - be used. - -1.3. Exported Parameters - -1.3.1. work_mode - - The work_mode (integer) parameter instructs the OSP module what - mode it should work in. If this value is set to 0, the OSP - module works in direct mode. If this value is set to 1, the OSP - module works in indirect mode. The default value is 0. - - Example 1.1. Instructing the module to work in direct mode -modparam("osp","work_mode",0) - -1.3.2. service_type - - The service_type (integer) parameter instructs the OSP module - what services it should provide. If this value is set to 0, the - OSP module provides normal voice service. If this value is set - to 1, the OSP module provides ported number query service. If - this value is set to 2, the OSP module provides CNAM query - service. The default value is 0. - - Example 1.2. Instructing the module to provide normal voice - service -modparam("osp","service_type",0) - -1.3.3. sp1_uri, sp2_uri, ..., sp16_uri - - These sp_uri (string) parameters define peering servers to be - used for requesting peering authorization and routing - information. At least one peering server must be configured. - Others are required only if there are more than one peering - servers. Each peering server address takes the form of a - standard URL, and consists of up to four components: - * An optional indication of the protocol to be used for - communicating with the peering server. Both HTTP and HTTP - secured with SSL/TLS are supported and are indicated by - "http://" and "https://" respectively. If the protocol is - not explicitly indicated, the OpenSIPS defaults to HTTP - secured with SSL. - * The Internet domain name for the peering server. An IP - address may also be used, provided it is enclosed in square - brackets such as [172.16.1.1]. - * An optional TCP port number for communicating with the - peering server. If the port number is omitted, the OpenSIPS - defaults to port 5045 (for HTTP) or port 1443 (for HTTP - secured with SSL). - The uniform resource identifier for requests to the peering - server. This component is not optional and must be - included. - - Example 1.3. Setting the OSP servers -modparam("osp","sp1_uri","http://osptestserver.transnexus.com:5045/osp") -modparam("osp","sp2_uri","https://[1.2.3.4]:1443/osp") - -1.3.4. sp1_weight, sp2_weight, ..., sp16_weight - - These sp_weight (integer) parameters are used for load - balancing peering requests to peering servers. These parameters - are most effective when configured as factors of 1000. For - example, if sp1_uri should manage twice the traffic load of - sp2_uri, then set sp1_weight to 2000 and sp2_weight to 1000. - Shared load balancing between peering servers is recommended. - However, peering servers can be configured as primary and - backup by assigning a sp_weight of 0 to the primary server and - a non-zero sp_weight to the back-up server. The default values - for sp1_weight and sp2_weight are 1000. - - Example 1.4. Setting the OSP server weights -modparam("osp","sp1_weight",1000) - -1.3.5. device_ip - - The device_ip (string) is a recommended parameter that - explicitly defines the IP address of OpenSIPS in a peering - request message (as SourceAlternate type=transport). The - dotted-decimal IP address must be in brackets as shown in the - example below. - - Example 1.5. Setting the device IP address -modparam("osp","device_ip","[127.0.0.1]:5060") - -1.3.6. use_security_features - - The use_security_features (integer) parameter instructs the OSP - module how to use the OSP security features. If this value is - set to 1, the OSP module uses the OSP security features. If - this value is set to 0, the OSP module will not use the OSP - security features. The default value is 0. - - Example 1.6. Instructing the module not to use OSP security - features -modparam("osp","use_security_features",0) - -1.3.7. token_format - - When OpenSIPS receives a SIP INVITE with a peering token, the - OSP module will validate the token to determine whether or not - the call has been authorized by a peering server. Peering - tokens may, or may not, be digitally signed. The token_format - (integer) parameter defines if OpenSIPS will validate signed or - unsigned tokens or both. The values for token format are - defined below. The default value is 2. - - If use_security_features parameter is set to 0, signed tokens - cannot be validated. - - 0 - Validate only signed tokens. Calls with valid signed tokens - are allowed. - - 1 - Validate only unsigned tokens. Calls with valid unsigned - tokens are allowed. - - 2 - Validate both signed and unsigned tokens are allowed. Calls - with valid tokens are allowed. - - Example 1.7. Setting the token format -modparam("osp","token_format",2) - -1.3.8. private_key, local_certificate, ca_certificates - - These parameters identify files are used for validating peering - authorization tokens and establishing a secure channel between - OpenSIPS and a peering server using SSL. The files are - generated using the 'Enroll' utility from the OSP Toolkit. By - default, the proxy will look for pkey.pem, localcert.pem, and - cacart_0.pem in the default configuration directory. The - default config directory is set at compile time using CFG_DIR - and defaults to /usr/local/etc/opensips/. The files may be - copied to the expected file location or the parameters below - may be changed. - - If use_security_features parameter is set to 0, these - parameters will be ignored. - - Example 1.8. Set authorization files - - If the default CFG_DIR value was used at compile time, the - files will be loaded from: -modparam("osp","private_key","/usr/local/etc/opensips/pkey.pem") -modparam("osp","local_certificate","/usr/local/etc/opensips/localcert.pe -m") -modparam("osp","ca_certificates","/usr/local/etc/opensips/cacert.pem") - -1.3.9. enable_crypto_hardware_support - - The enable_crypto_hardware_support (integer) parameter is used - to set the cryptographic hardware acceleration engine in the - openssl library. The default value is 0 (no crypto hardware is - present). If crypto hardware is used, the value should be set - to 1. - - Example 1.9. Setting the hardware support -modparam("osp","enable_crypto_hardware_support",0) - -1.3.10. ssl_lifetime - - The ssl_lifetime (integer) parameter defines the lifetime, in - seconds, of a single SSL session key. Once this time limit is - exceeded, the OSP module will negotiate a new session key. - Communication exchanges in progress will not be interrupted - when this time limit expires. This is an optional field with - default value is 200 seconds. - - Example 1.10. Setting the ssl lifetime -modparam("osp","ssl_lifetime",200) - -1.3.11. persistence - - The persistence (integer) parameter defines the time, in - seconds, that an HTTP connection should be maintained after the - completion of a communication exchange. The OSP module will - maintain the connection for this time period in anticipation of - future communication exchanges to the same peering server. - - Example 1.11. Setting the persistence -modparam("osp","persistence",1000) - -1.3.12. retry_delay - - The retry_delay (integer) parameter defines the time, in - seconds, between retrying connection attempts to an OSP peering - server. After exhausting all peering servers the OSP module - will delay for this amount of time before resuming connection - attempts. This is an optional field with default value is 1 - second. - - Example 1.12. Setting the retry delay -modparam("osp","retry_delay",1) - -1.3.13. retry_limit - - The retry_limit (integer) parameter defines the maximum number - of retries for connection attempts to a peering server. If no - connection is established after this many retry attempts to all - peering servers, the OSP module will cease connection attempts - and return appropriate error codes. This number does not count - the initial connection attempt, so that a retry_limit of 1 will - result in a total of two connection attempts to every peering - server. The default value is 2. - - Example 1.13. Setting the retry limit -modparam("osp","retry_limit",2) - -1.3.14. timeout - - The timeout (integer) parameter defines the maximum time in - milliseconds, to wait for a response from a peering server. If - no response is received within this time, the current - connection is aborted and the OSP module attempts to contact - the next peering server. The default value is 10 seconds. - - Example 1.14. Setting the timeout -modparam("osp","timeout",10) - -1.3.15. support_nonsip_protocol - - The support_nonsip_protocol (integer) parameter is used to tell - the OSP module if non-SIP signaling protocol destination - devices are supported. The default value is 0. - - Example 1.15. Setting support non-SIP destination devices -modparam("osp","support_nonsip_protocol",0) - -1.3.16. max_destinations - - The max_destinations (integer) parameter defines the maximum - number of destinations that OpenSIPS requests the peering - server to return in a peering response. The OSP module supports - up to 12 destinations. The default value is 12. - - Example 1.16. Setting the number of destination -modparam("osp","max_destinations",12) - -1.3.17. report_networkid - - The report_networkid (integer) parameter is used to tell the - OSP module if to report network ID in completed call CDRs. If - it is set to 0, ths OSP module does not report any network ID. - If it is set to 1, the OSP module reports source network ID. If - it is set to 2, the OSP module reports destination network ID. - If it is set to 3, the OSP module report both source and - destination network IDs. The default value is 3. - - Example 1.17. Setting report network ID flag -modparam("osp","report_networkid",3) - -1.3.18. validate_call_id - - The validate_call_id (integer) parameter instructs the OSP - module to validate call id in the peering token. If this value - is set to 1, the OSP module validates that the call id in the - SIP INVITE message matches the call id in the peering token. If - they do not match the INVITE is rejected. If this value is set - to 0, the OSP module will not validate the call id in the - peering token. The default value is 1. - - Example 1.18. Instructing the module to validate call id -modparam("osp","validate_call_id",1) - -1.3.19. use_number_portability - - The use_number_portability (integer) parameter instructs the - OSP module how to use the number portability parameters in the - Request URI of the SIP INVITE message. If this value is set to - 1, the OSP module uses the number portability parameters in the - Request URI when these parameters exist. If this value is set - to 0, the OSP module will not use the number portability - parameters. The default value is 1. - - Example 1.19. Instructing the module to use number portability - parameters in Request URI -modparam("osp","use_number_portablity",1) - -1.3.20. append_userphone - - The append_userphone (integer) parameter instructs the OSP - module if to append "user=phone" parameter in URI. If this - value is set to 0, the OSP module does not append "user=phone" - parameter. If this value is set to 1, the OSP module will - append "user=phone" parameter. The default value is 0 - - Example 1.20. Append user=phone parameter -modparam("osp","append_userphone",0) - -1.3.21. networkid_location - - The networkid_location (integer) parameter instructs the OSP - module where the destination network ID should be appended. The - default value is 2 - - 0 - network ID is not appended. - - 1 - network ID is appended as userinfo parameter. - - 2 - network ID is appended as URI parameter. - - Example 1.21. Append networkid location -modparam("osp","networkid_location",2) - -1.3.22. networkid_parameter - - The networkid_parameter (string) parameter instructs the OSP - module to use which parameter name in outbound destination URIs - to append destination network ID. The default value is - "networkid" - - Example 1.22. Networkid parameter name -modparam("osp","networkid_param","networkid") - -1.3.23. switchid_location - - The switchid_location (integer) parameter instructs the OSP - module where the destination switch ID should be appended. The - default value is 2 - - 0 - switch ID is not appended. - - 1 - switch ID is appended as userinfo parameter. - - 2 - switch ID is appended as URI parameter. - - Example 1.23. Append switchid location -modparam("osp","switchid_location",2) - -1.3.24. switchid_parameter - - The switchid_parameter (string) parameter instructs the OSP - module to use which parameter name in outbound destination URIs - to append destination switch ID. The default value is - "switchid" - - Example 1.24. Networkid parameter name -modparam("osp","switchid_param","switchid") - -1.3.25. parameterstring_location - - The parameterstring_location (integer) parameter instructs the - OSP module where the parameter string should be appended. The - default value is 0 - - 0 - parameter string is not appended. - - 1 - parameter string is appended as userinfo parameter. - - 2 - parameter string is appended as URI parameter. - - Example 1.25. Append parameter string location -modparam("osp","parameterstring_location",0) - -1.3.26. parameterstring_value - - The parameterstring_value (string) parameter instructs the OSP - module to append the parameter string in outbound URIs. The - default value is "" - - Example 1.26. Parameter string value -modparam("osp","parameterstring_value","") - -1.3.27. source_device_avp - - The source_device_avp (string) parameter instructs the OSP - module to use the defined AVP to pass the source device IP - value in the indirect work mode. The default value is - "$avp(_osp_source_device_)". Then the source device IP can be - set by "$avp(_osp_source_device_) = pseudo-variables". All - pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.27. Setting the source device IP AVP -modparam("osp","source_device_avp","$avp(srcdev)") - -1.3.28. source_networkid_avp - - The source_networkid_avp (string) parameter instructs the OSP - module to use the defined AVP to pass the source network ID - value. The default value is "$avp(_osp_source_networkid_)". - Then the source network ID can be set by - "$avp(_osp_source_networkid_) = pseudo-variables". All pseudo - variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.28. Setting the source network ID AVP -modparam("osp","source_networkid_avp","$avp(snid)") - -1.3.29. source_switchid_avp - - The source_switchid_avp (string) parameter instructs the OSP - module to use the defined AVP to pass the source switch ID - value. The default value is "$avp(_osp_source_switchid_)". Then - the source switch ID can be set by "$avp(_osp_source_switchid_) - = pseudo-variables". All pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.29. Setting the source switch ID AVP -modparam("osp","source_switchid_avp","$avp(swid)") - -1.3.30. custom_info_avp - - The custom_info_avp (string) parameter instructs the OSP module - to use the defined AVP to pass the custom information values. - The default value is "$avp(_osp_custom_info_)". Then the custom - information can be set by "$avp(_osp_custom_info_) = - pseudo-variables". All pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.30. Setting the custom info AVP -modparam("osp","custom_info_avp","$avp(cinfo)") - -1.3.31. cnam_avp - - The cnam_avp (string) parameter instructs the OSP module to use - the defined AVP to pass the CNAM values. The default value is - "$avp(_osp_cnam_)". Then the CNAM can be used by - "$avp(_osp_cnam_)". All pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.31. Setting the CNAM AVP -modparam("osp","cnam_avp","$avp(cnam)") - -1.3.32. extraheaders_value - - The extraheaders_value (string) parameter instructs the OSP - module to append the defined SIP headers in outbound SIP NOTIFY - messages. The default value is empty. - - Example 1.32. Setting the NOTIFY extra headers -modparam("osp", "extraheaders_value", "Source: N") - -1.3.33. source_media_avp, destination_media_avp - - These parameters are used to tell the OSP module which AVPs are - used to store media addresses. The default values are - "$avp(_osp_source_media_address_)" and - "$avp(_osp_destination_media_address_)". All pseudo variables - are described in https://opensips.org/Resources/DocsCoreVar. - - Example 1.33. Setting the media address AVPs -modparam("osp", "source_media_avp", "$avp(srcmedia)") -modparam("osp", "destination_media_avp", "$avp(destmedia)") - -1.3.34. request_date_avp - - The request_date_avp (string) parameter instructs the OSP - module to use the defined AVP to pass the SIP request Date - header values. The default value is "$avp(_osp_request_date_)". - Then the request date can be used by - "$avp(_osp_request_date_)". All pseudo variables are described - in https://opensips.org/Resources/DocsCoreVar. - - Example 1.34. Setting the request date AVP -modparam("osp","request_date_avp","$avp(reqdate)") - -1.3.35. sdp_fingerprint_avp - - The sdp_fingerprint_avp (string) parameter instructs the OSP - module to use the defined AVP to pass the SDP fing print - attribute values. The default value is - "$avp(_osp_sdp_fingerprint_)". Then the SDP finger print - attributes can be used by "$avp(_osp_sdp_fingerprint_)". All - pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.35. Setting the SDP finger print AVP -modparam("osp","sdp_fingerprint_avp","$avp(sdpfp)") - -1.3.36. identity_signature_avp, identity_algorithm_avp, -identity_information_avp, identity_type_avp, identity_canon_avp - - These parameters instruct the OSP module to use the defined - AVPs to pass the Identity related values. The default values - are "$avp(_osp_identity_signature_)", - "$avp(_osp_identity_algorithm_)", - "$avp(_osp_identity_information_)", - "$avp(_osp_identity_type_)", "$avp(_osp_identity_canon_)". Then - the indentity related values can be used by these AVPs. All - pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.36. Setting the Identity related AVPs -modparam("osp","identity_signature_avp","$avp(idsign)") -modparam("osp","identity_algorithm_avp","$avp(idalg)") -modparam("osp","identity_information_avp","$avp(idinfo)") -modparam("osp","identity_type_avp","$avp(idtype)") -modparam("osp","identity_canon_avp","$avp(idcanon)") - -1.3.37. service_provider_avp - - These parameter is used to tell the OSP module which AVP is - used to store source service provider information. The default - value is "$avp(_osp_service_provider_)". All pseudo variables - are described in https://opensips.org/Resources/DocsCoreVar. - - Example 1.37. Setting the source service provider AVP -modparam("osp", "service_provider_avp", "$avp(sp)") - -1.3.38. user_group_avp - - These parameter is used to tell the OSP module which AVP is - used to store source user group information. The default value - is "$avp(_osp_user_group_)". All pseudo variables are described - in https://opensips.org/Resources/DocsCoreVar. - - Example 1.38. Setting the source user group AVP -modparam("osp", "user_group_avp", "$avp(groupid)") - -1.3.39. user_id_avp - - These parameter is used to tell the OSP module which AVP is - used to store source user ID information. The default value is - "$avp(_osp_user_id_)". All pseudo variables are described in - https://opensips.org/Resources/DocsCoreVar. - - Example 1.39. Setting the source user ID AVP -modparam("osp", "user_id_avp", "$avp(userid)") - -1.4. Exported Functions - -1.4.1. checkospheader() - - This function checks for the existence of the OSP-Auth-Token - header field. - - This function can be used from REQUEST_ROUTE. - - Example 1.40. checkospheader usage -... -if (checkospheader()) { - log(1,"OSP header field found.\n"); -} else { - log(1,"no OSP header field present\n"); -}; -... - -1.4.2. validateospheader() - - This function validates an OSP-Token specified in the - OSP-Auth-Tokenheader field of the SIP message. If a peering - token is present, it will be validated locally. If no OSP - header is found or the header token is invalid or expired, -1 - is returned; on successful validation 1 is returned. - - This function can be used from REQUEST_ROUTE. - - Example 1.41. validateospheader usage -... -if (validateospheader()) { - log(1,"valid OSP header found\n"); -} else { - log(1,"OSP header not found, invalid or expired\n"); -}; -... - -1.4.3. getlocaladdress() - - This function gets the receiving IP address of SIP response and - stores it as proxy egress address. - - This function can be used from ONREPLY_ROUTE. - - Example 1.42. getlocaladress usage -... -if (getlocaladdress()) { - log(1,"Obtain proxy local egress address\n"); -} else { - log(1,"Failed to get proxy local egress address\n"); -}; -... - -1.4.4. setrequestdate() - - This function gets the receiving IP address of SIP response and - stores it as proxy egress address. - - This function can be used from REQUEST_ROUTE. - - Example 1.43. setrequestdate usage -... -if (setrequest()) { - log(1,"Set request date\n"); -} else { - log(1,"Failed to set request date\n"); -}; -... - -1.4.5. requestosprouting() - - This function launches a query to the peering server requesting - the IP address of one or more destination peers serving the - called party. If destination peers are available, the peering - server will return the IP address and a peering authorization - token for each destination peer. The OSP-Auth-Token Header - field is inserted into the SIP message and the SIP uri is - rewritten to the IP address of destination peer provided by the - peering server. - - The address of the called party must be a valid E164 number, - otherwise this function returns -1. If the transaction was - accepted by the peering server, the uri is being rewritten and - 1 returned, on errors (peering servers are not available, - authentication failed or there is no route to destination or - the route is blocked) -1 is returned. - - This function can be used from REQUEST_ROUTE. - - Example 1.44. requestosprouting usage -... -if (requestosprouting()) { - log(1,"successfully queried OSP server, now relaying call\n"); -} else { - log(1,"Authorization request was rejected from OSP server\n"); -}; -... - -1.4.6. checkosproute() - - This function is used to check if there is any route for the - call. - - This function can be used from REQUEST_ROUTE. - - Example 1.45. checkosproute usage -... -if (checkosproute()) { - log(1,"There is at least one route for the call\n"); -} else { - log(1,"There is not any route for the call\n"); -}; -... - -1.4.7. prepareosproute() - - This function tries to prepare the INVITE to be forwarded using - the destination in the list returned by the peering server. If - the calling number is translated, a RPID value for the RPID AVP - will be set. If the route could not be prepared, the function - returns 'FALSE' back to the script, which can then decide how - to handle the failure. Note, if checkosproute has been called - and returns 'TRUE' before calling prepareosproute, - prepareosproute should not return 'FALSE' because checkosproute - has confirmed that there is at least one route. - - This function can be used from BRANCH_ROUTE. - - Example 1.46. prepareosproute usage -... -if (prepareosproute()) { - log(1,"successfully prepared the route, now relaying call\n"); -} else { - log(1,"could not prepare the route, there is not route\n"); -}; -... - -1.4.8. prepareospresponse() - - This function tries to prepare all the routes in the list - returned by the peering server into SIP 300 Redirect or SIP 380 - Alternative Service message. The message is then replied to the - source. If unsuccessful in preparing the routes a SIP 500 is - sent back and a trace message is logged. - - This function can be used from REQUEST_ROUTE. - - Example 1.47. prepareospresponse usage -... -if (prepareospresponse()) { - log(1,"Response is prepared.\n"); -} else { - log(1,"Could not prepare the response.\n"); -}; -... - -1.4.9. prepareallosproutes() - - This function tries to prepare all the routes in the list - returned by the peering server. The message is then forked off - to the destinations. If unsuccessful in preparing the routes a - SIP 500 is sent back and a trace message is logged. - - This function can be used from REQUEST_ROUTE. - - Example 1.48. prepareallosproutes usage -... -if (prepareallosproutes()) { - log(1,"Routes are prepared, now forking the call\n"); -} else { - log(1,"Could not prepare the routes. No destination available\n"); -}; -... - -1.4.10. checkcallingtranslation() - - This function is used to check if the calling number is - translated. Before calling checkcallingtranslation, - prepareosproute should be called. If the calling number does - been translated, the original Remote-Party-ID, if it exists, - should be removed from the INVITE message. And a new - Remote-Party-ID header should be added (a RPID value for the - RPID AVP has been set by prepareosproute). If the calling - number is not translated, nothing should be done. - - This function can be used from BRANCH_ROUTE. - - Example 1.49. checkcallingtranslation usage -... -if (checkcallingtranslation()) { - # Remove the Remote_Party-ID from the received message - # Otherwise it will be forwarded on to the next hop - remove_hf("Remote-Party-ID"); - - # Append a new Remote_Party - append_rpid_hf(); -} -... - -1.4.11. reportospusage() - - This function should be called after receiving a BYE message. - If the message contains an OSP cookie, the function will - forward originating and/or terminating duration usage - information to a peering server. The function returns TRUE if - the BYE includes an OSP cookie. The actual usage message will - be send on a different thread and will not delay BYE - processing. The function should be called before relaying the - message. - - Meaning of the parameter is as follows: - * 0 - Source device releases the call. - * 1 - Destination device releases the call. - - This function can be used from REQUEST_ROUTE. - - Example 1.50. reportospusage usage -... -if (is_direction("downstream")) { - log(1,"This BYE message is from SOURCE\n"); - if (!reportospusage(0)) { - log(1,"This BYE message does not include OSP usage information\n"); - } -} else { - log(1,"This BYE message is from DESTINATION\n"); - if (!reportospusage(1)) { - log(1,"This BYE message does not include OSP usage information\n"); - } -} -... - -1.4.12. processsubscribe([cachedcnamrecord]) - - This function should be called after receiving a SUBSCRIBE for - CNAM message and there is a cached CNAM record for this - message. This function generates a NOTIFY message including the - cached CNAM record, then sends the NOTIFY message to the device - sending the SUBSCRIBE message. - - Meaning of the parameter is as follows: - * cachedcnamrecord (string) - Cached CNAM record. - - This function can be used from REQUEST_ROUTE. - - Example 1.51. processsubscribe usage -... -if (is_method("SUBSCRIBE")) { - if (($var(sevent) == "calling-name") && (is_myself("$rd"))) { - if ($var(cnamrecord) != NULL) { - processsubscribe($(var(cnamrecord){s.b64decode})); - } else { - t_relay("1.2.3.4", 0x02); - } - } else { - t_relay(); - } -} -... - -Chapter 2. Developer Guide - - The functions of the OSP modules are not used by other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Di-Shi Sun (@di-shi) 278 101 10368 5372 - 2. Dmitry Isakbayev 43 5 4120 159 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 37 31 232 217 - 4. Di-Shi Sun 18 2 1006 386 - 5. Liviu Chircu (@liviuchircu) 17 13 117 126 - 6. Daniel-Constantin Mierla (@miconda) 15 13 81 48 - 7. Razvan Crainea (@razvancrainea) 13 10 83 62 - 8. Zero King (@l2dy) 10 8 20 23 - 9. Vlad Patrascu (@rvlad-patrascu) 10 7 70 66 - 10. Ancuta Onofrei 9 1 206 318 - - All remaining contributors: Maksym Sobolyev (@sobomax), Dan - Pascu (@danpascu), Henning Westerholt (@henningw), Ovidiu Sas - (@ovidiusas), Vlad Paiu (@vladpaiu), Konstantin Bokarius, - fabriziopicconi, Andreas Granig, Ezequiel Lovelle (@lovelle), - Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Ralf Zerres, - Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2006 - May 2025 - 2. Maksym Sobolyev (@sobomax) Sep 2020 - Jun 2024 - 3. Razvan Crainea (@razvancrainea) Jun 2011 - Feb 2024 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - May 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Dan Pascu (@danpascu) Nov 2008 - Jul 2019 - 8. Ralf Zerres May 2019 - May 2019 - 9. Di-Shi Sun Oct 2018 - Feb 2019 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Di-Shi Sun (@di-shi), Julián Moreno - Patiño, Ezequiel Lovelle (@lovelle), fabriziopicconi, Ovidiu - Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Ancuta Onofrei, Dmitry - Isakbayev, Andreas Granig. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Zero King - (@l2dy), Vlad Patrascu (@rvlad-patrascu), Di-Shi Sun, Liviu - Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Di-Shi Sun - (@di-shi), Razvan Crainea (@razvancrainea), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Dmitry Isakbayev. - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/osp/README.md b/modules/osp/README.md new file mode 100644 index 00000000000..89c6c9c1360 --- /dev/null +++ b/modules/osp/README.md @@ -0,0 +1,868 @@ +--- +title: "OSP Module" +description: "The OSP module enables OpenSIPS to support secure, multi-lateral peering using the OSP standard defined by ETSI (TS 101 321 V4.1.1)." +--- + +## Admin Guide + + +### Overview + + +The OSP module enables OpenSIPS to support secure, multi-lateral peering using the OSP standard defined by ETSI (TS 101 321 V4.1.1). This module will enable your OpenSIPS to: + + +- Send a peering authorization request to a peering server. +- Validate a digitally signed peering authorization token received in a SIP INVITE message. +- Report usage information to a peering server. + + +### Dependencies + + +The OSP module depends on the following modules which must be loaded before the OSP module. + + +- *auth* -- Authentication Framework module +- *sqlops* -- SQL operation module +- *maxfwd* -- Max-Forward processor module +- *mi_fifo* -- FIFO support for Management Interface +- *options* -- OPTIONS server replier module +- *proto_udp* -- UDP protocol module - implements UDP-plain transport for SIP +- *registrar* -- SIP Registrar implementation module +- *rr* -- Record-Route and Route module +- *signaling* -- SIP signaling module +- *sipmsgops* -- SIP operations module +- *sl* -- Stateless replier module +- *tm* -- Transaction (stateful) module +- *uac* -- UAC functionalies (FROM mangling and UAC auth) +- *uac_auth* -- UAC Authentication functionality +- *usrloc* -- User location implementation module +- *OSP Toolkit* -- The OSP Toolkit, available from https://github.com/TransNexus/osptoolkit, must be built before building OpenSIPS with the OSP module. For instructions on building OpenSIPS with the OSP Toolkit, see http://www.http://transnexus.com/wp-content/uploads/OSP-Routing-and-CDR-Collection-Server-with-OpenSIPS-1.7.2.pdf. For OpenSIPS 2.4.0, OSP Toolkit 4.16.0 or later versions should be used. + + +### Exported Parameters + + +#### work_mode + + +The work_mode (integer) parameter instructs the OSP module what mode it should work in. If this value is set to 0, the OSP module works in direct mode. If this value is set to 1, the OSP module works in indirect mode. The default value is 0. + + +```opensips title="Instructing the module to work in direct mode" +modparam("osp","work_mode",0) + +``` + + +#### service_type + + +The service_type (integer) parameter instructs the OSP module what services it should provide. If this value is set to 0, the OSP module provides normal voice service. If this value is set to 1, the OSP module provides ported number query service. If this value is set to 2, the OSP module provides CNAM query service. The default value is 0. + + +```opensips title="Instructing the module to provide normal voice service" +modparam("osp","service_type",0) + +``` + + +#### sp1_uri, sp2_uri, ..., sp16_uri + + +These sp_uri (string) parameters define peering servers to be used for requesting peering authorization and routing information. At least one peering server must be configured. Others are required only if there are more than one peering servers. Each peering server address takes the form of a standard URL, and consists of up to four components: + + +- An optional indication of the protocol to be used for communicating with the peering server. Both HTTP and HTTP secured with SSL/TLS are supported and are indicated by "http://" and "https://" respectively. If the protocol is not explicitly indicated, the OpenSIPS defaults to HTTP secured with SSL. +- The Internet domain name for the peering server. An IP address may also be used, provided it is enclosed in square brackets such as [172.16.1.1]. +- An optional TCP port number for communicating with the peering server. If the port number is omitted, the OpenSIPS defaults to port 5045 (for HTTP) or port 1443 (for HTTP secured with SSL). +The uniform resource identifier for requests to the peering server. This component is not optional and must be included. + + +```opensips title="Setting the OSP servers" +modparam("osp","sp1_uri","http://osptestserver.transnexus.com:5045/osp") +modparam("osp","sp2_uri","https://[1.2.3.4]:1443/osp") + +``` + + +#### sp1_weight, sp2_weight, ..., sp16_weight + + +These sp_weight (integer) parameters are used for load balancing peering requests to peering servers. These parameters are most effective when configured as factors of 1000. For example, if sp1_uri should manage twice the traffic load of sp2_uri, then set sp1_weight to 2000 and sp2_weight to 1000. Shared load balancing between peering servers is recommended. However, peering servers can be configured as primary and backup by assigning a sp_weight of 0 to the primary server and a non-zero sp_weight to the back-up server. The default values for sp1_weight and sp2_weight are 1000. + + +```opensips title="Setting the OSP server weights" +modparam("osp","sp1_weight",1000) + +``` + + +#### device_ip + + +The device_ip (string) is a recommended parameter that explicitly defines the IP address of OpenSIPS in a peering request message (as SourceAlternate type=transport). The dotted-decimal IP address must be in brackets as shown in the example below. + + +```opensips title="Setting the device IP address" +modparam("osp","device_ip","[127.0.0.1]:5060") + +``` + + +#### use_security_features + + +The use_security_features (integer) parameter instructs the OSP module how to use the OSP security features. If this value is set to 1, the OSP module uses the OSP security features. If this value is set to 0, the OSP module will not use the OSP security features. The default value is 0. + + +```opensips title="Instructing the module not to use OSP security features" +modparam("osp","use_security_features",0) + +``` + + +#### token_format + + +When OpenSIPS receives a SIP INVITE with a peering token, the OSP module will validate the token to determine whether or not the call has been authorized by a peering server. Peering tokens may, or may not, be digitally signed. The token_format (integer) parameter defines if OpenSIPS will validate signed or unsigned tokens or both. The values for token format are defined below. The default value is 2. + + +If use_security_features parameter is set to 0, signed tokens cannot be validated. + + +0 - Validate only signed tokens. Calls with valid signed tokens are allowed. + + +1 - Validate only unsigned tokens. Calls with valid unsigned tokens are allowed. + + +2 - Validate both signed and unsigned tokens are allowed. Calls with valid tokens are allowed. + + +```opensips title="Setting the token format" +modparam("osp","token_format",2) + +``` + + +#### private_key, local_certificate, ca_certificates + + +These parameters identify files are used for validating peering authorization tokens and establishing a secure channel between OpenSIPS and a peering server using SSL. The files are generated using the 'Enroll' utility from the OSP Toolkit. By default, the proxy will look for pkey.pem, localcert.pem, and cacart_0.pem in the default configuration directory. The default config directory is set at compile time using CFG_DIR and defaults to /usr/local/etc/opensips/. The files may be copied to the expected file location or the parameters below may be changed. + + +If use_security_features parameter is set to 0, these parameters will be ignored. + + +If the default CFG_DIR value was used at compile time, the files will be loaded from: + + +```opensips title="Set authorization files" +modparam("osp","private_key","/usr/local/etc/opensips/pkey.pem") +modparam("osp","local_certificate","/usr/local/etc/opensips/localcert.pem") +modparam("osp","ca_certificates","/usr/local/etc/opensips/cacert.pem") + +``` + + +#### enable_crypto_hardware_support + + +The enable_crypto_hardware_support (integer) parameter is used to set the cryptographic hardware acceleration engine in the openssl library. The default value is 0 (no crypto hardware is present). If crypto hardware is used, the value should be set to 1. + + +```opensips title="Setting the hardware support" +modparam("osp","enable_crypto_hardware_support",0) + +``` + + +#### ssl_lifetime + + +The ssl_lifetime (integer) parameter defines the lifetime, in seconds, of a single SSL session key. Once this time limit is exceeded, the OSP module will negotiate a new session key. Communication exchanges in progress will not be interrupted when this time limit expires. This is an optional field with default value is 200 seconds. + + +```opensips title="Setting the ssl lifetime" +modparam("osp","ssl_lifetime",200) + +``` + + +#### persistence + + +The persistence (integer) parameter defines the time, in seconds, that an HTTP connection should be maintained after the completion of a communication exchange. The OSP module will maintain the connection for this time period in anticipation of future communication exchanges to the same peering server. + + +```opensips title="Setting the persistence" +modparam("osp","persistence",1000) + +``` + + +#### retry_delay + + +The retry_delay (integer) parameter defines the time, in seconds, between retrying connection attempts to an OSP peering server. After exhausting all peering servers the OSP module will delay for this amount of time before resuming connection attempts. This is an optional field with default value is 1 second. + + +```opensips title="Setting the retry delay" +modparam("osp","retry_delay",1) + +``` + + +#### retry_limit + + +The retry_limit (integer) parameter defines the maximum number of retries for connection attempts to a peering server. If no connection is established after this many retry attempts to all peering servers, the OSP module will cease connection attempts and return appropriate error codes. This number does not count the initial connection attempt, so that a retry_limit of 1 will result in a total of two connection attempts to every peering server. The default value is 2. + + +```opensips title="Setting the retry limit" +modparam("osp","retry_limit",2) + +``` + + +#### timeout + + +The timeout (integer) parameter defines the maximum time in milliseconds, to wait for a response from a peering server. If no response is received within this time, the current connection is aborted and the OSP module attempts to contact the next peering server. The default value is 10 seconds. + + +```opensips title="Setting the timeout" +modparam("osp","timeout",10) + +``` + + +#### support_nonsip_protocol + + +The support_nonsip_protocol (integer) parameter is used to tell the OSP module if non-SIP signaling protocol destination devices are supported. The default value is 0. + + +```opensips title="Setting support non-SIP destination devices" +modparam("osp","support_nonsip_protocol",0) + +``` + + +#### max_destinations + + +The max_destinations (integer) parameter defines the maximum number of destinations that OpenSIPS requests the peering server to return in a peering response. The OSP module supports up to 12 destinations. The default value is 12. + + +```opensips title="Setting the number of destination" +modparam("osp","max_destinations",12) + +``` + + +#### report_networkid + + +The report_networkid (integer) parameter is used to tell the OSP module if to report network ID in completed call CDRs. If it is set to 0, ths OSP module does not report any network ID. If it is set to 1, the OSP module reports source network ID. If it is set to 2, the OSP module reports destination network ID. If it is set to 3, the OSP module report both source and destination network IDs. The default value is 3. + + +```opensips title="Setting report network ID flag" +modparam("osp","report_networkid",3) + +``` + + +#### validate_call_id + + +The validate_call_id (integer) parameter instructs the OSP module to validate call id in the peering token. If this value is set to 1, the OSP module validates that the call id in the SIP INVITE message matches the call id in the peering token. If they do not match the INVITE is rejected. If this value is set to 0, the OSP module will not validate the call id in the peering token. The default value is 1. + + +```opensips title="Instructing the module to validate call id" +modparam("osp","validate_call_id",1) + +``` + + +#### use_number_portability + + +The use_number_portability (integer) parameter instructs the OSP module how to use the number portability parameters in the Request URI of the SIP INVITE message. If this value is set to 1, the OSP module uses the number portability parameters in the Request URI when these parameters exist. If this value is set to 0, the OSP module will not use the number portability parameters. The default value is 1. + + +```opensips title="Instructing the module to use number portability parameters in Request URI" +modparam("osp","use_number_portablity",1) + +``` + + +#### append_userphone + + +The append_userphone (integer) parameter instructs the OSP module if to append "user=phone" parameter in URI. If this value is set to 0, the OSP module does not append "user=phone" parameter. If this value is set to 1, the OSP module will append "user=phone" parameter. The default value is 0 + + +```opensips title="Append user=phone parameter" +modparam("osp","append_userphone",0) + +``` + + +#### networkid_location + + +The networkid_location (integer) parameter instructs the OSP module where the destination network ID should be appended. The default value is 2 + + +0 - network ID is not appended. + + +1 - network ID is appended as userinfo parameter. + + +2 - network ID is appended as URI parameter. + + +```opensips title="Append networkid location" +modparam("osp","networkid_location",2) + +``` + + +#### networkid_parameter + + +The networkid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination network ID. The default value is "networkid" + + +```opensips title="Networkid parameter name" +modparam("osp","networkid_param","networkid") + +``` + + +#### switchid_location + + +The switchid_location (integer) parameter instructs the OSP module where the destination switch ID should be appended. The default value is 2 + + +0 - switch ID is not appended. + + +1 - switch ID is appended as userinfo parameter. + + +2 - switch ID is appended as URI parameter. + + +```opensips title="Append switchid location" +modparam("osp","switchid_location",2) + +``` + + +#### switchid_parameter + + +The switchid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination switch ID. The default value is "switchid" + + +```opensips title="Networkid parameter name" +modparam("osp","switchid_param","switchid") + +``` + + +#### parameterstring_location + + +The parameterstring_location (integer) parameter instructs the OSP module where the parameter string should be appended. The default value is 0 + + +0 - parameter string is not appended. + + +1 - parameter string is appended as userinfo parameter. + + +2 - parameter string is appended as URI parameter. + + +```opensips title="Append parameter string location" +modparam("osp","parameterstring_location",0) + +``` + + +#### parameterstring_value + + +The parameterstring_value (string) parameter instructs the OSP module to append the parameter string in outbound URIs. The default value is "" + + +```opensips title="Parameter string value" +modparam("osp","parameterstring_value","") + +``` + + +#### source_device_avp + + +The source_device_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source device IP value in the indirect work mode. The default value is "$avp(_osp_source_device_)". Then the source device IP can be set by "$avp(_osp_source_device_) = pseudo-variables". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source device IP AVP" +modparam("osp","source_device_avp","$avp(srcdev)") + +``` + + +#### source_networkid_avp + + +The source_networkid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source network ID value. The default value is "$avp(_osp_source_networkid_)". Then the source network ID can be set by "$avp(_osp_source_networkid_) = pseudo-variables". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source network ID AVP" +modparam("osp","source_networkid_avp","$avp(snid)") + +``` + + +#### source_switchid_avp + + +The source_switchid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source switch ID value. The default value is "$avp(_osp_source_switchid_)". Then the source switch ID can be set by "$avp(_osp_source_switchid_) = pseudo-variables". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source switch ID AVP" +modparam("osp","source_switchid_avp","$avp(swid)") + +``` + + +#### custom_info_avp + + +The custom_info_avp (string) parameter instructs the OSP module to use the defined AVP to pass the custom information values. The default value is "$avp(_osp_custom_info_)". Then the custom information can be set by "$avp(_osp_custom_info_) = pseudo-variables". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the custom info AVP" +modparam("osp","custom_info_avp","$avp(cinfo)") + +``` + + +#### cnam_avp + + +The cnam_avp (string) parameter instructs the OSP module to use the defined AVP to pass the CNAM values. The default value is "$avp(_osp_cnam_)". Then the CNAM can be used by "$avp(_osp_cnam_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the CNAM AVP" +modparam("osp","cnam_avp","$avp(cnam)") + +``` + + +#### extraheaders_value + + +The extraheaders_value (string) parameter instructs the OSP module to append the defined SIP headers in outbound SIP NOTIFY messages. The default value is empty. + + +```opensips title="Setting the NOTIFY extra headers" +modparam("osp", "extraheaders_value", "Source: N") + +``` + + +#### source_media_avp, destination_media_avp + + +These parameters are used to tell the OSP module which AVPs are used to store media addresses. The default values are "$avp(_osp_source_media_address_)" and "$avp(_osp_destination_media_address_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the media address AVPs" +modparam("osp", "source_media_avp", "$avp(srcmedia)") +modparam("osp", "destination_media_avp", "$avp(destmedia)") + +``` + + +#### request_date_avp + + +The request_date_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SIP request Date header values. The default value is "$avp(_osp_request_date_)". Then the request date can be used by "$avp(_osp_request_date_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the request date AVP" +modparam("osp","request_date_avp","$avp(reqdate)") + +``` + + +#### sdp_fingerprint_avp + + +The sdp_fingerprint_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SDP fing print attribute values. The default value is "$avp(_osp_sdp_fingerprint_)". Then the SDP finger print attributes can be used by "$avp(_osp_sdp_fingerprint_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the SDP finger print AVP" +modparam("osp","sdp_fingerprint_avp","$avp(sdpfp)") + +``` + + +#### identity_signature_avp, identity_algorithm_avp, identity_information_avp, identity_type_avp, identity_canon_avp + + +These parameters instruct the OSP module to use the defined AVPs to pass the Identity related values. The default values are "$avp(_osp_identity_signature_)", "$avp(_osp_identity_algorithm_)", "$avp(_osp_identity_information_)", "$avp(_osp_identity_type_)", "$avp(_osp_identity_canon_)". Then the indentity related values can be used by these AVPs. All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the Identity related AVPs" +modparam("osp","identity_signature_avp","$avp(idsign)") +modparam("osp","identity_algorithm_avp","$avp(idalg)") +modparam("osp","identity_information_avp","$avp(idinfo)") +modparam("osp","identity_type_avp","$avp(idtype)") +modparam("osp","identity_canon_avp","$avp(idcanon)") + +``` + + +#### service_provider_avp + + +These parameter is used to tell the OSP module which AVP is used to store source service provider information. The default value is "$avp(_osp_service_provider_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source service provider AVP" +modparam("osp", "service_provider_avp", "$avp(sp)") + +``` + + +#### user_group_avp + + +These parameter is used to tell the OSP module which AVP is used to store source user group information. The default value is "$avp(_osp_user_group_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source user group AVP" +modparam("osp", "user_group_avp", "$avp(groupid)") + +``` + + +#### user_id_avp + + +These parameter is used to tell the OSP module which AVP is used to store source user ID information. The default value is "$avp(_osp_user_id_)". All pseudo variables are described in https://docs.opensips.org/manual/3-6/script-corevar/. + + +```opensips title="Setting the source user ID AVP" +modparam("osp", "user_id_avp", "$avp(userid)") + +``` + + +### Exported Functions + + +#### checkospheader() + + +This function checks for the existence of the OSP-Auth-Token header field. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="checkospheader usage" +... +if (checkospheader()) { + log(1,"OSP header field found.\n"); +} else { + log(1,"no OSP header field present\n"); +}; +... + +``` + + +#### validateospheader() + + +This function validates an OSP-Token specified in the OSP-Auth-Tokenheader field of the SIP message. If a peering token is present, it will be validated locally. If no OSP header is found or the header token is invalid or expired, -1 is returned; on successful validation 1 is returned. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="validateospheader usage" +... +if (validateospheader()) { + log(1,"valid OSP header found\n"); +} else { + log(1,"OSP header not found, invalid or expired\n"); +}; +... + +``` + + +#### getlocaladdress() + + +This function gets the receiving IP address of SIP response and stores it as proxy egress address. + + +This function can be used from ONREPLY_ROUTE. + + +```opensips title="getlocaladress usage" +... +if (getlocaladdress()) { + log(1,"Obtain proxy local egress address\n"); +} else { + log(1,"Failed to get proxy local egress address\n"); +}; +... + +``` + + +#### setrequestdate() + + +This function gets the receiving IP address of SIP response and stores it as proxy egress address. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="setrequestdate usage" +... +if (setrequest()) { + log(1,"Set request date\n"); +} else { + log(1,"Failed to set request date\n"); +}; +... + +``` + + +#### requestosprouting() + + +This function launches a query to the peering server requesting the IP address of one or more destination peers serving the called party. If destination peers are available, the peering server will return the IP address and a peering authorization token for each destination peer. The OSP-Auth-Token Header field is inserted into the SIP message and the SIP uri is rewritten to the IP address of destination peer provided by the peering server. + + +The address of the called party must be a valid E164 number, otherwise this function returns -1. If the transaction was accepted by the peering server, the uri is being rewritten and 1 returned, on errors (peering servers are not available, authentication failed or there is no route to destination or the route is blocked) -1 is returned. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="requestosprouting usage" +... +if (requestosprouting()) { + log(1,"successfully queried OSP server, now relaying call\n"); +} else { + log(1,"Authorization request was rejected from OSP server\n"); +}; +... + +``` + + +#### checkosproute() + + +This function is used to check if there is any route for the call. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="checkosproute usage" +... +if (checkosproute()) { + log(1,"There is at least one route for the call\n"); +} else { + log(1,"There is not any route for the call\n"); +}; +... + +``` + + +#### prepareosproute() + + +This function tries to prepare the INVITE to be forwarded using the destination in the list returned by the peering server. If the calling number is translated, a RPID value for the RPID AVP will be set. If the route could not be prepared, the function returns 'FALSE' back to the script, which can then decide how to handle the failure. Note, if checkosproute has been called and returns 'TRUE' before calling prepareosproute, prepareosproute should not return 'FALSE' because checkosproute has confirmed that there is at least one route. + + +This function can be used from BRANCH_ROUTE. + + +```opensips title="prepareosproute usage" +... +if (prepareosproute()) { + log(1,"successfully prepared the route, now relaying call\n"); +} else { + log(1,"could not prepare the route, there is not route\n"); +}; +... + +``` + + +#### prepareospresponse() + + +This function tries to prepare all the routes in the list returned by the peering server into SIP 300 Redirect or SIP 380 Alternative Service message. The message is then replied to the source. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="prepareospresponse usage" +... +if (prepareospresponse()) { + log(1,"Response is prepared.\n"); +} else { + log(1,"Could not prepare the response.\n"); +}; +... + +``` + + +#### prepareallosproutes() + + +This function tries to prepare all the routes in the list returned by the peering server. The message is then forked off to the destinations. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="prepareallosproutes usage" +... +if (prepareallosproutes()) { + log(1,"Routes are prepared, now forking the call\n"); +} else { + log(1,"Could not prepare the routes. No destination available\n"); +}; +... + +``` + + +#### checkcallingtranslation() + + +This function is used to check if the calling number is translated. Before calling checkcallingtranslation, prepareosproute should be called. If the calling number does been translated, the original Remote-Party-ID, if it exists, should be removed from the INVITE message. And a new Remote-Party-ID header should be added (a RPID value for the RPID AVP has been set by prepareosproute). If the calling number is not translated, nothing should be done. + + +This function can be used from BRANCH_ROUTE. + + +```opensips title="checkcallingtranslation usage" +... +if (checkcallingtranslation()) { + # Remove the Remote_Party-ID from the received message + # Otherwise it will be forwarded on to the next hop + remove_hf("Remote-Party-ID"); + + # Append a new Remote_Party + append_rpid_hf(); +} +... + +``` + + +#### reportospusage() + + +This function should be called after receiving a BYE message. If the message contains an OSP cookie, the function will forward originating and/or terminating duration usage information to a peering server. The function returns TRUE if the BYE includes an OSP cookie. The actual usage message will be send on a different thread and will not delay BYE processing. The function should be called before relaying the message. + + +Meaning of the parameter is as follows: + + +- 0 - Source device releases the call. +- 1 - Destination device releases the call. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="reportospusage usage" +... +if (is_direction("downstream")) { + log(1,"This BYE message is from SOURCE\n"); + if (!reportospusage(0)) { + log(1,"This BYE message does not include OSP usage information\n"); + } +} else { + log(1,"This BYE message is from DESTINATION\n"); + if (!reportospusage(1)) { + log(1,"This BYE message does not include OSP usage information\n"); + } +} +... + +``` + + +#### processsubscribe([cachedcnamrecord]) + + +This function should be called after receiving a SUBSCRIBE for CNAM message and there is a cached CNAM record for this message. This function generates a NOTIFY message including the cached CNAM record, then sends the NOTIFY message to the device sending the SUBSCRIBE message. + + +Meaning of the parameter is as follows: + + +- *cachedcnamrecord* (string) - Cached CNAM record. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="processsubscribe usage" +... +if (is_method("SUBSCRIBE")) { + if (($var(sevent) == "calling-name") && (is_myself("$rd"))) { + if ($var(cnamrecord) != NULL) { + processsubscribe($(var(cnamrecord){s.b64decode})); + } else { + t_relay("1.2.3.4", 0x02); + } + } else { + t_relay(); + } +} +... + +``` + + +## Developer Guide + + +The functions of the OSP modules are not used by other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/osp/doc/contributors.xml b/modules/osp/doc/contributors.xml deleted file mode 100644 index 685b155f3e1..00000000000 --- a/modules/osp/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Di-Shi Sun (@di-shi) - 278 - 101 - 10368 - 5372 - - - 2. - Dmitry Isakbayev - 43 - 5 - 4120 - 159 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 37 - 31 - 232 - 217 - - - 4. - Di-Shi Sun - 18 - 2 - 1006 - 386 - - - 5. - Liviu Chircu (@liviuchircu) - 17 - 13 - 117 - 126 - - - 6. - Daniel-Constantin Mierla (@miconda) - 15 - 13 - 81 - 48 - - - 7. - Razvan Crainea (@razvancrainea) - 13 - 10 - 83 - 62 - - - 8. - Zero King (@l2dy) - 10 - 8 - 20 - 23 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 10 - 7 - 70 - 66 - - - 10. - Ancuta Onofrei - 9 - 1 - 206 - 318 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Dan Pascu (@danpascu), Henning Westerholt (@henningw), Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Konstantin Bokarius, fabriziopicconi, Andreas Granig, Ezequiel Lovelle (@lovelle), Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Ralf Zerres, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2006 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Sep 2020 - Jun 2024 - - - 3. - Razvan Crainea (@razvancrainea) - Jun 2011 - Feb 2024 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Dan Pascu (@danpascu) - Nov 2008 - Jul 2019 - - - 8. - Ralf Zerres - May 2019 - May 2019 - - - 9. - Di-Shi Sun - Oct 2018 - Feb 2019 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Di-Shi Sun (@di-shi), Julián Moreno Patiño, Ezequiel Lovelle (@lovelle), fabriziopicconi, Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei, Dmitry Isakbayev, Andreas Granig. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Di-Shi Sun, Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Di-Shi Sun (@di-shi), Razvan Crainea (@razvancrainea), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dmitry Isakbayev. -
- -
diff --git a/modules/osp/doc/osp.xml b/modules/osp/doc/osp.xml deleted file mode 100644 index af58063e6cb..00000000000 --- a/modules/osp/doc/osp.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - OSP Module for Secure, Multi-Lateral Peering - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/osp/doc/osp_admin.xml b/modules/osp/doc/osp_admin.xml deleted file mode 100644 index 1610cab18d2..00000000000 --- a/modules/osp/doc/osp_admin.xml +++ /dev/null @@ -1,744 +0,0 @@ - - - - - &adminguide; -
- Overview - The OSP module enables OpenSIPS to support secure, multi-lateral peering using the OSP standard defined by ETSI (TS 101 321 V4.1.1). This module will enable your OpenSIPS to: - - - Send a peering authorization request to a peering server. - - - Validate a digitally signed peering authorization token received in a SIP INVITE message. - - - Report usage information to a peering server. - - -
-
- Dependencies - The OSP module depends on the following modules which must be loaded before the OSP module. - - - auth -- Authentication Framework module - - - sqlops -- SQL operation module - - - maxfwd -- Max-Forward processor module - - - mi_fifo -- FIFO support for Management Interface - - - options -- OPTIONS server replier module - - - proto_udp -- UDP protocol module - implements UDP-plain transport for SIP - - - registrar -- SIP Registrar implementation module - - - rr -- Record-Route and Route module - - - signaling -- SIP signaling module - - - sipmsgops -- SIP operations module - - - sl -- Stateless replier module - - - tm -- Transaction (stateful) module - - - uac -- UAC functionalies (FROM mangling and UAC auth) - - - uac_auth -- UAC Authentication functionality - - - usrloc -- User location implementation module - - - OSP Toolkit -- The OSP Toolkit, available from https://github.com/TransNexus/osptoolkit, must be built before building OpenSIPS with the OSP module. For instructions on building OpenSIPS with the OSP Toolkit, see http://www.http://transnexus.com/wp-content/uploads/OSP-Routing-and-CDR-Collection-Server-with-OpenSIPS-1.7.2.pdf. For OpenSIPS 2.4.0, OSP Toolkit 4.16.0 or later versions should be used. - - -
-
- Exported Parameters -
- <varname>work_mode</varname> - The work_mode (integer) parameter instructs the OSP module what mode it should work in. If this value is set to 0, the OSP module works in direct mode. If this value is set to 1, the OSP module works in indirect mode. The default value is 0. - - Instructing the module to work in direct mode - -modparam("osp","work_mode",0) - - -
-
- <varname>service_type</varname> - The service_type (integer) parameter instructs the OSP module what services it should provide. If this value is set to 0, the OSP module provides normal voice service. If this value is set to 1, the OSP module provides ported number query service. If this value is set to 2, the OSP module provides CNAM query service. The default value is 0. - - Instructing the module to provide normal voice service - -modparam("osp","service_type",0) - - -
-
- <varname>sp1_uri</varname>, <varname>sp2_uri</varname>, ..., <varname>sp16_uri</varname> - These sp_uri (string) parameters define peering servers to be used for requesting peering authorization and routing information. At least one peering server must be configured. Others are required only if there are more than one peering servers. Each peering server address takes the form of a standard URL, and consists of up to four components: - - - An optional indication of the protocol to be used for communicating with the peering server. Both HTTP and HTTP secured with SSL/TLS are supported and are indicated by "http://" and "https://" respectively. If the protocol is not explicitly indicated, the OpenSIPS defaults to HTTP secured with SSL. - - - The Internet domain name for the peering server. An IP address may also be used, provided it is enclosed in square brackets such as [172.16.1.1]. - - - An optional TCP port number for communicating with the peering server. If the port number is omitted, the OpenSIPS defaults to port 5045 (for HTTP) or port 1443 (for HTTP secured with SSL). - The uniform resource identifier for requests to the peering server. This component is not optional and must be included. - - - - Setting the OSP servers - -modparam("osp","sp1_uri","http://osptestserver.transnexus.com:5045/osp") -modparam("osp","sp2_uri","https://[1.2.3.4]:1443/osp") - - -
-
- <varname>sp1_weight</varname>, <varname>sp2_weight</varname>, ..., <varname>sp16_weight</varname> - These sp_weight (integer) parameters are used for load balancing peering requests to peering servers. These parameters are most effective when configured as factors of 1000. For example, if sp1_uri should manage twice the traffic load of sp2_uri, then set sp1_weight to 2000 and sp2_weight to 1000. Shared load balancing between peering servers is recommended. However, peering servers can be configured as primary and backup by assigning a sp_weight of 0 to the primary server and a non-zero sp_weight to the back-up server. The default values for sp1_weight and sp2_weight are 1000. - - Setting the OSP server weights - -modparam("osp","sp1_weight",1000) - - -
-
- <varname>device_ip</varname> - The device_ip (string) is a recommended parameter that explicitly defines the IP address of OpenSIPS in a peering request message (as SourceAlternate type=transport). The dotted-decimal IP address must be in brackets as shown in the example below. - - Setting the device IP address - -modparam("osp","device_ip","[127.0.0.1]:5060") - - -
-
- <varname>use_security_features</varname> - The use_security_features (integer) parameter instructs the OSP module how to use the OSP security features. If this value is set to 1, the OSP module uses the OSP security features. If this value is set to 0, the OSP module will not use the OSP security features. The default value is 0. - - Instructing the module not to use OSP security features - -modparam("osp","use_security_features",0) - - -
-
- <varname>token_format</varname> - When OpenSIPS receives a SIP INVITE with a peering token, the OSP module will validate the token to determine whether or not the call has been authorized by a peering server. Peering tokens may, or may not, be digitally signed. The token_format (integer) parameter defines if OpenSIPS will validate signed or unsigned tokens or both. The values for token format are defined below. The default value is 2. - If use_security_features parameter is set to 0, signed tokens cannot be validated. - 0 - Validate only signed tokens. Calls with valid signed tokens are allowed. - 1 - Validate only unsigned tokens. Calls with valid unsigned tokens are allowed. - 2 - Validate both signed and unsigned tokens are allowed. Calls with valid tokens are allowed. - - Setting the token format - -modparam("osp","token_format",2) - - -
-
- <varname>private_key</varname>, <varname>local_certificate</varname>, <varname>ca_certificates</varname> - These parameters identify files are used for validating peering authorization tokens and establishing a secure channel between OpenSIPS and a peering server using SSL. The files are generated using the 'Enroll' utility from the OSP Toolkit. By default, the proxy will look for pkey.pem, localcert.pem, and cacart_0.pem in the default configuration directory. The default config directory is set at compile time using CFG_DIR and defaults to /usr/local/etc/opensips/. The files may be copied to the expected file location or the parameters below may be changed. - If use_security_features parameter is set to 0, these parameters will be ignored. - - Set authorization files - If the default CFG_DIR value was used at compile time, the files will be loaded from: - -modparam("osp","private_key","/usr/local/etc/opensips/pkey.pem") -modparam("osp","local_certificate","/usr/local/etc/opensips/localcert.pem") -modparam("osp","ca_certificates","/usr/local/etc/opensips/cacert.pem") - - -
-
- <varname>enable_crypto_hardware_support</varname> - The enable_crypto_hardware_support (integer) parameter is used to set the cryptographic hardware acceleration engine in the openssl library. The default value is 0 (no crypto hardware is present). If crypto hardware is used, the value should be set to 1. - - Setting the hardware support - -modparam("osp","enable_crypto_hardware_support",0) - - -
-
- <varname>ssl_lifetime</varname> - The ssl_lifetime (integer) parameter defines the lifetime, in seconds, of a single SSL session key. Once this time limit is exceeded, the OSP module will negotiate a new session key. Communication exchanges in progress will not be interrupted when this time limit expires. This is an optional field with default value is 200 seconds. - - Setting the ssl lifetime - -modparam("osp","ssl_lifetime",200) - - -
-
- <varname>persistence</varname> - The persistence (integer) parameter defines the time, in seconds, that an HTTP connection should be maintained after the completion of a communication exchange. The OSP module will maintain the connection for this time period in anticipation of future communication exchanges to the same peering server. - - Setting the persistence - -modparam("osp","persistence",1000) - - -
-
- <varname>retry_delay</varname> - The retry_delay (integer) parameter defines the time, in seconds, between retrying connection attempts to an OSP peering server. After exhausting all peering servers the OSP module will delay for this amount of time before resuming connection attempts. This is an optional field with default value is 1 second. - - Setting the retry delay - -modparam("osp","retry_delay",1) - - -
-
- <varname>retry_limit</varname> - The retry_limit (integer) parameter defines the maximum number of retries for connection attempts to a peering server. If no connection is established after this many retry attempts to all peering servers, the OSP module will cease connection attempts and return appropriate error codes. This number does not count the initial connection attempt, so that a retry_limit of 1 will result in a total of two connection attempts to every peering server. The default value is 2. - - Setting the retry limit - -modparam("osp","retry_limit",2) - - -
-
- <varname>timeout</varname> - The timeout (integer) parameter defines the maximum time in milliseconds, to wait for a response from a peering server. If no response is received within this time, the current connection is aborted and the OSP module attempts to contact the next peering server. The default value is 10 seconds. - - Setting the timeout - -modparam("osp","timeout",10) - - -
-
- <varname>support_nonsip_protocol</varname> - The support_nonsip_protocol (integer) parameter is used to tell the OSP module if non-SIP signaling protocol destination devices are supported. The default value is 0. - - Setting support non-SIP destination devices - -modparam("osp","support_nonsip_protocol",0) - - -
-
- <varname>max_destinations</varname> - The max_destinations (integer) parameter defines the maximum number of destinations that OpenSIPS requests the peering server to return in a peering response. The OSP module supports up to 12 destinations. The default value is 12. - - Setting the number of destination - -modparam("osp","max_destinations",12) - - -
-
- <varname>report_networkid</varname> - The report_networkid (integer) parameter is used to tell the OSP module if to report network ID in completed call CDRs. If it is set to 0, ths OSP module does not report any network ID. If it is set to 1, the OSP module reports source network ID. If it is set to 2, the OSP module reports destination network ID. If it is set to 3, the OSP module report both source and destination network IDs. The default value is 3. - - Setting report network ID flag - -modparam("osp","report_networkid",3) - - -
-
- <varname>validate_call_id</varname> - The validate_call_id (integer) parameter instructs the OSP module to validate call id in the peering token. If this value is set to 1, the OSP module validates that the call id in the SIP INVITE message matches the call id in the peering token. If they do not match the INVITE is rejected. If this value is set to 0, the OSP module will not validate the call id in the peering token. The default value is 1. - - Instructing the module to validate call id - -modparam("osp","validate_call_id",1) - - -
-
- <varname>use_number_portability</varname> - The use_number_portability (integer) parameter instructs the OSP module how to use the number portability parameters in the Request URI of the SIP INVITE message. If this value is set to 1, the OSP module uses the number portability parameters in the Request URI when these parameters exist. If this value is set to 0, the OSP module will not use the number portability parameters. The default value is 1. - - Instructing the module to use number portability parameters in Request URI - -modparam("osp","use_number_portablity",1) - - -
-
- <varname>append_userphone</varname> - The append_userphone (integer) parameter instructs the OSP module if to append "user=phone" parameter in URI. If this value is set to 0, the OSP module does not append "user=phone" parameter. If this value is set to 1, the OSP module will append "user=phone" parameter. The default value is 0 - - Append user=phone parameter - -modparam("osp","append_userphone",0) - - -
-
- <varname>networkid_location</varname> - The networkid_location (integer) parameter instructs the OSP module where the destination network ID should be appended. The default value is 2 - 0 - network ID is not appended. - 1 - network ID is appended as userinfo parameter. - 2 - network ID is appended as URI parameter. - - Append networkid location - -modparam("osp","networkid_location",2) - - -
-
- <varname>networkid_parameter</varname> - The networkid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination network ID. The default value is "networkid" - - Networkid parameter name - -modparam("osp","networkid_param","networkid") - - -
-
- <varname>switchid_location</varname> - The switchid_location (integer) parameter instructs the OSP module where the destination switch ID should be appended. The default value is 2 - 0 - switch ID is not appended. - 1 - switch ID is appended as userinfo parameter. - 2 - switch ID is appended as URI parameter. - - Append switchid location - -modparam("osp","switchid_location",2) - - -
-
- <varname>switchid_parameter</varname> - The switchid_parameter (string) parameter instructs the OSP module to use which parameter name in outbound destination URIs to append destination switch ID. The default value is "switchid" - - Networkid parameter name - -modparam("osp","switchid_param","switchid") - - -
-
- <varname>parameterstring_location</varname> - The parameterstring_location (integer) parameter instructs the OSP module where the parameter string should be appended. The default value is 0 - 0 - parameter string is not appended. - 1 - parameter string is appended as userinfo parameter. - 2 - parameter string is appended as URI parameter. - - Append parameter string location - -modparam("osp","parameterstring_location",0) - - -
-
- <varname>parameterstring_value</varname> - The parameterstring_value (string) parameter instructs the OSP module to append the parameter string in outbound URIs. The default value is "" - - Parameter string value - -modparam("osp","parameterstring_value","") - - -
-
- <varname>source_device_avp</varname> - The source_device_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source device IP value in the indirect work mode. The default value is "$avp(_osp_source_device_)". Then the source device IP can be set by "$avp(_osp_source_device_) = pseudo-variables". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source device IP AVP - -modparam("osp","source_device_avp","$avp(srcdev)") - - -
-
- <varname>source_networkid_avp</varname> - The source_networkid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source network ID value. The default value is "$avp(_osp_source_networkid_)". Then the source network ID can be set by "$avp(_osp_source_networkid_) = pseudo-variables". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source network ID AVP - -modparam("osp","source_networkid_avp","$avp(snid)") - - -
-
- <varname>source_switchid_avp</varname> - The source_switchid_avp (string) parameter instructs the OSP module to use the defined AVP to pass the source switch ID value. The default value is "$avp(_osp_source_switchid_)". Then the source switch ID can be set by "$avp(_osp_source_switchid_) = pseudo-variables". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source switch ID AVP - -modparam("osp","source_switchid_avp","$avp(swid)") - - -
-
- <varname>custom_info_avp</varname> - The custom_info_avp (string) parameter instructs the OSP module to use the defined AVP to pass the custom information values. The default value is "$avp(_osp_custom_info_)". Then the custom information can be set by "$avp(_osp_custom_info_) = pseudo-variables". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the custom info AVP - -modparam("osp","custom_info_avp","$avp(cinfo)") - - -
-
- <varname>cnam_avp</varname> - The cnam_avp (string) parameter instructs the OSP module to use the defined AVP to pass the CNAM values. The default value is "$avp(_osp_cnam_)". Then the CNAM can be used by "$avp(_osp_cnam_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the CNAM AVP - -modparam("osp","cnam_avp","$avp(cnam)") - - -
-
- <varname>extraheaders_value</varname> - The extraheaders_value (string) parameter instructs the OSP module to append the defined SIP headers in outbound SIP NOTIFY messages. The default value is empty. - - Setting the NOTIFY extra headers - -modparam("osp", "extraheaders_value", "Source: N") - - -
-
- <varname>source_media_avp, destination_media_avp</varname> - These parameters are used to tell the OSP module which AVPs are used to store media addresses. The default values are "$avp(_osp_source_media_address_)" and "$avp(_osp_destination_media_address_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the media address AVPs - -modparam("osp", "source_media_avp", "$avp(srcmedia)") -modparam("osp", "destination_media_avp", "$avp(destmedia)") - - -
-
- <varname>request_date_avp</varname> - The request_date_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SIP request Date header values. The default value is "$avp(_osp_request_date_)". Then the request date can be used by "$avp(_osp_request_date_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the request date AVP - -modparam("osp","request_date_avp","$avp(reqdate)") - - -
-
- <varname>sdp_fingerprint_avp</varname> - The sdp_fingerprint_avp (string) parameter instructs the OSP module to use the defined AVP to pass the SDP fing print attribute values. The default value is "$avp(_osp_sdp_fingerprint_)". Then the SDP finger print attributes can be used by "$avp(_osp_sdp_fingerprint_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the SDP finger print AVP - -modparam("osp","sdp_fingerprint_avp","$avp(sdpfp)") - - -
-
- <varname>identity_signature_avp</varname>, <varname>identity_algorithm_avp</varname>, <varname>identity_information_avp</varname>, <varname>identity_type_avp</varname>, <varname>identity_canon_avp</varname> - These parameters instruct the OSP module to use the defined AVPs to pass the Identity related values. The default values are "$avp(_osp_identity_signature_)", "$avp(_osp_identity_algorithm_)", "$avp(_osp_identity_information_)", "$avp(_osp_identity_type_)", "$avp(_osp_identity_canon_)". Then the indentity related values can be used by these AVPs. All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the Identity related AVPs - -modparam("osp","identity_signature_avp","$avp(idsign)") -modparam("osp","identity_algorithm_avp","$avp(idalg)") -modparam("osp","identity_information_avp","$avp(idinfo)") -modparam("osp","identity_type_avp","$avp(idtype)") -modparam("osp","identity_canon_avp","$avp(idcanon)") - - -
-
- <varname>service_provider_avp</varname> - These parameter is used to tell the OSP module which AVP is used to store source service provider information. The default value is "$avp(_osp_service_provider_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source service provider AVP - -modparam("osp", "service_provider_avp", "$avp(sp)") - - -
-
- <varname>user_group_avp</varname> - These parameter is used to tell the OSP module which AVP is used to store source user group information. The default value is "$avp(_osp_user_group_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source user group AVP - -modparam("osp", "user_group_avp", "$avp(groupid)") - - -
-
- <varname>user_id_avp</varname> - These parameter is used to tell the OSP module which AVP is used to store source user ID information. The default value is "$avp(_osp_user_id_)". All pseudo variables are described in https://opensips.org/Resources/DocsCoreVar. - - Setting the source user ID AVP - -modparam("osp", "user_id_avp", "$avp(userid)") - - -
-
-
- Exported Functions -
- <function moreinfo="none">checkospheader()</function> - This function checks for the existence of the OSP-Auth-Token header field. - This function can be used from REQUEST_ROUTE. - - checkospheader usage - -... -if (checkospheader()) { - log(1,"OSP header field found.\n"); -} else { - log(1,"no OSP header field present\n"); -}; -... - - -
-
- <function moreinfo="none">validateospheader()</function> - This function validates an OSP-Token specified in the OSP-Auth-Tokenheader field of the SIP message. If a peering token is present, it will be validated locally. If no OSP header is found or the header token is invalid or expired, -1 is returned; on successful validation 1 is returned. - This function can be used from REQUEST_ROUTE. - - validateospheader usage - -... -if (validateospheader()) { - log(1,"valid OSP header found\n"); -} else { - log(1,"OSP header not found, invalid or expired\n"); -}; -... - - -
-
- <function moreinfo="none">getlocaladdress()</function> - This function gets the receiving IP address of SIP response and stores it as proxy egress address. - This function can be used from ONREPLY_ROUTE. - - getlocaladress usage - -... -if (getlocaladdress()) { - log(1,"Obtain proxy local egress address\n"); -} else { - log(1,"Failed to get proxy local egress address\n"); -}; -... - - -
-
- <function moreinfo="none">setrequestdate()</function> - This function gets the receiving IP address of SIP response and stores it as proxy egress address. - This function can be used from REQUEST_ROUTE. - - setrequestdate usage - -... -if (setrequest()) { - log(1,"Set request date\n"); -} else { - log(1,"Failed to set request date\n"); -}; -... - - -
-
- <function moreinfo="none">requestosprouting()</function> - This function launches a query to the peering server requesting the IP address of one or more destination peers serving the called party. If destination peers are available, the peering server will return the IP address and a peering authorization token for each destination peer. The OSP-Auth-Token Header field is inserted into the SIP message and the SIP uri is rewritten to the IP address of destination peer provided by the peering server. - The address of the called party must be a valid E164 number, otherwise this function returns -1. If the transaction was accepted by the peering server, the uri is being rewritten and 1 returned, on errors (peering servers are not available, authentication failed or there is no route to destination or the route is blocked) -1 is returned. - This function can be used from REQUEST_ROUTE. - - requestosprouting usage - -... -if (requestosprouting()) { - log(1,"successfully queried OSP server, now relaying call\n"); -} else { - log(1,"Authorization request was rejected from OSP server\n"); -}; -... - - -
-
- <function moreinfo="none">checkosproute()</function> - This function is used to check if there is any route for the call. - This function can be used from REQUEST_ROUTE. - - checkosproute usage - -... -if (checkosproute()) { - log(1,"There is at least one route for the call\n"); -} else { - log(1,"There is not any route for the call\n"); -}; -... - - -
-
- <function moreinfo="none">prepareosproute()</function> - This function tries to prepare the INVITE to be forwarded using the destination in the list returned by the peering server. If the calling number is translated, a RPID value for the RPID AVP will be set. If the route could not be prepared, the function returns 'FALSE' back to the script, which can then decide how to handle the failure. Note, if checkosproute has been called and returns 'TRUE' before calling prepareosproute, prepareosproute should not return 'FALSE' because checkosproute has confirmed that there is at least one route. - This function can be used from BRANCH_ROUTE. - - prepareosproute usage - -... -if (prepareosproute()) { - log(1,"successfully prepared the route, now relaying call\n"); -} else { - log(1,"could not prepare the route, there is not route\n"); -}; -... - - -
-
- <function moreinfo="none">prepareospresponse()</function> - This function tries to prepare all the routes in the list returned by the peering server into SIP 300 Redirect or SIP 380 Alternative Service message. The message is then replied to the source. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged. - This function can be used from REQUEST_ROUTE. - - prepareospresponse usage - -... -if (prepareospresponse()) { - log(1,"Response is prepared.\n"); -} else { - log(1,"Could not prepare the response.\n"); -}; -... - - -
-
- <function moreinfo="none">prepareallosproutes()</function> - This function tries to prepare all the routes in the list returned by the peering server. The message is then forked off to the destinations. If unsuccessful in preparing the routes a SIP 500 is sent back and a trace message is logged. - This function can be used from REQUEST_ROUTE. - - prepareallosproutes usage - -... -if (prepareallosproutes()) { - log(1,"Routes are prepared, now forking the call\n"); -} else { - log(1,"Could not prepare the routes. No destination available\n"); -}; -... - - -
-
- <function moreinfo="none">checkcallingtranslation()</function> - This function is used to check if the calling number is translated. Before calling checkcallingtranslation, prepareosproute should be called. If the calling number does been translated, the original Remote-Party-ID, if it exists, should be removed from the INVITE message. And a new Remote-Party-ID header should be added (a RPID value for the RPID AVP has been set by prepareosproute). If the calling number is not translated, nothing should be done. - This function can be used from BRANCH_ROUTE. - - checkcallingtranslation usage - -... -if (checkcallingtranslation()) { - # Remove the Remote_Party-ID from the received message - # Otherwise it will be forwarded on to the next hop - remove_hf("Remote-Party-ID"); - - # Append a new Remote_Party - append_rpid_hf(); -} -... - - -
-
- <function moreinfo="none">reportospusage()</function> - This function should be called after receiving a BYE message. If the message contains an OSP cookie, the function will forward originating and/or terminating duration usage information to a peering server. The function returns TRUE if the BYE includes an OSP cookie. The actual usage message will be send on a different thread and will not delay BYE processing. The function should be called before relaying the message. - Meaning of the parameter is as follows: - - - 0 - Source device releases the call. - - - 1 - Destination device releases the call. - - - - This function can be used from REQUEST_ROUTE. - - reportospusage usage - -... -if (is_direction("downstream")) { - log(1,"This BYE message is from SOURCE\n"); - if (!reportospusage(0)) { - log(1,"This BYE message does not include OSP usage information\n"); - } -} else { - log(1,"This BYE message is from DESTINATION\n"); - if (!reportospusage(1)) { - log(1,"This BYE message does not include OSP usage information\n"); - } -} -... - - -
-
- <function moreinfo="none">processsubscribe([cachedcnamrecord])</function> - This function should be called after receiving a SUBSCRIBE for CNAM message and there is a cached CNAM record for this message. This function generates a NOTIFY message including the cached CNAM record, then sends the NOTIFY message to the device sending the SUBSCRIBE message. - Meaning of the parameter is as follows: - - - cachedcnamrecord (string) - Cached CNAM record. - - - - This function can be used from REQUEST_ROUTE. - - processsubscribe usage - -... -if (is_method("SUBSCRIBE")) { - if (($var(sevent) == "calling-name") && (is_myself("$rd"))) { - if ($var(cnamrecord) != NULL) { - processsubscribe($(var(cnamrecord){s.b64decode})); - } else { - t_relay("1.2.3.4", 0x02); - } - } else { - t_relay(); - } -} -... - - -
-
-
- diff --git a/modules/osp/doc/osp_devel.xml b/modules/osp/doc/osp_devel.xml deleted file mode 100644 index 86cb509d675..00000000000 --- a/modules/osp/doc/osp_devel.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - &develguide; - The functions of the OSP modules are not used by other OpenSIPS modules. - - diff --git a/modules/path/README b/modules/path/README deleted file mode 100644 index eda5135e22b..00000000000 --- a/modules/path/README +++ /dev/null @@ -1,253 +0,0 @@ -path Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Path insertion for registrations - 1.1.2. Outbound routing to NAT'ed UACs - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. use_received (int) - 1.3.2. enable_double_path (integer) - - 1.4. Exported Functions - - 1.4.1. add_path([user]) - 1.4.2. add_path_received([user]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set use_received parameter - 1.2. Set enable_double_path parameter - 1.3. add_path(user) usage - 1.4. add_path_received(user) usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is designed to be used at intermediate sip proxies - like loadbalancers in front of registrars and proxies. It - provides functions for inserting a Path header including a - parameter for passing forward the received-URI of a - registration to the next hop. It also provides a mechanism for - evaluating this parameter in subsequent requests and to set the - destination URI according to it. - -1.1.1. Path insertion for registrations - - For registrations in a scenario like “[UAC] -> [P1] -> [REG]”, - the "path" module can be used at the intermediate proxy P1 to - insert a Path header into the message before forwarding it to - the registrar REG. Two functions can be used to achieve this: - * add_path(...) adds a Path header in the form of “Path: - ” to the message using the address of the - outgoing interface. A port is only added if it's not the - default port 5060. - If a username is passed to the function, it is also - included in the Path URI, like “Path: - ”. - * add_path_received(...) also add a Path header in the same - form as above, but also adds a parameter indicating the - received-URI of the message, like “Path: - ”. This is - especially useful if the proxy does NAT detection and wants - to pass the NAT'ed address to the registrar. - If the function is called with a username, it's included in - the Path URI too. - -1.1.2. Outbound routing to NAT'ed UACs - - If the NAT'ed address of an UAC is passed to the registrar, the - registrar routes back subsequent requests using the Path header - of the registration as Route header of the current request. If - the intermediate proxy had inserted a Path header including the - “received” parameter during the registration, this parameter - will show up in the Route header of the new request as well, - allowing the intermediate proxy to route to this address - instead of the one propagated in the Route URI for tunneling - through NAT. This behaviour can be activated by setting the - module parameter “use_received”. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * The "rr" module is needed for outbound routing according to - the “received” parameter. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. use_received (int) - - If set to 1, the “received” parameter of the first Route URI is - evaluated and used as destination-URI if present. - - Default value is 0. - - Example 1.1. Set use_received parameter -... -modparam("path", "use_received", 1) -... - -1.3.2. enable_double_path (integer) - - There are some situations when the server needs to insert two - Path header fields instead of one. For example when using two - disconnected networks or doing cross-protocol forwarding from - UDP->TCP. This parameter enables inserting of 2 Paths. - - Default value is 1 (yes). - - Example 1.2. Set enable_double_path parameter -... -modparam("path", "enable_double_path", 0) -... - -1.4. Exported Functions - -1.4.1. add_path([user]) - - This function adds a Path header in the form “Path: - ”. - - Meaning of the parameters is as follows: - * user (string, optional) - The username to be inserted as - user part. - - This function can be used from REQUEST_ROUTE. - - Example 1.3. add_path(user) usage -... -if (!add_path("loadbalancer")) { - sl_send_reply(503, "Internal Path Error"); - ... -}; -... - -1.4.2. add_path_received([user]) - - This function adds a Path header in the form “Path: - ”, setting - 'user' as username part of address, it's own outgoing address - as domain-part, and the address the request has been received - from as received-parameter. - - Meaning of the parameters is as follows: - * user (string, optional) - The username to be inserted as - user part. - - This function can be used from REQUEST_ROUTE. - - Example 1.4. add_path_received(user) usage -... -if (!add_path_received("inbound")) { - sl_send_reply(503, "Internal Path Error"); - ... -}; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 21 16 239 79 - 2. Liviu Chircu (@liviuchircu) 18 12 96 267 - 3. Andreas Granig 13 4 863 22 - 4. Daniel-Constantin Mierla (@miconda) 12 10 25 21 - 5. Razvan Crainea (@razvancrainea) 9 7 10 8 - 6. Vlad Patrascu (@rvlad-patrascu) 6 3 35 104 - 7. Maksym Sobolyev (@sobomax) 5 3 4 5 - 8. Henning Westerholt (@henningw) 4 2 5 32 - 9. Ancuta Onofrei 3 1 12 12 - 10. Konstantin Bokarius 3 1 2 5 - - All remaining contributors: Peter Lemenkov (@lemenkov), Edson - Gellert Schubert, Elena-Ramona Modroiu. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Aug 2010 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - Jul 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - 8. Konstantin Bokarius Mar 2008 - Mar 2008 - 9. Edson Gellert Schubert Feb 2008 - Feb 2008 - 10. Henning Westerholt (@henningw) Apr 2007 - Dec 2007 - - All remaining contributors: Ancuta Onofrei, Andreas Granig, - Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona - Modroiu, Andreas Granig. - - Documentation Copyrights: - - Copyright © 2006 Inode GmbH diff --git a/modules/path/README.md b/modules/path/README.md new file mode 100644 index 00000000000..f5be50debe4 --- /dev/null +++ b/modules/path/README.md @@ -0,0 +1,179 @@ +--- +title: "path Module" +description: "This module is designed to be used at intermediate sip proxies like loadbalancers in front of registrars and proxies." +--- + +## Admin Guide + + +### Overview + + +This module is designed to be used at intermediate sip proxies like loadbalancers in front of +registrars and proxies. It provides functions for inserting a Path header including a parameter for +passing forward the received-URI of a registration to the next hop. It also provides a mechanism +for evaluating this parameter in subsequent requests and to set the destination URI according to it. + + +#### Path insertion for registrations + + +For registrations in a scenario like "[UAC] -> [P1] -> [REG]", +the "path" module can be used at the intermediate proxy P1 to insert a Path +header into the message before forwarding it to the registrar REG. Two functions +can be used to achieve this: + + +- *add_path(...)* adds a Path header in the form of +"Path: " to the message using the address +of the outgoing interface. A port is only added if it's not the default +port 5060. +If a username is passed to the function, it is also included in the Path +URI, like "Path: ". +- *add_path_received(...)* also add a Path header in the +same form as above, but also adds a parameter indicating the received-URI +of the message, like +"Path: ". This +is especially useful if the proxy does NAT detection and wants to pass +the NAT'ed address to the registrar. +If the function is called with a username, it's included in the Path URI too. + + +#### Outbound routing to NAT'ed UACs + + +If the NAT'ed address of an UAC is passed to the registrar, the registrar routes back +subsequent requests using the Path header of the registration as Route header of the +current request. If the intermediate proxy had inserted a Path header including the +"received" parameter during the registration, this parameter will show up +in the Route header of the new request as well, allowing the intermediate proxy to route +to this address instead of the one propagated in the Route URI for tunneling through NAT. +This behaviour can be activated by setting the module parameter "use_received". + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- The "rr" module is needed for outbound routing according to the "received" +parameter. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### use_received (int) + + +If set to 1, the "received" parameter of the first Route URI is evaluated and +used as destination-URI if present. + + +*Default value is 0.* + + +```opensips title="Set use_received parameter" +... +modparam("path", "use_received", 1) +... +``` + + +#### enable_double_path (integer) + + +There are some situations when the server needs to insert two +Path header fields instead of one. For example when using +two disconnected networks or doing cross-protocol forwarding from +UDP->TCP. This parameter enables inserting of 2 +Paths. + + +*Default value is 1 (yes).* + + +```opensips title="Set enable_double_path parameter" +... +modparam("path", "enable_double_path", 0) +... +``` + + +### Exported Functions + + +#### add_path([user]) + + +This function adds a Path header in the form +"Path: ". + + +Meaning of the parameters is as follows: + + +- *user* (string, optional) - +The username to be inserted as user part. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="add_path(user) usage" +... +if (!add_path("loadbalancer")) { + sl_send_reply(503, "Internal Path Error"); + ... +}; +... +``` + + +#### add_path_received([user]) + + +This function adds a Path header in the form +"Path: ", setting +'user' as username part of address, it's own +outgoing address as domain-part, and the address the request has been received from as +received-parameter. + + +Meaning of the parameters is as follows: + + +- *user* (string, optional) - +The username to be inserted as user part. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="add_path_received(user) usage" +... +if (!add_path_received("inbound")) { + sl_send_reply(503, "Internal Path Error"); + ... +}; +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/path/doc/contributors.xml b/modules/path/doc/contributors.xml deleted file mode 100644 index ae74189ac34..00000000000 --- a/modules/path/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 21 - 16 - 239 - 79 - - - 2. - Liviu Chircu (@liviuchircu) - 18 - 12 - 96 - 267 - - - 3. - Andreas Granig - 13 - 4 - 863 - 22 - - - 4. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 25 - 21 - - - 5. - Razvan Crainea (@razvancrainea) - 9 - 7 - 10 - 8 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 3 - 35 - 104 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 4 - 5 - - - 8. - Henning Westerholt (@henningw) - 4 - 2 - 5 - 32 - - - 9. - Ancuta Onofrei - 3 - 1 - 12 - 12 - - - 10. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Elena-Ramona Modroiu. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2010 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - Jul 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - 8. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - 9. - Edson Gellert Schubert - Feb 2008 - Feb 2008 - - - 10. - Henning Westerholt (@henningw) - Apr 2007 - Dec 2007 - - - -
-All remaining contributors: Ancuta Onofrei, Andreas Granig, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Andreas Granig. -
- -
diff --git a/modules/path/doc/path.xml b/modules/path/doc/path.xml deleted file mode 100644 index 05d10a0ed02..00000000000 --- a/modules/path/doc/path.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - path Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 Inode GmbH - - diff --git a/modules/path/doc/path_admin.xml b/modules/path/doc/path_admin.xml deleted file mode 100644 index 489eaa45d5d..00000000000 --- a/modules/path/doc/path_admin.xml +++ /dev/null @@ -1,224 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is designed to be used at intermediate sip proxies like loadbalancers in front of - registrars and proxies. It provides functions for inserting a Path header including a parameter for - passing forward the received-&uri; of a registration to the next hop. It also provides a mechanism - for evaluating this parameter in subsequent requests and to set the destination &uri; according to it. - -
- Path insertion for registrations - - For registrations in a scenario like [UAC] -> [P1] -> [REG], - the "path" module can be used at the intermediate proxy P1 to insert a Path - header into the message before forwarding it to the registrar REG. Two functions - can be used to achieve this: - - - - add_path(...) adds a Path header in the form of - Path: <sip:1.2.3.4;lr> to the message using the address - of the outgoing interface. A port is only added if it's not the default - port 5060. - - - If a username is passed to the function, it is also included in the Path - &uri;, like Path: <sip:username@1.2.3.4;lr>. - - - - - - add_path_received(...) also add a Path header in the - same form as above, but also adds a parameter indicating the received-&uri; - of the message, like - Path: <sip:1.2.3.4;received=sip:2.3.4.5:1234;lr>. This - is especially useful if the proxy does NAT detection and wants to pass - the NAT'ed address to the registrar. - - - If the function is called with a username, it's included in the Path &uri; too. - - - - - - -
-
- Outbound routing to NAT'ed UACs - - If the NAT'ed address of an UAC is passed to the registrar, the registrar routes back - subsequent requests using the Path header of the registration as Route header of the - current request. If the intermediate proxy had inserted a Path header including the - received parameter during the registration, this parameter will show up - in the Route header of the new request as well, allowing the intermediate proxy to route - to this address instead of the one propagated in the Route &uri; for tunneling through NAT. - This behaviour can be activated by setting the module parameter use_received. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - The "rr" module is needed for outbound routing according to the received - parameter. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>use_received</varname> (int) - - If set to 1, the received parameter of the first Route &uri; is evaluated and - used as destination-&uri; if present. - - - - Default value is 0. - - - - Set <varname>use_received</varname> parameter - -... -modparam("path", "use_received", 1) -... - - -
-
- <varname>enable_double_path</varname> (integer) - - There are some situations when the server needs to insert two - Path header fields instead of one. For example when using - two disconnected networks or doing cross-protocol forwarding from - UDP->TCP. This parameter enables inserting of 2 - Paths. - - - - Default value is 1 (yes). - - - - Set <varname>enable_double_path</varname> parameter - -... -modparam("path", "enable_double_path", 0) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">add_path([user])</function> - - - This function adds a Path header in the form - Path: <sip:user@1.2.3.4;lr>. - - Meaning of the parameters is as follows: - - - - user (string, optional) - - The username to be inserted as user part. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>add_path(user)</function> usage - -... -if (!add_path("loadbalancer")) { - sl_send_reply(503, "Internal Path Error"); - ... -}; -... - - -
- -
- - <function moreinfo="none">add_path_received([user])</function> - - - This function adds a Path header in the form - Path: <sip:user@1.2.3.4;received=sip:2.3.4.5:1234;lr>, setting - 'user' as username part of address, it's own - outgoing address as domain-part, and the address the request has been received from as - received-parameter. - - Meaning of the parameters is as follows: - - - - user (string, optional) - - The username to be inserted as user part. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>add_path_received(user)</function> usage - -... -if (!add_path_received("inbound")) { - sl_send_reply(503, "Internal Path Error"); - ... -}; -... - - -
- - -
- - -
- diff --git a/modules/peering/README b/modules/peering/README deleted file mode 100644 index 93ca5278b83..00000000000 --- a/modules/peering/README +++ /dev/null @@ -1,266 +0,0 @@ -Peering Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. aaa_url (string) - 1.3.2. verify_destination_service_type (integer) - 1.3.3. verify_source_service_type (integer) - - 1.4. Exported Functions - - 1.4.1. verify_destination() - 1.4.2. verify_source() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set aaa_url parameter - 1.2. verify_destination_service_type parameter usage - 1.3. verify_source_service_type parameter usage - 1.4. verify_destination() usage - 1.5. verify_source() usage - -Chapter 1. Admin Guide - -1.1. Overview - - Peering module allows SIP providers (operators or - organizations) to verify from a broker if source or destination - of a SIP request is a trusted peer. - - In order to participate in the trust community provided by a - broker, each SIP provider registers with the broker the domains - (host parts of SIP URIs) that they serve. When a SIP proxy of a - provider needs to send a SIP request to a non-local domain, it - can find out from the broker using verify_destination() - function if the non-local domain is served by a trusted peer. - If so, the provider receives from the broker a hash of the SIP - request and a timestamp that it includes in the request to the - non-local domain. When a SIP proxy of the non-local domain - receives the SIP request, it, in turn, can verify from the - broker using verify_source() function if the request came from - a trusted peer. - - Verification functions communicate with the broker using an AAA - protocol. - - Comments and suggestions for improvements are welcome. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * an AAA implementing module - -1.3. Exported Parameters - -1.3.1. aaa_url (string) - - This is the url representing the AAA protocol used and the - location of the configuration file of this protocol. - - If the parameter is set to empty string, the AAA accounting - support will be disabled (even if compiled). - - Default value is “NULL”. - - Example 1.1. Set aaa_url parameter -... -modparam("peering", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient -.conf") -... - -1.3.2. verify_destination_service_type (integer) - - This is the value of the Service-Type AAA attribute to be used, - when sender of SIP Request verifies request's destination using - verify_destination() function. - - Default value is dictionary value of “Sip-Verify-Destination” - Service-Type. - - Example 1.2. verify_destination_service_type parameter usage -... -modparam("peering", "verify_destination_service_type", 21) -... - -1.3.3. verify_source_service_type (integer) - - This is the value of the Service-Type AAA attribute to be used, - when receiver of SIP Request verifies request's source using - verify_source() function. - - Default value is dictionary value of “Sip-Verify-Source” - Service-Type. - - Example 1.3. verify_source_service_type parameter usage -... -modparam("peering", "verify_source_service_type", 22) -... - -1.4. Exported Functions - -1.4.1. verify_destination() - - Function verify_destination() queries from broker's AAA server - if domain (host part) of Request URI is served by a trusted - peer. AAA request contains the following attributes/values: - * User-Name - Request-URI host - * SIP-URI-User - Request-URI user - * SIP-From-Tag - From tag - * SIP-Call-Id - Call id - * Service-Type - verify_destination_service_type - - Function returns value 1 if domain of Request URI is served by - a trusted peer and -1 otherwise. In case of positive result, - AAA server returns a set of SIP-AVP reply attributes. Value of - each SIP-AVP is of form: - - [#]name(:|#)value - - Value of each SIP-AVP reply attribute is mapped to an OpenSIPS - AVP. Prefix # in front of name or value indicates a string name - or string value, respectively. - - One of the SIP-AVP reply attributes contains a string that the - source peer must include "as is" in a P-Request-Hash header - when it sends the SIP request to the destination peer. The - string value may, for example, be of form hash@timestamp, where - hash contains a hash calculated by the broker based on the - attributes of the query and some local information and - timestamp is the time when the calculation was done. - - AVP names used in reply attributes are assigned by the broker. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.4. verify_destination() usage -... -if (verify_destination()) { - append_hf("P-Request-Hash: $avp(prh)\r\n"); -} -... - -1.4.2. verify_source() - - Function verify_source() queries from broker's AAA server if - SIP request was received from a trusted peer. AAA request - contains the following attributes/values: - * User-Name - Request-URI host - * SIP-URI-User - Request-URI user - * SIP-From-Tag - From tag - * SIP-Call-Id - Call id - * SIP-Request-Hash - body of P-Request-Hash header - * Service-Type - verify_source_service_type - - Function returns value 1 if SIP request was received from a - trusted peer and -1 otherwise. In case of positive result, AAA - server may return a set of SIP-AVP reply attributes. Value of - each SIP-AVP is of form: - - [#]name(:|#)value - - Value of each SIP-AVP reply attribute is mapped to an OpenSIPS - AVP. Prefix # in front of name or value indicates a string name - or string value, respectively. - - AVP names used in reply attributes are assigned by the broker. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.5. verify_source() usage -... -if (is_present_hf("P-Request-Hash")) { - if (verify_source()) { - xlog("L_INFO", "Request came from trusted peer\n") - } -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 13 11 29 32 - 2. Juha Heinanen (@juha-h) 13 4 909 5 - 3. Liviu Chircu (@liviuchircu) 10 8 27 39 - 4. Razvan Crainea (@razvancrainea) 9 7 13 9 - 5. Irina-Maria Stanescu 9 2 125 254 - 6. Vlad Patrascu (@rvlad-patrascu) 4 2 4 4 - 7. Maksym Sobolyev (@sobomax) 3 1 3 3 - 8. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Razvan Crainea (@razvancrainea) Apr 2013 - Sep 2019 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2008 - Apr 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 6. Liviu Chircu (@liviuchircu) Mar 2014 - Jun 2018 - 7. Irina-Maria Stanescu Aug 2009 - Aug 2009 - 8. Juha Heinanen (@juha-h) May 2008 - Jun 2008 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Irina-Maria Stanescu, Juha Heinanen - (@juha-h). - - Documentation Copyrights: - - Copyright © 2008 Juha Heinanen diff --git a/modules/peering/README.md b/modules/peering/README.md new file mode 100644 index 00000000000..7a46777affd --- /dev/null +++ b/modules/peering/README.md @@ -0,0 +1,226 @@ +--- +title: "Peering Module" +description: "Peering module allows SIP providers (operators or organizations) to verify from a broker if source or destination of a SIP request is a trusted peer." +--- + +## Admin Guide + + +### Overview + + +Peering module allows SIP +providers (operators or organizations) to verify from a broker +if source or destination of a SIP request is a trusted peer. + + +In order to participate in the trust community provided by a +broker, each SIP provider registers with the broker the domains +(host parts of SIP URIs) that they serve. When a SIP proxy of a +provider needs to send a SIP request to a non-local domain, it +can find out from the broker using verify_destination() function +if the non-local domain is served by a trusted peer. If so, the +provider receives from the broker a hash of the SIP request and +a timestamp that it includes in the request to the non-local +domain. When a SIP +proxy of the non-local domain receives the SIP request, it, in +turn, can verify from the broker using verify_source() function +if the request came from a trusted peer. + + +Verification functions communicate with the broker using an AAA +protocol. + + +Comments and suggestions for improvements are welcome. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules +(in the other words +the listed modules must be loaded before this module): + + +- *an AAA implementing module* + + +### Exported Parameters + + +#### aaa_url (string) + + +This is the url representing the AAA protocol used and the location of the configuration file of this protocol. + + +If the parameter is set to empty string, the AAA accounting support +will be disabled (even if compiled). + + +Default value is "NULL". + + +```opensips title="Set aaa_url parameter" +... +modparam("peering", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") +... +``` + + +#### verify_destination_service_type (integer) + + +This is the value of the Service-Type AAA attribute to be +used, when sender of SIP Request verifies request's +destination using verify_destination() function. + + +Default value is dictionary value of "Sip-Verify-Destination" +Service-Type. + + +```opensips title="verify_destination_service_type parameter usage" +... +modparam("peering", "verify_destination_service_type", 21) +... +``` + + +#### verify_source_service_type (integer) + + +This is the value of the Service-Type AAA attribute to be +used, when receiver of SIP Request verifies request's +source using verify_source() function. + + +Default value is dictionary value of "Sip-Verify-Source" +Service-Type. + + +```opensips title="verify_source_service_type parameter usage" +... +modparam("peering", "verify_source_service_type", 22) +... +``` + + +### Exported Functions + + +#### verify_destination() + + +Function verify_destination() queries from +broker's AAA server if domain (host part) of Request +URI is served by a trusted peer. AAA request contains the +following attributes/values: + + +- User-Name - Request-URI host +- SIP-URI-User - Request-URI user +- SIP-From-Tag - From tag +- SIP-Call-Id - Call id +- Service-Type - verify_destination_service_type + + +Function returns value 1 if domain of Request URI is +served by a trusted peer and -1 otherwise. In case of positive +result, AAA server returns a set of SIP-AVP reply attributes. +Value of each SIP-AVP is of form: + + +[#]name(:|#)value + + +Value of each SIP-AVP reply attribute is mapped to an +OpenSIPS AVP. Prefix # in front of name or value indicates a +string name or string value, respectively. + + +One of the SIP-AVP reply attributes contains a string +that the source peer must include "as is" in a +P-Request-Hash header when it sends the SIP request to +the destination peer. The string value may, for +example, be of form hash@timestamp, where hash contains +a hash calculated by the broker based on the attributes +of the query and some local information and timestamp +is the time when the calculation was done. + + +AVP names used in reply attributes are assigned by the +broker. + + +This function can be used from REQUEST_ROUTE and +FAILURE_ROUTE. + + +```opensips title="verify_destination() usage" +... +if (verify_destination()) { + append_hf("P-Request-Hash: $avp(prh)\r\n"); +} +... +``` + + +#### verify_source() + + +Function verify_source() queries from +broker's AAA server if SIP request was received from +a trusted peer. AAA request contains the +following attributes/values: + + +- User-Name - Request-URI host +- SIP-URI-User - Request-URI user +- SIP-From-Tag - From tag +- SIP-Call-Id - Call id +- SIP-Request-Hash - body of P-Request-Hash header +- Service-Type - verify_source_service_type + + +Function returns value 1 if SIP request was received +from a trusted peer and -1 otherwise. In case of positive +result, AAA server may return a set of SIP-AVP reply +attributes. Value of each SIP-AVP is of form: + + +[#]name(:|#)value + + +Value of each SIP-AVP reply attribute is mapped to an +OpenSIPS +AVP. Prefix # in front of name or value indicates a +string name or string value, respectively. + + +AVP names used in reply attributes are +assigned by the broker. + + +This function can be used from REQUEST_ROUTE and +FAILURE_ROUTE. + + +```opensips title="verify_source() usage" +... +if (is_present_hf("P-Request-Hash")) { + if (verify_source()) { + xlog("L_INFO", "Request came from trusted peer\n") + } +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/peering/doc/contributors.xml b/modules/peering/doc/contributors.xml deleted file mode 100644 index f24792545c2..00000000000 --- a/modules/peering/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 13 - 11 - 29 - 32 - - - 2. - Juha Heinanen (@juha-h) - 13 - 4 - 909 - 5 - - - 3. - Liviu Chircu (@liviuchircu) - 10 - 8 - 27 - 39 - - - 4. - Razvan Crainea (@razvancrainea) - 9 - 7 - 13 - 9 - - - 5. - Irina-Maria Stanescu - 9 - 2 - 125 - 254 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 4 - 4 - - - 7. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Razvan Crainea (@razvancrainea) - Apr 2013 - Sep 2019 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2008 - Apr 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jun 2018 - - - 7. - Irina-Maria Stanescu - Aug 2009 - Aug 2009 - - - 8. - Juha Heinanen (@juha-h) - May 2008 - Jun 2008 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Irina-Maria Stanescu, Juha Heinanen (@juha-h). -
- -
diff --git a/modules/peering/doc/peering.xml b/modules/peering/doc/peering.xml deleted file mode 100644 index fb89de8d5c5..00000000000 --- a/modules/peering/doc/peering.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Peering Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 Juha Heinanen - diff --git a/modules/peering/doc/peering_admin.xml b/modules/peering/doc/peering_admin.xml deleted file mode 100644 index 36f22f0a156..00000000000 --- a/modules/peering/doc/peering_admin.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - - - &adminguide; - -
- Overview - Peering module allows SIP - providers (operators or organizations) to verify from a broker - if source or destination of a SIP request is a trusted peer. - - - In order to participate in the trust community provided by a - broker, each SIP provider registers with the broker the domains - (host parts of SIP URIs) that they serve. When a SIP proxy of a - provider needs to send a SIP request to a non-local domain, it - can find out from the broker using verify_destination() function - if the non-local domain is served by a trusted peer. If so, the - provider receives from the broker a hash of the SIP request and - a timestamp that it includes in the request to the non-local - domain. When a SIP - proxy of the non-local domain receives the SIP request, it, in - turn, can verify from the broker using verify_source() function - if the request came from a trusted peer. - - - Verification functions communicate with the broker using an AAA - protocol. - - - - Comments and suggestions for improvements are welcome. - - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules - (in the other words - the listed modules must be loaded before this module): - - - an AAA implementing module - - - -
-
- -
- Exported Parameters -
- <varname>aaa_url</varname> (string) - - This is the url representing the AAA protocol used and the location of the configuration file of this protocol. - - - If the parameter is set to empty string, the AAA accounting support - will be disabled (even if compiled). - - - Default value is NULL. - - - Set <varname>aaa_url</varname> parameter - -... -modparam("peering", "aaa_url", "radius:/etc/radiusclient-ng/radiusclient.conf") -... - - -
-
- <varname>verify_destination_service_type</varname> (integer) - - This is the value of the Service-Type AAA attribute to be - used, when sender of SIP Request verifies request's - destination using verify_destination() function. - - - Default value is dictionary value of Sip-Verify-Destination - Service-Type. - - - <varname>verify_destination_service_type</varname> parameter usage - -... -modparam("peering", "verify_destination_service_type", 21) -... - - -
-
- <varname>verify_source_service_type</varname> (integer) - - This is the value of the Service-Type AAA attribute to be - used, when receiver of SIP Request verifies request's - source using verify_source() function. - - - Default value is dictionary value of Sip-Verify-Source - Service-Type. - - - <varname>verify_source_service_type</varname> parameter usage - -... -modparam("peering", "verify_source_service_type", 22) -... - - -
-
- -
- Exported Functions -
- <function moreinfo="none">verify_destination()</function> - - Function verify_destination() queries from - broker's AAA server if domain (host part) of Request - URI is served by a trusted peer. AAA request contains the - following attributes/values: - - - - User-Name - Request-URI host - - - SIP-URI-User - Request-URI user - - - SIP-From-Tag - From tag - - - SIP-Call-Id - Call id - - - Service-Type - verify_destination_service_type - - - - Function returns value 1 if domain of Request URI is - served by a trusted peer and -1 otherwise. In case of positive - result, AAA server returns a set of SIP-AVP reply attributes. - Value of each SIP-AVP is of form: - - - [#]name(:|#)value - - - Value of each SIP-AVP reply attribute is mapped to an - OpenSIPS AVP. Prefix # in front of name or value indicates a - string name or string value, respectively. - - - One of the SIP-AVP reply attributes contains a string - that the source peer must include "as is" in a - P-Request-Hash header when it sends the SIP request to - the destination peer. The string value may, for - example, be of form hash@timestamp, where hash contains - a hash calculated by the broker based on the attributes - of the query and some local information and timestamp - is the time when the calculation was done. - - - AVP names used in reply attributes are assigned by the - broker. - - - This function can be used from REQUEST_ROUTE and - FAILURE_ROUTE. - - - <function - moreinfo="none">verify_destination()</function> usage - -... -if (verify_destination()) { - append_hf("P-Request-Hash: $avp(prh)\r\n"); -} -... - - -
-
- <function moreinfo="none">verify_source()</function> - - Function verify_source() queries from - broker's AAA server if SIP request was received from - a trusted peer. AAA request contains the - following attributes/values: - - - - User-Name - Request-URI host - - - SIP-URI-User - Request-URI user - - - SIP-From-Tag - From tag - - - SIP-Call-Id - Call id - - - SIP-Request-Hash - body of P-Request-Hash header - - - Service-Type - verify_source_service_type - - - - Function returns value 1 if SIP request was received - from a trusted peer and -1 otherwise. In case of positive - result, AAA server may return a set of SIP-AVP reply - attributes. Value of each SIP-AVP is of form: - - - [#]name(:|#)value - - - Value of each SIP-AVP reply attribute is mapped to an - OpenSIPS - AVP. Prefix # in front of name or value indicates a - string name or string value, respectively. - - - AVP names used in reply attributes are - assigned by the broker. - - - This function can be used from REQUEST_ROUTE and - FAILURE_ROUTE. - - - <function - moreinfo="none">verify_source()</function> usage - -... -if (is_present_hf("P-Request-Hash")) { - if (verify_source()) { - xlog("L_INFO", "Request came from trusted peer\n") - } -} -... - - -
- -
-
diff --git a/modules/perl/README b/modules/perl/README deleted file mode 100644 index 323a256d95d..00000000000 --- a/modules/perl/README +++ /dev/null @@ -1,1448 +0,0 @@ -perl Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Installing the module - 1.3. Using the module - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. filename (string) - 1.5.2. modpath (string) - - 1.6. Exported Functions - - 1.6.1. perl_exec_simple(func, [param]) - 1.6.2. perl_exec(func, [param]) - - 2. OpenSIPS Perl API - - 2.1. OpenSIPS - - 2.1.1. log(level,message) - - 2.2. OpenSIPS::Message - - 2.2.1. getType() - 2.2.2. getStatus() - 2.2.3. getReason() - 2.2.4. getVersion() - 2.2.5. getRURI() - 2.2.6. getMethod() - 2.2.7. getFullHeader() - 2.2.8. getBody() - 2.2.9. getMessage() - 2.2.10. getHeader(name) - 2.2.11. getHeaderNames() - 2.2.12. moduleFunction(func,string1,string2) - 2.2.13. log(level,message) (deprecated type) - 2.2.14. rewrite_ruri(newruri) - 2.2.15. setFlag(flag) - 2.2.16. resetFlag(flag) - 2.2.17. isFlagSet(flag) - 2.2.18. pseudoVar(string) - 2.2.19. append_branch(branch,qval) - 2.2.20. serialize_branches(clean_before, keep_order) - 2.2.21. next_branches() - 2.2.22. getParsedRURI() - - 2.3. OpenSIPS::URI - - 2.3.1. user() - 2.3.2. host() - 2.3.3. passwd() - 2.3.4. port() - 2.3.5. params() - 2.3.6. headers() - 2.3.7. transport() - 2.3.8. ttl() - 2.3.9. user_param() - 2.3.10. maddr() - 2.3.11. method() - 2.3.12. lr() - 2.3.13. r2() - 2.3.14. transport_val() - 2.3.15. ttl_val() - 2.3.16. user_param_val() - 2.3.17. maddr_val() - 2.3.18. method_val() - 2.3.19. lr_val() - 2.3.20. r2_val() - - 2.4. OpenSIPS::AVP - - 2.4.1. add(name,val) - 2.4.2. get(name) - 2.4.3. destroy(name) - - 2.5. OpenSIPS::Utils::PhoneNumbers - - 2.5.1. - new(publicAccessPrefix,internationalPrefix,lon - gDistancePrefix,countryCode,areaCode,pbxCode - ) - - 2.5.2. canonicalForm( number [, context] ) - 2.5.3. dialNumber( number [, context] ) - - 2.6. OpenSIPS::LDAPUtils::LDAPConf - - 2.6.1. Constructor new() - 2.6.2. Method base() - 2.6.3. Method host() - 2.6.4. Method port() - 2.6.5. Method uri() - 2.6.6. Method rootbindpw() - 2.6.7. Method rootbinddn() - 2.6.8. Method binddn() - 2.6.9. Method bindpw() - - 2.7. OpenSIPS::LDAPUtils::LDAPConnection - - 2.7.1. Constructor new( [config, [authenticated]] ) - 2.7.2. Function/Method search( conf, filter, base, - [requested_attributes ...]) - - 2.8. OpenSIPS::VDB - 2.9. OpenSIPS::Constants - 2.10. OpenSIPS::VDB::Adapter::Speeddial - 2.11. OpenSIPS::VDB::Adapter::Alias - - 2.11.1. query(conds,retkeys,order) - - 2.12. OpenSIPS::VDB::Adapter::AccountingSIPtrace - 2.13. OpenSIPS::VDB::Adapter::Describe - 2.14. OpenSIPS::VDB::Adapter::Auth - 2.15. OpenSIPS::VDB::ReqCond - - 2.15.1. new(key,op,type,name) - 2.15.2. op() - - 2.16. OpenSIPS::VDB::Pair - - 2.16.1. new(key,type,name) - 2.16.2. key() - - 2.17. OpenSIPS::VDB::VTab - - 2.17.1. new() - 2.17.2. call(op,[args]) - - 2.18. OpenSIPS::VDB::Value - - 2.18.1. stringification - 2.18.2. new(type,data) - 2.18.3. type() - 2.18.4. data() - - 2.19. OpenSIPS::VDB::Column - - 2.19.1. Stringification - 2.19.2. new(type,name) - 2.19.3. type( ) - 2.19.4. name() - 2.19.5. OpenSIPS::VDB::Result - 2.19.6. new(coldefs,[row, row, ...]) - 2.19.7. coldefs() - 2.19.8. rows() - - 3. Perl samples - - 3.1. sample directory - - 3.1.1. Script descriptions - - 4. Frequently Asked Questions - 5. Contributors - - 5.1. By Commit Statistics - 5.2. By Commit Activity - - 6. Documentation - - 6.1. Contributors - - List of Tables - - 5.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 5.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set filename parameter - 1.2. Set modpath parameter - 1.3. perl_exec_simple() usage - 1.4. perl_exec() usage - -Chapter 1. Admin Guide - -1.1. Overview - - The time needed when writing a new OpenSIPS module - unfortunately is quite high, while the options provided by the - configuration file are limited to the features implemented in - the modules. - - With this Perl module, you can easily implement your own - OpenSIPS extensions in Perl. This allows for simple access to - the full world of CPAN modules. SIP URI rewriting could be - implemented based on regular expressions; accessing arbitrary - data backends, e.g. LDAP or Berkeley DB files, is now extremely - simple. - -1.2. Installing the module - - This Perl module is loaded in opensips.cfg (just like all the - other modules) with loadmodule("/path/to/perl.so");. - - For the Perl module to compile, you need a reasonably recent - version of perl (tested with 5.8.8) linked dynamically. It is - strongly advised to use a threaded version. The default binary - packages from your favorite Linux distribution should work - fine. - - Cross compilation is supported by the Makefile. You need to set - the environment variables PERLLDOPTS, PERLCCOPTS and TYPEMAP to - values similar to the output of -PERLLDOPTS: perl -MExtUtils::Embed -e ldopts -PERLCCOPTS: perl -MExtUtils::Embed -e ccopts -TYPEMAP: echo "`perl -MConfig -e 'print $Config{installprivlib}'`/Ext -Utils/typemap" - - The exact position of your (precompiled!) perl libraries - depends on the setup of your environment. - -1.3. Using the module - - The Perl module has two interfaces: The perl side, and the - OpenSIPS side. Once a Perl function is defined and loaded via - the module parameters (see below), it may be called in - OpenSIPS's configuration at an arbitary point. E.g., you could - write a function "ldap_alias" in Perl, and then execute -... -if (perl_exec("ldap_alias")) { - ... -} -... - - just as you would have done with the current alias_db module. - - The functions you can use are listed in the exported_functions - section below. - - On the Perl side, there are a number of functions that let you - read and modify the current SIP message, such as the RURI or - the message flags. An introduction to the Perl interface and - the full reference documentation can be found below. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * The "sl" module is needed for sending replies uppon fatal - errors. All other modules can be accessed from the Perl - module, though. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * Perl 5.8.x or later - - Additionally, a number of perl modules should be installed. The - OpenSIPS::LDAPUtils package relies on Net::LDAP to be - installed. One of the sample scripts needs IPC::Shareable - - This module has been developed and tested with Perl 5.8.8, but - should work with any 5.8.x release. Compilation is possible - with 5.6.x, but its behavior is unsupported. Earlier versions - do not work. - - On current Debian systems, at least the following packages - should be installed: - * perl - * perl-base - * perl-modules - * libperl5.8 - * libperl-dev - * libnet-ldap-perl - * libipc-shareable-perl - - It was reported that other Debian-style distributions (such as - Ubuntu) need the same packages. - - On SuSE systems, at least the following packages should be - installed: - * perl - * perl-ldap - * IPC::Shareable perl module from CPAN - - Although SuSE delivers a lot of perl modules, others may have - to be fetched from CPAN. Consider using the program “cpan2rpm” - - which, in turn, is available on CPAN. It creates RPM files - from CPAN. - -1.5. Exported Parameters - -1.5.1. filename (string) - - This is the file name of your script. This may be set once - only, but it may include an arbitary number of functions and - “use” as many Perl module as necessary. - - May not be empty! - - Example 1.1. Set filename parameter -... -modparam("perl", "filename", "/home/john/opensips/myperl.pl") -... - -1.5.2. modpath (string) - - The path to the Perl modules included (OpenSIPS.pm et.al). It - is not absolutely crucial to set this path, as you may install - the Modules in Perl's standard path, or update the “%INC” - variable from within your script. Using this module parameter - is the standard behavior, though. - - Example 1.2. Set modpath parameter -... -modparam("perl", "modpath", "/usr/local/lib/opensips/perl/") -... - -1.6. Exported Functions - -1.6.1. perl_exec_simple(func, [param]) - - Calls a perl function without passing it the current SIP - message. May be used for very simple simple requests that do - not have to fiddle with the message themselves, but rather - return information values about the environment. - - The first parameter is the function to be called. An arbitrary - string may optionally be passed as a parameter. - - The function returns 1 if the perl function was successfully - called or -1 if an internal error occured. Note that it does - not propagate the return value of the perl function. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE and BRANCH_ROUTE. - - Example 1.3. perl_exec_simple() usage -... -if ($rm=="INVITE") { - perl_exec_simple("dosomething", "on invite messages"); -}; -... - -1.6.2. perl_exec(func, [param]) - - Calls a perl function with passing it the current SIP message. - The SIP message is reflected by a Perl module that gives you - access to the information in the current SIP message - (OpenSIPS::Message). - - The first parameter is the function to be called. An arbitrary - string may be passed as a parameter. - - The function returns back to the OpenSIPS script the value - returned by the perl function. Note that if this value is 0 the - script execution will be stoped, similarly to calling exit. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE and BRANCH_ROUTE. - - Example 1.4. perl_exec() usage -... -if (perl_exec("ldapalias")) { - ... -}; -... - -Chapter 2. OpenSIPS Perl API - -2.1. OpenSIPS - - This module provides access to a limited number of OpenSIPS - core functions. As the most interesting functions deal with SIP - messages, they are located in the OpenSIPS::Message class - below. - -2.1.1. log(level,message) - - Logs the message with OpenSIPS's logging facility. The logging - level is one of the following: -* L_ALERT -* L_CRIT -* L_ERR -* L_WARN -* L_NOTICE -* L_INFO -* L_DBG - - Please note that this method is NOT automatically exported, as - it collides with the perl function log (which calculates the - logarithm). Either explicitly import the function (via use - OpenSIPS qw ( log );), or call it with its full name: -OpenSIPS::log(L_INFO, "foobar"); - -2.2. OpenSIPS::Message - - This package provides access functions for an OpenSIPS sip_msg - structure and its sub-components. Through its means it is - possible to fully configure alternative routing decisions. - -2.2.1. getType() - - Returns one of the constants SIP_REQUEST, SIP_REPLY, - SIP_INVALID stating the type of the current message. - -2.2.2. getStatus() - - Returns the status code of the current Reply message. This - function is invalid in Request context! - -2.2.3. getReason() - - Returns the reason of the current Reply message. This function - is invalid in Request context! - -2.2.4. getVersion() - - Returns the version string of the current SIP message. - -2.2.5. getRURI() - - This function returns the recipient URI of the present SIP - message: - - my $ruri = $m->getRURI(); - - getRURI returns a string. See “getParsedRURI()” below how to - receive a parsed structure. - - This function is valid in request messages only. - -2.2.6. getMethod() - - Returns the current method, such as INVITE, REGISTER, ACK and - so on. - - my $method = $m->getMethod(); - - This function is valid in request messages only. - -2.2.7. getFullHeader() - - Returns the full message header as present in the current - message. You might use this header to further work with it with - your favorite MIME package. - - my $hdr = $m->getFullHeader(); - -2.2.8. getBody() - - Returns the message body. - -2.2.9. getMessage() - - Returns the whole message including headers and body. - -2.2.10. getHeader(name) - - Returns the body of the first message header with this name. - - print $m->getHeader("To"); - - "John" - -2.2.11. getHeaderNames() - - Returns an array of all header names. Duplicates possible! - -2.2.12. moduleFunction(func,string1,string2) - - Search for an arbitrary function in module exports and call it - with the parameters self, string1, string2. - - string1 and/or string2 may be omitted. - - As this function provides access to the functions that are - exported to the OpenSIPS configuration file, it is autoloaded - for unknown functions. Instead of writing -$m->moduleFunction("sl_send_reply", "500", "Internal Error"); -$m->moduleFunction("xlog", "L_INFO", "foo"); - - you may as well write -$m->sl_send_reply("500", "Internal Error"); -$m->xlog("L_INFO", "foo"); - - WARNING - - In OpenSIPS 1.2, only a limited subset of module functions is - available. This restriction will be removed in a later version. - - Here is a list of functions that are expected to be working - (not claiming completeness): -* alias_db_lookup -* consume_credentials -* is_rpid_user_e164 -* append_rpid_hf -* bind_auth -* avp_print -* cpl_process_register -* cpl_process_register_norpl -* load_dlg -* ds_next_dst -* ds_next_domain -* ds_mark_dst -* ds_mark_dst -* is_from_local -* is_uri_host_local -* dp_can_connect -* dp_apply_policy -* enum_query (without parameters) -* enum_fquery (without parameters) -* is_from_user_enum (without parameters) -* i_enum_query (without parameters) -* imc_manager -* jab_* (all functions from the jabber module) -* sdp_mangle_ip -* sdp_mangle_port -* encode_contact -* decode_contact -* decode_contact_header -* fix_contact -* use_media_proxy -* end_media_session -* m_store -* m_dump -* fix_nated_contact -* unforce_rtp_proxy -* force_rtp_proxy -* fix_nated_register -* add_rcv_param -* options_reply -* checkospheader -* validateospheader -* requestosprouting -* checkosproute -* prepareosproute -* prepareallosproutes -* checkcallingtranslation -* reportospusage -* mangle_pidf -* mangle_message_cpim -* add_path (without parameters) -* add_path_received (without parameters) -* prefix2domain -* allow_routing (without parameters) -* allow_trusted -* pike_check_req -* handle_publish -* handle_subscribe -* stored_pres_info -* bind_pua -* send_publish -* send_subscribe -* pua_set_publish -* loose_route -* record_route -* load_rr -* sip_trace -* sl_reply_error -* sd_lookup -* sstCheckMin -* append_time -* has_body (without parameters) -* is_peer_verified -* t_newtran -* t_release -* t_relay (without parameters) -* t_flush_flags -* t_check_trans -* t_was_cancelled -* uac_restore_from -* uac_auth -* has_totag -* tel2sip -* check_to -* check_from -* radius_does_uri_exist -* ul_* (All functions exported by the usrloc module for user access) -* xmpp_send_message - -2.2.13. log(level,message) (deprecated type) - - Logs the message with OpenSIPS's logging facility. The logging - level is one of the following: -* L_ALERT -* L_CRIT -* L_ERR -* L_WARN -* L_NOTICE -* L_INFO -* L_DBG - - The logging function should be accessed via the OpenSIPS module - variant. This one, located in OpenSIPS::Message, is deprecated. - -2.2.14. rewrite_ruri(newruri) - - Sets a new destination (recipient) URI. Useful for rerouting - the current message/call. -if ($m->getRURI() =~ m/\@somedomain.net/) { - $m->rewrite_ruri("sip:dispatcher\@organization.net"); -} - -2.2.15. setFlag(flag) - - Sets a message flag. The constants as known from the C API may - be used, when Constants.pm is included. - -2.2.16. resetFlag(flag) - - Resets a message flag. - -2.2.17. isFlagSet(flag) - - Returns whether a message flag is set or not. - -2.2.18. pseudoVar(string) - - Returns a new string where all pseudo variables are substituted - by their values. Can be used to receive the values of single - variables, too. - - Please remember that you need to escape the '$' sign in perl - strings! - -2.2.19. append_branch(branch,qval) - - Append a branch to current message. - -2.2.20. serialize_branches(clean_before, keep_order) - - Serialize branches. - -2.2.21. next_branches() - - Next branches. - -2.2.22. getParsedRURI() - - Returns the current destination URI as an OpenSIPS::URI object. - -2.3. OpenSIPS::URI - - This package provides functions for access to sip_uri - structures. - -2.3.1. user() - - Returns the user part of this URI. - -2.3.2. host() - - Returns the host part of this URI. - -2.3.3. passwd() - - Returns the passwd part of this URI. - -2.3.4. port() - - Returns the port part of this URI. - -2.3.5. params() - - Returns the params part of this URI. - -2.3.6. headers() - - Returns the headers part of this URI. - -2.3.7. transport() - - Returns the transport part of this URI. - -2.3.8. ttl() - - Returns the ttl part of this URI. - -2.3.9. user_param() - - Returns the user_param part of this URI. - -2.3.10. maddr() - - Returns the maddr part of this URI. - -2.3.11. method() - - Returns the method part of this URI. - -2.3.12. lr() - - Returns the lr part of this URI. - -2.3.13. r2() - - Returns the r2 part of this URI. - -2.3.14. transport_val() - - Returns the transport_val part of this URI. - -2.3.15. ttl_val() - - Returns the ttl_val part of this URI. - -2.3.16. user_param_val() - - Returns the user_param_val part of this URI. - -2.3.17. maddr_val() - - Returns the maddr_val part of this URI. - -2.3.18. method_val() - - Returns the method_val part of this URI. - -2.3.19. lr_val() - - Returns the lr_val part of this URI. - -2.3.20. r2_val() - - Returns the r2_val part of this URI. - -2.4. OpenSIPS::AVP - - This package provides access functions for OpenSIPS's AVPs. - These variables can be created, evaluated, modified and removed - through this package. - - Please note that these functions do NOT support the notation - used in the configuration file, but directly work on strings or - numbers. See documentation of add method below. - -2.4.1. add(name,val) - - Add an AVP. - - Add an OpenSIPS AVP to its environment. name and val may both - be integers or strings; this function will try to guess what is - correct. Please note that -OpenSIPS::AVP::add("10", "10") - - is something different than -OpenSIPS::AVP::add(10, 10) - - due to this evaluation: The first will create _string_ AVPs - with the name 10, while the latter will create a numerical AVP. - - You can modify/overwrite AVPs with this function. - -2.4.2. get(name) - - get an OpenSIPS AVP: -my $numavp = OpenSIPS::AVP::get(5); -my $stravp = OpenSIPS::AVP::get("foo"); - -2.4.3. destroy(name) - - Destroy an AVP. -OpenSIPS::AVP::destroy(5); -OpenSIPS::AVP::destroy("foo"); - -2.5. OpenSIPS::Utils::PhoneNumbers - - OpenSIPS::Utils::PhoneNumbers - Functions for canonical forms - of phone numbers. -use OpenSIPS::Utils::PhoneNumbers; - -my $phonenumbers = new OpenSIPS::Utils::PhoneNumbers( - publicAccessPrefix => "0", - internationalPrefix => "+", - longDistancePrefix => "0", - areaCode => "761", - pbxCode => "456842", - countryCode => "49" - ); - -$canonical = $phonenumbers->canonicalForm("07612034567"); -$number = $phonenumbers->dialNumber("+497612034567"); - - A telphone number starting with a plus sign and containing all - dial prefixes is in canonical form. This is usally not the - number to dial at any location, so the dialing number depends - on the context of the user/system. - - The idea to canonicalize numbers were taken from hylafax. - - Example: +497614514829 is the canonical form of my phone - number, 829 is the number to dial at Pyramid, 4514829 is the - dialing number from Freiburg are and so on. - - To canonicalize any number, we strip off any dial prefix we - find and then add the prefixes for the location. So, when the - user enters the number 04514829 in context pyramid, we remove - the publicAccessPrefix (at Pyramid this is 0) and the pbxPrefix - (4514 here). The result is 829. Then we add all the general - dial prefixes - 49 (country) 761 (area) 4514 (pbx) and 829, the - number itself => +497614514829 - - To get the dialing number from a canonical phone number, we - substract all general prefixes until we have something - - As said before, the interpretation of a phone number depends on - the context of the location. For the functions in this package, - the context is created through the new operator. - - The following fields should be set: -'longDistancePrefix' -'areaCode' -'pbxCode' -'internationalPrefix' -'publicAccessPrefix' -'countryCode' - - This module exports the following functions when useed: - -2.5.1. new(publicAccessPrefix,internationalPrefix,longDistancePrefix, -countryCode,areaCode,pbxCode) - - The new operator returns an object of this type and sets its - locational context according to the passed parameters. See - OpenSIPS::Utils::PhoneNumbers above. - -2.5.2. canonicalForm( number [, context] ) - - Convert a phone number (given as first argument) into its - canonical form. When no context is passed in as the second - argument, the default context from the systems configuration - file is used. - -2.5.3. dialNumber( number [, context] ) - - Convert a canonical phone number (given in the first argument) - into a number to to dial. WHen no context is given in the - second argument, a default context from the systems - configuration is used. - -2.6. OpenSIPS::LDAPUtils::LDAPConf - - OpenSIPS::LDAPUtils::LDAPConf - Read openldap config from - standard config files. -use OpenSIPS::LDAPUtils::LDAPConf; -my $conf = new OpenSIPS::LDAPUtils::LDAPConf(); - - This module may be used to retrieve the global LDAP - configuration as used by other LDAP software, such as - nsswitch.ldap and pam-ldap. The configuration is usualy stored - in /etc/openldap/ldap.conf - - When used from an account with sufficient privilegs (e.g. - root), the ldap manager passwort is also retrieved. - -2.6.1. Constructor new() - - Returns a new, initialized OpenSIPS::LDAPUtils::LDAPConf - object. - -2.6.2. Method base() - - Returns the servers base-dn to use when doing queries. - -2.6.3. Method host() - - Returns the ldap host to contact. - -2.6.4. Method port() - - Returns the ldap servers port. - -2.6.5. Method uri() - - Returns an uri to contact the ldap server. When there is no - ldap_uri in the configuration file, an ldap: uri is constucted - from host and port. - -2.6.6. Method rootbindpw() - - Returns the ldap "root" password. - - Note that the rootbindpw is only available when the current - account has sufficient privilegs to access - /etc/openldap/ldap.secret. - -2.6.7. Method rootbinddn() - - Returns the DN to use for "root"-access to the ldap server. - -2.6.8. Method binddn() - - Returns the DN to use for authentication to the ldap server. - When no bind dn has been specified in the configuration file, - returns the rootbinddn. - -2.6.9. Method bindpw() - - Returns the password to use for authentication to the ldap - server. When no bind password has been specified, returns the - rootbindpw if any. - -2.7. OpenSIPS::LDAPUtils::LDAPConnection - - OpenSIPS::LDAPUtils::LDAPConnection - Perl module to perform - simple LDAP queries. - - OO-Style interface: -use OpenSIPS::LDAPUtils::LDAPConnection; -my $ldap = new OpenSIPS::LDAPUtils::LDAPConnection; -my @rows = $ldap-search("uid=andi","ou=people,ou=coreworks,ou=de"); - - Procedural interface: -use OpenSIPS::LDAPUtils::LDAPConnection; -my @rows = $ldap->search( - new OpenSIPS::LDAPUtils::LDAPConfig(), "uid=andi","ou=people,ou=co -reworks,ou=de"); - - This perl module offers a somewhat simplified interface to the - Net::LDAP functionality. It is intended for cases where just a - few attributes should be retrieved without the overhead of the - full featured Net::LDAP. - -2.7.1. Constructor new( [config, [authenticated]] ) - - Set up a new LDAP connection. - - The first argument, when given, should be a hash reference - pointing to to the connection parameters, possibly an - OpenSIPS::LDAPUtils::LDAPConfig object. This argument may be - undef in which case a new (default) - OpenSIPS::LDAPUtils::LDAPConfig object is used. - - When the optional second argument is a true value, the - connection will be authenticated. Otherwise an anonymous bind - is done. - - On success, a new LDAPConnection object is returned, otherwise - the result is undef. - -2.7.2. Function/Method search( conf, filter, base, -[requested_attributes ...]) - - perform an ldap search, return the dn of the first matching - directory entry, unless a specific attribute has been - requested, in wich case the values(s) fot this attribute are - returned. - - When the first argument (conf) is a - OpenSIPS::LDAPUtils::LDAPConnection, it will be used to perform - the queries. You can pass the first argument implicitly by - using the "method" syntax. - - Otherwise the conf argument should be a reference to a hash - containing the connection setup parameters as contained in a - OpenSIPS::LDAPUtils::LDAPConf object. In this mode, the - OpenSIPS::LDAPUtils::LDAPConnection from previous queries will - be reused. - -2.7.2.1. Arguments: - - conf - configuration object, used to find host,port,suffix and - use_ldap_checks - - filter - ldap search filter, eg '(mail=some@domain)' - - base - search base for this query. If undef use default suffix, - concat base with default suffix if the last char is a - ',' - - requested_attributes - retrieve the given attributes instead of the dn from the - ldap directory. - -2.7.2.2. Result: - - Without any specific requested_attributes, return the dn of all - matching entries in the LDAP directory. - - When some requested_attributes are given, return an array with - those attibutes. When multiple entries match the query, the - attribute lists are concatenated. - -2.8. OpenSIPS::VDB - - This package is an (abstract) base class for all virtual - databases. Derived packages can be configured to be used by - OpenSIPS as a database. - - The base class itself should NOT be used in this context, as it - does not provide any functionality. - -2.9. OpenSIPS::Constants - - This package provides a number of constants taken from enums - and defines of OpenSIPS header files. Unfortunately, there is - no mechanism for updating the constants automatically, so check - the values if you are in doubt. - -2.10. OpenSIPS::VDB::Adapter::Speeddial - - This adapter can be used with the speeddial module. - -2.11. OpenSIPS::VDB::Adapter::Alias - - This package is intended for usage with the alias_db module. - The query VTab has to take two arguments and return an array of - two arguments (user name/domain). - -2.11.1. query(conds,retkeys,order) - - Queries the vtab with the given arguments for request - conditions, keys to return and sort order column name. - -2.12. OpenSIPS::VDB::Adapter::AccountingSIPtrace - - This package is an Adapter for the acc and tracer modules, - featuring only an insert operation. - -2.13. OpenSIPS::VDB::Adapter::Describe - - This package is intended for debug usage. It will print - information about requested functions and operations of a - client module. - - Use this module to request schema information when creating new - adapters. - -2.14. OpenSIPS::VDB::Adapter::Auth - - This adapter is intended for usage with the auth_db module. The - VTab should take a username as an argument and return a (plain - text!) password. - -2.15. OpenSIPS::VDB::ReqCond - - This package represents a request condition for database - access, consisting of a column name, an operator (=, <, >, - ...), a data type and a value. - - This package inherits from OpenSIPS::VDB::Pair and thus - includes its methods. - -2.15.1. new(key,op,type,name) - - Constructs a new Column object. - -2.15.2. op() - - Returns or sets the current operator. - -2.16. OpenSIPS::VDB::Pair - - This package represents database key/value pairs, consisting of - a key, a value type, and the value. - - This package inherits from OpenSIPS::VDB::Value and thus has - the same methods. - -2.16.1. new(key,type,name) - - Constructs a new Column object. - -2.16.2. key() - - Returns or sets the current key. - -2.17. OpenSIPS::VDB::VTab - - This package handles virtual tables and is used by the - OpenSIPS::VDB class to store information about valid tables. - The package is not inteded for end user access. - -2.17.1. new() - -Constructs a new VTab object - -2.17.2. call(op,[args]) - - Invokes an operation on the table (insert, update, ...) with - the given arguments. - -2.18. OpenSIPS::VDB::Value - - This package represents a database value. Additional to the - data itself, information about its type is stored. - -2.18.1. stringification - - When accessing a OpenSIPS::VDB::Value object as a string, it - simply returns its data regardless of its type. =cut - - use strict; - - package OpenSIPS::VDB::Value; - - use overload '""' => \&stringify; - - sub stringify { shift->{data} } - - use OpenSIPS; use OpenSIPS::Constants; - - our @ISA = qw ( OpenSIPS::Utils::Debug ); - -2.18.2. new(type,data) - - Constructs a new Value object. Its data type and the data are - passed as parameters. - -2.18.3. type() - - Returns or sets the current data type. Please consider using - the constants from OpenSIPS::Constants - -2.18.4. data() - - Returns or sets the current data. - -2.19. OpenSIPS::VDB::Column - - This package represents database column definition, consisting - of a column name and its data type. - -2.19.1. Stringification - - When accessing a OpenSIPS::VDB::Column object as a string, it - simply returns its column name regardless of its type. =cut - - package OpenSIPS::VDB::Column; - - use overload '""' => \&stringify; - - sub stringify { shift->{name} } - - use OpenSIPS; use OpenSIPS::Constants; - - our @ISA = qw ( OpenSIPS::Utils::Debug ); - -2.19.2. new(type,name) - - Constructs a new Column object. Its type and the name are - passed as parameters. - -2.19.3. type( ) - - Returns or sets the current type. Please consider using the - constants from OpenSIPS::Constants - -2.19.4. name() - - Returns or sets the current column name. - -2.19.5. OpenSIPS::VDB::Result - - This class represents a VDB result set. It contains a column - definition, plus an array of rows. Rows themselves are simply - references to arrays of scalars. - -2.19.6. new(coldefs,[row, row, ...]) - - The constructor creates a new Result object. Its first - parameter is a reference to an array of OpenSIPS::VDB::Column - objects. Additional parameters may be passed to provide initial - rows, which are references to arrays of scalars. - -2.19.7. coldefs() - -Returns or sets the column definition of the object. - -2.19.8. rows() - -Returns or sets the rows of the object. - -Chapter 3. Perl samples - - Revision History - Revision $Revision: 5901 $ $Date$ - -3.1. sample directory - - There are a number of example scripts in the “samples/”. They - are documented well. Read them, it will explain a lot to you :) - - If you want to use any of these scripts directly in your - implementation, you can use Perl's “require” mechanism to - import them (just remember that you need to use quotes when - require'ing .pl files). - -3.1.1. Script descriptions - - The included sample scripts are described below: - -3.1.1.1. branches.pl - - The minimal function in branches.pl demonstrates that you can - access the "append_branch" function from within perl, just as - you would have done from your normal configuration file. You'll - find documentation on the concepts of branching in the OpenSIPS - documentation. - -3.1.1.2. firstline.pl - - Message's first_line structure may be evaluated. Message can be - either of SIP_REQUEST or SIP_REPLY. Depending on that, - different information can be received. This script demonstrates - these functions. - -3.1.1.3. flags.pl - - The perl module provides access to OpenSIPS's flagging - mechanism. The flag names available for OpenSIPS modules are - made available through the OpenSIPS::Constants package, so you - can flag messages as "green", "magenta" etc. - - The first function, setflag, demonstrates how the "green" flag - is set. In the second function, readflag, the "green" and - "magenta" flags are evaluated. - -3.1.1.4. functions.pl - - This sample script demonstrates different things related to - calling functions from within perl, and the different types of - functions you can offer for OpenSIPS access. - - “exportedfuncs” simply demonstrates that you can use the - moduleFunction method to call functions offered by other - modules. The results are equivalent to calling these functions - from your config file. In the demonstrated case, telephone - calls with a destination number beginning with 555... are - rejected with an internal server error. Other destination - addresses are passed to the alias_db module. - - Please note that the moduleFunction method is not fully - available in OpenSIPS 1.2. See the method's documentation for - details. - - “paramfunc” shows that you can pass arbitrary strings to perl - functions. Do with them whatever you want :) - - “autotest” demonstrates that unknown functions in - OpenSIPS::Message objects are automatically transformed into - calls to module functions. - - The “diefunc”s show that dying perl scripts - by "manual" - dying, or because of script errors - are handled by the - OpenSIPS package. The error message is logged through - OpenSIPS's logging mechanism. Please note that this only works - correctly if you do NOT overwrite the default die handler. Oh, - yes, that works for warnings, too. - -3.1.1.5. headers.pl - - Header extraction is among the most crucial functionalities - while processing SIP messages. This sample script demonstrates - access to header names and values within two sample functions. - - “headernames” extracts all header names and logs their names. - - “someheaders” logs the contents of the two headers, “To” and - “WWW-Contact”. As you can see, headers that occur more than - once are retrieved as an array, which may be accessed by Perl's - array accessing methods. - -3.1.1.6. logging.pl - - For debugging purposes, you probably want to write messages to - the syslog. The “logdemo” shows three ways to access the - OpenSIPS log function: it is available through the OpenSIPS - class as well as through the OpenSIPS::Message class. - - Remember that you can use exported functions from other - modules. You may thus as well use the “xlog” module and it's - xlog function. - - The L_INFO, L_DBG, L_ERR, L_CRIT... constants are available - through the OpenSIPS::Constants package. - -3.1.1.7. messagedump.pl - - This script demonstrates how to access the whole message header - of the current message. Please note that modifications on the - message made by earlier function calls in your configuration - script may NOT be reflected in this dump. - -3.1.1.8. persistence.pl - - When processing SIP messages, you may want to use persistent - data across multiple calls to your Perl functions. Your first - option is to use global variables in your script. - Unfortunately, these globals are not visible from the mulitple - instances of OpenSIPS. You may want to use a mechanism such as - the IPC::Shareable shared memory access package to correct - this. - -3.1.1.9. phonenumbers.pl - - The OpenSIPS::Utils::PhoneNumbers package provides two methods - for the transformation of local to canonical telephone numbers, - and vice versa. This script demonstrates it's use. - -3.1.1.10. pseudovars.pl - - This script demonstrates the Perl module's “pseudoVar” method. - It may be used to retrieve the values of current pseudo - variables. - - You might notice that there is no particular function for - setting pseudo variables; you may use the exported functions - from the sqlops module, though. - -Chapter 4. Frequently Asked Questions - - 4.1. - - Are there known bugs in the Perl module? - - The Perl module does have a few shortcomings that may be - regarded as bugs. - * Missing module functions. Not all functions of other - modules are available for Perl access. The reason for this - is a design property of OpenSIPS. Making available more - functions is work in progress. - * Perl and threads. Perl itself is, when compiled with the - correct parameters, thread safe; unfortunately, not all - Perl modules are. The DBI modules, especially (but not - restricted to) DBI::ODBC are known NOT to be thread safe. - Using DBI::ODBC -- and possibly other non-thread-safe Perl - extensions -- may result in erroneous behavior of OpenSIPS, - including (but not restricted to) server crashes and wrong - routing. - - 4.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 4.3. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 4.4. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 5. Contributors - -5.1. By Commit Statistics - - Table 5.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bastian Friedrich 116 38 8597 284 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 51 32 715 688 - 3. Razvan Crainea (@razvancrainea) 23 21 99 60 - 4. Liviu Chircu (@liviuchircu) 22 18 62 133 - 5. Vlad Patrascu (@rvlad-patrascu) 20 10 264 408 - 6. Daniel-Constantin Mierla (@miconda) 19 14 164 125 - 7. Maksym Sobolyev (@sobomax) 5 3 10 42 - 8. Julien Blache 4 1 80 64 - 9. Edson Gellert Schubert 4 1 0 141 - 10. Ionut Ionita (@ionutrazvanionita) 3 1 100 7 - - All remaining contributors: Ancuta Onofrei, Konstantin - Bokarius, Boris Ratner, Julián Moreno Patiño, Klaus Darilion, - Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Aaron - Meriwether, Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -5.2. By Commit Activity - - Table 5.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2006 - May 2025 - 2. Aaron Meriwether May 2024 - May 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jan 2020 - 6. Fabian Gast (@fgast) Jan 2020 - Jan 2020 - 7. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Ionut Ionita (@ionutrazvanionita) Oct 2015 - Oct 2015 - - All remaining contributors: Boris Ratner, Ovidiu Sas - (@ovidiusas), Dan Pascu (@danpascu), Klaus Darilion, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Bastian Friedrich, Ancuta Onofrei, Julien - Blache. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 6. Documentation - -6.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), - Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ovidiu - Sas (@ovidiusas), Klaus Darilion, Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Bastian Friedrich. - - Documentation Copyrights: - - Copyright © 2007 Collax GmbH diff --git a/modules/perl/README.md b/modules/perl/README.md new file mode 100644 index 00000000000..67edcf7d966 --- /dev/null +++ b/modules/perl/README.md @@ -0,0 +1,1550 @@ +--- +title: "perl Module" +description: "The time needed when writing a new OpenSIPS module unfortunately is quite high, while the options provided by the configuration file are limited to the features implemented in the modules." +--- + +## Admin Guide + + +### Overview + + +The time needed when writing a new OpenSIPS module unfortunately is quite high, while the +options provided by the configuration file are limited to the features implemented in the +modules. + + +With this Perl module, you can easily implement your own OpenSIPS extensions in Perl. This allows +for simple access to the full world of CPAN modules. SIP URI rewriting could be implemented +based on regular expressions; accessing arbitrary data backends, e.g. LDAP or Berkeley DB files, +is now extremely simple. + + +### Installing the module + + +This Perl module is loaded in opensips.cfg (just like all the other modules) with +loadmodule("/path/to/perl.so");. + + +For the Perl module to compile, you need a reasonably recent version of perl (tested +with 5.8.8) linked dynamically. It is strongly advised to use a threaded version. +The default binary packages from your favorite Linux distribution should work fine. + + +Cross compilation is supported by the Makefile. You need to set the environment variables +PERLLDOPTS, PERLCCOPTS and TYPEMAP to values similar to the output of + + +```c +PERLLDOPTS: perl -MExtUtils::Embed -e ldopts +PERLCCOPTS: perl -MExtUtils::Embed -e ccopts +TYPEMAP: echo "`perl -MConfig -e 'print $Config{installprivlib}'`/ExtUtils/typemap" +``` + + +The exact position of your (precompiled!) perl libraries depends on the setup of your +environment. + + +### Using the module + + +The Perl module has two interfaces: The perl side, and the OpenSIPS side. Once a Perl +function is defined and loaded via the module parameters (see below), it may be +called in OpenSIPS's configuration at an arbitary point. E.g., you could write +a function "ldap_alias" in Perl, and then execute + + +```opensips +... +if (perl_exec("ldap_alias")) { + ... +} +... +``` + + +just as you would have done with the current alias_db module. + + +The functions you can use are listed in the +[exported functions](#exported_functions) section below. + + +On the Perl side, there are a number of functions that let you read and modify the +current SIP message, such as the RURI or the message flags. An introduction +to the Perl interface and the full reference documentation can be found below. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- The "sl" module is needed for sending replies uppon fatal errors. All other modules +can be accessed from the Perl module, though. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *Perl 5.8.x or later* + + +Additionally, a number of perl modules should be installed. The OpenSIPS::LDAPUtils package +relies on Net::LDAP to be installed. One of the sample scripts needs IPC::Shareable + + +This module has been developed and tested with Perl 5.8.8, but should work with any +5.8.x release. Compilation is possible with 5.6.x, but its behavior is unsupported. +Earlier versions do not work. + + +On current Debian systems, at least the following packages should be installed: + + +- perl +- perl-base +- perl-modules +- libperl5.8 +- libperl-dev +- libnet-ldap-perl +- libipc-shareable-perl + + +It was reported that other Debian-style distributions (such as Ubuntu) need the +same packages. + + +On SuSE systems, at least the following packages should be installed: + + +- perl +- perl-ldap +- IPC::Shareable perl module from CPAN + + +Although SuSE delivers a lot of perl modules, others may have to be fetched +from CPAN. Consider using the program "cpan2rpm" - which, in turn, +is available on CPAN. It creates RPM files from CPAN. + + +### Exported Parameters + + +#### filename (string) + + +This is the file name of your script. This may be set once only, but it may include an arbitary +number of functions and "use" as many Perl module as necessary. + + +*May not be empty!* + + +```opensips title="Set filename parameter" +... +modparam("perl", "filename", "/home/john/opensips/myperl.pl") +... +``` + + +#### modpath (string) + + +The path to the Perl modules included (OpenSIPS.pm et.al). It is not absolutely +crucial to set this path, +as you *may* install the Modules in Perl's standard path, or update +the "%INC" variable from within your script. Using this module parameter +is the standard behavior, though. + + +```opensips title="Set modpath parameter" +... +modparam("perl", "modpath", "/usr/local/lib/opensips/perl/") +... +``` + + +### Exported Functions + + +#### perl_exec_simple(func, [param]) + + +Calls a perl function *without* passing it the current SIP message. +May be used for very simple simple requests that do not have to fiddle with the message +themselves, but rather return information values about the environment. + + +The first parameter is the function to be called. +An arbitrary string may optionally be passed as a parameter. + + +The function returns *1* if the perl function was successfully called +or *-1* if an internal error occured. Note that it does not propagate +the return value of the perl function. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE and BRANCH_ROUTE. + + +```opensips title="perl_exec_simple() usage" +... +if ($rm=="INVITE") { + perl_exec_simple("dosomething", "on invite messages"); +}; +... +``` + + +#### perl_exec(func, [param]) + + +Calls a perl function *with* passing it the current SIP message. +The SIP message is reflected by a Perl module that gives you access to the information +in the current SIP message (OpenSIPS::Message). + + +The first parameter is the function to be called. +An arbitrary string may be passed as a parameter. + + +The function returns back to the OpenSIPS script the value returned by the perl function. +Note that if this value is *0* the script execution +will be stoped, similarly to calling *exit*. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE and BRANCH_ROUTE. + + +```opensips title="perl_exec() usage" +... +if (perl_exec("ldapalias")) { + ... +}; +... +``` + + +## OpenSIPS Perl API + + +### OpenSIPS + + +This module provides access to a limited number of OpenSIPS core +functions. As the most interesting functions deal with SIP messages, +they are located in the OpenSIPS::Message class below. + + +#### log(level,message) + + +Logs the message with OpenSIPS's logging facility. The logging level +is one of the following: + + +```c +* L_ALERT +* L_CRIT +* L_ERR +* L_WARN +* L_NOTICE +* L_INFO +* L_DBG +``` + + +Please note that this method is *NOT* automatically exported, as it collides +with the perl function log (which calculates the logarithm). Either +explicitly import the function (via `use OpenSIPS qw ( log );`), or call +it with its full name: + + +```c +OpenSIPS::log(L_INFO, "foobar"); +``` + + +### OpenSIPS::Message + + +This package provides access functions for an OpenSIPS `sip_msg` structure and its +sub-components. Through its means it is possible to fully configure +alternative routing decisions. + + +#### getType() + + +Returns one of the constants SIP_REQUEST, SIP_REPLY, SIP_INVALID +stating the type of the current message. + + +#### getStatus() + + +Returns the status code of the current Reply message. This function +is invalid in Request context! + + +#### getReason() + + +Returns the reason of the current Reply message. This function is +invalid in Request context! + + +#### getVersion() + + +Returns the version string of the current SIP message. + + +#### getRURI() + + +This function returns the recipient URI of the present SIP message: + + +`my $ruri = +$m->getRURI();` + + +getRURI returns a string. See ["getParsedRURI()"](#getparsedruri) +below how to receive a parsed structure. + + +This function is valid in request messages only. + + +#### getMethod() + + +Returns the current method, such as `INVITE`, `REGISTER`, `ACK` and so on. + + +`my $method = +$m->getMethod();` + + +This function is valid in request messages only. + + +#### getFullHeader() + + +Returns the full message header as present in the current message. +You might use this header to further work with it with your +favorite MIME package. + + +`my $hdr = +$m->getFullHeader();` + + +#### getBody() + + +Returns the message body. + + +#### getMessage() + + +Returns the whole message including headers and body. + + +#### getHeader(name) + + +Returns the body of the first message header with this name. + + +`print +$m->getHeader("To");` + + +**`"John" +`** + + +#### getHeaderNames() + + +Returns an array of all header names. Duplicates possible! + + +#### moduleFunction(func,string1,string2) + + +Search for an arbitrary function in module exports and call it with +the parameters self, string1, string2. + + +`string1` and/or `string2` may be omitted. + + +As this function provides access to the functions that are exported +to the OpenSIPS configuration file, it is autoloaded for unknown +functions. Instead of writing + + +```c +$m->moduleFunction("sl_send_reply", "500", "Internal Error"); +$m->moduleFunction("xlog", "L_INFO", "foo"); +``` + + +you may as well write + + +```c +$m->sl_send_reply("500", "Internal Error"); +$m->xlog("L_INFO", "foo"); +``` + + +> [!WARNING] +> In OpenSIPS 1.2, only a limited subset of module functions is +> available. This restriction will be removed in a later version. + + +Here is a list of functions that are expected to be working (not +claiming completeness): +* alias_db_lookup +* consume_credentials +* is_rpid_user_e164 +* append_rpid_hf +* bind_auth +* avp_print +* cpl_process_register +* cpl_process_register_norpl +* load_dlg +* ds_next_dst +* ds_next_domain +* ds_mark_dst +* ds_mark_dst +* is_from_local +* is_uri_host_local +* dp_can_connect +* dp_apply_policy +* enum_query (without parameters) +* enum_fquery (without parameters) +* is_from_user_enum (without parameters) +* i_enum_query (without parameters) +* imc_manager +* jab_* (all functions from the jabber module) +* sdp_mangle_ip +* sdp_mangle_port +* encode_contact +* decode_contact +* decode_contact_header +* fix_contact +* use_media_proxy +* end_media_session +* m_store +* m_dump +* fix_nated_contact +* unforce_rtp_proxy +* force_rtp_proxy +* fix_nated_register +* add_rcv_param +* options_reply +* checkospheader +* validateospheader +* requestosprouting +* checkosproute +* prepareosproute +* prepareallosproutes +* checkcallingtranslation +* reportospusage +* mangle_pidf +* mangle_message_cpim +* add_path (without parameters) +* add_path_received (without parameters) +* prefix2domain +* allow_routing (without parameters) +* allow_trusted +* pike_check_req +* handle_publish +* handle_subscribe +* stored_pres_info +* bind_pua +* send_publish +* send_subscribe +* pua_set_publish +* loose_route +* record_route +* load_rr +* sip_trace +* sl_reply_error +* sd_lookup +* sstCheckMin +* append_time +* has_body (without parameters) +* is_peer_verified +* t_newtran +* t_release +* t_relay (without parameters) +* t_flush_flags +* t_check_trans +* t_was_cancelled +* uac_restore_from +* uac_auth +* has_totag +* tel2sip +* check_to +* check_from +* radius_does_uri_exist +* ul_* (All functions exported by the usrloc module for user access) +* xmpp_send_message + +#### log(level,message) (deprecated type) + + +Logs the message with OpenSIPS's logging facility. The logging level +is one of the following: + +* L_ALERT +* L_CRIT +* L_ERR +* L_WARN +* L_NOTICE +* L_INFO +* L_DBG + +The logging function should be accessed via the OpenSIPS module +variant. This one, located in OpenSIPS::Message, is deprecated. + + +#### rewrite_ruri(newruri) + + +Sets a new destination (recipient) URI. Useful for rerouting the +current message/call. + + +```c +if ($m->getRURI() =~ m/\@somedomain.net/) { + $m->rewrite_ruri("sip:dispatcher\@organization.net"); +} +``` + + +#### setFlag(flag) + + +Sets a message flag. The constants as known from the C API may be +used, when Constants.pm is included. + + +#### resetFlag(flag) + + +Resets a message flag. + + +#### isFlagSet(flag) + + +Returns whether a message flag is set or not. + + +#### pseudoVar(string) + + +Returns a new string where all pseudo variables are substituted by +their values. Can be used to receive the values of single +variables, too. + + +**Please remember that you need to escape the +'$' sign in perl strings!** + + +#### append_branch(branch,qval) + + +Append a branch to current message. + + +#### serialize_branches(clean_before, keep_order) + + +Serialize branches. + + +#### next_branches() + + +Next branches. + + +#### getParsedRURI() + + +Returns the current destination URI as an OpenSIPS::URI object. + + +### OpenSIPS::URI + + +This package provides functions for access to sip_uri structures. + + +#### user() + + +Returns the user part of this URI. + + +#### host() + + +Returns the host part of this URI. + + +#### passwd() + + +Returns the passwd part of this URI. + + +#### port() + + +Returns the port part of this URI. + + +#### params() + + +Returns the params part of this URI. + + +#### headers() + + +Returns the headers part of this URI. + + +#### transport() + + +Returns the transport part of this URI. + + +#### ttl() + + +Returns the ttl part of this URI. + + +#### user_param() + + +Returns the user_param part of this URI. + + +#### maddr() + + +Returns the maddr part of this URI. + + +#### method() + + +Returns the method part of this URI. + + +#### lr() + + +Returns the lr part of this URI. + + +#### r2() + + +Returns the r2 part of this URI. + + +#### transport_val() + + +Returns the transport_val part of this URI. + + +#### ttl_val() + + +Returns the ttl_val part of this URI. + + +#### user_param_val() + + +Returns the user_param_val part of this URI. + + +#### maddr_val() + + +Returns the maddr_val part of this URI. + + +#### method_val() + + +Returns the method_val part of this URI. + + +#### lr_val() + + +Returns the lr_val part of this URI. + + +#### r2_val() + + +Returns the r2_val part of this URI. + + +### OpenSIPS::AVP + + +This package provides access functions for OpenSIPS's AVPs. These +variables can be created, evaluated, modified and removed through +this package. + + +Please note that these functions do NOT support the notation used in +the configuration file, but directly work on strings or numbers. See +documentation of add method below. + + +#### add(name,val) + + +Add an AVP. + + +Add an OpenSIPS AVP to its environment. name and val may both be +integers or strings; this function will try to guess what is +correct. Please note that + + +```c +OpenSIPS::AVP::add("10", "10") +``` + + +is something different than + + +```c +OpenSIPS::AVP::add(10, 10) +``` + + +due to this evaluation: The first will create _string_ AVPs with +the name 10, while the latter will create a numerical AVP. + + +You can modify/overwrite AVPs with this function. + + +#### get(name) + + +get an OpenSIPS AVP: + + +```c +my $numavp = OpenSIPS::AVP::get(5); +my $stravp = OpenSIPS::AVP::get("foo"); +``` + + +#### destroy(name) + + +Destroy an AVP. + + +```c +OpenSIPS::AVP::destroy(5); +OpenSIPS::AVP::destroy("foo"); +``` + + +### OpenSIPS::Utils::PhoneNumbers + + +OpenSIPS::Utils::PhoneNumbers - Functions for canonical forms of phone +numbers. + + +```c +use OpenSIPS::Utils::PhoneNumbers; + +my $phonenumbers = new OpenSIPS::Utils::PhoneNumbers( + publicAccessPrefix => "0", + internationalPrefix => "+", + longDistancePrefix => "0", + areaCode => "761", + pbxCode => "456842", + countryCode => "49" + ); + +$canonical = $phonenumbers->canonicalForm("07612034567"); +$number = $phonenumbers->dialNumber("+497612034567"); +``` + + +A telphone number starting with a plus sign and containing all dial +prefixes is in canonical form. This is usally not the number to dial +at any location, so the dialing number depends on the context of the +user/system. + + +The idea to canonicalize numbers were taken from hylafax. + + +Example: +497614514829 is the canonical form of my phone number, 829 +is the number to dial at Pyramid, 4514829 is the dialing number from +Freiburg are and so on. + + +To canonicalize any number, we strip off any dial prefix we find and +then add the prefixes for the location. So, when the user enters the +number 04514829 in context pyramid, we remove the publicAccessPrefix +(at Pyramid this is 0) and the pbxPrefix (4514 here). The result is + 829. Then we add all the general dial prefixes - 49 (country) 761 +(area) 4514 (pbx) and 829, the number itself => +497614514829 + + +To get the dialing number from a canonical phone number, we substract +all general prefixes until we have something + + +As said before, the interpretation of a phone number depends on the +context of the location. For the functions in this package, the +context is created through the `new` operator. + + +The following fields should be set: + + +```c +'longDistancePrefix' +'areaCode' +'pbxCode' +'internationalPrefix' +'publicAccessPrefix' +'countryCode' +``` + + +This module exports the following functions when `use`ed: + + +#### new(publicAccessPrefix,internationalPrefix,longDistancePrefix,countryCode,areaCode,pbxCode) + + +The new operator returns an object of this type and sets its +locational context according to the passed parameters. See + +OpenSIPS::Utils::PhoneNumbers +above. + + +#### canonicalForm( number [, context] ) + + +Convert a phone number (given as first argument) into its canonical +form. When no context is passed in as the second argument, the +default context from the systems configuration file is used. + + +#### dialNumber( number [, context] ) + + +Convert a canonical phone number (given in the first argument) into +a number to to dial. WHen no context is given in the second +argument, a default context from the systems configuration is used. + + +### OpenSIPS::LDAPUtils::LDAPConf + + +OpenSIPS::LDAPUtils::LDAPConf - Read openldap config from standard +config files. + + +```c +use OpenSIPS::LDAPUtils::LDAPConf; +my $conf = new OpenSIPS::LDAPUtils::LDAPConf(); +``` + + +This module may be used to retrieve the global LDAP configuration as +used by other LDAP software, such as `nsswitch.ldap` and `pam-ldap`. The configuration is +usualy stored in `/etc/openldap/ldap.conf` + + +When used from an account with sufficient privilegs (e.g. root), the +ldap manager passwort is also retrieved. + + +#### Constructor new() + + +Returns a new, initialized `OpenSIPS::LDAPUtils::LDAPConf` +object. + + +#### Method base() + + +Returns the servers base-dn to use when doing queries. + + +#### Method host() + + +Returns the ldap host to contact. + + +#### Method port() + + +Returns the ldap servers port. + + +#### Method uri() + + +Returns an uri to contact the ldap server. When there is no +ldap_uri in the configuration file, an `ldap:` uri is constucted from host +and port. + + +#### Method rootbindpw() + + +Returns the ldap "root" password. + + +Note that the `rootbindpw` +is only available when the current account has sufficient privilegs +to access `/etc/openldap/ldap.secret`. + + +#### Method rootbinddn() + + +Returns the DN to use for "root"-access to the ldap server. + + +#### Method binddn() + + +Returns the DN to use for authentication to the ldap server. When +no bind dn has been specified in the configuration file, returns +the `rootbinddn`. + + +#### Method bindpw() + + +Returns the password to use for authentication to the ldap server. +When no bind password has been specified, returns the `rootbindpw` if any. + + +### OpenSIPS::LDAPUtils::LDAPConnection + + +OpenSIPS::LDAPUtils::LDAPConnection - Perl module to perform simple +LDAP queries. + + +OO-Style interface: + + +```c +use OpenSIPS::LDAPUtils::LDAPConnection; +my $ldap = new OpenSIPS::LDAPUtils::LDAPConnection; +my @rows = $ldap-search("uid=andi","ou=people,ou=coreworks,ou=de"); +``` + + +Procedural interface: + + +```c +use OpenSIPS::LDAPUtils::LDAPConnection; +my @rows = $ldap->search( + new OpenSIPS::LDAPUtils::LDAPConfig(), "uid=andi","ou=people,ou=coreworks,ou=de"); +``` + + +This perl module offers a somewhat simplified interface to the +`Net::LDAP` functionality. +It is intended for cases where just a few attributes should be +retrieved without the overhead of the full featured `Net::LDAP`. + + +#### Constructor new( [config, [authenticated]] ) + + +Set up a new LDAP connection. + + +The first argument, when given, should be a hash reference pointing +to to the connection parameters, possibly an `OpenSIPS::LDAPUtils::LDAPConfig` +object. This argument may be `undef` in which case a new +(default) `OpenSIPS::LDAPUtils::LDAPConfig` +object is used. + + +When the optional second argument is a true value, the connection +will be authenticated. Otherwise an anonymous bind is done. + + +On success, a new `LDAPConnection` object is +returned, otherwise the result is `undef`. + + +#### Function/Method search( conf, filter, base, [requested_attributes ...]) + + +perform an ldap search, return the dn of the first matching +directory entry, unless a specific attribute has been requested, in +wich case the values(s) fot this attribute are returned. + + +When the first argument (conf) is a `OpenSIPS::LDAPUtils::LDAPConnection`, +it will be used to perform the queries. You can pass the first +argument implicitly by using the "method" syntax. + + +Otherwise the `conf` +argument should be a reference to a hash containing the connection +setup parameters as contained in a `OpenSIPS::LDAPUtils::LDAPConf` +object. In this mode, the `OpenSIPS::LDAPUtils::LDAPConnection` +from previous queries will be reused. + + +##### Arguments: + + +**conf** + + +configuration object, used to find host,port,suffix and +use_ldap_checks + + +**filter** + + +ldap search filter, eg '(mail=some@domain)' + + +**base** + + +search base for this query. If undef use default suffix, +concat base with default suffix if the last char is a ',' + + +**requested_attributes** + + +retrieve the given attributes instead of the dn from the +ldap directory. + + +##### Result: + + +Without any specific `requested_attributes`, return +the dn of all matching entries in the LDAP directory. + + +When some `requested_attributes` are given, +return an array with those attibutes. When multiple entries match +the query, the attribute lists are concatenated. + + +### OpenSIPS::VDB + + +This package is an (abstract) base class for all virtual databases. +Derived packages can be configured to be used by OpenSIPS as a +database. + + +The base class itself should NOT be used in this context, as it does +not provide any functionality. + + +### OpenSIPS::Constants + + +This package provides a number of constants taken from enums and +defines of OpenSIPS header files. Unfortunately, there is no mechanism +for updating the constants automatically, so check the values if you +are in doubt. + + +### OpenSIPS::VDB::Adapter::Speeddial + + +This adapter can be used with the speeddial module. + + +### OpenSIPS::VDB::Adapter::Alias + + +This package is intended for usage with the alias_db module. The +query VTab has to take two arguments and return an array of two +arguments (user name/domain). + + +#### query(conds,retkeys,order) + + +Queries the vtab with the given arguments for request conditions, +keys to return and sort order column name. + + +### OpenSIPS::VDB::Adapter::AccountingSIPtrace + + +This package is an Adapter for the acc and tracer modules, +featuring only an insert operation. + + +### OpenSIPS::VDB::Adapter::Describe + + +This package is intended for debug usage. It will print information +about requested functions and operations of a client module. + + +Use this module to request schema information when creating new +adapters. + + +### OpenSIPS::VDB::Adapter::Auth + + +This adapter is intended for usage with the auth_db module. The VTab +should take a username as an argument and return a (plain text!) +password. + + +### OpenSIPS::VDB::ReqCond + + +This package represents a request condition for database access, +consisting of a column name, an operator (=, <, >, ...), a data +type and a value. + + +This package inherits from OpenSIPS::VDB::Pair and thus includes its +methods. + + +#### new(key,op,type,name) + + +Constructs a new Column object. + + +#### op() + + +Returns or sets the current operator. + + +### OpenSIPS::VDB::Pair + + +This package represents database key/value pairs, consisting of a +key, a value type, and the value. + + +This package inherits from OpenSIPS::VDB::Value and thus has the same +methods. + + +#### new(key,type,name) + + +Constructs a new Column object. + + +#### key() + + +Returns or sets the current key. + + +### OpenSIPS::VDB::VTab + + +This package handles virtual tables and is used by the OpenSIPS::VDB +class to store information about valid tables. The package is not +inteded for end user access. + + +#### new() + + +```c +Constructs a new VTab object +``` + + +#### call(op,[args]) + + +Invokes an operation on the table (insert, update, ...) with the +given arguments. + + +### OpenSIPS::VDB::Value + + +This package represents a database value. Additional to the data +itself, information about its type is stored. + + +#### stringification + + +When accessing a OpenSIPS::VDB::Value object as a string, it simply +returns its data regardless of its type. =cut + + +use strict; + + +package OpenSIPS::VDB::Value; + + +use overload '""' => \&stringify; + + +sub stringify { shift->{data} } + + +use OpenSIPS; use OpenSIPS::Constants; + + +our @ISA = qw ( OpenSIPS::Utils::Debug ); + + +#### new(type,data) + + +Constructs a new Value object. Its data type and the data are +passed as parameters. + + +#### type() + + +Returns or sets the current data type. Please consider using the +constants from OpenSIPS::Constants + + +#### data() + + +Returns or sets the current data. + + +### OpenSIPS::VDB::Column + + +This package represents database column definition, consisting of a +column name and its data type. + + +#### Stringification + + +When accessing a OpenSIPS::VDB::Column object as a string, it simply +returns its column name regardless of its type. =cut + + +package OpenSIPS::VDB::Column; + + +use overload '""' => \&stringify; + + +sub stringify { shift->{name} } + + +use OpenSIPS; use OpenSIPS::Constants; + + +our @ISA = qw ( OpenSIPS::Utils::Debug ); + + +#### new(type,name) + + +Constructs a new Column object. Its type and the name are passed as +parameters. + + +#### type( ) + + +Returns or sets the current type. Please consider using the +constants from OpenSIPS::Constants + + +#### name() + + +Returns or sets the current column name. + + +#### OpenSIPS::VDB::Result + + +This class represents a VDB result set. It contains a column +definition, plus an array of rows. Rows themselves are simply +references to arrays of scalars. + + +#### new(coldefs,[row, row, ...]) + + +The constructor creates a new Result object. Its first parameter is +a reference to an array of OpenSIPS::VDB::Column objects. Additional +parameters may be passed to provide initial rows, which are +references to arrays of scalars. + + +#### coldefs() + + +```c +Returns or sets the column definition of the object. +``` + + +#### rows() + + +```c +Returns or sets the rows of the object. +``` + + +## Perl samples + + +### sample directory + + +There are a number of example scripts in the "samples/". They are +documented well. Read them, it will explain a lot to you :) + + +If you want to use any of these scripts directly in your implementation, you +can use Perl's "require" mechanism to import them (just remember +that you need to use quotes when require'ing .pl files). + + +#### Script descriptions + + +The included sample scripts are described below: + + +##### branches.pl + + +The minimal function in branches.pl demonstrates that you can access the "append_branch" +function from within perl, just as you would have done from your normal configuration file. +You'll find documentation on the concepts of branching in the OpenSIPS documentation. + + +##### firstline.pl + + +Message's first_line structure may be evaluated. Message can be either of +SIP_REQUEST or SIP_REPLY. Depending on that, different information can be received. +This script demonstrates these functions. + + +##### flags.pl + + +The perl module provides access to OpenSIPS's flagging mechanism. The flag names available +for OpenSIPS modules are made available through the OpenSIPS::Constants package, so you can +flag messages as "green", "magenta" etc. + + +The first function, setflag, demonstrates how the "green" flag is set. In the second function, +readflag, the "green" and "magenta" flags are evaluated. + + +##### functions.pl + + +This sample script demonstrates different things related to calling functions from within perl, +and the different types of functions you can offer for OpenSIPS access. + + +"exportedfuncs" simply demonstrates that you can use the moduleFunction method +to call functions offered by other modules. The results are equivalent to calling these +functions from your config file. In the demonstrated case, telephone calls with a destination +number beginning with 555... are rejected with an internal server error. Other destination +addresses are passed to the alias_db module. + + +Please note that the moduleFunction method is not fully available in OpenSIPS 1.2. See the method's +documentation for details. + + +"paramfunc" shows that you can pass arbitrary strings to perl functions. Do with +them whatever you want :) + + +"autotest" demonstrates that unknown functions in OpenSIPS::Message objects are +automatically transformed into calls to module functions. + + +The "diefunc"s show that dying perl scripts - by "manual" dying, or because of script +errors - are handled by the OpenSIPS package. The error message is logged through OpenSIPS's logging +mechanism. Please note that this only works correctly if you do NOT overwrite the default die handler. +Oh, yes, that works for warnings, too. + + +##### headers.pl + + +Header extraction is among the most crucial functionalities while processing SIP messages. This +sample script demonstrates access to header names and values within two sample functions. + + +"headernames" extracts all header names and logs their names. + + +"someheaders" logs the contents of the two headers, "To" and +"WWW-Contact". As you can see, headers that occur more than once are retrieved +as an array, which may be accessed by Perl's array accessing methods. + + +##### logging.pl + + +For debugging purposes, you probably want to write messages to the syslog. The "logdemo" +shows three ways to access the OpenSIPS log function: it is available through the OpenSIPS class as well +as through the OpenSIPS::Message class. + + +Remember that you can use exported functions from other modules. You may thus as well use the +"xlog" module and it's xlog function. + + +The L_INFO, L_DBG, L_ERR, L_CRIT... constants are available through the OpenSIPS::Constants package. + + +##### messagedump.pl + + +This script demonstrates how to access the whole message header of the current message. Please note that +modifications on the message made by earlier function calls in your configuration script may NOT be +reflected in this dump. + + +##### persistence.pl + + +When processing SIP messages, you may want to use persistent data across multiple calls to your +Perl functions. Your first option is to use global variables in your script. Unfortunately, +these globals are not visible from the mulitple instances of OpenSIPS. You may want to use a +mechanism such as the IPC::Shareable shared memory access package to correct this. + + +##### phonenumbers.pl + + +The OpenSIPS::Utils::PhoneNumbers package provides two methods for the transformation of local to +canonical telephone numbers, and vice versa. This script demonstrates it's use. + + +##### pseudovars.pl + + +This script demonstrates the Perl module's "pseudoVar" method. It may be used to +retrieve the values of current pseudo variables. + + +You might notice that there is no particular function for setting pseudo variables; you may use +the exported functions from the sqlops module, though. + + +## Frequently Asked Questions + + +**Q: Are there known bugs in the Perl module?** + + +The Perl module does have a few shortcomings that may be regarded as bugs. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/perl/doc/contributors.xml b/modules/perl/doc/contributors.xml deleted file mode 100644 index 21b4b796fef..00000000000 --- a/modules/perl/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bastian Friedrich - 116 - 38 - 8597 - 284 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 51 - 32 - 715 - 688 - - - 3. - Razvan Crainea (@razvancrainea) - 23 - 21 - 99 - 60 - - - 4. - Liviu Chircu (@liviuchircu) - 22 - 18 - 62 - 133 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 20 - 10 - 264 - 408 - - - 6. - Daniel-Constantin Mierla (@miconda) - 19 - 14 - 164 - 125 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 10 - 42 - - - 8. - Julien Blache - 4 - 1 - 80 - 64 - - - 9. - Edson Gellert Schubert - 4 - 1 - 0 - 141 - - - 10. - Ionut Ionita (@ionutrazvanionita) - 3 - 1 - 100 - 7 - - - -
-All remaining contributors: Ancuta Onofrei, Konstantin Bokarius, Boris Ratner, Julián Moreno Patiño, Klaus Darilion, Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Aaron Meriwether, Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2006 - May 2025 - - - 2. - Aaron Meriwether - May 2024 - May 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jan 2020 - - - 6. - Fabian Gast (@fgast) - Jan 2020 - Jan 2020 - - - 7. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Oct 2015 - Oct 2015 - - - -
-All remaining contributors: Boris Ratner, Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Bastian Friedrich, Ancuta Onofrei, Julien Blache. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Bastian Friedrich. -
- -
diff --git a/modules/perl/doc/perl.xml b/modules/perl/doc/perl.xml deleted file mode 100644 index cae7641361a..00000000000 --- a/modules/perl/doc/perl.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - perl Module - &osipsname; - - - - &admin; - &pod; - &samples; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Collax GmbH - - diff --git a/modules/perl/doc/perl_admin.xml b/modules/perl/doc/perl_admin.xml deleted file mode 100644 index a7518015189..00000000000 --- a/modules/perl/doc/perl_admin.xml +++ /dev/null @@ -1,258 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The time needed when writing a new OpenSIPS module unfortunately is quite high, while the - options provided by the configuration file are limited to the features implemented in the - modules. - - - With this Perl module, you can easily implement your own OpenSIPS extensions in Perl. This allows - for simple access to the full world of CPAN modules. SIP URI rewriting could be implemented - based on regular expressions; accessing arbitrary data backends, e.g. LDAP or Berkeley DB files, - is now extremely simple. - -
-
- Installing the module - - This Perl module is loaded in opensips.cfg (just like all the other modules) with - loadmodule("/path/to/perl.so");. - - - - For the Perl module to compile, you need a reasonably recent version of perl (tested - with 5.8.8) linked dynamically. It is strongly advised to use a threaded version. - The default binary packages from your favorite Linux distribution should work fine. - - - - Cross compilation is supported by the Makefile. You need to set the environment variables - PERLLDOPTS, PERLCCOPTS and TYPEMAP to values similar to the output of - - -PERLLDOPTS: perl -MExtUtils::Embed -e ldopts -PERLCCOPTS: perl -MExtUtils::Embed -e ccopts -TYPEMAP: echo "`perl -MConfig -e 'print $Config{installprivlib}'`/ExtUtils/typemap" - - - The exact position of your (precompiled!) perl libraries depends on the setup of your - environment. - -
- -
- Using the module - - The Perl module has two interfaces: The perl side, and the OpenSIPS side. Once a Perl - function is defined and loaded via the module parameters (see below), it may be - called in OpenSIPS's configuration at an arbitary point. E.g., you could write - a function "ldap_alias" in Perl, and then execute -... -if (perl_exec("ldap_alias")) { - ... -} -... - - just as you would have done with the current alias_db module. - - - - The functions you can use are listed in the - section below. - - - On the Perl side, there are a number of functions that let you read and modify the - current SIP message, such as the RURI or the message flags. An introduction - to the Perl interface and the full reference documentation can be found below. - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - The "sl" module is needed for sending replies uppon fatal errors. All other modules - can be accessed from the Perl module, though. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - Perl 5.8.x or later - - - - Additionally, a number of perl modules should be installed. The OpenSIPS::LDAPUtils package - relies on Net::LDAP to be installed. One of the sample scripts needs IPC::Shareable - - - This module has been developed and tested with Perl 5.8.8, but should work with any - 5.8.x release. Compilation is possible with 5.6.x, but its behavior is unsupported. - Earlier versions do not work. - - - On current Debian systems, at least the following packages should be installed: - - - perl - perl-base - perl-modules - libperl5.8 - libperl-dev - libnet-ldap-perl - libipc-shareable-perl - - - It was reported that other Debian-style distributions (such as Ubuntu) need the - same packages. - - - On SuSE systems, at least the following packages should be installed: - - - perl - perl-ldap - IPC::Shareable perl module from CPAN - - - Although SuSE delivers a lot of perl modules, others may have to be fetched - from CPAN. Consider using the program cpan2rpm - which, in turn, - is available on CPAN. It creates RPM files from CPAN. - -
-
- -
- Exported Parameters -
- <varname>filename</varname> (string) - - This is the file name of your script. This may be set once only, but it may include an arbitary - number of functions and use as many Perl module as necessary. - - - - May not be empty! - - - - Set <varname>filename</varname> parameter - -... -modparam("perl", "filename", "/home/john/opensips/myperl.pl") -... - - -
- -
- <varname>modpath</varname> (string) - - The path to the Perl modules included (OpenSIPS.pm et.al). It is not absolutely - crucial to set this path, - as you may install the Modules in Perl's standard path, or update - the %INC variable from within your script. Using this module parameter - is the standard behavior, though. - - - Set <varname>modpath</varname> parameter - -... -modparam("perl", "modpath", "/usr/local/lib/opensips/perl/") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">perl_exec_simple(func, [param])</function> - - - Calls a perl function without passing it the current SIP message. - May be used for very simple simple requests that do not have to fiddle with the message - themselves, but rather return information values about the environment. - - - The first parameter is the function to be called. - An arbitrary string may optionally be passed as a parameter. - - - The function returns 1 if the perl function was successfully called - or -1 if an internal error occured. Note that it does not propagate - the return value of the perl function. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE and BRANCH_ROUTE. - - - <function>perl_exec_simple()</function> usage - -... -if ($rm=="INVITE") { - perl_exec_simple("dosomething", "on invite messages"); -}; -... - - -
- -
- - <function moreinfo="none">perl_exec(func, [param])</function> - - - Calls a perl function with passing it the current SIP message. - The SIP message is reflected by a Perl module that gives you access to the information - in the current SIP message (OpenSIPS::Message). - - - The first parameter is the function to be called. - An arbitrary string may be passed as a parameter. - - - The function returns back to the OpenSIPS script the value returned by the perl function. - Note that if this value is 0 the script execution - will be stoped, similarly to calling exit. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE and BRANCH_ROUTE. - - - <function>perl_exec()</function> usage - -... -if (perl_exec("ldapalias")) { - ... -}; -... - - -
-
- -
- diff --git a/modules/perl/doc/perl_faq.xml b/modules/perl/doc/perl_faq.xml deleted file mode 100644 index 0f029cf2630..00000000000 --- a/modules/perl/doc/perl_faq.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - &faqguide; - - - - Are there known bugs in the Perl module? - - - - The Perl module does have a few shortcomings that may be regarded as bugs. - - - - Missing module functions. Not all functions of other modules are - available for Perl access. The reason for this is a design property of - OpenSIPS. Making available more functions is work in progress. - - - Perl and threads. Perl itself is, when compiled with the correct - parameters, thread safe; unfortunately, not all Perl modules are. - The DBI modules, especially (but not restricted to) DBI::ODBC are known - NOT to be thread safe. - Using DBI::ODBC -- and possibly other non-thread-safe Perl - extensions -- may result in erroneous behavior of OpenSIPS, including - (but not restricted to) server crashes and wrong routing. - - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/perl/doc/perl_pod.xml b/modules/perl/doc/perl_pod.xml deleted file mode 100644 index c3a9439d2d1..00000000000 --- a/modules/perl/doc/perl_pod.xml +++ /dev/null @@ -1,1009 +0,0 @@ - -OpenSIPS Perl API -
OpenSIPS - - This module provides access to a limited number of OpenSIPS core - functions. As the most interesting functions deal with SIP messages, - they are located in the OpenSIPS::Message class below. - -
log(level,message) - - Logs the message with OpenSIPS's logging facility. The logging level - is one of the following: - - - - Please note that this method is NOT automatically exported, as it collides - with the perl function log (which calculates the logarithm). Either - explicitly import the function (via ), or call - it with its full name: - - -
-
-
OpenSIPS::Message - - This package provides access functions for an OpenSIPS structure and its - sub-components. Through its means it is possible to fully configure - alternative routing decisions. - -
getType() - - Returns one of the constants SIP_REQUEST, SIP_REPLY, SIP_INVALID - stating the type of the current message. - -
-
getStatus() - - Returns the status code of the current Reply message. This function - is invalid in Request context! - -
-
getReason() - - Returns the reason of the current Reply message. This function is - invalid in Request context! - -
-
getVersion() - - Returns the version string of the current SIP message. - -
-
getRURI() - - This function returns the recipient URI of the present SIP message: - - - getRURI();]]> - - - getRURI returns a string. See getParsedRURI() - below how to receive a parsed structure. - - - This function is valid in request messages only. - -
-
getMethod() - - Returns the current method, such as , , and so on. - - - getMethod();]]> - - - This function is valid in request messages only. - -
-
getFullHeader() - - Returns the full message header as present in the current message. - You might use this header to further work with it with your - favorite MIME package. - - - getFullHeader();]]> - -
-
getBody() - - Returns the message body. - -
-
getMessage() - - Returns the whole message including headers and body. - -
-
getHeader(name) - - Returns the body of the first message header with this name. - - - getHeader("To");]]> - - - ]]> - -
-
getHeaderNames() - - Returns an array of all header names. Duplicates possible! - -
-
moduleFunction(func,string1,string2) - - Search for an arbitrary function in module exports and call it with - the parameters self, string1, string2. - - - and/or may be omitted. - - - As this function provides access to the functions that are exported - to the OpenSIPS configuration file, it is autoloaded for unknown - functions. Instead of writing - - moduleFunction("sl_send_reply", "500", "Internal Error"); -$m->moduleFunction("xlog", "L_INFO", "foo");]]> - - you may as well write - - sl_send_reply("500", "Internal Error"); -$m->xlog("L_INFO", "foo");]]> - - WARNING - - - In OpenSIPS 1.2, only a limited subset of module functions is - available. This restriction will be removed in a later version. - - - Here is a list of functions that are expected to be working (not - claiming completeness): - - -
-
log(level,message) (deprecated type) - - Logs the message with OpenSIPS's logging facility. The logging level - is one of the following: - - - - The logging function should be accessed via the OpenSIPS module - variant. This one, located in OpenSIPS::Message, is deprecated. - -
-
rewrite_ruri(newruri) - - Sets a new destination (recipient) URI. Useful for rerouting the - current message/call. - - getRURI() =~ m/\@somedomain.net/) { - $m->rewrite_ruri("sip:dispatcher\@organization.net"); -}]]> -
-
setFlag(flag) - - Sets a message flag. The constants as known from the C API may be - used, when Constants.pm is included. - -
-
resetFlag(flag) - - Resets a message flag. - -
-
isFlagSet(flag) - - Returns whether a message flag is set or not. - -
-
pseudoVar(string) - - Returns a new string where all pseudo variables are substituted by - their values. Can be used to receive the values of single - variables, too. - - - Please remember that you need to escape the - '$' sign in perl strings! - -
-
append_branch(branch,qval) - - Append a branch to current message. - -
-
serialize_branches(clean_before, keep_order) - - Serialize branches. - -
-
next_branches() - - Next branches. - -
-
getParsedRURI() - - Returns the current destination URI as an OpenSIPS::URI object. - -
-
-
OpenSIPS::URI - - This package provides functions for access to sip_uri structures. - -
user() - - Returns the user part of this URI. - -
-
host() - - Returns the host part of this URI. - -
-
passwd() - - Returns the passwd part of this URI. - -
-
port() - - Returns the port part of this URI. - -
-
params() - - Returns the params part of this URI. - -
-
headers() - - Returns the headers part of this URI. - -
-
transport() - - Returns the transport part of this URI. - -
-
ttl() - - Returns the ttl part of this URI. - -
-
user_param() - - Returns the user_param part of this URI. - -
-
maddr() - - Returns the maddr part of this URI. - -
-
method() - - Returns the method part of this URI. - -
-
lr() - - Returns the lr part of this URI. - -
-
r2() - - Returns the r2 part of this URI. - -
-
transport_val() - - Returns the transport_val part of this URI. - -
-
ttl_val() - - Returns the ttl_val part of this URI. - -
-
user_param_val() - - Returns the user_param_val part of this URI. - -
-
maddr_val() - - Returns the maddr_val part of this URI. - -
-
method_val() - - Returns the method_val part of this URI. - -
-
lr_val() - - Returns the lr_val part of this URI. - -
-
r2_val() - - Returns the r2_val part of this URI. - -
-
-
OpenSIPS::AVP - - This package provides access functions for OpenSIPS's AVPs. These - variables can be created, evaluated, modified and removed through - this package. - - - Please note that these functions do NOT support the notation used in - the configuration file, but directly work on strings or numbers. See - documentation of add method below. - -
add(name,val) - - Add an AVP. - - - Add an OpenSIPS AVP to its environment. name and val may both be - integers or strings; this function will try to guess what is - correct. Please note that - - - - is something different than - - - - due to this evaluation: The first will create _string_ AVPs with - the name 10, while the latter will create a numerical AVP. - - - You can modify/overwrite AVPs with this function. - -
-
get(name) - - get an OpenSIPS AVP: - - -
-
destroy(name) - - Destroy an AVP. - - -
-
-
OpenSIPS::Utils::PhoneNumbers - - OpenSIPS::Utils::PhoneNumbers - Functions for canonical forms of phone - numbers. - - "0", - internationalPrefix => "+", - longDistancePrefix => "0", - areaCode => "761", - pbxCode => "456842", - countryCode => "49" - ); - -$canonical = $phonenumbers->canonicalForm("07612034567"); -$number = $phonenumbers->dialNumber("+497612034567");]]> - - A telphone number starting with a plus sign and containing all dial - prefixes is in canonical form. This is usally not the number to dial - at any location, so the dialing number depends on the context of the - user/system. - - - The idea to canonicalize numbers were taken from hylafax. - - - Example: +497614514829 is the canonical form of my phone number, 829 - is the number to dial at Pyramid, 4514829 is the dialing number from - Freiburg are and so on. - - - To canonicalize any number, we strip off any dial prefix we find and - then add the prefixes for the location. So, when the user enters the - number 04514829 in context pyramid, we remove the publicAccessPrefix - (at Pyramid this is 0) and the pbxPrefix (4514 here). The result is - 829. Then we add all the general dial prefixes - 49 (country) 761 - (area) 4514 (pbx) and 829, the number itself => +497614514829 - - - To get the dialing number from a canonical phone number, we substract - all general prefixes until we have something - - - As said before, the interpretation of a phone number depends on the - context of the location. For the functions in this package, the - context is created through the operator. - - - The following fields should be set: - - - - This module exports the following functions when ed: - -
new(publicAccessPrefix,internationalPrefix,longDistancePrefix,countryCode,areaCode,pbxCode) - - The new operator returns an object of this type and sets its - locational context according to the passed parameters. See - - OpenSIPS::Utils::PhoneNumbers - above. - -
-
canonicalForm( number [, context] ) - - Convert a phone number (given as first argument) into its canonical - form. When no context is passed in as the second argument, the - default context from the systems configuration file is used. - -
-
dialNumber( number [, context] ) - - Convert a canonical phone number (given in the first argument) into - a number to to dial. WHen no context is given in the second - argument, a default context from the systems configuration is used. - -
-
-
OpenSIPS::LDAPUtils::LDAPConf - - OpenSIPS::LDAPUtils::LDAPConf - Read openldap config from standard - config files. - - - - This module may be used to retrieve the global LDAP configuration as - used by other LDAP software, such as and . The configuration is - usualy stored in - - - When used from an account with sufficient privilegs (e.g. root), the - ldap manager passwort is also retrieved. - -
Constructor new() - - Returns a new, initialized - object. - -
-
Method base() - - Returns the servers base-dn to use when doing queries. - -
-
Method host() - - Returns the ldap host to contact. - -
-
Method port() - - Returns the ldap servers port. - -
-
Method uri() - - Returns an uri to contact the ldap server. When there is no - ldap_uri in the configuration file, an uri is constucted from host - and port. - -
-
Method rootbindpw() - - Returns the ldap "root" password. - - - Note that the - is only available when the current account has sufficient privilegs - to access . - -
-
Method rootbinddn() - - Returns the DN to use for "root"-access to the ldap server. - -
-
Method binddn() - - Returns the DN to use for authentication to the ldap server. When - no bind dn has been specified in the configuration file, returns - the . - -
-
Method bindpw() - - Returns the password to use for authentication to the ldap server. - When no bind password has been specified, returns the if any. - -
-
-
OpenSIPS::LDAPUtils::LDAPConnection - - OpenSIPS::LDAPUtils::LDAPConnection - Perl module to perform simple - LDAP queries. - - - OO-Style interface: - - - - Procedural interface: - - search( - new OpenSIPS::LDAPUtils::LDAPConfig(), "uid=andi","ou=people,ou=coreworks,ou=de");]]> - - This perl module offers a somewhat simplified interface to the - functionality. - It is intended for cases where just a few attributes should be - retrieved without the overhead of the full featured . - -
Constructor new( [config, [authenticated]] ) - - Set up a new LDAP connection. - - - The first argument, when given, should be a hash reference pointing - to to the connection parameters, possibly an - object. This argument may be in which case a new - (default) - object is used. - - - When the optional second argument is a true value, the connection - will be authenticated. Otherwise an anonymous bind is done. - - - On success, a new object is - returned, otherwise the result is . - -
-
Function/Method search( conf, filter, base, [requested_attributes ...]) - - perform an ldap search, return the dn of the first matching - directory entry, unless a specific attribute has been requested, in - wich case the values(s) fot this attribute are returned. - - - When the first argument (conf) is a , - it will be used to perform the queries. You can pass the first - argument implicitly by using the "method" syntax. - - - Otherwise the - argument should be a reference to a hash containing the connection - setup parameters as contained in a - object. In this mode, the - from previous queries will be reused. - -
Arguments: - - - - conf - - - configuration object, used to find host,port,suffix and - use_ldap_checks - - - - - filter - - - ldap search filter, eg '(mail=some@domain)' - - - - - base - - - search base for this query. If undef use default suffix, - concat base with default suffix if the last char is a ',' - - - - - requested_attributes - - - retrieve the given attributes instead of the dn from the - ldap directory. - - - - - -
-
Result: - - Without any specific , return - the dn of all matching entries in the LDAP directory. - - - When some are given, - return an array with those attibutes. When multiple entries match - the query, the attribute lists are concatenated. - -
-
-
-
OpenSIPS::VDB - - This package is an (abstract) base class for all virtual databases. - Derived packages can be configured to be used by OpenSIPS as a - database. - - - The base class itself should NOT be used in this context, as it does - not provide any functionality. - -
-
OpenSIPS::Constants - - This package provides a number of constants taken from enums and - defines of OpenSIPS header files. Unfortunately, there is no mechanism - for updating the constants automatically, so check the values if you - are in doubt. - -
-
OpenSIPS::VDB::Adapter::Speeddial - - This adapter can be used with the speeddial module. - -
-
OpenSIPS::VDB::Adapter::Alias - - This package is intended for usage with the alias_db module. The - query VTab has to take two arguments and return an array of two - arguments (user name/domain). - -
query(conds,retkeys,order) - - Queries the vtab with the given arguments for request conditions, - keys to return and sort order column name. - -
-
-
OpenSIPS::VDB::Adapter::AccountingSIPtrace - - This package is an Adapter for the acc and tracer modules, - featuring only an insert operation. - -
-
OpenSIPS::VDB::Adapter::Describe - - This package is intended for debug usage. It will print information - about requested functions and operations of a client module. - - - Use this module to request schema information when creating new - adapters. - -
-
OpenSIPS::VDB::Adapter::Auth - - This adapter is intended for usage with the auth_db module. The VTab - should take a username as an argument and return a (plain text!) - password. - -
-
OpenSIPS::VDB::ReqCond - - This package represents a request condition for database access, - consisting of a column name, an operator (=, <, >, ...), a data - type and a value. - - - This package inherits from OpenSIPS::VDB::Pair and thus includes its - methods. - -
new(key,op,type,name) - - Constructs a new Column object. - -
-
op() - - Returns or sets the current operator. - -
-
-
OpenSIPS::VDB::Pair - - This package represents database key/value pairs, consisting of a - key, a value type, and the value. - - - This package inherits from OpenSIPS::VDB::Value and thus has the same - methods. - -
new(key,type,name) - - Constructs a new Column object. - -
-
key() - - Returns or sets the current key. - -
-
-
OpenSIPS::VDB::VTab - - This package handles virtual tables and is used by the OpenSIPS::VDB - class to store information about valid tables. The package is not - inteded for end user access. - -
new() - -
-
call(op,[args]) - - Invokes an operation on the table (insert, update, ...) with the - given arguments. - -
-
-
OpenSIPS::VDB::Value - - This package represents a database value. Additional to the data - itself, information about its type is stored. - -
stringification - - When accessing a OpenSIPS::VDB::Value object as a string, it simply - returns its data regardless of its type. =cut - - - use strict; - - - package OpenSIPS::VDB::Value; - - - use overload '""' => \&stringify; - - - sub stringify { shift->{data} } - - - use OpenSIPS; use OpenSIPS::Constants; - - - our @ISA = qw ( OpenSIPS::Utils::Debug ); - -
-
new(type,data) - - Constructs a new Value object. Its data type and the data are - passed as parameters. - -
-
type() - - Returns or sets the current data type. Please consider using the - constants from OpenSIPS::Constants - -
-
data() - - Returns or sets the current data. - -
-
-
OpenSIPS::VDB::Column - - This package represents database column definition, consisting of a - column name and its data type. - -
Stringification - - When accessing a OpenSIPS::VDB::Column object as a string, it simply - returns its column name regardless of its type. =cut - - - package OpenSIPS::VDB::Column; - - - use overload '""' => \&stringify; - - - sub stringify { shift->{name} } - - - use OpenSIPS; use OpenSIPS::Constants; - - - our @ISA = qw ( OpenSIPS::Utils::Debug ); - -
-
new(type,name) - - Constructs a new Column object. Its type and the name are passed as - parameters. - -
-
type( ) - - Returns or sets the current type. Please consider using the - constants from OpenSIPS::Constants - -
-
name() - - Returns or sets the current column name. - -
-
OpenSIPS::VDB::Result - - This class represents a VDB result set. It contains a column - definition, plus an array of rows. Rows themselves are simply - references to arrays of scalars. - -
-
new(coldefs,[row, row, ...]) - - The constructor creates a new Result object. Its first parameter is - a reference to an array of OpenSIPS::VDB::Column objects. Additional - parameters may be passed to provide initial rows, which are - references to arrays of scalars. - -
-
coldefs() - -
-
rows() - -
-
-
diff --git a/modules/perl/doc/perl_samples.xml b/modules/perl/doc/perl_samples.xml deleted file mode 100644 index c1d01b77b3e..00000000000 --- a/modules/perl/doc/perl_samples.xml +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - - $Revision: 5901 $ - $Date$ - - - - Perl samples - -
- sample directory - - There are a number of example scripts in the samples/. They are - documented well. Read them, it will explain a lot to you :) - - - If you want to use any of these scripts directly in your implementation, you - can use Perl's require mechanism to import them (just remember - that you need to use quotes when require'ing .pl files). - -
- Script descriptions - - The included sample scripts are described below: - -
- branches.pl - - The minimal function in branches.pl demonstrates that you can access the "append_branch" - function from within perl, just as you would have done from your normal configuration file. - You'll find documentation on the concepts of branching in the OpenSIPS documentation. - -
-
- firstline.pl - - Message's first_line structure may be evaluated. Message can be either of - SIP_REQUEST or SIP_REPLY. Depending on that, different information can be received. - This script demonstrates these functions. - -
-
- flags.pl - - The perl module provides access to OpenSIPS's flagging mechanism. The flag names available - for OpenSIPS modules are made available through the OpenSIPS::Constants package, so you can - flag messages as "green", "magenta" etc. - - - The first function, setflag, demonstrates how the "green" flag is set. In the second function, - readflag, the "green" and "magenta" flags are evaluated. - -
-
- functions.pl - - This sample script demonstrates different things related to calling functions from within perl, - and the different types of functions you can offer for OpenSIPS access. - - - exportedfuncs simply demonstrates that you can use the moduleFunction method - to call functions offered by other modules. The results are equivalent to calling these - functions from your config file. In the demonstrated case, telephone calls with a destination - number beginning with 555... are rejected with an internal server error. Other destination - addresses are passed to the alias_db module. - - - Please note that the moduleFunction method is not fully available in OpenSIPS 1.2. See the method's - documentation for details. - - - paramfunc shows that you can pass arbitrary strings to perl functions. Do with - them whatever you want :) - - - autotest demonstrates that unknown functions in OpenSIPS::Message objects are - automatically transformed into calls to module functions. - - - The diefuncs show that dying perl scripts - by "manual" dying, or because of script - errors - are handled by the OpenSIPS package. The error message is logged through OpenSIPS's logging - mechanism. Please note that this only works correctly if you do NOT overwrite the default die handler. - Oh, yes, that works for warnings, too. - -
-
- headers.pl - - Header extraction is among the most crucial functionalities while processing SIP messages. This - sample script demonstrates access to header names and values within two sample functions. - - - headernames extracts all header names and logs their names. - - - someheaders logs the contents of the two headers, To and - WWW-Contact. As you can see, headers that occur more than once are retrieved - as an array, which may be accessed by Perl's array accessing methods. - -
-
- logging.pl - - For debugging purposes, you probably want to write messages to the syslog. The logdemo - shows three ways to access the OpenSIPS log function: it is available through the OpenSIPS class as well - as through the OpenSIPS::Message class. - - - Remember that you can use exported functions from other modules. You may thus as well use the - xlog module and it's xlog function. - - - The L_INFO, L_DBG, L_ERR, L_CRIT... constants are available through the OpenSIPS::Constants package. - -
-
- messagedump.pl - - This script demonstrates how to access the whole message header of the current message. Please note that - modifications on the message made by earlier function calls in your configuration script may NOT be - reflected in this dump. - -
-
- persistence.pl - - When processing SIP messages, you may want to use persistent data across multiple calls to your - Perl functions. Your first option is to use global variables in your script. Unfortunately, - these globals are not visible from the mulitple instances of OpenSIPS. You may want to use a - mechanism such as the IPC::Shareable shared memory access package to correct this. - -
-
- phonenumbers.pl - - The OpenSIPS::Utils::PhoneNumbers package provides two methods for the transformation of local to - canonical telephone numbers, and vice versa. This script demonstrates it's use. - -
-
- pseudovars.pl - - This script demonstrates the Perl module's pseudoVar method. It may be used to - retrieve the values of current pseudo variables. - - - You might notice that there is no particular function for setting pseudo variables; you may use - the exported functions from the sqlops module, though. - -
-
-
- - -
- diff --git a/modules/permissions/README b/modules/permissions/README deleted file mode 100644 index 3eab3e79884..00000000000 --- a/modules/permissions/README +++ /dev/null @@ -1,833 +0,0 @@ -permissions Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Call Routing - 1.1.2. Registration Permissions - 1.1.3. URI Permissions - 1.1.4. Address Permissions - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_allow_file (string) - 1.3.2. default_deny_file (string) - 1.3.3. check_all_branches (integer) - 1.3.4. allow_suffix (string) - 1.3.5. deny_suffix (string) - 1.3.6. db_url (string) - 1.3.7. address_table (string) - 1.3.8. partition (string) - 1.3.9. grp_col (string) - 1.3.10. ip_col (string) - 1.3.11. mask_col (string) - 1.3.12. port_col (string) - 1.3.13. proto_col (string) - 1.3.14. pattern_col (string) - 1.3.15. info_col (string) - - 1.4. Exported Functions - - 1.4.1. check_address(group_id, ip, port, proto [, - context_info], [pattern], [partition]) - - 1.4.2. check_source_address(group_id , - [context_info], [pattern], [partition]) - - 1.4.3. get_source_group(var,[partition]) - 1.4.4. allow_routing() - 1.4.5. allow_routing(basename) - 1.4.6. allow_register(basename) - 1.4.7. allow_uri(basename, uri) - - 1.5. Exported MI Functions - - 1.5.1. address_reload - 1.5.2. address_dump - 1.5.3. subnet_dump - 1.5.4. allow_uri - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_allow_file parameter - 1.2. Set default_deny_file parameter - 1.3. Set check_all_branches parameter - 1.4. Set allow_suffix parameter - 1.5. Set deny_suffix parameter - 1.6. Set db_url parameter - 1.7. Set address_table parameter - 1.8. Set partition parameter - 1.9. Set grp_col parameter - 1.10. Set ip_col parameter - 1.11. Set mask_col parameter - 1.12. Set port_col parameter - 1.13. Set proto_col parameter - 1.14. Set pattern_col parameter - 1.15. Set info_col parameter - 1.16. check_address() usage - 1.17. check_source_address() usage - 1.18. get_source_group() usage - 1.19. allow_routing usage - 1.20. allow_routing(basename) usage - 1.21. allow_register(basename) usage - 1.22. allow_uri(basename, uri) usage - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. Call Routing - - The module can be used to determine if a call has appropriate - permission to be established. Permission rules are stored in - plaintext configuration files similar to hosts.allow and - hosts.deny files used by tcpd. - - When allow_routing function is called it tries to find a rule - that matches selected fields of the message. - - OpenSIPS is a forking proxy and therefore a single message can - be sent to different destinations simultaneously. When checking - permissions all the destinations must be checked and if one of - them fails, the forwarding will fail. - - The matching algorithm is as follows, first match wins: - * Create a set of pairs of form (From, R-URI of branch 1), - (From, R-URI of branch 2), etc. - * Routing will be allowed when all pairs match an entry in - the allow file. - * Otherwise routing will be denied when one of pairs matches - an entry in the deny file. - * Otherwise, routing will be allowed. - - A non-existing permission control file is treated as if it were - an empty file. Thus, permission control can be turned off by - providing no permission control files. - - From header field and Request-URIs are always compared with - regular expressions! For the syntax see the sample file: - config/permissions.allow. - -1.1.2. Registration Permissions - - In addition to call routing it is also possible to check - REGISTER messages and decide--based on the configuration - files--whether the message should be allowed and the - registration accepted or not. - - Main purpose of the function is to prevent registration of - "prohibited" IP addresses. One example, when a malicious user - registers a contact containing IP address of a PSTN gateway, he - might be able to bypass authorization checks performed by the - SIP proxy. That is undesirable and therefore attempts to - register IP address of a PSTN gateway should be rejected. Files - config/register.allow and config/register.deny contain an - example configuration. - - Function for registration checking is called allow_register and - the algorithm is very similar to the algorithm described in - Section 1.1.1, “Call Routing”. The only difference is in the - way how pairs are created. - - Instead of From header field the function uses To header field - because To header field in REGISTER messages contains the URI - of the person being registered. Instead of the Request-URI of - branches the function uses Contact header field. - - Thus, pairs used in matching will look like this: (To, Contact - 1), (To, Contact 2), (To, Contact 3), and so on.. - - The algorithm of matching is same as described in - Section 1.1.1, “Call Routing”. - -1.1.3. URI Permissions - - The module can be used to determine if request is allowed to - the destination specified by an URI stored in a pvar. - Permission rules are stored in plaintext configuration files - similar to hosts.allow and hosts.deny used by tcpd. - - When allow_uri function is called, it tries to find a rule that - matches selected fields of the message. The matching algorithm - is as follows, first match wins: - * Create a pair . - * Request will be allowed when the pair matches an entry in - the allow file. - * Otherwise request will be denied when the pair matches an - entry in the deny file. - * Otherwise, request will be allowed. - - A non-existing permission control file is treated as if it were - an empty file. Thus, permission control can be turned off by - providing no permission control files. - - From URI and URI stored in pvar are always compared with - regular expressions! For the syntax see the sample file: - config/permissions.allow. - -1.1.4. Address Permissions - - The module can be used to determine if an address (IP address - and port) matches any of the IP subnets stored in cached - OpenSIPS database table. Port 0 in cached database table - matches any port. Group ID, IP address, port and transport - protocol values to be matched can be either taken from the - request (check_source_address) or given as pvar arguments or - directly as strings(check_address). - - Addresses stored in cached database table can be grouped - together into one or more groups specified by a group - identifier (unsigned integer). Group identifier is given as - argument to check_address and check_source_address. - - Otherwise the request is rejected. - - The address database table is specified by module parameters. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. default_allow_file (string) - - Default allow file used by functions without parameters. If you - don't specify full pathname then the directory in which is the - main config file is located will be used. - - Default value is “permissions.allow”. - - Example 1.1. Set default_allow_file parameter -... -modparam("permissions", "default_allow_file", "/etc/permissions.allow") -... - -1.3.2. default_deny_file (string) - - Default file containing deny rules. The file is used by - functions without parameters. If you don't specify full - pathname then the directory in which the main config file is - located will be used. - - Default value is “permissions.deny”. - - Example 1.2. Set default_deny_file parameter -... -modparam("permissions", "default_deny_file", "/etc/permissions.deny") -... - -1.3.3. check_all_branches (integer) - - If set then allow_routing functions will check Request-URI of - all branches (default). If disabled then only Request-URI of - the first branch will be checked. - -Warning - - Do not disable this parameter unless you really know what you - are doing. - - Default value is 1. - - Example 1.3. Set check_all_branches parameter -... -modparam("permissions", "check_all_branches", 0) -... - -1.3.4. allow_suffix (string) - - Suffix to be appended to basename to create filename of the - allow file when version with one parameter of either - allow_routing or allow_register is used. - -Note - - Including leading dot. - - Default value is “.allow”. - - Example 1.4. Set allow_suffix parameter -... -modparam("permissions", "allow_suffix", ".allow") -... - -1.3.5. deny_suffix (string) - - Suffix to be appended to basename to create filename of the - deny file when version with one parameter of either - allow_routing or allow_register is used. - -Note - - Including leading dot. - - Default value is “.deny”. - - Example 1.5. Set deny_suffix parameter -... -modparam("permissions", "deny_suffix", ".deny") -... - -1.3.6. db_url (string) - - The URL of the database to be used for loading the data related - to IP-based checking (“address” table). - - This parameter is optional and it is needed only if you use - functions related to IP-based checking. If you do so, you need - to explicitly set this parameter (it will not inherit from - “db_default_url”) - - Since version 2.2, this URL represents the db_url for the - “default” partition. - - Default value is “NULL”. - - Example 1.6. Set db_url parameter -... -modparam("permissions", "db_url", "dbdriver://username:password@dbhost/d -bname") -... - -1.3.7. address_table (string) - - Name of database table containing matching rules used by - allow_register function. Since version 2.2, this table name - also represents the default table name for partitions without a - 'table_name' setting. - - Default value is “address”. - - Example 1.7. Set address_table parameter -... -modparam("permissions", "address_table", "pbx") -... - -1.3.8. partition (string) - - Specify a new IP-based checking partition (data source). This - parameter may be set multiple times. Each partition may have a - specific "db_url" and "table_name". If not specified, these - values will be inherited from db_url, db_default_url or - address_table, respectively. The name of the default partition - is 'default'. - - Example 1.8. Set partition parameter -... -modparam("permissions", "partition", " - inbound: - db_url = postgres://opensips:opensipsrw@127.0.0.1/opensi -ps; - table_name = address") -... - - -1.3.9. grp_col (string) - - Name of address table column containing group identifier of the - address. - - Default value is “grp”. - - Example 1.9. Set grp_col parameter -... -modparam("permissions", "grp_col", "group_id") -... - -1.3.10. ip_col (string) - - Name of address table column containing IP address part of the - address. - - Default value is “ip”. - - Example 1.10. Set ip_col parameter -... -modparam("permissions", "ip_col", "ipess") -... - -1.3.11. mask_col (string) - - Name of address table column containing network mask of the - address. Possible values are 0-128. It should be up to 32 if - the IP is v4 and up to 128 if the IP is v6. - - Default value is “mask”. - - Example 1.11. Set mask_col parameter -... -modparam("permissions", "mask_col", "subnet_length") -... - -1.3.12. port_col (string) - - Name of address table column containing port part of the - address. - - Default value is “port”. - - Example 1.12. Set port_col parameter -... -modparam("permissions", "port_col", "prt") -... - -1.3.13. proto_col (string) - - Name of address table column containing transport protocol that - is matched against transport protocol of received request. - Possible values that can be stored in proto_col are “any”, - “udp”, “tcp”, “tls”, “sctp”, and “none”. Value “any” matches - always and value “none” never. - - Default value is “proto”. - - Example 1.13. Set proto_col parameter -... -modparam("permissions", "proto_col", "transport") -... - -1.3.14. pattern_col (string) - - Name of address table column containinga a pattern (a shell - wildcard pattern, like the ones used for file name matching) - that is matched against the arguments received by check_address - or check_source_address. - - Default value is “pattern”. - - Example 1.14. Set pattern_col parameter -... -modparam("permissions", "pattern_col", "wildcard_col") -... - -1.3.15. info_col (string) - - Name of address table column containing a string that is added - as value to a pvar given as argument to check_address or - check_source_address in case the function succedes. - - Default value is “context_info”. - - Example 1.15. Set info_col parameter -... -modparam("permissions", "info_col", "info_col") -... - -1.4. Exported Functions - -1.4.1. check_address(group_id, ip, port, proto [, context_info], -[pattern], [partition]) - - Returns 1 if group id, IP address, port and protocol given as - arguments match an IP subnet found in cached address table, as - described in Section 1.1.4, “Address Permissions” . The - function takes 4 mandatory arguments and 3 optional ones. - - This function can be useful to check if a request can be - allowed without authentication. - - Meaning of the parameter is as follows: - * group_id (int) - This argument represents the group id to be matched. If the - group_id argument is "0", the query can match any group in - the cached address table. - * ip (string) - This argument represents the ip address to be matched. This - argument cannot be null/empty. - * port (int) - This argument represents the port to be matched. Cached - address table entry containing port value 0 matches any - port. Also, a 0 value for the argument will match any port - in the address table. - * proto (string) - This argument represents the protocol used for transport; - Transport protocol is either "ANY" or any valid transport - protocol value: "UDP, "TCP", "TLS", and "SCTP". - * context_info (var, optional) - This argument represents the variable in wich the - context_info field from the cached address table will be - stored in case of match. - * pattern (string, optional) - This argument is a string to be matched against the - wildcard pattern field from the address table. - * partition (string, optional) - An optional parition name for the group id. If no partition - specified, the “default” one will be used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, - EVENT_ROUTE. - - Example 1.16. check_address() usage -... - -// Checks if the tuple IP address/port (given as strings) and source pro -tocol -// (given as pvar), belongs to group 4, verifies if the string "texttest -" -// matches the wildcard pattern field in the database table and stores t -he -// context information in $avp(ctx) -if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", $avp(c -tx), "texttest")) { - t_relay(); - xlog("$avp(ctx)\n"); -} - -if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", , , "m -y_part")) { - t_relay(); - xlog("$avp(ctx)\n"); -} -... - -// Checks if the tuple IP address/port/protocol of the source message is - in group 4 -if (check_address( 4, "$si", "$sp", "$socket_in(proto)")) { - t_relay(); -} - -... - -// Checks if the tuple IP address/port/protocol stored in AVPs s:ip/s:po -rt/s:proto -// is in group 4 and stores context information in $avp(ctx) -$avp(ip) = "192.168.2.135"; -$avp(port) = 5061; -$avp(proto) = "any"; -$avp(partition)="my_part"; -if (check_address( 4, $avp(ip), $avp(port), $avp(proto), $avp(ctx), , $a -vp(partition))) { - t_relay(); - xlog("$avp(ctx)\n"); -} - -... - -// Checks if the tuple IP address/port (given as strings) and source pro -tocol -// (given as pvar) is in group 4, verifies if string the "texttest" matc -hes -// the wildcard pattern field in the database table, without storing any -// context information -if (check_address( 4,$si, 5700, $socket_in(proto), ,"texttest")) { - t_relay(); -} - -... - - -1.4.2. check_source_address(group_id , [context_info], [pattern], -[partition]) - - Equivalent to check_address(group_id, "$si", "$sp", - "$socket_in(proto)", context_info, pattern, partition). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, - EVENT_ROUTE. - - Example 1.17. check_source_address() usage -... -// Check if source address/port/proto is in group 4 and stores -// context information in $avp(ctx) -if (check_source_address( 4,$avp(ctx), , , $avp(my_partition))) { - xlog("$avp(ctx)\n"); -}else { - sl_send_reply(403, "Forbidden"); -} -... - -1.4.3. get_source_group(var,[partition]) - - Checks if an entry with the source ip/port/protocol is found in - cached address or subnet table in any group. If yes, returns - that group in the variable parameter. If not returns -1. Port - value 0 in cached address and subnet table matches any port. - Optionally, you can also specify the partition. If no partition - specified, the “default” one will be used. - - Parameters: - * var (var) - * partition (string, optional) - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE. - - Example 1.18. get_source_group() usage - -... - -if ( get_source_group( $var(group)) ) { - # do something with $var(group) - xlog("group is $var(group)\n"); -}; -... - - -1.4.4. allow_routing() - - Returns true if all pairs constructed as described in - Section 1.1.1, “Call Routing” have appropriate permissions - according to the configuration files. This function uses - default configuration files specified in default_allow_file and - default_deny_file. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.19. allow_routing usage -... -if (allow_routing()) { - t_relay(); -}; -... - -1.4.5. allow_routing(basename) - - Returns true if all pairs constructed as described in - Section 1.1.1, “Call Routing” have appropriate permissions - according to the configuration files given as parameters. - - Meaning of the parameters is as follows: - * basename (string) - Basename from which allow and deny - filenames will be created by appending contents of - allow_suffix and deny_suffix parameters. - If the parameter doesn't contain full pathname then the - function expects the file to be located in the same - directory as the main configuration file of the server. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.20. allow_routing(basename) usage -... -if (allow_routing("basename")) { - t_relay(); -}; -... - -1.4.6. allow_register(basename) - - The function returns true if all pairs constructed as described - in Section 1.1.2, “Registration Permissions” have appropriate - permissions according to the configuration files given as - parameters. - - Meaning of the parameters is as follows: - * basename (string) - Basename from which allow and deny - filenames will be created by appending contents of - allow_suffix and deny_suffix parameters. - If the parameter doesn't contain full pathname then the - function expects the file to be located in the same - directory as the main configuration file of the server. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.21. allow_register(basename) usage -... -if ($rm=="REGISTER") { - if (allow_register("register")) { - save("location"); - exit; - } else { - sl_send_reply(403, "Forbidden"); - }; -}; -... - -1.4.7. allow_uri(basename, uri) - - Returns true if the pair constructed as described in - Section 1.1.3, “URI Permissions” have appropriate permissions - according to the configuration files specified by the - parameter. - - Meaning of the parameter is as follows: - * basename (string) - Basename from which allow and deny - filenames will be created by appending contents of - allow_suffix and deny_suffix parameters. - If the parameter doesn't contain full pathname then the - function expects the file to be located in the same - directory as the main configuration file of the server. - * uri (string) - SIP URI to be checked. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.22. allow_uri(basename, uri) usage -... -if (allow_uri("basename", $rt)) { // Check Refer-To URI - t_relay(); -}; -if (allow_uri("basename", $avp(uri)) { // Check URI stored in $avp(uri) - t_relay(); -}; -... - -1.5. Exported MI Functions - -1.5.1. address_reload - - Causes permissions module to re-read the contents of the - address database table into cache memory. In cache memory the - entries are for performance reasons stored in two different - tables: address table and subnet table depending on the value - of the mask field (32 or smaller). - - Parameters: - * partition - the name of the partition to be reloaded. If - none specified all the partitions shall be reloaded. - -1.5.2. address_dump - - Causes permissions module to dump contents of the address table - from cache memory. - - Parameters: - * partition - the name of the partition to be dumped. If none - specified all the partitions shall be dumped. - -1.5.3. subnet_dump - - Causes permissions module to dump contents of cache memory - subnet table. - - Parameters: - * partition - the name of the partition to be dumped. If none - specified all the partitions shall be dumped. - -1.5.4. allow_uri - - Tests if (URI, Contact) pair is allowed according to allow/deny - files. The files must already have been loaded by OpenSIPS. - - Parameters: - * basename - Basename from which allow and deny filenames - will be created by appending contents of allow_suffix and - deny_suffix parameters. - * URI - URI to be tested - * Contact - Contact to be tested - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 124 78 1085 2148 - 2. Juha Heinanen (@juha-h) 63 21 3406 729 - 3. Jan Janak (@janakj) 57 21 2871 621 - 4. Irina-Maria Stanescu 52 9 1218 1908 - 5. Liviu Chircu (@liviuchircu) 32 21 414 371 - 6. Razvan Crainea (@razvancrainea) 27 23 178 117 - 7. Bence Szigeti 26 5 794 803 - 8. Daniel-Constantin Mierla (@miconda) 17 11 126 221 - 9. Ionut Ionita (@ionutrazvanionita) 16 4 970 175 - 10. Henning Westerholt (@henningw) 15 10 136 148 - - All remaining contributors: Vlad Patrascu (@rvlad-patrascu), - Andrei Pelinescu-Onciul, Dan Pascu (@danpascu), Miklos Tirpak, - Ancuta Onofrei, Saúl Ibarra Corretgé (@saghul), Jiri Kuthan - (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Elena-Ramona - Modroiu, Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), - Anca Vamanu, wuhanck, Konstantin Bokarius, Norman Brandinger - (@NormB), UnixDev, Andreas Granig, Baptiste Cholley, Julián - Moreno Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2025 - 2. Razvan Crainea (@razvancrainea) Jan 2011 - Jun 2025 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2005 - Jun 2025 - 4. Bence Szigeti Jan 2025 - Feb 2025 - 5. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 7. Dan Pascu (@danpascu) Nov 2006 - May 2019 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 9. wuhanck Apr 2018 - Apr 2018 - 10. Julián Moreno Patiño Feb 2016 - Feb 2016 - - All remaining contributors: Dusan Klinec (@ph4r05), Ionut - Ionita (@ionutrazvanionita), Baptiste Cholley, Saúl Ibarra - Corretgé (@saghul), Irina-Maria Stanescu, Anca Vamanu, UnixDev, - Henning Westerholt (@henningw), Juha Heinanen (@juha-h), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Ancuta Onofrei, Elena-Ramona Modroiu, Norman - Brandinger (@NormB), Andreas Granig, Andrei Pelinescu-Onciul, - Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Miklos - Tirpak. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Razvan - Crainea (@razvancrainea), Irina-Maria Stanescu, Henning - Westerholt (@henningw), Juha Heinanen (@juha-h), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2009 Irina-Maria Stanescu - - Copyright © 2006-2008 Juha Heinanen - - Copyright © 2003 Miklos Tirpak diff --git a/modules/permissions/README.md b/modules/permissions/README.md new file mode 100644 index 00000000000..89c499a4d38 --- /dev/null +++ b/modules/permissions/README.md @@ -0,0 +1,836 @@ +--- +title: "permissions Module" +--- + +## Admin Guide + + +### Overview + + +#### Call Routing + + +The module can be used to determine if a call has appropriate +permission to be established. +Permission rules are stored in plaintext configuration files similar to +`hosts.allow` and `hosts.deny` files used by tcpd. + + +When `allow_routing` function is +called it tries to find a rule that matches selected fields of the +message. + + +OpenSIPS is a forking proxy and therefore a single message can be sent +to different destinations simultaneously. When checking permissions +all the destinations must be checked and if one of them fails, the +forwarding will fail. + + +The matching algorithm is as follows, first match wins: + + +- Create a set of pairs of form (From, R-URI of branch 1), +(From, R-URI of branch 2), etc. +- Routing will be allowed when all pairs match an entry in the +allow file. +- Otherwise routing will be denied when one of pairs matches an +entry in the deny file. +- Otherwise, routing will be allowed. + + +A non-existing permission control file is treated as if it were an +empty file. Thus, permission control can be turned off by providing +no permission control files. + + +From header field and Request-URIs are always compared with regular +expressions! For the syntax see the sample file: +`config/permissions.allow`. + + +#### Registration Permissions + + +In addition to call routing it is also possible to check REGISTER +messages and decide--based on the configuration files--whether the +message should be allowed and the registration accepted or not. + + +Main purpose of the function is to prevent registration of "prohibited" +IP addresses. One example, when a malicious user registers a contact +containing IP address of a PSTN gateway, he might be able to bypass +authorization checks performed by the SIP proxy. That is undesirable +and therefore attempts to register IP address of a PSTN gateway should +be rejected. Files `config/register.allow` and `config/register.deny` contain an example +configuration. + + +Function for registration checking is called `allow_register` and the algorithm is very +similar to the algorithm described in +[sec call routing](#call_routing). The only difference is in the way +how pairs are created. + + +Instead of From header field the function uses To header field because +To header field in REGISTER messages contains the URI of the person +being registered. Instead of the Request-URI of branches the function +uses Contact header field. + + +Thus, pairs used in matching will look like this: (To, Contact 1), +(To, Contact 2), (To, Contact 3), and so on.. + + +The algorithm of matching is same as described in +[sec call routing](#call_routing). + + +#### URI Permissions + + +The module can be used to determine if request is +allowed to the destination specified by an URI stored in +a pvar. Permission rules are stored in +plaintext configuration files similar to +`hosts.allow` and +`hosts.deny` used by tcpd. + + +When `allow_uri` +function is called, it tries to find a rule that matches +selected fields of the message. +The matching algorithm is as follows, first match wins: + + +- Create a pair . +- Request will be allowed when the pair matches +an entry in the allow file. +- Otherwise request will be denied when the pair +matches an entry in the deny file. +- Otherwise, request will be allowed. + + +A non-existing permission control file is treated as if it were an +empty file. Thus, permission control can be turned off by providing +no permission control files. + + +From URI and URI stored in pvar are always compared with regular +expressions! For the syntax see the sample file: +`config/permissions.allow`. + + +#### Address Permissions + + +The module can be used to determine if an address (IP +address and port) matches any of the IP subnets +stored in cached OpenSIPS database table. +Port 0 in cached database table matches any port. Group ID, IP +address, port and transport protocol values to be matched can be either taken from +the request (`check_source_address`) or given as pvar +arguments or directly as strings(`check_address`). + + +Addresses stored in cached database table can be grouped +together into one or more groups specified by a group +identifier (unsigned integer). Group identifier is given as +argument to `check_address` and +`check_source_address`. + + +Otherwise the request is rejected. + + +The address database table is specified by module parameters. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### default_allow_file (string) + + +Default allow file used by functions without parameters. If you +don't specify full pathname then the directory in which is the main +config file is located will be used. + + +*Default value is "permissions.allow".* + + +```opensips title="Set default_allow_file parameter" +... +modparam("permissions", "default_allow_file", "/etc/permissions.allow") +... +``` + + +#### default_deny_file (string) + + +Default file containing deny rules. The file is used by functions +without parameters. If you don't specify full pathname then the +directory in which the main config file is located will be used. + + +*Default value is "permissions.deny".* + + +```opensips title="Set default_deny_file parameter" +... +modparam("permissions", "default_deny_file", "/etc/permissions.deny") +... +``` + + +#### check_all_branches (integer) + + +If set then allow_routing functions will check Request-URI of all +branches (default). If disabled then only Request-URI of the first +branch will be checked. + + +> [!WARNING] +> Do not disable this parameter unless you really know what you +are doing. + + +*Default value is 1.* + + +```opensips title="Set check_all_branches parameter" +... +modparam("permissions", "check_all_branches", 0) +... +``` + + +#### allow_suffix (string) + + +Suffix to be appended to basename to create filename of the allow +file when version with one parameter of either +`allow_routing` or +`allow_register` is used. + + +> [!NOTE] +> Including leading dot. + + +*Default value is ".allow".* + + +```opensips title="Set allow_suffix parameter" +... +modparam("permissions", "allow_suffix", ".allow") +... +``` + + +#### deny_suffix (string) + + +Suffix to be appended to basename to create filename of the deny file +when version with one parameter of either +`allow_routing` or +`allow_register` is used. + + +> [!NOTE] +> Including leading dot. + + +*Default value is ".deny".* + + +```opensips title="Set deny_suffix parameter" +... +modparam("permissions", "deny_suffix", ".deny") +... +``` + + +#### db_url (string) + + +The URL of the database to be used for loading the data related to +IP-based checking ("address" table). + + +This parameter is optional and it is needed only if you use +functions related to IP-based checking. If you do so, you need to +explicitly set this parameter (it will not inherit from +"db_default_url") + + +Since version 2.2, this URL represents the db_url for the +"default" partition. + + +*Default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("permissions", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### address_table (string) + + +Name of database table containing matching rules used by +`allow_register` function. +Since version 2.2, this table name also represents the default table +name for partitions without a 'table_name' setting. + + +*Default value is "address".* + + +```opensips title="Set address_table parameter" +... +modparam("permissions", "address_table", "pbx") +... +``` + + +#### partition (string) + + +Specify a new IP-based checking partition (data source). This +parameter may be set multiple times. Each partition may have a +specific "db_url" and "table_name". If not specified, these values +will be inherited from [db url](#param_db_url), db_default_url +or [address table](#param_address_table), respectively. The name of +the default partition is 'default'. + + +```opensips title="Set partition parameter" +... +modparam("permissions", "partition", " + inbound: + db_url = postgres://opensips:opensipsrw@127.0.0.1/opensips; + table_name = address") +... +``` + + +#### grp_col (string) + + +Name of address table column containing group +identifier of the address. + + +*Default value is "grp".* + + +```opensips title="Set grp_col parameter" +... +modparam("permissions", "grp_col", "group_id") +... +``` + + +#### ip_col (string) + + +Name of address table column containing IP address +part of the address. + + +*Default value is "ip".* + + +```opensips title="Set ip_col parameter" +... +modparam("permissions", "ip_col", "ipess") +... +``` + + +#### mask_col (string) + + +Name of address table column containing network mask of +the address. Possible values are 0-128. It should be up to 32 if +the IP is v4 and up to 128 if the IP is v6. + + +*Default value is "mask".* + + +```opensips title="Set mask_col parameter" +... +modparam("permissions", "mask_col", "subnet_length") +... +``` + + +#### port_col (string) + + +Name of address table column containing port +part of the address. + + +*Default value is "port".* + + +```opensips title="Set port_col parameter" +... +modparam("permissions", "port_col", "prt") +... +``` + + +#### proto_col (string) + + +Name of address table column containing transport +protocol that is matched against transport protocol of +received request. Possible values that can be stored in +proto_col are "any", "udp", +"tcp", "tls", +"sctp", and "none". Value +"any" matches always and value +"none" never. + + +*Default value is "proto".* + + +```opensips title="Set proto_col parameter" +... +modparam("permissions", "proto_col", "transport") +... +``` + + +#### pattern_col (string) + + +Name of address table column containinga a pattern (a shell wildcard +pattern, like the ones used for file name matching) that is matched +against the arguments received by +`check_address` +or `check_source_address`. + + +*Default value is "pattern".* + + +```opensips title="Set pattern_col parameter" +... +modparam("permissions", "pattern_col", "wildcard_col") +... +``` + + +#### info_col (string) + + +Name of address table column containing a string +that is added as value to a pvar given as argument +to `check_address` +or `check_source_address` in +case the function succedes. + + +*Default value is "context_info".* + + +```opensips title="Set info_col parameter" +... +modparam("permissions", "info_col", "info_col") +... +``` + + +### Exported Functions + + +#### check_address(group_id, ip, port, proto [, context_info], [pattern], [partition]) + + +Returns 1 if group id, IP address, port and protocol given as +arguments match an IP subnet found in cached address table, +as described in [sec address permissions](#address_permissions) . +The function takes 4 mandatory arguments and 3 optional ones. + + +This function can be useful to check if a request can be allowed +without authentication. + + +Meaning of the parameter is as follows: + + +- group_id (int) +This argument represents the group id to be matched. +If the group_id argument is "0", the query can match any group +in the cached address table. +- ip (string) +This argument represents the ip address to be matched. +This argument cannot be null/empty. +- port (int) +This argument represents the port to be matched. +Cached address table entry containing port value 0 +matches any port. +Also, a *0* value for the argument will match any port in the +address table. +- proto (string) +This argument represents the protocol used for transport; +Transport protocol is either "ANY" or any +valid transport protocol value: "UDP, "TCP", "TLS", and "SCTP". +- context_info (var, optional) +This argument represents the variable in wich the context_info field +from the cached address table will be stored in case of match. +- pattern (string, optional) +This argument is a string to be matched against the wildcard +pattern field from the address table. +- partition (string, optional) +An optional parition name for the group id. If no partition +specified, the "default" one will be used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. + + +```opensips title="check_address() usage" +... + +// Checks if the tuple IP address/port (given as strings) and source protocol +// (given as pvar), belongs to group 4, verifies if the string "texttest" +// matches the wildcard pattern field in the database table and stores the +// context information in $avp(ctx) +if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", $avp(ctx), "texttest")) { + t_relay(); + xlog("$avp(ctx)\n"); +} + +if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", , , "my_part")) { + t_relay(); + xlog("$avp(ctx)\n"); +} +... + +// Checks if the tuple IP address/port/protocol of the source message is in group 4 +if (check_address( 4, "$si", "$sp", "$socket_in(proto)")) { + t_relay(); +} + +... + +// Checks if the tuple IP address/port/protocol stored in AVPs s:ip/s:port/s:proto +// is in group 4 and stores context information in $avp(ctx) +$avp(ip) = "192.168.2.135"; +$avp(port) = 5061; +$avp(proto) = "any"; +$avp(partition)="my_part"; +if (check_address( 4, $avp(ip), $avp(port), $avp(proto), $avp(ctx), , $avp(partition))) { + t_relay(); + xlog("$avp(ctx)\n"); +} + +... + +// Checks if the tuple IP address/port (given as strings) and source protocol +// (given as pvar) is in group 4, verifies if string the "texttest" matches +// the wildcard pattern field in the database table, without storing any +// context information +if (check_address( 4,$si, 5700, $socket_in(proto), ,"texttest")) { + t_relay(); +} + +... +``` + + +#### check_source_address(group_id , [context_info], [pattern], [partition]) + + +Equivalent to check_address(group_id, "$si", "$sp", "$socket_in(proto)", context_info, pattern, partition). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. + + +```opensips title="check_source_address() usage" +... +// Check if source address/port/proto is in group 4 and stores +// context information in $avp(ctx) +if (check_source_address( 4,$avp(ctx), , , $avp(my_partition))) { + xlog("$avp(ctx)\n"); +}else { + sl_send_reply(403, "Forbidden"); +} +... +``` + + +#### get_source_group(var,[partition]) + + +Checks if an entry with the source ip/port/protocol is +found in cached address or subnet table in any group. +If yes, returns that group in the variable parameter. +If not returns -1. Port value 0 in cached address and +subnet table matches any port. Optionally, you can also +specify the partition. If no partition +specified, the "default" one will be used. + + +Parameters: + + +- *var* (var) +- *partition* (string, optional) + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +LOCAL_ROUTE, BRANCH_ROUTE. + + +```opensips title="get_source_group() usage" +... + +if ( get_source_group( $var(group)) ) { + # do something with $var(group) + xlog("group is $var(group)\n"); +}; +... +``` + + +#### allow_routing() + + +Returns true if all pairs constructed as described in [sec call routing](#call_routing) have appropriate permissions according to +the configuration files. This function uses default configuration +files specified in `default_allow_file` and +`default_deny_file`. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="allow_routing usage" +... +if (allow_routing()) { + t_relay(); +}; +... +``` + + +#### allow_routing(basename) + + +Returns true if all pairs constructed as described in [sec call routing](#call_routing) have appropriate permissions according +to the configuration files given as parameters. + + +Meaning of the parameters is as follows: + + +- *basename* (string) - Basename from which allow +and deny filenames will be created by appending contents of +`allow_suffix` and `deny_suffix` +parameters. +If the parameter doesn't contain full pathname then the function +expects the file to be located in the same directory as the main +configuration file of the server. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="allow_routing(basename) usage" +... +if (allow_routing("basename")) { + t_relay(); +}; +... +``` + + +#### allow_register(basename) + + +The function returns true if all pairs constructed as described in [sec registration permissions](#registration_permissions) have appropriate permissions +according to the configuration files given as parameters. + + +Meaning of the parameters is as follows: + + +- *basename* (string) - Basename from which allow +and deny filenames will be created by appending contents of +`allow_suffix` and `deny_suffix` +parameters. +If the parameter doesn't contain full pathname then the function +expects the file to be located in the same directory as the main +configuration file of the server. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="allow_register(basename) usage" +... +if ($rm=="REGISTER") { + if (allow_register("register")) { + save("location"); + exit; + } else { + sl_send_reply(403, "Forbidden"); + }; +}; +... +``` + + +#### allow_uri(basename, uri) + + +Returns true if the pair constructed as described in [sec uri permissions](#uri_permissions) have appropriate permissions +according to the configuration files specified by the parameter. + + +Meaning of the parameter is as follows: + + +- *basename* (string) - Basename from which allow +and deny filenames will be created by appending contents of +`allow_suffix` and `deny_suffix` +parameters. +If the parameter doesn't contain full pathname then the function +expects the file to be located in the same directory as the main +configuration file of the server. +- *uri* (string) - SIP URI to be checked. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="allow_uri(basename, uri) usage" +... +if (allow_uri("basename", $rt)) { // Check Refer-To URI + t_relay(); +}; +if (allow_uri("basename", $avp(uri)) { // Check URI stored in $avp(uri) + t_relay(); +}; +... +``` + + +### Exported MI Functions + + +#### address_reload + + +Causes permissions module to re-read the contents of +the address database table into cache +memory. In cache memory the entries are +for performance reasons stored in two +different tables: address table and +subnet table depending on the value of +the mask field (32 or smaller). + + +Parameters: + + +- *partition* - +the name of the partition to be reloaded. If none +specified all the partitions shall be reloaded. + + +#### address_dump + + +Causes permissions module to dump contents of +the address table from cache memory. + + +Parameters: + + +- *partition* - +the name of the partition to be dumped. If none +specified all the partitions shall be dumped. + + +#### subnet_dump + + +Causes permissions module to dump +contents of cache memory subnet table. + + +Parameters: + + +- *partition* - +the name of the partition to be dumped. If none +specified all the partitions shall be dumped. + + +#### allow_uri + + +Tests if (URI, Contact) pair is allowed according to +allow/deny files. The files must already have been +loaded by OpenSIPS. + + +Parameters: + + +- *basename* - +Basename from +which allow and deny filenames will be created by +appending contents of allow_suffix and deny_suffix +parameters. +- *URI* - URI to be tested +- *Contact* - Contact +to be tested + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/permissions/doc/contributors.xml b/modules/permissions/doc/contributors.xml deleted file mode 100644 index 32106953ef2..00000000000 --- a/modules/permissions/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 124 - 78 - 1085 - 2148 - - - 2. - Juha Heinanen (@juha-h) - 63 - 21 - 3406 - 729 - - - 3. - Jan Janak (@janakj) - 57 - 21 - 2871 - 621 - - - 4. - Irina-Maria Stanescu - 52 - 9 - 1218 - 1908 - - - 5. - Liviu Chircu (@liviuchircu) - 32 - 21 - 414 - 371 - - - 6. - Razvan Crainea (@razvancrainea) - 27 - 23 - 178 - 117 - - - 7. - Bence Szigeti - 26 - 5 - 794 - 803 - - - 8. - Daniel-Constantin Mierla (@miconda) - 17 - 11 - 126 - 221 - - - 9. - Ionut Ionita (@ionutrazvanionita) - 16 - 4 - 970 - 175 - - - 10. - Henning Westerholt (@henningw) - 15 - 10 - 136 - 148 - - - -
-All remaining contributors: Vlad Patrascu (@rvlad-patrascu), Andrei Pelinescu-Onciul, Dan Pascu (@danpascu), Miklos Tirpak, Ancuta Onofrei, Saúl Ibarra Corretgé (@saghul), Jiri Kuthan (@jiriatipteldotorg), Maksym Sobolyev (@sobomax), Elena-Ramona Modroiu, Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), Anca Vamanu, wuhanck, Konstantin Bokarius, Norman Brandinger (@NormB), UnixDev, Andreas Granig, Baptiste Cholley, Julián Moreno Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jan 2011 - Jun 2025 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2005 - Jun 2025 - - - 4. - Bence Szigeti - Jan 2025 - Feb 2025 - - - 5. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 7. - Dan Pascu (@danpascu) - Nov 2006 - May 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 9. - wuhanck - Apr 2018 - Apr 2018 - - - 10. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - -
-All remaining contributors: Dusan Klinec (@ph4r05), Ionut Ionita (@ionutrazvanionita), Baptiste Cholley, Saúl Ibarra Corretgé (@saghul), Irina-Maria Stanescu, Anca Vamanu, UnixDev, Henning Westerholt (@henningw), Juha Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Ancuta Onofrei, Elena-Ramona Modroiu, Norman Brandinger (@NormB), Andreas Granig, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Miklos Tirpak. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Razvan Crainea (@razvancrainea), Irina-Maria Stanescu, Henning Westerholt (@henningw), Juha Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/permissions/doc/permissions.xml b/modules/permissions/doc/permissions.xml deleted file mode 100644 index 2b33875d482..00000000000 --- a/modules/permissions/doc/permissions.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - permissions Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 Irina-Maria Stanescu - ©right; 2006-2008 Juha Heinanen - ©right; 2003 Miklos Tirpak - - diff --git a/modules/permissions/doc/permissions_admin.xml b/modules/permissions/doc/permissions_admin.xml deleted file mode 100644 index 0352ea8ccbd..00000000000 --- a/modules/permissions/doc/permissions_admin.xml +++ /dev/null @@ -1,1037 +0,0 @@ - - - - - &adminguide; - -
- Overview -
- Call Routing - - The module can be used to determine if a call has appropriate - permission to be established. - Permission rules are stored in plaintext configuration files similar to - hosts.allow and hosts.deny files used by tcpd. - - - When allow_routing function is - called it tries to find a rule that matches selected fields of the - message. - - - &osips; is a forking proxy and therefore a single message can be sent - to different destinations simultaneously. When checking permissions - all the destinations must be checked and if one of them fails, the - forwarding will fail. - - - The matching algorithm is as follows, first match wins: - - - - - Create a set of pairs of form (From, R-URI of branch 1), - (From, R-URI of branch 2), etc. - - - - - Routing will be allowed when all pairs match an entry in the - allow file. - - - - - Otherwise routing will be denied when one of pairs matches an - entry in the deny file. - - - - - Otherwise, routing will be allowed. - - - - - A non-existing permission control file is treated as if it were an - empty file. Thus, permission control can be turned off by providing - no permission control files. - - - From header field and Request-URIs are always compared with regular - expressions! For the syntax see the sample file: - config/permissions.allow. - -
-
- Registration Permissions - - In addition to call routing it is also possible to check REGISTER - messages and decide--based on the configuration files--whether the - message should be allowed and the registration accepted or not. - - - Main purpose of the function is to prevent registration of "prohibited" - IP addresses. One example, when a malicious user registers a contact - containing IP address of a PSTN gateway, he might be able to bypass - authorization checks performed by the SIP proxy. That is undesirable - and therefore attempts to register IP address of a PSTN gateway should - be rejected. Files config/register.allow and config/register.deny contain an example - configuration. - - - Function for registration checking is called allow_register and the algorithm is very - similar to the algorithm described in - . The only difference is in the way - how pairs are created. - - - Instead of From header field the function uses To header field because - To header field in REGISTER messages contains the URI of the person - being registered. Instead of the Request-URI of branches the function - uses Contact header field. - - - Thus, pairs used in matching will look like this: (To, Contact 1), - (To, Contact 2), (To, Contact 3), and so on.. - - - The algorithm of matching is same as described in - . - -
-
- URI Permissions - - The module can be used to determine if request is - allowed to the destination specified by an URI stored in - a pvar. Permission rules are stored in - plaintext configuration files similar to - hosts.allow and - hosts.deny used by tcpd. - - - When allow_uri - function is called, it tries to find a rule that matches - selected fields of the message. - The matching algorithm is as follows, first match wins: - - - - - Create a pair <From URI, URI stored in pvar>. - - - - - Request will be allowed when the pair matches - an entry in the allow file. - - - - - Otherwise request will be denied when the pair - matches an entry in the deny file. - - - - - Otherwise, request will be allowed. - - - - - A non-existing permission control file is treated as if it were an - empty file. Thus, permission control can be turned off by providing - no permission control files. - - - From URI and URI stored in pvar are always compared with regular - expressions! For the syntax see the sample file: - config/permissions.allow. - -
-
- Address Permissions - - The module can be used to determine if an address (IP - address and port) matches any of the IP subnets - stored in cached &osips; database table. - Port 0 in cached database table matches any port. Group ID, IP - address, port and transport protocol values to be matched can be either taken from - the request (check_source_address) or given as pvar - arguments or directly as strings(check_address). - - - Addresses stored in cached database table can be grouped - together into one or more groups specified by a group - identifier (unsigned integer). Group identifier is given as - argument to check_address and - check_source_address. - - - Otherwise the request is rejected. - - - The address database table is specified by module parameters. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>default_allow_file</varname> (string) - - Default allow file used by functions without parameters. If you - don't specify full pathname then the directory in which is the main - config file is located will be used. - - - - Default value is permissions.allow. - - - - Set <varname>default_allow_file</varname> parameter - -... -modparam("permissions", "default_allow_file", "/etc/permissions.allow") -... - - -
-
- <varname>default_deny_file</varname> (string) - - Default file containing deny rules. The file is used by functions - without parameters. If you don't specify full pathname then the - directory in which the main config file is located will be used. - - - - Default value is permissions.deny. - - - - Set <varname>default_deny_file</varname> parameter - -... -modparam("permissions", "default_deny_file", "/etc/permissions.deny") -... - - -
-
- <varname>check_all_branches</varname> (integer) - - If set then allow_routing functions will check Request-URI of all - branches (default). If disabled then only Request-URI of the first - branch will be checked. - - - - Do not disable this parameter unless you really know what you - are doing. - - - - - Default value is 1. - - - - Set <varname>check_all_branches</varname> parameter - -... -modparam("permissions", "check_all_branches", 0) -... - - -
-
- <varname>allow_suffix</varname> (string) - - Suffix to be appended to basename to create filename of the allow - file when version with one parameter of either - allow_routing or - allow_register is used. - - - - Including leading dot. - - - - - Default value is .allow. - - - - Set <varname>allow_suffix</varname> parameter - -... -modparam("permissions", "allow_suffix", ".allow") -... - - -
-
- <varname>deny_suffix</varname> (string) - - Suffix to be appended to basename to create filename of the deny file - when version with one parameter of either - allow_routing or - allow_register is used. - - - - Including leading dot. - - - - - Default value is .deny. - - - - Set <varname>deny_suffix</varname> parameter - -... -modparam("permissions", "deny_suffix", ".deny") -... - - -
-
- <varname>db_url</varname> (string) - - The URL of the database to be used for loading the data related to - IP-based checking (address table). - - - This parameter is optional and it is needed only if you use - functions related to IP-based checking. If you do so, you need to - explicitly set this parameter (it will not inherit from - db_default_url) - - - Since version 2.2, this URL represents the db_url for the - default partition. - - - - Default value is NULL. - - - - Set <varname>db_url</varname> parameter - -... -modparam("permissions", "db_url", "&exampledb;") -... - - -
-
- <varname>address_table</varname> (string) - - Name of database table containing matching rules used by - allow_register function. - Since version 2.2, this table name also represents the default table - name for partitions without a 'table_name' setting. - - - - Default value is address. - - - - Set <varname>address_table</varname> parameter - -... -modparam("permissions", "address_table", "pbx") -... - - -
-
- <varname>partition</varname> (string) - - Specify a new IP-based checking partition (data source). This - parameter may be set multiple times. Each partition may have a - specific "db_url" and "table_name". If not specified, these values - will be inherited from , db_default_url - or , respectively. The name of - the default partition is 'default'. - - - - - Set <varname>partition</varname> parameter - -... -modparam("permissions", "partition", " - inbound: - db_url = postgres://opensips:opensipsrw@127.0.0.1/opensips; - table_name = address") -... - - - -
-
- <varname>grp_col</varname> (string) - - Name of address table column containing group - identifier of the address. - - - - Default value is grp. - - - - Set <varname>grp_col</varname> parameter - -... -modparam("permissions", "grp_col", "group_id") -... - - -
-
- <varname>ip_col</varname> (string) - - Name of address table column containing IP address - part of the address. - - - - Default value is ip. - - - - Set <varname>ip_col</varname> parameter - -... -modparam("permissions", "ip_col", "ipess") -... - - -
-
- <varname>mask_col</varname> (string) - - Name of address table column containing network mask of - the address. Possible values are 0-128. It should be up to 32 if - the IP is v4 and up to 128 if the IP is v6. - - - - Default value is mask. - - - - Set <varname>mask_col</varname> parameter - -... -modparam("permissions", "mask_col", "subnet_length") -... - - -
-
- <varname>port_col</varname> (string) - - Name of address table column containing port - part of the address. - - - - Default value is port. - - - - Set <varname>port_col</varname> parameter - -... -modparam("permissions", "port_col", "prt") -... - - -
- - -
- <varname>proto_col</varname> (string) - - Name of address table column containing transport - protocol that is matched against transport protocol of - received request. Possible values that can be stored in - proto_col are any, udp, - tcp, tls, - sctp, and none. Value - any matches always and value - none never. - - - - Default value is proto. - - - - Set <varname>proto_col</varname> parameter - -... -modparam("permissions", "proto_col", "transport") -... - - -
-
- <varname>pattern_col</varname> (string) - - Name of address table column containinga a pattern (a shell wildcard - pattern, like the ones used for file name matching) that is matched - against the arguments received by - check_address - or check_source_address. - - - - Default value is pattern. - - - - Set <varname>pattern_col</varname> parameter - -... -modparam("permissions", "pattern_col", "wildcard_col") -... - - -
-
- <varname>info_col</varname> (string) - - Name of address table column containing a string - that is added as value to a pvar given as argument - to check_address - or check_source_address in - case the function succedes. - - - - Default value is context_info. - - - - Set <varname>info_col</varname> parameter - -... -modparam("permissions", "info_col", "info_col") -... - - -
-
- -
- Exported Functions - -
- - <function moreinfo="none">check_address(group_id, ip, - port, proto [, context_info], [pattern], [partition])</function> - - - Returns 1 if group id, IP address, port and protocol given as - arguments match an IP subnet found in cached address table, - as described in . - The function takes 4 mandatory arguments and 3 optional ones. - - - This function can be useful to check if a request can be allowed - without authentication. - - - Meaning of the parameter is as follows: - - - - group_id (int) - - This argument represents the group id to be matched. - If the group_id argument is "0", the query can match any group - in the cached address table. - - - - ip (string) - - This argument represents the ip address to be matched. - This argument cannot be null/empty. - - - - port (int) - - This argument represents the port to be matched. - Cached address table entry containing port value 0 - matches any port. - Also, a 0 value for the argument will match any port in the - address table. - - - - proto (string) - - This argument represents the protocol used for transport; - Transport protocol is either "ANY" or any - valid transport protocol value: "UDP, "TCP", "TLS", and "SCTP". - - - - context_info (var, optional) - - This argument represents the variable in wich the context_info field - from the cached address table will be stored in case of match. - - - - pattern (string, optional) - - This argument is a string to be matched against the wildcard - pattern field from the address table. - - - - partition (string, optional) - - An optional parition name for the group id. If no partition - specified, the default one will be used. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. - - - <function>check_address() - </function> usage - -... - -// Checks if the tuple IP address/port (given as strings) and source protocol -// (given as pvar), belongs to group 4, verifies if the string "texttest" -// matches the wildcard pattern field in the database table and stores the -// context information in $avp(ctx) -if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", $avp(ctx), "texttest")) { - t_relay(); - xlog("$avp(ctx)\n"); -} - -if (check_address( 4, "192.168.2.135", 5700, "$socket_in(proto)", , , "my_part")) { - t_relay(); - xlog("$avp(ctx)\n"); -} -... - -// Checks if the tuple IP address/port/protocol of the source message is in group 4 -if (check_address( 4, "$si", "$sp", "$socket_in(proto)")) { - t_relay(); -} - -... - -// Checks if the tuple IP address/port/protocol stored in AVPs s:ip/s:port/s:proto -// is in group 4 and stores context information in $avp(ctx) -$avp(ip) = "192.168.2.135"; -$avp(port) = 5061; -$avp(proto) = "any"; -$avp(partition)="my_part"; -if (check_address( 4, $avp(ip), $avp(port), $avp(proto), $avp(ctx), , $avp(partition))) { - t_relay(); - xlog("$avp(ctx)\n"); -} - -... - -// Checks if the tuple IP address/port (given as strings) and source protocol -// (given as pvar) is in group 4, verifies if string the "texttest" matches -// the wildcard pattern field in the database table, without storing any -// context information -if (check_address( 4,$si, 5700, $socket_in(proto), ,"texttest")) { - t_relay(); -} - -... - - - -
- -
- - <function moreinfo="none">check_source_address(group_id , [context_info], [pattern], [partition])</function> - - - Equivalent to check_address(group_id, "$si", "$sp", "$socket_in(proto)", context_info, pattern, partition). - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE, STARTUP_ROUTE, TIMER_ROUTE, EVENT_ROUTE. - - - <function>check_source_address()</function> usage - -... -// Check if source address/port/proto is in group 4 and stores -// context information in $avp(ctx) -if (check_source_address( 4,$avp(ctx), , , $avp(my_partition))) { - xlog("$avp(ctx)\n"); -}else { - sl_send_reply(403, "Forbidden"); -} -... - - -
- -
- - <function moreinfo="none">get_source_group(var,[partition])</function> - - - Checks if an entry with the source ip/port/protocol is - found in cached address or subnet table in any group. - If yes, returns that group in the variable parameter. - If not returns -1. Port value 0 in cached address and - subnet table matches any port. Optionally, you can also - specify the partition. If no partition - specified, the default one will be used. - - Parameters: - - - var (var) - - - partition (string, optional) - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - LOCAL_ROUTE, BRANCH_ROUTE. - - - <function>get_source_group()</function> usage - - -... - -if ( get_source_group( $var(group)) ) { - # do something with $var(group) - xlog("group is $var(group)\n"); -}; -... - - - -
- -
- - <function moreinfo="none">allow_routing()</function> - - - Returns true if all pairs constructed as described in have appropriate permissions according to - the configuration files. This function uses default configuration - files specified in default_allow_file and - default_deny_file. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>allow_routing</function> usage - -... -if (allow_routing()) { - t_relay(); -}; -... - - -
-
- - <function moreinfo="none">allow_routing(basename)</function> - - - Returns true if all pairs constructed as described in have appropriate permissions according - to the configuration files given as parameters. - - Meaning of the parameters is as follows: - - - basename (string) - Basename from which allow - and deny filenames will be created by appending contents of - allow_suffix and deny_suffix - parameters. - - - If the parameter doesn't contain full pathname then the function - expects the file to be located in the same directory as the main - configuration file of the server. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>allow_routing(basename)</function> usage - -... -if (allow_routing("basename")) { - t_relay(); -}; -... - - -
-
- - <function moreinfo="none">allow_register(basename)</function> - - - The function returns true if all pairs constructed as described in have appropriate permissions - according to the configuration files given as parameters. - - Meaning of the parameters is as follows: - - - basename (string) - Basename from which allow - and deny filenames will be created by appending contents of - allow_suffix and deny_suffix - parameters. - - - If the parameter doesn't contain full pathname then the function - expects the file to be located in the same directory as the main - configuration file of the server. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>allow_register(basename)</function> usage - -... -if ($rm=="REGISTER") { - if (allow_register("register")) { - save("location"); - exit; - } else { - sl_send_reply(403, "Forbidden"); - }; -}; -... - - -
-
- - <function moreinfo="none">allow_uri(basename, uri)</function> - - - Returns true if the pair constructed as described in have appropriate permissions - according to the configuration files specified by the parameter. - - Meaning of the parameter is as follows: - - - basename (string) - Basename from which allow - and deny filenames will be created by appending contents of - allow_suffix and deny_suffix - parameters. - - - If the parameter doesn't contain full pathname then the function - expects the file to be located in the same directory as the main - configuration file of the server. - - - - uri (string) - SIP URI to be checked. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>allow_uri(basename, uri)</function> usage - -... -if (allow_uri("basename", $rt)) { // Check Refer-To URI - t_relay(); -}; -if (allow_uri("basename", $avp(uri)) { // Check URI stored in $avp(uri) - t_relay(); -}; -... - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">address_reload</function> - - - Causes permissions module to re-read the contents of - the address database table into cache - memory. In cache memory the entries are - for performance reasons stored in two - different tables: address table and - subnet table depending on the value of - the mask field (32 or smaller). - - Parameters: - - - partition - - the name of the partition to be reloaded. If none - specified all the partitions shall be reloaded. - - - - -
- -
- - <function moreinfo="none">address_dump</function> - - - Causes permissions module to dump contents of - the address table from cache memory. - - Parameters: - - - partition - - the name of the partition to be dumped. If none - specified all the partitions shall be dumped. - - - - - -
- -
- - <function moreinfo="none">subnet_dump</function> - - - Causes permissions module to dump - contents of cache memory subnet table. - - Parameters: - - - partition - - the name of the partition to be dumped. If none - specified all the partitions shall be dumped. - - - - - -
- -
- - <function moreinfo="none">allow_uri</function> - - - Tests if (URI, Contact) pair is allowed according to - allow/deny files. The files must already have been - loaded by OpenSIPS. - - Parameters: - - - basename - - Basename from - which allow and deny filenames will be created by - appending contents of allow_suffix and deny_suffix - parameters. - - - URI - URI to be tested - - - Contact - Contact - to be tested - - - -
-
- -
- diff --git a/modules/pi_http/README b/modules/pi_http/README deleted file mode 100644 index c1eb1a19924..00000000000 --- a/modules/pi_http/README +++ /dev/null @@ -1,333 +0,0 @@ -pi_http Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Usage - 1.3. Framework - - 1.3.1. Database connection definition block - 1.3.2. Table definition block - 1.3.3. Command definition block - - 1.4. To-do - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - - 1.6. External Libraries or Applications - 1.7. Exported Parameters - - 1.7.1. pi_http_root(string) - 1.7.2. framework(string) - 1.7.3. pi_http_method(integrer) - - 1.8. Exported MI Functions - - 1.8.1. pi_reload_tbls_and_cmds - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set pi_http_root parameter - 1.2. Set framework parameter - 1.3. Set pi_http_method parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides an HTTP provisioning interface for - OpenSIPS. It is using the OpenSIPS's internal database API to - provide a simple way of manipulating records inside OpenSIPS's - tables. - - The module offers: - * ability to connect to multiple/different databases through - OpenSIPS's db API; (all OpenSIPS's databases are - supported); - * ability to perform data input validation through OpenSIPS - API; - * ability to reconfigure the interface layout on the fly by - reloading the config from the xml framework via mi command - interface. - - Note: when provisioning tables using db_text, any change made - to a db_text table will not be reflected on the actual text - file. In order to force a write out to the disk of the cached - tables, the db_text mi command dbt_dump must be used. - -1.2. Usage - - The layout of the provisioning interface is controlled via an - external xml file (see the framework parameter). An example of - a framework xml file is provided inside the examples directory - of the pi_http module. A simple framework file can be generated - by the opensips-cli command: -opensips-cli pframework create - - The generated framework will be saved inside OpenSIPS's config - directory as pi_framework_sample. The list of configurable - tables will be based on the "database_modules" setting of - opensips-cli.cfg if present, otherwise a default set of - configurable tables will be used. - -1.3. Framework - - The xml framework file is organized in three distinctive - blocks: - * database connection definition block - * table definition block - * command definition block - -1.3.1. Database connection definition block - - Each connection to a particular database must be defined here - with a unique database connection id. The connection parameters - are defined following the db_url param pattern for all OpenSIPS - modules that are using a database. - - Supported databases: - * berkeley - * flatstore - * http - * mysql - * oracle - * postgres - * text - * unixodbc - * virtual - -1.3.2. Table definition block - - Each table managed through the OpenSIPS provisioning interface - must be defined here with a unique table id. For each table, - the database connection id must be specified. Each table must - list all columns that will be managed by the OpenSIPS - provisioning interface. Each column must have a unique field - name and a type. Each column may have a validation tag for - validating input data. - - Supported column types: - * DB_INT - * DB_BIGINT - * DB_DOUBLE - * DB_STRING - * DB_STR - * DB_DATETIME - + Note: input field must be provided in 'YEAR-MM-DD - HH:MM:SS' format. - * DB_BLOB - * DB_BITMAP - - Supported validation methods: - * IPV4 - represents an IPv4 address - * URI - represents a SIP URI - * URI_IPV4HOST - represents a SIP URI with an IPV4 as a host - * P_HOST_PORT - represents [proto:]host[:port] - * P_IPV4_PORT - represents [proto:]IPv4[:port] - -1.3.3. Command definition block - - Multiple provisioning commands can be grouped together. Each - group can have multiple commands. Each command definition in a - group must have the table id of the table that is operating on - along with the command type to be performed. - - The command type can have up to three type of column - parameters: - * clause columns - * query columns - * order by columns - - Each column parameter must define the name(s) of the column(s) - (must match a field name in the description table identified by - the table id). A column can accept a list of imposed values. - Each imposed value will have an id that will be displayed on - the web interface and the actual value that will be used for db - operations. Clause columns must define operators. Here's the - list of supported operators: '<', '>', '=', '<=', '>=', '!='. - - Supported database command types: - * DB_QUERY - performs an SQL query and supports three type of - columns: - + clause: 0 or more columns - + query: 1 column - + order: 0 or 1 column - * DB_INSERT - performs an SQL insert and supports one type of - column: - + query: 1 or more columns - * DB_DELETE - performs an SQL delete and supports one type of - column: - + clause: 1 or more columns - * DB_UPDATE - performs an SQL update and supports two type of - columns: - + clause: 0 or more columns - + query: 1 or more columns - * DB_REPLACE - performs an SQL replace and supports one type - of column: - + query: 1 or more columns - - Please note that some databases have a restricted set of - database command types. - -1.4. To-do - - Features to be added in the future: - * full subscriber provisionning with automatic ha1/ha1b - fields. - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * httpd module. - -1.6. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml2 - -1.7. Exported Parameters - -1.7.1. pi_http_root(string) - - Specifies the root path for pi HTTP requests. The link to the - OpenSIPS provisioning web interface must be constructed using - the following patern: - http://[opensips_IP]:[opensips_mi_port]/[pi_http_root] - - The default value is "pi". - - Example 1.1. Set pi_http_root parameter -... -modparam("pi_http", "pi_http_root", "opensips_pi") -... - -1.7.2. framework(string) - - Specifies the full path for xml framework descriptor. - - There's no default value. This parameter is mandatory. - - Example 1.2. Set framework parameter -... -modparam("pi_http", "framework", "/usr/local/etc/opensips/pi_framework.x -ml") -... - -1.7.3. pi_http_method(integrer) - - Specifies the HTTP request method to be used: - * 0 - use GET HTTP request - * 1 - use POST HTTP request - - The default value is 0. - - Example 1.3. Set pi_http_method parameter -... -modparam("pi_http", "pi_http_method", 1) -... - -1.8. Exported MI Functions - -1.8.1. pi_reload_tbls_and_cmds - - Reloads the layout of the provisioning interface from the - framework file. - - Name: pi_reload_tbls_and_cmds - - Parameters: none - - MI FIFO Command Format: -opensips-cli -x mi pi_reload_tbls_and_cmds - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 72 31 4389 206 - 2. Liviu Chircu (@liviuchircu) 15 13 40 57 - 3. Razvan Crainea (@razvancrainea) 13 11 30 31 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 7 5 5 5 - 5. Vlad Patrascu (@rvlad-patrascu) 6 4 21 19 - 6. Maksym Sobolyev (@sobomax) 5 3 8 5 - 7. Ionut Ionita (@ionutrazvanionita) 4 2 53 28 - 8. Vlad Paiu (@vladpaiu) 4 2 5 2 - 9. Zero King (@l2dy) 3 1 2 2 - 10. Ken Rice 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - Mar 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2013 - Mar 2020 - 5. Zero King (@l2dy) Mar 2020 - Mar 2020 - 6. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jan 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ionut Ionita (@ionutrazvanionita) Nov 2015 - Jan 2017 - 10. Ovidiu Sas (@ovidiusas) Oct 2012 - Apr 2016 - - All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu - (@rvlad-patrascu), Ovidiu Sas (@ovidiusas), Bogdan-Andrei Iancu - (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2012-2013 VoIP Embedded, Inc. diff --git a/modules/pi_http/README.md b/modules/pi_http/README.md new file mode 100644 index 00000000000..4f2e39195b9 --- /dev/null +++ b/modules/pi_http/README.md @@ -0,0 +1,300 @@ +--- +title: "pi_http Module" +description: "This module provides an HTTP provisioning interface for OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module provides an HTTP provisioning interface +for OpenSIPS. It is using the OpenSIPS's internal +database API to provide a simple way of manipulating +records inside OpenSIPS's tables. +The module offers: +- ability to connect to multiple/different databases through OpenSIPS's db API; +(all OpenSIPS's databases are supported); +- ability to perform data input validation through OpenSIPS API; +- ability to reconfigure the interface layout on the fly by +reloading the config from the xml framework via mi command interface. + +> [!NOTE] +> When provisioning tables using *db_text*, +> any change made to a *db_text* table will not +> be reflected on the actual text file. In order to force a write +> out to the disk of the cached tables, the db_text mi command +> *dbt_dump* must be used. + + +### Usage + + +The layout of the provisioning interface is controlled via an external +xml file (see the framework parameter). +An example of a framework xml file is provided inside the examples +directory of the pi_http module. +A simple framework file can be generated by the opensips-cli command: + + +```c +opensips-cli pframework create +``` + + +The generated framework will be saved inside OpenSIPS's config +directory as pi_framework_sample. The list of configurable tables will +be based on the "database_modules" setting of opensips-cli.cfg if present, +otherwise a default set of configurable tables will be used. + + +### Framework + + +The xml framework file is organized in three distinctive blocks: + + +- database connection definition block +- table definition block +- command definition block + + +#### Database connection definition block + + +Each connection to a particular database must be defined here +with a unique database connection id. +The connection parameters are defined following the db_url param pattern +for all OpenSIPS modules that are using a database. + + +Supported databases: +- berkeley +- flatstore +- http +- mysql +- oracle +- postgres +- text +- unixodbc +- virtual + + +#### Table definition block + + +Each table managed through the OpenSIPS provisioning interface +must be defined here with a unique table id. +For each table, the database connection id must be specified. +Each table must list all columns that will be managed by the +OpenSIPS provisioning interface. +Each column must have a unique field name and a type. +Each column may have a validation tag for validating input data. + + +Supported column types: + + +- DB_INT +- DB_BIGINT +- DB_DOUBLE +- DB_STRING +- DB_STR +- DB_DATETIME + > [!NOTE] + > Input field must be provided in + > 'YEAR-MM-DD HH:MM:SS' format. + +- DB_BLOB +- DB_BITMAP + + +Supported validation methods: + + +- IPV4 - represents an IPv4 address +- URI - represents a SIP URI +- URI_IPV4HOST - represents a SIP URI with an IPV4 as a host +- P_HOST_PORT - represents [proto:]host[:port] +- P_IPV4_PORT - represents [proto:]IPv4[:port] + + +#### Command definition block + + +Multiple provisioning commands can be grouped together. +Each group can have multiple commands. +Each command definition in a group must have the table id +of the table that is operating on along with the command +type to be performed. + + +The command type can have up to three type of column parameters: + + +- clause columns +- query columns +- order by columns + + +Each column parameter must define the name(s) of the column(s) +(must match a field name in the description table identified +by the table id). +A column can accept a list of imposed values. +Each imposed value will have an id that will be displayed +on the web interface and the actual value that will be +used for db operations. +Clause columns must define operators. +Here's the list of supported operators: +'<', '>', '=', '<=', '>=', '!='. + + +Supported database command types: + + +- DB_QUERY - performs an SQL query +and supports three type of columns: + + - clause: 0 or more columns + - query: 1 column + - order: 0 or 1 column +- DB_INSERT - performs an SQL insert +and supports one type of column: + + - query: 1 or more columns +- DB_DELETE - performs an SQL delete +and supports one type of column: + + - clause: 1 or more columns +- DB_UPDATE - performs an SQL update +and supports two type of columns: + + - clause: 0 or more columns + - query: 1 or more columns +- DB_REPLACE - performs an SQL replace +and supports one type of column: + + - query: 1 or more columns + + +Please note that some databases have a restricted +set of database command types. + + +### To-do + + +Features to be added in the future: + + +- full subscriber provisionning with automatic ha1/ha1b fields. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *httpd* module. + + +### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libxml2* + + +### Exported Parameters + + +#### pi_http_root(string) + + +Specifies the root path for pi HTTP requests. +The link to the OpenSIPS provisioning web interface must be constructed +using the following patern: +http://[opensips_IP]:[opensips_mi_port]/[pi_http_root] + + +*The default value is "pi".* + + +```opensips title="Set pi_http_root parameter" +... +modparam("pi_http", "pi_http_root", "opensips_pi") +... +``` + + +#### framework(string) + + +Specifies the full path for xml framework descriptor. + + +*There's no default value. This parameter is mandatory.* + + +```opensips title="Set framework parameter" +... +modparam("pi_http", "framework", "/usr/local/etc/opensips/pi_framework.xml") +... +``` + + +#### pi_http_method(integrer) + + +Specifies the HTTP request method to be used: + + +- 0 - use GET HTTP request +- 1 - use POST HTTP request + + +*The default value is 0.* + + +```opensips title="Set pi_http_method parameter" +... +modparam("pi_http", "pi_http_method", 1) +... +``` + + +### Exported MI Functions + + +#### pi_reload_tbls_and_cmds + + +Reloads the layout of the provisioning interface from the framework file. + + +Name: *pi_reload_tbls_and_cmds* + + +Parameters: none + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi pi_reload_tbls_and_cmds + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pi_http/doc/contributors.xml b/modules/pi_http/doc/contributors.xml deleted file mode 100644 index f543ab0f3a8..00000000000 --- a/modules/pi_http/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 72 - 31 - 4389 - 206 - - - 2. - Liviu Chircu (@liviuchircu) - 15 - 13 - 40 - 57 - - - 3. - Razvan Crainea (@razvancrainea) - 13 - 11 - 30 - 31 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 5 - 5 - 5 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 21 - 19 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 8 - 5 - - - 7. - Ionut Ionita (@ionutrazvanionita) - 4 - 2 - 53 - 28 - - - 8. - Vlad Paiu (@vladpaiu) - 4 - 2 - 5 - 2 - - - 9. - Zero King (@l2dy) - 3 - 1 - 2 - 2 - - - 10. - Ken Rice - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - Mar 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2013 - Mar 2020 - - - 5. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 6. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jan 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Nov 2015 - Jan 2017 - - - 10. - Ovidiu Sas (@ovidiusas) - Oct 2012 - Apr 2016 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Ovidiu Sas (@ovidiusas), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/pi_http/doc/pi_http.xml b/modules/pi_http/doc/pi_http.xml deleted file mode 100644 index 880ee7f10c5..00000000000 --- a/modules/pi_http/doc/pi_http.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - pi_http Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2012-2013 VoIP Embedded, Inc. - - - - diff --git a/modules/pi_http/doc/pi_http_admin.xml b/modules/pi_http/doc/pi_http_admin.xml deleted file mode 100644 index 78ad23fe097..00000000000 --- a/modules/pi_http/doc/pi_http_admin.xml +++ /dev/null @@ -1,342 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides an HTTP provisioning interface - for &osips;. It is using the &osips;'s internal - database API to provide a simple way of manipulating - records inside &osips;'s tables. - - The module offers: - - - ability to connect to multiple/different databases through &osips;'s db API; - (all &osips;'s databases are supported); - - - ability to perform data input validation through &osips; API; - - - ability to reconfigure the interface layout on the fly by - reloading the config from the xml framework via mi command interface. - - - - - Note: when provisioning tables using db_text, - any change made to a db_text table will not - be reflected on the actual text file. In order to force a write - out to the disk of the cached tables, the db_text mi command - dbt_dump must be used. - - -
- -
- Usage - - The layout of the provisioning interface is controlled via an external - xml file (see the framework parameter). - An example of a framework xml file is provided inside the examples - directory of the pi_http module. - A simple framework file can be generated by the opensips-cli command: - -opensips-cli pframework create - - The generated framework will be saved inside &osips;'s config - directory as pi_framework_sample. The list of configurable tables will - be based on the "database_modules" setting of opensips-cli.cfg if present, - otherwise a default set of configurable tables will be used. - -
-
- Framework - - The xml framework file is organized in three distinctive blocks: - - - database connection definition block - - - table definition block - - - command definition block - - - -
- Database connection definition block - - Each connection to a particular database must be defined here - with a unique database connection id. - The connection parameters are defined following the db_url param pattern - for all &osips; modules that are using a database. - - - Supported databases: - - berkeley - flatstore - http - mysql - oracle - postgres - text - unixodbc - virtual - - -
-
- Table definition block - - Each table managed through the &osips; provisioning interface - must be defined here with a unique table id. - For each table, the database connection id must be specified. - Each table must list all columns that will be managed by the - &osips; provisioning interface. - Each column must have a unique field name and a type. - Each column may have a validation tag for validating input data. - - - Supported column types: - - DB_INT - DB_BIGINT - DB_DOUBLE - DB_STRING - DB_STR - DB_DATETIME - - Note: input field must be provided in - 'YEAR-MM-DD HH:MM:SS' format. - - - - DB_BLOB - DB_BITMAP - - - - Supported validation methods: - - - IPV4 - represents an IPv4 address - - - URI - represents a SIP URI - - - URI_IPV4HOST - represents a SIP URI with an IPV4 as a host - - - P_HOST_PORT - represents [proto:]host[:port] - - - P_IPV4_PORT - represents [proto:]IPv4[:port] - - - -
-
- Command definition block - - Multiple provisioning commands can be grouped together. - Each group can have multiple commands. - Each command definition in a group must have the table id - of the table that is operating on along with the command - type to be performed. - - - The command type can have up to three type of column parameters: - - clause columns - query columns - order by columns - - Each column parameter must define the name(s) of the column(s) - (must match a field name in the description table identified - by the table id). - A column can accept a list of imposed values. - Each imposed value will have an id that will be displayed - on the web interface and the actual value that will be - used for db operations. - Clause columns must define operators. - Here's the list of supported operators: - '<', '>', '=', '<=', '>=', '!='. - - - Supported database command types: - - DB_QUERY - performs an SQL query - and supports three type of columns: - - clause: 0 or more columns - query: 1 column - order: 0 or 1 column - - - DB_INSERT - performs an SQL insert - and supports one type of column: - - query: 1 or more columns - - - DB_DELETE - performs an SQL delete - and supports one type of column: - - clause: 1 or more columns - - - DB_UPDATE - performs an SQL update - and supports two type of columns: - - clause: 0 or more columns - query: 1 or more columns - - - DB_REPLACE - performs an SQL replace - and supports one type of column: - - query: 1 or more columns - - - - Please note that some databases have a restricted - set of database command types. - -
-
- -
- To-do - - Features to be added in the future: - - - - full subscriber provisionning with automatic ha1/ha1b fields. - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - httpd module. - - - - -
-
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - libxml2 - - - -
- -
- Exported Parameters -
- <varname>pi_http_root</varname>(string) - - Specifies the root path for pi HTTP requests. - The link to the &osips; provisioning web interface must be constructed - using the following patern: - http://[opensips_IP]:[opensips_mi_port]/[pi_http_root] - - - The default value is "pi". - - - Set <varname>pi_http_root</varname> parameter - -... -modparam("pi_http", "pi_http_root", "opensips_pi") -... - - -
-
- <varname>framework</varname>(string) - - Specifies the full path for xml framework descriptor. - - - There's no default value. This parameter is mandatory. - - - Set <varname>framework</varname> parameter - -... -modparam("pi_http", "framework", "/usr/local/etc/opensips/pi_framework.xml") -... - - -
-
- <varname>pi_http_method</varname>(integrer) - - Specifies the HTTP request method to be used: - - 0 - use GET HTTP request - 1 - use POST HTTP request - - - - The default value is 0. - - - Set <varname>pi_http_method</varname> parameter - -... -modparam("pi_http", "pi_http_method", 1) -... - - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">pi_reload_tbls_and_cmds</function> - - Reloads the layout of the provisioning interface from the framework file. - - - Name: pi_reload_tbls_and_cmds - - Parameters: none - - MI FIFO Command Format: - - -opensips-cli -x mi pi_reload_tbls_and_cmds - -
-
- -
- diff --git a/modules/pi_http/http_fnc.c b/modules/pi_http/http_fnc.c index f408d079fe7..257939b029f 100644 --- a/modules/pi_http/http_fnc.c +++ b/modules/pi_http/http_fnc.c @@ -2510,7 +2510,7 @@ int getVal(db_val_t *val, db_type_t val_type, db_key_t key, ph_db_table_t *table struct sip_uri uri; char c; - for(i=0;i<=table->cols_size;i++){ + for(i=0;icols_size;i++){ if(table->cols[i].type==val_type && table->cols[i].field.len==key->len && strncmp(table->cols[i].field.s,key->s,key->len)==0){ @@ -3230,4 +3230,3 @@ int ph_run_pi_cmd(int mod, int cmd, if(q_vals) pkg_free(q_vals); return 0; } - diff --git a/modules/pike/README b/modules/pike/README deleted file mode 100644 index 405f26579f5..00000000000 --- a/modules/pike/README +++ /dev/null @@ -1,408 +0,0 @@ -pike Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How to use - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. sampling_time_unit (integer) - 1.4.2. reqs_density_per_unit (integer) - 1.4.3. remove_latency (integer) - 1.4.4. check_route (integer) - 1.4.5. pike_log_level (integer) - - 1.5. Exported Functions - - 1.5.1. pike_check_req() - - 1.6. Exported MI Functions - - 1.6.1. pike_list - 1.6.2. pike_rm - - 1.7. Exported Events - - 1.7.1. E_PIKE_BLOCKED - - 1.8. Provided Status/Report Identifiers - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set sampling_time_unit parameter - 1.2. Set reqs_density_per_unit parameter - 1.3. Set remove_latency parameter - 1.4. Set check_route parameter - 1.5. Set pike_log_level parameter - 1.6. pike_check_req usage - 2.1. Tree of IP addresses - -Chapter 1. Admin Guide - -1.1. Overview - - The module provides a simple mechanism for DOS protection - DOS - based on floods at network level. The module keeps trace of all - (or selected ones) IPs of incoming SIP traffic (as source IP) - and blocks the ones that exceeded some limit. Works - simultaneous for IPv4 and IPv6 addresses. - - The module does not implement any actions on blocking - it just - simply reports that there is a high traffic from an IP; what to - do, is the administator decision (via scripting). - -1.2. How to use - - There are 2 ways of using this module (as detecting flood - attacks and as taking the right action to limit the impact on - the system): - * manual - from routing script you can force the check of the - source IP of an incoming requests, using "pike_check_req" - function. Note that this checking works only for SIP - requests and you can decide (based on scripting logic) what - source IPs to be monitored and what action to be taken when - a flood is detected. - * automatic - the module will install internal hooks to catch - all incoming requests and replies (even if not well formed - from SIP point of view) - more or less the module will - monitor all incoming packages (from the network) on the SIP - sockets. Each time the source IP of a package needs to be - analyse (to see if trusted or not), the module will run a - script route - see "check_route" module parameter -, where, - based on custom logic, you can decide if that IP needs to - be monitored for flooding or not. As action, when flood is - detected, the module will automatically drop the packages. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. sampling_time_unit (integer) - - Time period used for sampling (or the sampling accuracy ;-) ). - The smaller the better, but slower. If you want to detect - peaks, use a small one. To limit the access (like total number - of requests on a long period of time) to a proxy resource (a - gateway for ex), use a bigger value of this parameter. - - IMPORTANT: a too small value may lead to performance penalties - due timer process overloading. - - Default value is 2. - - Example 1.1. Set sampling_time_unit parameter -... -modparam("pike", "sampling_time_unit", 10) -... - -1.4.2. reqs_density_per_unit (integer) - - How many requests should be allowed per sampling_time_unit - before blocking all the incoming request from that IP. - Practically, the blocking limit is between ( let's have - x=reqs_density_per_unit) x and 3*x for IPv4 addresses and - between x and 8*x for ipv6 addresses. - - Default value is 30. - - Example 1.2. Set reqs_density_per_unit parameter -... -modparam("pike", "reqs_density_per_unit", 30) -... - -1.4.3. remove_latency (integer) - - For how long the IP address will be kept in memory after the - last request from that IP address. It's a sort of timeout - value. - - Note: If the remove_latency value is lower than - sampling_time_unit value, nodes might expire before being - unblocked, therefore losing some UNBLOCK events. In order to - prevent this, if the remove_latency is lower, OpenSIPS - internally forces its value to sampling_time_unit + 1. - - Default value is 120. - - Example 1.3. Set remove_latency parameter -... -modparam("pike", "remove_latency", 130) -... - -1.4.4. check_route (integer) - - The name of the script route to be triggers (in automatic way) - when a package is received from the network. If you do a "drop" - in this route, it will indicate to the module that the source - IP of the package does not need to be monitored. Otherwise, the - source IP will be automatically monitered. - - By defining this parameter, the automatic checking mode is - enabled. - - Default value is NONE (no auto mode). - - Example 1.4. Set check_route parameter -... -modparam("pike", "check_route", "pike") -... -route[pike]{ - if ($si==111.222.111.222) /*trusted, do not check it*/ - drop; - /* all other IPs are checked*/ -} -.... - -1.4.5. pike_log_level (integer) - - Log level to be used by module to auto report the blocking - (only first time) and unblocking of IPs detected as source of - floods. - - Default value is 1 (L_WARN). - - Example 1.5. Set pike_log_level parameter -... -modparam("pike", "pike_log_level", -1) -... - -1.5. Exported Functions - -1.5.1. pike_check_req() - - Process the source IP of the current request and returns false - if the IP was exceeding the blocking limit. - - Return codes: - * 1 (true) - IP is not to be blocked or internal error - occurred. - -Warning - IMPORTANT: in case of internal error, the function returns - true to avoid reporting the current processed IP as - blocked. - * -1 (false) - IP is source of flooding, being previously - detected - * -2 (false) - IP is detected as a new source of flooding - - first time detection - - This function can be used from REQUEST_ROUTE. - - Example 1.6. pike_check_req usage -... -if (!pike_check_req()) { exit; }; -... - -1.6. Exported MI Functions - -1.6.1. pike_list - - Lists the nodes in the pike tree. - - Name: pike_list - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi pike_list - -1.6.2. pike_rm - - Remove a node from the pike tree by IP address. - - Name: pike_rm - - Parameters: - * IP - IP address currently blocked. - - MI FIFO Command Format: - opensips-cli -x mi pike_rm 10.0.0.106 - -1.7. Exported Events - -1.7.1. E_PIKE_BLOCKED - - This event is raised when the pike module decides that an IP - should be blocked. - - Parameters: - * ip - the IP address that has been blocked. - -1.8. Provided Status/Report Identifiers - - The module provides the "pike" Status/Report group, only with - the "main"/default SR identifier. - - There is no usefull status published by the module. - - In terms of reports/logs, the following events will be - reported: - * IP X.Y.Z.W detected as flooding - - For how to access and use the Status/Report information, please - see - https://www.opensips.org/Documentation/Interface-StatusReport-3 - -3. - -Chapter 2. Developer Guide - - One single tree (for both IPv4 and IPv6) is used. Each node - contains a byte, the IP addresses stretching from root to the - leafs. - - Example 2.1. Tree of IP addresses - / 193 - 175 - 132 - 164 -tree root / \ 142 - \ 195 - 37 - 78 - 163 - \ 79 - 134 - - To detect the whole address, step by step, from the root to the - leafs, the nodes corresponding to each byte of the ip address - are expanded. In order to be expended a node has to be hit for - a given number of times (possible by different addresses; in - the previous example, the node “37” was expended by the - 195.37.78.163 and 195.37.79.134 hits). - - For 193.175.132.164 with x= reqs_density_per_unit: - * After first req hits -> the “193” node is built. - * After x more hits, the “175” node is build; the hits of - “193” node are split between itself and its child--both of - them gone have x/2. - * And so on for node “132” and “164”. - * Once “164” build the entire address can be found in the - tree. “164” becomes a leaf. After it will be hit as a leaf - for x times, it will become “RED” (further request from - this address will be blocked). - - So, to build and block this address were needed 3*x hits. Now, - if reqs start coming from 193.175.132.142, the first 3 bytes - are already in the tree (they are shared with the previous - address), so I will need only x hits (to build node “142” and - to make it “RED”) to make this address also to be blocked. This - is the reason for the variable number of hits necessary to - block an IP. - - The maximum number of hits to turn an address red are (n is the - address's number of bytes): - - 1 (first byte) + x (second byte) + (x / 2) * (n - 2) (for the - rest of the bytes) + (n - 1) (to turn the node to red). - - So, for IPv4 (n = 4) will be 3x and for IPv6 (n = 16) will be - 9x. The minimum number of hits to turn an address red is x. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 140 59 4217 2675 - 2. Andrei Pelinescu-Onciul 16 8 120 336 - 3. Razvan Crainea (@razvancrainea) 14 12 99 18 - 4. Liviu Chircu (@liviuchircu) 13 10 29 69 - 5. Daniel-Constantin Mierla (@miconda) 11 9 24 20 - 6. Jan Janak (@janakj) 9 4 386 34 - 7. Vlad Patrascu (@rvlad-patrascu) 8 6 73 52 - 8. Jiri Kuthan (@jiriatipteldotorg) 6 3 257 0 - 9. Jarrod Baumann (@jarrodb) 5 3 111 22 - 10. Maksym Sobolyev (@sobomax) 4 2 3 4 - - All remaining contributors: Henning Westerholt (@henningw), - Elena-Ramona Modroiu, Ancuta Onofrei, Konstantin Bokarius, - Julián Moreno Patiño, Jesus Rodrigues, Norman Brandinger - (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) May 2011 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2002 - May 2023 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Julián Moreno Patiño Feb 2016 - Feb 2016 - 8. Jarrod Baumann (@jarrodb) Apr 2015 - Apr 2015 - 9. Norman Brandinger (@NormB) Aug 2013 - Aug 2013 - 10. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw), Jesus Rodrigues, - Ancuta Onofrei, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, - Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Julián - Moreno Patiño, Jarrod Baumann (@jarrodb), Norman Brandinger - (@NormB), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona - Modroiu, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2005-2009 Voice Sistem SRL - - Copyright © 2003 FhG FOKUS diff --git a/modules/pike/README.md b/modules/pike/README.md new file mode 100644 index 00000000000..98cf4eed23c --- /dev/null +++ b/modules/pike/README.md @@ -0,0 +1,361 @@ +--- +title: "pike Module" +description: "The module provides a simple mechanism for DOS protection - DOS based on floods at network level." +--- + +## Admin Guide + + +### Overview + + +The module provides a simple mechanism for DOS protection - DOS based +on floods at network level. The module keeps trace of all (or selected +ones) IPs of incoming SIP traffic (as source IP) and blocks the ones +that exceeded some limit. +Works simultaneous for IPv4 and IPv6 addresses. + + +The module does not implement any actions on blocking - it just simply +reports that there is a high traffic from an IP; what to do, is +the administator decision (via scripting). + + +### How to use + + +There are 2 ways of using this module (as detecting flood attacks and +as taking the right action to limit the impact on the system): + + +- *manual* - from routing script you can force +the check of the source IP of an incoming requests, using +"pike_check_req" function. Note that this checking works only +for SIP requests and you can decide (based on scripting logic) +what source IPs to be monitored and what action to be taken +when a flood is detected. +- *automatic* - the module will install +internal hooks to catch all incoming requests and replies (even +if not well formed from SIP point of view) - more or less the +module will monitor all incoming packages (from the network) on +the SIP sockets. Each time the source IP of a package needs to +be analyse (to see if trusted or not), the module will run a +script route - see "check_route" module parameter -, where, +based on custom logic, you can decide if that IP needs to be +monitored for flooding or not. As action, when flood is +detected, the module will automatically drop the packages. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### sampling_time_unit (integer) + + +Time period used for sampling (or the sampling accuracy ;-) ). The +smaller the better, but slower. If you want to detect peaks, use a +small one. To limit the access (like total number of requests on a +long period of time) to a proxy resource (a gateway for ex), use +a bigger value of this parameter. + + +> [!IMPORTANT] +> A too small value may lead to performance penalties due +> timer process overloading. + + +*Default value is 2.* + + +```opensips title="Set sampling_time_unit parameter" +... +modparam("pike", "sampling_time_unit", 10) +... +``` + + +#### reqs_density_per_unit (integer) + + +How many requests should be allowed per sampling_time_unit before +blocking all the incoming request from that IP. Practically, the +blocking limit is between ( let's have x=reqs_density_per_unit) x +and 3*x for IPv4 addresses and between x and 8*x for ipv6 addresses. + + +*Default value is 30.* + + +```opensips title="Set reqs_density_per_unit parameter" +... +modparam("pike", "reqs_density_per_unit", 30) +... +``` + + +#### remove_latency (integer) + + +For how long the IP address will be kept in memory after the last +request from that IP address. It's a sort of timeout value. + + +> [!NOTE] +> If the *remove_latency* +> value is lower than *sampling_time_unit* value, +> nodes might expire before being unblocked, therefore losing some +> UNBLOCK events. In order to prevent this, if the +> *remove_latency* is lower, OpenSIPS internally +> forces its value to *sampling_time_unit + 1*. + + +*Default value is 120.* + + +```opensips title="Set remove_latency parameter" +... +modparam("pike", "remove_latency", 130) +... +``` + + +#### check_route (integer) + + +The name of the script route to be triggers (in automatic way) when a +package is received from the network. If you do a "drop" in this route, +it will indicate to the module that the source IP of the package does +not need to be monitored. Otherwise, the source IP will be +automatically monitered. + + +By defining this parameter, the automatic checking mode is enabled. + + +*Default value is NONE (no auto mode).* + + +```opensips title="Set check_route parameter" +... +modparam("pike", "check_route", "pike") +... +route[pike]{ + if ($si==111.222.111.222) /*trusted, do not check it*/ + drop; + /* all other IPs are checked*/ +} +.... +``` + + +#### pike_log_level (integer) + + +Log level to be used by module to auto report the blocking (only first +time) and unblocking of IPs detected as source of floods. + + +*Default value is 1 (L_WARN).* + + +```opensips title="Set pike_log_level parameter" +... +modparam("pike", "pike_log_level", -1) +... +``` + + +### Exported Functions + + +#### pike_check_req() + + +Process the source IP of the current request and returns false if +the IP was exceeding the blocking limit. + + +Return codes: + + +- *1 (true)* - IP is not to be blocked or +internal error occurred. + > [!IMPORTANT] + > In case of internal error, the function returns true to avoid reporting the current processed IP as blocked. + +- *-1 (false)* - IP is source of +flooding, being previously detected +- *-2 (false)* - IP is detected as a new +source of flooding - first time detection + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="pike_check_req usage" +... +if (!pike_check_req()) { exit; }; +... +``` + + +### Exported MI Functions + + +#### pike_list + + +Lists the nodes in the pike tree. + + +Name: *pike_list* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi pike_list +``` + + +#### pike_rm + + +Remove a node from the pike tree by IP address. + + +Name: *pike_rm* + + +Parameters: + + +- *IP* - IP address currently blocked. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi pike_rm 10.0.0.106 +``` + + +### Exported Events + + +#### E_PIKE_BLOCKED + + +This event is raised when the *pike* module +decides that an IP should be blocked. + + +Parameters: + + +- *ip* - the IP address that has been blocked. + + +### Provided Status/Report Identifiers + + +The module provides the "pike" Status/Report group, only with +the "main"/default SR identifier. + + +There is no usefull status published by the module. + + +In terms of reports/logs, the following events will be reported: + + +- IP X.Y.Z.W detected as flooding + + +For how to access and use the Status/Report information, please see +[https://docs.opensips.org/manual/3-6/interface-statusreport/](>https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +## Developer Guide + + +One single tree (for both IPv4 and IPv6) is used. Each node contains a byte, the IP +addresses stretching from root to the leafs. + + +```c title="Tree of IP addresses" + / 193 - 175 - 132 - 164 +tree root / \ 142 + \ 195 - 37 - 78 - 163 + \ 79 - 134 +``` + + +To detect the whole address, step by step, from the root to the leafs, the nodes corresponding +to each byte of the ip address are expanded. In order to be expended a node has to be hit +for a given number of times (possible by different addresses; in the previous example, the +node "37" was expended by the 195.37.78.163 and 195.37.79.134 hits). + + +For 193.175.132.164 with x= reqs_density_per_unit: + + +- After first req hits -> the "193" node is built. +- After x more hits, the "175" node is build; the hits of +"193" node are split between itself and its child--both of them gone +have x/2. +- And so on for node "132" and "164". +- Once "164" build the entire address can be found in the +tree. "164" becomes a leaf. After it will be hit as a leaf for x +times, it will become "RED" (further request from this address will +be blocked). + + +So, to build and block this address were needed 3*x hits. Now, if reqs start coming from +193.175.132.142, the first 3 bytes are already in the tree (they are shared with the previous +address), so I will need only x hits (to build node "142" and to make it +"RED") to make this address also to be blocked. This is the reason for the +variable number of hits necessary to block an IP. + + +The maximum number of hits to turn an address red are (n is the address's number of bytes): + + +1 (first byte) + x (second byte) + (x / 2) * (n - 2) (for the rest of the bytes) + (n - 1) +(to turn the node to red). + + +So, for IPv4 (n = 4) will be 3x and for IPv6 (n = 16) will be 9x. The minimum number of hits +to turn an address red is x. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pike/doc/contributors.xml b/modules/pike/doc/contributors.xml deleted file mode 100644 index d2dfe9cf11c..00000000000 --- a/modules/pike/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 140 - 59 - 4217 - 2675 - - - 2. - Andrei Pelinescu-Onciul - 16 - 8 - 120 - 336 - - - 3. - Razvan Crainea (@razvancrainea) - 14 - 12 - 99 - 18 - - - 4. - Liviu Chircu (@liviuchircu) - 13 - 10 - 29 - 69 - - - 5. - Daniel-Constantin Mierla (@miconda) - 11 - 9 - 24 - 20 - - - 6. - Jan Janak (@janakj) - 9 - 4 - 386 - 34 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 8 - 6 - 73 - 52 - - - 8. - Jiri Kuthan (@jiriatipteldotorg) - 6 - 3 - 257 - 0 - - - 9. - Jarrod Baumann (@jarrodb) - 5 - 3 - 111 - 22 - - - 10. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Elena-Ramona Modroiu, Ancuta Onofrei, Konstantin Bokarius, Julián Moreno Patiño, Jesus Rodrigues, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - May 2011 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2002 - May 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 8. - Jarrod Baumann (@jarrodb) - Apr 2015 - Apr 2015 - - - 9. - Norman Brandinger (@NormB) - Aug 2013 - Aug 2013 - - - 10. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jesus Rodrigues, Ancuta Onofrei, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Julián Moreno Patiño, Jarrod Baumann (@jarrodb), Norman Brandinger (@NormB), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/pike/doc/pike.xml b/modules/pike/doc/pike.xml deleted file mode 100644 index 26f9fa13a36..00000000000 --- a/modules/pike/doc/pike.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - pike Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2009 &voicesystem; - ©right; 2003 &fhg; - - diff --git a/modules/pike/doc/pike_admin.xml b/modules/pike/doc/pike_admin.xml deleted file mode 100644 index 60594123e4d..00000000000 --- a/modules/pike/doc/pike_admin.xml +++ /dev/null @@ -1,366 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module provides a simple mechanism for DOS protection - DOS based - on floods at network level. The module keeps trace of all (or selected - ones) IPs of incoming SIP traffic (as source IP) and blocks the ones - that exceeded some limit. - Works simultaneous for IPv4 and IPv6 addresses. - - - The module does not implement any actions on blocking - it just simply - reports that there is a high traffic from an IP; what to do, is - the administator decision (via scripting). - -
- -
- How to use - - There are 2 ways of using this module (as detecting flood attacks and - as taking the right action to limit the impact on the system): - - - - manual - from routing script you can force - the check of the source IP of an incoming requests, using - "pike_check_req" function. Note that this checking works only - for SIP requests and you can decide (based on scripting logic) - what source IPs to be monitored and what action to be taken - when a flood is detected. - - - - - automatic - the module will install - internal hooks to catch all incoming requests and replies (even - if not well formed from SIP point of view) - more or less the - module will monitor all incoming packages (from the network) on - the SIP sockets. Each time the source IP of a package needs to - be analyse (to see if trusted or not), the module will run a - script route - see "check_route" module parameter -, where, - based on custom logic, you can decide if that IP needs to be - monitored for flooding or not. As action, when flood is - detected, the module will automatically drop the packages. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>sampling_time_unit</varname> (integer) - - Time period used for sampling (or the sampling accuracy ;-) ). The - smaller the better, but slower. If you want to detect peaks, use a - small one. To limit the access (like total number of requests on a - long period of time) to a proxy resource (a gateway for ex), use - a bigger value of this parameter. - - - IMPORTANT: a too small value may lead to performance penalties due - timer process overloading. - - - - Default value is 2. - - - - Set <varname>sampling_time_unit</varname> parameter - -... -modparam("pike", "sampling_time_unit", 10) -... - - -
-
- <varname>reqs_density_per_unit</varname> (integer) - - How many requests should be allowed per sampling_time_unit before - blocking all the incoming request from that IP. Practically, the - blocking limit is between ( let's have x=reqs_density_per_unit) x - and 3*x for IPv4 addresses and between x and 8*x for ipv6 addresses. - - - - Default value is 30. - - - - Set <varname>reqs_density_per_unit</varname> parameter - -... -modparam("pike", "reqs_density_per_unit", 30) -... - - -
-
- <varname>remove_latency</varname> (integer) - - For how long the IP address will be kept in memory after the last - request from that IP address. It's a sort of timeout value. - - - Note: If the remove_latency - value is lower than sampling_time_unit value, - nodes might expire before being unblocked, therefore losing some - UNBLOCK events. In order to prevent this, if the - remove_latency is lower, &osips; internally - forces its value to sampling_time_unit + 1. - - - - Default value is 120. - - - - Set <varname>remove_latency</varname> parameter - -... -modparam("pike", "remove_latency", 130) -... - - -
- -
- <varname>check_route</varname> (integer) - - The name of the script route to be triggers (in automatic way) when a - package is received from the network. If you do a "drop" in this route, - it will indicate to the module that the source IP of the package does - not need to be monitored. Otherwise, the source IP will be - automatically monitered. - - - By defining this parameter, the automatic checking mode is enabled. - - - - Default value is NONE (no auto mode). - - - - Set <varname>check_route</varname> parameter - -... -modparam("pike", "check_route", "pike") -... -route[pike]{ - if ($si==111.222.111.222) /*trusted, do not check it*/ - drop; - /* all other IPs are checked*/ -} -.... - - -
- -
- <varname>pike_log_level</varname> (integer) - - Log level to be used by module to auto report the blocking (only first - time) and unblocking of IPs detected as source of floods. - - - - Default value is 1 (L_WARN). - - - - Set <varname>pike_log_level</varname> parameter - -... -modparam("pike", "pike_log_level", -1) -... - - -
-
- - -
- Exported Functions -
- - <function moreinfo="none">pike_check_req()</function> - - - Process the source IP of the current request and returns false if - the IP was exceeding the blocking limit. - - - Return codes: - - - - 1 (true) - IP is not to be blocked or - internal error occurred. - - - IMPORTANT: in case of internal error, the function returns true to - avoid reporting the current processed IP as blocked. - - - - - -1 (false) - IP is source of - flooding, being previously detected - - - - - -2 (false) - IP is detected as a new - source of flooding - first time detection - - - - - - This function can be used from REQUEST_ROUTE. - - - <function>pike_check_req</function> usage - -... -if (!pike_check_req()) { exit; }; -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">pike_list</function> - - - Lists the nodes in the pike tree. - - - Name: pike_list - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi pike_list - -
-
- - <function moreinfo="none">pike_rm</function> - - - Remove a node from the pike tree by IP address. - - - Name: pike_rm - - Parameters: - - - IP - IP address currently blocked. - - - - MI FIFO Command Format: - - - opensips-cli -x mi pike_rm 10.0.0.106 - -
-
- -
- Exported Events -
- - <function moreinfo="none">E_PIKE_BLOCKED</function> - - - This event is raised when the pike module - decides that an IP should be blocked. - - Parameters: - - - ip - the IP address that has been blocked. - - -
-
- -
- Provided Status/Report Identifiers - - - The module provides the "pike" Status/Report group, only with - the "main"/default SR identifier. - - - There is no usefull status published by the module. - - - In terms of reports/logs, the following events will be reported: - - - - IP X.Y.Z.W detected as flooding - - - - - For how to access and use the Status/Report information, please see - https://www.opensips.org/Documentation/Interface-StatusReport-3-3. - - -
- - -
- diff --git a/modules/pike/doc/pike_devel.xml b/modules/pike/doc/pike_devel.xml deleted file mode 100644 index 72e5571a92e..00000000000 --- a/modules/pike/doc/pike_devel.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - &develguide; - - One single tree (for both IPv4 and IPv6) is used. Each node contains a byte, the &ip; - addresses stretching from root to the leafs. - - - Tree of &ip; addresses - - / 193 - 175 - 132 - 164 -tree root / \ 142 - \ 195 - 37 - 78 - 163 - \ 79 - 134 - - - - To detect the whole address, step by step, from the root to the leafs, the nodes corresponding - to each byte of the ip address are expanded. In order to be expended a node has to be hit - for a given number of times (possible by different addresses; in the previous example, the - node 37 was expended by the 195.37.78.163 and 195.37.79.134 hits). - - - For 193.175.132.164 with x= reqs_density_per_unit: - - - - - After first req hits -> the 193 node is built. - - - - - After x more hits, the 175 node is build; the hits of - 193 node are split between itself and its child--both of them gone - have x/2. - - - - - And so on for node 132 and 164. - - - - - Once 164 build the entire address can be found in the - tree. 164 becomes a leaf. After it will be hit as a leaf for x - times, it will become RED (further request from this address will - be blocked). - - - - - So, to build and block this address were needed 3*x hits. Now, if reqs start coming from - 193.175.132.142, the first 3 bytes are already in the tree (they are shared with the previous - address), so I will need only x hits (to build node 142 and to make it - RED) to make this address also to be blocked. This is the reason for the - variable number of hits necessary to block an &ip;. - - - The maximum number of hits to turn an address red are (n is the address's number of bytes): - - - 1 (first byte) + x (second byte) + (x / 2) * (n - 2) (for the rest of the bytes) + (n - 1) - (to turn the node to red). - - - So, for IPv4 (n = 4) will be 3x and for IPv6 (n = 16) will be 9x. The minimum number of hits - to turn an address red is x. - - - diff --git a/modules/presence/README b/modules/presence/README deleted file mode 100644 index e4dcf38609d..00000000000 --- a/modules/presence/README +++ /dev/null @@ -1,1156 +0,0 @@ -Presence Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Presence clustering - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. db_url(str) - 1.4.2. fallback2db (int) - 1.4.3. cluster_id (int) - 1.4.4. cluster_federation_mode (str) - 1.4.5. cluster_pres_events (str) - 1.4.6. cluster_be_active_shtag (str) - 1.4.7. expires_offset (int) - 1.4.8. max_expires_subscribe (int) - 1.4.9. max_expires_publish (int) - 1.4.10. contact_user (str) - 1.4.11. enable_sphere_check (int) - 1.4.12. waiting_subs_daysno (int) - 1.4.13. mix_dialog_presence (int) - 1.4.14. bla_presentity_spec (str) - 1.4.15. bla_fix_remote_target (int) - 1.4.16. notify_offline_body (int) - 1.4.17. end_sub_on_timeout (int) - 1.4.18. clean_period (int) - 1.4.19. db_update_period (int) - 1.4.20. presentity_table(str) - 1.4.21. active_watchers_table(str) - 1.4.22. watchers_table(str) - 1.4.23. subs_htable_size (int) - 1.4.24. pres_htable_size (int) - - 1.5. Exported Functions - - 1.5.1. handle_publish([sender_uri]) - 1.5.2. handle_subscribe([force_active] - [,sharing_tag]) - - 1.6. Exported MI Functions - - 1.6.1. refresh_watchers - 1.6.2. cleanup - 1.6.3. pres_phtable_list - 1.6.4. subs_phtable_list - 1.6.5. pres_expose - - 1.7. Exported Events - - 1.7.1. E_PRESENCE_PUBLISH - 1.7.2. E_PRESENCE_EXPOSED - - 1.8. Installation - - 2. Developer Guide - - 2.1. bind_presence(presence_api_t* api) - 2.2. add_event - 2.3. get_rules_doc - 2.4. get_auth_status - 2.5. apply_auth_nbody - 2.6. agg_nbody - 2.7. free_body - 2.8. aux_body_processing - 2.9. aux_free_body - 2.10. evs_publ_handl - 2.11. evs_subs_handl - 2.12. contains_event - 2.13. get_event_list - 2.14. update_watchers_status - 2.15. get_sphere - 2.16. contains_presence - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set fallback2db parameter - 1.3. Set cluster_id parameter - 1.4. Set cluster_federation_mode parameter - 1.5. Set cluster_pres_events parameter - 1.6. Set cluster_be_active_shtag parameter - 1.7. Set expires_offset parameter - 1.8. Set max_expires_subscribe parameter - 1.9. Set max_expires_publish parameter - 1.10. Set contact_user parameter - 1.11. Set enable_sphere_check parameter - 1.12. Set waiting_subs_daysno parameter - 1.13. Set mix_dialog_presence parameter - 1.14. Set bla_presentity_spec parameter - 1.15. Set bla_fix_remote_target parameter - 1.16. Set notify_offline_body parameter - 1.17. Set end_sub_on_timeout parameter - 1.18. Set clean_period parameter - 1.19. Set db_update_period parameter - 1.20. Set presentity_table parameter - 1.21. Set active_watchers_table parameter - 1.22. Set watchers_table parameter - 1.23. Set subs_htable_size parameter - 1.24. Set pres_htable_size parameter - 1.25. handle_publish usage - 1.26. handle_subscribe usage - 2.1. presence_api_t structure - -Chapter 1. Admin Guide - -1.1. Overview - - The modules handles PUBLISH and SUBSCRIBE messages and - generates NOTIFY messages in a general, event independent way. - It allows registering events from other OpenSIPS modules. - Events that can currently be added are: - * presence, presence.winfo, dialog;sla from presence_xml - module - * message-summary from presence_mwi module - * call-info, line-seize from presence_callinfo module - * dialog from presence_dialoginfo module - * xcap-diff from presence_xcapdiff module - * as-feature-event from presence_dfks module - - The module uses database storage. It has later been improved - with memory caching operations to improve performance. The - Subscribe dialog information are stored in memory and are - periodically updated in database, while for Publish only the - presence or absence of stored info for a certain resource is - maintained in memory to avoid unnecessary, costly db - operations. It is possible to configure a fallback to database - mode(by setting module parameter "fallback2db"). In this mode, - in case a searched record is not found in cache, the search is - continued in database. This is useful for an architecture in - which processing and memory load might be divided on more - machines using the same database. - - The module can also work only with the functionality of a - library, with no message processing and generation, but used - only for the exported functions. This mode of operation is - enabled if the db_url parameter is not set to any value. - - The server follows the specifications in: RFC3265, RFC3856, - RFC3857, RFC3858. - -1.2. Presence clustering - - To read and understand the presence clustering, its abilities - and how to implement scenarios like High-Availability, Load - Balancing or Federations, please refer to this article - https://blog.opensips.org/2018/03/27/clustering-presence-servic - es-with-opensips-2-4/. - - As data synchronization at startup is performed when using the - full-sharing cluster_federation_mode, you should define at - least one "seed" node in the cluster in this case. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - * signaling. - * clusterer, if the cluster_id module parameter is set and - clustering support activated. - -1.3.2. External Libraries or Applications - - * libxml-dev. - -1.4. Exported Parameters - -1.4.1. db_url(str) - - The database url. - - If set, the module is a fully operational presence server. - Otherwise, it is used as a 'library', for its exported - functions. - - Default value is “NULL”. - - Example 1.1. Set db_url parameter -... -modparam("presence", "db_url", - "mysql://opensips:opensipsrw@192.168.2.132/opensips") -... - -1.4.2. fallback2db (int) - - Setting this parameter enables a fallback to db mode of - operation. In this mode, in case a searched record is not found - in cache, the search is continued in database. Useful for an - architecture in which processing and memory load might be - divided on more machines using the same database. - - Example 1.2. Set fallback2db parameter -... -modparam("presence", "fallback2db", 1) -... - -1.4.3. cluster_id (int) - - The ID of the cluster this presence server belongs to. This - parameter is to be used only if clustering mode is needed. In - order to understand th concept of a cluster ID, please see the - clusterer module. - - This OpenSIPS cluster exposes the "presence" capability in - order to mark nodes as eligible for becoming data donors during - an arbitrary sync request. Consequently, the cluster must have - at least one node marked with the "seed" value as the - clusterer.flags column/property in order to be fully - functional. Consult the clusterer - Capabilities chapter for - more details. - - For more on presence clustering see the Section 1.2, “Presence - clustering” chapter. - - Default value is “None”. - - Example 1.3. Set cluster_id parameter -... -modparam("presence", "cluster_id", 2) -... - -1.4.4. cluster_federation_mode (str) - - When enabling the federation mode, nodes inside the presence - cluster will start broadcasting the data to other nodes via the - clustering support. - - Possible values: - * disabled - federation mode is disabled - * on-demand-sharing - the minimum needed information is kept - on each node. Replicated information for non local - subscribers is discarded and queries are broadcasted in the - cluster for new subscribers. - * full-sharing - published state is kept on all presence - nodes even when there aren't any local subscribers. - - If you don't want to use a shared database (via fallback2db), - but still want a complete data set everywhere, you may choose - mode full-sharing. This mode allows you to switch PUBLISH - endpoints, even for already published Event States, thus - allowing you to add and remove presence servers without losing - state. - - For more on presence clustering see the Section 1.2, “Presence - clustering” chapter. - - Default value is “disabled”. - - Example 1.4. Set cluster_federation_mode parameter -... -modparam("presence", "cluster_federation_mode", "full-sharing") -... - -1.4.5. cluster_pres_events (str) - - Comma Separated Value (CSV) list with the events to considered - by the federated cluster - only presentities advertising one of - these events will be broadcasted via the cluster. - - For more on presence clustering see the Section 1.2, “Presence - clustering” chapter. - - Default value is “empty” (meaning all). - - Example 1.5. Set cluster_pres_events parameter -... -modparam("presence", "cluster_pres_events" ,"presence, dialog;sla, messa -ge-summary") -... - -1.4.6. cluster_be_active_shtag (str) - - The name of a cluster sharing tag to be used to indicate when - this node (as part of the cluster) should be active or not. If - the sharing tag is off (or as backup), the node will become - inactive from clustering perspective, meaning not sending and - not accepting any presence related cluster traffic. - - This ability of a node to become inactive may be used when - creating a federated cluster where 2 nodes are acting as a - local active-backup setup (for local High Availability - purposes). - - This parameter has meaning only in clustering mode. If not - defined, the node will be active all the time. - - For more on presence clustering see the Section 1.2, “Presence - clustering” chapter. - - Default value is “empty” (not tag define). - - Example 1.6. Set cluster_be_active_shtag parameter -... -modparam("presence", "cluster_be_active_shtag" ,"local_ha") -... - -1.4.7. expires_offset (int) - - The extra time to store a subscription/publication. - - Default value is “0”. - - Example 1.7. Set expires_offset parameter -... -modparam("presence", "expires_offset", 10) -... - -1.4.8. max_expires_subscribe (int) - - The the maximum admissible expires value for SUBSCRIBE - messages. - - Default value is “3600”. - - Example 1.8. Set max_expires_subscribe parameter -... -modparam("presence", "max_expires_subscribe", 3600) -... - -1.4.9. max_expires_publish (int) - - The the maximum admissible expires value for PUBLISH messages. - - Default value is “3600”. - - Example 1.9. Set max_expires_publish parameter -... -modparam("presence", "max_expires_publish", 3600) -... - -1.4.10. contact_user (str) - - This is the username that will be used in the Contact header - for the 200 OK replies to SUBSCRIBE and in the following - in-dialog NOTIFY requests. The IP address, port and transport - for the Contact will be automatically determined based on the - interface where the SUBSCRIBE was received. - - If set to an empty string, no username will be added to the - contact and the contact will be built just out of the IP, port - and transport. - - Default value is “presence”. - - Example 1.10. Set contact_user parameter -... -modparam("presence", "contact_user", "presence") -... - -1.4.11. enable_sphere_check (int) - - This parameter is a flag that should be set if permission rules - include sphere checking. The sphere information is expected to - be present in the RPID body published by the presentity. The - flag is introduced as this check requires extra processing that - should be avoided if this feature is not supported by the - clients. - - Default value is “0 ”. - - Example 1.11. Set enable_sphere_check parameter -... -modparam("presence", "enable_sphere_check", 1) -... - -1.4.12. waiting_subs_daysno (int) - - The number of days to keep the record of a subscription in - server database if the subscription is in pending or waiting - state (no authorization policy was defined for it or the target - user did not register sice the subscription and was not - informed about it). - - Default value is “3” days. Maximum accepted value is 30 days. - - Example 1.12. Set waiting_subs_daysno parameter -... -modparam("presence", "waiting_subs_daysno", 2) -... - -1.4.13. mix_dialog_presence (int) - - This module parameter enables a very nice feature in the - presence server - generating presence information from dialogs - state. If this parameter is set, the presence server will tell - you if a buddy is in a call even if his phone did not send a - presence Publish with this information. You will need to load - the dialoginfo modules, presence_dialoginfo, pua_dialoginfo, - dialog and pua. - - Default value is “0”. - - Example 1.13. Set mix_dialog_presence parameter -... -modparam("presence", "mix_dialog_presence", 1) -... - -1.4.14. bla_presentity_spec (str) - - By default the presentity uri for BLA subscribes - (event=dialog;sla) is computed from contact username + from - domain. In some cases though, this way of computing the - presentity might not be right (for example if you have a SBC in - front that masquerades the contact). So we added this parameter - that allows defining a custom uri to be used as presentity uri - for BLA subscribes. You should set this parameter to the name - of a pseudovariable and then set this pseudovariable to the - desired URI before calling the handle_subscribe() function. - - Default value is “NULL”. - - Example 1.14. Set bla_presentity_spec parameter -... -modparam("presence", "bla_presentity_spec", "$var(bla_pres)") -... - -1.4.15. bla_fix_remote_target (int) - - Polycom has a bug in the bla implementation. It inserts the - remote IP contact in the Notify body and when a phone picks up - a call put on hold by another phone in the same BLA group, it - sends an Invite directly to the remote IP. OpenSIPS BLA server - tries to prevent this by replacing the IP contact with the - domain, when this is possible. - - In some cases(configurations) however this is not desirable, so - this parameter was introduced to disable this behaviour when - needed. - - Default value is “1”. - - Example 1.15. Set bla_fix_remote_target parameter -... -modparam("presence", "bla_fix_remote_target", 0) -... - -1.4.16. notify_offline_body (int) - - If this parameter is set, when no published info is found for a - user, the presence server will generate a dummy body with - status 'closed' and use it when sending Notify, instead of - notifying with no body. - - Default value is “0”. - - Example 1.16. Set notify_offline_body parameter -... -modparam("presence", "notify_offline_body", 1) -... - -1.4.17. end_sub_on_timeout (int) - - If a presence subscription should be automatically terminated - (destroyed) when receiving a SIP timeout (408) for a sent - NOTIFY requests. - - Default value is “1” (enabled). - - Example 1.17. Set end_sub_on_timeout parameter -... -modparam("presence", "end_sub_on_timeout", 0) -... - -1.4.18. clean_period (int) - - The period at which to clean the expired subscription dialogs. - - Default value is “100”. A zero or negative value disables this - activity. - - Example 1.18. Set clean_period parameter -... -modparam("presence", "clean_period", 100) -... - -1.4.19. db_update_period (int) - - The period at which to synchronize cached subscriber info with - the database. - - Default value is “100”. A zero or negative value disables - synchronization. - - Example 1.19. Set db_update_period parameter -... -modparam("presence", "db_update_period", 100) -... - -1.4.20. presentity_table(str) - - The name of the db table where Publish information are stored. - - Default value is “presentity”. - - Example 1.20. Set presentity_table parameter -... -modparam("presence", "presentity_table", "presentity") -... - -1.4.21. active_watchers_table(str) - - The name of the db table where active subscription information - are stored. - - Default value is “active_watchers”. - - Example 1.21. Set active_watchers_table parameter -... -modparam("presence", "active_watchers_table", "active_watchers") -... - -1.4.22. watchers_table(str) - - The name of the db table where subscription states are stored. - - Default value is “watchers”. - - Example 1.22. Set watchers_table parameter -... -modparam("presence", "watchers_table", "watchers") -... - -1.4.23. subs_htable_size (int) - - The size of the hash table to store subscription dialogs. This - parameter will be used as the power of 2 when computing table - size. - - Default value is “9 (512)”. - - Example 1.23. Set subs_htable_size parameter -... -modparam("presence", "subs_htable_size", 11) -... - -1.4.24. pres_htable_size (int) - - The size of the hash table to store publish records. This - parameter will be used as the power of 2 when computing table - size. - - Default value is “9 (512)”. - - Example 1.24. Set pres_htable_size parameter -... -modparam("presence", "pres_htable_size", 11) -... - -1.5. Exported Functions - -1.5.1. handle_publish([sender_uri]) - - The function handles PUBLISH requests. It stores and updates - published information in database and calls functions to send - NOTIFY messages when changes in the published information - occur. - - It may takes one optional string argument, the 'sender_uri' SIP - URI. The parameter was added for enabling BLA implementation. - If present, Notification of a change in published state is not - sent to the respective uri even though a subscription exists. - It should be taken from the Sender header. It was left at the - decision of the administrator whether or not to transmit the - content of this header as parameter for handle_publish, to - prevent security problems. - - This function can be used from REQUEST_ROUTE. - - Return code: - * 1 - if success. - * -1 - if error. - - The module sends an appropriate stateless reply in all cases. - - Example 1.25. handle_publish usage -... - if(is_method("PUBLISH")) - { - if($hdr(Sender)!= NULL) - handle_publish($hdr(Sender)); - else - handle_publish(); - } -... - -1.5.2. handle_subscribe([force_active] [,sharing_tag]) - - This function is to be used for handling SUBSCRIBE requests. It - stores or updates the watcher/subscriber information in - database. Additionally, in response to initial SUBSCRIBE - requests (creating a new subscription session), the function - also sends back the NOTIFY (with the presence information) to - the wathcer/subscriber. - - The function may take the following parameters: - * force_active (int, optional) - optional parameter that - controls what is the default policy (of the presentity) on - accepting new subscriptions (accept or reject) - of course, - this parameter makes sense only when using a presence - configuration with privacy rules enabled (force_active - parameter in presence_xml module is not set). - There are scenarios where the presentity (the party you - subscribe to) can not upload an XCAP document with its - privacy rules (to control which watchers are allowed to - subscribe to it). In such cases, from script level, you can - force the presence server to consider the current - subscription allowed (with Subscription-Status:active) by - calling the handle_subscribe() function with the integer - parameter "1". - * sharing_tag (string, optional) - optional parameter telling - the owner tag (for the subscription) in clusetering - scenarios where the subscription data is shared between - multiple servers - see the Section 1.2, “Presence - clustering” chapter for more details. - - Ex: - if($ru =~ "kphone@opensips.org") - handle_subscribe(1); - - This function can be used from REQUEST_ROUTE. - - Return code: - * 1 - if success. - * -1 - if error. - - The module sends an appropriate stateless reply in all cases. - - Example 1.26. handle_subscribe usage -... -if($rm=="SUBSCRIBE") - handle_subscribe(); -... - -1.6. Exported MI Functions - -1.6.1. refresh_watchers - - Triggers sending Notify messages to watchers if a change in - watchers authorization or in published state occurred. - - Name: refresh_watchers - - Parameters: - * presentity_uri : the uri of the user who made the change - and whose watchers should be informed - * event : the event package - * refresh type : it distinguishes between the two different - types of events that can trigger a refresh: - + a change in watchers authentication: refresh type= 0 ; - + a statical update in published state (either through - direct update in db table or by modifying the pidf - manipulation document, if pidf_manipulation parameter - is set): refresh type!= 0. - - MI FIFO Command Format: -opensips-cli -x mi refresh_watchers sip:11@192.168.2.132 presence 1 - -1.6.2. cleanup - - Manually triggers the cleanup functions for watchers and - presentity tables. Useful if you have set clean_period to zero - or less. - - Name: cleanup - - Parameters: none - - MI FIFO Command Format: -opensips-cli -x mi cleanup - -1.6.3. pres_phtable_list - - Lists all the presentity records. - - Name: pres_phtable_list - - Parameters: none - - MI FIFO Command Format: -opensips-cli -x mi pres_phtable_list - -1.6.4. subs_phtable_list - - Lists all the subscription records, or the subscriptions for - which the "To" and "From" URIs match the given parameters. - - Name: subs_phtable_list - - Parameters - * from(optional) - wildcard for "From" URI - * to(optional) - wildcard for "To" URI - - MI FIFO Command Format: -opensips-cli -x mi subs_phtable_list sip:222@domain2.com sip:user_1@exam -ple.com - -1.6.5. pres_expose - - Exposes in the script, by rasing an E_PRESENCE_EXPOSED event, - all the presentities of a specific event that match a specified - filter. - - Name: pres_expose - - Parameters: - * event - the desired presence event. - * filter(optional) - a regular expression (REGEXP) used for - filtering the presentities for that event. Only the - presentities that match will be exposed. If not specified, - all presentities for that event are exposed. - - MI FIFO Command Format: -opensips-cli -x mi pres_expose presence ^sip:10\.0\.5\.[0-9]* - -1.7. Exported Events - -1.7.1. E_PRESENCE_PUBLISH - - This event is raised when the presence module receives a - PUBLISH message. - - Parameters: - * user - the AOR of the user - * domain - the domain - * event - the type of the event published - * expires - the expire value of the publish - * etag - the entity tag - * old_etag - the entity tag to be refreshed - * body - the body of the PUBLISH request - -1.7.2. E_PRESENCE_EXPOSED - - This event is raised for each presentity exposeed by the - pres_expose. - - Parameters: - - Same parameters as the E_PRESENCE_PUBLISH event. - -1.8. Installation - - The module requires 3 table in OpenSIPS database: presentity, - active_watchers and watchers tables. The SQL syntax to create - them can be found in presence-create.sql script in the database - directories in the opensips/scripts folder. You can also find - the complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer Guide - - The module provides the following functions that can be used in - other OpenSIPS modules. - -2.1. bind_presence(presence_api_t* api) - - This function binds the presence modules and fills the - structure with the exported functions that represent functions - adding events in presence module and functions specific for - Subscribe processing. - - Example 2.1. presence_api_t structure -... -typedef struct presence_api { - add_event_t add_event; - contains_event_t contains_event; - search_event_t search_event; - get_event_list_t get_event_list; - - update_watchers_t update_watchers_status; - - /* subs hash table handling functions */ - new_shtable_t new_shtable; - destroy_shtable_t destroy_shtable; - insert_shtable_t insert_shtable; - search_shtable_t search_shtable; - delete_shtable_t delete_shtable; - update_shtable_t update_shtable; - /* function to duplicate a subs structure*/ - mem_copy_subs_t mem_copy_subs; - /* function used for update in database*/ - update_db_subs_t update_db_subs; - /* function to extract dialog information from a - SUBSCRIBE message */ - extract_sdialog_info_t extract_sdialog_info; - /* function to request sphere defition for a presentity */ - pres_get_sphere_t get_sphere; - pres_contains_presence_t contains_presence; -}presence_api_t; -... - -2.2. add_event - - Field type: -... -typedef int (*add_event_t)(pres_ev_t* event); -... - - This function receives as a parameter a structure with event - specific information and adds it to presence event list. - - The structure received as a parameter: -... -typedef struct pres_ev -{ - str name; - event_t* evp; - str content_type; - int default_expires; - int type; - int etag_not_new; - /* - * 0 - the standard mechanism (allocating new etag - for each Publish) - * 1 - allocating an etag only - for an initial Publish - */ - int req_auth; - get_rules_doc_t* get_rules_doc; - apply_auth_t* apply_auth_nbody; - is_allowed_t* get_auth_status; - - /* an agg_body_t function should be registered - * if the event permits having multiple published - * states and requires an aggregation of the information - * otherwise, this field should be NULL and the last - * published state is taken when constructing Notify msg - */ - agg_nbody_t* agg_nbody; - publ_handling_t * evs_publ_handl; - subs_handling_t * evs_subs_handl; - free_body_t* free_body; - - /* sometimes it is necessary that a module make changes for a bo -dy for each - * active watcher (e.g. setting the "version" parameter in an XM -L document. - * If a module registers the aux_body_processing callback, it ge -ts called for - * each watcher. It either gets the body received by the PUBLISH -, or the body - * generated by the agg_nbody function. - * The module can deceide if it makes a copy of the original bod -y, which is then - * manipulated, or if it works directly in the original body. If - the module makes a - * copy of the original body, it also has to register the aux_fr -ee_body() to - * free this "per watcher" body. - */ - aux_body_processing_t* aux_body_processing; - free_body_t* aux_free_body; - - struct pres_ev* wipeer; - struct pres_ev* next; - -}pres_ev_t; -... - -2.3. get_rules_doc - - Filed type: -... -typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc); -... - - This function returns the authorization rules document that - will be used in obtaining the status of the subscription and - processing the notified body. A reference to the document - should be put in the auth_rules_doc of the subs_t structure - given as a parameter to the functions described bellow. - -2.4. get_auth_status - - This filed is a function to be called for a subscription - request to return the state for that subscription according to - authorization rules. In the auth_rules_doc field of the subs_t - structure received as a parameter should contain the rules - document of the presentity in case, if it exists. - - It is called only if the req_auth field is not 0. - - Filed type: -... -typedef int (is_allowed_t)(struct subscription* subs); -... - -2.5. apply_auth_nbody - - This parameter should be a function to be called for an event - that requires authorization, when constructing final body. The - authorization document is taken from the auth_rules_doc field - of the subs_t structure given as a parameter. It is called only - if the req_auth field is not 0. - - Filed type: -... -typedef int (apply_auth_t)(str* , struct subscription*, str** ); -... - -2.6. agg_nbody - - If present, this field marks that the events requires - aggregation of states. This function receives a body array and - should return the final body. If not present, it is considered - that the event does not require aggregation and the most recent - published information is used when constructing Notifies. - - Filed type: -... -typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain, -str** body_array, int n, int off_index); -.. - -2.7. free_body - - This field must be field in if subsequent processing is - performed on the info from database before being inserted in - Notify message body(if agg_nbody or apply_auth_nbody fields are - filled in). It should match the allocation function used when - processing the body. - - Filed type: -... -typedef void(free_body_t)(char* body); -.. - -2.8. aux_body_processing - - This field must be set if the module needs to manipulate the - NOTIFY body for each watcher. E.g. if the XML body includes a - 'version' parameter which will be increased for each NOTIFY, on - a "per watcher" basis. The module can either allocate a new - buffer for the new body an return it (aux_free_body function - must be set too) or it manipualtes the original body directly - and returns NULL. - - Filed type: -... -typedef str* (aux_body_processing_t)(struct subscription *subs, str* bod -y); -.. - -2.9. aux_free_body - - This field must be set if the module registers the - aux_body_processing function and allocates memory for the new - modified body. Then, this function will be used to free the - pointer returned by the aux_body_processing function. If the - module does use the aux_body_processing, but does not allocate - new memory, but manipulates directly the original body buffer, - then the aux_body_processing must return NULL and this field - should not be set. - - Filed type: -... -typedef void(free_body_t)(char* body); -.. - -2.10. evs_publ_handl - - This function is called when handling Publish requests. Most - contain body correctness check. - -... -typedef int (publ_handling_t)(struct sip_msg*); -.. - -2.11. evs_subs_handl - - It is not compulsory. Should contain event specific handling - for Subscription requests. - - Filed type: -... -typedef int (subs_handling_t)(struct sip_msg*); -.. - -2.12. contains_event - - Field type: -.. -typedef pres_ev_t* (*contains_event_t)(str* name, -event_t* parsed_event); -... - - The function parses the event name received as a parameter and - searches the result in the list. It returns the found event or - NULL, if not found. If the second argument is an allocated - event_t* structure it fills it with the result of the parsing. - -2.13. get_event_list - - Field type: -... -typedef int (*get_event_list_t) (str** ev_list); -... - - This function returns a string representation of the events - registered in presence module.( used for Allowed-Events - header). - -2.14. update_watchers_status - - Field type: -... -typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev, -str* rules_doc); -... - - This function is an external command that can be used to - announce a change in authorization rules for a presentity. It - updates the stored status and sends a Notify to the watchers - whose status has changes. (used by presence_xml module when - notified through an MI command of a change in an xcap - document). - -2.15. get_sphere - - Field type: -... -typedef char* (*pres_get_sphere_t)(str* pres_uri); -... - - This function searches for a sphere definition in the published - information if this has type RPID. If not found returns NULL. - (the return value is allocated in private memory and should be - freed) - -2.16. contains_presence - - Field type: -... -typedef int (*pres_contains_presence_t)(str* pres_uri); -... - - This function searches is a presence uri has published any - presence information. It return 1 if a record is found, -1 - otherwise. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 659 247 24146 12623 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 155 96 3231 1846 - 3. Razvan Crainea (@razvancrainea) 35 28 423 163 - 4. Liviu Chircu (@liviuchircu) 35 25 287 397 - 5. Vlad Patrascu (@rvlad-patrascu) 33 19 631 481 - 6. Ovidiu Sas (@ovidiusas) 29 20 618 170 - 7. Daniel-Constantin Mierla (@miconda) 24 19 174 165 - 8. Dan Pascu (@danpascu) 20 14 162 201 - 9. Henning Westerholt (@henningw) 14 6 340 302 - 10. Walter Doekes (@wdoekes) 11 7 150 105 - - All remaining contributors: Saúl Ibarra Corretgé (@saghul), - Maksym Sobolyev (@sobomax), Vlad Paiu (@vladpaiu), Juha - Heinanen (@juha-h), Edson Gellert Schubert, Alexandra Titoc, - Stanislaw Pitucha, Damien Sandras (@dsandras), Kobi Eshun - (@ekobi), Carsten Bock, Norman Brandinger (@NormB), Dusan - Klinec (@ph4r05), Angel Marin, Klaus Darilion, Carlos Oliva, - Sergio Gutierrez, Kennard White, Elena-Ramona Modroiu, Jasper - Hafkenscheid, Vasil Kolev, Benny Prijono, James Criscuolo, - Peter Lemenkov (@lemenkov), Vallimamod Abdullah, UnixDev, Denis - Bilenko, Julián Moreno Patiño, John Riordan, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - Nov 2025 - 2. Norman Brandinger (@NormB) May 2024 - Nov 2024 - 3. Alexandra Titoc Sep 2024 - Sep 2024 - 4. Carsten Bock Mar 2024 - Mar 2024 - 5. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2022 - 7. Jasper Hafkenscheid Jul 2022 - Jul 2022 - 8. Razvan Crainea (@razvancrainea) Sep 2011 - Jun 2021 - 9. Walter Doekes (@wdoekes) Apr 2010 - Apr 2021 - 10. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - - All remaining contributors: Ovidiu Sas (@ovidiusas), Dan Pascu - (@danpascu), Peter Lemenkov (@lemenkov), James Criscuolo, - Julián Moreno Patiño, Dusan Klinec (@ph4r05), Carlos Oliva, - Damien Sandras (@dsandras), Vlad Paiu (@vladpaiu), Saúl Ibarra - Corretgé (@saghul), Anca Vamanu, Vallimamod Abdullah, Kennard - White, Stanislaw Pitucha, Angel Marin, John Riordan, Vasil - Kolev, UnixDev, Sergio Gutierrez, Kobi Eshun (@ekobi), Klaus - Darilion, Denis Bilenko, Henning Westerholt (@henningw), Juha - Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Edson - Gellert Schubert, Julien Blache, Benny Prijono, Elena-Ramona - Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Jasper Hafkenscheid, Ovidiu Sas - (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Walter Doekes - (@wdoekes), Dan Pascu (@danpascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Saúl Ibarra - Corretgé (@saghul), Anca Vamanu, Kennard White, Angel Marin, - Kobi Eshun (@ekobi), Klaus Darilion, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Edson Gellert - Schubert, Juha Heinanen (@juha-h), Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/presence/README.md b/modules/presence/README.md new file mode 100644 index 00000000000..c3d903e8490 --- /dev/null +++ b/modules/presence/README.md @@ -0,0 +1,1297 @@ +--- +title: "Presence Module" +description: "The modules handles PUBLISH and SUBSCRIBE messages and generates NOTIFY messages in a general, event independent way." +--- + +## Admin Guide + + +### Overview + + +The modules handles PUBLISH and SUBSCRIBE messages and generates +NOTIFY messages in a general, event independent way. It allows registering +events from other OpenSIPS modules. Events that can currently be added are: + + +- *presence*, *presence.winfo*, +*dialog;sla* from presence_xml module +- *message-summary* from presence_mwi module +- *call-info*, *line-seize* from +presence_callinfo module +- *dialog* from presence_dialoginfo module +- *xcap-diff* from presence_xcapdiff module +- *as-feature-event* from presence_dfks module + + +The module uses database storage. +It has later been improved with memory caching operations to improve +performance. The Subscribe dialog information are stored in memory and +are periodically updated in database, while for Publish only the presence +or absence of stored info for a certain resource is maintained in memory +to avoid unnecessary, costly db operations. +It is possible to configure a fallback to database mode(by setting module +parameter "fallback2db"). In this mode, in case a searched record is not +found in cache, the search is continued in database. This is useful for +an architecture in which processing and memory load might be divided on +more machines using the same database. + + +The module can also work only with the functionality of a library, +with no message processing and generation, but used only for the exported +functions. +This mode of operation is enabled if the db_url parameter is not set to any value. + + +The server follows the specifications in: RFC3265, RFC3856, RFC3857, +RFC3858. + + +### Presence clustering + + +To read and understand the presence clustering, its abilities and how to +implement scenarios like High-Availability, Load Balancing or Federations, +please refer to this article [https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/](https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/). + + +As data synchronization at startup is performed when using the +*full-sharing* [cluster federation mode](#param_cluster_federation_mode), +you should define at least one "seed" node in the cluster in this case. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. +- *signaling*. +- *clusterer*, if the cluster_id +module parameter is set and clustering support activated. + + +#### External Libraries or Applications + + +- *libxml-dev*. + + +### Exported Parameters + + +#### db_url(str) + + +The database url. + + +If set, the module is a fully operational +presence server. Otherwise, it is used as a 'library', for +its exported functions. + + +*Default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("presence", "db_url", + "mysql://opensips:opensipsrw@192.168.2.132/opensips") +... +``` + + +#### fallback2db (int) + + +Setting this parameter enables a fallback to db mode of operation. +In this mode, in case a searched record is not found in cache, +the search is continued in database. Useful for an architecture in +which processing and memory load might be divided on more machines +using the same database. + + +```opensips title="Set fallback2db parameter" +... +modparam("presence", "fallback2db", 1) +... +``` + + +#### cluster_id (int) + + +The ID of the cluster this presence server belongs to. This parameter +is to be used only if clustering mode is needed. In order to +understand th concept of a cluster ID, please see the +*clusterer* module. + + +This OpenSIPS cluster exposes the **"presence"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +For more on presence clustering see the +[presence clustering](#presence_clustering) chapter. + + +*Default value is "None".* + + +```opensips title="Set cluster_id parameter" +... +modparam("presence", "cluster_id", 2) +... +``` + + +#### cluster_federation_mode (str) + + +When enabling the federation mode, nodes inside the presence +cluster will start broadcasting the data to other nodes via the +clustering support. + + +*Possible values:* + + +- *disabled* - federation mode is disabled +- *on-demand-sharing* - the minimum needed information is +kept on each node. Replicated information for non local +subscribers is discarded and queries are broadcasted +in the cluster for new subscribers. +- *full-sharing* - published state is kept on all presence +nodes even when there aren't any local subscribers. + + +If you don't want to use a shared database (via +[fallback2db](#param_fallback2db)), but still want a +complete data set everywhere, you may choose mode *full-sharing*. +This mode allows you to switch PUBLISH endpoints, +even for already published Event States, thus allowing +you to add and remove presence servers without losing +state. + + +For more on presence clustering see the +[presence clustering](#presence_clustering) chapter. + + +*Default value is "disabled".* + + +```opensips title="Set cluster_federation_mode parameter" +... +modparam("presence", "cluster_federation_mode", "full-sharing") +... +``` + + +#### cluster_pres_events (str) + + +Comma Separated Value (CSV) list with the events to considered by the +federated cluster - only presentities advertising one of these events +will be broadcasted via the cluster. + + +For more on presence clustering see the +[presence clustering](#presence_clustering) chapter. + + +*Default value is "empty" (meaning all).* + + +```opensips title="Set cluster_pres_events parameter" +... +modparam("presence", "cluster_pres_events" ,"presence, dialog;sla, message-summary") +... +``` + + +#### cluster_be_active_shtag (str) + + +The name of a cluster sharing tag to be used to indicate when this +node (as part of the cluster) should be active or not. If the sharing +tag is off (or as backup), the node will become inactive from +clustering perspective, meaning not sending and not accepting any +presence related cluster traffic. + + +This ability of a node to become inactive may be used when creating a +federated cluster where 2 nodes are acting as a local active-backup +setup (for local High Availability purposes). + + +This parameter has meaning only in clustering mode. If not defined, the +node will be active all the time. + + +For more on presence clustering see the +[presence clustering](#presence_clustering) chapter. + + +*Default value is "empty" (not tag define).* + + +```opensips title="Set cluster_be_active_shtag parameter" +... +modparam("presence", "cluster_be_active_shtag" ,"local_ha") +... +``` + + +#### expires_offset (int) + + +The extra time to store a subscription/publication. + + +*Default value is "0".* + + +```opensips title="Set expires_offset parameter" +... +modparam("presence", "expires_offset", 10) +... +``` + + +#### max_expires_subscribe (int) + + +The the maximum admissible expires value for SUBSCRIBE +messages. + + +*Default value is "3600".* + + +```opensips title="Set max_expires_subscribe parameter" +... +modparam("presence", "max_expires_subscribe", 3600) +... +``` + + +#### max_expires_publish (int) + + +The the maximum admissible expires value for PUBLISH +messages. + + +*Default value is "3600".* + + +```opensips title="Set max_expires_publish parameter" +... +modparam("presence", "max_expires_publish", 3600) +... +``` + + +#### contact_user (str) + + +This is the username that will be used in the Contact header for the 200 OK +replies to SUBSCRIBE and in the following in-dialog NOTIFY requests. +The IP address, port and transport for the Contact will be automatically +determined based on the interface where the SUBSCRIBE was received. + + +If set to an empty string, no username will be added to the contact and +the contact will be built just out of the IP, port and transport. + + +*Default value is "presence".* + + +```opensips title="Set contact_user parameter" +... +modparam("presence", "contact_user", "presence") +... + +``` + + +#### enable_sphere_check (int) + + +This parameter is a flag that should be set if permission rules +include sphere checking. The sphere information is expected to be +present in the RPID body published by the presentity. The flag is +introduced as this check requires extra processing that should be +avoided if this feature is not supported by the clients. + + +*Default value is "0 ".* + + +```opensips title="Set enable_sphere_check parameter" +... +modparam("presence", "enable_sphere_check", 1) +... + +``` + + +#### waiting_subs_daysno (int) + + +The number of days to keep the record of a subscription in server +database if the subscription is in pending or waiting state +(no authorization policy was defined for it or the target user +did not register sice the subscription and was not informed about +it). + + +*Default value is "3" days. Maximum accepted +value is 30 days.* + + +```opensips title="Set waiting_subs_daysno parameter" +... +modparam("presence", "waiting_subs_daysno", 2) +... + +``` + + +#### mix_dialog_presence (int) + + +This module parameter enables a very nice feature in the presence +server - generating presence information from dialogs state. If this +parameter is set, the presence server will tell you if a buddy is in +a call even if his phone did not send a presence Publish with this +information. You will need to load the dialoginfo modules, +presence_dialoginfo, pua_dialoginfo, dialog and pua. + + +*Default value is "0".* + + +```opensips title="Set mix_dialog_presence parameter" +... +modparam("presence", "mix_dialog_presence", 1) +... + +``` + + +#### bla_presentity_spec (str) + + +By default the presentity uri for BLA subscribes (event=dialog;sla) +is computed from contact username + from domain. In some cases +though, this way of computing the presentity might not be right +(for example if you have a SBC in front that masquerades the +contact). So we added this parameter that allows defining a custom +uri to be used as presentity uri for BLA subscribes. You should +set this parameter to the name of a pseudovariable and then set +this pseudovariable to the desired URI before calling the +[handle subscribe](#func_handle_subscribe) function. + + +*Default value is "NULL".* + + +```opensips title="Set bla_presentity_spec parameter" +... +modparam("presence", "bla_presentity_spec", "$var(bla_pres)") +... + +``` + + +#### bla_fix_remote_target (int) + + +Polycom has a bug in the bla implementation. It inserts the +remote IP contact in the Notify body and when a phone picks up a +call put on hold by another phone in the same BLA group, it sends +an Invite directly to the remote IP. OpenSIPS BLA server tries to +prevent this by replacing the IP contact with the +domain, when this is possible. + + +In some cases(configurations) however this is not desirable, so +this parameter was introduced to disable this behaviour when +needed. + + +*Default value is "1".* + + +```opensips title="Set bla_fix_remote_target parameter" +... +modparam("presence", "bla_fix_remote_target", 0) +... + +``` + + +#### notify_offline_body (int) + + +If this parameter is set, when no published info is found for +a user, the presence server will generate a dummy body with status +'closed' and use it when sending Notify, instead of notifying with +no body. + + +*Default value is "0".* + + +```opensips title="Set notify_offline_body parameter" +... +modparam("presence", "notify_offline_body", 1) +... + +``` + + +#### end_sub_on_timeout (int) + + +If a presence subscription should be automatically terminated +(destroyed) when receiving a SIP timeout (408) for a sent +NOTIFY requests. + + +*Default value is "1" (enabled).* + + +```opensips title="Set end_sub_on_timeout parameter" +... +modparam("presence", "end_sub_on_timeout", 0) +... + +``` + + +#### clean_period (int) + + +The period at which to clean the expired subscription dialogs. + + +*Default value is "100". A zero or negative +value disables this activity.* + + +```opensips title="Set clean_period parameter" +... +modparam("presence", "clean_period", 100) +... +``` + + +#### db_update_period (int) + + +The period at which to synchronize cached subscriber info with the +database. + + +*Default value is "100". A zero or negative +value disables synchronization.* + + +```opensips title="Set db_update_period parameter" +... +modparam("presence", "db_update_period", 100) +... +``` + + +#### presentity_table(str) + + +The name of the db table where Publish information are stored. + + +*Default value is "presentity".* + + +```opensips title="Set presentity_table parameter" +... +modparam("presence", "presentity_table", "presentity") +... +``` + + +#### active_watchers_table(str) + + +The name of the db table where active subscription information are +stored. + + +*Default value is "active_watchers".* + + +```opensips title="Set active_watchers_table parameter" +... +modparam("presence", "active_watchers_table", "active_watchers") +... +``` + + +#### watchers_table(str) + + +The name of the db table where subscription states are stored. + + +*Default value is "watchers".* + + +```opensips title="Set watchers_table parameter" +... +modparam("presence", "watchers_table", "watchers") +... +``` + + +#### subs_htable_size (int) + + +The size of the hash table to store subscription dialogs. +This parameter will be used as the power of 2 when computing table size. + + +*Default value is "9 (512)".* + + +```opensips title="Set subs_htable_size parameter" +... +modparam("presence", "subs_htable_size", 11) +... + +``` + + +#### pres_htable_size (int) + + +The size of the hash table to store publish records. +This parameter will be used as the power of 2 when computing table size. + + +*Default value is "9 (512)".* + + +```opensips title="Set pres_htable_size parameter" +... +modparam("presence", "pres_htable_size", 11) +... + +``` + + +### Exported Functions + + +#### handle_publish([sender_uri]) + + +The function handles PUBLISH requests. It stores and updates +published information in database and calls functions to send +NOTIFY messages when changes in the published information occur. + + +It may takes one optional string argument, the 'sender_uri' SIP URI. +The parameter was added +for enabling BLA implementation. If present, Notification of +a change in published state is not sent to the respective uri +even though a subscription exists. +It should be taken from the Sender header. It was left at the +decision of the administrator whether or not to transmit the +content of this header as parameter for handle_publish, to +prevent security problems. + + +This function can be used from REQUEST_ROUTE. + + +*Return code:* + + +- *1 - if success*. +- *-1 - if error*. + + +The module sends an appropriate stateless reply +in all cases. + + +```opensips title="handle_publish usage" +... + if(is_method("PUBLISH")) + { + if($hdr(Sender)!= NULL) + handle_publish($hdr(Sender)); + else + handle_publish(); + } +... +``` + + +#### handle_subscribe([force_active] [,sharing_tag]) + + +This function is to be used for handling SUBSCRIBE requests. It stores +or updates the watcher/subscriber information in database. +Additionally, in response to initial SUBSCRIBE requests (creating a +new subscription session), the function also sends back the NOTIFY +(with the presence information) to the wathcer/subscriber. + + +The function may take the following parameters: + + +- *force_active* (int, optional) - optional parameter that +controls what is the default policy (of the presentity) on +accepting new subscriptions (accept or reject) - of course, +this parameter makes sense only when using a presence +configuration with privacy rules enabled (force_active +parameter in presence_xml module is not set). +There are scenarios where the presentity (the party you +subscribe to) can not upload an XCAP document with its +privacy rules (to control which watchers are allowed to +subscribe to it). In such cases, from script level, you can +force the presence server to consider the current subscription +allowed (with Subscription-Status:active) by calling the +handle_subscribe() function with the integer parameter "1". +- *sharing_tag* (string, optional) - optional parameter telling +the owner tag (for the subscription) in clusetering scenarios +where the subscription data is shared between multiple +servers - see the [presence clustering](#presence_clustering) +chapter for more details. + + +```opensips + Ex: + if($ru =~ "kphone@opensips.org") + handle_subscribe(1); + +``` + + +This function can be used from REQUEST_ROUTE. + + +*Return code:* + + +- *1 - if success*. +- *-1 - if error*. + + +The module sends an appropriate stateless reply +in all cases. + + +```opensips title="handle_subscribe usage" +... +if($rm=="SUBSCRIBE") + handle_subscribe(); +... +``` + + +### Exported MI Functions + + +#### refresh_watchers + + +Triggers sending Notify messages to watchers if a change in watchers +authorization or in published state occurred. + + +Name: *refresh_watchers* + + +Parameters: + + +- presentity_uri : the uri of the user who made the change +and whose watchers should be informed +- event : the event package +- refresh type : it distinguishes between the two different types of events +that can trigger a refresh: + - a change in watchers authentication: refresh type= 0 ; + - a statical update in published state (either through direct + update in db table or by modifying the pidf manipulation document, + if pidf_manipulation parameter is set): refresh type!= 0. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi refresh_watchers sip:11@192.168.2.132 presence 1 +``` + + +#### cleanup + + +Manually triggers the cleanup functions for watchers and presentity tables. Useful if you +have set `clean_period` to zero or less. + + +Name: *cleanup* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi cleanup +``` + + +#### pres_phtable_list + + +Lists all the presentity records. + + +Name: *pres_phtable_list* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi pres_phtable_list +``` + + +#### subs_phtable_list + + +Lists all the subscription records, or the subscriptions for which the "To" and "From" URIs match the given parameters. + + +Name: *subs_phtable_list* + + +Parameters + + +- *from*(optional) - wildcard for "From" URI +- *to*(optional) - wildcard for "To" URI + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi subs_phtable_list sip:222@domain2.com sip:user_1@example.com +``` + + +#### pres_expose + + +Exposes in the script, by rasing an +*E_PRESENCE_EXPOSED* event, all the +presentities of a specific event that match a specified +filter. + + +Name: *pres_expose* + + +Parameters: + + +- *event* - the desired presence +event. +- *filter*(optional) - a regular +expression (REGEXP) used for filtering the presentities +for that event. Only the presentities that match will +be exposed. If not specified, all presentities for that +event are exposed. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi pres_expose presence ^sip:10\.0\.5\.[0-9]* +``` + + +### Exported Events + + +#### E_PRESENCE_PUBLISH + + +This event is raised when the presence module receives +a PUBLISH message. + + +Parameters: +- *user* - the AOR of the user +- *domain* - the domain +- *event* - the type of the +event published +- *expires* - the expire value +of the publish +- *etag* - the entity tag +- *old_etag* - the entity tag to be refreshed +- *body* - the body of the +PUBLISH request + + +#### E_PRESENCE_EXPOSED + + +This event is raised for each presentity exposeed +by the *pres_expose*. + + +Parameters: + + +Same parameters as the +*E_PRESENCE_PUBLISH* event. + + +### Installation + + +The module requires 3 table in OpenSIPS database: presentity, +active_watchers and watchers tables. The SQL +syntax to create them can be found in presence-create.sql +script in the database directories in the opensips/scripts folder. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +## Developer Guide + + +The module provides the following functions that can be used +in other OpenSIPS modules. + + +### bind_presence(presence_api_t* api) + + +This function binds the presence modules and fills the structure +with the exported functions that represent functions adding events +in presence module and functions specific for Subscribe processing. + + +```c title="presence_api_t structure" +... +typedef struct presence_api { + add_event_t add_event; + contains_event_t contains_event; + search_event_t search_event; + get_event_list_t get_event_list; + + update_watchers_t update_watchers_status; + + /* subs hash table handling functions */ + new_shtable_t new_shtable; + destroy_shtable_t destroy_shtable; + insert_shtable_t insert_shtable; + search_shtable_t search_shtable; + delete_shtable_t delete_shtable; + update_shtable_t update_shtable; + /* function to duplicate a subs structure*/ + mem_copy_subs_t mem_copy_subs; + /* function used for update in database*/ + update_db_subs_t update_db_subs; + /* function to extract dialog information from a + SUBSCRIBE message */ + extract_sdialog_info_t extract_sdialog_info; + /* function to request sphere defition for a presentity */ + pres_get_sphere_t get_sphere; + pres_contains_presence_t contains_presence; +}presence_api_t; +... +``` + + +### add_event + + +Field type: + + +```c +... +typedef int (*add_event_t)(pres_ev_t* event); +... +``` + + +This function receives as a parameter a structure with event specific +information and adds it to presence event list. + + +The structure received as a parameter: + + +```c +... +typedef struct pres_ev +{ + str name; + event_t* evp; + str content_type; + int default_expires; + int type; + int etag_not_new; + /* + * 0 - the standard mechanism (allocating new etag + for each Publish) + * 1 - allocating an etag only + for an initial Publish + */ + int req_auth; + get_rules_doc_t* get_rules_doc; + apply_auth_t* apply_auth_nbody; + is_allowed_t* get_auth_status; + + /* an agg_body_t function should be registered + * if the event permits having multiple published + * states and requires an aggregation of the information + * otherwise, this field should be NULL and the last + * published state is taken when constructing Notify msg + */ + agg_nbody_t* agg_nbody; + publ_handling_t * evs_publ_handl; + subs_handling_t * evs_subs_handl; + free_body_t* free_body; + + /* sometimes it is necessary that a module make changes for a body for each + * active watcher (e.g. setting the "version" parameter in an XML document. + * If a module registers the aux_body_processing callback, it gets called for + * each watcher. It either gets the body received by the PUBLISH, or the body + * generated by the agg_nbody function. + * The module can deceide if it makes a copy of the original body, which is then + * manipulated, or if it works directly in the original body. If the module makes a + * copy of the original body, it also has to register the aux_free_body() to + * free this "per watcher" body. + */ + aux_body_processing_t* aux_body_processing; + free_body_t* aux_free_body; + + struct pres_ev* wipeer; + struct pres_ev* next; + +}pres_ev_t; +... +``` + + +### get_rules_doc + + +Filed type: + + +```c +... +typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc); +... + +``` + + +This function returns the authorization rules document that will be +used in obtaining the status of the subscription and processing the +notified body. A reference to the document should be put in the +auth_rules_doc of the subs_t structure given as a parameter to the +functions described bellow. + + +### get_auth_status + + +This filed is a function to be called for a subscription request +to return the state for that subscription according to +authorization rules. In the auth_rules_doc field of the subs_t +structure received as a parameter should contain the rules +document of the presentity in case, if it exists. + + +It is called only if the req_auth field is not 0. + + +Filed type: + + +```c +... +typedef int (is_allowed_t)(struct subscription* subs); +... + +``` + + +### apply_auth_nbody + + +This parameter should be a function to be called for an event +that requires authorization, when constructing final body. +The authorization document is taken from the auth_rules_doc +field of the subs_t structure given as a parameter. +It is called only if the req_auth field is not 0. + + +Filed type: + + +```c +... +typedef int (apply_auth_t)(str* , struct subscription*, str** ); +... + +``` + + +### agg_nbody + + +If present, this field marks that the events requires aggregation +of states. This function receives a body array and should return +the final body. If not present, it is considered that the event +does not require aggregation and the most recent published +information is used when constructing Notifies. + + +Filed type: + + +```c +... +typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain, +str** body_array, int n, int off_index); +.. + +``` + + +### free_body + + +This field must be field in if subsequent processing is performed +on the info from database before being inserted in Notify +message body(if agg_nbody or apply_auth_nbody fields are +filled in). It should match the allocation function used when +processing the body. + + +Filed type: + + +```c +... +typedef void(free_body_t)(char* body); +.. + +``` + + +### aux_body_processing + + +This field must be set if the module needs to manipulate the NOTIFY body +for each watcher. E.g. if the XML body includes a 'version' parameter which +will be increased for each NOTIFY, on a "per watcher" basis. +The module can either allocate a new buffer for the new body an return it (aux_free_body +function must be set too) or it manipualtes the original body directly and returns NULL. + + +Filed type: + + +```c +... +typedef str* (aux_body_processing_t)(struct subscription *subs, str* body); +.. + +``` + + +### aux_free_body + + +This field must be set if the module registers the aux_body_processing function +and allocates memory for the new modified body. Then, this function will be used +to free the pointer returned by the aux_body_processing function. +If the module does use the aux_body_processing, but does not allocate new memory, but +manipulates directly the original body buffer, then the aux_body_processing +must return NULL and this field should not be set. + + +Filed type: + + +```c +... +typedef void(free_body_t)(char* body); +.. + +``` + + +### evs_publ_handl + + +This function is called when handling Publish requests. Most contain +body correctness check. + + +```c +... +typedef int (publ_handling_t)(struct sip_msg*); +.. + +``` + + +### evs_subs_handl + + +It is not compulsory. Should contain event specific handling for +Subscription requests. + + +Field type: + + +```c +... +typedef int (subs_handling_t)(struct sip_msg*); +.. +``` + + +### contains_event + + +Field type: + + +```c +.. +typedef pres_ev_t* (*contains_event_t)(str* name, +event_t* parsed_event); +... +``` + + +The function parses the event name received as a parameter and searches +the result in the list. It returns the found event or NULL, if not found. +If the second argument is an allocated event_t* structure it fills it +with the result of the parsing. + + +### get_event_list + + +Field type: + + +```c +... +typedef int (*get_event_list_t) (str** ev_list); +... +``` + + +This function returns a string representation of the events registered +in presence module.( used for Allowed-Events header). + + +### update_watchers_status + + +Field type: + + +```c +... +typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev, +str* rules_doc); +... +``` + + +This function is an external command that can be used to announce a change +in authorization rules for a presentity. It updates the stored status and +sends a Notify to the watchers whose status has changes. (used by +presence_xml module when notified through an MI command of a change in +an xcap document). + + +### get_sphere + + +Field type: + + +```c +... +typedef char* (*pres_get_sphere_t)(str* pres_uri); +... +``` + + +This function searches for a sphere definition in the published information +if this has type RPID. If not found returns NULL. (the return value is +allocated in private memory and should be freed) + + +### contains_presence + + +Field type: + + +```c +... +typedef int (*pres_contains_presence_t)(str* pres_uri); +... +``` + + +This function searches is a presence uri has published any presence +information. It return 1 if a record is found, -1 otherwise. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence/doc/contributors.xml b/modules/presence/doc/contributors.xml deleted file mode 100644 index 26baefdc884..00000000000 --- a/modules/presence/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 659 - 247 - 24146 - 12623 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 155 - 96 - 3231 - 1846 - - - 3. - Razvan Crainea (@razvancrainea) - 35 - 28 - 423 - 163 - - - 4. - Liviu Chircu (@liviuchircu) - 35 - 25 - 287 - 397 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 33 - 19 - 631 - 481 - - - 6. - Ovidiu Sas (@ovidiusas) - 29 - 20 - 618 - 170 - - - 7. - Daniel-Constantin Mierla (@miconda) - 24 - 19 - 174 - 165 - - - 8. - Dan Pascu (@danpascu) - 20 - 14 - 162 - 201 - - - 9. - Henning Westerholt (@henningw) - 14 - 6 - 340 - 302 - - - 10. - Walter Doekes (@wdoekes) - 11 - 7 - 150 - 105 - - - -
-All remaining contributors: Saúl Ibarra Corretgé (@saghul), Maksym Sobolyev (@sobomax), Vlad Paiu (@vladpaiu), Juha Heinanen (@juha-h), Edson Gellert Schubert, Alexandra Titoc, Stanislaw Pitucha, Damien Sandras (@dsandras), Kobi Eshun (@ekobi), Carsten Bock, Norman Brandinger (@NormB), Dusan Klinec (@ph4r05), Angel Marin, Klaus Darilion, Carlos Oliva, Sergio Gutierrez, Kennard White, Elena-Ramona Modroiu, Jasper Hafkenscheid, Vasil Kolev, Benny Prijono, James Criscuolo, Peter Lemenkov (@lemenkov), Vallimamod Abdullah, UnixDev, Denis Bilenko, Julián Moreno Patiño, John Riordan, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - Nov 2025 - - - 2. - Norman Brandinger (@NormB) - May 2024 - Nov 2024 - - - 3. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 4. - Carsten Bock - Mar 2024 - Mar 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2022 - - - 7. - Jasper Hafkenscheid - Jul 2022 - Jul 2022 - - - 8. - Razvan Crainea (@razvancrainea) - Sep 2011 - Jun 2021 - - - 9. - Walter Doekes (@wdoekes) - Apr 2010 - Apr 2021 - - - 10. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu), Peter Lemenkov (@lemenkov), James Criscuolo, Julián Moreno Patiño, Dusan Klinec (@ph4r05), Carlos Oliva, Damien Sandras (@dsandras), Vlad Paiu (@vladpaiu), Saúl Ibarra Corretgé (@saghul), Anca Vamanu, Vallimamod Abdullah, Kennard White, Stanislaw Pitucha, Angel Marin, John Riordan, Vasil Kolev, UnixDev, Sergio Gutierrez, Kobi Eshun (@ekobi), Klaus Darilion, Denis Bilenko, Henning Westerholt (@henningw), Juha Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Julien Blache, Benny Prijono, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Jasper Hafkenscheid, Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Walter Doekes (@wdoekes), Dan Pascu (@danpascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Saúl Ibarra Corretgé (@saghul), Anca Vamanu, Kennard White, Angel Marin, Kobi Eshun (@ekobi), Klaus Darilion, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Juha Heinanen (@juha-h), Elena-Ramona Modroiu. -
- -
diff --git a/modules/presence/doc/presence.xml b/modules/presence/doc/presence.xml deleted file mode 100644 index c95bad2c244..00000000000 --- a/modules/presence/doc/presence.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - Presence Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - - - diff --git a/modules/presence/doc/presence_admin.xml b/modules/presence/doc/presence_admin.xml deleted file mode 100644 index 958913a3a2b..00000000000 --- a/modules/presence/doc/presence_admin.xml +++ /dev/null @@ -1,1070 +0,0 @@ - - - - &adminguide; - -
- Overview - The modules handles PUBLISH and SUBSCRIBE messages and generates - NOTIFY messages in a general, event independent way. It allows registering - events from other &osips; modules. Events that can currently be added are: - - - presence, presence.winfo, - dialog;sla from presence_xml module - - - message-summary from presence_mwi module - - - call-info, line-seize from - presence_callinfo module - - - dialog from presence_dialoginfo module - - - xcap-diff from presence_xcapdiff module - - - as-feature-event from presence_dfks module - - - - - The module uses database storage. - It has later been improved with memory caching operations to improve - performance. The Subscribe dialog information are stored in memory and - are periodically updated in database, while for Publish only the presence - or absence of stored info for a certain resource is maintained in memory - to avoid unnecessary, costly db operations. - It is possible to configure a fallback to database mode(by setting module - parameter "fallback2db"). In this mode, in case a searched record is not - found in cache, the search is continued in database. This is useful for - an architecture in which processing and memory load might be divided on - more machines using the same database. - - The module can also work only with the functionality of a library, - with no message processing and generation, but used only for the exported - functions. - This mode of operation is enabled if the db_url parameter is not set to any value. - - - The server follows the specifications in: RFC3265, RFC3856, RFC3857, - RFC3858. - -
- -
- Presence clustering - - To read and understand the presence clustering, its abilities and how to - implement scenarios like High-Availability, Load Balancing or Federations, - please refer to this article https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/. - - - As data synchronization at startup is performed when using the - full-sharing , - you should define at least one "seed" node in the cluster in this case. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module. - - - - - signaling. - - - - - clusterer, if the cluster_id - module parameter is set and clustering support activated. - - - - - -
- -
- External Libraries or Applications - - - - libxml-dev. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname>(str) - - The database url. - - If set, the module is a fully operational - presence server. Otherwise, it is used as a 'library', for - its exported functions. - - - Default value is NULL. - - - - Set <varname>db_url</varname> parameter - -... -modparam("presence", "db_url", - "mysql://opensips:opensipsrw@192.168.2.132/opensips") -... - - -
- -
- <varname>fallback2db</varname> (int) - - Setting this parameter enables a fallback to db mode of operation. - In this mode, in case a searched record is not found in cache, - the search is continued in database. Useful for an architecture in - which processing and memory load might be divided on more machines - using the same database. - - - Set <varname>fallback2db</varname> parameter - -... -modparam("presence", "fallback2db", 1) -... - - -
- -
- <varname>cluster_id</varname> (int) - - The ID of the cluster this presence server belongs to. This parameter - is to be used only if clustering mode is needed. In order to - understand th concept of a cluster ID, please see the - clusterer module. - - - &clusterer_sync_cap_para; - - - For more on presence clustering see the - chapter. - - - Default value is None. - - - - Set <varname>cluster_id</varname> parameter - -... -modparam("presence", "cluster_id", 2) -... - - -
- -
- <varname>cluster_federation_mode</varname> (str) - - When enabling the federation mode, nodes inside the presence - cluster will start broadcasting the data to other nodes via the - clustering support. - - - Possible values: - - - - disabled - federation mode is disabled - - - - - on-demand-sharing - the minimum needed information is - kept on each node. Replicated information for non local - subscribers is discarded and queries are broadcasted - in the cluster for new subscribers. - - - - - full-sharing - published state is kept on all presence - nodes even when there aren't any local subscribers. - - - - - - If you don't want to use a shared database (via - ), but still want a - complete data set everywhere, you may choose mode full-sharing. - This mode allows you to switch PUBLISH endpoints, - even for already published Event States, thus allowing - you to add and remove presence servers without losing - state. - - - For more on presence clustering see the - chapter. - - - Default value is disabled. - - - - Set <varname>cluster_federation_mode</varname> parameter - -... -modparam("presence", "cluster_federation_mode", "full-sharing") -... - - -
- -
- <varname>cluster_pres_events</varname> (str) - - Comma Separated Value (CSV) list with the events to considered by the - federated cluster - only presentities advertising one of these events - will be broadcasted via the cluster. - - - For more on presence clustering see the - chapter. - - - Default value is empty (meaning all). - - - - Set <varname>cluster_pres_events</varname> parameter - -... -modparam("presence", "cluster_pres_events" ,"presence, dialog;sla, message-summary") -... - - -
- -
- <varname>cluster_be_active_shtag</varname> (str) - - The name of a cluster sharing tag to be used to indicate when this - node (as part of the cluster) should be active or not. If the sharing - tag is off (or as backup), the node will become inactive from - clustering perspective, meaning not sending and not accepting any - presence related cluster traffic. - - - This ability of a node to become inactive may be used when creating a - federated cluster where 2 nodes are acting as a local active-backup - setup (for local High Availability purposes). - - - This parameter has meaning only in clustering mode. If not defined, the - node will be active all the time. - - - For more on presence clustering see the - chapter. - - - Default value is empty (not tag define). - - - - Set <varname>cluster_be_active_shtag</varname> parameter - -... -modparam("presence", "cluster_be_active_shtag" ,"local_ha") -... - - -
- - - -
- <varname>expires_offset</varname> (int) - - The extra time to store a subscription/publication. - - - Default value is 0. - - - - Set <varname>expires_offset</varname> parameter - -... -modparam("presence", "expires_offset", 10) -... - - - -
-
- <varname>max_expires_subscribe</varname> (int) - - The the maximum admissible expires value for SUBSCRIBE - messages. - - - Default value is 3600. - - - - Set <varname>max_expires_subscribe</varname> parameter - -... -modparam("presence", "max_expires_subscribe", 3600) -... - - -
- -
- <varname>max_expires_publish</varname> (int) - - The the maximum admissible expires value for PUBLISH - messages. - - - Default value is 3600. - - - - Set <varname>max_expires_publish</varname> parameter - -... -modparam("presence", "max_expires_publish", 3600) -... - - -
- - -
- <varname>contact_user</varname> (str) - - This is the username that will be used in the Contact header for the 200 OK - replies to SUBSCRIBE and in the following in-dialog NOTIFY requests. - The IP address, port and transport for the Contact will be automatically - determined based on the interface where the SUBSCRIBE was received. - - - If set to an empty string, no username will be added to the contact and - the contact will be built just out of the IP, port and transport. - - - Default value is presence. - - - Set <varname>contact_user</varname> parameter - -... -modparam("presence", "contact_user", "presence") -... - - -
- -
- <varname>enable_sphere_check</varname> (int) - - This parameter is a flag that should be set if permission rules - include sphere checking. The sphere information is expected to be - present in the RPID body published by the presentity. The flag is - introduced as this check requires extra processing that should be - avoided if this feature is not supported by the clients. - - - Default value is 0 . - - - - Set <varname>enable_sphere_check</varname> parameter - -... -modparam("presence", "enable_sphere_check", 1) -... - - -
- -
- <varname>waiting_subs_daysno</varname> (int) - - The number of days to keep the record of a subscription in server - database if the subscription is in pending or waiting state - (no authorization policy was defined for it or the target user - did not register sice the subscription and was not informed about - it). - - - Default value is 3 days. Maximum accepted - value is 30 days. - - - - Set <varname>waiting_subs_daysno</varname> parameter - -... -modparam("presence", "waiting_subs_daysno", 2) -... - - -
-
- <varname>mix_dialog_presence</varname> (int) - - This module parameter enables a very nice feature in the presence - server - generating presence information from dialogs state. If this - parameter is set, the presence server will tell you if a buddy is in - a call even if his phone did not send a presence Publish with this - information. You will need to load the dialoginfo modules, - presence_dialoginfo, pua_dialoginfo, dialog and pua. - - - Default value is 0. - - - - Set <varname>mix_dialog_presence</varname> parameter - -... -modparam("presence", "mix_dialog_presence", 1) -... - - -
-
- <varname>bla_presentity_spec</varname> (str) - - By default the presentity uri for BLA subscribes (event=dialog;sla) - is computed from contact username + from domain. In some cases - though, this way of computing the presentity might not be right - (for example if you have a SBC in front that masquerades the - contact). So we added this parameter that allows defining a custom - uri to be used as presentity uri for BLA subscribes. You should - set this parameter to the name of a pseudovariable and then set - this pseudovariable to the desired URI before calling the - function. - - - Default value is NULL. - - - - Set <varname>bla_presentity_spec</varname> parameter - -... -modparam("presence", "bla_presentity_spec", "$var(bla_pres)") -... - - -
- -
- <varname>bla_fix_remote_target</varname> (int) - - Polycom has a bug in the bla implementation. It inserts the - remote IP contact in the Notify body and when a phone picks up a - call put on hold by another phone in the same BLA group, it sends - an Invite directly to the remote IP. OpenSIPS BLA server tries to - prevent this by replacing the IP contact with the - domain, when this is possible. - - - In some cases(configurations) however this is not desirable, so - this parameter was introduced to disable this behaviour when - needed. - - - Default value is 1. - - - - Set <varname>bla_fix_remote_target</varname> parameter - -... -modparam("presence", "bla_fix_remote_target", 0) -... - - -
- - -
- <varname>notify_offline_body</varname> (int) - - If this parameter is set, when no published info is found for - a user, the presence server will generate a dummy body with status - 'closed' and use it when sending Notify, instead of notifying with - no body. - - - Default value is 0. - - - - Set <varname>notify_offline_body</varname> parameter - -... -modparam("presence", "notify_offline_body", 1) -... - - -
- -
- <varname>end_sub_on_timeout</varname> (int) - - If a presence subscription should be automatically terminated - (destroyed) when receiving a SIP timeout (408) for a sent - NOTIFY requests. - - - Default value is 1 (enabled). - - - - Set <varname>end_sub_on_timeout</varname> parameter - -... -modparam("presence", "end_sub_on_timeout", 0) -... - - -
- -
- <varname>clean_period</varname> (int) - - The period at which to clean the expired subscription dialogs. - - - Default value is 100. A zero or negative - value disables this activity. - - - - Set <varname>clean_period</varname> parameter - -... -modparam("presence", "clean_period", 100) -... - - -
- -
- <varname>db_update_period</varname> (int) - - The period at which to synchronize cached subscriber info with the - database. - - - Default value is 100. A zero or negative - value disables synchronization. - - - - Set <varname>db_update_period</varname> parameter - -... -modparam("presence", "db_update_period", 100) -... - - -
- -
- <varname>presentity_table</varname>(str) - - The name of the db table where Publish information are stored. - - - Default value is presentity. - - - - Set <varname>presentity_table</varname> parameter - -... -modparam("presence", "presentity_table", "presentity") -... - - -
- -
- <varname>active_watchers_table</varname>(str) - - The name of the db table where active subscription information are - stored. - - - Default value is active_watchers. - - - - Set <varname>active_watchers_table</varname> parameter - -... -modparam("presence", "active_watchers_table", "active_watchers") -... - - -
- -
- <varname>watchers_table</varname>(str) - - The name of the db table where subscription states are stored. - - - Default value is watchers. - - - - Set <varname>watchers_table</varname> parameter - -... -modparam("presence", "watchers_table", "watchers") -... - - -
- -
- <varname>subs_htable_size</varname> (int) - - The size of the hash table to store subscription dialogs. - This parameter will be used as the power of 2 when computing table size. - - - Default value is 9 (512). - - - - Set <varname>subs_htable_size</varname> parameter - -... -modparam("presence", "subs_htable_size", 11) -... - - -
- -
- <varname>pres_htable_size</varname> (int) - - The size of the hash table to store publish records. - This parameter will be used as the power of 2 when computing table size. - - - Default value is 9 (512). - - - - Set <varname>pres_htable_size</varname> parameter - -... -modparam("presence", "pres_htable_size", 11) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">handle_publish([sender_uri])</function> - - - The function handles PUBLISH requests. It stores and updates - published information in database and calls functions to send - NOTIFY messages when changes in the published information occur. - - - It may takes one optional string argument, the 'sender_uri' SIP URI. - The parameter was added - for enabling BLA implementation. If present, Notification of - a change in published state is not sent to the respective uri - even though a subscription exists. - It should be taken from the Sender header. It was left at the - decision of the administrator whether or not to transmit the - content of this header as parameter for handle_publish, to - prevent security problems. - - - This function can be used from REQUEST_ROUTE. - - - Return code: - - - - 1 - if success. - - - - - -1 - if error. - - - - - - The module sends an appropriate stateless reply - in all cases. - - - - <function>handle_publish</function> usage - -... - if(is_method("PUBLISH")) - { - if($hdr(Sender)!= NULL) - handle_publish($hdr(Sender)); - else - handle_publish(); - } -... - - -
- -
- - <function moreinfo="none">handle_subscribe([force_active] [,sharing_tag])</function> - - - This function is to be used for handling SUBSCRIBE requests. It stores - or updates the watcher/subscriber information in database. - Additionally, in response to initial SUBSCRIBE requests (creating a - new subscription session), the function also sends back the NOTIFY - (with the presence information) to the wathcer/subscriber. - - - The function may take the following parameters: - - - - - force_active (int, optional) - optional parameter that - controls what is the default policy (of the presentity) on - accepting new subscriptions (accept or reject) - of course, - this parameter makes sense only when using a presence - configuration with privacy rules enabled (force_active - parameter in presence_xml module is not set). - - - There are scenarios where the presentity (the party you - subscribe to) can not upload an XCAP document with its - privacy rules (to control which watchers are allowed to - subscribe to it). In such cases, from script level, you can - force the presence server to consider the current subscription - allowed (with Subscription-Status:active) by calling the - handle_subscribe() function with the integer parameter "1". - - - - - sharing_tag (string, optional) - optional parameter telling - the owner tag (for the subscription) in clusetering scenarios - where the subscription data is shared between multiple - servers - see the - chapter for more details. - - - - - Ex: - if($ru =~ "kphone@opensips.org") - handle_subscribe(1); - - - This function can be used from REQUEST_ROUTE. - - - Return code: - - - - 1 - if success. - - - - - -1 - if error. - - - - - - The module sends an appropriate stateless reply - in all cases. - - - - <function>handle_subscribe</function> usage - -... -if($rm=="SUBSCRIBE") - handle_subscribe(); -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">refresh_watchers</function> - - - Triggers sending Notify messages to watchers if a change in watchers - authorization or in published state occurred. - - - Name: refresh_watchers - - Parameters: - - - presentity_uri : the uri of the user who made the change - and whose watchers should be informed - - - event : the event package - - - refresh type : it distinguishes between the two different types of events - that can trigger a refresh: - - - - a change in watchers authentication: refresh type= 0 ; - - - - - a statical update in published state (either through direct - update in db table or by modifying the pidf manipulation document, - if pidf_manipulation parameter is set): refresh type!= 0. - - - - - - - - - MI FIFO Command Format: - - -opensips-cli -x mi refresh_watchers sip:11@192.168.2.132 presence 1 - -
- -
- - <function moreinfo="none">cleanup</function> - - - Manually triggers the cleanup functions for watchers and presentity tables. Useful if you - have set clean_period to zero or less. - - - Name: cleanup - - Parameters: none - - - MI FIFO Command Format: - - -opensips-cli -x mi cleanup - -
- -
- - <function moreinfo="none">pres_phtable_list</function> - - - Lists all the presentity records. - - - Name: pres_phtable_list - - Parameters: none - - - MI FIFO Command Format: - - -opensips-cli -x mi pres_phtable_list - -
- -
- - <function moreinfo="none">subs_phtable_list</function> - - - Lists all the subscription records, or the subscriptions for which the "To" and "From" URIs match the given parameters. - - - Name: subs_phtable_list - - Parameters - - - from(optional) - wildcard for "From" URI - - - to(optional) - wildcard for "To" URI - - - - MI FIFO Command Format: - - -opensips-cli -x mi subs_phtable_list sip:222@domain2.com sip:user_1@example.com - -
- -
- - <function moreinfo="none">pres_expose</function> - - - Exposes in the script, by rasing an - E_PRESENCE_EXPOSED event, all the - presentities of a specific event that match a specified - filter. - - - Name: pres_expose - - Parameters: - - - event - the desired presence - event. - - - filter(optional) - a regular - expression (REGEXP) used for filtering the presentities - for that event. Only the presentities that match will - be exposed. If not specified, all presentities for that - event are exposed. - - - - - MI FIFO Command Format: - - -opensips-cli -x mi pres_expose presence ^sip:10\.0\.5\.[0-9]* - -
-
- - -
- Exported Events -
- - <function moreinfo="none">E_PRESENCE_PUBLISH</function> - - - This event is raised when the presence module receives - a PUBLISH message. - - Parameters: - - - user - the AOR of the user - - - domain - the domain - - - event - the type of the - event published - - - expires - the expire value - of the publish - - - etag - the entity tag - - - old_etag - the entity tag to be refreshed - - - body - the body of the - PUBLISH request - - -
-
- - <function moreinfo="none">E_PRESENCE_EXPOSED</function> - - - This event is raised for each presentity exposeed - by the pres_expose. - - Parameters: - Same parameters as the - E_PRESENCE_PUBLISH event. -
-
- -
- Installation - - The module requires 3 table in OpenSIPS database: presentity, - active_watchers and watchers tables. The SQL - syntax to create them can be found in presence-create.sql - script in the database directories in the opensips/scripts folder. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- -
- diff --git a/modules/presence/doc/presence_devel.xml b/modules/presence/doc/presence_devel.xml deleted file mode 100644 index 2537c48e5d9..00000000000 --- a/modules/presence/doc/presence_devel.xml +++ /dev/null @@ -1,414 +0,0 @@ - - - - &develguide; - - The module provides the following functions that can be used - in other &osips; modules. - -
- - <function moreinfo="none">bind_presence(presence_api_t* api)</function> - - - This function binds the presence modules and fills the structure - with the exported functions that represent functions adding events - in presence module and functions specific for Subscribe processing. - - - <function>presence_api_t</function> structure - -... -typedef struct presence_api { - add_event_t add_event; - contains_event_t contains_event; - search_event_t search_event; - get_event_list_t get_event_list; - - update_watchers_t update_watchers_status; - - /* subs hash table handling functions */ - new_shtable_t new_shtable; - destroy_shtable_t destroy_shtable; - insert_shtable_t insert_shtable; - search_shtable_t search_shtable; - delete_shtable_t delete_shtable; - update_shtable_t update_shtable; - /* function to duplicate a subs structure*/ - mem_copy_subs_t mem_copy_subs; - /* function used for update in database*/ - update_db_subs_t update_db_subs; - /* function to extract dialog information from a - SUBSCRIBE message */ - extract_sdialog_info_t extract_sdialog_info; - /* function to request sphere defition for a presentity */ - pres_get_sphere_t get_sphere; - pres_contains_presence_t contains_presence; -}presence_api_t; -... - - - -
- -
- - <function moreinfo="none">add_event</function> - - - Field type: - - -... -typedef int (*add_event_t)(pres_ev_t* event); -... - - - This function receives as a parameter a structure with event specific - information and adds it to presence event list. - - - The structure received as a parameter: - - -... -typedef struct pres_ev -{ - str name; - event_t* evp; - str content_type; - int default_expires; - int type; - int etag_not_new; - /* - * 0 - the standard mechanism (allocating new etag - for each Publish) - * 1 - allocating an etag only - for an initial Publish - */ - int req_auth; - get_rules_doc_t* get_rules_doc; - apply_auth_t* apply_auth_nbody; - is_allowed_t* get_auth_status; - - /* an agg_body_t function should be registered - * if the event permits having multiple published - * states and requires an aggregation of the information - * otherwise, this field should be NULL and the last - * published state is taken when constructing Notify msg - */ - agg_nbody_t* agg_nbody; - publ_handling_t * evs_publ_handl; - subs_handling_t * evs_subs_handl; - free_body_t* free_body; - - /* sometimes it is necessary that a module make changes for a body for each - * active watcher (e.g. setting the "version" parameter in an XML document. - * If a module registers the aux_body_processing callback, it gets called for - * each watcher. It either gets the body received by the PUBLISH, or the body - * generated by the agg_nbody function. - * The module can deceide if it makes a copy of the original body, which is then - * manipulated, or if it works directly in the original body. If the module makes a - * copy of the original body, it also has to register the aux_free_body() to - * free this "per watcher" body. - */ - aux_body_processing_t* aux_body_processing; - free_body_t* aux_free_body; - - struct pres_ev* wipeer; - struct pres_ev* next; - -}pres_ev_t; -... - -
-
- - <function moreinfo="none">get_rules_doc</function> - - - - - - Filed type: - -... -typedef int (get_rules_doc_t)(str* user, str* domain, str** rules_doc); -... - - - - This function returns the authorization rules document that will be - used in obtaining the status of the subscription and processing the - notified body. A reference to the document should be put in the - auth_rules_doc of the subs_t structure given as a parameter to the - functions described bellow. - -
- -
- - <function moreinfo="none">get_auth_status</function> - - - This filed is a function to be called for a subscription request - to return the state for that subscription according to - authorization rules. In the auth_rules_doc field of the subs_t - structure received as a parameter should contain the rules - document of the presentity in case, if it exists. - - - It is called only if the req_auth field is not 0. - - - Filed type: - -... -typedef int (is_allowed_t)(struct subscription* subs); -... - - -
- -
- - <function moreinfo="none">apply_auth_nbody</function> - - - This parameter should be a function to be called for an event - that requires authorization, when constructing final body. - The authorization document is taken from the auth_rules_doc - field of the subs_t structure given as a parameter. - It is called only if the req_auth field is not 0. - - - Filed type: - -... -typedef int (apply_auth_t)(str* , struct subscription*, str** ); -... - - -
- -
- - <function moreinfo="none">agg_nbody</function> - - - If present, this field marks that the events requires aggregation - of states. This function receives a body array and should return - the final body. If not present, it is considered that the event - does not require aggregation and the most recent published - information is used when constructing Notifies. - - - Filed type: - -... -typedef str* (agg_nbody_t)(str* pres_user, str* pres_domain, -str** body_array, int n, int off_index); -.. - - -
- -
- - <function moreinfo="none">free_body</function> - - - This field must be field in if subsequent processing is performed - on the info from database before being inserted in Notify - message body(if agg_nbody or apply_auth_nbody fields are - filled in). It should match the allocation function used when - processing the body. - - - Filed type: - -... -typedef void(free_body_t)(char* body); -.. - - -
- -
- - <function moreinfo="none">aux_body_processing</function> - - - This field must be set if the module needs to manipulate the NOTIFY body - for each watcher. E.g. if the XML body includes a 'version' parameter which - will be increased for each NOTIFY, on a "per watcher" basis. - The module can either allocate a new buffer for the new body an return it (aux_free_body - function must be set too) or it manipualtes the original body directly and returns NULL. - - - Filed type: - -... -typedef str* (aux_body_processing_t)(struct subscription *subs, str* body); -.. - - -
- -
- - <function moreinfo="none">aux_free_body</function> - - - This field must be set if the module registers the aux_body_processing function - and allocates memory for the new modified body. Then, this function will be used - to free the pointer returned by the aux_body_processing function. - If the module does use the aux_body_processing, but does not allocate new memory, but - manipulates directly the original body buffer, then the aux_body_processing - must return NULL and this field should not be set. - - - Filed type: - -... -typedef void(free_body_t)(char* body); -.. - - -
- -
- - <function moreinfo="none">evs_publ_handl</function> - - - This function is called when handling Publish requests. Most contain - body correctness check. - - - -... -typedef int (publ_handling_t)(struct sip_msg*); -.. - - -
- -
- - <function moreinfo="none">evs_subs_handl</function> - - - It is not compulsory. Should contain event specific handling for - Subscription requests. - - - Filed type: - - -... -typedef int (subs_handling_t)(struct sip_msg*); -.. - -
- -
- - <function moreinfo="none">contains_event</function> - - - Field type: - - -.. -typedef pres_ev_t* (*contains_event_t)(str* name, -event_t* parsed_event); -... - - - The function parses the event name received as a parameter and searches - the result in the list. It returns the found event or NULL, if not found. - If the second argument is an allocated event_t* structure it fills it - with the result of the parsing. - -
- -
- - <function moreinfo="none">get_event_list</function> - - - Field type: - - -... -typedef int (*get_event_list_t) (str** ev_list); -... - - - This function returns a string representation of the events registered - in presence module.( used for Allowed-Events header). - -
- -
- - <function moreinfo="none">update_watchers_status</function> - - - Field type: - - -... -typedef int (*update_watchers_t)(str pres_uri, pres_ev_t* ev, -str* rules_doc); -... - - - This function is an external command that can be used to announce a change - in authorization rules for a presentity. It updates the stored status and - sends a Notify to the watchers whose status has changes. (used by - presence_xml module when notified through an MI command of a change in - an xcap document). - -
- -
- - <function moreinfo="none">get_sphere</function> - - - Field type: - - -... -typedef char* (*pres_get_sphere_t)(str* pres_uri); -... - - - This function searches for a sphere definition in the published information - if this has type RPID. If not found returns NULL. (the return value is - allocated in private memory and should be freed) - -
- -
- - <function moreinfo="none">contains_presence</function> - - - Field type: - - -... -typedef int (*pres_contains_presence_t)(str* pres_uri); -... - - - This function searches is a presence uri has published any presence - information. It return 1 if a record is found, -1 otherwise. - -
- -
- diff --git a/modules/presence/notify.c b/modules/presence/notify.c index 601db3cec3b..eb8e90a9871 100644 --- a/modules/presence/notify.c +++ b/modules/presence/notify.c @@ -2336,7 +2336,6 @@ str* create_winfo_xml(watcher_t* watchers, char* version, xmlDocPtr doc = NULL; xmlNodePtr root_node = NULL, node = NULL; xmlNodePtr w_list_node = NULL; - char content[200]; str *body= NULL; char* buffer= NULL; watcher_t* w; @@ -2397,15 +2396,13 @@ str* create_winfo_xml(watcher_t* watchers, char* version, w= watchers->next; while(w) { - strncpy( content,w->uri.s, w->uri.len); - content[ w->uri.len ]='\0'; - node = xmlNewChild(w_list_node, NULL, BAD_CAST "watcher", - BAD_CAST content) ; + node = xmlNewChild(w_list_node, NULL, BAD_CAST "watcher", NULL) ; if( node ==NULL) { LM_ERR("while adding child\n"); goto error; } + xmlNodeSetContentLen(node, BAD_CAST w->uri.s, w->uri.len); if(xmlNewProp(node, BAD_CAST "id", BAD_CAST w->id.s)== NULL) { LM_ERR("while adding new attribute\n"); @@ -2439,8 +2436,6 @@ str* create_winfo_xml(watcher_t* watchers, char* version, xmlCleanupParser(); - xmlMemoryDump(); - return body; error: diff --git a/modules/presence/presence.c b/modules/presence/presence.c index 20987b9012f..04ba012810b 100644 --- a/modules/presence/presence.c +++ b/modules/presence/presence.c @@ -848,7 +848,7 @@ static mi_response_t *mi_list_shtable(const mi_params_t *params, str *from, str mi_response_t *resp; mi_item_t *resp_arr; subs_t *s; - unsigned int i,j; + unsigned int i; char from_w[256], to_w[256]; str match_from = {0,0}, match_to = {0,0}; int rc; @@ -869,7 +869,7 @@ static mi_response_t *mi_list_shtable(const mi_params_t *params, str *from, str to_w[to->len] = 0; } - for (i = 0, j = 0; i < shtable_size; i++) { + for (i = 0; i < shtable_size; i++) { lock_get(&subs_htable[i].lock); for (s = subs_htable[i].entries->next; s; s = s->next) { @@ -884,7 +884,6 @@ static mi_response_t *mi_list_shtable(const mi_params_t *params, str *from, str if (mi_print_shtable_record(resp_arr, s) < 0) goto error; - j++; } lock_release(&subs_htable[i].lock); } diff --git a/modules/presence/presentity.c b/modules/presence/presentity.c index 40c339ab082..02afd73216a 100644 --- a/modules/presence/presentity.c +++ b/modules/presence/presentity.c @@ -351,7 +351,6 @@ int get_dialog_state(str body, int *dialog_state) xmlFree(state); xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); if(i == DLG_STATES_NO) { @@ -1610,7 +1609,6 @@ str* xml_dialog_gen_presence(str* pres_uri, int dlg_state) if(pres_doc) xmlFreeDoc(pres_doc); xmlCleanupParser(); - xmlMemoryDump(); return dialog_body; } @@ -1655,7 +1653,6 @@ str* xml_dialog2presence(str* pres_uri, str* body) xmlFree(state); xmlFreeDoc(dlg_doc); xmlCleanupParser(); - xmlMemoryDump(); if(i == DLG_STATES_NO) { @@ -1752,8 +1749,6 @@ str* build_offline_presence(str* pres_uri) if(pres_doc) xmlFreeDoc(pres_doc); xmlCleanupParser(); - xmlMemoryDump(); return body; } - diff --git a/modules/presence/publish.c b/modules/presence/publish.c index 04756be8f67..d662590e71a 100644 --- a/modules/presence/publish.c +++ b/modules/presence/publish.c @@ -421,6 +421,7 @@ int handle_publish(struct sip_msg* msg, str* sender_uri) int reply_code; str reply_str; int sent_reply= 0; + int content_type; char* sphere= NULL; reply_code= 400; @@ -544,10 +545,18 @@ int handle_publish(struct sip_msg* msg, str* sender_uri) goto error; } - if(sphere_enable && event->evp->parsed == EVENT_PRESENCE && - get_content_type(msg)== SUBTYPE_PIDFXML) - { - sphere= extract_sphere(body); + if(sphere_enable && event->evp->parsed == EVENT_PRESENCE) { + content_type = parse_content_type_hdr(msg); + if (content_type < 0) { + LM_ERR("cannot parse content type\n"); + goto error; + } + if (content_type == 0) { + LM_ERR("Content-Type header not found\n"); + goto error; + } + if(content_type == (TYPE_APPLICATION << 16 | SUBTYPE_PIDFXML)) + sphere= extract_sphere(body); } } } diff --git a/modules/presence_callinfo/README b/modules/presence_callinfo/README deleted file mode 100644 index aef35342373..00000000000 --- a/modules/presence_callinfo/README +++ /dev/null @@ -1,358 +0,0 @@ -Presence_CallInfo Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Usage modes - - 1.2.1. External publishing - 1.2.2. Internal publishing - - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. call_info_timeout_notification (int) - 1.4.2. line_seize_timeout_notification (int) - 1.4.3. disable_dialog_support_for_sca (int) - 1.4.4. line_hash_size (int) - - 1.5. Exported Functions - - 1.5.1. sca_set_calling_line([line]) - 1.5.2. sca_set_called_line([line]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set call_info_timeout_notification parameter - 1.2. Set line_seize_timeout_notification parameter - 1.3. Set disable_dialog_support_for_sca parameter - 1.4. Set line_hash_size parameter - 1.5. sca_set_calling_line() usage - 1.6. sca_set_called_line() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides OpenSIPS support for shared call - appearances (SCA) as defined by BroadWorks SIP Access Side - Extensions Interface specifications. The SCA mechanism is a - fundamental building block for a variety of enhanced telephony - services. Features like attendant console, line extensions, and - key system emulation cannot be delivered without some mechanism - for sharing call appearances across access devices. Although - SIP (RFC 3261) by itself offers no inherent semantics for - supporting SCA features, when coupled with an appropriate - instantiation of the “SIP Specific Event Notification” - framework (RFC 3265), these services can be deployed quite - easily in a distributed network. - - A shared line is an address of record managed by central - controlling element, such as an application server. The - application server allows multiple endpoints to register - locations against the address of record. The application server - is responsible for policing who can register and who cannot - register against the shared line. - - The module enables the handling of "call-info" and "line-seize" - events inside the presence module. It is used with the general - event handling module: presence and it constructs and adds - "Call-Info" headers to notification events. - -1.2. Usage modes - - The module can be used in two ways (depending on who is doing - the publishing of the "call-info" data: - * external publishing - the "call-info" data is received from - a third party via SIP PUBLISH requests. In this mode, the - modules simply distributes the SCA info, it is not - producing any of it - a third-party application must - publish "call-info" events to the presence server. - * internal publishing - the "call-info" data is internally - generated by the module, based on the information received - from the dialog module - what calls are using what - line/index, what is the state of the call, etc. There is no - SIP PUBLISH in this case and there is no need for a - third-party - the module is self-sufficient and stand alone - as functionality. - - The used mode can be controlled via the module parameter - "disable_dialog_support_for_sca" - see below in the parameter's - section. - -1.2.1. External publishing - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by a - third-party application and subscribe requests only by - subscriber to call-info and line-seize events. Authorization - can thus be easily done by OpenSIPS configuration file before - calling handle_publish() and handle_subscribe() functions. - - To get better understanding on how the module works please take - a look at the follwing figure: - - caller proxy & callee watcher publisher -alice@example presence bob@example watcher@example - server - | | | | | - | |<-----SUBSCRIBE bob----| | - | |------200 OK---------->| | - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | - |--INV bob--->| | | | - | |--INV bob->| | | - | |<-100------| | | - | |<-----PUBLISH(alerting)---------------| - | |------200 OK------------------------->| - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | - | |<-180 ring-| | | - |<--180 ring--| | | | - | | | | | - | | | | | - | |<-200 OK---| | | - |<--200 OK----| | | | - | |<-----PUBLISH(active)-----------------| - | |------200 OK------------------------->| - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | - - - * The watcher subscribes the "Event: dialog" of Bob. - * Alice calls Bob. - * The publisher is publishing the "alerting" state for Bob. - * PUBLISH is received and handled by presence module. - Presence module updates the "presentity". Presence module - checks for active watchers of the presentity. The active - watcher is notified via a NOTIFY SIP request. - * Bob answers the call. - * The publisher is publishing the "active" state for Bob. - * PUBLISH is received and handled by presence module. - Presence module updates the "presentity". Presence module - checks for active watchers of the presentity. The active - watcher is notified via a NOTIFY SIP request. - -1.2.2. Internal publishing - - In this mode, the module requires the "dialog" module to be - loaded into OpenSIPS. All the publishing will be automatically - done (the modules will exchange data directly via C API). - - From presence perspective, the OpenSIPS script must be - configured to handle the SUBSCRIBE requests only (there is no - need for PUBLISH handling as there is no SIP publishing in this - mode). So be sure to use the "handle_subscribe()" function - (from presence module) in the script. - - To trigger the internal publishing (from the dialog module) for - a certain call, use the "sca_set_calling_line()" or - "sca_set_called_line()" functions from the script when handling - a new call. These functions will do all the work (creating - dialog, setting the internal publishing, etc) - you just need - to use them and eventually specify the name of the line (if - other then the one from the SIP INVITE) - see the below - documentation. - - LIMITATIONS : in this mode, the module does not really check if - the line exists or not (like defined) - it blindly trust the - traffic; also there is no check on how many indexes are for - each line. Such information (lines and indexes) are not - provisioned into the module, but the module will dynamically - accept and handle any line and index based on the SIP traffic. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - * dialog. - -1.3.2. External Libraries or Applications - - None. - -1.4. Exported Parameters - -1.4.1. call_info_timeout_notification (int) - - Enables or disables call_info event timeout notifications. - - Default value is “1” (enabled). - - Example 1.1. Set call_info_timeout_notification parameter -... -modparam("presence_callinfo", "call_info_timeout_notification", 0) -... - -1.4.2. line_seize_timeout_notification (int) - - Enables or disables line_seize event timeout notifications. - - Default value is “0” (disabled). - - Example 1.2. Set line_seize_timeout_notification parameter -... -modparam("presence_callinfo", "line_seize_timeout_notification", 1) -... - -1.4.3. disable_dialog_support_for_sca (int) - - Disables the internal publishing of the "call-info" events - (generated by the dialog module). The publishing is expected to - be done via SIP PUBLISH from a third-party. See the wroking - mode described in the beginning of this document. - - Default value is “0” (not disabled). - - Example 1.3. Set disable_dialog_support_for_sca parameter -... -modparam("presence_callinfo", "disable_dialog_support_for_sca", 1) -... - -1.4.4. line_hash_size (int) - - Allows you to controll the size of the internal hash table used - for storing the information about the lines and indexes (in the - internal publishing mode). - - The value must be a power of 2. You may consider increasing the - value if using a large set of lines (>1000). - - Default value is “64”. - - Example 1.4. Set line_hash_size parameter -... -modparam("presence_callinfo", "line_hash_size", 128) -... - -1.5. Exported Functions - -1.5.1. sca_set_calling_line([line]) - - The function (to be used only in internal publishing mode) is - setting for the current new call (initinal INVITE) the outbound - line - the line used for calling out. - - If no parameter is provided, the name of the line is taken from - the SIP FROM header of the INVITE. You can override that by - providing the name of the line as a string parameter - be - careful as the value must be a SIP URI ! - - This function can be used from REQUEST_ROUTE. - - Example 1.5. sca_set_calling_line() usage -... - if (is_method("INVITE") and !has_totag()) { - sca_set_calling_line(); - } -... - -1.5.2. sca_set_called_line([line]) - - The function (to be used only in internal publishing mode) is - setting for the current new call (initinal INVITE) the inbound - line - the line the call was received on. - - If no parameter is provided, the name of the line is taken from - the SIP RURI of the INVITE. You can override that by providing - the name of the line as a string parameter - be careful as the - value must be a SIP URI ! Variables are accepted. - - This function can be used from REQUEST_ROUTE. - - Example 1.6. sca_set_called_line() usage -... - if (is_method("INVITE") and !has_totag()) { - sca_set_called_line(); - } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 21 8 1409 60 - 2. Ovidiu Sas (@ovidiusas) 12 6 577 7 - 3. Razvan Crainea (@razvancrainea) 10 8 22 14 - 4. Liviu Chircu (@liviuchircu) 9 7 42 52 - 5. Vlad Patrascu (@rvlad-patrascu) 7 4 45 67 - 6. Maksym Sobolyev (@sobomax) 6 4 5 6 - 7. Walter Doekes (@wdoekes) 3 1 2 2 - 8. Alexandra Titoc 3 1 1 1 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Alexandra Titoc Sep 2024 - Sep 2024 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2013 - Apr 2024 - 3. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 4. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 5. Razvan Crainea (@razvancrainea) Oct 2011 - Sep 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Liviu Chircu (@liviuchircu) Mar 2014 - Jun 2018 - 8. Walter Doekes (@wdoekes) Mar 2014 - Mar 2014 - 9. Ovidiu Sas (@ovidiusas) Dec 2010 - Mar 2011 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Ovidiu Sas (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2010-2013 VoIP Embedded, Inc. diff --git a/modules/presence_callinfo/README.md b/modules/presence_callinfo/README.md new file mode 100644 index 00000000000..9b5ac2bf5ea --- /dev/null +++ b/modules/presence_callinfo/README.md @@ -0,0 +1,312 @@ +--- +title: "Presence_CallInfo Module" +description: "This module provides OpenSIPS support for shared call appearances (SCA) as defined by BroadWorks SIP Access Side Extensions Interface specifications." +--- + +## Admin Guide + + +### Overview + + +This module provides OpenSIPS support for shared call appearances (SCA) +as defined by BroadWorks SIP Access Side Extensions Interface specifications. +The SCA mechanism is a fundamental building block for a variety of enhanced +telephony services. Features like attendant console, line extensions, +and key system emulation cannot be delivered without some mechanism for +sharing call appearances across access devices. Although SIP (RFC 3261) +by itself offers no inherent semantics for supporting SCA features, when +coupled with an appropriate instantiation of the “SIP Specific Event Notification” +framework (RFC 3265), these services can be deployed quite easily in a +distributed network. + + +A shared line is an address of record managed by central +controlling element, such as an application server. The application server +allows multiple endpoints to register locations against the address of record. +The application server is responsible for policing who can register and who +cannot register against the shared line. + + +The module enables the handling of "call-info" and "line-seize" +events inside the presence module. It is used with the general event +handling module: presence and it constructs and adds "Call-Info" headers +to notification events. + + +### Usage modes + + +The module can be used in two ways (depending on who is doing the +publishing of the "call-info" data: + + +- external publishing - the "call-info" data +is received from a third party via SIP PUBLISH requests. In this +mode, the modules simply distributes the SCA info, it is not +producing any of it - a third-party application must publish +"call-info" events to the presence server. +- internal publishing - the "call-info" data +is internally generated by the module, based on the information +received from the dialog module - what calls are using what +line/index, what is the state of the call, etc. There is no SIP +PUBLISH in this case and there is no need for a third-party - +the module is self-sufficient and stand alone as functionality. + + +The used mode can be controlled via the module parameter +"disable_dialog_support_for_sca" - see below in the parameter's +section. + + +#### External publishing + + +The module does not currently implement any authorization +rules. It assumes that publish requests are only issued by +a third-party application and subscribe requests only by +subscriber to call-info and line-seize events. Authorization +can thus be easily done by OpenSIPS configuration file before +calling handle_publish() and handle_subscribe() functions. + + +To get better understanding on how the module works please take a +look at the follwing figure: + + +```c + caller proxy & callee watcher publisher +alice@example presence bob@example watcher@example + server + | | | | | + | |<-----SUBSCRIBE bob----| | + | |------200 OK---------->| | + | |------NOTIFY---------->| | + | |<-----200 OK-----------| | + | | | | | + |--INV bob--->| | | | + | |--INV bob->| | | + | |<-100------| | | + | |<-----PUBLISH(alerting)---------------| + | |------200 OK------------------------->| + | |------NOTIFY---------->| | + | |<-----200 OK-----------| | + | | | | | + | |<-180 ring-| | | + |<--180 ring--| | | | + | | | | | + | | | | | + | |<-200 OK---| | | + |<--200 OK----| | | | + | |<-----PUBLISH(active)-----------------| + | |------200 OK------------------------->| + | |------NOTIFY---------->| | + | |<-----200 OK-----------| | + | | | | | + + +``` + + +- The watcher subscribes the "Event: dialog" of Bob. +- Alice calls Bob. +- The publisher is publishing the "alerting" state for Bob. +- PUBLISH is received and handled by presence module. +Presence module updates the "presentity". +Presence module checks for active watchers of the presentity. +The active watcher is notified via a NOTIFY SIP request. +- Bob answers the call. +- The publisher is publishing the "active" state for Bob. +- PUBLISH is received and handled by presence module. +Presence module updates the "presentity". +Presence module checks for active watchers of the presentity. +The active watcher is notified via a NOTIFY SIP request. + + +#### Internal publishing + + +In this mode, the module requires the "dialog" module to be +loaded into OpenSIPS. All the publishing will be automatically +done (the modules will exchange data directly via C API). + + +From presence perspective, the OpenSIPS script must be configured +to handle the SUBSCRIBE requests only (there is no need for PUBLISH +handling as there is no SIP publishing in this mode). So be sure +to use the "handle_subscribe()" function (from presence module) in +the script. + + +To trigger the internal publishing (from the dialog module) for a +certain call, use the "sca_set_calling_line()" or +"sca_set_called_line()" functions from the script when handling a +new call. These functions will do all the work (creating dialog, +setting the internal publishing, etc) - you just need to use them +and eventually specify the name of the line (if other then the one +from the SIP INVITE) - see the below documentation. + + +LIMITATIONS : in this mode, the module does not really check if the +line exists or not (like defined) - it blindly trust the traffic; +also there is no check on how many indexes are for each line. Such +information (lines and indexes) are not provisioned into the module, +but the module will dynamically accept and handle any line and index +based on the SIP traffic. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. +- *dialog*. + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### call_info_timeout_notification (int) + + +Enables or disables call_info event timeout notifications. + + +*Default value is "1"* (enabled). + + +```opensips title="Set call_info_timeout_notification parameter" +... +modparam("presence_callinfo", "call_info_timeout_notification", 0) +... + +``` + + +#### line_seize_timeout_notification (int) + + +Enables or disables line_seize event timeout notifications. + + +*Default value is "0"* (disabled). + + +```opensips title="Set line_seize_timeout_notification parameter" +... +modparam("presence_callinfo", "line_seize_timeout_notification", 1) +... + +``` + + +#### disable_dialog_support_for_sca (int) + + +Disables the internal publishing of the "call-info" events (generated by the dialog module). +The publishing is expected to be done via SIP PUBLISH from a third-party. See +the wroking mode described in the beginning of this document. + + +*Default value is "0"* (not disabled). + + +```opensips title="Set disable_dialog_support_for_sca parameter" +... +modparam("presence_callinfo", "disable_dialog_support_for_sca", 1) +... + +``` + + +#### line_hash_size (int) + + +Allows you to controll the size of the internal hash table used for storing the +information about the lines and indexes (in the internal publishing mode). + + +The value must be a power of 2. You may consider increasing the value if using +a large set of lines (>1000). + + +*Default value is "64"*. + + +```opensips title="Set line_hash_size parameter" +... +modparam("presence_callinfo", "line_hash_size", 128) +... + +``` + + +### Exported Functions + + +#### sca_set_calling_line([line]) + + +The function (to be used only in internal publishing mode) is setting +for the current new call (initinal INVITE) the outbound line - the line +used for calling out. + + +If no parameter is provided, the name of the line is taken from the +SIP FROM header of the INVITE. You can override that by providing +the name of the line as a string parameter - be careful as the value must be +a SIP URI ! + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="sca_set_calling_line() usage" +... + if (is_method("INVITE") and !has_totag()) { + sca_set_calling_line(); + } +... +``` + + +#### sca_set_called_line([line]) + + +The function (to be used only in internal publishing mode) is setting +for the current new call (initinal INVITE) the inbound line - the line +the call was received on. + + +If no parameter is provided, the name of the line is taken from the +SIP RURI of the INVITE. You can override that by providing +the name of the line as a string parameter - be careful as the value must be +a SIP URI ! Variables are accepted. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="sca_set_called_line() usage" +... + if (is_method("INVITE") and !has_totag()) { + sca_set_called_line(); + } +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_callinfo/doc/contributors.xml b/modules/presence_callinfo/doc/contributors.xml deleted file mode 100644 index 868a2a54d67..00000000000 --- a/modules/presence_callinfo/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 21 - 8 - 1409 - 60 - - - 2. - Ovidiu Sas (@ovidiusas) - 12 - 6 - 577 - 7 - - - 3. - Razvan Crainea (@razvancrainea) - 10 - 8 - 22 - 14 - - - 4. - Liviu Chircu (@liviuchircu) - 9 - 7 - 42 - 52 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 7 - 4 - 45 - 67 - - - 6. - Maksym Sobolyev (@sobomax) - 6 - 4 - 5 - 6 - - - 7. - Walter Doekes (@wdoekes) - 3 - 1 - 2 - 2 - - - 8. - Alexandra Titoc - 3 - 1 - 1 - 1 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2013 - Apr 2024 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Oct 2011 - Sep 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jun 2018 - - - 8. - Walter Doekes (@wdoekes) - Mar 2014 - Mar 2014 - - - 9. - Ovidiu Sas (@ovidiusas) - Dec 2010 - Mar 2011 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/presence_callinfo/doc/presence_callinfo.xml b/modules/presence_callinfo/doc/presence_callinfo.xml deleted file mode 100644 index 7d7340a77f7..00000000000 --- a/modules/presence_callinfo/doc/presence_callinfo.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Presence_CallInfo Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2010-2013 VoIP Embedded, Inc. - diff --git a/modules/presence_callinfo/doc/presence_callinfo_admin.xml b/modules/presence_callinfo/doc/presence_callinfo_admin.xml deleted file mode 100644 index 9673d80d34b..00000000000 --- a/modules/presence_callinfo/doc/presence_callinfo_admin.xml +++ /dev/null @@ -1,344 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - This module provides OpenSIPS support for shared call appearances (SCA) - as defined by BroadWorks SIP Access Side Extensions Interface specifications. - The SCA mechanism is a fundamental building block for a variety of enhanced - telephony services. Features like attendant console, line extensions, - and key system emulation cannot be delivered without some mechanism for - sharing call appearances across access devices. Although SIP (RFC 3261) - by itself offers no inherent semantics for supporting SCA features, when - coupled with an appropriate instantiation of the “SIP Specific Event Notification” - framework (RFC 3265), these services can be deployed quite easily in a - distributed network. - - - A shared line is an address of record managed by central - controlling element, such as an application server. The application server - allows multiple endpoints to register locations against the address of record. - The application server is responsible for policing who can register and who - cannot register against the shared line. - - - The module enables the handling of "call-info" and "line-seize" - events inside the presence module. It is used with the general event - handling module: presence and it constructs and adds "Call-Info" headers - to notification events. - -
- -
- Usage modes - - The module can be used in two ways (depending on who is doing the - publishing of the "call-info" data: - - - external publishing - the "call-info" data - is received from a third party via SIP PUBLISH requests. In this - mode, the modules simply distributes the SCA info, it is not - producing any of it - a third-party application must publish - "call-info" events to the presence server. - - internal publishing - the "call-info" data - is internally generated by the module, based on the information - received from the dialog module - what calls are using what - line/index, what is the state of the call, etc. There is no SIP - PUBLISH in this case and there is no need for a third-party - - the module is self-sufficient and stand alone as functionality. - - - The used mode can be controlled via the module parameter - "disable_dialog_support_for_sca" - see below in the parameter's - section. - - -
- External publishing - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by - a third-party application and subscribe requests only by - subscriber to call-info and line-seize events. Authorization - can thus be easily done by &osips; configuration file before - calling handle_publish() and handle_subscribe() functions. - - - To get better understanding on how the module works please take a - look at the follwing figure: - -| | - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | - |--INV bob--->| | | | - | |--INV bob->| | | - | |<-100------| | | - | |<-----PUBLISH(alerting)---------------| - | |------200 OK------------------------->| - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | - | |<-180 ring-| | | - |<--180 ring--| | | | - | | | | | - | | | | | - | |<-200 OK---| | | - |<--200 OK----| | | | - | |<-----PUBLISH(active)-----------------| - | |------200 OK------------------------->| - | |------NOTIFY---------->| | - | |<-----200 OK-----------| | - | | | | | -]]> - - - - The watcher subscribes the "Event: dialog" of Bob. - - - Alice calls Bob. - - - The publisher is publishing the "alerting" state for Bob. - - - PUBLISH is received and handled by presence module. - Presence module updates the "presentity". - Presence module checks for active watchers of the presentity. - The active watcher is notified via a NOTIFY SIP request. - - - Bob answers the call. - - - The publisher is publishing the "active" state for Bob. - - - PUBLISH is received and handled by presence module. - Presence module updates the "presentity". - Presence module checks for active watchers of the presentity. - The active watcher is notified via a NOTIFY SIP request. - - - -
- -
- Internal publishing - - In this mode, the module requires the "dialog" module to be - loaded into OpenSIPS. All the publishing will be automatically - done (the modules will exchange data directly via C API). - - - From presence perspective, the OpenSIPS script must be configured - to handle the SUBSCRIBE requests only (there is no need for PUBLISH - handling as there is no SIP publishing in this mode). So be sure - to use the "handle_subscribe()" function (from presence module) in - the script. - - - To trigger the internal publishing (from the dialog module) for a - certain call, use the "sca_set_calling_line()" or - "sca_set_called_line()" functions from the script when handling a - new call. These functions will do all the work (creating dialog, - setting the internal publishing, etc) - you just need to use them - and eventually specify the name of the line (if other then the one - from the SIP INVITE) - see the below documentation. - - - LIMITATIONS : in this mode, the module does not really check if the - line exists or not (like defined) - it blindly trust the traffic; - also there is no check on how many indexes are for each line. Such - information (lines and indexes) are not provisioned into the module, - but the module will dynamically accept and handle any line and index - based on the SIP traffic. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - - dialog. - - - - -
- -
- External Libraries or Applications - - None. - -
-
- -
- Exported Parameters -
- <varname>call_info_timeout_notification</varname> (int) - - Enables or disables call_info event timeout notifications. - - Default value is 1 (enabled). - - Set <varname>call_info_timeout_notification</varname> parameter - -... -modparam("presence_callinfo", "call_info_timeout_notification", 0) -... - - -
- -
- <varname>line_seize_timeout_notification</varname> (int) - - Enables or disables line_seize event timeout notifications. - - Default value is 0 (disabled). - - Set <varname>line_seize_timeout_notification</varname> parameter - -... -modparam("presence_callinfo", "line_seize_timeout_notification", 1) -... - - -
- -
- <varname>disable_dialog_support_for_sca</varname> (int) - - Disables the internal publishing of the "call-info" events (generated by the dialog module). - The publishing is expected to be done via SIP PUBLISH from a third-party. See - the wroking mode described in the beginning of this document. - - Default value is 0 (not disabled). - - Set <varname>disable_dialog_support_for_sca</varname> parameter - -... -modparam("presence_callinfo", "disable_dialog_support_for_sca", 1) -... - - -
- -
- <varname>line_hash_size</varname> (int) - - Allows you to controll the size of the internal hash table used for storing the - information about the lines and indexes (in the internal publishing mode). - - - The value must be a power of 2. You may consider increasing the value if using - a large set of lines (>1000). - - Default value is 64. - - Set <varname>line_hash_size</varname> parameter - -... -modparam("presence_callinfo", "line_hash_size", 128) -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">sca_set_calling_line([line])</function> - - - The function (to be used only in internal publishing mode) is setting - for the current new call (initinal INVITE) the outbound line - the line - used for calling out. - - - If no parameter is provided, the name of the line is taken from the - SIP FROM header of the INVITE. You can override that by providing - the name of the line as a string parameter - be careful as the value must be - a SIP URI ! - - - This function can be used from REQUEST_ROUTE. - - - <function>sca_set_calling_line()</function> usage - -... - if (is_method("INVITE") and !has_totag()) { - sca_set_calling_line(); - } -... - - -
- -
- - <function moreinfo="none">sca_set_called_line([line])</function> - - - The function (to be used only in internal publishing mode) is setting - for the current new call (initinal INVITE) the inbound line - the line - the call was received on. - - - If no parameter is provided, the name of the line is taken from the - SIP RURI of the INVITE. You can override that by providing - the name of the line as a string parameter - be careful as the value must be - a SIP URI ! Variables are accepted. - - - This function can be used from REQUEST_ROUTE. - - - <function>sca_set_called_line()</function> usage - -... - if (is_method("INVITE") and !has_totag()) { - sca_set_called_line(); - } -... - - -
- -
- -
- diff --git a/modules/presence_dfks/README b/modules/presence_dfks/README deleted file mode 100644 index c5332c9c7aa..00000000000 --- a/modules/presence_dfks/README +++ /dev/null @@ -1,262 +0,0 @@ -presence_dfks Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. get_route (string) - 1.3.2. set_route (string) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. dfks_set_feature - - 1.6. Exported Pseudo-Variables - - 1.6.1. $dfks(field) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set parameter - 1.2. Set parameter - 1.3. dfks usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module enables the handling of the "as-feature-event" event - package (as defined by Broadsoft's Device Feature Key - Synchronization protocol) by the presence module. This can be - used to synchronize the status of features such as Do Not - Disturb and different forwarding types between a SIP phone and - a SIP server. - - The module supports synchronization for the following features: - Do Not Disturb, Call Forwarding Always, Call Forwarding Busy - and Call Forwarding No Answer. Feature status can be changed - either from the SIP phone or the OpenSIPS Server( by running an - MI command). - - When handling a SUBSCRIBE message without a body, the module - will run a script route for each feature, that will be used to - retrieve the current status of that feature. Conversely, a - SUBSCRIBE with a body will trigger a script route where the - updated status of a specific feature is available. This route - might also be run if the feature update was triggered from - OpenSIPS via MI. - - Note that the module does not automatically cache or persist - any feature information as this is left for the script writer - to implement in the routes triggered by the module. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - -1.2.2. External Libraries or Applications - - * libxml2-dev. - -1.3. Exported Parameters - -1.3.1. get_route (string) - - The name of the script route to be run in order to retrieve the - status of a feature. - - Default value is “dfks_get”. - - Example 1.1. Set parameter -... -modparam("presence_dfks", "get_route", "dfks_get") -... - -1.3.2. set_route (string) - - The name of the script route to be run when a feature status - update from a SIP phone is received. - - Default value is “dfks_get”. - - Example 1.2. Set parameter -... -modparam("presence_dfks", "set_route", "dfks_set") -... - -1.4. Exported Functions - - None. - -1.5. Exported MI Functions - -1.5.1. dfks_set_feature - - Triggers the sending of NOTIFY messages containing a feature - status update to all watchers. - - Note: calling this MI function also triggers the set_route run. - One can determine if the route is triggered by an MI function - by checking the existence of the $dfks(param) variable. - - Name: dfks_set_feature - - Parameters: - * presentity: the URI of the user whose feature status should - be updated - * feature: The name of the feature to update. Takes one of - the following values: - + DoNotDisturb - + CallForwardingAlways - + CallForwardingBusy - + CallForwardingNoAnswer - * status: the new status of the feature: 0 - disabled, 1 - - enabled - * route_param: optional string parameter passed to the - $dfks(param) variable in set_route. - * values: an array of extra values that can be updated for a - feature. The format of an array element is: field/value. - Supported fields are: - + forwardTo - for all forwarding types - + ringCount - for CallForwardingNoAnswer - - MI FIFO Command Format: -opensips-cli -x mi dfks_set_feature sip:alice@10.0.0.11 CallForwardingNo -Answer 1 1 \ -ringCount/4 forwardTo/sip:bob@10.0.0.11 - -1.6. Exported Pseudo-Variables - -1.6.1. $dfks(field) - - This pseudo-variable can be used in the routes triggered by the - module to handle the feature information through the following - subnames: - * assigned - inform the SIP phone that a feature is - unassigned by setting this to 0 (the NOTIFY response will - contain no XML data for the corresponding feature) By - default, features are assigned. - * notify - suppress the sending of the NOTIFY message by - setting this to 0. By default, the NOTIFY is sent. - * presentity - read-only, returns the current presentity URI. - * feature - read-only, returns the current feature name. - Possible values are: - + DoNotDisturb - + CallForwardingAlways - + CallForwardingBusy - + CallForwardingNoAnswer - * status - read or write the feature status. A value of 1 - means enabled and 0 disabled. - * param - returns the parameter passed by the - mi_dfks_set_feature MI function. This field will be NULL if - the parameter was not specified, or if the set_route is not - triggered by an MI command, but by SIP signalling. - * value/field - read or write extra feature values. field can - be one of: - + forwardTo - for all forwarding types - + ringCount - for CallForwardingNoAnswer - - Example 1.3. dfks usage -... -route[dfks_set] { - # CallForwardingAlways is not allowed - if ($dfks(feature) == "CallForwardingAlways") - $dfks(status) = 0; - - xlog("New status: $dfks(status) for feature '$dfks(feature)' of user - '$dfks(presentity)'\n"); -} -route[dfks_get] { - if ($dfks(feature) == "CallForwardingNoAnswer") { - $dfks(status) = 1; - $dfks(value/forwardTo) = "sip:bob@10.0.0.11"; - $dfks(value/ringCount) = "3"; - } else if ($dfks(feature) == "CallForwardingAlways") - $dfks(assigned) = 0; - } else { - ... - } -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 23 7 1641 92 - 2. Maksym Sobolyev (@sobomax) 8 6 16 21 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 31 26 - 4. Liviu Chircu (@liviuchircu) 4 2 2 2 - 5. Razvan Crainea (@razvancrainea) 3 1 67 21 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2020 - Jan 2024 - 2. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 3. Liviu Chircu (@liviuchircu) Nov 2020 - Jan 2021 - 4. Vlad Patrascu (@rvlad-patrascu) Dec 2019 - Sep 2020 - 5. Razvan Crainea (@razvancrainea) Feb 2020 - Feb 2020 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2019 www.opensips-solutions.com diff --git a/modules/presence_dfks/README.md b/modules/presence_dfks/README.md new file mode 100644 index 00000000000..5f7024335d2 --- /dev/null +++ b/modules/presence_dfks/README.md @@ -0,0 +1,212 @@ +--- +title: "presence_dfks Module" +description: "The module enables the handling of the \"as-feature-event\" event package (as defined by Broadsoft's [Device Feature Key Synchronization](https://h30434.www3.hp.com/psg/attachments/psg/Desk_IP_Conference_Phones/1740/1/DeviceFeatureKeySynchronizationFD.pdf) protocol) by the presence module." +--- + +## Admin Guide + + +### Overview + + +The module enables the handling of the "as-feature-event" event package (as +defined by Broadsoft's +[Device Feature Key Synchronization](https://h30434.www3.hp.com/psg/attachments/psg/Desk_IP_Conference_Phones/1740/1/DeviceFeatureKeySynchronizationFD.pdf) +protocol) by the presence module. This can be used to synchronize the status of +features such as Do Not Disturb and different forwarding types between a SIP +phone and a SIP server. + + +The module supports synchronization for the following features: Do Not Disturb, +Call Forwarding Always, Call Forwarding Busy and Call Forwarding No Answer. +Feature status can be changed either from the SIP phone or the OpenSIPS Server( +by running an MI command). + + +When handling a SUBSCRIBE message without a body, the module will run a script +route for each feature, that will be used to retrieve the current status of that +feature. Conversely, a SUBSCRIBE with a body will trigger a script route where the +updated status of a specific feature is available. This route might also be run +if the feature update was triggered from OpenSIPS via MI. + + +> [!NOTE] +> The module does not automatically cache or persist any feature information +> as this is left for the script writer to implement in the routes triggered by the module. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. + + +#### External Libraries or Applications + + +- *libxml2-dev*. + + +### Exported Parameters + + +#### get_route (string) + + +The name of the script route to be run in order to retrieve the status +of a feature. + + +*Default value is "dfks_get".* + + +```opensips title="Set parameter" +... +modparam("presence_dfks", "get_route", "dfks_get") +... +``` + + +#### set_route (string) + + +The name of the script route to be run when a feature status update +from a SIP phone is received. + + +*Default value is "dfks_get".* + + +```opensips title="Set parameter" +... +modparam("presence_dfks", "set_route", "dfks_set") +... +``` + + +### Exported Functions + + +None. + + +### Exported MI Functions + + +#### dfks_set_feature + + +Triggers the sending of NOTIFY messages containing a feature status update +to all watchers. + + +> [!NOTE] +> Calling this MI function also triggers the +> *set_route* run. One can determine if the route is +> triggered by an MI function by checking the existence of the +> *$dfks(param)* variable. + + +Name: *dfks_set_feature* + + +Parameters: + + +- *presentity*: the URI of the user whose feature status +should be updated +- *feature*: The name of the feature to update. Takes one +of the following values: + - *DoNotDisturb* + - *CallForwardingAlways* + - *CallForwardingBusy* + - *CallForwardingNoAnswer* +- *status*: the new status of the feature: +*0* - disabled, *1* - enabled +- *route_param*: optional string parameter +passed to the *$dfks(param)* variable in +*set_route*. +- *values*: an array of extra values that can be updated +for a feature. The format of an array element is: +*field*/*value*. Supported fields are: + - *forwardTo* - for all forwarding types + - *ringCount* - for *CallForwardingNoAnswer* + + +MI FIFO Command Format: +```bash +opensips-cli -x mi dfks_set_feature sip:alice@10.0.0.11 CallForwardingNoAnswer 1 1 \ +ringCount/4 forwardTo/sip:bob@10.0.0.11 +``` + + +### Exported Pseudo-Variables + + +#### $dfks(field) + + +This pseudo-variable can be used in the routes triggered by the module +to handle the feature information through the following subnames: + + +- *assigned* - inform the SIP phone that a +feature is unassigned by setting this to *0* (the NOTIFY response +will contain no XML data for the corresponding feature) By default, features are assigned. +- *notify* - suppress the sending of the NOTIFY +message by setting this to *0*. By default, the NOTIFY is sent. +- *presentity* - read-only, returns the current presentity URI. +- *feature* - read-only, returns the current feature name. +Possible values are: + + - *DoNotDisturb* + - *CallForwardingAlways* + - *CallForwardingBusy* + - *CallForwardingNoAnswer* +- *status* - read or write the feature status. A value of +*1* means enabled and *0* disabled. +- *param* - returns the parameter passed by the +*mi_dfks_set_feature* MI function. This field will be +*NULL* if the parameter was not specified, or if the +*set_route* is not triggered by an MI command, but by +SIP signalling. +- *value/field* - read or write extra feature values. +*field* can be one of: + - *forwardTo* - for all forwarding types + - *ringCount* - for *CallForwardingNoAnswer* + + +```opensips title="dfks usage" +... +route[dfks_set] { + # CallForwardingAlways is not allowed + if ($dfks(feature) == "CallForwardingAlways") + $dfks(status) = 0; + + xlog("New status: $dfks(status) for feature '$dfks(feature)' of user '$dfks(presentity)'\n"); +} +route[dfks_get] { + if ($dfks(feature) == "CallForwardingNoAnswer") { + $dfks(status) = 1; + $dfks(value/forwardTo) = "sip:bob@10.0.0.11"; + $dfks(value/ringCount) = "3"; + } else if ($dfks(feature) == "CallForwardingAlways") + $dfks(assigned) = 0; + } else { + ... + } +} +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_dfks/doc/contributors.xml b/modules/presence_dfks/doc/contributors.xml deleted file mode 100644 index 3b55e419346..00000000000 --- a/modules/presence_dfks/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 23 - 7 - 1641 - 92 - - - 2. - Maksym Sobolyev (@sobomax) - 8 - 6 - 16 - 21 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 31 - 26 - - - 4. - Liviu Chircu (@liviuchircu) - 4 - 2 - 2 - 2 - - - 5. - Razvan Crainea (@razvancrainea) - 3 - 1 - 67 - 21 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2020 - Jan 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 3. - Liviu Chircu (@liviuchircu) - Nov 2020 - Jan 2021 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Dec 2019 - Sep 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2020 - Feb 2020 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/presence_dfks/doc/presence_dfks.xml b/modules/presence_dfks/doc/presence_dfks.xml deleted file mode 100644 index 2ecc048dbdf..00000000000 --- a/modules/presence_dfks/doc/presence_dfks.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - presence_dfks Module - &osips; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2019 &osipssol; - diff --git a/modules/presence_dfks/doc/presence_dfks_admin.xml b/modules/presence_dfks/doc/presence_dfks_admin.xml deleted file mode 100644 index b702a1b890f..00000000000 --- a/modules/presence_dfks/doc/presence_dfks_admin.xml +++ /dev/null @@ -1,302 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module enables the handling of the "as-feature-event" event package (as - defined by Broadsoft's - Device Feature Key Synchronization - protocol) by the presence module. This can be used to synchronize the status of - features such as Do Not Disturb and different forwarding types between a SIP - phone and a SIP server. - - - The module supports synchronization for the following features: Do Not Disturb, - Call Forwarding Always, Call Forwarding Busy and Call Forwarding No Answer. - Feature status can be changed either from the SIP phone or the OpenSIPS Server( - by running an MI command). - - - When handling a SUBSCRIBE message without a body, the module will run a script - route for each feature, that will be used to retrieve the current status of that - feature. Conversely, a SUBSCRIBE with a body will trigger a script route where the - updated status of a specific feature is available. This route might also be run - if the feature update was triggered from OpenSIPS via MI. - - - Note that the module does not automatically cache or persist any feature information - as this is left for the script writer to implement in the routes triggered by the module. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - -
- -
- External Libraries or Applications - - - - libxml2-dev. - - - -
-
- -
- Exported Parameters - -
- <varname>get_route</varname> (string) - - The name of the script route to be run in order to retrieve the status - of a feature. - - - Default value is dfks_get. - - - Set <varname></varname> parameter - -... -modparam("presence_dfks", "get_route", "dfks_get") -... - - -
- -
- <varname>set_route</varname> (string) - - The name of the script route to be run when a feature status update - from a SIP phone is received. - - - Default value is dfks_get. - - - Set <varname></varname> parameter - -... -modparam("presence_dfks", "set_route", "dfks_set") -... - - -
- -
- -
- Exported Functions - - None. - -
- -
- Exported MI Functions -
- - <function moreinfo="none">dfks_set_feature</function> - - - Triggers the sending of NOTIFY messages containing a feature status update - to all watchers. - - - Note: calling this MI function also triggers the - set_route run. One can determine if the route is - triggered by an MI function by checking the existence of the - $dfks(param) variable. - - - Name: dfks_set_feature - - Parameters: - - - - presentity: the URI of the user whose feature status - should be updated - - - - - feature: The name of the feature to update. Takes one - of the following values: - - - - DoNotDisturb - - - CallForwardingAlways - - - CallForwardingBusy - - - CallForwardingNoAnswer - - - - - - status: the new status of the feature: - 0 - disabled, 1 - enabled - - - - - route_param: optional string parameter - passed to the $dfks(param) variable in - set_route. - - - - - values: an array of extra values that can be updated - for a feature. The format of an array element is: - field/value. Supported fields are: - - - forwardTo - for all forwarding types - - - ringCount - for CallForwardingNoAnswer - - - - - - - - - MI FIFO Command Format: - - -opensips-cli -x mi dfks_set_feature sip:alice@10.0.0.11 CallForwardingNoAnswer 1 1 \ -ringCount/4 forwardTo/sip:bob@10.0.0.11 - -
-
- -
- Exported Pseudo-Variables -
- - <varname>$dfks(field)</varname> - - This pseudo-variable can be used in the routes triggered by the module - to handle the feature information through the following subnames: - - - assigned - inform the SIP phone that a - feature is unassigned by setting this to 0 (the NOTIFY response - will contain no XML data for the corresponding feature) By default, features are assigned. - - - - notify - suppress the sending of the NOTIFY - message by setting this to 0. By default, the NOTIFY is sent. - - - - presentity - read-only, returns the current presentity URI. - - - - feature - read-only, returns the current feature name. - Possible values are: - - - - DoNotDisturb - - - CallForwardingAlways - - - CallForwardingBusy - - - CallForwardingNoAnswer - - - - - status - read or write the feature status. A value of - 1 means enabled and 0 disabled. - - - - param - returns the parameter passed by the - mi_dfks_set_feature MI function. This field will be - NULL if the parameter was not specified, or if the - set_route is not triggered by an MI command, but by - SIP signalling. - - - - value/field - read or write extra feature values. - field can be one of: - - - forwardTo - for all forwarding types - - - ringCount - for CallForwardingNoAnswer - - - - - - - - <varname>dfks</varname> usage - -... -route[dfks_set] { - # CallForwardingAlways is not allowed - if ($dfks(feature) == "CallForwardingAlways") - $dfks(status) = 0; - - xlog("New status: $dfks(status) for feature '$dfks(feature)' of user '$dfks(presentity)'\n"); -} -route[dfks_get] { - if ($dfks(feature) == "CallForwardingNoAnswer") { - $dfks(status) = 1; - $dfks(value/forwardTo) = "sip:bob@10.0.0.11"; - $dfks(value/ringCount) = "3"; - } else if ($dfks(feature) == "CallForwardingAlways") - $dfks(assigned) = 0; - } else { - ... - } -} -... - - -
- -
- -
diff --git a/modules/presence_dialoginfo/README b/modules/presence_dialoginfo/README deleted file mode 100644 index 2bd7f64410e..00000000000 --- a/modules/presence_dialoginfo/README +++ /dev/null @@ -1,279 +0,0 @@ -presence_dialoginfo Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. force_single_dialog (int) - - 1.4. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The module enables the handling of "Event: dialog" (as defined - in RFC 4235) inside of the presence module. This can be used - distribute the dialog-info status to the subscribed watchers. - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by an - authorized application and subscribe requests only by - authorized users. Authorization can thus be easily done in - OpenSIPS configuration file before calling handle_publish() and - handle_subscribe() functions. - - Note: This module only activates the processing of the "dialog" - in the presence module. To send dialog-info to watchers you - also need a source which PUBLISH the dialog info to the - presence module. For example you can use the pua_dialoginfo - module or any external component. This approach allows to have - the presence server and the dialog-info aware publisher (e.g. - the main proxy) on different OpenSIPS instances. - - This module by default does body aggregation. That means, if - the presence module received PUBLISH from multiple presentities - (e.g. if the entity has multiple dialogs the pua_dialoginfo - will send multiple PUBLISH), the module will parse all the - received (and still valid, depending on the Expires header in - the PUBLISH request) XML documents and generate a single XML - document with multiple "dialog" elements. This is perfectly - valid, but unfortunately not supported by all SIP phones, e.g. - Linksys SPA962 crashes when it receives dialog-info with - multiple dialog elements. In this case use the - force_single_dialog module parameter. - - To get better understanding how all the module works together - please take a look at the follwing figure: - - - Main Proxy and Presence Server on the same Instance - - caller proxy & callee watcher -alice@example presence bob@example watcher@example - server - | | | | - | |<-------SUBSCRIBE bob-------| - | |--------200 OK------------->| - | |--------NOTIFY------------->| - | |<-------200 OK--------------| - | | | | - |--INV bob--->| | | - | |--INV bob-->| | - | |<-100-------| | - | | | | - | |<-180 ring--| | - |<--180 ring--| | | - | |-- | | - | | \ | | - | | PUBLISH bob| | - | | / | | - | |<- | | - | | | | - | |-- | | - | | \ | | - | | 200 ok | | - | | / | | - | |<- | | - | |--------NOTIFY------------->| - | |<-------200 OK--------------| - | | | | - - - * The watcher subscribes the "Event: dialog" of Bob. - * Alice calls Bob. - * Bob replies with ringing, the dialog in the dialog module - transits to "early". The callback in pua_dialoginfo is - executed. The pua_dialoginfo module creates the XML - document and uses the pua module to send the PUBLISH. (pua - module itself uses tm module to send the PUBLISH stateful) - * PUBLISH is received and handled by presence module. - Presence module updates the "presentity". Presence module - checks for active watchers of the presentity. It gives all - the XML dcouments to presence_dialoginfo module to - aggregate them into a single XML document. Then it sends - the NOTIFY with the aggregated XML document to all active - watchers. - - The presence server can also be separated from the main proxy - by using a separate OpenSIPS instance as shown in the following - figure. (Either set the outbound_proxy parameter of pua module - or make sure to route the "looped" PUBLISH requests from the - main proxy to the presence server). - - - Main Proxy and Presence Server use a separate Instance - - caller proxy & presence callee watcher -alice@example server server bob@example watcher@example - | | | | | - | |<--------------------SUBSCRIBE bob-------| - | |-SUBSC bob->| | | - | |<-200 ok----| | | - | |---------------------200 OK------------->| - | | .... NOTIFY ... 200 OK ... | - | | | | | - | | | | | - |--INV bob--->| | | | - | |--INV bob------------------>| | - | |<-100-----------------------| | - | | | | | - | |<-180 ring------------------| | - |<--180 ring--| | | | - | |--PUBL bob->| | | - | |<-200 ok----| | | - | | |--------NOTIFY------------->| - | | |<-------200 OK--------------| - | | | | | - - - - - Known issues: - * The "version" attribute is increased for every NOTIFY, even - if the XML document has not changed. This is of course - valid, but not very smart. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - -1.2.2. External Libraries or Applications - - None. - -1.3. Exported Parameters - -1.3.1. force_single_dialog (int) - - By default the module aggregates all available dialog info into - a single dialog-info document containing multiple "dialog" - elements. If the phone does not support this, you can activate - this parameter. - - If this parameter is set, only the dialog element with the - currently most interesting dialog state will be put into the - dialog-info document. Thus, the dialog-info element will - contain only a single "dialog" element. The algorithm chooses - the state based onf the following order of priority (least - important first): terminated, trying, proceeding, confirmed, - early. Note: I consider the "early" state more intersting than - confirmed as often you might want to pickup a call if the - originall callee is already busy in a call. - - Default value is “0”. - - Example 1.1. Set parameter -... -modparam("presence_dialoginfo", "force_single_dialog", 1) -... - -1.4. Exported Functions - - None to be used in configuration file. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 14 12 62 30 - 2. Liviu Chircu (@liviuchircu) 13 10 29 78 - 3. Razvan Crainea (@razvancrainea) 11 9 15 19 - 4. Klaus Darilion 11 1 1181 0 - 5. Walter Doekes (@wdoekes) 7 4 66 82 - 6. Ovidiu Sas (@ovidiusas) 6 4 78 18 - 7. shiningstarj 4 2 2 2 - 8. Angel Marin 4 1 123 1 - 9. Anca Vamanu 3 1 14 18 - 10. Vallimamod Abdullah 3 1 4 3 - - All remaining contributors: Maksym Sobolyev (@sobomax), Ken - Rice, Peter Lemenkov (@lemenkov), Vlad Patrascu - (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2009 - May 2022 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2020 - 5. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 8. shiningstarj Oct 2015 - Oct 2015 - 9. Walter Doekes (@wdoekes) Apr 2010 - Mar 2014 - 10. Ovidiu Sas (@ovidiusas) Oct 2010 - Jan 2013 - - All remaining contributors: Anca Vamanu, Vallimamod Abdullah, - Angel Marin, Klaus Darilion. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Walter - Doekes (@wdoekes), Klaus Darilion. - - Documentation Copyrights: - - Copyright © 2008 Klaus Darilion, IPCom (Module implementation - was partly sponsored by Silver Server (www.sil.at)) - - Copyright © 2007 Juha Heinanen diff --git a/modules/presence_dialoginfo/README.md b/modules/presence_dialoginfo/README.md new file mode 100644 index 00000000000..573ec213571 --- /dev/null +++ b/modules/presence_dialoginfo/README.md @@ -0,0 +1,201 @@ +--- +title: "presence_dialoginfo Module" +description: "The module enables the handling of \"Event: dialog\" (as defined in RFC 4235) inside of the presence module." +--- + +## Admin Guide + + +### Overview + + +The module enables the handling of "Event: dialog" (as defined +in RFC 4235) inside of the presence module. This can be used +distribute the dialog-info status to the subscribed watchers. + + +The module does not currently implement any authorization +rules. It assumes that publish requests are only issued by +an authorized application and subscribe requests only by +authorized users. Authorization can thus be easily done in +OpenSIPS configuration file before calling handle_publish() +and handle_subscribe() functions. + + +> [!NOTE] +> This module only activates the processing of the "dialog" +> in the presence module. To send dialog-info to watchers you also +> need a source which PUBLISH the dialog info to the presence module. +> For example you can use the pua_dialoginfo module or any external +> component. This approach allows to have the presence server and the +> dialog-info aware publisher (e.g. the main proxy) on different +> OpenSIPS instances. + + +This module by default does body aggregation. That means, if the presence +module received PUBLISH from multiple presentities (e.g. if the entity has +multiple dialogs the pua_dialoginfo will send multiple PUBLISH), the +module will parse all the received (and still valid, depending on the Expires +header in the PUBLISH request) XML documents and generate a single +XML document with multiple "dialog" elements. This is perfectly valid, but +unfortunately not supported by all SIP phones, e.g. Linksys SPA962 crashes +when it receives dialog-info with multiple dialog elements. In this case use +the force_single_dialog module parameter. + + +To get better understanding how all the module works together please take a +look at the follwing figure: + + +```c + Main Proxy and Presence Server on the same Instance + + caller proxy & callee watcher +alice@example presence bob@example watcher@example + server + | | | | + | |<-------SUBSCRIBE bob-------| + | |--------200 OK------------->| + | |--------NOTIFY------------->| + | |<-------200 OK--------------| + | | | | + |--INV bob--->| | | + | |--INV bob-->| | + | |<-100-------| | + | | | | + | |<-180 ring--| | + |<--180 ring--| | | + | |-- | | + | | \ | | + | | PUBLISH bob| | + | | / | | + | |<- | | + | | | | + | |-- | | + | | \ | | + | | 200 ok | | + | | / | | + | |<- | | + | |--------NOTIFY------------->| + | |<-------200 OK--------------| + | | | | +``` + + +- The watcher subscribes the "Event: dialog" of Bob. +- Alice calls Bob. +- Bob replies with ringing, the dialog in the dialog module +transits to "early". The callback in pua_dialoginfo is executed. +The pua_dialoginfo module creates the XML document and uses the +pua module to send the PUBLISH. (pua module itself uses tm module +to send the PUBLISH stateful) +- PUBLISH is received and handled by presence module. Presence +module updates the "presentity". Presence module checks for active watchers +of the presentity. It gives all the XML dcouments to presence_dialoginfo +module to aggregate them into a single XML document. Then it sends the +NOTIFY with the aggregated XML document to all active watchers. + + +The presence server can also be separated from the main proxy by using a separate +OpenSIPS instance as shown in the following figure. (Either set the outbound_proxy +parameter of pua module or make sure to route the "looped" PUBLISH requests from the +main proxy to the presence server). + + +```c + Main Proxy and Presence Server use a separate Instance + + caller proxy & presence callee watcher +alice@example server server bob@example watcher@example + | | | | | + | |<--------------------SUBSCRIBE bob-------| + | |-SUBSC bob->| | | + | |<-200 ok----| | | + | |---------------------200 OK------------->| + | | .... NOTIFY ... 200 OK ... | + | | | | | + | | | | | + |--INV bob--->| | | | + | |--INV bob------------------>| | + | |<-100-----------------------| | + | | | | | + | |<-180 ring------------------| | + |<--180 ring--| | | | + | |--PUBL bob->| | | + | |<-200 ok----| | | + | | |--------NOTIFY------------->| + | | |<-------200 OK--------------| + | | | | | +``` + + +Known issues: + + +- The "version" attribute is increased for every NOTIFY, even +if the XML document has not changed. This is of course valid, +but not very smart. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### force_single_dialog (int) + + +By default the module aggregates all available dialog info +into a single dialog-info document containing multiple +"dialog" elements. If the phone does not support this, you +can activate this parameter. + + +If this parameter is set, only the dialog element with the +currently most interesting dialog state will be put into the +dialog-info document. Thus, the dialog-info element will contain +only a single "dialog" element. The algorithm chooses the state +based onf the following order of priority (least important first): +terminated, trying, proceeding, confirmed, early. + +> [!NOTE] +> I consider the "early" state more intersting than confirmed as often you might +> want to pickup a call if the originall callee is already busy in a +> call. + + +*Default value is "0".* + + +```opensips title="Set parameter" +... +modparam("presence_dialoginfo", "force_single_dialog", 1) +... +``` + + +### Exported Functions + + +None to be used in configuration file. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_dialoginfo/doc/contributors.xml b/modules/presence_dialoginfo/doc/contributors.xml deleted file mode 100644 index 9a18bd5a00c..00000000000 --- a/modules/presence_dialoginfo/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 14 - 12 - 62 - 30 - - - 2. - Liviu Chircu (@liviuchircu) - 13 - 10 - 29 - 78 - - - 3. - Razvan Crainea (@razvancrainea) - 11 - 9 - 15 - 19 - - - 4. - Klaus Darilion - 11 - 1 - 1181 - 0 - - - 5. - Walter Doekes (@wdoekes) - 7 - 4 - 66 - 82 - - - 6. - Ovidiu Sas (@ovidiusas) - 6 - 4 - 78 - 18 - - - 7. - shiningstarj - 4 - 2 - 2 - 2 - - - 8. - Angel Marin - 4 - 1 - 123 - 1 - - - 9. - Anca Vamanu - 3 - 1 - 14 - 18 - - - 10. - Vallimamod Abdullah - 3 - 1 - 4 - 3 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Ken Rice, Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2009 - May 2022 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 8. - shiningstarj - Oct 2015 - Oct 2015 - - - 9. - Walter Doekes (@wdoekes) - Apr 2010 - Mar 2014 - - - 10. - Ovidiu Sas (@ovidiusas) - Oct 2010 - Jan 2013 - - - -
-All remaining contributors: Anca Vamanu, Vallimamod Abdullah, Angel Marin, Klaus Darilion. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Walter Doekes (@wdoekes), Klaus Darilion. -
- -
diff --git a/modules/presence_dialoginfo/doc/presence_dialoginfo.xml b/modules/presence_dialoginfo/doc/presence_dialoginfo.xml deleted file mode 100644 index 79a1a0fdea5..00000000000 --- a/modules/presence_dialoginfo/doc/presence_dialoginfo.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - presence_dialoginfo Module - &osips; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 Klaus Darilion, IPCom (Module implementation was partly sponsored by Silver Server (www.sil.at)) - ©right; 2007 Juha Heinanen - diff --git a/modules/presence_dialoginfo/doc/presence_dialoginfo_admin.xml b/modules/presence_dialoginfo/doc/presence_dialoginfo_admin.xml deleted file mode 100644 index 3de37dcfd1a..00000000000 --- a/modules/presence_dialoginfo/doc/presence_dialoginfo_admin.xml +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - The module enables the handling of "Event: dialog" (as defined - in RFC 4235) inside of the presence module. This can be used - distribute the dialog-info status to the subscribed watchers. - - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by - an authorized application and subscribe requests only by - authorized users. Authorization can thus be easily done in - &osips; configuration file before calling handle_publish() - and handle_subscribe() functions. - - - Note: This module only activates the processing of the "dialog" - in the presence module. To send dialog-info to watchers you also - need a source which PUBLISH the dialog info to the presence module. - For example you can use the pua_dialoginfo module or any external - component. This approach allows to have the presence server and the - dialog-info aware publisher (e.g. the main proxy) on different - &osips; instances. - - - This module by default does body aggregation. That means, if the presence - module received PUBLISH from multiple presentities (e.g. if the entity has - multiple dialogs the pua_dialoginfo will send multiple PUBLISH), the - module will parse all the received (and still valid, depending on the Expires - header in the PUBLISH request) XML documents and generate a single - XML document with multiple "dialog" elements. This is perfectly valid, but - unfortunately not supported by all SIP phones, e.g. Linksys SPA962 crashes - when it receives dialog-info with multiple dialog elements. In this case use - the force_single_dialog module parameter. - - - To get better understanding how all the module works together please take a - look at the follwing figure: - -| - | |--------NOTIFY------------->| - | |<-------200 OK--------------| - | | | | - |--INV bob--->| | | - | |--INV bob-->| | - | |<-100-------| | - | | | | - | |<-180 ring--| | - |<--180 ring--| | | - | |-- | | - | | \ | | - | | PUBLISH bob| | - | | / | | - | |<- | | - | | | | - | |-- | | - | | \ | | - | | 200 ok | | - | | / | | - | |<- | | - | |--------NOTIFY------------->| - | |<-------200 OK--------------| - | | | | -]]> - - - - - The watcher subscribes the "Event: dialog" of Bob. - - - Alice calls Bob. - - - Bob replies with ringing, the dialog in the dialog module - transits to "early". The callback in pua_dialoginfo is executed. - The pua_dialoginfo module creates the XML document and uses the - pua module to send the PUBLISH. (pua module itself uses tm module - to send the PUBLISH stateful) - - - PUBLISH is received and handled by presence module. Presence - module updates the "presentity". Presence module checks for active watchers - of the presentity. It gives all the XML dcouments to presence_dialoginfo - module to aggregate them into a single XML document. Then it sends the - NOTIFY with the aggregated XML document to all active watchers. - - - - The presence server can also be separated from the main proxy by using a separate - &osips; instance as shown in the following figure. (Either set the outbound_proxy - parameter of pua module or make sure to route the "looped" PUBLISH requests from the - main proxy to the presence server). - - -| | | - | |<-200 ok----| | | - | |---------------------200 OK------------->| - | | .... NOTIFY ... 200 OK ... | - | | | | | - | | | | | - |--INV bob--->| | | | - | |--INV bob------------------>| | - | |<-100-----------------------| | - | | | | | - | |<-180 ring------------------| | - |<--180 ring--| | | | - | |--PUBL bob->| | | - | |<-200 ok----| | | - | | |--------NOTIFY------------->| - | | |<-------200 OK--------------| - | | | | | - - -]]> - - - - - Known issues: - - - The "version" attribute is increased for every NOTIFY, even - if the XML document has not changed. This is of course valid, - but not very smart. - - - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - -
- -
- External Libraries or Applications - - None. - -
-
- -
- Exported Parameters - -
- <varname>force_single_dialog</varname> (int) - - By default the module aggregates all available dialog info - into a single dialog-info document containing multiple - "dialog" elements. If the phone does not support this, you - can activate this parameter. - - - If this parameter is set, only the dialog element with the - currently most interesting dialog state will be put into the - dialog-info document. Thus, the dialog-info element will contain - only a single "dialog" element. The algorithm chooses the state - based onf the following order of priority (least important first): - terminated, trying, proceeding, confirmed, early. Note: I consider - the "early" state more intersting than confirmed as often you might - want to pickup a call if the originall callee is already busy in a - call. - - - Default value is 0. - - - Set <varname></varname> parameter - -... -modparam("presence_dialoginfo", "force_single_dialog", 1) -... - - -
- -
- -
- Exported Functions - - None to be used in configuration file. - -
- -
diff --git a/modules/presence_dialoginfo/notify_body.c b/modules/presence_dialoginfo/notify_body.c index 36b5cd8b572..50529522e6c 100644 --- a/modules/presence_dialoginfo/notify_body.c +++ b/modules/presence_dialoginfo/notify_body.c @@ -99,7 +99,6 @@ str* dlginfo_agg_nbody(str* pres_user, str* pres_domain, str** body_array, int n } xmlCleanupParser(); - xmlMemoryDump(); if (n_body== NULL) n_body = _build_empty_dialoginfo(pres_uri_char, NULL); @@ -274,7 +273,6 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n, in pkg_free(xml_array); xmlCleanupParser(); - xmlMemoryDump(); return body; @@ -471,7 +469,6 @@ static str* _build_empty_dialoginfo(const char* pres_uri_char, str* extra_hdrs) xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); return nbody; error: diff --git a/modules/presence_mwi/README b/modules/presence_mwi/README deleted file mode 100644 index e0d15740207..00000000000 --- a/modules/presence_mwi/README +++ /dev/null @@ -1,144 +0,0 @@ -Presence_MWI Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - -Chapter 1. Admin Guide - -1.1. Overview - - The module does specific handling for notify-subscribe - message-summary (message waiting indication) events as - specified in RFC 3842. It is used with the general event - handling module, presence. It constructs and adds - message-summary event to it. - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by a - voicemail application and subscribe requests only by the owner - of voicemail box. Authorization can thus be easily done by - OpenSIPS configuration file before calling handle_publish() and - handle_subscribe() functions. - - The module implements a simple check of content type - application/simple-message-summary: Content must start with - Messages-Waiting status line followed by zero or more lines - that consist of tabs and printable ASCII characters. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - -1.2.2. External Libraries or Applications - - None. - -1.3. Exported Parameters - - None. - -1.4. Exported Functions - - None to be used in configuration file. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 15 13 30 30 - 2. Juha Heinanen (@juha-h) 12 5 645 11 - 3. Anca Vamanu 10 7 18 88 - 4. Liviu Chircu (@liviuchircu) 9 7 25 30 - 5. Daniel-Constantin Mierla (@miconda) 9 7 13 11 - 6. Razvan Crainea (@razvancrainea) 9 7 10 8 - 7. Maksym Sobolyev (@sobomax) 4 2 3 4 - 8. Ovidiu Sas (@ovidiusas) 3 2 2 0 - 9. Sergio Gutierrez 3 1 41 10 - 10. Ancuta Onofrei 3 1 10 13 - - All remaining contributors: Konstantin Bokarius, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Vlad Patrascu - (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Apr 2019 - 4. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Jun 2018 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 7. Ovidiu Sas (@ovidiusas) Oct 2010 - Mar 2011 - 8. Anca Vamanu Jul 2007 - Sep 2010 - 9. Sergio Gutierrez Nov 2008 - Nov 2008 - 10. Daniel-Constantin Mierla (@miconda) Oct 2007 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Juha Heinanen (@juha-h), Ancuta Onofrei. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Juha Heinanen (@juha-h). - - Documentation Copyrights: - - Copyright © 2007 Juha Heinanen diff --git a/modules/presence_mwi/README.md b/modules/presence_mwi/README.md new file mode 100644 index 00000000000..d7cf43d8302 --- /dev/null +++ b/modules/presence_mwi/README.md @@ -0,0 +1,68 @@ +--- +title: "Presence_MWI Module" +description: "The module does specific handling for notify-subscribe message-summary (message waiting indication) events as specified in RFC 3842." +--- + +## Admin Guide + + +### Overview + + +The module does specific handling for notify-subscribe +message-summary (message waiting indication) events +as specified in RFC 3842. +It is used with the general event handling module, +presence. It constructs and adds message-summary event to +it. + + +The module does not currently implement any authorization +rules. It assumes that publish requests are only issued by +a voicemail application and subscribe requests only by +the owner of voicemail box. Authorization can thus +be easily done by OpenSIPS configuration file before +calling handle_publish() and handle_subscribe() +functions. + + +The module implements a simple check of content type +application/simple-message-summary: Content must start +with Messages-Waiting status line followed by zero or +more lines that consist of tabs and printable ASCII +characters. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +None. + + +### Exported Functions + + +None to be used in configuration file. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_mwi/doc/contributors.xml b/modules/presence_mwi/doc/contributors.xml deleted file mode 100644 index d220cf00c14..00000000000 --- a/modules/presence_mwi/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 15 - 13 - 30 - 30 - - - 2. - Juha Heinanen (@juha-h) - 12 - 5 - 645 - 11 - - - 3. - Anca Vamanu - 10 - 7 - 18 - 88 - - - 4. - Liviu Chircu (@liviuchircu) - 9 - 7 - 25 - 30 - - - 5. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 13 - 11 - - - 6. - Razvan Crainea (@razvancrainea) - 9 - 7 - 10 - 8 - - - 7. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 8. - Ovidiu Sas (@ovidiusas) - 3 - 2 - 2 - 0 - - - 9. - Sergio Gutierrez - 3 - 1 - 41 - 10 - - - 10. - Ancuta Onofrei - 3 - 1 - 10 - 13 - - - -
-All remaining contributors: Konstantin Bokarius, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Vlad Patrascu (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Apr 2019 - - - 4. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jun 2018 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 7. - Ovidiu Sas (@ovidiusas) - Oct 2010 - Mar 2011 - - - 8. - Anca Vamanu - Jul 2007 - Sep 2010 - - - 9. - Sergio Gutierrez - Nov 2008 - Nov 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Oct 2007 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h), Ancuta Onofrei. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). -
- -
diff --git a/modules/presence_mwi/doc/presence_mwi.xml b/modules/presence_mwi/doc/presence_mwi.xml deleted file mode 100644 index 52621ca7a8b..00000000000 --- a/modules/presence_mwi/doc/presence_mwi.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Presence_MWI Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 Juha Heinanen - - - - diff --git a/modules/presence_mwi/doc/presence_mwi_admin.xml b/modules/presence_mwi/doc/presence_mwi_admin.xml deleted file mode 100644 index 0d310dbd2f5..00000000000 --- a/modules/presence_mwi/doc/presence_mwi_admin.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - The module does specific handling for notify-subscribe - message-summary (message waiting indication) events - as specified in RFC 3842. - It is used with the general event handling module, - presence. It constructs and adds message-summary event to - it. - - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by - a voicemail application and subscribe requests only by - the owner of voicemail box. Authorization can thus - be easily done by &osips; configuration file before - calling handle_publish() and handle_subscribe() - functions. - - - The module implements a simple check of content type - application/simple-message-summary: Content must start - with Messages-Waiting status line followed by zero or - more lines that consist of tabs and printable ASCII - characters. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - -
- -
- External Libraries or Applications - - None. - -
-
- -
- Exported Parameters - - None. - -
- -
- Exported Functions - - None to be used in configuration file. - -
- -
- diff --git a/modules/presence_reginfo/README b/modules/presence_reginfo/README deleted file mode 100644 index 4b96728f32d..00000000000 --- a/modules/presence_reginfo/README +++ /dev/null @@ -1,167 +0,0 @@ -presence_reginfo Module - -Carsten Bock - - - -Edited by - -Carsten Bock - - - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Parameters - - 1.3.1. default_expires (int) - 1.3.2. aggregate_presentities (int) - - 1.4. Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_expires parameter - 1.2. Set aggregate_presentities parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The module enables the handling of "Event: reg" (as defined in - RFC 3680) inside of the presence module. This can be used - distribute the registration-info status to the subscribed - watchers. - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by an - authorized application and subscribe requests only by - authorized users. Authorization can thus be easily done in - OpenSIPS configuration file before calling handle_publish() and - handle_subscribe() functions. - - Note: This module only activates the processing of the "reg" in - the presence module. To send dialog-info to watchers you also - need a source which PUBLISH the reg info to the presence - module. For example you can use the pua_reginfo module or any - external component. This approach allows to have the presence - server and the reg-info aware publisher (e.g. the main proxy) - on different OpenSIPS instances. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - -1.2.2. External Libraries or Applications - - None. - -1.3. Parameters - -1.3.1. default_expires (int) - - The default expires value used when missing from SUBSCRIBE - message (in seconds). - - Default value is “3600”. - - Example 1.1. Set default_expires parameter - ... - modparam("presence_reginfo", "default_expires", 3600) - ... - -1.3.2. aggregate_presentities (int) - - Whether to aggregate in a single notify body all registration - presentities. Useful to have all registrations on first NOTIFY - following initial SUBSCRIBE. - - Default value is “0” (disabled). - - Example 1.2. Set aggregate_presentities parameter - ... - modparam("presence_reginfo", "ag -gregate_presentities", 1) - ... - -1.4. Functions - - None to be used in configuration file. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Carsten Bock 8 1 771 0 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 14 17 - 3. Ken Rice 3 1 2 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2024 - Apr 2024 - 3. Carsten Bock Mar 2024 - Mar 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Carsten - Bock. - - Documentation Copyrights: - - Copyright © 2011-2023 Carsten Bock, carsten@ng-voice.com, - http://www.ng-voice.com diff --git a/modules/presence_reginfo/README.md b/modules/presence_reginfo/README.md new file mode 100644 index 00000000000..b5844ad3db0 --- /dev/null +++ b/modules/presence_reginfo/README.md @@ -0,0 +1,100 @@ +--- +title: "presence_reginfo Module" +description: "The module enables the handling of \"Event: reg\" (as defined in RFC 3680) inside of the presence module." +--- + +## Admin Guide + + +### Overview + + +The module enables the handling of "Event: reg" (as defined +in RFC 3680) inside of the presence module. This can be used +distribute the registration-info status to the subscribed watchers. + + +The module does not currently implement any authorization +rules. It assumes that publish requests are only issued by +an authorized application and subscribe requests only by +authorized users. Authorization can thus be easily done in +OpenSIPS configuration file before calling handle_publish() +and handle_subscribe() functions. + + +Note: This module only activates the processing of the "reg" +in the presence module. To send dialog-info to watchers you also +need a source which PUBLISH the reg info to the presence module. +For example you can use the pua_reginfo module or any external +component. This approach allows to have the presence server and the +reg-info aware publisher (e.g. the main proxy) on different +OpenSIPS instances. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### default_expires (int) + + +The default expires value used when missing from SUBSCRIBE +message (in seconds). + + +*Default value is "3600".* + + +```opensips title="Set default_expires parameter" +... +modparam("presence_reginfo", "default_expires", 3600) +... + +``` + + +#### aggregate_presentities (int) + + +Whether to aggregate in a single notify body all registration +presentities. Useful to have all registrations on first NOTIFY +following initial SUBSCRIBE. + + +*Default value is "0" (disabled).* + + +```opensips title="Set aggregate_presentities parameter" +... +modparam("presence_reginfo", "aggregate_presentities", 1) +... + +``` + + +### Exported Functions + + +None to be used in configuration file. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_reginfo/doc/contributors.xml b/modules/presence_reginfo/doc/contributors.xml deleted file mode 100644 index f435f1a20ec..00000000000 --- a/modules/presence_reginfo/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Carsten Bock - 8 - 1 - 771 - 0 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 14 - 17 - - - 3. - Ken Rice - 3 - 1 - 2 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2024 - Apr 2024 - - - 3. - Carsten Bock - Mar 2024 - Mar 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Carsten Bock. -
- -
diff --git a/modules/presence_reginfo/doc/presence_reginfo.xml b/modules/presence_reginfo/doc/presence_reginfo.xml deleted file mode 100644 index 754df499c05..00000000000 --- a/modules/presence_reginfo/doc/presence_reginfo.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - presence_reginfo Module - &osipsname; - - - Carsten - Bock - carsten@ng-voice.com - - - Carsten - Bock - carsten@ng-voice.com - - - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011-2023 Carsten Bock, carsten@ng-voice.com, http://www.ng-voice.com - - - - - diff --git a/modules/presence_reginfo/doc/presence_reginfo_admin.xml b/modules/presence_reginfo/doc/presence_reginfo_admin.xml deleted file mode 100644 index 5639cae8525..00000000000 --- a/modules/presence_reginfo/doc/presence_reginfo_admin.xml +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - The module enables the handling of "Event: reg" (as defined - in RFC 3680) inside of the presence module. This can be used - distribute the registration-info status to the subscribed watchers. - - - The module does not currently implement any authorization - rules. It assumes that publish requests are only issued by - an authorized application and subscribe requests only by - authorized users. Authorization can thus be easily done in - &osips; configuration file before calling handle_publish() - and handle_subscribe() functions. - - - Note: This module only activates the processing of the "reg" - in the presence module. To send dialog-info to watchers you also - need a source which PUBLISH the reg info to the presence module. - For example you can use the pua_reginfo module or any external - component. This approach allows to have the presence server and the - reg-info aware publisher (e.g. the main proxy) on different - &osips; instances. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - -
- -
- External Libraries or Applications - - None. - -
-
- -
- Parameters -
- <varname>default_expires</varname> (int) - - The default expires value used when missing from SUBSCRIBE - message (in seconds). - - - Default value is 3600. - - - - Set <varname>default_expires</varname> parameter - - ... - modparam("presence_reginfo", "default_expires", 3600) - ... - - -
- -
- <varname>aggregate_presentities</varname> (int) - - Whether to aggregate in a single notify body all registration - presentities. Useful to have all registrations on first NOTIFY - following initial SUBSCRIBE. - - - Default value is 0 (disabled). - - - - Set <varname>aggregate_presentities</varname> parameter - - ... - modparam("presence_reginfo", "aggregate_presentities", 1) - ... - - -
- -
- - -
- Functions - - None to be used in configuration file. - -
- -
diff --git a/modules/presence_reginfo/notify_body.c b/modules/presence_reginfo/notify_body.c index 07dd2e9a671..8cb98c91134 100644 --- a/modules/presence_reginfo/notify_body.c +++ b/modules/presence_reginfo/notify_body.c @@ -69,7 +69,6 @@ str *reginfo_agg_nbody(str *pres_user, str *pres_domain, str **body_array, } xmlCleanupParser(); - xmlMemoryDump(); return n_body; } @@ -206,7 +205,6 @@ str *aggregate_xmls(str *pres_user, str *pres_domain, str **body_array, int n) pkg_free(xml_array); xmlCleanupParser(); - xmlMemoryDump(); return body; diff --git a/modules/presence_xcapdiff/README b/modules/presence_xcapdiff/README deleted file mode 100644 index 5f30514d77b..00000000000 --- a/modules/presence_xcapdiff/README +++ /dev/null @@ -1,133 +0,0 @@ -Presence_XCAPDiff Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - -Chapter 1. Admin Guide - -1.1. Overview - - The presence_xcapdiff is an OpenSIPS module that adds support - for the "xcap-diff" event to presence and pua. At the moment, - the module just registers the event but doesn't do any - event-specific processing. The module will automatically - determine if the presence and/or pua modules are present and if - so it will register the xcap-diff event with them. This allows - the module to automatically offer presence or pua related - functionality simply based on the presence of the - aforementioned modules in the OpenSIPS configuration, without - any need for manual configuration. - - Registering the event with pua, allows the XCAP server to - publish the xcap-event when some modification of a document - happens. Registering the event with presence allows clients to - subscribe to the event. - - The module is intended to be used with the OpenXCAP server - (www.openxcap.org), although it doesn't contain any - OpenXCAP-specific code and should be usable with any XCAP - server. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence module - to enable clients to subscribe to the - xcap-diff event package. - * pua module - to be able to publish the xcap-diff event when - some modification of a document happens. - * pua_mi module - to enable pua to publish the xcap-diff - event using the MI interface. This is needed if this module - is intended to be used in conjunction with OpenXCAP. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 9 7 7 7 - 2. Liviu Chircu (@liviuchircu) 8 6 26 31 - 3. Denis Bilenko 7 3 300 4 - 4. Razvan Crainea (@razvancrainea) 6 4 4 2 - 5. Vlad Patrascu (@rvlad-patrascu) 5 3 4 7 - 6. Anca Vamanu 4 2 2 11 - 7. Dan Pascu (@danpascu) 4 1 76 120 - 8. Maksym Sobolyev (@sobomax) 3 1 2 2 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2009 - Apr 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 6. Liviu Chircu (@liviuchircu) Jul 2014 - Jun 2018 - 7. Anca Vamanu Sep 2010 - Dec 2010 - 8. Dan Pascu (@danpascu) Sep 2008 - Sep 2008 - 9. Denis Bilenko Sep 2008 - Sep 2008 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Dan Pascu (@danpascu), Denis Bilenko. - - Documentation Copyrights: - - Copyright © 2008 AG Projects diff --git a/modules/presence_xcapdiff/README.md b/modules/presence_xcapdiff/README.md new file mode 100644 index 00000000000..2c527715f02 --- /dev/null +++ b/modules/presence_xcapdiff/README.md @@ -0,0 +1,64 @@ +--- +title: "Presence_XCAPDiff Module" +description: "The presence_xcapdiff is an OpenSIPS module that adds support for the \"xcap-diff\" event to presence and pua." +--- + +## Admin Guide + + +### Overview + + +The presence_xcapdiff is an OpenSIPS module that adds support for the +"xcap-diff" event to presence and pua. At the moment, the module +just registers the event but doesn't do any event-specific processing. +The module will automatically determine if the presence and/or pua +modules are present and if so it will register the xcap-diff event +with them. This allows the module to automatically offer presence +or pua related functionality simply based on the presence of the +aforementioned modules in the OpenSIPS configuration, without any +need for manual configuration. + + +Registering the event with pua, allows the XCAP server to publish +the xcap-event when some modification of a document happens. +Registering the event with presence allows clients to subscribe +to the event. + + +The module is intended to be used with the OpenXCAP server (www.openxcap.org), +although it doesn't contain any OpenXCAP-specific code and should be usable +with any XCAP server. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence* module - to enable clients to +subscribe to the xcap-diff event package. +- *pua* module - to be able to publish the +xcap-diff event when some modification of a document happens. +- *pua_mi* module - to enable pua to publish +the xcap-diff event using the MI interface. This is needed if +this module is intended to be used in conjunction with OpenXCAP. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_xcapdiff/doc/contributors.xml b/modules/presence_xcapdiff/doc/contributors.xml deleted file mode 100644 index c2eecc01ad9..00000000000 --- a/modules/presence_xcapdiff/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 7 - 7 - 7 - - - 2. - Liviu Chircu (@liviuchircu) - 8 - 6 - 26 - 31 - - - 3. - Denis Bilenko - 7 - 3 - 300 - 4 - - - 4. - Razvan Crainea (@razvancrainea) - 6 - 4 - 4 - 2 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 4 - 7 - - - 6. - Anca Vamanu - 4 - 2 - 2 - 11 - - - 7. - Dan Pascu (@danpascu) - 4 - 1 - 76 - 120 - - - 8. - Maksym Sobolyev (@sobomax) - 3 - 1 - 2 - 2 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2009 - Apr 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 6. - Liviu Chircu (@liviuchircu) - Jul 2014 - Jun 2018 - - - 7. - Anca Vamanu - Sep 2010 - Dec 2010 - - - 8. - Dan Pascu (@danpascu) - Sep 2008 - Sep 2008 - - - 9. - Denis Bilenko - Sep 2008 - Sep 2008 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Dan Pascu (@danpascu), Denis Bilenko. -
- -
diff --git a/modules/presence_xcapdiff/doc/presence_xcapdiff.xml b/modules/presence_xcapdiff/doc/presence_xcapdiff.xml deleted file mode 100644 index 5cb3689c9d8..00000000000 --- a/modules/presence_xcapdiff/doc/presence_xcapdiff.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Presence_XCAPDiff Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 AG Projects - - diff --git a/modules/presence_xcapdiff/doc/presence_xcapdiff_admin.xml b/modules/presence_xcapdiff/doc/presence_xcapdiff_admin.xml deleted file mode 100644 index fcde9f0149f..00000000000 --- a/modules/presence_xcapdiff/doc/presence_xcapdiff_admin.xml +++ /dev/null @@ -1,80 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The presence_xcapdiff is an &osips; module that adds support for the - "xcap-diff" event to presence and pua. At the moment, the module - just registers the event but doesn't do any event-specific processing. - The module will automatically determine if the presence and/or pua - modules are present and if so it will register the xcap-diff event - with them. This allows the module to automatically offer presence - or pua related functionality simply based on the presence of the - aforementioned modules in the &osips; configuration, without any - need for manual configuration. - - - Registering the event with pua, allows the XCAP server to publish - the xcap-event when some modification of a document happens. - Registering the event with presence allows clients to subscribe - to the event. - - - The module is intended to be used with the OpenXCAP server (www.openxcap.org), - although it doesn't contain any OpenXCAP-specific code and should be usable - with any XCAP server. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence module - to enable clients to - subscribe to the xcap-diff event package. - - - - - pua module - to be able to publish the - xcap-diff event when some modification of a document happens. - - - - - pua_mi module - to enable pua to publish - the xcap-diff event using the MI interface. This is needed if - this module is intended to be used in conjunction with OpenXCAP. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- diff --git a/modules/presence_xml/README b/modules/presence_xml/README deleted file mode 100644 index bf8995529a6..00000000000 --- a/modules/presence_xml/README +++ /dev/null @@ -1,268 +0,0 @@ -Presence_XML Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. force_active (int) - 1.3.2. pidf_manipulation (int) - 1.3.3. xcap_server (str) - 1.3.4. pres_rules_auid (str) - 1.3.5. pres_rules_filename (str) - 1.3.6. generate_offline_body (str) - - 1.4. Exported Functions - 1.5. Installation - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set force_active parameter - 1.2. Set pidf_manipulation parameter - 1.3. Set xcap_server parameter - 1.4. Set pres_rules_auid parameter - 1.5. Set pres_rules_filename parameter - 1.6. Set generate_offline_body parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The module does specific handling for notify-subscribe events - using xml bodies. It is used with the general event handling - module, presence. It constructs and adds 3 events to it: - presence, presence.winfo, dialog;sla. - - This module takes the xcap permission rule documents from - xcap_table. The presence permission rules are interpreted - according to the specifications in RFC 4745 and RFC 5025. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - * presence. - * signaling. - * xcap. - * xcap_client. - Only compulsory if not using an integrated xcap server (if - 'integrated_xcap_server' parameter is not set). - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml-dev. - -1.3. Exported Parameters - -1.3.1. force_active (int) - - This parameter is used for permissions when handling Subscribe - messages. If set to 1, subscription state is considered active - and the presentity is not queried for permissions(should be set - to 1 if not using an xcap server). Otherwise,the xcap server is - queried and the subscription states is according to user - defined permission rules. If no rules are defined for a certain - watcher, the subscriptions remains in pending state and the - Notify sent will have no body. - - Note: When switching from one value to another, the watchers - table must be emptied. - - Default value is “0”. - - Example 1.1. Set force_active parameter -... -modparam("presence_xml", "force_active", 1) -... - -1.3.2. pidf_manipulation (int) - - Setting this parameter to 1 enables the features described in - RFC 4827. It gives the possibility to have a permanent state - notified to the users even in the case in which the phone is - not online. The presence document is taken from the xcap server - and aggregated together with the other presence information, if - any exist, for each Notify that is sent to the watchers. It is - also possible to have information notified even if not issuing - any Publish (useful for services such as email, SMS, MMS). - - Default value is “0”. - - Example 1.2. Set pidf_manipulation parameter -... -modparam("presence_xml", "pidf_manipulation", 1) -... - -1.3.3. xcap_server (str) - - The address of the xcap servers used for storage. This - parameter is compulsory if the integrated_xcap_server parameter - is not set. It can be set more that once, to construct an - address list of trusted XCAP servers. - - Example 1.3. Set xcap_server parameter -... -modparam("presence_xml", "xcap_server", "xcap_server.example.org") -modparam("presence_xml", "xcap_server", "xcap_server.ag.org") -... - -1.3.4. pres_rules_auid (str) - - This parameter should be configured if you are using the non - integrated xcap mode and you need to use another pres-rules - auid than the default 'pres-rules'. - - Example 1.4. Set pres_rules_auid parameter -... -modparam("presence_xml", "pres_rules_auid", "org.openmobilealliance.pres --rules") -... - -1.3.5. pres_rules_filename (str) - - This parameter should be configured if you are using the non - integrated xcap mode and you need to configure another filename - than the default 'index'. - - Example 1.5. Set pres_rules_filename parameter -... -modparam("presence_xml", "pres_rules_filename", "pres-rules") -... - -1.3.6. generate_offline_body (str) - - This parameter should be set to 0 if you want to prevent - OpenSIPS from automatically generating a PIDF body when a - publication expires or is explicitly terminated (a PUBLISH - request is received with Expires: 0). - - Example 1.6. Set generate_offline_body parameter -... -modparam("presence_xml", "generate_offline_body", 0) -... - -1.4. Exported Functions - - None to be used in configuration file. - -1.5. Installation - - The module requires 1 table in OpenSIPS database: xcap. The SQL - syntax to create it can be found in presence-create.sql script - in the database directories in the opensips/scripts folder. You - can also find the complete database documentation on the - project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer Guide - - The module exports no function to be used in other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 124 54 4745 1776 - 2. Saúl Ibarra Corretgé (@saghul) 30 9 1499 471 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 28 24 80 130 - 4. Razvan Crainea (@razvancrainea) 15 13 40 32 - 5. Liviu Chircu (@liviuchircu) 14 11 45 71 - 6. Daniel-Constantin Mierla (@miconda) 8 6 15 14 - 7. Henning Westerholt (@henningw) 6 4 45 50 - 8. Maksym Sobolyev (@sobomax) 4 2 4 4 - 9. Dan Pascu (@danpascu) 4 2 3 3 - 10. Ovidiu Sas (@ovidiusas) 3 2 6 0 - - All remaining contributors: Kennard White, Vlad Paiu - (@vladpaiu), Walter Doekes (@wdoekes), Konstantin Bokarius, - Alexandra Titoc, Peter Lemenkov (@lemenkov), UnixDev, Zero King - (@l2dy), Edson Gellert Schubert, Denis Bilenko, Vlad Patrascu - (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Nov 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2020 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Dan Pascu (@danpascu) Oct 2007 - Nov 2018 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 10. Saúl Ibarra Corretgé (@saghul) May 2012 - Mar 2013 - - All remaining contributors: Anca Vamanu, Vlad Paiu (@vladpaiu), - Ovidiu Sas (@ovidiusas), Kennard White, Walter Doekes - (@wdoekes), UnixDev, Denis Bilenko, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl - Ibarra Corretgé (@saghul), Razvan Crainea (@razvancrainea), - Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Dan Pascu (@danpascu). - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/presence_xml/README.md b/modules/presence_xml/README.md new file mode 100644 index 00000000000..e12d2ecf5dc --- /dev/null +++ b/modules/presence_xml/README.md @@ -0,0 +1,187 @@ +--- +title: "Presence_XML Module" +description: "The module does specific handling for notify-subscribe events using xml bodies." +--- + +## Admin Guide + + +### Overview + + +The module does specific handling for notify-subscribe events using xml bodies. +It is used with the general event handling module, presence. It constructs and adds +3 events to it: presence, presence.winfo, dialog;sla. + + +This module takes the xcap permission rule documents from xcap_table. + +The presence permission rules are interpreted according to the specifications +in RFC 4745 and RFC 5025. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. +- *presence*. +- *signaling*. +- *xcap*. +- *xcap_client*. +Only compulsory if not using an integrated xcap server +(if 'integrated_xcap_server' parameter is not set). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml-dev*. + + +### Exported Parameters + + +#### force_active (int) + + +This parameter is used for permissions when handling Subscribe messages. +If set to 1, subscription state is considered active and the presentity +is not queried for permissions(should be set to 1 if not using an xcap +server). +Otherwise,the xcap server is queried and the subscription states is +according to user defined permission rules. If no rules are defined for +a certain watcher, the subscriptions remains in pending state and the +Notify sent will have no body. + + +> [!NOTE] +> When switching from one value to another, the watchers table must be emptied. + + +*Default value is "0".* + + +```opensips title="Set force_active parameter" +... +modparam("presence_xml", "force_active", 1) +... +``` + + +#### pidf_manipulation (int) + + +Setting this parameter to 1 enables the features described in RFC 4827. +It gives the possibility to have a permanent state notified to the users +even in the case in which the phone is not online. The presence document +is taken from the xcap server and aggregated together with the other +presence information, if any exist, for each Notify that is sent to the +watchers. It is also possible to have information notified even if not +issuing any Publish (useful for services such as email, SMS, MMS). + + +*Default value is "0".* + + +```opensips title="Set pidf_manipulation parameter" +... +modparam("presence_xml", "pidf_manipulation", 1) +... +``` + + +#### xcap_server (str) + + +The address of the xcap servers used for storage. +This parameter is compulsory if the integrated_xcap_server parameter +is not set. It can be set more that once, to construct an address +list of trusted XCAP servers. + + +```opensips title="Set xcap_server parameter" +... +modparam("presence_xml", "xcap_server", "xcap_server.example.org") +modparam("presence_xml", "xcap_server", "xcap_server.ag.org") +... +``` + + +#### pres_rules_auid (str) + + +This parameter should be configured if you are using the non integrated xcap +mode and you need to use another pres-rules auid than the default 'pres-rules'. + + +```opensips title="Set pres_rules_auid parameter" +... +modparam("presence_xml", "pres_rules_auid", "org.openmobilealliance.pres-rules") +... +``` + + +#### pres_rules_filename (str) + + +This parameter should be configured if you are using the non integrated xcap +mode and you need to configure another filename than the default 'index'. + + +```opensips title="Set pres_rules_filename parameter" +... +modparam("presence_xml", "pres_rules_filename", "pres-rules") +... +``` + + +#### generate_offline_body (str) + + +This parameter should be set to 0 if you want to prevent OpenSIPS from automatically +generating a PIDF body when a publication expires or is explicitly terminated +(a PUBLISH request is received with Expires: 0). + + +```opensips title="Set generate_offline_body parameter" +... +modparam("presence_xml", "generate_offline_body", 0) +... +``` + + +### Exported Functions + + +None to be used in configuration file. + + +### Installation + + +The module requires 1 table in OpenSIPS database: xcap. The SQL +syntax to create it can be found in presence-create.sql +script in the database directories in the opensips/scripts folder. +You can also find the complete database documentation on the +project webpage, https://opensips.org/docs/db/db-schema-devel.html. + + +## Developer Guide + + +The module exports no function to be used in other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/presence_xml/add_events.c b/modules/presence_xml/add_events.c index 2ac244da5cc..fc083708169 100644 --- a/modules/presence_xml/add_events.c +++ b/modules/presence_xml/add_events.c @@ -72,13 +72,11 @@ int xml_publ_handl(struct sip_msg* msg, int* sent_reply) } xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); return 1; error: xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); return -1; } @@ -124,14 +122,12 @@ str* bla_set_version(subs_t* subs, str* body) xmlFreeDoc(doc); - xmlMemoryDump(); xmlCleanupParser(); return new_body; error: if(doc) xmlFreeDoc(doc); - xmlMemoryDump(); xmlCleanupParser(); return 0; } @@ -210,4 +206,3 @@ int xml_add_events(void) return 0; } - diff --git a/modules/presence_xml/doc/contributors.xml b/modules/presence_xml/doc/contributors.xml deleted file mode 100644 index 21898773384..00000000000 --- a/modules/presence_xml/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 124 - 54 - 4745 - 1776 - - - 2. - Saúl Ibarra Corretgé (@saghul) - 30 - 9 - 1499 - 471 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 28 - 24 - 80 - 130 - - - 4. - Razvan Crainea (@razvancrainea) - 15 - 13 - 40 - 32 - - - 5. - Liviu Chircu (@liviuchircu) - 14 - 11 - 45 - 71 - - - 6. - Daniel-Constantin Mierla (@miconda) - 8 - 6 - 15 - 14 - - - 7. - Henning Westerholt (@henningw) - 6 - 4 - 45 - 50 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 4 - - - 9. - Dan Pascu (@danpascu) - 4 - 2 - 3 - 3 - - - 10. - Ovidiu Sas (@ovidiusas) - 3 - 2 - 6 - 0 - - - -
-All remaining contributors: Kennard White, Vlad Paiu (@vladpaiu), Walter Doekes (@wdoekes), Konstantin Bokarius, Alexandra Titoc, Peter Lemenkov (@lemenkov), UnixDev, Zero King (@l2dy), Edson Gellert Schubert, Denis Bilenko, Vlad Patrascu (@rvlad-patrascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Nov 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2020 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Dan Pascu (@danpascu) - Oct 2007 - Nov 2018 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 10. - Saúl Ibarra Corretgé (@saghul) - May 2012 - Mar 2013 - - - -
-All remaining contributors: Anca Vamanu, Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Kennard White, Walter Doekes (@wdoekes), UnixDev, Denis Bilenko, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Razvan Crainea (@razvancrainea), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dan Pascu (@danpascu). -
- -
diff --git a/modules/presence_xml/doc/presence_xml.xml b/modules/presence_xml/doc/presence_xml.xml deleted file mode 100644 index a71954dfcb8..00000000000 --- a/modules/presence_xml/doc/presence_xml.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Presence_XML Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - - - diff --git a/modules/presence_xml/doc/presence_xml_admin.xml b/modules/presence_xml/doc/presence_xml_admin.xml deleted file mode 100644 index ab5fdbe88c9..00000000000 --- a/modules/presence_xml/doc/presence_xml_admin.xml +++ /dev/null @@ -1,222 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module does specific handling for notify-subscribe events using xml bodies. - It is used with the general event handling module, presence. It constructs and adds - 3 events to it: presence, presence.winfo, dialog;sla. - - - This module takes the xcap permission rule documents from xcap_table. - - The presence permission rules are interpreted according to the specifications - in RFC 4745 and RFC 5025. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module. - - - - - presence. - - - - - signaling. - - - - - xcap. - - - - - xcap_client. - - - Only compulsory if not using an integrated xcap server - (if 'integrated_xcap_server' parameter is not set). - - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml-dev. - - - - -
-
- -
- Exported Parameters -
- <varname>force_active</varname> (int) - - This parameter is used for permissions when handling Subscribe messages. - If set to 1, subscription state is considered active and the presentity - is not queried for permissions(should be set to 1 if not using an xcap - server). - Otherwise,the xcap server is queried and the subscription states is - according to user defined permission rules. If no rules are defined for - a certain watcher, the subscriptions remains in pending state and the - Notify sent will have no body. - - - Note: When switching from one value to another, the watchers table must - be emptied. - - - Default value is 0. - - - - Set <varname>force_active</varname> parameter - -... -modparam("presence_xml", "force_active", 1) -... - - -
-
- <varname>pidf_manipulation</varname> (int) - - Setting this parameter to 1 enables the features described in RFC 4827. - It gives the possibility to have a permanent state notified to the users - even in the case in which the phone is not online. The presence document - is taken from the xcap server and aggregated together with the other - presence information, if any exist, for each Notify that is sent to the - watchers. It is also possible to have information notified even if not - issuing any Publish (useful for services such as email, SMS, MMS). - - - Default value is 0. - - - - Set <varname>pidf_manipulation</varname> parameter - -... -modparam("presence_xml", "pidf_manipulation", 1) -... - - -
-
- <varname>xcap_server</varname> (str) - - The address of the xcap servers used for storage. - This parameter is compulsory if the integrated_xcap_server parameter - is not set. It can be set more that once, to construct an address - list of trusted XCAP servers. - - Set <varname>xcap_server</varname> parameter - -... -modparam("presence_xml", "xcap_server", "xcap_server.example.org") -modparam("presence_xml", "xcap_server", "xcap_server.ag.org") -... - - -
-
- <varname>pres_rules_auid</varname> (str) - - This parameter should be configured if you are using the non integrated xcap - mode and you need to use another pres-rules auid than the default 'pres-rules'. - - - Set <varname>pres_rules_auid</varname> parameter - -... -modparam("presence_xml", "pres_rules_auid", "org.openmobilealliance.pres-rules") -... - - -
- -
- <varname>pres_rules_filename</varname> (str) - - This parameter should be configured if you are using the non integrated xcap - mode and you need to configure another filename than the default 'index'. - - - Set <varname>pres_rules_filename</varname> parameter - -... -modparam("presence_xml", "pres_rules_filename", "pres-rules") -... - - -
- -
- <varname>generate_offline_body</varname> (str) - - This parameter should be set to 0 if you want to prevent OpenSIPS from automatically - generating a PIDF body when a publication expires or is explicitly terminated - (a PUBLISH request is received with Expires: 0). - - - Set <varname>generate_offline_body</varname> parameter - -... -modparam("presence_xml", "generate_offline_body", 0) -... - - -
- - - -
-
- Exported Functions - - None to be used in configuration file. - -
- -
- Installation - - The module requires 1 table in OpenSIPS database: xcap. The SQL - syntax to create it can be found in presence-create.sql - script in the database directories in the opensips/scripts folder. - You can also find the complete database documentation on the - project webpage, &osipsdbdocs;. - -
- -
- diff --git a/modules/presence_xml/doc/presence_xml_devel.xml b/modules/presence_xml/doc/presence_xml_devel.xml deleted file mode 100644 index cffc9fe5cd0..00000000000 --- a/modules/presence_xml/doc/presence_xml_devel.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - &develguide; - - The module exports no function to be used in other &osips; modules. - - - diff --git a/modules/prometheus/README b/modules/prometheus/README deleted file mode 100644 index e4cfc5b5813..00000000000 --- a/modules/prometheus/README +++ /dev/null @@ -1,428 +0,0 @@ -Prometheus Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. External Libraries or Applications - 1.2.2. OpenSIPS Modules - - 1.3. Exported Parameters - - 1.3.1. root(string) - 1.3.2. prefix(string) - 1.3.3. group_prefix(string) - 1.3.4. delimiter(string) - 1.3.5. group_label(string) - 1.3.6. group_mode(int) - 1.3.7. statistics(string) - 1.3.8. labels(string) - 1.3.9. script_route(string) - - 1.4. Exported Functions - - 1.4.1. prometheus_declare_stat(name, [type], [help]) - - 1.4.2. prometheus_push_stat(value, [label_name], - [label_value]) - - 1.5. Examples - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set root parameter - 1.2. Set prefix parameter - 1.3. Set group_prefix parameter - 1.4. Set delimiter parameter - 1.5. Set group_label parameter - 1.6. Set group_mode parameter - 1.7. Set statistics parameter - 1.8. Set statistics parameter - 1.9. Set script_route parameter - 1.10. prometheus_declare_stat usage - 1.11. prometheus_push_stat usage - 1.12. Prometheus Scrape Config - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a HTTP interface for the Prometheus - monitoring system, allowing it to fetch different statistics - from OpenSIPS. - - In order to use it, you have to explicitely define the - statistics you want to provide by listing them in the - statistics parameter. - - Currently only counter and gauge metrics types are supported by - the module, and whether to choose one or the other for a - specific statistic is dictated by the way that statistic was - defined either internally, or explicitely through the variable - parameter of the statistics module. - - Each exported statistic comes with a group label that indicates - the group it belongs to. - -1.2. Dependencies - -1.2.1. External Libraries or Applications - - None - -1.2.2. OpenSIPS Modules - - The following modules must be loaded before this module: - * httpd module. - -1.3. Exported Parameters - -1.3.1. root(string) - - Specifies the root metrics path Promethus uses to query the - stats: http://[opensips_IP]:[opensips_httpd_port]/[root] - - The default value is "metrics". - - Example 1.1. Set root parameter -... -modparam("prometheus", "root", "prometheus") -... - -1.3.2. prefix(string) - - Appends a prefix to each statistic exported. - - The default value is "opensips". - - Example 1.2. Set prefix parameter -... -modparam("prometheus", "prefix", "opensips_1") -... - -1.3.3. group_prefix(string) - - Appends a prefix to the name of the group the statistic belongs - to. - - The default value is "" (no group prefix). - - Example 1.3. Set group_prefix parameter -... -modparam("prometheus", "group_prefix", "opensips") -... - -1.3.4. delimiter(string) - - Specifies the delimiter to be used to separate prefix and - group_prefix. - - The default value is "_". - - Example 1.4. Set delimiter parameter -... -modparam("prometheus", "delimiter", "-") -... - -1.3.5. group_label(string) - - Specifies the label used to store the group when group_mode is - 2. - - The default value is "group". - - Example 1.5. Set group_label parameter -... -modparam("prometheus", "group_label", "grp") -... - -1.3.6. group_mode(int) - - Specifies how the group of the statistic should be provisioned - to Prometheus. Available modes are: - * 0 - do not send the statistics groups. - * 1 - send the group in the name of the statstic. - For example, timestamp statistic from the core group would - be exported as opensips_core_timestamp. Note that the - group_prefix is still attached to the group's name. - * 2 - send the group as a label of the statstic. - The name of the label is specified by the group_label - parameter. - - The default value is 0 (do not specify the group). - - Example 1.6. Set group_mode parameter -... -modparam("prometheus", "group_mode", 1) -... - -1.3.7. statistics(string) - - The statistics that are being exported by OpenSIPS, separated - by space. The list can also contain statistics groups's names - - to do that, you shall add a colon (:) at the end of the - groups's name. - - If the all value is used, then the module will expose all - available statistics - therefore any other settings of this - parameter is useless; - - This parameter can be defined multiple times. - - The default value is empty: no metric is exported. - - Example 1.7. Set statistics parameter -... -# export the number of active dialogs and the load statistics class -modparam("prometheus", "statistics", "active_dialogs load:") -... - -1.3.8. labels(string) - - Rules that define how to convert the name of a statistic within - a group to obtain the name and set of labels to be pushed in - Prometheus. - - The format is group: regex, where group represents the group of - statistics for whom the regular expression should be applied - for, and regexp is a regular expression used to match the - statistic's name and convert it to the desired name and labels. - - The regex format is - /matching_expression/substitution_expression/flags. The - substitution_expression resulted after the substituion should - result in a string with the following format: name:labels, - where name represents the name of the statistic as it will be - pushed towards Prometheus, and labels the labels, expressed as - key=value pairs separated by comma, as they are received by - Prometheus. Note that the labels string resulted is - concatenated to the other labeles as plain string - no other - transformations are performed. - - If a statistic's name within the declared group does not match - the regular, or the resulted format does not comply with the - name:labels format, the statistics transformations are ignored - and it shall be printed as a regular statistic, as if the rule - was not even used. - - This parameter can be defined multiple times, even for a single - group. However, if the statistic matches multiple regular - expressions, only the first regular expression that matches is - considered. The order they are checked is the order declared in - the script. - - The default value is empty: statistic name is provided. - - Example 1.8. Set statistics parameter -... -# convert duration_gateway to stat duration with gateway as a label -modparam("prometheus", "labels", "group: /^(.*)_(.*)$/\1:gateway=\"\2\"/ -") -... - -1.3.9. script_route(string) - - Specifies the route name to be used to for adding custom - prometheus information. - - The default value is "" - no custom route called. - - Example 1.9. Set script_route parameter -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - # * the returned JSON needs to contain an array of objects - # containing a header and a values field - # * the header field to contain the custom prometheus stats head -er - # * the values field is an array itself, of name/value objects - # used for individual stats publishing - return (1, '[{ - "header": "# TYPE opensips_total_cps gauge", - "values": [ - { - "name": "opensips_total_cps", - "value": 3 - } - ] - }, { - "header": "# TYPE opensips_disabled_rtpengine gauge", - "values": [ - { - "name": "opensips_disabled_rtpengine", - "value": 0 - } - ] - }]'); -} -... - -1.4. Exported Functions - -1.4.1. prometheus_declare_stat(name, [type], [help]) - - NOTE: this function can only be used in the route declared in - the script_route parameter. - - Declares a custom statistic exported to Prometheus server. It - specifies its type and optionally a help string. - - Parameters - * name (string) - the name of the statistic - type (string, optional) - the type of the statistic (i.e. - counter or gauge). If missing the statistic is declared as - gauge. - help (string, optional) - an optional value used to - describe the statistic meaning. If missing, it is not used. - - This function can only be used in the request route declared in - the script_route parameter. - - Example 1.10. prometheus_declare_stat usage -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - ... - prometheus_declare_stat("opensips_cps"); - prometheus_push_stat(3); - ... -} - -1.4.2. prometheus_push_stat(value, [label_name], [label_value]) - - NOTE: this function can only be used in the route declared in - the script_route parameter. - - Pushes a custom statistic value and optionally a set of labels - to the Prometheus server. - - NOTE: a statistic's value should only be pushed after it had - been declared using the prometheus_declare_stat function. - - Parameters - * value (integer) - the value of the statistic - label_name (string, optional) - used to define labels for - the pushed statistic. If the label_value parameter is - missing, this parameter is appended to the name of the - statisic - this means that it should contain the whole set - of labels for the value (including curly brackets). If the - label_value is provided as well, then the parameter should - only contain one label's name. - label_value (string, optional) - the value that should be - used for the label_name parameter label. - - This function can only be used in the request route declared in - the script_route parameter. - - Example 1.11. prometheus_push_stat usage -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - ... - prometheus_declare_stat("opensips_cps"); - prometheus_push_stat(3); # no label is being used - prometheus_declare_stat("opensips_cc"); - # the next two are equivalent - prometheus_push_stat(10, "{gateway=\"gw1\"}"); # no label is bei -ng used - prometheus_push_stat(10, "gateway", "gw1"); # same as the above - ... -} - -1.5. Examples - - In order to have Prometheus query OpenSIPS for statistics, you - need to tell him where to get statistics from. To do that, you - should define a scarpe job in Prometheus's scrape_configs - config, indicating the IP and port you've configured the httpd - module to listen on (default: 0.0.0.0:8888). - - Example 1.12. Prometheus Scrape Config - -scrape_configs: - - job_name: opensips - - static_configs: - - targets: ['localhost:8888'] - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 37 20 1540 223 - 2. Maksym Sobolyev (@sobomax) 4 2 2 3 - 3. Dudu Ben Moshe 4 1 272 0 - 4. Vlad Paiu (@vladpaiu) 3 1 6 6 - 5. Ovidiu Sas (@ovidiusas) 3 1 6 5 - 6. Liviu Chircu (@liviuchircu) 3 1 1 1 - 7. OpenSIPS 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ovidiu Sas (@ovidiusas) Apr 2025 - Apr 2025 - 2. Razvan Crainea (@razvancrainea) Feb 2021 - Nov 2024 - 3. Vlad Paiu (@vladpaiu) May 2024 - May 2024 - 4. Dudu Ben Moshe Feb 2024 - Feb 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Liviu Chircu (@liviuchircu) Aug 2022 - Aug 2022 - 7. OpenSIPS Feb 2021 - Feb 2021 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ovidiu Sas (@ovidiusas), Razvan Crainea - (@razvancrainea), Dudu Ben Moshe, Liviu Chircu (@liviuchircu), - OpenSIPS. - - Documentation Copyrights: - - Copyright © 2021 www.opensips-solutions.com diff --git a/modules/prometheus/README.md b/modules/prometheus/README.md new file mode 100644 index 00000000000..1320af3a46e --- /dev/null +++ b/modules/prometheus/README.md @@ -0,0 +1,405 @@ +--- +title: "Prometheus Module" +description: "This module provides a HTTP interface for the [Prometheus](https://prometheus.io/) monitoring system, allowing it to fetch different statistics from OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module provides a HTTP interface for the +[Prometheus](https://prometheus.io/) +monitoring system, allowing it to fetch different +statistics from OpenSIPS. + + +In order to use it, you have to explicitely define the +statistics you want to provide by listing them in the +[statistics](#param_statistics) parameter. + + +Currently only *counter* and *gauge* +metrics types are supported by the module, and whether to choose +one or the other for a specific statistic is dictated by the way that +statistic was defined either internally, or explicitely through the +*variable* parameter of the *statistics* +module. + + +Each exported statistic comes with a *group* label that +indicates the group it belongs to. + + +### Dependencies + + +#### External Libraries or Applications + + +None + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *httpd* module. + + +### Exported Parameters + + +#### root(string) + + +Specifies the root metrics path Promethus uses to query the stats: +*http://[opensips_IP]:[opensips_httpd_port]/[root]* + + +*The default value is "metrics".* + + +```opensips title="Set root parameter" +... +modparam("prometheus", "root", "prometheus") +... +``` + + +#### prefix(string) + + +Appends a prefix to each statistic exported. + + +*The default value is "opensips".* + + +```opensips title="Set prefix parameter" +... +modparam("prometheus", "prefix", "opensips_1") +... +``` + + +#### group_prefix(string) + + +Appends a prefix to the name of the group the statistic belongs to. + + +*The default value is "" (no group prefix).* + + +```opensips title="Set group_prefix parameter" +... +modparam("prometheus", "group_prefix", "opensips") +... +``` + + +#### delimiter(string) + + +Specifies the delimiter to be used to separate *prefix* +and *group_prefix*. + + +*The default value is "_".* + + +```opensips title="Set delimiter parameter" +... +modparam("prometheus", "delimiter", "-") +... +``` + + +#### group_label(string) + + +Specifies the label used to store the group when *group_mode* is 2. + + +*The default value is "group".* + + +```opensips title="Set group_label parameter" +... +modparam("prometheus", "group_label", "grp") +... +``` + + +#### group_mode(int) + + +Specifies how the group of the statistic should be provisioned to +Prometheus. Available modes are: + + +- *0* - do not send the statistics groups. +- *1* - send the group in the name of the statstic. +timestamp +core +opensips_core_timestamp +group_prefix +- *2* - send the group as a label of the statstic. +group_label + + +*The default value is 0 (do not specify the group).* + + +```opensips title="Set group_mode parameter" +... +modparam("prometheus", "group_mode", 1) +... +``` + + +#### statistics(string) + + +The statistics that are being exported by OpenSIPS, separated by space. +The list can also contain statistics groups's names - to do that, you shall +add a colon (*:*) at the end of the groups's name. + + +If the *all* value is used, then the module will expose +all available statistics - therefore any other settings of this parameter +is useless; + + +This parameter can be defined multiple times. + + +*The default value is empty: no metric is exported.* + + +```opensips title="Set statistics parameter" +... +# export the number of active dialogs and the load statistics class +modparam("prometheus", "statistics", "active_dialogs load:") +... +``` + + +#### labels(string) + + +Rules that define how to convert the name of a statistic +within a group to obtain the name and set of labels to be +pushed in Prometheus. + + +The format is *group: regex*, where +*group* represents the group of statistics +for whom the regular expression should be applied for, and +*regexp* is a regular expression used to +match the statistic's name and convert it to the desired name +and labels. + + +The *regex* format is +*/matching_expression/substitution_expression/flags*. +The *substitution_expression* resulted after +the substituion should result in a string with the following +format: *name:labels*, where +*name* represents the name of the statistic +as it will be pushed towards Prometheus, and *labels* +the labels, expressed as *key=value* pairs +separated by comma, as they are received by Prometheus. +*Note* that the *labels* +string resulted is concatenated to the other labeles as +plain string - no other transformations are performed. + + +If a statistic's name within the declared group does not match the +regular, or the resulted format does not comply with the +*name:labels* format, the statistics transformations +are ignored and it shall be printed as a regular statistic, as if +the rule was not even used. + + +This parameter can be defined multiple times, even for a single group. +However, if the statistic matches multiple regular expressions, only +the first regular expression that matches is considered. The order +they are checked is the order declared in the script. + + +*The default value is empty: statistic name is provided.* + + +```opensips title="Set statistics parameter" +... +# convert duration_gateway to stat duration with gateway as a label +modparam("prometheus", "labels", "group: /^(.*)_(.*)$/\1:gateway=\"\2\"/") +... +``` + + +#### script_route(string) + + +Specifies the route name to be used to for adding custom prometheus information. + + +*The default value is "" - no custom route called.* + + +```opensips title="Set script_route parameter" +... +modparam("prometheus", "script_route", "my_custom_prometheus_route") +... +route[my_custom_prometheus_route] { + # * the returned JSON needs to contain an array of objects + # containing a header and a values field + # * the header field to contain the custom prometheus stats header + # * the values field is an array itself, of name/value objects + # used for individual stats publishing + return (1, '[{ + "header": "# TYPE opensips_total_cps gauge", + "values": [ + { + "name": "opensips_total_cps", + "value": 3 + } + ] + }, { + "header": "# TYPE opensips_disabled_rtpengine gauge", + "values": [ + { + "name": "opensips_disabled_rtpengine", + "value": 0 + } + ] + }]'); +} +... +``` + + +### Exported Functions + + +#### prometheus_declare_stat(name, [type], [help]) + + +> [!NOTE] +> This function can only be used in the +> route declared in the [script route](#param_script_route) parameter. + + +Declares a custom statistic exported to Prometheus server. It specifies +its type and optionally a help string. + + +Parameters + + +- *name* (string) - the name of the statistic +*type* (string, optional) - the type of the +statistic (i.e. *counter* or *gauge*). +If missing the statistic is declared as *gauge*. +*help* (string, optional) - an optional value +used to describe the statistic meaning. If missing, it is not used. + + +This function can only be used in the request +route declared in the [script route](#param_script_route) parameter. + + +```opensips title="prometheus_declare_stat usage" +... +modparam("prometheus", "script_route", "my_custom_prometheus_route") +... +route[my_custom_prometheus_route] { + ... + prometheus_declare_stat("opensips_cps"); + prometheus_push_stat(3); + ... +} +``` + + +#### prometheus_push_stat(value, [label_name], [label_value]) + + +> [!NOTE] +> This function can only be used in the +> route declared in the [script route](#param_script_route) parameter. + + +Pushes a custom statistic value and optionally a set of labels +to the Prometheus server. + + +> [!NOTE] +> A statistic's value should only be pushed +> after it had been declared using the +> [prometheus declare stat](#func_prometheus_declare_stat) function. + + +Parameters + + +- *value* (integer) - the value of the statistic +*label_name* (string, optional) - used to define +labels for the pushed statistic. If the *label_value* +parameter is missing, this parameter is appended to the name of the +statisic - this means that it should contain the whole set of labels +for the value (including curly brackets). If the +*label_value* is provided as well, then the parameter +should only contain one label's name. +*label_value* (string, optional) - the value that +should be used for the *label_name* parameter label. + + +This function can only be used in the request +route declared in the [script route](#param_script_route) parameter. + + +```opensips title="prometheus_push_stat usage" +... +modparam("prometheus", "script_route", "my_custom_prometheus_route") +... +route[my_custom_prometheus_route] { + ... + prometheus_declare_stat("opensips_cps"); + prometheus_push_stat(3); # no label is being used + prometheus_declare_stat("opensips_cc"); + # the next two are equivalent + prometheus_push_stat(10, "{gateway=\"gw1\"}"); # no label is being used + prometheus_push_stat(10, "gateway", "gw1"); # same as the above + ... +} +``` + + +### Examples + + +In order to have Prometheus query OpenSIPS for statistics, you need to +tell him where to get statistics from. To do that, you should define +a scarpe job in Prometheus's *scrape_configs* config, +indicating the IP and port you've configured the *httpd* +module to listen on (default: *0.0.0.0:8888*). + + +```c title="Prometheus Scrape Config" +scrape_configs: + - job_name: opensips + + static_configs: + - targets: ['localhost:8888'] +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/prometheus/doc/contributors.xml b/modules/prometheus/doc/contributors.xml deleted file mode 100644 index 1fe768bb621..00000000000 --- a/modules/prometheus/doc/contributors.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 37 - 20 - 1540 - 223 - - - 2. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - 3. - Dudu Ben Moshe - 4 - 1 - 272 - 0 - - - 4. - Vlad Paiu (@vladpaiu) - 3 - 1 - 6 - 6 - - - 5. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 6 - 5 - - - 6. - Liviu Chircu (@liviuchircu) - 3 - 1 - 1 - 1 - - - 7. - OpenSIPS - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ovidiu Sas (@ovidiusas) - Apr 2025 - Apr 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Feb 2021 - Nov 2024 - - - 3. - Vlad Paiu (@vladpaiu) - May 2024 - May 2024 - - - 4. - Dudu Ben Moshe - Feb 2024 - Feb 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Liviu Chircu (@liviuchircu) - Aug 2022 - Aug 2022 - - - 7. - OpenSIPS - Feb 2021 - Feb 2021 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ovidiu Sas (@ovidiusas), Razvan Crainea (@razvancrainea), Dudu Ben Moshe, Liviu Chircu (@liviuchircu), OpenSIPS. -
- -
diff --git a/modules/prometheus/doc/prometheus.xml b/modules/prometheus/doc/prometheus.xml deleted file mode 100644 index a5e91aa3b49..00000000000 --- a/modules/prometheus/doc/prometheus.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Prometheus Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2021 &osipssol; - - - - diff --git a/modules/prometheus/doc/prometheus_admin.xml b/modules/prometheus/doc/prometheus_admin.xml deleted file mode 100644 index 918a02b3327..00000000000 --- a/modules/prometheus/doc/prometheus_admin.xml +++ /dev/null @@ -1,442 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides a HTTP interface for the - Prometheus - monitoring system, allowing it to fetch different - statistics from OpenSIPS. - - - In order to use it, you have to explicitely define the - statistics you want to provide by listing them in the - parameter. - - - Currently only counter and gauge - metrics types are supported by the module, and whether to choose - one or the other for a specific statistic is dictated by the way that - statistic was defined either internally, or explicitely through the - variable parameter of the statistics - module. - - - Each exported statistic comes with a group label that - indicates the group it belongs to. - -
- -
- Dependencies -
- External Libraries or Applications - None - -
-
- &osips; Modules - - The following modules must be loaded before this module: - - - httpd module. - - - -
-
- -
- Exported Parameters -
- <varname>root</varname>(string) - - Specifies the root metrics path Promethus uses to query the stats: - http://[opensips_IP]:[opensips_httpd_port]/[root] - - - The default value is "metrics". - - - Set <varname>root</varname> parameter - -... -modparam("prometheus", "root", "prometheus") -... - - -
- -
- <varname>prefix</varname>(string) - - Appends a prefix to each statistic exported. - - - The default value is "opensips". - - - Set <varname>prefix</varname> parameter - -... -modparam("prometheus", "prefix", "opensips_1") -... - - -
- -
- <varname>group_prefix</varname>(string) - - Appends a prefix to the name of the group the statistic belongs to. - - - The default value is "" (no group prefix). - - - Set <varname>group_prefix</varname> parameter - -... -modparam("prometheus", "group_prefix", "opensips") -... - - -
- -
- <varname>delimiter</varname>(string) - - Specifies the delimiter to be used to separate prefix - and group_prefix. - - - The default value is "_". - - - Set <varname>delimiter</varname> parameter - -... -modparam("prometheus", "delimiter", "-") -... - - -
- -
- <varname>group_label</varname>(string) - - Specifies the label used to store the group when group_mode is 2. - - - The default value is "group". - - - Set <varname>group_label</varname> parameter - -... -modparam("prometheus", "group_label", "grp") -... - - -
- -
- <varname>group_mode</varname>(int) - - Specifies how the group of the statistic should be provisioned to - Prometheus. Available modes are: - - - 0 - do not send the statistics groups. - - - 1 - send the group in the name of the statstic. - For example, timestamp statistic from the core - group would be exported as opensips_core_timestamp. Note that the - group_prefix is still attached to the group's name. - - - 2 - send the group as a label of the statstic. - The name of the label is specified by the group_label parameter. - - - - - The default value is 0 (do not specify the group). - - - Set <varname>group_mode</varname> parameter - -... -modparam("prometheus", "group_mode", 1) -... - - -
- -
- <varname>statistics</varname>(string) - - The statistics that are being exported by OpenSIPS, separated by space. - The list can also contain statistics groups's names - to do that, you shall - add a colon (:) at the end of the groups's name. - - - If the all value is used, then the module will expose - all available statistics - therefore any other settings of this parameter - is useless; - - - This parameter can be defined multiple times. - - - The default value is empty: no metric is exported. - - - Set <varname>statistics</varname> parameter - -... -# export the number of active dialogs and the load statistics class -modparam("prometheus", "statistics", "active_dialogs load:") -... - - -
-
- <varname>labels</varname>(string) - - Rules that define how to convert the name of a statistic - within a group to obtain the name and set of labels to be - pushed in Prometheus. - - - The format is group: regex, where - group represents the group of statistics - for whom the regular expression should be applied for, and - regexp is a regular expression used to - match the statistic's name and convert it to the desired name - and labels. - - - The regex format is - /matching_expression/substitution_expression/flags. - The substitution_expression resulted after - the substituion should result in a string with the following - format: name:labels, where - name represents the name of the statistic - as it will be pushed towards Prometheus, and labels - the labels, expressed as key=value pairs - separated by comma, as they are received by Prometheus. - Note that the labels - string resulted is concatenated to the other labeles as - plain string - no other transformations are performed. - - - If a statistic's name within the declared group does not match the - regular, or the resulted format does not comply with the - name:labels format, the statistics transformations - are ignored and it shall be printed as a regular statistic, as if - the rule was not even used. - - - This parameter can be defined multiple times, even for a single group. - However, if the statistic matches multiple regular expressions, only - the first regular expression that matches is considered. The order - they are checked is the order declared in the script. - - - The default value is empty: statistic name is provided. - - - Set <varname>statistics</varname> parameter - -... -# convert duration_gateway to stat duration with gateway as a label -modparam("prometheus", "labels", "group: /^(.*)_(.*)$/\1:gateway=\"\2\"/") -... - - -
- -
- <varname>script_route</varname>(string) - - Specifies the route name to be used to for adding custom prometheus information. - - - The default value is "" - no custom route called. - - - Set <varname>script_route</varname> parameter - -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - # * the returned JSON needs to contain an array of objects - # containing a header and a values field - # * the header field to contain the custom prometheus stats header - # * the values field is an array itself, of name/value objects - # used for individual stats publishing - return (1, '[{ - "header": "# TYPE opensips_total_cps gauge", - "values": [ - { - "name": "opensips_total_cps", - "value": 3 - } - ] - }, { - "header": "# TYPE opensips_disabled_rtpengine gauge", - "values": [ - { - "name": "opensips_disabled_rtpengine", - "value": 0 - } - ] - }]'); -} -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">prometheus_declare_stat(name, [type], [help])</function> - - - NOTE: this function can only be used in the - route declared in the parameter. - - - Declares a custom statistic exported to Prometheus server. It specifies - its type and optionally a help string. - - Parameters - - - name (string) - the name of the statistic - - type (string, optional) - the type of the - statistic (i.e. counter or gauge). - If missing the statistic is declared as gauge. - - help (string, optional) - an optional value - used to describe the statistic meaning. If missing, it is not used. - - - - - This function can only be used in the request - route declared in the parameter. - - - <function moreinfo="none">prometheus_declare_stat</function> usage - -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - ... - prometheus_declare_stat("opensips_cps"); - prometheus_push_stat(3); - ... -} - - -
-
- - <function moreinfo="none">prometheus_push_stat(value, [label_name], [label_value])</function> - - - NOTE: this function can only be used in the - route declared in the parameter. - - - Pushes a custom statistic value and optionally a set of labels - to the Prometheus server. - - - NOTE: a statistic's value should only be pushed - after it had been declared using the - function. - - Parameters - - - value (integer) - the value of the statistic - - label_name (string, optional) - used to define - labels for the pushed statistic. If the label_value - parameter is missing, this parameter is appended to the name of the - statisic - this means that it should contain the whole set of labels - for the value (including curly brackets). If the - label_value is provided as well, then the parameter - should only contain one label's name. - - label_value (string, optional) - the value that - should be used for the label_name parameter label. - - - - - This function can only be used in the request - route declared in the parameter. - - - <function moreinfo="none">prometheus_push_stat</function> usage - -... -modparam("prometheus", "script_route", "my_custom_prometheus_route") -... -route[my_custom_prometheus_route] { - ... - prometheus_declare_stat("opensips_cps"); - prometheus_push_stat(3); # no label is being used - prometheus_declare_stat("opensips_cc"); - # the next two are equivalent - prometheus_push_stat(10, "{gateway=\"gw1\"}"); # no label is being used - prometheus_push_stat(10, "gateway", "gw1"); # same as the above - ... -} - - -
-
- -
- Examples - - In order to have Prometheus query &osips; for statistics, you need to - tell him where to get statistics from. To do that, you should define - a scarpe job in Prometheus's scrape_configs config, - indicating the IP and port you've configured the httpd - module to listen on (default: 0.0.0.0:8888). - - - Prometheus Scrape Config - - - - -
- -
- diff --git a/modules/proto_bin/README b/modules/proto_bin/README deleted file mode 100644 index 8ca3ee0012f..00000000000 --- a/modules/proto_bin/README +++ /dev/null @@ -1,243 +0,0 @@ -proto_bin Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. bin_port (integer) - 1.3.2. bin_send_timeout (integer) - 1.3.3. bin_max_msg_chunks (integer) - 1.3.4. bin_async (integer) - 1.3.5. bin_async_max_postponed_chunks (integer) - 1.3.6. bin_async_local_connect_timeout (integer) - 1.3.7. bin_async_local_write_timeout (integer) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set bin_port parameter - 1.2. Set bin_send_timeout parameter - 1.3. Set bin_max_msg_chunks parameter - 1.4. Set bin_async parameter - 1.5. Set bin_async_max_postponed_chunks parameter - 1.6. Set bin_async_local_connect_timeout parameter - 1.7. Set bin_async_local_write_timeout parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The proto_bin module is a transport module which implements - Binary Interface TCP-based communication. It does not handle - TCP connections management, but only offers higher-level - primitives to read and write BIN messages over TCP. It calls - registered callback functions for every complete message - received. - - Once loaded, you will be able to define BIN listeners in your - configuration file by adding their IP and, optionally, a - listening port, similar to this example: - -... -socket= bin:127.0.0.1 # change the listening IP -socket= bin:127.0.0.1:5080 # change the listening IP and port -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. bin_port (integer) - - The default port to be used by all TCP listeners. - - Default value is 5555. - - Example 1.1. Set bin_port parameter -... -modparam("proto_bin", "bin_port", 6666) -... - -1.3.2. bin_send_timeout (integer) - - Time in milliseconds after a TCP connection will be closed if - it is not available for blocking writing in this interval (and - OpenSIPS wants to send something on it). - - Default value is 100 ms. - - Example 1.2. Set bin_send_timeout parameter -... -modparam("proto_bin", "bin_send_timeout", 200) -... - -1.3.3. bin_max_msg_chunks (integer) - - The maximum number of chunks in which a BIN message is expected - to arrive via TCP. If a received packet is more fragmented than - this, the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - Default value is 32. - - Example 1.3. Set bin_max_msg_chunks parameter -... -modparam("proto_bin", "bin_max_msg_chunks", 8) -... - -1.3.4. bin_async (integer) - - Specifies whether the TCP connect and write operations should - be done in an asynchronous mode (non-blocking connect and - write) or not. If disabled, OpenSIPS will block and wait for - TCP operations like connect and write. - - Default value is 1 (enabled). - - Example 1.4. Set bin_async parameter -... -modparam("proto_bin", "bin_async", 0) -... - -1.3.5. bin_async_max_postponed_chunks (integer) - - If bin_async is enabled, this specifies the maximum number of - BIN messages that can be stashed for later/async writing. If - the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - Default value is 1024. - - Example 1.5. Set bin_async_max_postponed_chunks parameter -... -modparam("proto_bin", "bin_async_max_postponed_chunks", 1024) -... - -1.3.6. bin_async_local_connect_timeout (integer) - - If bin_async is enabled, this specifies the number of - milliseconds that a connect will be tried in blocking mode - (optimization). If the connect operation lasts more than this, - the connect will go to async mode and will be passed to TCP - MAIN for polling. - - Default value is 100 ms. - - Example 1.6. Set bin_async_local_connect_timeout parameter -... -modparam("proto_bin", "bin_async_local_connect_timeout", 200) -... - -1.3.7. bin_async_local_write_timeout (integer) - - If bin_async is enabled, this specifies the number of - milliseconds that a write op will be tried in blocking mode - (optimization). If the write operation lasts more than this, - the write will go to async mode and will be passed to bin MAIN - for polling. - - Default value is 10 ms. - - Example 1.7. Set bin_async_local_write_timeout parameter -... -modparam("proto_bin", "tcp_async_local_write_timeout", 100) -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 29 20 62 467 - 2. Vlad Patrascu (@rvlad-patrascu) 16 4 954 140 - 3. Ionel Cerghit (@ionel-cerghit) 15 3 1196 38 - 4. Liviu Chircu (@liviuchircu) 13 10 63 63 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 9 7 29 9 - 6. Maksym Sobolyev (@sobomax) 5 3 34 36 - 7. Eseanu Marius Cristian (@eseanucristian) 4 2 1 5 - 8. Nick Altmann (@nikbyte) 3 1 4 4 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Aug 2015 - Jul 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2016 - Dec 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Oct 2021 - 5. Nick Altmann (@nikbyte) May 2021 - May 2021 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2017 - Apr 2021 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionel Cerghit (@ionel-cerghit) Jul 2015 - Dec 2016 - 9. Eseanu Marius Cristian (@eseanucristian) Jul 2015 - Jul 2015 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei - Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Ionel - Cerghit (@ionel-cerghit). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_bin/README.md b/modules/proto_bin/README.md new file mode 100644 index 00000000000..70d910f8728 --- /dev/null +++ b/modules/proto_bin/README.md @@ -0,0 +1,191 @@ +--- +title: "proto_bin Module" +description: "The **proto_bin** module is a transport module which implements Binary Interface TCP-based communication." +--- + +## Admin Guide + + +### Overview + + +The **proto_bin** module is a +transport module which implements Binary Interface TCP-based communication. It does +not handle TCP connections management, but only offers higher-level +primitives to read and write BIN messages over TCP. It calls registered +callback functions for every complete message received. + + +Once loaded, you will be able to define BIN listeners in your +configuration file by adding their IP and, optionally, a listening port, +similar to this example: + +```opensips +... +socket = bin:127.0.0.1 # change the listening IP +socket = bin:127.0.0.1:5080 # change the listening IP and port +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### bin_port (integer) + + +The default port to be used by all TCP listeners. + + +*Default value is 5555.* + + +```c title="Set bin_port parameter" +... +modparam("proto_bin", "bin_port", 6666) +... +``` + + +#### bin_send_timeout (integer) + + +Time in milliseconds after a TCP connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set bin_send_timeout parameter" +... +modparam("proto_bin", "bin_send_timeout", 200) +... +``` + + +#### bin_max_msg_chunks (integer) + + +The maximum number of chunks in which a BIN message is expected to +arrive via TCP. If a received packet is more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending very +fragmented traffic in order to decrease server performance). + + +*Default value is 32.* + + +```opensips title="Set bin_max_msg_chunks parameter" +... +modparam("proto_bin", "bin_max_msg_chunks", 8) +... +``` + + +#### bin_async (integer) + + +Specifies whether the TCP connect and write operations should be +done in an asynchronous mode (non-blocking connect and +write) or not. If disabled, OpenSIPS will block and wait for TCP +operations like connect and write. + + +*Default value is 1 (enabled).* + + +```opensips title="Set bin_async parameter" +... +modparam("proto_bin", "bin_async", 0) +... +``` + + +#### bin_async_max_postponed_chunks (integer) + + +If *bin_async* is enabled, this specifies the +maximum number of BIN messages that can be stashed for later/async +writing. If the connection pending writes exceed this number, the +connection will be marked as broken and dropped. + + +*Default value is 1024.* + + +```opensips title="Set bin_async_max_postponed_chunks parameter" +... +modparam("proto_bin", "bin_async_max_postponed_chunks", 1024) +... +``` + + +#### bin_async_local_connect_timeout (integer) + + +If *bin_async* is enabled, this specifies the +number of milliseconds that a connect will be tried in blocking +mode (optimization). If the connect operation lasts more than +this, the connect will go to async mode and will be passed to TCP +MAIN for polling. + + +*Default value is 100 ms.* + + +```opensips title="Set bin_async_local_connect_timeout parameter" +... +modparam("proto_bin", "bin_async_local_connect_timeout", 200) +... +``` + + +#### bin_async_local_write_timeout (integer) + + +If *bin_async* is enabled, this specifies the +number of milliseconds that a write op will be tried in blocking +mode (optimization). If the write operation lasts more than this, +the write will go to async mode and will be passed to bin MAIN for +polling. + + +*Default value is 10 ms.* + + +```opensips title="Set bin_async_local_write_timeout parameter" +... +modparam("proto_bin", "tcp_async_local_write_timeout", 100) +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_bin/bin_common.h b/modules/proto_bin/bin_common.h index 37f25bc7e61..90e052b3437 100644 --- a/modules/proto_bin/bin_common.h +++ b/modules/proto_bin/bin_common.h @@ -35,6 +35,17 @@ static inline void bin_parse_headers(struct tcp_req *req){ px = (unsigned int*)(req->buf + MARKER_SIZE); req->content_len = (*px); + if (req->content_len < MIN_BIN_PACKET_SIZE) { + LM_ERR("invalid BIN packet size %u\n", req->content_len); + req->error = TCP_REQ_BAD_LEN; + return; + } + if (req->content_len > BIN_MAX_BUF_LEN) { + LM_ERR("BIN packet size %u exceeds max size %zu\n", + req->content_len, (size_t)BIN_MAX_BUF_LEN); + req->error = TCP_REQ_BAD_LEN; + return; + } if(req->pos - req->buf == req->content_len){ LM_DBG("received a COMPLETE message\n"); req->complete = 1; diff --git a/modules/proto_bin/doc/contributors.xml b/modules/proto_bin/doc/contributors.xml deleted file mode 100644 index 5ff86524807..00000000000 --- a/modules/proto_bin/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 29 - 20 - 62 - 467 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 16 - 4 - 954 - 140 - - - 3. - Ionel Cerghit (@ionel-cerghit) - 15 - 3 - 1196 - 38 - - - 4. - Liviu Chircu (@liviuchircu) - 13 - 10 - 63 - 63 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 7 - 29 - 9 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 34 - 36 - - - 7. - Eseanu Marius Cristian (@eseanucristian) - 4 - 2 - 1 - 5 - - - 8. - Nick Altmann (@nikbyte) - 3 - 1 - 4 - 4 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Aug 2015 - Jul 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2016 - Dec 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Oct 2021 - - - 5. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2017 - Apr 2021 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionel Cerghit (@ionel-cerghit) - Jul 2015 - Dec 2016 - - - 9. - Eseanu Marius Cristian (@eseanucristian) - Jul 2015 - Jul 2015 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Ionel Cerghit (@ionel-cerghit). -
- -
diff --git a/modules/proto_bin/doc/proto_bin.xml b/modules/proto_bin/doc/proto_bin.xml deleted file mode 100644 index af19e010db1..00000000000 --- a/modules/proto_bin/doc/proto_bin.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_bin Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/proto_bin/doc/proto_bin_admin.xml b/modules/proto_bin/doc/proto_bin_admin.xml deleted file mode 100644 index 6f63f34dc91..00000000000 --- a/modules/proto_bin/doc/proto_bin_admin.xml +++ /dev/null @@ -1,222 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_bin module is a - transport module which implements Binary Interface TCP-based communication. It does - not handle TCP connections management, but only offers higher-level - primitives to read and write BIN messages over TCP. It calls registered - callback functions for every complete message received. - -
- - Once loaded, you will be able to define BIN listeners in your - configuration file by adding their IP and, optionally, a listening port, - similar to this example: - - -... -socket= bin:127.0.0.1 # change the listening IP -socket= bin:127.0.0.1:5080 # change the listening IP and port -... - - - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>bin_port</varname> (integer) - - The default port to be used by all TCP listeners. - - - - Default value is 5555. - - - - Set <varname>bin_port</varname> parameter - -... -modparam("proto_bin", "bin_port", 6666) -... - - -
- -
- <varname>bin_send_timeout</varname> (integer) - - Time in milliseconds after a TCP connection will be closed if it is - not available for blocking writing in this interval (and &osips; wants - to send something on it). - - - - Default value is 100 ms. - - - - Set <varname>bin_send_timeout</varname> parameter - -... -modparam("proto_bin", "bin_send_timeout", 200) -... - - -
-
- <varname>bin_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a BIN message is expected to - arrive via TCP. If a received packet is more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - - - Default value is 32. - - - - Set <varname>bin_max_msg_chunks</varname> parameter - -... -modparam("proto_bin", "bin_max_msg_chunks", 8) -... - - -
-
- <varname>bin_async</varname> (integer) - - Specifies whether the TCP connect and write operations should be - done in an asynchronous mode (non-blocking connect and - write) or not. If disabled, OpenSIPS will block and wait for TCP - operations like connect and write. - - - - Default value is 1 (enabled). - - - - Set <varname>bin_async</varname> parameter - -... -modparam("proto_bin", "bin_async", 0) -... - - -
-
- <varname>bin_async_max_postponed_chunks</varname> (integer) - - If bin_async is enabled, this specifies the - maximum number of BIN messages that can be stashed for later/async - writing. If the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - - - Default value is 1024. - - - - Set <varname>bin_async_max_postponed_chunks</varname> parameter - -... -modparam("proto_bin", "bin_async_max_postponed_chunks", 1024) -... - - -
-
- <varname>bin_async_local_connect_timeout</varname> (integer) - - If bin_async is enabled, this specifies the - number of milliseconds that a connect will be tried in blocking - mode (optimization). If the connect operation lasts more than - this, the connect will go to async mode and will be passed to TCP - MAIN for polling. - - - - Default value is 100 ms. - - - - Set <varname>bin_async_local_connect_timeout</varname> parameter - -... -modparam("proto_bin", "bin_async_local_connect_timeout", 200) -... - - -
-
- <varname>bin_async_local_write_timeout</varname> (integer) - - If bin_async is enabled, this specifies the - number of milliseconds that a write op will be tried in blocking - mode (optimization). If the write operation lasts more than this, - the write will go to async mode and will be passed to bin MAIN for - polling. - - - - Default value is 10 ms. - - - - Set <varname>bin_async_local_write_timeout</varname> parameter - -... -modparam("proto_bin", "tcp_async_local_write_timeout", 100) -... - - -
-
- -
diff --git a/modules/proto_bins/README b/modules/proto_bins/README deleted file mode 100644 index 7ea71df88fe..00000000000 --- a/modules/proto_bins/README +++ /dev/null @@ -1,318 +0,0 @@ -proto_bins Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. bins_port (integer) - 1.3.2. bins_handshake_timeout (integer) - 1.3.3. bins_send_timeout (integer) - 1.3.4. bins_max_msg_chunks (integer) - 1.3.5. bins_async (integer) - 1.3.6. bins_async_max_postponed_chunks (integer) - 1.3.7. bins_async_local_connect_timeout (integer) - 1.3.8. bins_async_handshake_timeout (integer) - 1.3.9. trace_destination (string) - 1.3.10. trace_on (int) - - 1.4. Exported MI Functions - - 1.4.1. bins_trace - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set bins_port parameter - 1.2. Set bins_handshake_timeout variable - 1.3. Set bins_send_timeout parameter - 1.4. Set bins_max_msg_chunks parameter - 1.5. Set bins_async parameter - 1.6. Set bins_async_max_postponed_chunks parameter - 1.7. Set bins_async_local_connect_timeout parameter - 1.8. Set bins_async_handshake_timeout parameter - 1.9. Set trace_destination parameter - 1.10. Set trace_on parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements a secure Binary communication protocol - over TLS, to be used by the OpenSIPS clustering engine provided - by the clusterer module. - - Once loaded, you will be able to define BINS listeners in your - configuration file by adding their IP and, optionally, a - listening port, similar to this example: - -... -socket= bins:127.0.0.1 # change the listening IP -socket= bins:127.0.0.1:5557 # change the listening IP and port -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_openssl or tls_wolfssl, depending on the desired TLS - library - * tls_mgm. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. bins_port (integer) - - The default port to be used by all BINS listeners. - - Default value is 5556. - - Example 1.1. Set bins_port parameter -... -modparam("proto_bins", "bins_port", 5557) -... - -1.3.2. bins_handshake_timeout (integer) - - Sets the timeout (in milliseconds) for the SSL/TLS handshake - sequence to complete. It may be necessary to increase this - value when using a CPU intensive cipher for the connection to - allow time for keys to be generated and processed. - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is - being initiated (outbound). - - Default value is 100. - - Example 1.2. Set bins_handshake_timeout variable - -param("proto_tls", "bins_handshake_timeout", 200) # number of millisecon -ds - - -1.3.3. bins_send_timeout (integer) - - Sets the timeout (in milliseconds) for blocking send operations - to complete. - - The send timeout is invoked for all TLS write operations, - excluding the handshake process (see: bins_handshake_timeout) - - Default value is 100 ms. - - Example 1.3. Set bins_send_timeout parameter -... -modparam("proto_bins", "bins_send_timeout", 200) -... - -1.3.4. bins_max_msg_chunks (integer) - - The maximum number of chunks in which a BINS message is - expected to arrive via TCP. If a received packet is more - fragmented than this, the connection is dropped (either the - connection is very overloaded and this leads to high - fragmentation - or we are the victim of an ongoing attack where - the attacker is sending very fragmented traffic in order to - decrease server performance). - - Default value is 32. - - Example 1.4. Set bins_max_msg_chunks parameter -... -modparam("proto_bins", "bins_max_msg_chunks", 8) -... - -1.3.5. bins_async (integer) - - Specifies whether the TCP/TLS connect and write operations - should be done in an asynchronous mode (non-blocking connect - and write) or not. If disabled, OpenSIPS will block and wait - for TCP/TLS operations like connect and write. - - Default value is 1 (enabled). - - Example 1.5. Set bins_async parameter -... -modparam("proto_bins", "bins_async", 0) -... - -1.3.6. bins_async_max_postponed_chunks (integer) - - If bins_async is enabled, this specifies the maximum number of - BINS messages that can be stashed for later/async writing. If - the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - Default value is 32. - - Example 1.6. Set bins_async_max_postponed_chunks parameter -... -modparam("proto_bins", "bins_async_max_postponed_chunks", 16) -... - -1.3.7. bins_async_local_connect_timeout (integer) - - If bin_async is enabled, this specifies the number of - milliseconds that a connect will be tried in blocking mode - (optimization). If the connect operation lasts more than this, - the connect will go to async mode and will be passed to TCP - MAIN for polling. - - Default value is 100 ms. - - Example 1.7. Set bins_async_local_connect_timeout parameter -... -modparam("proto_bins", "bins_async_local_connect_timeout", 200) -... - -1.3.8. bins_async_handshake_timeout (integer) - - If tls_async is enabled, this specifies the number of - milliseconds that a TLS handshake should be tried in blocking - mode (optimization). If the handshake operation lasts more than - this, the write will go to async mode and will be passed to tls - MAIN for polling. - - Default value is 10 ms. - - Example 1.8. Set bins_async_handshake_timeout parameter - ... - modparam("proto_tls", "bins_async_handshake_timeout", 100) - ... - -1.3.9. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. Network events such as - connect, accept and connection closed events shall be traced - along with errors that could appear in the process. For each - connection that is created an event containing information - about the client and server certificates, master key and - network layer information shall be sent. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.9. Set trace_destination parameter -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;versio -n=3") - -modparam("proto_bins", "trace_destination", "hep_dest") -... - -1.3.10. trace_on (int) - - This controls whether tracing for tls is on or not. You still - need to define trace_destinationin order to work, but this - value will be controlled using mi function bins_trace. - Default value is 0(tracing inactive). - - Example 1.10. Set trace_on parameter -... -modparam("proto_bins", "trace_on", 1) -... - -1.4. Exported MI Functions - -1.4.1. bins_trace - - Name: bins_trace - - Parameters: - * trace_mode(optional): set bins tracing on and off. This - parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - + on - + off - - MI FIFO Command Format: - opensips-cli -x mi bins_trace on - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 15 4 1118 24 - 2. Maksym Sobolyev (@sobomax) 5 3 19 20 - 3. Liviu Chircu (@liviuchircu) 5 3 13 7 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 5 3 - 5. Nick Altmann (@nikbyte) 3 1 2 2 - 6. Razvan Crainea (@razvancrainea) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jul 2025 - Jul 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2021 - May 2023 - 4. Liviu Chircu (@liviuchircu) Apr 2022 - Apr 2022 - 5. Vlad Patrascu (@rvlad-patrascu) Feb 2021 - Oct 2021 - 6. Nick Altmann (@nikbyte) May 2021 - May 2021 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_bins/README.md b/modules/proto_bins/README.md new file mode 100644 index 00000000000..86f9b0d5c56 --- /dev/null +++ b/modules/proto_bins/README.md @@ -0,0 +1,290 @@ +--- +title: "proto_bins Module" +description: "This module implements a secure Binary communication protocol over TLS, to be used by the OpenSIPS clustering engine provided by the clusterer module." +--- + +## Admin Guide + + +### Overview + + +This module implements a secure Binary communication protocol +over TLS, to be used by the OpenSIPS clustering engine provided +by the clusterer module. + + +Once loaded, you will be able to define BINS listeners in your +configuration file by adding their IP and, optionally, a +listening port, similar to this example: + +```opensips +... +socket = bins:127.0.0.1 # change the listening IP +socket = bins:127.0.0.1:5557 # change the listening IP and port +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_openssl* or *tls_wolfssl*, +depending on the desired TLS library +- *tls_mgm*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### bins_port (integer) + + +The default port to be used by all BINS listeners. + + +*Default value is 5556.* + + +```c title="Set bins_port parameter" +... +modparam("proto_bins", "bins_port", 5557) +... +``` + + +#### bins_handshake_timeout (integer) + + +Sets the timeout (in milliseconds) for the SSL/TLS handshake +sequence to complete. It may be necessary to increase this +value when using a CPU intensive cipher for the connection to +allow time for keys to be generated and processed. + + +The timeout is invoked during acceptance of a new connection +(inbound) and during the wait period when a new session is +being initiated (outbound). + + +*Default value is 100.* + + +```opensips title="Set bins_handshake_timeout variable" +param("proto_tls", "bins_handshake_timeout", 200) # number of milliseconds +``` + + +#### bins_send_timeout (integer) + + +Sets the timeout (in milliseconds) for blocking send operations +to complete. + + +The send timeout is invoked for all TLS write operations, +excluding the handshake process (see: bins_handshake_timeout) + + +*Default value is 100 ms.* + + +```opensips title="Set bins_send_timeout parameter" +... +modparam("proto_bins", "bins_send_timeout", 200) +... +``` + + +#### bins_max_msg_chunks (integer) + + +The maximum number of chunks in which a BINS message is +expected to arrive via TCP. If a received packet is more +fragmented than this, the connection is dropped (either the +connection is very overloaded and this leads to high +fragmentation - or we are the victim of an ongoing attack where +the attacker is sending very fragmented traffic in order to +decrease server performance). + + +*Default value is 32.* + + +```opensips title="Set bins_max_msg_chunks parameter" +... +modparam("proto_bins", "bins_max_msg_chunks", 8) +... +``` + + +#### bins_async (integer) + + +Specifies whether the TCP/TLS connect and write operations +should be done in an asynchronous mode (non-blocking connect +and write) or not. If disabled, OpenSIPS will block and wait +for TCP/TLS operations like connect and write. + + +*Default value is 1 (enabled).* + + +```opensips title="Set bins_async parameter" +... +modparam("proto_bins", "bins_async", 0) +... +``` + + +#### bins_async_max_postponed_chunks (integer) + + +If bins_async is enabled, this specifies the maximum number of +BINS messages that can be stashed for later/async writing. If +the connection pending writes exceed this number, the +connection will be marked as broken and dropped. + + +*Default value is 32.* + + +```opensips title="Set bins_async_max_postponed_chunks parameter" +... +modparam("proto_bins", "bins_async_max_postponed_chunks", 16) +... +``` + + +#### bins_async_local_connect_timeout (integer) + + +If bin_async is enabled, this specifies the number of +milliseconds that a connect will be tried in blocking mode +(optimization). If the connect operation lasts more than this, +the connect will go to async mode and will be passed to TCP +MAIN for polling. + + +*Default value is 100 ms.* + + +```opensips title="Set bins_async_local_connect_timeout parameter" +... +modparam("proto_bins", "bins_async_local_connect_timeout", 200) +... +``` + + +#### bins_async_handshake_timeout (integer) + + +If *tls_async* is enabled, this specifies the +number of milliseconds that a TLS handshake should be tried in blocking +mode (optimization). If the handshake operation lasts more than this, +the write will go to async mode and will be passed to tls MAIN for +polling. + + +*Default value is 10 ms.* + + +```opensips title="Set bins_async_handshake_timeout parameter" + ... + modparam("proto_tls", "bins_async_handshake_timeout", 100) + ... + +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. +For each connection that is created an event containing information +about the client and server certificates, master key and network layer +information shall be sent. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") +modparam("proto_bins", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for tls is on or not. You still need to define +[trace destination](#param_trace_destination)in order to work, but this value will be +controlled using mi function [mi bins trace](#mi_bins_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_bins", "trace_on", 1) +... +``` + + +### Exported MI Functions + + +#### bins_trace + + +Name: *bins_trace* + + +Parameters: + + +- trace_mode(optional): set bins tracing on and off. This parameter +can be missing and the command will show the current tracing +status for this module( on or off ); +Possible values: + - on + - off + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi bins_trace on +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_bins/doc/contributors.xml b/modules/proto_bins/doc/contributors.xml deleted file mode 100644 index be84b74297f..00000000000 --- a/modules/proto_bins/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 15 - 4 - 1118 - 24 - - - 2. - Maksym Sobolyev (@sobomax) - 5 - 3 - 19 - 20 - - - 3. - Liviu Chircu (@liviuchircu) - 5 - 3 - 13 - 7 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 5 - 3 - - - 5. - Nick Altmann (@nikbyte) - 3 - 1 - 2 - 2 - - - 6. - Razvan Crainea (@razvancrainea) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jul 2025 - Jul 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2021 - May 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Apr 2022 - Apr 2022 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - Feb 2021 - Oct 2021 - - - 6. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/proto_bins/doc/proto_bins.xml b/modules/proto_bins/doc/proto_bins.xml deleted file mode 100644 index 3b036ad75d8..00000000000 --- a/modules/proto_bins/doc/proto_bins.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_bins Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/proto_bins/doc/proto_bins_admin.xml b/modules/proto_bins/doc/proto_bins_admin.xml deleted file mode 100644 index fd9f2d07b62..00000000000 --- a/modules/proto_bins/doc/proto_bins_admin.xml +++ /dev/null @@ -1,346 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements a secure Binary communication protocol - over TLS, to be used by the OpenSIPS clustering engine provided - by the clusterer module. - -
- - Once loaded, you will be able to define BINS listeners in your - configuration file by adding their IP and, optionally, a - listening port, similar to this example: - - -... -socket= bins:127.0.0.1 # change the listening IP -socket= bins:127.0.0.1:5557 # change the listening IP and port -... - - - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_openssl or tls_wolfssl, - depending on the desired TLS library - - - - - tls_mgm. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>bins_port</varname> (integer) - - The default port to be used by all BINS listeners. - - - - Default value is 5556. - - - - Set <varname>bins_port</varname> parameter - -... -modparam("proto_bins", "bins_port", 5557) -... - - -
- -
- <varname>bins_handshake_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the SSL/TLS handshake - sequence to complete. It may be necessary to increase this - value when using a CPU intensive cipher for the connection to - allow time for keys to be generated and processed. - - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is - being initiated (outbound). - - - Default value is 100. - - - Set <varname>bins_handshake_timeout</varname> variable - - -param("proto_tls", "bins_handshake_timeout", 200) # number of milliseconds - - - -
- -
- <varname>bins_send_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for blocking send operations - to complete. - - - The send timeout is invoked for all TLS write operations, - excluding the handshake process (see: bins_handshake_timeout) - - - - Default value is 100 ms. - - - - Set <varname>bins_send_timeout</varname> parameter - -... -modparam("proto_bins", "bins_send_timeout", 200) -... - - -
-
- <varname>bins_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a BINS message is - expected to arrive via TCP. If a received packet is more - fragmented than this, the connection is dropped (either the - connection is very overloaded and this leads to high - fragmentation - or we are the victim of an ongoing attack where - the attacker is sending very fragmented traffic in order to - decrease server performance). - - - - Default value is 32. - - - - Set <varname>bins_max_msg_chunks</varname> parameter - -... -modparam("proto_bins", "bins_max_msg_chunks", 8) -... - - -
-
- <varname>bins_async</varname> (integer) - - Specifies whether the TCP/TLS connect and write operations - should be done in an asynchronous mode (non-blocking connect - and write) or not. If disabled, OpenSIPS will block and wait - for TCP/TLS operations like connect and write. - - - - Default value is 1 (enabled). - - - - Set <varname>bins_async</varname> parameter - -... -modparam("proto_bins", "bins_async", 0) -... - - -
-
- <varname>bins_async_max_postponed_chunks</varname> (integer) - - If bins_async is enabled, this specifies the maximum number of - BINS messages that can be stashed for later/async writing. If - the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - - - Default value is 32. - - - - Set <varname>bins_async_max_postponed_chunks</varname> parameter - -... -modparam("proto_bins", "bins_async_max_postponed_chunks", 16) -... - - -
-
- <varname>bins_async_local_connect_timeout</varname> (integer) - - If bin_async is enabled, this specifies the number of - milliseconds that a connect will be tried in blocking mode - (optimization). If the connect operation lasts more than this, - the connect will go to async mode and will be passed to TCP - MAIN for polling. - - - - Default value is 100 ms. - - - - Set <varname>bins_async_local_connect_timeout</varname> parameter - -... -modparam("proto_bins", "bins_async_local_connect_timeout", 200) -... - - -
-
- <varname>bins_async_handshake_timeout</varname> (integer) - - If tls_async is enabled, this specifies the - number of milliseconds that a TLS handshake should be tried in blocking - mode (optimization). If the handshake operation lasts more than this, - the write will go to async mode and will be passed to tls MAIN for - polling. - - - - Default value is 10 ms. - - - - Set <varname>bins_async_handshake_timeout</varname> parameter - - ... - modparam("proto_tls", "bins_async_handshake_timeout", 100) - ... - - -
-
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - For each connection that is created an event containing information - about the client and server certificates, master key and network layer - information shall be sent. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_bins", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for tls is on or not. You still need to define - in order to work, but this value will be - controlled using mi function . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_bins", "trace_on", 1) -... - - -
-
-
- Exported MI Functions - -
- - <function moreinfo="none">bins_trace</function> - - - - - - - Name: bins_trace - - - Parameters: - - - trace_mode(optional): set bins tracing on and off. This parameter - can be missing and the command will show the current tracing - status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi bins_trace on - -
-
- -
diff --git a/modules/proto_hep/README b/modules/proto_hep/README deleted file mode 100644 index a8b776b2501..00000000000 --- a/modules/proto_hep/README +++ /dev/null @@ -1,448 +0,0 @@ -proto_hep Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. hep_id (str) - 1.3.2. homer5_on (int) - 1.3.3. homer5_delim (str) - 1.3.4. hep_port (integer) - 1.3.5. hep_send_timeout (integer) - 1.3.6. hep_max_msg_chunks (integer) - 1.3.7. hep_async (integer) - 1.3.8. hep_async_max_postponed_chunks (integer) - 1.3.9. hep_capture_id (integer) - 1.3.10. hep_retry_cooldown (integer) - 1.3.11. hep_max_retries (integer) - 1.3.12. hep_async_local_connect_timeout (integer) - 1.3.13. hep_async_local_write_timeout (integer) - - 1.4. Exported Functions - - 1.4.1. correlate(hep_id, type1, correlation1, type2, - correlation2) - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. pack_hep(from, to, proto, payload, plen, - retbuf, retlen) - - 2.1.2. register_hep_cb(cb) - 2.1.3. hep_version - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hep_id parameter - 1.2. Set homer5_on parameter - 1.3. Set homer5_on parameter - 1.4. Set hep_port parameter - 1.5. Set hep_send_timeout parameter - 1.6. Set hep_max_msg_chunks parameter - 1.7. Set hep_async parameter - 1.8. Set hep_async_max_postponed_chunks parameter - 1.9. Set hep_capture_id parameter - 1.10. Set hep_retry_cooldown parameter - 1.11. Set hep_max_retries parameter - 1.12. Set hep_async_local_connect_timeout parameter - 1.13. Set hep_async_local_write_timeout parameter - 1.14. correlate usage - -Chapter 1. Admin Guide - -1.1. Overview - - The proto_hep module is a transport module which implements - hepV1 and hepV2 UDP-based communication and hepV3 TCP-based - communication. It also offers an API with which you can - register callbacks which are called after the HEP header is - parsed and also can pack sip messages to HEP messages.The - unpacking part is done internally. - - Once loaded, you will be able to define HEP listeners in your - configuration file by adding their IP and, optionally, a - listening port. You can define both TCP, UDP, and TLS - listeners. On UDP you will be able to receive HEP v1, v2 and v3 - packets, on TCP and TLS only HEPv3. - -... -#HEPv3 listener -socket= hep_tcp:127.0.0.1:6061 # change the listening IP -#HEPv1, v2, v3 listener -socket= hep_udp:127.0.0.1:6061 # change the listening IP -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_mgm - optional, only if a TLS based HEP listener is - defined in the script. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. hep_id (str) - - Specify a destination for HEP packets and the version of HEP - protocol used. All parameters inside hep_id must be separated - by ;. The parameters are given in key-value format, the - possible keys being uri, transport and version, except - destiantion's URI which doesn't have a key and is in host:port - . transport key can be TCP, UDP or TLS. TCP and TLS works only - for HEP version 3. Version is the hep protocol version and can - be 1, 2 or 3. - - HEPv1 and HEPv2 can use only UDP. HEPv3 can use TCP, UDP and - TLS having the default set to TCP. If no hep version defined, - the default is version 3 with TCP and TLS. - - NO default value. If hep_id the module can't be used for HEP - tracing. - - Example 1.1. Set hep_id parameter -... -/* define a destination to localhost on port 8001 using hepV3 on tcp */ -modparam("proto_hep", "hep_id", -"[hep_dst] 127.0.0.1:8001; transport=tcp; version=3") -/* define a destination to 1.2.3.4 on port 5000 using hepV2; no transpor -t(default UDP) */ -modparam("proto_hep", "hep_id", "[hep_dst] 1.2.3.4:5000; version=2") -/* define only the destination uri; version will be 3(default) and trans -port TCP(default) */ -modparam("proto_hep", "hep_id", "[hep_dst] 1.2.3.4:5000") - -1.3.2. homer5_on (int) - - Specify how the data should be encapsulated in the HEP packet. - If set to 0, then the JSON based HOMER 6 format will be used. - Otherwise, if set to anything different than 0, the plain text - HOMER 5 format will be used for encapsulation. On the capturing - node, this parameter affects the behavior of the report_capture - function from the sipcapture module. - - Default value 1, HOMER5 format. - - Example 1.2. Set homer5_on parameter -modparam("proto_hep", "homer5_on", 0) - -1.3.3. homer5_delim (str) - - In case homer5_on is set (different than 0), with this - parameter you will be able to set the delmiter between - different payload parts. - - Default value ":". - - Example 1.3. Set homer5_on parameter -modparam("proto_hep", "homer5_delim", "##") - -1.3.4. hep_port (integer) - - The default port to be used by all TCP/UDP/TLS listeners. - - Default value is 5656. - - Example 1.4. Set hep_port parameter -... -modparam("proto_hep", "hep_port", 6666) -... - -1.3.5. hep_send_timeout (integer) - - Time in milliseconds after a TCP connection will be closed if - it is not available for blocking writing in this interval (and - OpenSIPS wants to send something on it). - - Default value is 100 ms. - - Example 1.5. Set hep_send_timeout parameter -... -modparam("proto_hep", "hep_send_timeout", 200) -... - -1.3.6. hep_max_msg_chunks (integer) - - The maximum number of chunks in which a HEP message is expected - to arrive via TCP. If a received packet is more fragmented than - this, the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - Default value is 32. - - Example 1.6. Set hep_max_msg_chunks parameter -... -modparam("proto_hep", "hep_max_msg_chunks", 8) -... - -1.3.7. hep_async (integer) - - Specifies whether the TCP connect and write operations should - be done in an asynchronous mode (non-blocking connect and - write) or not. If disabled, OpenSIPS will block and wait for - TCP operations like connect and write. - - Default value is 1 (enabled). - - Example 1.7. Set hep_async parameter -... -modparam("proto_hep", "hep_async", 0) -... - -1.3.8. hep_async_max_postponed_chunks (integer) - - If hep_async is enabled, this specifies the maximum number of - HEP messages that can be stashed for later/async writing. If - the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - Default value is 32. - - Example 1.8. Set hep_async_max_postponed_chunks parameter -... -modparam("proto_hep", "hep_async_max_postponed_chunks", 16) -... - -1.3.9. hep_capture_id (integer) - - The parameter indicate the capture agent ID for HEPv2/v3 - protocol. Limitation: 16-bit integer. - - Default value is "1". - - Example 1.9. Set hep_capture_id parameter -... -modparam("proto_hep", "hep_capture_id", 234) -... - -1.3.10. hep_retry_cooldown (integer) - - This parameter defines how many seconds OpenSIPS should wait - before retrying a TCP connection to the HEP destination after - reaching the maximum number of failed attempts set by - hep_max_retries. Limitation: 16-bit integer. - - Default value is "3600". - - Example 1.10. Set hep_retry_cooldown parameter -... -modparam("proto_hep", "hep_retry_cooldown", 60) -... - -1.3.11. hep_max_retries (integer) - - This parameter defines the maximum number of attempts OpenSIPS - will make to establish a TCP connection with the HEP - destination. Limitation: 16-bit integer. - - Default value is "5". - - Example 1.11. Set hep_max_retries parameter -... -modparam("proto_hep", "hep_max_retries", 10) -... - -1.3.12. hep_async_local_connect_timeout (integer) - - If hep_async is enabled, this specifies the number of - milliseconds that a connect will be tried in blocking mode - (optimization). If the connect operation lasts more than this, - the connect will go to async mode and will be passed to TCP - MAIN for polling. - - Default value is 100 ms. - - Example 1.12. Set hep_async_local_connect_timeout parameter -... -modparam("proto_hep", "hep_async_local_connect_timeout", 200) -... - -1.3.13. hep_async_local_write_timeout (integer) - - If hep_async is enabled, this specifies the number of - milliseconds that a write op will be tried in blocking mode - (optimization). If the write operation lasts more than this, - the write will go to async mode and will be passed to bin MAIN - for polling. - - Default value is 10 ms. - - Example 1.13. Set hep_async_local_write_timeout parameter -... -modparam("proto_hep", "hep_async_local_write_timeout", 100) -... - -1.4. Exported Functions - -1.4.1. correlate(hep_id, type1, correlation1, type2, correlation2) - - Send a hep message with an extra correlation id containing the - two correlation given as arguments. The two types must differ. - This will help on the capturing side to correlate two calls for - example, being given their callid as correlation ids. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE. - - Meaning of the parameters is as follows: - * hep_id (string) the name of the hep_id defined in modparam - section, specifying where to do the tracing. - * type1 (string) the key name identify the first correlation - id. - * correlation1 (string) the first extra correlation id that - will be put in the extra correlation chunk. - * type2 (string) the key name identify the second correlation - id. - * correlation2 (string) the second extra correlation id that - will be put in the extra correlation chunk. - - Example 1.14. correlate usage -... -/* see declaration of hep_dst in trace_id section */ -/* we suppose we have two correlations in two varibles: cor1 and cor2 */ - correlate("hep_dst", "correlation-no-1",$var(cor1),"correlation- -no-2", $var(cor2)); -... - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. pack_hep(from, to, proto, payload, plen, retbuf, retlen) - - The function packs connection details and sip message into HEP - message. It's your job to free both the old and the new buffer. - - Meaning of the parameters is as follows: - * sockaddr_union *from - sockaddr_union describing sending - socket - * sockaddr_union *to - sockaddr_union describing receiving - socket - * int proto - protocol used in hep header; - * char *payload SIP payload buffer - * int plen SIP payload buffer length - * char **retbuf HEP message buffer - * int *retlen HEP message buffer length - -2.1.2. register_hep_cb(cb) - - The function register callbacks to be called whenever a HEP - message is received. The callbacks parameters are struct - hep_desc*(see hep.h for details) a structure that holds all - details about the hep header and the receive_info* structure. - The callback can return HEP_SCRIPT_SKIP which stops the HEP - message from being passed thrrough scripts. - - Meaning of the parameters is as follows: - * hep_cb_t cb HEP callback - -2.1.3. hep_version - - Current version of hep used. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ionut Ionita (@ionutrazvanionita) 151 66 8047 998 - 2. Razvan Crainea (@razvancrainea) 42 32 100 494 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 27 20 391 175 - 4. Liviu Chircu (@liviuchircu) 20 17 107 100 - 5. Bence Szigeti 9 2 405 180 - 6. Vlad Patrascu (@rvlad-patrascu) 7 4 36 84 - 7. Maksym Sobolyev (@sobomax) 5 3 41 41 - 8. rita7lopes 3 1 84 11 - 9. Nick Altmann (@nikbyte) 3 1 2 2 - 10. Dan Pascu (@danpascu) 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov), Walter - Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Nov 2015 - Jul 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2016 - May 2025 - 3. rita7lopes May 2025 - May 2025 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2017 - May 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 6. Bence Szigeti Jul 2023 - Aug 2023 - 7. Nick Altmann (@nikbyte) May 2021 - May 2021 - 8. Walter Doekes (@wdoekes) May 2020 - May 2020 - 9. Dan Pascu (@danpascu) May 2019 - May 2019 - 10. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - - All remaining contributors: Peter Lemenkov (@lemenkov), Ionut - Ionita (@ionutrazvanionita). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: rita7lopes, Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Bence - Szigeti, Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_hep/README.md b/modules/proto_hep/README.md new file mode 100644 index 00000000000..83466f500dd --- /dev/null +++ b/modules/proto_hep/README.md @@ -0,0 +1,414 @@ +--- +title: "proto_hep Module" +description: "The **proto_hep** module is a transport module which implements hepV1 and hepV2 UDP-based communication and hepV3 TCP-based communication." +--- + +## Admin Guide + + +### Overview + + +The **proto_hep** module is a +transport module which implements hepV1 and hepV2 UDP-based communication +and hepV3 TCP-based communication. It also offers an API with which +you can register callbacks which are called after the HEP header is +parsed and also can pack sip messages to HEP messages.The unpacking +part is done internally. + + +Once loaded, you will be able to define HEP listeners in your +configuration file by adding their IP and, optionally, a listening port. +You can define both TCP, UDP, and TLS listeners. On UDP you will be able to +receive HEP v1, v2 and v3 packets, on TCP and TLS only HEPv3. + +```opensips +... +#HEPv3 listener +socket = hep_tcp:127.0.0.1:6061 # change the listening IP +#HEPv1, v2, v3 listener +socket = hep_udp:127.0.0.1:6061 # change the listening IP +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_mgm* - optional, only if a TLS based +HEP listener is defined in the script. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### hep_id (str) + + +Specify a destination for HEP packets and the version of +HEP protocol used. All parameters inside +**hep_id** must be separated by +**;**. The parameters +are given in key-value format, the possible keys being +**uri**, **transport** +and **version**, except destiantion's +URI which doesn't have a key and is in **host:port**. **transport** key can be +**TCP**, **UDP** or +**TLS**. +**TCP** and **TLS** +works only for HEP version 3. +**Version** is the hep protocol version +and can be **1**, **2** +or **3**. + + +HEPv1 and HEPv2 can use only UDP. HEPv3 can use TCP, UDP and TLS having the +default set to TCP. If no hep version defined, the default is version 3 with +TCP and TLS. + + +NO default value. If **hep_id** the module +can't be used for HEP tracing. + + +```opensips title="Set hep_id parameter" +... +/* define a destination to localhost on port 8001 using hepV3 on tcp */ +modparam("proto_hep", "hep_id", +"[hep_dst] 127.0.0.1:8001; transport=tcp; version=3") +/* define a destination to 1.2.3.4 on port 5000 using hepV2; no transport(default UDP) */ +modparam("proto_hep", "hep_id", "[hep_dst] 1.2.3.4:5000; version=2") +/* define only the destination uri; version will be 3(default) and transport TCP(default) */ +modparam("proto_hep", "hep_id", "[hep_dst] 1.2.3.4:5000") +... +``` + + +#### homer5_on (int) + + +Specify how the data should be encapsulated in the HEP packet. If set to +*0*, then the JSON based HOMER 6 format will be used. Otherwise, +if set to anything different than *0*, the plain text HOMER 5 +format will be used for encapsulation. On the capturing node, this parameter +affects the behavior of the *report_capture* function from the +[sipcapture](../sipcapture#func_report_capture) +module. + + +Default value 1, HOMER5 format. + + +```opensips title="Set homer5_on parameter" +modparam("proto_hep", "homer5_on", 0) +``` + + +#### homer5_delim (str) + + +In case **homer5_on** is set +(different than 0), with this parameter you will be able to set +the delmiter between different payload parts. + + +Default value ":". + + +```opensips title="Set homer5_on parameter" +modparam("proto_hep", "homer5_delim", "##") +``` + + +#### hep_port (integer) + + +The default port to be used by all TCP/UDP/TLS listeners. + + +*Default value is 5656.* + + +```opensips title="Set hep_port parameter" +... +modparam("proto_hep", "hep_port", 6666) +... +``` + + +#### hep_send_timeout (integer) + + +Time in milliseconds after a TCP connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set hep_send_timeout parameter" +... +modparam("proto_hep", "hep_send_timeout", 200) +... +``` + + +#### hep_max_msg_chunks (integer) + + +The maximum number of chunks in which a HEP message is expected to +arrive via TCP. If a received packet is more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending very +fragmented traffic in order to decrease server performance). + + +*Default value is 32.* + + +```opensips title="Set hep_max_msg_chunks parameter" +... +modparam("proto_hep", "hep_max_msg_chunks", 8) +... +``` + + +#### hep_async (integer) + + +Specifies whether the TCP connect and write operations should be +done in an asynchronous mode (non-blocking connect and +write) or not. If disabled, OpenSIPS will block and wait for TCP +operations like connect and write. + + +*Default value is 1 (enabled).* + + +```opensips title="Set hep_async parameter" +... +modparam("proto_hep", "hep_async", 0) +... +``` + + +#### hep_async_max_postponed_chunks (integer) + + +If *hep_async* is enabled, this specifies the +maximum number of HEP messages that can be stashed for later/async +writing. If the connection pending writes exceed this number, the +connection will be marked as broken and dropped. + + +*Default value is 32.* + + +```opensips title="Set hep_async_max_postponed_chunks parameter" +... +modparam("proto_hep", "hep_async_max_postponed_chunks", 16) +... +``` + + +#### hep_capture_id (integer) + + +The parameter indicate the capture agent ID for HEPv2/v3 protocol. +Limitation: 16-bit integer. + + +*Default value is "1".* + + +```opensips title="Set hep_capture_id parameter" +... +modparam("proto_hep", "hep_capture_id", 234) +... +``` + + +#### hep_retry_cooldown (integer) + + +This parameter defines how many seconds OpenSIPS should wait before retrying a TCP connection to the HEP destination after reaching the maximum number of failed attempts set by hep_max_retries. +Limitation: 16-bit integer. + + +*Default value is "3600".* + + +```opensips title="Set hep_retry_cooldown parameter" +... +modparam("proto_hep", "hep_retry_cooldown", 60) +... +``` + + +#### hep_max_retries (integer) + + +This parameter defines the maximum number of attempts OpenSIPS will make to establish a TCP connection with the HEP destination. +Limitation: 16-bit integer. + + +*Default value is "5".* + + +```opensips title="Set hep_max_retries parameter" +... +modparam("proto_hep", "hep_max_retries", 10) +... +``` + + +#### hep_async_local_connect_timeout (integer) + + +If *hep_async* is enabled, this specifies the +number of milliseconds that a connect will be tried in blocking +mode (optimization). If the connect operation lasts more than +this, the connect will go to async mode and will be passed to TCP +MAIN for polling. + + +*Default value is 100 ms.* + + +```opensips title="Set hep_async_local_connect_timeout parameter" +... +modparam("proto_hep", "hep_async_local_connect_timeout", 200) +... +``` + + +#### hep_async_local_write_timeout (integer) + + +If *hep_async* is enabled, this specifies the +number of milliseconds that a write op will be tried in blocking +mode (optimization). If the write operation lasts more than this, +the write will go to async mode and will be passed to bin MAIN for +polling. + + +*Default value is 10 ms.* + + +```opensips title="Set hep_async_local_write_timeout parameter" +... +modparam("proto_hep", "hep_async_local_write_timeout", 100) +... +``` + + +### Exported Functions + + +#### correlate(hep_id, type1, correlation1, type2, correlation2) + + +Send a hep message with an extra correlation id containing the two correlation given +as arguments. The two types must differ. This will help +on the capturing side to correlate two calls for example, being given their callid +as correlation ids. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, LOCAL_ROUTE. + + +Meaning of the parameters is as follows: + + +- *hep_id (string)* +the name of the *hep_id* defined in modparam section, +specifying where to do the tracing. +- *type1 (string)* +the key name identify the first correlation id. +- *correlation1 (string)* +the first extra correlation id that will be put in the extra correlation chunk. +- *type2 (string)* +the key name identify the second correlation id. +- *correlation2 (string)* +the second extra correlation id that will be put in the extra correlation chunk. + + +```opensips title="correlate usage" +... +/* see declaration of hep_dst in trace_id section */ +/* we suppose we have two correlations in two varibles: cor1 and cor2 */ +correlate("hep_dst", "correlation-no-1", $var(cor1), "correlation-no-2", $var(cor2)); +... +``` + + +## Developer Guide + + +### Available Functions + + +#### pack_hep(from, to, proto, payload, plen, retbuf, retlen) + + +The function packs connection details and sip message into HEP message. It's +your job to free both the old and the new buffer. + + +Meaning of the parameters is as follows: + + +- *sockaddr_union *from* - sockaddr_union describing +sending socket +- *sockaddr_union *to* - sockaddr_union describing +receiving socket +- *int proto* - protocol used in hep header; +- *char *payload* SIP payload buffer +- *int plen* SIP payload buffer length +- *char **retbuf* HEP message buffer +- *int *retlen* HEP message buffer length + + +#### register_hep_cb(cb) + + +The function register callbacks to be called whenever a HEP message +is received. The callbacks parameters are struct hep_desc*(see hep.h for +details) a structure that holds all details about the hep header and the +receive_info* structure. The callback can return HEP_SCRIPT_SKIP which +stops the HEP message from being passed thrrough scripts. + + +Meaning of the parameters is as follows: + + +- *hep_cb_t cb* HEP callback + + +#### hep_version + + +Current version of hep used. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_hep/doc/contributors.xml b/modules/proto_hep/doc/contributors.xml deleted file mode 100644 index 8fa80cc953f..00000000000 --- a/modules/proto_hep/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ionut Ionita (@ionutrazvanionita) - 151 - 66 - 8047 - 998 - - - 2. - Razvan Crainea (@razvancrainea) - 42 - 32 - 100 - 494 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 27 - 20 - 391 - 175 - - - 4. - Liviu Chircu (@liviuchircu) - 20 - 17 - 107 - 100 - - - 5. - Bence Szigeti - 9 - 2 - 405 - 180 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 7 - 4 - 36 - 84 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 41 - 41 - - - 8. - rita7lopes - 3 - 1 - 84 - 11 - - - 9. - Nick Altmann (@nikbyte) - 3 - 1 - 2 - 2 - - - 10. - Dan Pascu (@danpascu) - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Nov 2015 - Jul 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2016 - May 2025 - - - 3. - rita7lopes - May 2025 - May 2025 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2017 - May 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 6. - Bence Szigeti - Jul 2023 - Aug 2023 - - - 7. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 8. - Walter Doekes (@wdoekes) - May 2020 - May 2020 - - - 9. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: rita7lopes, Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Bence Szigeti, Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/proto_hep/doc/proto_hep.xml b/modules/proto_hep/doc/proto_hep.xml deleted file mode 100644 index 591eeb1fb60..00000000000 --- a/modules/proto_hep/doc/proto_hep.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - proto_hep Module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/proto_hep/doc/proto_hep_devel.xml b/modules/proto_hep/doc/proto_hep_devel.xml deleted file mode 100644 index 306e385cf4c..00000000000 --- a/modules/proto_hep/doc/proto_hep_devel.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - &develguide; -
- Available Functions - -
- - <function moreinfo="none">pack_hep(from, to, proto, payload, plen, retbuf, retlen) - </function> - - - The function packs connection details and sip message into HEP message. It's - your job to free both the old and the new buffer. - - Meaning of the parameters is as follows: - - - sockaddr_union *from - sockaddr_union describing - sending socket - - - - sockaddr_union *to - sockaddr_union describing - receiving socket - - - - int proto - protocol used in hep header; - - - - char *payload SIP payload buffer - - - - int plen SIP payload buffer length - - - - char **retbuf HEP message buffer - - - - int *retlen HEP message buffer length - - - -
- -
- - <function moreinfo="none">register_hep_cb(cb) - </function> - - - The function register callbacks to be called whenever a HEP message - is received. The callbacks parameters are struct hep_desc*(see hep.h for - details) a structure that holds all details about the hep header and the - receive_info* structure. The callback can return HEP_SCRIPT_SKIP which - stops the HEP message from being passed thrrough scripts. - - Meaning of the parameters is as follows: - - - hep_cb_t cb HEP callback - - - -
- -
- - <function moreinfo="none">hep_version - </function> - - - Current version of hep used. - -
- -
- -
- diff --git a/modules/proto_hep/hep.c b/modules/proto_hep/hep.c index c1f21dba938..1ebd2645132 100644 --- a/modules/proto_hep/hep.c +++ b/modules/proto_hep/hep.c @@ -245,13 +245,22 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) _len -= _off; \ } while (0); +#define CHECK_CHUNK_SIZE(_len, _type) \ + do { \ + if ((_len) != sizeof(_type)) { \ + LM_ERR("invalid HEPv3 chunk %u length %u, expected %zu\n", \ + chunk_id, (unsigned int)(_len), sizeof(_type)); \ + goto error; \ + } \ + } while (0); + int rc; unsigned char *compressed_payload; unsigned long compress_len; struct hepv3 h3; - unsigned short tlen; + unsigned short tlen, chunk_len; unsigned long decompress_len; generic_chunk_t* gen_chunk, *it; @@ -263,7 +272,17 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) h->version = 3; + if (len < sizeof(hep_ctrl_t)) { + LM_ERR("invalid HEPv3 packet length %d\n", len); + return -1; + } + tlen = ntohs(((hep_ctrl_t*)buf)->length); + if (tlen < sizeof(hep_ctrl_t) || tlen > len) { + LM_ERR("invalid HEPv3 advertised length %u for packet length %d\n", + (unsigned int)tlen, len); + return -1; + } buf += sizeof(hep_ctrl_t); tlen -= sizeof(hep_ctrl_t); @@ -271,11 +290,26 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) memset( &h3, 0, sizeof(struct hepv3)); while (tlen > 0) { + if (tlen < sizeof(hep_chunk_t)) { + LM_ERR("truncated HEPv3 chunk header, remaining length %u\n", + (unsigned int)tlen); + goto error; + } + /* we don't look at vendor id; we only need to parse the buffer */ - chunk_id = ((hep_chunk_t*)buf)->type_id; + chunk_id = ntohs(((hep_chunk_t*)buf)->type_id); + chunk_len = ntohs(((hep_chunk_t*)buf)->length); + + if (chunk_len < sizeof(hep_chunk_t) || chunk_len > tlen) { + LM_ERR("invalid HEPv3 chunk %u length %u, remaining length %u\n", + chunk_id, (unsigned int)chunk_len, (unsigned int)tlen); + goto error; + } - switch (ntohs(chunk_id)) { + switch (chunk_id) { case HEP_PROTO_FAMILY: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint8_t); + /* ip family*/ h3.hg.ip_family = *((hep_chunk_uint8_t*)buf); @@ -284,6 +318,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_PROTO_ID: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint8_t); + /* ip protocol ID*/ h3.hg.ip_proto = *((hep_chunk_uint8_t*)buf); @@ -292,6 +328,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_IPV4_SRC: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_ip4_t); + /* ipv4 source */ h3.addr.ip4_addr.src_ip4 = *((hep_chunk_ip4_t*)buf); @@ -300,6 +338,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_IPV4_DST: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_ip4_t); + /* ipv4 dest */ h3.addr.ip4_addr.dst_ip4 = *((hep_chunk_ip4_t*)buf); @@ -308,6 +348,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_IPV6_SRC: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_ip6_t); + /* ipv6 source */ h3.addr.ip6_addr.src_ip6 = *((hep_chunk_ip6_t*)buf); @@ -316,6 +358,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_IPV6_DST: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_ip6_t); + /* ipv6 dest */ h3.addr.ip6_addr.dst_ip6 = *((hep_chunk_ip6_t*)buf); @@ -324,6 +368,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_SRC_PORT: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint16_t); + /* source port */ h3.hg.src_port = *((hep_chunk_uint16_t*)buf); @@ -334,6 +380,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_DST_PORT: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint16_t); + /* dest port */ h3.hg.dst_port = *((hep_chunk_uint16_t*)buf); @@ -344,6 +392,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_TIMESTAMP: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint32_t); + /* timestamp */ h3.hg.time_sec = *((hep_chunk_uint32_t*)buf); @@ -354,6 +404,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_TIMESTAMP_US: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint32_t); + /* timestamp microsecs offset */ h3.hg.time_usec = *((hep_chunk_uint32_t*)buf); @@ -364,6 +416,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_PROTO_TYPE: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint8_t); + /* proto type */ h3.hg.proto_t = *((hep_chunk_uint8_t*)buf); @@ -372,6 +426,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) break; case HEP_AGENT_ID: + CHECK_CHUNK_SIZE(chunk_len, hep_chunk_uint32_t); + /* capture agent id */ h3.hg.capt_id = *((hep_chunk_uint32_t*)buf); @@ -426,7 +482,7 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) * locking will be required */ if ((gen_chunk = shm_malloc(sizeof(generic_chunk_t)))==NULL) { LM_ERR("no more pkg mem!\n"); - return -1; + goto error; } memset(gen_chunk, 0, sizeof(generic_chunk_t)); @@ -439,7 +495,8 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) if (gen_chunk->data == NULL) { LM_ERR("no more shared memory!\n"); - return -1; + shm_free(gen_chunk); + goto error; } memcpy(gen_chunk->data, (char *)buf + sizeof(hep_chunk_t), @@ -459,10 +516,28 @@ int unpack_hepv3(char *buf, int len, struct hep_desc *h) } } + if (!h3.payload_chunk.data || + h3.payload_chunk.chunk.length < sizeof(hep_chunk_t)) { + LM_ERR("HEPv3 packet missing payload chunk\n"); + goto error; + } + safe_exit: h->u.hepv3 = h3; return 0; + +error: + while (h3.chunk_list) { + it = h3.chunk_list; + h3.chunk_list = it->next; + shm_free(it->data); + shm_free(it); + } + if (decompressed_payload.s) + pkg_free(decompressed_payload.s); +#undef CHECK_CHUNK_SIZE + return -1; } static int diff --git a/modules/proto_hep/proto_hep.c b/modules/proto_hep/proto_hep.c index 9317f9cddc4..1c01e616236 100644 --- a/modules/proto_hep/proto_hep.c +++ b/modules/proto_hep/proto_hep.c @@ -1065,7 +1065,7 @@ static int hep_udp_read_req(const struct socket_info* si, int* bytes_read) if (len < 4) { LM_ERR("invalid message! too short!\n"); - return -1; + goto error_free_hep; } if (!memcmp(buf, HEP_HEADER_ID, HEP_HEADER_ID_LEN)) { @@ -1073,14 +1073,14 @@ static int hep_udp_read_req(const struct socket_info* si, int* bytes_read) /* coverity[tainted_data] */ if (unpack_hepv3(buf, len, &hep_ctx->h)) { LM_ERR("hepv3 unpacking failed\n"); - return -1; + goto error_free_hep; } } else { /* HEPv2 */ /* coverity[tainted_data] */ if (unpack_hepv12(buf, len, &hep_ctx->h)) { LM_ERR("hepv12 unpacking failed\n"); - return -1; + goto error_free_hep; } } @@ -1104,7 +1104,7 @@ static int hep_udp_read_req(const struct socket_info* si, int* bytes_read) set_global_context(NULL); if (ret < 0) { LM_ERR("failed to run hep callbacks\n"); - return -1; + goto error_free_ctx; } if (hep_ctx->h.version == 3) { @@ -1136,8 +1136,10 @@ static int hep_udp_read_req(const struct socket_info* si, int* bytes_read) return 0; +error_free_ctx: + context_free(ctx); error_free_hep: - shm_free(hep_ctx); + free_hep_context(hep_ctx); return -1; } diff --git a/modules/proto_ipsec/README b/modules/proto_ipsec/README deleted file mode 100644 index 380c276c812..00000000000 --- a/modules/proto_ipsec/README +++ /dev/null @@ -1,414 +0,0 @@ -proto_ipsec Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. port (integer) - 1.3.2. min_spi (integer) - 1.3.3. max_spi (integer) - 1.3.4. temporary_timeout (integer) - 1.3.5. default_client_port (integer) - 1.3.6. default_server_port (integer) - 1.3.7. allowed_algorithms (string) - 1.3.8. disable_deprecated_algorithms (integer) - - 1.4. Exported Functions - - 1.4.1. ipsec_create([port_server], [port_client], - [algos]) - - 1.5. Exported Pseudo-Variables - - 1.5.1. $ipsec - 1.5.2. $ipsec_ue - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set port parameter - 1.2. Set min_spi parameter - 1.3. Set max_spi parameter - 1.4. Set temporary_timeout variable - 1.5. Set default_client_port parameter - 1.6. Set default_server_port parameter - 1.7. Set allowed_algorithms parameter - 1.8. Set disable_deprecated_algorithms parameter - 1.9. ipsec_create() usage - 1.10. $ipsec(field) usage - 1.11. $ipsec_ue(field) usage - -Chapter 1. Admin Guide - -1.1. Overview - - The proto_ipsec module provides IPSec sockets for establishing - secure communication channels. It relies on RFC 3329 (Security - Mechanism Agreement for the Session Initiation Protocol (SIP)) - to establish the IPSec parameters necessary for creating - dynamic Security Associations (SAs) for each connection. - - This module has been developed to fully comply with the VoLTE - specification (GSMA PRD IR.92) and implements the extensions - defined in TS 33.203 (3G Security: Access Security for IP-based - Services). - - It allows creation of both UDP and TCP secure connections on - the same IP:port pair, defined as sockets. Essentially, when - defining a socket using the proto_ipsec protocol, two new - internal/hidden sockets are created on the specified port. For - example, defining the following socket: - -... -socket=ipsec:127.0.0.1:5100 -... - - Internally, two different sockets are created: - -... -socket=udp:127.0.0.1:5100 -socket=tcp:127.0.0.1:5100 -... - - Communication through these sockets should be done over IPSec, - thus appropriate security associations (SAs) should be made - prior to using these listeners, as defined in RFC 3329. - - NOTE that this means that you can no longer define these - sockets in your config, otherwise they will overlap with the - internally defined ones. - - IPSec communication requires each participant to define at - least two ports for each connection: one when the entity - behaves as a client and another when it behaves as a server. - Consequently, it's typically necessary to define at least two - IPSec sockets for the module to function correctly. - - The module implements the entire logic of keeping track of the - registration status by hooking into the usrloc module and - listening for contact changes updates. It also ensures the - persistency of the tunnels by restoring them after a restart. - - When a request is received over an IPSec tunnel, the module - provides two variables, $ipsec(field) and $ipsec_ue(field) to - inspect details about it. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tm - used to keep track of IPSec SA context between - requests and replies. - * usrloc - used to identify when a successful - registration/de-registration happens. - * proto_udp - used for handling IPSec UDP connections - operations. - * proto_tcp - used for handling IPSec TCP connections - operations. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libmnl - Minimalistic Netlink Library used to create IPSec - SA using the XFRM kernel interface. - -1.3. Exported Parameters - -1.3.1. port (integer) - - Default IPSec port used when no prot is being specified in the - socket global parameter. - - Default value is 5062. - - Example 1.1. Set port parameter -... -modparam("proto_ipsec", "port", 5100) -... - -1.3.2. min_spi (integer) - - This parameter represents the minimum value for the Security - Association's (SA) SPI parameter. In conjunction with the - max_spi setting, it defines the SPI range [min_spi, max_spi] - that must be unique within the system. - - Default value is 65536. - - Example 1.2. Set min_spi parameter -... -modparam("proto_ipsec", "min_spi", 10000) -... - -1.3.3. max_spi (integer) - - This parameter represents the maximum value for the Security - Association's (SA) SPI parameter. In conjunction with the - min_spi setting, it defines the SPI range [min_spi, max_spi] - that must be unique within the system. - - Default value is 262144. - - Example 1.3. Set max_spi parameter -... -modparam("proto_ipsec", "max_spi", 20000) -... - -1.3.4. temporary_timeout (integer) - - Sets the timeout (in seconds) a temporary security association - can be stored in memory until in is confirmed (or used) by the - remote endpoint. - - The timeout signifies the duration elapsed after sending the - Security Association's (SA) parameters in the 401 reply and - when the User Equipment (UE) transmits the initial message over - the new secure channel. - - Default value is 30. - - Example 1.4. Set temporary_timeout variable - -param("proto_ipsec", "temporary_timeout", 10) # number of seconds - - -1.3.5. default_client_port (integer) - - Default port value to be used when we act as clients in the - IPSec communication. - - Default value is not defined - a random socket is being used, - but needs to be different from the server socket. - - Example 1.5. Set default_client_port parameter -... -modparam("proto_ipsec", "default_client_port", 5100) -... - -1.3.6. default_server_port (integer) - - Default port value to be used when we act as server in the - IPSec communication. - - Default value is not defined - a random socket is being used, - but needs to be different from the client socket. - - Example 1.6. Set default_server_port parameter -... -modparam("proto_ipsec", "default_server_port", 6100) -... - -1.3.7. allowed_algorithms (string) - - Whitelists the authentication and encryption algorithms that - can be used for IPSec. - - Its format is: alg|ealg|alg=ealg - - Multiple algorithms pairs can be specified separated by comma. - - Currently supported algorithms are: - * Authentication algorithms: - + hmac-md5-96 - + hmac-sha-1-96 - + aes-gmac - + null - * Encryption algorithms: - + des-ede3-cbc - + aes-cbc - + aes-gcm - + null - - Default value is none - this means that all algorithms can be - used. - - Example 1.7. Set allowed_algorithms parameter -... -modparam("proto_ipsec", "allowed_algorithms", "null") -modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null") -modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null,aes-gm -ac=aes-gcm") -... - -1.3.8. disable_deprecated_algorithms (integer) - - Indicates whether we should ignore deprecated algorithms, as - defined in TS 33.203 (3G Security: Access Security for IP-based - Services). At the moment, this disables the following - algorithms: - * hmac-md5-96 and hmac-sha-1-96 authentication algorithms - * des-ede3-cbc and aes-cbc encryption algorithms - - Default value is false - all algorithms can be used. - - Example 1.8. Set disable_deprecated_algorithms parameter -... -modparam("proto_ipsec", "disable_deprecated_algorithms", yes) -... - -1.4. Exported Functions - -1.4.1. ipsec_create([port_server], [port_client], [algos]) - - Creates an IPSec SA/tunnel according to the Security-Client - header and the AKA information received in the 401 reply. - - This function should only be called on a 401 reply for a - REGISTER message. - - Upon successful creation of the IPSec tunnel, it builds the - Security-Server header and appends it to the reply. - - Meaning of the parameters is as follows: - * port_server (integer, optional) - the server port to be - used in the IPSec communication. It should be an existing - IPSec port and is advertised in the Security-Server header. - If missing, the default_client_port is considered. - * port_client (integer, optional) - the client port to be - used in the IPSec communication. It should be an existing - IPSec port and is advertised in the Security-Server header. - If missing, the default_server_port is considered. - * algos (string, optional) - a list of algorithms that should - be used for creating this security association. It has the - same format as disable_allowed_algorithms and overwrites - its value when used. If missing, the - disable_allowed_algorithms is considered. - - This function can be used from REPLY_ROUTE. - - Example 1.9. ipsec_create() usage -... -onreply_route[ipsec] { - if ($T_reply_code == 401) - if (ipsec_create()) -} -... - -1.5. Exported Pseudo-Variables - -1.5.1. $ipsec - - Populated for a request that is being received over an IPSec - tunnel, it contains information about the local IPSec endpoint. - - The following fields can be retrieved: - * ik - integrity key being used by the IPSec tunnel. - * ck - confidentiality key being used by the IPSec tunnel. - * alg - authentication algorithm being used. - * ealg - encryption algorithm being used. - * ip - local IP bound for this tunnel. - * spi-c - local SPI chosen for receiving messages through the - client channel. - * spi-s - local SPI chosen for receiving messages through the - server channel. - * port-c - local port chosen for communicating through the - client channel. - * port-c - local port chosen for communicating through the - server channel. - - Example 1.10. $ipsec(field) usage -... -xlog("Using $ipsec(ip):$ipsec(port-c) and $ipsec(ip):$ipsec(port-s) sock -et\n"); -... - -1.5.2. $ipsec_ue - - Populated for a request that is being received over an IPSec - tunnel, it contains information about the remote IPSec - endpoint. - - The following fields can be retrieved: - * ik - integrity key being used by the IPSec tunnel. - * ck - confidentiality key being used by the IPSec tunnel. - * alg - authentication algorithm being used. - * ealg - encryption algorithm being used. - * ip - remote IP of the UE that uses this tunnel. - * spi-c - remote SPI chosen for sending messages through the - client channel. - * spi-s - remote SPI chosen for sending messages through the - server channel. - * port-c - remote port chosen for communicating through the - client channel. - * port-c - remote port chosen for communicating through the - server channel. - - Example 1.11. $ipsec_ue(field) usage -... -xlog("Using $ipsec_ue(ip):$ipsec_ue(port-c) and $ipsec_ue(ip):$ipsec_ue( -port-s) socket\n"); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 65 20 4519 393 - 2. Liviu Chircu (@liviuchircu) 4 2 23 15 - 3. Alexandra Titoc 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Apr 2024 - Dec 2025 - 2. Alexandra Titoc Sep 2024 - Sep 2024 - 3. Liviu Chircu (@liviuchircu) May 2024 - May 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Solutions; diff --git a/modules/proto_ipsec/README.md b/modules/proto_ipsec/README.md new file mode 100644 index 00000000000..ed0f63ba9ac --- /dev/null +++ b/modules/proto_ipsec/README.md @@ -0,0 +1,417 @@ +--- +title: "proto_ipsec Module" +description: "The **proto_ipsec** module provides IPSec sockets for establishing secure communication channels." +--- + +## Admin Guide + + +### Overview + + +The **proto_ipsec** module provides +IPSec sockets for establishing secure communication channels. +It relies on RFC 3329 (Security Mechanism Agreement for the Session +Initiation Protocol (SIP)) to establish the IPSec parameters necessary +for creating dynamic Security Associations (SAs) for each connection. + + +This module has been developed to fully comply with the VoLTE +specification (GSMA PRD IR.92) and implements the extensions defined +in TS 33.203 (3G Security: Access Security for IP-based Services). + + +It allows creation of both UDP and TCP secure connections on the same +IP:port pair, defined as sockets. Essentially, when defining a socket +using the *proto_ipsec* protocol, two new +internal/hidden sockets are created on the specified port. +For example, defining the following socket: +```opensips +... +socket=ipsec:127.0.0.1:5100 +... +``` + +Internally, two different sockets are created: +```opensips +... +socket=udp:127.0.0.1:5100 +socket=tcp:127.0.0.1:5100 +... +``` + +Communication through these sockets should be done over IPSec, +thus appropriate security associations (SAs) should be made prior +to using these listeners, as defined in RFC 3329. + + +> [!NOTE] +> That this means that you can no longer +> define these sockets in your config, otherwise they will overlap +> with the internally defined ones. + + +IPSec communication requires each participant to define at least two +ports for each connection: one when the entity behaves as a client and +another when it behaves as a server. Consequently, it's typically +necessary to define at least two IPSec sockets for the module to +function correctly. + + +The module implements the entire logic of keeping track of the +registration status by hooking into the usrloc module and listening +for contact changes updates. It also ensures the persistency of the +tunnels by restoring them after a restart. + + +When a request is received over an IPSec tunnel, the module provides +two variables, [ipsec](#pv_ipsec) and +[ipsec ue](#pv_ipsec_ue) to inspect details about it. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tm* - used to keep track of IPSec +SA context between requests and replies. +- *usrloc* - used to identify when +a successful registration/de-registration happens. +- *proto_udp* - used for handling +IPSec UDP connections operations. +- *proto_tcp* - used for handling +IPSec TCP connections operations. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libmnl* - Minimalistic Netlink Library +used to create IPSec SA using the XFRM kernel interface. + + +### Exported Parameters + + +#### port (integer) + + +Default IPSec port used when no prot is being specified in the +*socket* global parameter. + + +*Default value is 5062.* + + +```opensips title="Set port parameter" +... +modparam("proto_ipsec", "port", 5100) +... +``` + + +#### min_spi (integer) + + +This parameter represents the minimum value for the Security +Association's (SA) SPI parameter. In conjunction with the +*max_spi* setting, it defines the SPI +range *[min_spi, max_spi]* that must be +unique within the system. + + +*Default value is 65536.* + + +```opensips title="Set min_spi parameter" +... +modparam("proto_ipsec", "min_spi", 10000) +... +``` + + +#### max_spi (integer) + + +This parameter represents the maximum value for the Security +Association's (SA) SPI parameter. In conjunction with the +*min_spi* setting, it defines the SPI +range *[min_spi, max_spi]* that must be +unique within the system. + + +*Default value is 262144.* + + +```opensips title="Set max_spi parameter" +... +modparam("proto_ipsec", "max_spi", 20000) +... +``` + + +#### temporary_timeout (integer) + + +Sets the timeout (in seconds) a temporary security association +can be stored in memory until in is confirmed (or used) by the +remote endpoint. + + +The timeout signifies the duration elapsed after sending the +Security Association's (SA) parameters in the 401 reply and +when the User Equipment (UE) transmits the initial message +over the new secure channel. + + +*Default value is 30.* + + +```opensips title="Set temporary_timeout variable" +param("proto_ipsec", "temporary_timeout", 10) # number of seconds + + +``` + + +#### default_client_port (integer) + + +Default port value to be used when we act as clients in the +IPSec communication. + + +*Default value is not defined - a random socket is being used, +but needs to be different from the server socket.* + + +```opensips title="Set default_client_port parameter" +... +modparam("proto_ipsec", "default_client_port", 5100) +... +``` + + +#### default_server_port (integer) + + +Default port value to be used when we act as server in the +IPSec communication. + + +*Default value is not defined - a random socket is being used, +but needs to be different from the client socket.* + + +```opensips title="Set default_server_port parameter" +... +modparam("proto_ipsec", "default_server_port", 6100) +... +``` + + +#### allowed_algorithms (string) + + +Whitelists the authentication and encryption algorithms +that can be used for IPSec. + + +Its format is: *alg|ealg|alg=ealg* + + +Multiple algorithms pairs can be specified separated by comma. + + +Currently supported algorithms are: + + +- Authentication algorithms: + - hmac-md5-96 - deprecated by TS 33.203 V13 + - hmac-sha-1-96 - not recommended by TS 33.203 V17 + - aes-gmac + - null - must only be used with aes-gcm encryption +- Encryption algorithms: + - des-ede3-cbc - not recommended + - aes-cbc - not recommended by TS 33.203 V17 + - aes-gcm + - null - no encryption + + +*Default value is none - this means that all algorithms can be used.* + + +```opensips title="Set allowed_algorithms parameter" +... +modparam("proto_ipsec", "allowed_algorithms", "null") +modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null") +modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null,aes-gmac=aes-gcm") +... +``` + + +#### disable_deprecated_algorithms (integer) + + +Indicates whether we should ignore deprecated algorithms, +as defined in TS 33.203 (3G Security: Access Security for +IP-based Services). At the moment, this disables the +following algorithms: + + +- *hmac-md5-96* and *hmac-sha-1-96* authentication algorithms +- *des-ede3-cbc* and *aes-cbc* encryption algorithms + + +*Default value is false - all algorithms can be used.* + + +```opensips title="Set disable_deprecated_algorithms parameter" +... +modparam("proto_ipsec", "disable_deprecated_algorithms", yes) +... +``` + + +### Exported Functions + + +#### ipsec_create([port_server], [port_client], [algos]) + + +Creates an IPSec SA/tunnel according to the +*Security-Client* header and the AKA information +received in the 401 reply. + + +This function should only be called on a 401 reply for a REGISTER message. + + +Upon successful creation of the IPSec tunnel, it builds the +*Security-Server* header and appends it to the reply. + + +Meaning of the parameters is as follows: + + +- *port_server (integer, optional)* - the server +port to be used in the IPSec communication. It should be an existing +IPSec port and is advertised in the +*Security-Server* header. If missing, the +[default client port](#param_default_client_port) is considered. +- *port_client (integer, optional)* - the client +port to be used in the IPSec communication. It should be an existing +IPSec port and is advertised in the +*Security-Server* header. If missing, the +[default server port](#param_default_server_port) is considered. +- *algos (string, optional)* - a list of +algorithms that should be used for creating this security association. +It has the same format as [allowed algorithms](#param_allowed_algorithms) +and overwrites its value when used. If missing, the +[allowed algorithms](#param_allowed_algorithms) is considered. + + +This function can be used from REPLY_ROUTE. + + +```opensips title="ipsec_create() usage" +... +onreply_route[ipsec] { + if ($T_reply_code == 401) + if (ipsec_create()) +} +... +``` + + +### Exported Pseudo-Variables + + +#### $ipsec + + +Populated for a request that is being received over +an IPSec tunnel, it contains information about the +local IPSec endpoint. + + +The following fields can be retrieved: + + +- *ik* - integrity key +being used by the IPSec tunnel. +- *ck* - confidentiality key +being used by the IPSec tunnel. +- *alg* - authentication +algorithm being used. +- *ealg* - encryption +algorithm being used. +- *ip* - local IP bound +for this tunnel. +- *spi-c* - local SPI +chosen for receiving messages through the client channel. +- *spi-s* - local SPI +chosen for receiving messages through the server channel. +- *port-c* - local port +chosen for communicating through the client channel. +- *port-c* - local port +chosen for communicating through the server channel. + + +```opensips title="$ipsec(field) usage" +... +xlog("Using $ipsec(ip):$ipsec(port-c) and $ipsec(ip):$ipsec(port-s) socket\n"); +... +``` + + +#### $ipsec_ue + + +Populated for a request that is being received over +an IPSec tunnel, it contains information about the +remote IPSec endpoint. + + +The following fields can be retrieved: + + +- *ik* - integrity key +being used by the IPSec tunnel. +- *ck* - confidentiality key +being used by the IPSec tunnel. +- *alg* - authentication +algorithm being used. +- *ealg* - encryption +algorithm being used. +- *ip* - remote IP of +the UE that uses this tunnel. +- *spi-c* - remote SPI +chosen for sending messages through the client channel. +- *spi-s* - remote SPI +chosen for sending messages through the server channel. +- *port-c* - remote port +chosen for communicating through the client channel. +- *port-c* - remote port +chosen for communicating through the server channel. + + +```opensips title="$ipsec_ue(field) usage" +... +xlog("Using $ipsec_ue(ip):$ipsec_ue(port-c) and $ipsec_ue(ip):$ipsec_ue(port-s) socket\n"); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_ipsec/doc/contributors.xml b/modules/proto_ipsec/doc/contributors.xml deleted file mode 100644 index 572af1d930c..00000000000 --- a/modules/proto_ipsec/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 65 - 20 - 4519 - 393 - - - 2. - Liviu Chircu (@liviuchircu) - 4 - 2 - 23 - 15 - - - 3. - Alexandra Titoc - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Apr 2024 - Dec 2025 - - - 2. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 3. - Liviu Chircu (@liviuchircu) - May 2024 - May 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/proto_ipsec/doc/proto_ipsec.xml b/modules/proto_ipsec/doc/proto_ipsec.xml deleted file mode 100644 index 99ec5da3e3b..00000000000 --- a/modules/proto_ipsec/doc/proto_ipsec.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_ipsec Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Solutions; - - diff --git a/modules/proto_ipsec/doc/proto_ipsec_admin.xml b/modules/proto_ipsec/doc/proto_ipsec_admin.xml deleted file mode 100644 index 7f3d3672cfe..00000000000 --- a/modules/proto_ipsec/doc/proto_ipsec_admin.xml +++ /dev/null @@ -1,521 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_ipsec module provides - IPSec sockets for establishing secure communication channels. - It relies on RFC 3329 (Security Mechanism Agreement for the Session - Initiation Protocol (SIP)) to establish the IPSec parameters necessary - for creating dynamic Security Associations (SAs) for each connection. - - - This module has been developed to fully comply with the VoLTE - specification (GSMA PRD IR.92) and implements the extensions defined - in TS 33.203 (3G Security: Access Security for IP-based Services). - - - It allows creation of both UDP and TCP secure connections on the same - IP:port pair, defined as sockets. Essentially, when defining a socket - using the proto_ipsec protocol, two new - internal/hidden sockets are created on the specified port. - For example, defining the following socket: - - -... -socket=ipsec:127.0.0.1:5100 -... - - - Internally, two different sockets are created: - - -... -socket=udp:127.0.0.1:5100 -socket=tcp:127.0.0.1:5100 -... - - - Communication through these sockets should be done over IPSec, - thus appropriate security associations (SAs) should be made prior - to using these listeners, as defined in RFC 3329. - - - NOTE that this means that you can no longer - define these sockets in your config, otherwise they will overlap - with the internally defined ones. - - - IPSec communication requires each participant to define at least two - ports for each connection: one when the entity behaves as a client and - another when it behaves as a server. Consequently, it's typically - necessary to define at least two IPSec sockets for the module to - function correctly. - - - The module implements the entire logic of keeping track of the - registration status by hooking into the usrloc module and listening - for contact changes updates. It also ensures the persistency of the - tunnels by restoring them after a restart. - - - When a request is received over an IPSec tunnel, the module provides - two variables, and - to inspect details about it. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tm - used to keep track of IPSec - SA context between requests and replies. - - - - - usrloc - used to identify when - a successful registration/de-registration happens. - - - - - proto_udp - used for handling - IPSec UDP connections operations. - - - - - proto_tcp - used for handling - IPSec TCP connections operations. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libmnl - Minimalistic Netlink Library - used to create IPSec SA using the XFRM kernel interface. - - - - -
-
- -
- Exported Parameters -
- <varname>port</varname> (integer) - - Default IPSec port used when no prot is being specified in the - socket global parameter. - - - - Default value is 5062. - - - - Set <varname>port</varname> parameter - -... -modparam("proto_ipsec", "port", 5100) -... - - -
-
- <varname>min_spi</varname> (integer) - - This parameter represents the minimum value for the Security - Association's (SA) SPI parameter. In conjunction with the - max_spi setting, it defines the SPI - range [min_spi, max_spi] that must be - unique within the system. - - - - Default value is 65536. - - - - Set <varname>min_spi</varname> parameter - -... -modparam("proto_ipsec", "min_spi", 10000) -... - - -
-
- <varname>max_spi</varname> (integer) - - This parameter represents the maximum value for the Security - Association's (SA) SPI parameter. In conjunction with the - min_spi setting, it defines the SPI - range [min_spi, max_spi] that must be - unique within the system. - - - - Default value is 262144. - - - - Set <varname>max_spi</varname> parameter - -... -modparam("proto_ipsec", "max_spi", 20000) -... - - -
- -
- <varname>temporary_timeout</varname> (integer) - - Sets the timeout (in seconds) a temporary security association - can be stored in memory until in is confirmed (or used) by the - remote endpoint. - - - The timeout signifies the duration elapsed after sending the - Security Association's (SA) parameters in the 401 reply and - when the User Equipment (UE) transmits the initial message - over the new secure channel. - - - Default value is 30. - - - Set <varname>temporary_timeout</varname> variable - - -param("proto_ipsec", "temporary_timeout", 10) # number of seconds - - - -
- - -
- <varname>default_client_port</varname> (integer) - - Default port value to be used when we act as clients in the - IPSec communication. - - - - Default value is not defined - a random socket is being used, - but needs to be different from the server socket. - - - - Set <varname>default_client_port</varname> parameter - -... -modparam("proto_ipsec", "default_client_port", 5100) -... - - -
- -
- <varname>default_server_port</varname> (integer) - - Default port value to be used when we act as server in the - IPSec communication. - - - - Default value is not defined - a random socket is being used, - but needs to be different from the client socket. - - - - Set <varname>default_server_port</varname> parameter - -... -modparam("proto_ipsec", "default_server_port", 6100) -... - - -
- -
- <varname>allowed_algorithms</varname> (string) - - Whitelists the authentication and encryption algorithms - that can be used for IPSec. - - - Its format is: alg|ealg|alg=ealg - - - Multiple algorithms pairs can be specified separated by comma. - - - Currently supported algorithms are: - - - - Authentication algorithms: - - hmac-md5-96 - deprecated by TS 33.203 V13 - hmac-sha-1-96 - not recommended by TS 33.203 V17 - aes-gmac - null - must only be used with aes-gcm encryption - - - - - - Encryption algorithms: - - des-ede3-cbc - not recommended - aes-cbc - not recommended by TS 33.203 V17 - aes-gcm - null - no encryption - - - - - - - - Default value is none - this means that all algorithms can be used. - - - - Set <varname>allowed_algorithms</varname> parameter - -... -modparam("proto_ipsec", "allowed_algorithms", "null") -modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null") -modparam("proto_ipsec", "allowed_algorithms", "hmac-sha-1-96=null,aes-gmac=aes-gcm") -... - - -
- -
- <varname>disable_deprecated_algorithms</varname> (integer) - - Indicates whether we should ignore deprecated algorithms, - as defined in TS 33.203 (3G Security: Access Security for - IP-based Services). At the moment, this disables the - following algorithms: - - - - hmac-md5-96 and hmac-sha-1-96 authentication algorithms - - - - - des-ede3-cbc and aes-cbc encryption algorithms - - - - - - - Default value is false - all algorithms can be used. - - - - Set <varname>disable_deprecated_algorithms</varname> parameter - -... -modparam("proto_ipsec", "disable_deprecated_algorithms", yes) -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">ipsec_create([port_server], [port_client], [algos])</function> - - - Creates an IPSec SA/tunnel according to the - Security-Client header and the AKA information - received in the 401 reply. - - - This function should only be called on a 401 reply for a REGISTER message. - - - Upon successful creation of the IPSec tunnel, it builds the - Security-Server header and appends it to the reply. - - Meaning of the parameters is as follows: - - - port_server (integer, optional) - the server - port to be used in the IPSec communication. It should be an existing - IPSec port and is advertised in the - Security-Server header. If missing, the - is considered. - - - - port_client (integer, optional) - the client - port to be used in the IPSec communication. It should be an existing - IPSec port and is advertised in the - Security-Server header. If missing, the - is considered. - - - - algos (string, optional) - a list of - algorithms that should be used for creating this security association. - It has the same format as - and overwrites its value when used. If missing, the - is considered. - - - - - - This function can be used from REPLY_ROUTE. - - - <function>ipsec_create()</function> usage - -... -onreply_route[ipsec] { - if ($T_reply_code == 401) - if (ipsec_create()) -} -... - - -
-
- -
- Exported Pseudo-Variables -
- <varname>$ipsec</varname> - - Populated for a request that is being received over - an IPSec tunnel, it contains information about the - local IPSec endpoint. - - - The following fields can be retrieved: - - ik - integrity key - being used by the IPSec tunnel. - - ck - confidentiality key - being used by the IPSec tunnel. - - alg - authentication - algorithm being used. - - ealg - encryption - algorithm being used. - - ip - local IP bound - for this tunnel. - - spi-c - local SPI - chosen for receiving messages through the client channel. - - spi-s - local SPI - chosen for receiving messages through the server channel. - - port-c - local port - chosen for communicating through the client channel. - - port-c - local port - chosen for communicating through the server channel. - - - - - <function>$ipsec(field)</function> usage - -... -xlog("Using $ipsec(ip):$ipsec(port-c) and $ipsec(ip):$ipsec(port-s) socket\n"); -... - - -
-
- <varname>$ipsec_ue</varname> - - Populated for a request that is being received over - an IPSec tunnel, it contains information about the - remote IPSec endpoint. - - - The following fields can be retrieved: - - ik - integrity key - being used by the IPSec tunnel. - - ck - confidentiality key - being used by the IPSec tunnel. - - alg - authentication - algorithm being used. - - ealg - encryption - algorithm being used. - - ip - remote IP of - the UE that uses this tunnel. - - spi-c - remote SPI - chosen for sending messages through the client channel. - - spi-s - remote SPI - chosen for sending messages through the server channel. - - port-c - remote port - chosen for communicating through the client channel. - - port-c - remote port - chosen for communicating through the server channel. - - - - - <function>$ipsec_ue(field)</function> usage - -... -xlog("Using $ipsec_ue(ip):$ipsec_ue(port-c) and $ipsec_ue(ip):$ipsec_ue(port-s) socket\n"); -... - - -
-
- -
diff --git a/modules/proto_msrp/README b/modules/proto_msrp/README deleted file mode 100644 index 52d04c70666..00000000000 --- a/modules/proto_msrp/README +++ /dev/null @@ -1,310 +0,0 @@ -proto_msrp Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. send_timeout (integer) - 1.3.2. max_msg_chunks (integer) - 1.3.3. tls_handshake_timeout (integer) - 1.3.4. cert_check_on_conn_reusage (integer) - 1.3.5. trace_destination (string) - 1.3.6. trace_on (int) - 1.3.7. trace_filter_route (string) - - 1.4. Exported MI Functions - - 1.4.1. msrp_trace - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set send_timeout parameter - 1.2. Set max_msg_chunks parameter - 1.3. Set tls_handshake_timeout variable - 1.4. Set cert_check_on_conn_reusage parameter - 1.5. Set trace_destination parameter - 1.6. Set trace_on parameter - 1.7. Set trace_filter_route parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The proto_msrp module provides the MSRP protocol stack, meaning - the network read/wite (plain and TLS), message parsing and - assembling, transactional layer and the basic signalling - operations. - - Once loaded, you will be able to define MSRP listeners in your - script, by adding its IP, and optionally the listening port, in - your configuration file, similar to this example: - -... -socket=msrp:127.0.0.1:65432 -socket=msrps:127.0.0.1:65431 -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_mgm - you need to load this module if using MSRPS - (secure) sockets. Via this module you will manage the SSL - certificates - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. send_timeout (integer) - - Time in milliseconds after a MSRP connection will be closed if - it is not available for blocking writing in this interval (and - OpenSIPS wants to send something on it). - - Default value is 100 ms. - - Example 1.1. Set send_timeout parameter -... -modparam("proto_msrp", "send_timeout", 200) -... - -1.3.2. max_msg_chunks (integer) - - The maximum number of chunks that a SIP message is expected to - arrive via MSRP. If a packet is received more fragmented than - this, the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending the - traffic very fragmented in order to decrease our performance). - - Default value is 4. - - Example 1.2. Set max_msg_chunks parameter -... -modparam("proto_msrp", "max_msg_chunks", 8) -... - -1.3.3. tls_handshake_timeout (integer) - - Sets the timeout (in milliseconds) for the SSL handshake - sequence to complete. It may be necessary to increase this - value when using a CPU intensive cipher for the connection to - allow time for keys to be generated and processed. - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is - being initiated (outbound). - - Default value is 100. - - Example 1.3. Set tls_handshake_timeout variable - -param("proto_msrp", "tls_handshake_timeout", 200) # number of millisecon -ds - - -1.3.4. cert_check_on_conn_reusage (integer) - - This parameter turns on or off the extra checking/matching of - the TLS domain (SSL certificate) when comes to reusing an - existing TLS connection. Without this extra check, only IP and - port of the connections will be check (in order to re-use an - existing connection). With this extra check, the connection to - be reused must have the same SSL certificate as the one set for - the current signaling operation. - - This checking is done only when comes to send SIP traffic via - TLS and it is applied only against connections that were - created / initiated by OpenSIPS (as TLS client). Any accepte - connection (as TLS server) will automatically match (the extra - test will be skipped). - - Default value is 0 (disabled). - - Example 1.4. Set cert_check_on_conn_reusage parameter -... -modparam("proto_msrp", "cert_check_on_conn_reusage", 1) -... - -1.3.5. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. Network events such as - connect, accept and connection closed events shall be traced - along with errors that could appear in the process. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.5. Set trace_destination parameter -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;versio -n=3") - -modparam("proto_msrp", "trace_destination", "hep_dest") -... - -1.3.6. trace_on (int) - - This controls whether tracing for MSRP is on or not. You still - need to define Section 1.3.5, “trace_destination (string)”in - order to work, but this value will be controlled using MI - function Section 1.4.1, “ msrp_trace ”. - Default value is 0(tracing inactive). - - Example 1.6. Set trace_on parameter -... -modparam("proto_msrp", "trace_on", 1) -... - -1.3.7. trace_filter_route (string) - - Define the name of a route in which you can filter which - connections will be trace and which connections won't be. In - this route you will have information regarding source and - destination ips and ports for the current connection. To - disable tracing for a specific connection the last call in this - route must be drop, any other exit mode resulting in tracing - the current connection ( of course you still have to define a - Section 1.3.5, “trace_destination (string)” and trace must be - on at the time this connection is opened. - - IMPORTANT Filtering on ip addresses and ports can be made using - $si and $sp for matching either the entity that is connecting - to OpenSIPS or the entity to which OpenSIPS is connecting. The - name might be misleading ( $si meaning the source ip if you - read the docs) but in reality it is simply the socket other - than the OpenSIPS socket. In order to match OpenSIPS interface - (either the one that accepted the connection or the one that - initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - WARNING: IF Section 1.3.6, “trace_on (int)” is set to 0 or - tracing is deactived via the mi command Section 1.4.1, “ - msrp_trace ” this route won't be called. - Default value is none(no route is set). - - Example 1.7. Set trace_filter_route parameter -... -modparam("proto_msrp", "trace_filter_route", "msrp_filter") -... -/* all MSRP connections will go through this route if tracing is activat -ed - * and a trace destination is defined */ -route[msrp_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 506 -0) - exit; - else - drop; -} -... - -1.4. Exported MI Functions - -1.4.1. msrp_trace - - Name: msrp_trace - - Parameters: - * trace_mode(optional): set MSRP tracing on and off. This - parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - + on - + off - - MI FIFO Command Format: - :msrp_trace:_reply_fifo_file_ - trace_mode - _empty_line_ - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 67 17 4831 525 - 2. Vlad Patrascu (@rvlad-patrascu) 32 22 422 348 - 3. Maksym Sobolyev (@sobomax) 6 4 30 28 - 4. Liviu Chircu (@liviuchircu) 6 4 23 21 - 5. Razvan Crainea (@razvancrainea) 5 3 5 3 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Sep 2022 - Jul 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2022 - May 2023 - 4. Vlad Patrascu (@rvlad-patrascu) Mar 2022 - Jul 2022 - 5. Liviu Chircu (@liviuchircu) Apr 2022 - Jul 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2022 www.opensips-solutions.com diff --git a/modules/proto_msrp/README.md b/modules/proto_msrp/README.md new file mode 100644 index 00000000000..ff298010612 --- /dev/null +++ b/modules/proto_msrp/README.md @@ -0,0 +1,267 @@ +--- +title: "proto_msrp Module" +description: "The **proto_msrp** module provides the MSRP protocol stack, meaning the network read/wite (plain and TLS), message parsing and assembling, transactional layer and the basic signalling operations." +--- + +## Admin Guide + + +### Overview + + +The **proto_msrp** module provides +the MSRP protocol stack, meaning the network read/wite (plain and TLS), +message parsing and assembling, transactional layer and the basic +signalling operations. + + +Once loaded, you will be able to define MSRP listeners in your script, +by adding its IP, and optionally the listening port, +in your configuration file, similar to this example: +```opensips +... +socket=msrp:127.0.0.1:65432 +socket=msrps:127.0.0.1:65431 +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_mgm* - you need to load this module +if using MSRPS (secure) sockets. Via this module you will +manage the SSL certificates + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### send_timeout (integer) + + +Time in milliseconds after a MSRP connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set send_timeout parameter" +... +modparam("proto_msrp", "send_timeout", 200) +... +``` + + +#### max_msg_chunks (integer) + + +The maximum number of chunks that a SIP message is expected to +arrive via MSRP. If a packet is received more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending the +traffic very fragmented in order to decrease our performance). + + +*Default value is 4.* + + +```opensips title="Set max_msg_chunks parameter" +... +modparam("proto_msrp", "max_msg_chunks", 8) +... +``` + + +#### tls_handshake_timeout (integer) + + +Sets the timeout (in milliseconds) for the SSL handshake sequence +to complete. It may be necessary to increase this value when using +a CPU intensive cipher +for the connection to allow time for keys to be generated and +processed. + + +The timeout is invoked during acceptance of a new connection +(inbound) and during the wait period when a new session is being +initiated (outbound). + + +*Default value is 100.* + + +```opensips title="Set tls_handshake_timeout variable" +param("proto_msrp", "tls_handshake_timeout", 200) # number of milliseconds +``` + + +#### cert_check_on_conn_reusage (integer) + + +This parameter turns on or off the extra checking/matching of the +TLS domain (SSL certificate) when comes to reusing an existing TLS +connection. Without this extra check, only IP and port of the +connections will be check (in order to re-use an existing connection). +With this extra check, the connection to be reused must have the same +SSL certificate as the one set for the current signaling operation. + + +This checking is done only when comes to send SIP traffic via TLS and +it is applied only against connections that were created / initiated +by OpenSIPS (as TLS client). Any accepte connection (as TLS server) +will automatically match (the extra test will be skipped). + + +*Default value is 0 (disabled).* + + +```opensips title="Set cert_check_on_conn_reusage parameter" +... +modparam("proto_msrp", "cert_check_on_conn_reusage", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. + + +**WARNING:**A tracing module must be +loaded in order for this parameter to work. (for example +**proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("proto_msrp", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for MSRP is on or not. You still need +to define [trace destination](#param_trace_destination)in order to work, but +this value will be controlled using MI function +[msrp trace](#mi_msrp_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_msrp", "trace_on", 1) +... +``` + + +#### trace_filter_route (string) + + +Define the name of a route in which you can filter which connections will +be trace and which connections won't be. In this route you will have +information regarding source and destination ips and ports for the current +connection. To disable tracing for a specific connection the last call in +this route must be **drop**, any other exit +mode resulting in tracing the current connection ( of course you still +have to define a [trace destination](#param_trace_destination) and trace must be +on at the time this connection is opened. + + +> [!IMPORTANT] +> Filtering on ip addresses and ports can be made using **$si** and **$sp** for matching +> either the entity that is connecting to OpenSIPS or the entity to which +> OpenSIPS is connecting. The name might be misleading (**$si** meaning the source ip if you read the docs) but in reality +> it is simply the socket other than the OpenSIPS socket. In order to match +> OpenSIPS interface (either the one that accepted the connection or the one +> that initiated a connection) **$socket_in(ip)** (ip) and +> **$socket_in(port)** (port) can be used. + + +> [!WARNING] +> If [trace on](#param_trace_on) is +> set to 0 or tracing is deactived via the mi command [msrp trace](#msrp-trace) +> this route won't be called. + + +```opensips title="Set trace_filter_route parameter" +... +modparam("proto_msrp", "trace_filter_route", "msrp_filter") +... +/* all MSRP connections will go through this route if tracing is activated + * and a trace destination is defined */ +route[msrp_filter] { + ... + /* all connections opened from/by ip 1.1.1.1:8000 will be traced + on interface 1.1.1.10:5060(opensips listener) + all the other connections won't be */ + if ( $si == "1.1.1.1" && $sp == 8000 && + $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) + exit; + else + drop; +} +... +``` + + +### Exported MI Functions + + +#### msrp_trace + + +Name: *msrp_trace* + + +Parameters: + + +- trace_mode(optional): set MSRP tracing on and off. +This parameter can be missing and the command will show the +current tracing status for this module( on or off ); +Possible values: + - on + - off + + +MI FIFO Command Format: +```bash +:msrp_trace:_reply_fifo_file_ +trace_mode +_empty_line_ +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_msrp/doc/contributors.xml b/modules/proto_msrp/doc/contributors.xml deleted file mode 100644 index 89a653b0629..00000000000 --- a/modules/proto_msrp/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 67 - 17 - 4831 - 525 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 32 - 22 - 422 - 348 - - - 3. - Maksym Sobolyev (@sobomax) - 6 - 4 - 30 - 28 - - - 4. - Liviu Chircu (@liviuchircu) - 6 - 4 - 23 - 21 - - - 5. - Razvan Crainea (@razvancrainea) - 5 - 3 - 5 - 3 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Sep 2022 - Jul 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2022 - May 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Mar 2022 - Jul 2022 - - - 5. - Liviu Chircu (@liviuchircu) - Apr 2022 - Jul 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/proto_msrp/doc/proto_msrp.xml b/modules/proto_msrp/doc/proto_msrp.xml deleted file mode 100644 index 0cdb46fc98c..00000000000 --- a/modules/proto_msrp/doc/proto_msrp.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_msrp Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssol; - - diff --git a/modules/proto_msrp/doc/proto_msrp_admin.xml b/modules/proto_msrp/doc/proto_msrp_admin.xml deleted file mode 100644 index 643dcfb369c..00000000000 --- a/modules/proto_msrp/doc/proto_msrp_admin.xml +++ /dev/null @@ -1,322 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_msrp module provides - the MSRP protocol stack, meaning the network read/wite (plain and TLS), - message parsing and assembling, transactional layer and the basic - signalling operations. - -
- - Once loaded, you will be able to define MSRP listeners in your script, - by adding its IP, and optionally the listening port, - in your configuration file, similar to this example: - - -... -socket=msrp:127.0.0.1:65432 -socket=msrps:127.0.0.1:65431 -... - - - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_mgm - you need to load this module - if using MSRPS (secure) sockets. Via this module you will - manage the SSL certificates - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>send_timeout</varname> (integer) - - Time in milliseconds after a MSRP connection will be closed if it is - not available for blocking writing in this interval (and &osips; wants - to send something on it). - - - - Default value is 100 ms. - - - - Set <varname>send_timeout</varname> parameter - -... -modparam("proto_msrp", "send_timeout", 200) -... - - -
-
- <varname>max_msg_chunks</varname> (integer) - - The maximum number of chunks that a SIP message is expected to - arrive via MSRP. If a packet is received more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending the - traffic very fragmented in order to decrease our performance). - - - - Default value is 4. - - - - Set <varname>max_msg_chunks</varname> parameter - -... -modparam("proto_msrp", "max_msg_chunks", 8) -... - - -
- -
- <varname>tls_handshake_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the SSL handshake sequence - to complete. It may be necessary to increase this value when using - a CPU intensive cipher - for the connection to allow time for keys to be generated and - processed. - - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is being - initiated (outbound). - - - Default value is 100. - - - Set <varname>tls_handshake_timeout</varname> variable - - -param("proto_msrp", "tls_handshake_timeout", 200) # number of milliseconds - - - -
- - -
- <varname>cert_check_on_conn_reusage</varname> (integer) - - This parameter turns on or off the extra checking/matching of the - TLS domain (SSL certificate) when comes to reusing an existing TLS - connection. Without this extra check, only IP and port of the - connections will be check (in order to re-use an existing connection). - With this extra check, the connection to be reused must have the same - SSL certificate as the one set for the current signaling operation. - - - This checking is done only when comes to send SIP traffic via TLS and - it is applied only against connections that were created / initiated - by OpenSIPS (as TLS client). Any accepte connection (as TLS server) - will automatically match (the extra test will be skipped). - - - - Default value is 0 (disabled). - - - - Set <varname>cert_check_on_conn_reusage</varname> parameter - -... -modparam("proto_msrp", "cert_check_on_conn_reusage", 1) -... - - -
- - -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_msrp", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for MSRP is on or not. You still need - to define in order to work, but - this value will be controlled using MI function - . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_msrp", "trace_on", 1) -... - - -
- -
- <varname>trace_filter_route</varname> (string) - - Define the name of a route in which you can filter which connections will - be trace and which connections won't be. In this route you will have - information regarding source and destination ips and ports for the current - connection. To disable tracing for a specific connection the last call in - this route must be drop, any other exit - mode resulting in tracing the current connection ( of course you still - have to define a and trace must be - on at the time this connection is opened. - - - IMPORTANT - Filtering on ip addresses and ports can be made using - $si and $sp for matching - either the entity that is connecting to &osips; or the entity to which - &osips; is connecting. The name might be misleading ( - $si meaning the source ip if you read the docs) but in reality - it is simply the socket other than the &osips; socket. In order to match - &osips; interface (either the one that accepted the connection or the one - that initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - - WARNING: IF is - set to 0 or tracing is deactived via the mi command - this route won't be called. - - - Default value is none(no route is set). - - - Set <varname>trace_filter_route</varname> parameter - -... -modparam("proto_msrp", "trace_filter_route", "msrp_filter") -... -/* all MSRP connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[msrp_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) - exit; - else - drop; -} -... - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">msrp_trace</function> - - - - - - - Name: msrp_trace - - - Parameters: - - - trace_mode(optional): set MSRP tracing on and off. - This parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - :msrp_trace:_reply_fifo_file_ - trace_mode - _empty_line_ - -
-
-
diff --git a/modules/proto_msrp/msrp_parser.c b/modules/proto_msrp/msrp_parser.c index 16cd49298c4..0914f9cba8d 100644 --- a/modules/proto_msrp/msrp_parser.c +++ b/modules/proto_msrp/msrp_parser.c @@ -184,12 +184,13 @@ int parse_msrp_msg( char* buf, int len, struct msrp_msg *msg) case HDR_EXPIRES_T: link_hdr( expires, hf); break; - case HDR_OTHER_T: - break; case HDR_ERROR_T: - default: LM_INFO("bad header field\n"); goto err_free_hf; + case HDR_OTHER_T: + default: + /* There can be other headers in the MSRP but we don't need to use them, so ignoring it */ + break; } /* add the header to the list*/ diff --git a/modules/proto_sctp/README b/modules/proto_sctp/README deleted file mode 100644 index 18b3cb7aa23..00000000000 --- a/modules/proto_sctp/README +++ /dev/null @@ -1,154 +0,0 @@ -proto_sctp Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. sctp_port (integer) - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set sctp_port parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The proto_sctp module is an optional transport module (shared - library) which exports the required logic in order to handle - SCTP-based communication. (socket initialization and send/recv - primitives to be used by higher-level network layers) - - Once loaded, you will be able to define "sctp:" listeners in - your script. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. sctp_port (integer) - - The default port to be used for all SCTP related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the SCTP listeners) and the SIP - sending part (if the destination SCTP URI has no explicit - port). - - If you want to change only the listening port for STP, use the - port option in the SIP listener defintion. - - Default value is 5060. - - Example 1.1. Set sctp_port parameter -... -modparam("proto_sctp", "sctp_port", 5070) -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - After switching to OpenSIPS 2.1, I'm getting this error: - "listeners found for protocol sctp, but no module can handle - it" - - You need to load the "proto_sctp" module. In your script, make - sure you do a loadmodule "proto_sctp.so" after setting the - mpath. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 11 5 448 73 - 2. Razvan Crainea (@razvancrainea) 10 8 11 18 - 3. Liviu Chircu (@liviuchircu) 7 4 153 25 - 4. Maksym Sobolyev (@sobomax) 4 2 11 10 - 5. Ionut Ionita (@ionutrazvanionita) 3 1 1 1 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - 7. Zero King (@l2dy) 3 1 1 1 - 8. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2015 - Apr 2021 - 3. Zero King (@l2dy) Mar 2020 - Mar 2020 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 6. Liviu Chircu (@liviuchircu) Mar 2015 - Jun 2018 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 8. Ionut Ionita (@ionutrazvanionita) Feb 2016 - Feb 2016 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Zero King (@l2dy), Peter Lemenkov (@lemenkov), - Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_sctp/README.md b/modules/proto_sctp/README.md new file mode 100644 index 00000000000..5f9cf9d6165 --- /dev/null +++ b/modules/proto_sctp/README.md @@ -0,0 +1,82 @@ +--- +title: "proto_sctp Module" +description: "The **proto_sctp** module is an optional transport module (shared library) which exports the required logic in order to handle SCTP-based communication." +--- + +## Admin Guide + + +### Overview + + +The **proto_sctp** module is an optional transport module (shared library) which +exports the required logic in order to handle SCTP-based communication. (socket initialization +and send/recv primitives to be used by higher-level network layers) + + +Once loaded, you will be able to define *"sctp:"* listeners in your script. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### sctp_port (integer) + + +The default port to be used for all SCTP related operation. Be careful +as the default port impacts both the SIP listening part (if no port is +defined in the SCTP listeners) and the SIP sending part (if the +destination SCTP URI has no explicit port). + + +If you want to change only the listening port for STP, use the port +option in the SIP listener defintion. + + +*Default value is 5060.* + + +```opensips title="Set sctp_port parameter" +... +modparam("proto_sctp", "sctp_port", 5070) +... +``` + + +## Frequently Asked Questions + + +**Q: After switching to OpenSIPS 2.1, I'm getting this error: +"listeners found for protocol sctp, but no module can handle it"** + + +You need to load the "proto_sctp" module. In your script, make sure +you do a **loadmodule "proto_sctp.so"** +after setting the **[mpath](https://docs.opensips.org/manual/3-6/script-coreparameters#mpath)**. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_sctp/doc/contributors.xml b/modules/proto_sctp/doc/contributors.xml deleted file mode 100644 index 7f2e4a6a628..00000000000 --- a/modules/proto_sctp/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 11 - 5 - 448 - 73 - - - 2. - Razvan Crainea (@razvancrainea) - 10 - 8 - 11 - 18 - - - 3. - Liviu Chircu (@liviuchircu) - 7 - 4 - 153 - 25 - - - 4. - Maksym Sobolyev (@sobomax) - 4 - 2 - 11 - 10 - - - 5. - Ionut Ionita (@ionutrazvanionita) - 3 - 1 - 1 - 1 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 7. - Zero King (@l2dy) - 3 - 1 - 1 - 1 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2015 - Apr 2021 - - - 3. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2015 - Jun 2018 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 8. - Ionut Ionita (@ionutrazvanionita) - Feb 2016 - Feb 2016 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Zero King (@l2dy), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/proto_sctp/doc/proto_sctp.xml b/modules/proto_sctp/doc/proto_sctp.xml deleted file mode 100644 index 30218258803..00000000000 --- a/modules/proto_sctp/doc/proto_sctp.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - proto_sctp Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - diff --git a/modules/proto_sctp/doc/proto_sctp_admin.xml b/modules/proto_sctp/doc/proto_sctp_admin.xml deleted file mode 100644 index e6c78d558f4..00000000000 --- a/modules/proto_sctp/doc/proto_sctp_admin.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_sctp module is an optional transport module (shared library) which - exports the required logic in order to handle SCTP-based communication. (socket initialization - and send/recv primitives to be used by higher-level network layers) - - - Once loaded, you will be able to define "sctp:" listeners in your script. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>sctp_port</varname> (integer) - - The default port to be used for all SCTP related operation. Be careful - as the default port impacts both the SIP listening part (if no port is - defined in the SCTP listeners) and the SIP sending part (if the - destination SCTP URI has no explicit port). - - - If you want to change only the listening port for STP, use the port - option in the SIP listener defintion. - - - - Default value is 5060. - - - - Set <varname>sctp_port</varname> parameter - -... -modparam("proto_sctp", "sctp_port", 5070) -... - - -
-
- -
diff --git a/modules/proto_sctp/doc/proto_sctp_faq.xml b/modules/proto_sctp/doc/proto_sctp_faq.xml deleted file mode 100644 index 6b448ad7c0f..00000000000 --- a/modules/proto_sctp/doc/proto_sctp_faq.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - &faqguide; - - - - - After switching to OpenSIPS 2.1, I'm getting this error: - "listeners found for protocol sctp, but no module can handle it" - - - - - You need to load the "proto_sctp" module. In your script, make sure - you do a loadmodule "proto_sctp.so" - after setting the mpath. - - - - - - diff --git a/modules/proto_smpp/README b/modules/proto_smpp/README deleted file mode 100644 index ddb7a8edbe6..00000000000 --- a/modules/proto_smpp/README +++ /dev/null @@ -1,509 +0,0 @@ -proto_smpp module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. SIP to SMPP bridging - 1.3. SMPP to SIP bridging - 1.4. SMSC binding - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. Dependencies of external libraries - - 1.6. OpenSIPS Exported parameters - - 1.6.1. db_url (string) - 1.6.2. smpp_port (integer) - 1.6.3. smpp_max_msg_chunks (integer) - 1.6.4. smpp_send_timeout (integer) - 1.6.5. outbound_uri (string) - 1.6.6. smpp_table (string) - 1.6.7. name_col (string) - 1.6.8. ip_col (string) - 1.6.9. port_col (string) - 1.6.10. system_id_col (string) - 1.6.11. password_col (string) - 1.6.12. system_type_col (string) - 1.6.13. src_ton_col (string) - 1.6.14. src_npi_col (string) - 1.6.15. dst_ton_col (string) - 1.6.16. dst_npi_col (string) - 1.6.17. session_type_col (string) - - 1.7. Exported Functions - - 1.7.1. send_smpp_message(smsc_name, - [from],[to],[body],[utf-16],[delivery_receip - t]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set smpp_port variable - 1.3. Set smpp_max_msg_chunks parameter - 1.4. Set smpp_send_timeout parameter - 1.5. Set outbound_uri parameter - 1.6. Set smpp_table parameter - 1.7. Set name_col parameter - 1.8. Set ip_col parameter - 1.9. Set port_col parameter - 1.10. Set system_id_col parameter - 1.11. Set password_col parameter - 1.12. Set system_type_col parameter - 1.13. Set src_ton_col parameter - 1.14. Set src_npi_col parameter - 1.15. Set dst_ton_col parameter - 1.16. Set dst_npi_col parameter - 1.17. Set session_type_col parameter - 1.18. send_smpp_message() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module offers interoperability between SIP and SMPP (Short - Message Peer-to-Peer) protocols. It provides the means to build - a messaging gateway/bridge between the two protocols, being - able to convert messages from both directions. - - * SIP to SMPP - messages coming from SIP can be converted to - a SMPP PDU (Protocol Data Unit) message and sent further to - a SMSC (Short Message Service Center). - * SMPP to SIP - the module can act as an ESME (External Short - Messaging Entity), receiving messages from a SMSC and - converting them to a SIP Message that is sent further to a - SIP proxy. - - The module is compatible with the SMPP v3.4 specifications. - -1.2. SIP to SMPP bridging - - In order to convert a SIP message to a SMPP all you need to do - is to call the send_smpp_message() function, indicating the - SMSc you want to send the message to. The module will build the - PDU according to the parameters provisioned in the database. - -1.3. SMPP to SIP bridging - - When bridging a message received over the SMPP interface, - OpenSIPS builds a SIP Message and sends it to the outbound - proxy identified by the outbound_uri module's parameter. - -1.4. SMSC binding - - In order to be able to deliver messages to SMSc, an ESME needs - to first bind to the SMSc. This is done at OpenSIPS startup by - sending a SMPP bind_transciever command to connect to the SMSc, - or an outbind command to inform an SMSc it can now bind to our - gateway. - - The description of all SMSc servers is provisioned in the - database. For each server, one can cofigure the following - information: - * Name - an unique name given to the SMSc that is used to - reference this SMSc in the OpenSIPS script. - * IP - The IP the SMSc is listening on for new - bindings/connections. - * Port - The TCP port that the SMSc is listening on for new - bindings/connections. - * System ID - Also known as the User name that is used to - authenticate to the SMSc. - * Password - A password used to authenticate to the SMSc. - * System Type - Usually “SMPP”, this field is required by - some SMPP providers. - * Source Type of Number (TON) - Specifies the format of the - number used to send messages from. Some comon values are: - + 0 - Unknown - + 1 - International - + 2 - National - + 3 - Network Specific - + 4 - Subscriber Number - + 5 - Alphanumeric - + 6 - Abbreviated - Default value is 0 - Unknown. - * Source Number Plan Indicator (NPI) - Specifies the - numbering scheme of the number used to send messages from. - Some comon values are: - + 0 - Unknown - + 1 - ISDN/telephone numbering plan (E163/E164) - + 3 - Data numbering plan (X.121) - + 4 - Telex numbering plan (F.69) - + 6 - Land Mobile (E.212) - + 8 - National numbering plan - + 9 - Private numbering plan - + 10 - ERMES numbering plan (ETSI DE/PS 3 01-3) - + 13 - Internet (IP) - + 18 - WAP Client Id (to be defined by WAP Forum) - Default value is 0 - Unknown. - * Destination Type of Number (TON) - Specifies the format of - the number used to send messages to. Can have the same - values as Source Type of Number (TON) and default value is - 0 - Unknown. - * Destination Number Plan Indicator (NPI) - Specifies the - numbering scheme of the number used to send messages to. - Can have the same values as Source Number Plan Indicator - (NPI) and default value is 0 - Unknown. - * Session Type - Specifies what type of session should be - used to connecto th the SMSc. Possible values are: - + 1 - Transciever - + 2 - Transmitter - + 3 - Receiver - + 4 - Outbind - Default value is 1 - Transciever. - - When OpenSIPS starts up, it reads all SMSc specifications from - the database and triggers a binding with them. Note: reloading - the SMSc database is not yet supported, but it is a work in - progress. - - Each SMPP connection is periodically pinged (currently every 5 - seconds) using enquire_link SMPP commands to keep the - connection active. - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * database -- Any database module - -1.5.2. Dependencies of external libraries - - * None. - -1.6. OpenSIPS Exported parameters - - All these parameters can be used from the opensips.cfg file, to - configure the behavior of OpenSIPS-SMPP gateway. - -1.6.1. db_url (string) - - The database handler where the SMPP connection will be stored. - This parameter is mandatory. - - Default value is unset. - - Example 1.1. Set db_url parameter -... -modparam("proto_smpp", "db_url", "dbdriver://username:password@dbhost/db -name") -... - -1.6.2. smpp_port (integer) - - Used to change the default value of the SMPP port used to - listen for new connections. - - Default value is 2775. - - Example 1.2. Set smpp_port variable -... -modparam("proto_smpp", "smpp_port", 27775) -... - -1.6.3. smpp_max_msg_chunks (integer) - - The maximum number of chunks in which a SMPP message is - expected to arrive via TCP. If a received packet is more - fragmented than this, the connection is dropped (either the - connection is very overloaded and this leads to high - fragmentation - or we are the victim of an ongoing attack where - the attacker is sending very fragmented traffic in order to - decrease server performance). - - Default value is 8. - - Example 1.3. Set smpp_max_msg_chunks parameter -... -modparam("proto_smpp", "smpp_max_msg_chunks", 32) -... - -1.6.4. smpp_send_timeout (integer) - - Time in milliseconds after a TCP connection will be closed if - it is not available for blocking writing in this interval (and - OpenSIPS wants to send something on it). - - Default value is 100 ms. - - Example 1.4. Set smpp_send_timeout parameter -... -modparam("proto_smpp", "smpp_send_timeout", 200) -... - -1.6.5. outbound_uri (string) - - This parameter represents the URI of the outbound proxy used to - send a message converted from SMPP to SIP. - - Default value is None. - - Example 1.5. Set outbound_uri parameter -... -modparam("proto_smpp", "outbound_uri", "sip:127.0.0.1:5060") -... - -1.6.6. smpp_table (string) - - The name of the database table containing definitions of the - SMSc servers used to connect to. - - Default value is “smpp”. - - Example 1.6. Set smpp_table parameter -... -modparam("proto_smpp", "smpp_table", "smsc") -... - - -1.6.7. name_col (string) - - The name of the column that holds the SMSc identifier used by - the send_smpp_message() function. - - Default value is “name”. - - Example 1.7. Set name_col parameter -... -modparam("proto_smpp", "name_col", "smsc_name") -... - - -1.6.8. ip_col (string) - - The name of the column that holds the IP of the SMSc. - - Default value is “ip”. - - Example 1.8. Set ip_col parameter -... -modparam("proto_smpp", "ip_col", "smsc_ip") -... - - -1.6.9. port_col (string) - - The name of the column that holds the SMSc port. - - Default value is “port”. - - Example 1.9. Set port_col parameter -... -modparam("proto_smpp", "port_col", "smsc_port") -... - - -1.6.10. system_id_col (string) - - The name of the column that holds the SMSc System ID. - - Default value is “system_id”. - - Example 1.10. Set system_id_col parameter -... -modparam("proto_smpp", "system_id_col", "smsc_system_id") -... - - -1.6.11. password_col (string) - - The name of the password column used to authenticate the SMSc. - - Default value is “password”. - - Example 1.11. Set password_col parameter -... -modparam("proto_smpp", "password_col", "smsc_password") -... - - -1.6.12. system_type_col (string) - - The name of the System Type column used to bind the SMSc. - - Default value is “system_type”. - - Example 1.12. Set system_type_col parameter -... -modparam("proto_smpp", "system_type_col", "smsc_system_type") -... - - -1.6.13. src_ton_col (string) - - The name of the column that holds the Source TON values. - - Default value is “src_ton”. - - Example 1.13. Set src_ton_col parameter -... -modparam("proto_smpp", "src_ton_col", "smsc_src_ton") -... - - -1.6.14. src_npi_col (string) - - The name of the column that holds the Source NPI values. - - Default value is “src_npi”. - - Example 1.14. Set src_npi_col parameter -... -modparam("proto_smpp", "src_npi_col", "smsc_src_npi") -... - - -1.6.15. dst_ton_col (string) - - The name of the column that holds the Destination TON values. - - Default value is “dst_ton”. - - Example 1.15. Set dst_ton_col parameter -... -modparam("proto_smpp", "dst_ton_col", "smsc_dst_ton") -... - - -1.6.16. dst_npi_col (string) - - The name of the column that holds the Destination NPI values. - - Default value is “dst_npi”. - - Example 1.16. Set dst_npi_col parameter -... -modparam("proto_smpp", "dst_npi_col", "smsc_dst_npi") -... - - -1.6.17. session_type_col (string) - - The name of the column that holds the Session Type of the SMSc. - - Default value is “session_type”. - - Example 1.17. Set session_type_col parameter -... -modparam("proto_smpp", "session_type_col", "smsc_session_type") -... - - -1.7. Exported Functions - -1.7.1. send_smpp_message(smsc_name, -[from],[to],[body],[utf-16],[delivery_receipt]) - - This function is used to convert a SIP message received in the - OpenSIPS script to a SMPP PDU and send it to the smsc_name - (string) received as parameter. The SMPP parameters used to - construct the PDU are provisione in the database, and the - command sent is either submit_sm or deliver_sm, depending on - the type of the SMSc. - - The function returns -2 if the SMSc the message should be sent - does not exist in the database, -1 if there was an internal - error, or positive value in case of success. - - Meaning of the parameters is as follows: - * sms_name (string) - name of the SMS to be used for sending - the SMPP traffic. - * from (string, optional) - the source number. If missing, - the SIP message from username is used. - * to (string, optional) - the destination number. If missing, - the SIP request URI username is used. - * body (string, optional) - the body of the SMS. If missing, - the SIP message body is used. - * UTF-16 (int, optional) - set to 1 if the body of the - message is in UTF-16. format. If missing or 0, UTF-8 is - used. - * delivery_receipt (int, optional) - Whether the SMSC should - confirm delivery for this SMS or not - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE or - BRANCH_ROUTE. - - Example 1.18. send_smpp_message() usage -... - if (is_method("MESSAGE")) - send_smpp_message("MY_SMSC"); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Victor Ciurel (@victor-ciurel) 81 21 3760 1658 - 2. Razvan Crainea (@razvancrainea) 73 41 2048 800 - 3. Liviu Chircu (@liviuchircu) 9 7 49 37 - 4. Vlad Paiu (@vladpaiu) 8 5 234 37 - 5. Maksym Sobolyev (@sobomax) 6 4 12 13 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 7 3 - 7. Vlad Patrascu (@rvlad-patrascu) 4 2 10 13 - 8. Zero King (@l2dy) 3 1 4 2 - 9. Nick Altmann (@nikbyte) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jan 2019 - Jul 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Liviu Chircu (@liviuchircu) May 2020 - Apr 2022 - 4. Nick Altmann (@nikbyte) May 2021 - May 2021 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2021 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Vlad Paiu (@vladpaiu) May 2019 - Sep 2019 - 8. Vlad Patrascu (@rvlad-patrascu) Apr 2019 - Apr 2019 - 9. Victor Ciurel (@victor-ciurel) Sep 2017 - Jan 2019 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Vlad Paiu - (@vladpaiu), Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: diff --git a/modules/proto_smpp/README.md b/modules/proto_smpp/README.md new file mode 100644 index 00000000000..69d328c6a3a --- /dev/null +++ b/modules/proto_smpp/README.md @@ -0,0 +1,494 @@ +--- +title: "proto_smpp module" +description: "This module offers interoperability between SIP and SMPP (Short Message Peer-to-Peer) protocols." +--- + +## Admin Guide + + +### Overview + + +This module offers interoperability between SIP and SMPP +(Short Message Peer-to-Peer) protocols. It provides the +means to build a messaging gateway/bridge between the two +protocols, being able to convert messages from both directions. + + +- SIP to SMPP - messages coming from SIP can be converted to a +SMPP PDU (Protocol Data Unit) message and sent further to a +SMSC (Short Message Service Center). +- SMPP to SIP - the module can act as an ESME (External Short +Messaging Entity), receiving messages from a SMSC and converting +them to a SIP Message that is sent further to a SIP proxy. + + +The module is compatible with the +[SMPP v3.4](http://opensmpp.org/specs/SMPP_v3_4_Issue1_2.pdf) specifications. + + +### SIP to SMPP bridging + + +In order to convert a SIP message to a SMPP all you need to do +is to call the [send smpp message](#func_send_smpp_message) function, +indicating the SMSc you want to send the message to. The module +will build the PDU according to the parameters provisioned +in the database. + + +### SMPP to SIP bridging + + +When bridging a message received over the SMPP interface, +OpenSIPS builds a SIP Message and sends it to the outbound +proxy identified by the [smpp outbound uri](#param_outbound_uri) +module's parameter. + + +### SMSC binding + + +In order to be able to deliver messages to SMSc, an ESME needs to +first bind to the SMSc. This is done at OpenSIPS startup by sending +a SMPP *bind_transciever* command to connect +to the SMSc, or an *outbind* command to inform +an SMSc it can now bind to our gateway. + + +The description of all SMSc servers is provisioned in the database. +For each server, one can cofigure the following information: + + +- *Name* - an unique name given to +the SMSc that is used to reference this SMSc in the OpenSIPS script. +- *IP* - The IP the SMSc is listening +on for new bindings/connections. +- *Port* - The TCP port that the SMSc +is listening on for new bindings/connections. +- *System ID* - Also known as the +User name that is used to authenticate to the SMSc. +- *Password* - A password used to +authenticate to the SMSc. +- *System Type* - Usually +"SMPP", this field is required by some SMPP providers. +- *Source Type of Number (TON)* - Specifies +the format of the number used to send messages from. Some comon values are: + + *0* - Unknown + *1* - International + *2* - National + *3* - Network Specific + *4* - Subscriber Number + *5* - Alphanumeric + *6* - Abbreviated + + Default value is *0 - Unknown*. +- *Source Number Plan Indicator (NPI)* - Specifies +the numbering scheme of the number used to send messages from. Some comon values are: + + - *0* - Unknown + - *1* - ISDN/telephone numbering plan (E163/E164) + - *3* - Data numbering plan (X.121) + - *4* - Telex numbering plan (F.69) + - *6* - Land Mobile (E.212) + - *8* - National numbering plan + - *9* - Private numbering plan + - *10* - ERMES numbering plan (ETSI DE/PS 3 01-3) + - *13* - Internet (IP) + - *18* - WAP Client Id (to be defined by WAP Forum) + + *Default value is *0 - Unknown*.* +- *Destination Type of Number (TON)* - Specifies +the format of the number used to send messages to. Can have the same values as +*Source Type of Number (TON)* and default value is *0 - +Unknown*. +- *Destination Number Plan Indicator (NPI)* - +Specifies the numbering scheme of the number used to send messages to. Can have +the same values as *Source Number Plan Indicator (NPI)* +and *default value is *0 - Unknown**. +- *Session Type* - Specifies what type of session +should be used to connecto th the SMSc. Possible values are: + - *1* - Transciever + - *2* - Transmitter + - *3* - Receiver + - *4* - Outbind + + *Default value is *1 - Transciever**. + + +When OpenSIPS starts up, it reads all SMSc specifications from the +database and triggers a binding with them. *Note:* +reloading the SMSc database is not yet supported, but it is a work in +progress. + + +Each SMPP connection is periodically pinged (currently every 5 seconds) +using *enquire_link* SMPP commands to keep the +connection active. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *database* -- Any database module + + +#### Dependencies of external libraries + + +- *None*. + + +### Exported Parameters + + +All these parameters can be used from the opensips.cfg file, +to configure the behavior of OpenSIPS-SMPP gateway. + + +#### db_url (string) + + +The database handler where the SMPP connection will be +stored. This parameter is mandatory. + + +*Default value is *unset*.* + + +```opensips title="Set db_url parameter" +... +modparam("proto_smpp", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### smpp_port (integer) + + +Used to change the default value of the SMPP port used to +listen for new connections. + + +*Default value is 2775.* + + +```opensips title="Set smpp_port variable" +... +modparam("proto_smpp", "smpp_port", 27775) +... + +``` + + +#### smpp_max_msg_chunks (integer) + + +The maximum number of chunks in which a SMPP message is expected to +arrive via TCP. If a received packet is more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending very +fragmented traffic in order to decrease server performance). + + +*Default value is 8.* + + +```opensips title="Set smpp_max_msg_chunks parameter" +... +modparam("proto_smpp", "smpp_max_msg_chunks", 32) +... +``` + + +#### smpp_send_timeout (integer) + + +Time in milliseconds after a TCP connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set smpp_send_timeout parameter" +... +modparam("proto_smpp", "smpp_send_timeout", 200) +... +``` + + +#### outbound_uri (string) + + +This parameter represents the URI of the outbound proxy used to send +a message converted from SMPP to SIP. + + +*Default value is *None*.* + + +```opensips title="Set outbound_uri parameter" +... +modparam("proto_smpp", "outbound_uri", "sip:127.0.0.1:5060") +... +``` + + +#### smpp_table (string) + + +The name of the database table containing definitions +of the SMSc servers used to connect to. + + +*Default value is "smpp".* + + +```opensips title="Set smpp_table parameter" +... +modparam("proto_smpp", "smpp_table", "smsc") +... +``` + + +#### name_col (string) + + +The name of the column that holds the SMSc identifier used by +the *send_smpp_message()* function. + + +*Default value is "name".* + + +```opensips title="Set name_col parameter" +... +modparam("proto_smpp", "name_col", "smsc_name") +... +``` + + +#### ip_col (string) + + +The name of the column that holds the IP of the SMSc. + + +*Default value is "ip".* + + +```opensips title="Set ip_col parameter" +... +modparam("proto_smpp", "ip_col", "smsc_ip") +... +``` + + +#### port_col (string) + + +The name of the column that holds the SMSc port. + + +*Default value is "port".* + + +```opensips title="Set port_col parameter" +... +modparam("proto_smpp", "port_col", "smsc_port") +... +``` + + +#### system_id_col (string) + + +The name of the column that holds the SMSc System ID. + + +*Default value is "system_id".* + + +```opensips title="Set system_id_col parameter" +... +modparam("proto_smpp", "system_id_col", "smsc_system_id") +... +``` + + +#### password_col (string) + + +The name of the password column used to authenticate the SMSc. + + +*Default value is "password".* + + +```opensips title="Set password_col parameter" +... +modparam("proto_smpp", "password_col", "smsc_password") +... +``` + + +#### system_type_col (string) + + +The name of the System Type column used to bind the SMSc. + + +*Default value is "system_type".* + + +```opensips title="Set system_type_col parameter" +... +modparam("proto_smpp", "system_type_col", "smsc_system_type") +... +``` + + +#### src_ton_col (string) + + +The name of the column that holds the Source TON values. + + +*Default value is "src_ton".* + + +```opensips title="Set src_ton_col parameter" +... +modparam("proto_smpp", "src_ton_col", "smsc_src_ton") +... +``` + + +#### src_npi_col (string) + + +The name of the column that holds the Source NPI values. + + +*Default value is "src_npi".* + + +```opensips title="Set src_npi_col parameter" +... +modparam("proto_smpp", "src_npi_col", "smsc_src_npi") +... +``` + + +#### dst_ton_col (string) + + +The name of the column that holds the Destination TON values. + + +*Default value is "dst_ton".* + + +```opensips title="Set dst_ton_col parameter" +... +modparam("proto_smpp", "dst_ton_col", "smsc_dst_ton") +... +``` + + +#### dst_npi_col (string) + + +The name of the column that holds the Destination NPI values. + + +*Default value is "dst_npi".* + + +```opensips title="Set dst_npi_col parameter" +... +modparam("proto_smpp", "dst_npi_col", "smsc_dst_npi") +... +``` + + +#### session_type_col (string) + + +The name of the column that holds the Session Type of the SMSc. + + +*Default value is "session_type".* + + +```opensips title="Set session_type_col parameter" +... +modparam("proto_smpp", "session_type_col", "smsc_session_type") +... +``` + + +### Exported Functions + + +#### send_smpp_message(smsc_name, [from],[to],[body],[utf-16],[delivery_receipt]) + + +This function is used to convert a SIP message received in the +OpenSIPS script to a SMPP PDU and send it to the +*smsc_name (string)* received as parameter. +The SMPP parameters used to construct the PDU are provisione +in the database, and the command sent is either +*submit_sm* or *deliver_sm*, +depending on the type of the SMSc. + + +The function returns *-2* if the SMSc +the message should be sent does not exist in the database, +*-1* if there was an internal error, +or positive value in case of success. + + +Meaning of the parameters is as follows: + + +- *sms_name (string)* - name of the SMS +to be used for sending the SMPP traffic. +- *from (string, optional)* - the source number. +If missing, the SIP message from username is used. +- *to (string, optional)* - the destination number. +If missing, the SIP request URI username is used. +- *body (string, optional)* - the body of the SMS. +If missing, the SIP message body is used. +- *UTF-16 (int, optional)* - set to +*1* if the body of the message is in UTF-16. +format. If missing or *0*, UTF-8 is used. +- *delivery_receipt (int, optional)* - Whether +the SMSC should confirm delivery for this SMS or not + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE +or BRANCH_ROUTE. + + +```opensips title="send_smpp_message() usage" +... +if (is_method("MESSAGE")) + send_smpp_message("MY_SMSC"); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_smpp/doc/contributors.xml b/modules/proto_smpp/doc/contributors.xml deleted file mode 100644 index aa522006d9a..00000000000 --- a/modules/proto_smpp/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Victor Ciurel (@victor-ciurel) - 81 - 21 - 3760 - 1658 - - - 2. - Razvan Crainea (@razvancrainea) - 73 - 41 - 2048 - 800 - - - 3. - Liviu Chircu (@liviuchircu) - 9 - 7 - 49 - 37 - - - 4. - Vlad Paiu (@vladpaiu) - 8 - 5 - 234 - 37 - - - 5. - Maksym Sobolyev (@sobomax) - 6 - 4 - 12 - 13 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 7 - 3 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 10 - 13 - - - 8. - Zero King (@l2dy) - 3 - 1 - 4 - 2 - - - 9. - Nick Altmann (@nikbyte) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jan 2019 - Jul 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Liviu Chircu (@liviuchircu) - May 2020 - Apr 2022 - - - 4. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2021 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Vlad Paiu (@vladpaiu) - May 2019 - Sep 2019 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - Apr 2019 - Apr 2019 - - - 9. - Victor Ciurel (@victor-ciurel) - Sep 2017 - Jan 2019 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Vlad Paiu (@vladpaiu), Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/proto_smpp/doc/proto_smpp.xml b/modules/proto_smpp/doc/proto_smpp.xml deleted file mode 100644 index c24393f1978..00000000000 --- a/modules/proto_smpp/doc/proto_smpp.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_smpp module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - diff --git a/modules/proto_smpp/doc/proto_smpp_admin.xml b/modules/proto_smpp/doc/proto_smpp_admin.xml deleted file mode 100644 index 3e405afda6a..00000000000 --- a/modules/proto_smpp/doc/proto_smpp_admin.xml +++ /dev/null @@ -1,637 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module offers interoperability between SIP and SMPP - (Short Message Peer-to-Peer) protocols. It provides the - means to build a messaging gateway/bridge between the two - protocols, being able to convert messages from both directions. - - - - - - SIP to SMPP - messages coming from SIP can be converted to a - SMPP PDU (Protocol Data Unit) message and sent further to a - SMSC (Short Message Service Center). - - - SMPP to SIP - the module can act as an ESME (External Short - Messaging Entity), receiving messages from a SMSC and converting - them to a SIP Message that is sent further to a SIP proxy. - - - - - The module is compatible with the - - SMPP v3.4 specifications. - -
- -
- SIP to SMPP bridging - - In order to convert a SIP message to a SMPP all you need to do - is to call the function, - indicating the SMSc you want to send the message to. The module - will build the PDU according to the parameters provisioned - in the database. - -
- -
- SMPP to SIP bridging - - When bridging a message received over the SMPP interface, - OpenSIPS builds a SIP Message and sends it to the outbound - proxy identified by the - module's parameter. - -
- -
- SMSC binding - - In order to be able to deliver messages to SMSc, an ESME needs to - first bind to the SMSc. This is done at &osips; startup by sending - a SMPP bind_transciever command to connect - to the SMSc, or an outbind command to inform - an SMSc it can now bind to our gateway. - - - The description of all SMSc servers is provisioned in the database. - For each server, one can cofigure the following information: - - Name - an unique name given to - the SMSc that is used to reference this SMSc in the &osips; script. - - IP - The IP the SMSc is listening - on for new bindings/connections. - - Port - The TCP port that the SMSc - is listening on for new bindings/connections. - - System ID - Also known as the - User name that is used to authenticate to the SMSc. - - Password - A password used to - authenticate to the SMSc. - - System Type - Usually - SMPP, this field is required by some SMPP providers. - - Source Type of Number (TON) - Specifies - the format of the number used to send messages from. Some comon values are: - - 0 - Unknown - 1 - International - 2 - National - 3 - Network Specific - 4 - Subscriber Number - 5 - Alphanumeric - 6 - Abbreviated - - Default value is 0 - Unknown. - - Source Number Plan Indicator (NPI) - Specifies - the numbering scheme of the number used to send messages from. Some comon values are: - - 0 - Unknown - 1 - ISDN/telephone numbering plan (E163/E164) - 3 - Data numbering plan (X.121) - 4 - Telex numbering plan (F.69) - 6 - Land Mobile (E.212) - 8 - National numbering plan - 9 - Private numbering plan - 10 - ERMES numbering plan (ETSI DE/PS 3 01-3) - 13 - Internet (IP) - 18 - WAP Client Id (to be defined by WAP Forum) - - Default value is 0 - Unknown. - - Destination Type of Number (TON) - Specifies - the format of the number used to send messages to. Can have the same values as - Source Type of Number (TON) and default value is 0 - - Unknown. - - Destination Number Plan Indicator (NPI) - - Specifies the numbering scheme of the number used to send messages to. Can have - the same values as Source Number Plan Indicator (NPI) - and default value is 0 - Unknown. - - Session Type - Specifies what type of session - should be used to connecto th the SMSc. Possible values are: - - 1 - Transciever - 2 - Transmitter - 3 - Receiver - 4 - Outbind - - Default value is 1 - Transciever. - - - - - When &osips; starts up, it reads all SMSc specifications from the - database and triggers a binding with them. Note: - reloading the SMSc database is not yet supported, but it is a work in - progress. - - - Each SMPP connection is periodically pinged (currently every 5 seconds) - using enquire_link SMPP commands to keep the - connection active. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - database -- Any database module - - - - -
-
- Dependencies of external libraries - - - - - None. - - - - -
-
- -
- &osips; Exported parameters - - All these parameters can be used from the opensips.cfg file, - to configure the behavior of &osips;-SMPP gateway. - - -
- <varname>db_url</varname> (string) - - The database handler where the SMPP connection will be - stored. This parameter is mandatory. - - - - Default value is unset. - - - - Set <varname>db_url</varname> parameter - -... -modparam("proto_smpp", "db_url", "&exampledb;") -... - - -
- -
- <varname>smpp_port</varname> (integer) - - Used to change the default value of the SMPP port used to - listen for new connections. - - - Default value is 2775. - - - Set <varname>smpp_port</varname> variable - -... -modparam("proto_smpp", "smpp_port", 27775) -... - - -
- -
- <varname>smpp_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a SMPP message is expected to - arrive via TCP. If a received packet is more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - - - Default value is 8. - - - - Set <varname>smpp_max_msg_chunks</varname> parameter - -... -modparam("proto_smpp", "smpp_max_msg_chunks", 32) -... - - -
- -
- <varname>smpp_send_timeout</varname> (integer) - - Time in milliseconds after a TCP connection will be closed if it is - not available for blocking writing in this interval (and &osips; wants - to send something on it). - - - - Default value is 100 ms. - - - - Set <varname>smpp_send_timeout</varname> parameter - -... -modparam("proto_smpp", "smpp_send_timeout", 200) -... - - -
- -
- <varname>outbound_uri</varname> (string) - - This parameter represents the URI of the outbound proxy used to send - a message converted from SMPP to SIP. - - - - Default value is None. - - - - Set <varname>outbound_uri</varname> parameter - -... -modparam("proto_smpp", "outbound_uri", "sip:127.0.0.1:5060") -... - - -
- -
- <varname>smpp_table</varname> (string) - - The name of the database table containing definitions - of the SMSc servers used to connect to. - - - - Default value is smpp. - - - - - Set <varname>smpp_table</varname> parameter - -... -modparam("proto_smpp", "smpp_table", "smsc") -... - - - -
- -
- <varname>name_col</varname> (string) - - The name of the column that holds the SMSc identifier used by - the send_smpp_message() function. - - - - Default value is name. - - - - - Set <varname>name_col</varname> parameter - -... -modparam("proto_smpp", "name_col", "smsc_name") -... - - - -
- -
- <varname>ip_col</varname> (string) - - The name of the column that holds the IP of the SMSc. - - - - Default value is ip. - - - - - Set <varname>ip_col</varname> parameter - -... -modparam("proto_smpp", "ip_col", "smsc_ip") -... - - - -
- -
- <varname>port_col</varname> (string) - - The name of the column that holds the SMSc port. - - - - Default value is port. - - - - - Set <varname>port_col</varname> parameter - -... -modparam("proto_smpp", "port_col", "smsc_port") -... - - - -
- -
- <varname>system_id_col</varname> (string) - - The name of the column that holds the SMSc System ID. - - - - Default value is system_id. - - - - - Set <varname>system_id_col</varname> parameter - -... -modparam("proto_smpp", "system_id_col", "smsc_system_id") -... - - - -
- -
- <varname>password_col</varname> (string) - - The name of the password column used to authenticate the SMSc. - - - - Default value is password. - - - - - Set <varname>password_col</varname> parameter - -... -modparam("proto_smpp", "password_col", "smsc_password") -... - - - -
- -
- <varname>system_type_col</varname> (string) - - The name of the System Type column used to bind the SMSc. - - - - Default value is system_type. - - - - - Set <varname>system_type_col</varname> parameter - -... -modparam("proto_smpp", "system_type_col", "smsc_system_type") -... - - - -
- -
- <varname>src_ton_col</varname> (string) - - The name of the column that holds the Source TON values. - - - - Default value is src_ton. - - - - - Set <varname>src_ton_col</varname> parameter - -... -modparam("proto_smpp", "src_ton_col", "smsc_src_ton") -... - - - -
- -
- <varname>src_npi_col</varname> (string) - - The name of the column that holds the Source NPI values. - - - - Default value is src_npi. - - - - - Set <varname>src_npi_col</varname> parameter - -... -modparam("proto_smpp", "src_npi_col", "smsc_src_npi") -... - - - -
- -
- <varname>dst_ton_col</varname> (string) - - The name of the column that holds the Destination TON values. - - - - Default value is dst_ton. - - - - - Set <varname>dst_ton_col</varname> parameter - -... -modparam("proto_smpp", "dst_ton_col", "smsc_dst_ton") -... - - - -
- -
- <varname>dst_npi_col</varname> (string) - - The name of the column that holds the Destination NPI values. - - - - Default value is dst_npi. - - - - - Set <varname>dst_npi_col</varname> parameter - -... -modparam("proto_smpp", "dst_npi_col", "smsc_dst_npi") -... - - - -
- -
- <varname>session_type_col</varname> (string) - - The name of the column that holds the Session Type of the SMSc. - - - - Default value is session_type. - - - - - Set <varname>session_type_col</varname> parameter - -... -modparam("proto_smpp", "session_type_col", "smsc_session_type") -... - - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">send_smpp_message(smsc_name, [from],[to],[body],[utf-16],[delivery_receipt])</function> - - - This function is used to convert a SIP message received in the - &osips; script to a SMPP PDU and send it to the - smsc_name (string) received as parameter. - The SMPP parameters used to construct the PDU are provisione - in the database, and the command sent is either - submit_sm or deliver_sm, - depending on the type of the SMSc. - - - The function returns -2 if the SMSc - the message should be sent does not exist in the database, - -1 if there was an internal error, - or positive value in case of success. - - Meaning of the parameters is as follows: - - - sms_name (string) - name of the SMS - to be used for sending the SMPP traffic. - - - - from (string, optional) - the source number. - If missing, the SIP message from username is used. - - - - to (string, optional) - the destination number. - If missing, the SIP request URI username is used. - - - - body (string, optional) - the body of the SMS. - If missing, the SIP message body is used. - - - - UTF-16 (int, optional) - set to - 1 if the body of the message is in UTF-16. - format. If missing or 0, UTF-8 is used. - - - - delivery_receipt (int, optional) - Whether - the SMSC should confirm delivery for this SMS or not - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE - or BRANCH_ROUTE. - - - <function>send_smpp_message()</function> usage - -... - if (is_method("MESSAGE")) - send_smpp_message("MY_SMSC"); -... - - -
-
- -
diff --git a/modules/proto_smpp/proto_smpp.c b/modules/proto_smpp/proto_smpp.c index b39b2ca75fc..639a5fa95b6 100644 --- a/modules/proto_smpp/proto_smpp.c +++ b/modules/proto_smpp/proto_smpp.c @@ -348,6 +348,11 @@ static inline void smpp_parse_headers(struct tcp_req *req) } req->content_len = ntohl(*px); + if (req->content_len < HEADER_SZ) { + LM_ERR("invalid SMPP packet length %u\n", req->content_len); + req->error = TCP_REQ_BAD_LEN; + return; + } if (req->pos - req->buf == req->content_len) { LM_DBG("received a complete message\n"); req->complete = 1; diff --git a/modules/proto_smpp/smpp.c b/modules/proto_smpp/smpp.c index 43185650592..8236976dd8f 100644 --- a/modules/proto_smpp/smpp.c +++ b/modules/proto_smpp/smpp.c @@ -372,30 +372,40 @@ static int convert_utf16_to_ucs2(str *input, char *output) return input->len / 2; } -static int convert_utf8_to_gsm7(str *input, char *output) +static int convert_utf8_to_gsm7(str *input, char *output, int output_len) { +#define CHECK_OUT(_n) \ + do { \ + if (end - o < (_n)) \ + return -1; \ + } while (0) +#define PUSH_OUT(_v) \ + do { \ + CHECK_OUT(1); \ + *o++ = (_v); \ + } while (0) #define CASE_OUT_REPR(_c, _v) \ - case (_c): *o++ = (_v); break; + case (_c): PUSH_OUT(_v); break; #define CASE_OUT_REPR_EN(_c, _v) \ - case (_c): *o++ = 0x1B; *o++ = (_v); break; + case (_c): CHECK_OUT(2); *o++ = 0x1B; *o++ = (_v); break; int i; - unsigned char c, c1, c2, *o; + unsigned char c, c1, c2, *o, *end; unsigned int t; o = (unsigned char *)output; - /* GSM7 is definitely smaller than UTF8 */ + end = o + output_len; for (i = 0; i < input->len; i++) { c = input->s[i]; if ((c & 0xF8) == 0xF0) { /* four bytes - no representation in GSM */ - *o++ = '?'; + PUSH_OUT('?'); i += 3; /* skip a total of 4 bytes */ continue; } if ((c & 0xF0) == 0xE0) { /* three bytes */ if (i + 2 >= input->len) { - *o++ = '?'; + PUSH_OUT('?'); i += 2; /* terminate */ continue; } @@ -404,17 +414,18 @@ static int convert_utf8_to_gsm7(str *input, char *output) t = ((c & 0x0F) << 12) | ((c1 & 0x3F) << 6) | (c2 & 0x3F); /* we only support the euro sign */ if (t == 0x20AC) { + CHECK_OUT(2); *o++ = 0x1B; *o++ = 0x65; } else { - *o++ = '?'; + PUSH_OUT('?'); } continue; } if ((c & 0xE0) == 0xC0) { /* two bytes */ if (i + 1 >= input->len) { - *o++ = '?'; + PUSH_OUT('?'); i++; /* terminate */ continue; } @@ -426,7 +437,7 @@ static int convert_utf8_to_gsm7(str *input, char *output) if ((t >= 0x20 /* ' ' */ && t <= 0x5A /* 'Z' */ && t != 0x24 && t != 0x40) || (t >= 0x61 /* 'z' */ && t <= 0x7A /* 'z' */)) { - *o++ = t; + PUSH_OUT(t); } else { /* handle exceptions */ switch (t) { @@ -490,7 +501,7 @@ static int convert_utf8_to_gsm7(str *input, char *output) CASE_OUT_REPR(0x39E, 0x1A); default: /* unknown representation */ - *o++ = '?'; + PUSH_OUT('?'); break; } } @@ -498,6 +509,22 @@ static int convert_utf8_to_gsm7(str *input, char *output) return (char *)o - output; #undef CASE_OUT_REPR #undef CASE_OUT_REPR_EN +#undef PUSH_OUT +#undef CHECK_OUT +} + +static int smpp_set_addr(char *addr, int addr_size, str *value, const char *name) +{ + if (value->len >= addr_size) { + LM_ERR("%s too long: %d (max %d)\n", + name, value->len, addr_size - 1); + return -1; + } + + memcpy(addr, value->s, value->len); + addr[value->len] = '\0'; + + return 0; } static int convert_gsm7_to_utf8(unsigned char *input, int input_len, char *output) @@ -598,6 +625,7 @@ static int build_submit_or_deliver_request(smpp_submit_sm_req_t **preq, int chunk_id, int total_chunks,uint8_t chunk_group_id) { char *start; + int sm_len; if (!preq || !src || !dst || !message) { LM_ERR("NULL params\n"); @@ -636,10 +664,14 @@ static int build_submit_or_deliver_request(smpp_submit_sm_req_t **preq, memset(body, 0, sizeof(*body)); body->source_addr_ton = session->source_addr_ton; body->source_addr_npi = session->source_addr_npi; - strncpy(body->source_addr, src->s, src->len); + if (smpp_set_addr(body->source_addr, MAX_ADDRESS_LEN, src, + "source address") < 0) + goto payload_err; body->dest_addr_ton = session->dest_addr_ton; body->dest_addr_npi = session->dest_addr_npi; - strncpy(body->destination_addr, dst->s, dst->len); + if (smpp_set_addr(body->destination_addr, MAX_ADDRESS_LEN, dst, + "destination address") < 0) + goto payload_err; if (total_chunks > 1) { body->esm_class = 0x40; @@ -665,12 +697,18 @@ static int build_submit_or_deliver_request(smpp_submit_sm_req_t **preq, if (message_type == SMPP_CODING_DEFAULT) { body->data_coding = SMPP_CODING_DEFAULT; - body->sm_length += convert_utf8_to_gsm7(message, start); + sm_len = convert_utf8_to_gsm7(message, start, + sizeof(body->short_message) - body->sm_length); } else { /* UTF-16 */ body->data_coding = SMPP_CODING_UCS2; - body->sm_length += convert_utf16_to_ucs2(message, start); + sm_len = convert_utf16_to_ucs2(message, start); + } + if (sm_len < 0) { + LM_ERR("message too long after encoding\n"); + goto payload_err; } + body->sm_length += sm_len; if (delivery_confirmation && *delivery_confirmation > 0) body->registered_delivery = 1; @@ -692,6 +730,8 @@ static int build_submit_or_deliver_request(smpp_submit_sm_req_t **preq, return 0; payload_err: + if (req->payload.s) + pkg_free(req->payload.s); pkg_free(body); body_err: pkg_free(header); @@ -952,89 +992,229 @@ static int smpp_parse_header(smpp_header_t *header, char *buffer) return 0; } -static void parse_submit_or_deliver_body(smpp_submit_sm_t *body, smpp_header_t *header, char *buffer) +static int smpp_body_end(smpp_header_t *header, char *buffer, char **end) +{ + if (header->command_length < HEADER_SZ) { + LM_ERR("invalid SMPP command length %u\n", header->command_length); + return -1; + } + + *end = buffer + header->command_length - HEADER_SZ; + return 0; +} + +static int smpp_read_u8(char **p, char *end, uint8_t *out, const char *name) +{ + if (*p + 1 > end) { + LM_ERR("truncated SMPP field %s\n", name); + return -1; + } + + *out = *(*p)++; + return 0; +} + +static int smpp_read_fixed(char **p, char *end, char *out, int len, + const char *name) +{ + if (*p + len > end) { + LM_ERR("truncated SMPP field %s\n", name); + return -1; + } + + memcpy(out, *p, len); + *p += len; + return 0; +} + +static int smpp_read_c_octet(char **p, char *end, char *out, int out_size, + const char *name) { + char *nul; + int len; + + if (*p >= end) { + LM_ERR("missing SMPP field %s\n", name); + return -1; + } + + nul = memchr(*p, '\0', end - *p); + if (!nul) { + LM_ERR("unterminated SMPP field %s\n", name); + return -1; + } + + len = nul - *p; + if (len >= out_size) { + LM_ERR("SMPP field %s too long: %d (max %d)\n", + name, len, out_size - 1); + return -1; + } + + memcpy(out, *p, len); + out[len] = '\0'; + *p = nul + 1; + return 0; +} + +static int parse_submit_or_deliver_body(smpp_submit_sm_t *body, + smpp_header_t *header, char *buffer) +{ + char *p, *end; + if (!body || !header || !buffer) { LM_ERR("NULL params\n"); - return; + return -1; + } + + if (smpp_body_end(header, buffer, &end) < 0) + return -1; + + p = buffer; + if (smpp_read_c_octet(&p, end, body->service_type, + MAX_SERVICE_TYPE_LEN, "service_type") < 0 || + smpp_read_u8(&p, end, &body->source_addr_ton, + "source_addr_ton") < 0 || + smpp_read_u8(&p, end, &body->source_addr_npi, + "source_addr_npi") < 0 || + smpp_read_c_octet(&p, end, body->source_addr, + MAX_ADDRESS_LEN, "source_addr") < 0 || + smpp_read_u8(&p, end, &body->dest_addr_ton, + "dest_addr_ton") < 0 || + smpp_read_u8(&p, end, &body->dest_addr_npi, + "dest_addr_npi") < 0 || + smpp_read_c_octet(&p, end, body->destination_addr, + MAX_ADDRESS_LEN, "destination_addr") < 0 || + smpp_read_u8(&p, end, &body->esm_class, + "esm_class") < 0 || + smpp_read_u8(&p, end, &body->protocol_id, + "protocol_id") < 0 || + smpp_read_u8(&p, end, &body->protocol_flag, + "protocol_flag") < 0 || + smpp_read_c_octet(&p, end, body->schedule_delivery_time, + MAX_SCHEDULE_DELIVERY_LEN, "schedule_delivery_time") < 0 || + smpp_read_c_octet(&p, end, body->validity_period, + MAX_VALIDITY_PERIOD, "validity_period") < 0 || + smpp_read_u8(&p, end, &body->registered_delivery, + "registered_delivery") < 0 || + smpp_read_u8(&p, end, &body->replace_if_present_flag, + "replace_if_present_flag") < 0 || + smpp_read_u8(&p, end, &body->data_coding, + "data_coding") < 0 || + smpp_read_u8(&p, end, &body->sm_default_msg_id, + "sm_default_msg_id") < 0 || + smpp_read_u8(&p, end, &body->sm_length, + "sm_length") < 0) + return -1; + + if (body->sm_length > MAX_SMS_CHARACTERS) { + LM_ERR("invalid short_message length %u (max %u)\n", + body->sm_length, MAX_SMS_CHARACTERS); + body->sm_length = 0; + return -1; + } + if (smpp_read_fixed(&p, end, body->short_message, + body->sm_length, "short_message") < 0) { + body->sm_length = 0; + return -1; } - char *p = buffer; - p += copy_var_str(body->service_type, p, MAX_SERVICE_TYPE_LEN); - body->source_addr_ton = *p++; - body->source_addr_npi = *p++; - p += copy_var_str(body->source_addr, p, MAX_ADDRESS_LEN); - body->dest_addr_ton = *p++; - body->dest_addr_npi = *p++; - p += copy_var_str(body->destination_addr, p, MAX_ADDRESS_LEN); - body->esm_class = *p++; - body->protocol_id = *p++; - body->protocol_flag = *p++; - p += copy_var_str(body->schedule_delivery_time, p, MAX_SCHEDULE_DELIVERY_LEN); - p += copy_var_str(body->validity_period, p, MAX_VALIDITY_PERIOD); - body->registered_delivery = *p++; - body->replace_if_present_flag = *p++; - body->data_coding = *p++; - body->sm_default_msg_id = *p++; - body->sm_length = *p++; - copy_fixed_str(body->short_message, p, body->sm_length); -} - -void parse_bind_receiver_body(smpp_bind_receiver_t *body, smpp_header_t *header, char *buffer) + return 0; +} + +int parse_bind_receiver_body(smpp_bind_receiver_t *body, + smpp_header_t *header, char *buffer) { + char *p, *end; + if (!body || !header || !buffer) { LM_ERR("NULL params\n"); - return; + return -1; } - char *p = buffer; - p += copy_var_str(body->system_id, p, MAX_SYSTEM_ID_LEN); - p += copy_var_str(body->password, p, MAX_PASSWORD_LEN); - p += copy_var_str(body->system_type, p, MAX_SYSTEM_TYPE_LEN); - body->interface_version = *p++; - body->addr_ton = *p++; - body->addr_npi = *p++; - p += copy_var_str(body->address_range, p, MAX_ADDRESS_RANGE_LEN); + if (smpp_body_end(header, buffer, &end) < 0) + return -1; + + p = buffer; + if (smpp_read_c_octet(&p, end, body->system_id, + MAX_SYSTEM_ID_LEN, "system_id") < 0 || + smpp_read_c_octet(&p, end, body->password, + MAX_PASSWORD_LEN, "password") < 0 || + smpp_read_c_octet(&p, end, body->system_type, + MAX_SYSTEM_TYPE_LEN, "system_type") < 0 || + smpp_read_u8(&p, end, &body->interface_version, + "interface_version") < 0 || + smpp_read_u8(&p, end, &body->addr_ton, "addr_ton") < 0 || + smpp_read_u8(&p, end, &body->addr_npi, "addr_npi") < 0 || + smpp_read_c_octet(&p, end, body->address_range, + MAX_ADDRESS_RANGE_LEN, "address_range") < 0) + return -1; + + return 0; } -void parse_bind_receiver_resp_body(smpp_bind_receiver_resp_t *body, smpp_header_t *header, char *buffer) +int parse_bind_receiver_resp_body(smpp_bind_receiver_resp_t *body, + smpp_header_t *header, char *buffer) { + char *p, *end; + if (!body || !header || !buffer) { LM_ERR("NULL params\n"); - return; + return -1; } - copy_var_str(body->system_id, buffer, MAX_SYSTEM_ID_LEN); + if (smpp_body_end(header, buffer, &end) < 0) + return -1; + + p = buffer; + return smpp_read_c_octet(&p, end, body->system_id, + MAX_SYSTEM_ID_LEN, "system_id"); } -void parse_bind_transmitter_body(smpp_bind_transmitter_t *body, smpp_header_t *header, char *buffer) +int parse_bind_transmitter_body(smpp_bind_transmitter_t *body, + smpp_header_t *header, char *buffer) { - parse_bind_receiver_body((smpp_bind_receiver_t*)body, header, buffer); + return parse_bind_receiver_body((smpp_bind_receiver_t*)body, + header, buffer); } -void parse_bind_transmitter_resp_body(smpp_bind_transmitter_resp_t *body, smpp_header_t *header, char *buffer) +int parse_bind_transmitter_resp_body(smpp_bind_transmitter_resp_t *body, + smpp_header_t *header, char *buffer) { - parse_bind_receiver_resp_body((smpp_bind_receiver_resp_t*)body, header, buffer); + return parse_bind_receiver_resp_body((smpp_bind_receiver_resp_t*)body, + header, buffer); } -void parse_bind_transceiver_body(smpp_bind_transceiver_t *body, smpp_header_t *header, char *buffer) +int parse_bind_transceiver_body(smpp_bind_transceiver_t *body, + smpp_header_t *header, char *buffer) { - parse_bind_receiver_body((smpp_bind_receiver_t*)body, header, buffer); + return parse_bind_receiver_body((smpp_bind_receiver_t*)body, + header, buffer); } -void parse_bind_transceiver_resp_body(smpp_bind_transceiver_resp_t *body, smpp_header_t *header, char *buffer) +int parse_bind_transceiver_resp_body(smpp_bind_transceiver_resp_t *body, + smpp_header_t *header, char *buffer) { - parse_bind_receiver_resp_body((smpp_bind_receiver_resp_t*)body, header, buffer); + return parse_bind_receiver_resp_body((smpp_bind_receiver_resp_t*)body, + header, buffer); } -void parse_submit_or_deliver_resp_body(smpp_submit_sm_resp_t *body, smpp_header_t *header, char *buffer) +int parse_submit_or_deliver_resp_body(smpp_submit_sm_resp_t *body, + smpp_header_t *header, char *buffer) { + char *p, *end; + if (!body || !header || !buffer) { LM_ERR("NULL params\n"); - return; + return -1; } - copy_var_str(body->message_id, buffer, MAX_MESSAGE_ID); + if (smpp_body_end(header, buffer, &end) < 0) + return -1; + + p = buffer; + return smpp_read_c_octet(&p, end, body->message_id, + MAX_MESSAGE_ID, "message_id"); } void send_submit_or_deliver_resp(smpp_submit_sm_req_t *req, smpp_session_t *session) @@ -1112,7 +1292,8 @@ void handle_bind_receiver_cmd(smpp_header_t *header, char *buffer, smpp_session_ smpp_bind_receiver_t body; memset(&body, 0, sizeof(body)); - parse_bind_receiver_body(&body, header, buffer); + if (parse_bind_receiver_body(&body, header, buffer) < 0) + return; uint32_t command_status = check_bind_session(&body, session); send_bind_resp(header, &body, command_status, session); } @@ -1136,7 +1317,8 @@ void handle_bind_transmitter_cmd(smpp_header_t *header, char *buffer, smpp_sessi smpp_bind_transmitter_t body; memset(&body, 0, sizeof(body)); - parse_bind_transmitter_body(&body, header, buffer); + if (parse_bind_transmitter_body(&body, header, buffer) < 0) + return; uint32_t command_status = check_bind_session(&body, session); send_bind_resp(header, &body, command_status, session); } @@ -1160,7 +1342,8 @@ void handle_submit_or_deliver_cmd(smpp_header_t *header, char *buffer, smpp_submit_sm_t body; memset(&body, 0, sizeof(body)); - parse_submit_or_deliver_body(&body, header, buffer); + if (parse_submit_or_deliver_body(&body, header, buffer) < 0) + return; LM_DBG("Received SMPP message\n" "FROM:\t%02x %02x %s\n" "TO:\t%02x %02x %s\nLEN:\t%d\n%.*s\n", @@ -1186,7 +1369,8 @@ void handle_submit_or_deliver_resp_cmd(smpp_header_t *header, char *buffer, smpp_submit_sm_resp_t body; memset(&body, 0, sizeof(body)); - parse_submit_or_deliver_resp_body(&body, header, buffer); + if (parse_submit_or_deliver_resp_body(&body, header, buffer) < 0) + return; LM_INFO("Successfully sent message \"%s\"\n", body.message_id); } @@ -1258,7 +1442,8 @@ static void handle_bind_transceiver_cmd(smpp_header_t *header, char *buffer, } smpp_bind_transceiver_t body; memset(&body, 0, sizeof(body)); - parse_bind_transceiver_body(&body, header, buffer); + if (parse_bind_transceiver_body(&body, header, buffer) < 0) + return; uint32_t command_status = check_bind_session(&body, session); send_bind_resp(header, &body, command_status, session); } @@ -1277,7 +1462,8 @@ static void handle_bind_transceiver_resp_cmd(smpp_header_t *header, } smpp_bind_transceiver_resp_t body; memset(&body, 0, sizeof(body)); - parse_bind_transceiver_resp_body(&body, header, buffer); + if (parse_bind_transceiver_resp_body(&body, header, buffer) < 0) + return; LM_INFO("Successfully bound transceiver \"%s\"\n", body.system_id); } @@ -1549,6 +1735,14 @@ static int recv_smpp_msg(smpp_header_t *header, smpp_deliver_sm_t *body, else init_str(&hdr, "Content-Type:text/plain\r\n"); + if (body->sm_length > MAX_SMS_CHARACTERS) { + LM_ERR("invalid short_message length %u (max %u)\n", + body->sm_length, MAX_SMS_CHARACTERS); + pkg_free(src.s); + pkg_free(dst.s); + return -1; + } + if (body->data_coding == SMPP_CODING_UCS2) { memset(sms_body,0,2*MAX_SMS_CHARACTERS); body_str.len = string2hex((char *)body->short_message, diff --git a/modules/proto_smpp/utils.c b/modules/proto_smpp/utils.c index 4e7c05c4705..677d8a981a7 100644 --- a/modules/proto_smpp/utils.c +++ b/modules/proto_smpp/utils.c @@ -38,9 +38,13 @@ int copy_var_str(char *to, char *from, int maxlen) { int iret = 1; - while (*from && maxlen--) { + if (maxlen <= 0) + return 0; + + while (maxlen > 1 && *from) { *to++ = *from++; iret++; + maxlen--; } *to++ = '\0'; @@ -63,4 +67,3 @@ int copy_u32(char *to, uint32_t from) return 4; } - diff --git a/modules/proto_tls/README b/modules/proto_tls/README deleted file mode 100644 index 1c9fc03244a..00000000000 --- a/modules/proto_tls/README +++ /dev/null @@ -1,657 +0,0 @@ -proto_tls module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. History - 1.3. Scenario - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. Dependencies of external libraries - - 1.5. OpenSIPS Exported parameters - - 1.5.1. listen=interface - 1.5.2. tls_port (integer) - 1.5.3. tls_crlf_pingpong (integer) - 1.5.4. tls_crlf_drop (integer) - 1.5.5. tls_max_msg_chunks (integer) - 1.5.6. cert_check_on_conn_reusage (integer) - 1.5.7. trace_destination (string) - 1.5.8. trace_on (int) - 1.5.9. trace_filter_route (string) - 1.5.10. tls_handshake_timeout (integer) - 1.5.11. tls_send_timeout (integer) - 1.5.12. tls_async (integer) - 1.5.13. tls_async_max_postponed_chunks (integer) - 1.5.14. tls_async_local_connect_timeout (integer) - 1.5.15. tls_async_handshake_timeout (integer) - - 1.6. Exported MI Functions - - 1.6.1. tls_trace - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set listen variable - 1.2. Set tls_port variable - 1.3. Set tls_crlf_pingpong parameter - 1.4. Set tls_crlf_drop parameter - 1.5. Set tls_max_msg_chunks parameter - 1.6. Set cert_check_on_conn_reusage parameter - 1.7. Set trace_destination parameter - 1.8. Set trace_on parameter - 1.9. Set trace_filter_route parameter - 1.10. Set tls_handshake_timeout variable - 1.11. Set tls_send_timeout variable - 1.12. Set tls_async variable - 1.13. Set tls_async_max_postponed_chunks parameter - 1.14. Set tls_async_local_connect_timeout parameter - 1.15. Set tls_async_handshake_timeout parameter - -Chapter 1. Admin Guide - -1.1. Overview - - TLS, as defined in SIP RFC 3261, is a mandatory feature for - proxies and can be used to secure the SIP signalling on a - hop-by-hop basis (not end-to-end). TLS works on top of TCP. - DTLS, or TLS over UDP is already defined by IETF and may become - available in the future. - -1.2. History - - The TLS support was originally developed by Peter Griffiths and - posted as a patch on SER development mailing list. Thanks to - Cesc Santasusana, several problems were fixed and some - improvements were added. - - The TLS support was simultaneously added in both projects. In - SER, the support was committed in a separate “experimental” CVS - tree, as patch to the main CVS tree. In OpenSIPS, the support - was integrated directly into the CVS tree, as a built-in - component, and is part of stable OpenSIPS since release - >=1.0.0. - - Starting with OpenSIPS 2.1, the TLS has been moved to a - separate transport module, that implements the more generic - Transport Interface. - -1.3. Scenario - - By the increased number of providers the SIP world is - continuously growing. More users means more calls and more - calls means a high probability for a user to receive calls from - totally unknown people or, in the worst case, to receive - unwanted calls. To prevent this, a defense mechanism must be - adopted by the SIP provider. Since only the called user is - fully able to classify a call as being unwanted, the SIP - server, based on all information regarding the call should - notify the user about the desirability of the call. Information - like the caller domain, the received source or the incoming - protocol can be very useful for a SIP server to establish the - nature of the call. - - As this information is quite limited, is very improbable for a - server to be able detect the unwanted calls - there are many - calls that it cannot predict anything about its status (neutral - calls). So, instead on alerting the called user about unwanted - calls, the server can notify the user about calls that are - considered trusted - calls for which the server is 100% sure - there are not unwanted. - - So, a trust concept must be defined for SIP servers. Which - calls are trusted and which are not? A call is trusted if the - caller can be identify as a trustable user - a user about we - have reliable information. - - Since all the user from its domain are authenticated (or should - be), a SIP server can consider all the calls generated by its - user as trusted. Now we have to extend the trust concept to the - multi-domain level. A mutual agreement, between several - domains, can establish a trusting relationship. So, a domain - (called A) will consider also as trusted calls all the calls - generated by user from a different domain (called B) and - vice-versa. But just an agreement is not enough; since the - authentication information is strictly limited to a domain (a - domain can authenticate only its own user, not the user from - other domains), there is still the problem of checking the - authenticity of the caller - he can impersonate (by a false - FROM header) a user from a domain that is trusted. - - The answer to this problem is TLS (Transport Layer Security). - All calls via domain A and domain B will be done via TLS. - Authentication in origin domain plus TLS transport between - domains will make the call 100% trusted for the target domain. - - For such a mechanism to work, the following requirements must - be met: - * all UA must have set as outbound proxy their home server. - * all SIP servers must authenticated all the calls generated - by their own users. - * all SIP servers must relay the calls generated be their - user to a trusted domain via TLS. - - Based on this, a server can classify as trusted a call for one - of its user only if the call is also generated by one of its - users or is the call is received from a trusted domain ( which - is equivalent with a call received via TLS). Untrusted call - will be calls received from users belonging to untrusted - domains or from users from trusted domains, but whose calls are - not routed via their home server (so, they are not - authenticated by there home servers). - - Once the server is able to tell if the call is trusted or not, - the still open issue is about the mechanism used by server to - notify the called user about the nature of the incoming call. - - One way to do it is by remotely changing the ringing type of - the called user's phone. This can be done by inserting special - header into the INVITE request. Such feature is supported by - now by several hardphones like CISCO ATA, CISCO 7960 and SNOM. - This phones can change their ringing tone based on the present - or content of the "Alert-Info" SIP header as follows: - * CISCO ATA - it has 4 pre-defined ringing types. The - Alert-Info header must look like “Alert-info: Bellcore-drX - EOH” where X can be between 1 and 4. Note that 1 is the - phone default ringing tone. - * CISCO 7960 - it has 2 pre-defined ringing types and the - possibility of uploading new ones. The “Alert-Info” header - must look like “Alert-info: X EOH” where X can be whatever - number. When this header is present, the phones will not - change the ringing tone, but the ringing pattern. Normally, - the phone rings like [ring.........ring..........ring] - where [ring] is the ringing tone; if the header is present, - the ringing pattern will be - [ring.ring.........ring.ring........]. So, to be able to - hear some difference between the two patterns (and not only - as length), its strongly recommended to have a highly - asymmetric ringing type (as the pre-defined are not!!). - * SNOM - The “Alert-Info” header must look like “Alert-info: - URL EOH"” where URL can be a HTTP URL (for example) from - where the phone can retrieve a ringing tone. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_openssl or tls_wolfssl, depending on the desired TLS - library - * tls_mgm. - -1.4.2. Dependencies of external libraries - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. OpenSIPS Exported parameters - - All these parameters can be used from the opensips.cfg file, to - configure the behavior of OpenSIPS-TLS. - -1.5.1. listen=interface - - Not specific to TLS. Allows to specify the protocol (udp, tcp, - tls), the IP address and the port where the listening server - will be. - - Example 1.1. Set listen variable -... -socket= tls:1.2.3.4:5061 -... - -1.5.2. tls_port (integer) - - The default port to be used for all TLS related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the TLS listeners) and the SIP - sending part (if the destination URI has no explicit port). - - If you want to change only the listening port for TLS, use the - port option in the SIP listener defintion. - - Default value is 5061. - - Example 1.2. Set tls_port variable -... -modparam("proto_tls", "tls_port", 5062) -... - -1.5.3. tls_crlf_pingpong (integer) - - Send CRLF pong (\r\n) to incoming CRLFCRLF ping messages over - TLS. By default it is enabled (1). - - Default value is 1 (enabled). - - Example 1.3. Set tls_crlf_pingpong parameter -... -modparam("proto_tls", "tls_crlf_pingpong", 0) -... - -1.5.4. tls_crlf_drop (integer) - - Drop CRLF (\r\n) ping messages. When this parameter is enabled, - the TLS layer drops packets that contains a single CRLF - message. If a CRLFCRLF message is received, it is handled - according to the tls_crlf_pingpong parameter. - - Default value is 0 (disabled). - - Example 1.4. Set tls_crlf_drop parameter -... -modparam("proto_tls", "tls_crlf_drop", 1) -... - -1.5.5. tls_max_msg_chunks (integer) - - The maximum number of chunks that a SIP message is expected to - arrive via TLS. If a packet is received more fragmented than - this, the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending the - traffic very fragmented in order to decrease server - performance). - - Default value is 4. - - Example 1.5. Set tls_max_msg_chunks parameter -... -modparam("proto_tls", "tls_max_msg_chunks", 8) -... - -1.5.6. cert_check_on_conn_reusage (integer) - - This parameter turns on or off the extra checking/matching of - the TLS domain (SSL certificate) when comes to reusing an - existing TLS connection. Without this extra check, only IP and - port of the connections will be check (in order to re-use an - existing connection). With this extra check, the connection to - be reused must have the same SSL certificate as the one set for - the current signaling operation. - - This checking is done only when comes to send SIP traffic via - TLS and it is applied only against connections that were - created / initiated by OpenSIPS (as TLS client). Any accepte - connection (as TLS server) will automatically match (the extra - test will be skipped). - - Default value is 0 (disabled). - - Example 1.6. Set cert_check_on_conn_reusage parameter -... -modparam("proto_tls", "cert_check_on_conn_reusage", 1) -... - -1.5.7. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. Network events such as - connect, accept and connection closed events shall be traced - along with errors that could appear in the process. For each - connection that is created an event containing information - about the client and server certificates, master key and - network layer information shall be sent. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.7. Set trace_destination parameter -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;versio -n=3") - -modparam("proto_tls", "trace_destination", "hep_dest") -... - -1.5.8. trace_on (int) - - This controls whether tracing for tls is on or not. You still - need to define trace_destinationin order to work, but this - value will be controlled using mi function tls_trace. - Default value is 0(tracing inactive). - - Example 1.8. Set trace_on parameter -... -modparam("proto_tls", "trace_on", 1) -... - -1.5.9. trace_filter_route (string) - - Define the name of a route in which you can filter which - connections will be trace and which connections won't be. In - this route you will have information regarding source and - destination ips and ports for the current connection. To - disable tracing for a specific connection the last call in this - route must be drop, any other exit mode resulting in tracing - the current connection ( of course you still have to define a - trace_destination and trace must be on at the time this - connection is opened. - - IMPORTANT Filtering on ip addresses and ports can be made using - $si and $sp for matching either the entity that is connecting - to OpenSIPS or the entity to which OpenSIPS is connecting. The - name might be misleading ( $si meaning the source ip if you - read the docs) but in reality it is simply the socket other - than the OpenSIPS socket. In order to match OpenSIPS interface - (either the one that accepted the connection or the one that - initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - WARNING: IF trace_on is set to 0 or tracing is deactived via - the mi command tls_trace this route won't be called. - Default value is none(no route is set). - - Example 1.9. Set trace_filter_route parameter -... -modparam("proto_tls", "trace_filter_route", "tls_filter") -... -/* all tls connections will go through this route if tracing is activate -d - * and a trace destination is defined */ -route[tls_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 506 -0) - exit; - else - drop; -} -... - -1.5.10. tls_handshake_timeout (integer) - - Sets the timeout (in milliseconds) for the SSL handshake - sequence to complete. It may be necessary to increase this - value when using a CPU intensive cipher for the connection to - allow time for keys to be generated and processed. - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is - being initiated (outbound). - - Default value is 100. - - Example 1.10. Set tls_handshake_timeout variable -... -modparam("proto_tls", "tls_handshake_timeout", 200) # number of millisec -onds -... - -1.5.11. tls_send_timeout (integer) - - Sets the timeout (in milliseconds) for the send operations to - complete - - The send timeout is invoked for all TLS write operations, - excluding the handshake process (see: tls_handshake_timeout) - - Default value is 100. - - Example 1.11. Set tls_send_timeout variable -... -modparam("proto_tls", "tls_send_timeout", 200) # number of milliseconds -... - -1.5.12. tls_async (integer) - - If the TLS connect and write operations should be done in an - asynchronous mode (non-blocking connect and write). If - disabled, OpenSIPS will block and wait for TLS operations like - connect and write. - - Default value is 1 (enabled). - - Example 1.12. Set tls_async variable -... -modparam("proto_tls", "tls_async", 1) # enable async TLS -... - -1.5.13. tls_async_max_postponed_chunks (integer) - - If tls_async is enabled, this specifies the maximum number of - SIP messages that can be stashed for later/async writing. If - the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - Default value is 32. - - Example 1.13. Set tls_async_max_postponed_chunks parameter -... -modparam("proto_tls", "tls_async_max_postponed_chunks", 16) -... - -1.5.14. tls_async_local_connect_timeout (integer) - - If tls_async is enabled, this specifies the number of - milliseconds that a connect will be tried in blocking mode - (optimization). If the connect operation lasts more than this, - the connect will go to async mode and will be passed to tls - MAIN for polling. - - Default value is 100 ms. - - Example 1.14. Set tls_async_local_connect_timeout parameter -... -modparam("proto_tls", "tls_async_local_connect_timeout", 200) -... - -1.5.15. tls_async_handshake_timeout (integer) - - If tls_async is enabled, this specifies the number of - milliseconds that a TLS handshake should be tried in blocking - mode (optimization). If the handshake operation lasts more than - this, the write will go to async mode and will be passed to tls - MAIN for polling. - - Default value is 10 ms. - - Example 1.15. Set tls_async_handshake_timeout parameter -... -modparam("proto_tls", "tls_async_handshake_timeout", 100) -... - -1.6. Exported MI Functions - -1.6.1. tls_trace - - Name: tls_trace - - Parameters: - * trace_mode(optional): set tls tracing on and off. This - parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - + on - + off - - MI FIFO Command Format: - opensips-cli -x mi tls_trace on - -Chapter 2. Frequently Asked Questions - - 2.1. - - Where can I post a question about TLS? - - Use one (the most appropriate) of the OpenSIPS mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - Remember: first at all, check if your question wasn't already - answered. - - 2.2. - - How can I report a bug? - - Accumulate as much as possible information (OpenSIPS version, - opensips -V output, your OS (uname -a), OpenSIPS logs, network - dumps, core dump files, configuration file) and send a mail to - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - Also you may try OpenSIPS's bug report web page: - https://opensips.org/pmwiki.php?n=Development.Tracker - - 2.3. - - How can I debug ssl/tls problems? - - Increase the log level in opensips.cfg (log_level=4) and watch - the log statements in syslog. - - Install the ssldump utility and start it. This will give you a - trace of the ssl/tls connections. - - 2.4. - - What is the difference between the TLS directory and the TLSOPS - module directory? - - The code in the TLS directory implements the TLS transport - layer. The TLSOPS module implements TLS related functions which - can be used in the routing script. - - 2.5. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.6. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.7. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 63 35 1562 827 - 2. Razvan Crainea (@razvancrainea) 54 34 921 706 - 3. Eseanu Marius Cristian (@eseanucristian) 42 5 55 2133 - 4. Ionut Ionita (@ionutrazvanionita) 35 14 1232 576 - 5. Vlad Patrascu (@rvlad-patrascu) 20 14 186 213 - 6. Liviu Chircu (@liviuchircu) 15 12 49 118 - 7. Maksym Sobolyev (@sobomax) 6 4 20 35 - 8. Bogdan Chifor 5 2 141 1 - 9. Vlad Paiu (@vladpaiu) 4 2 84 3 - 10. Dan Pascu (@danpascu) 3 1 2 4 - - All remaining contributors: Nick Altmann (@nikbyte), James - Stanley, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Zero - King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Feb 2015 - Jul 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2015 - Jun 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2015 - Jul 2024 - 4. James Stanley Dec 2023 - Dec 2023 - 5. Maksym Sobolyev (@sobomax) Jul 2017 - Nov 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Feb 2023 - 7. Nick Altmann (@nikbyte) May 2021 - May 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Dan Pascu (@danpascu) Jan 2020 - Jan 2020 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Julián Moreno Patiño, Eseanu Marius Cristian (@eseanucristian), - Bogdan Chifor, Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Zero King (@l2dy), Razvan Crainea - (@razvancrainea), Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Ionut Ionita (@ionutrazvanionita), Eseanu Marius - Cristian (@eseanucristian), Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com - - Copyright © 2013 Secusmart GmbH - - Copyright © 2006 enum.at - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2005 Cesc Santasusana diff --git a/modules/proto_tls/README.md b/modules/proto_tls/README.md new file mode 100644 index 00000000000..8e4c8d44836 --- /dev/null +++ b/modules/proto_tls/README.md @@ -0,0 +1,692 @@ +--- +title: "proto_tls module" +description: "TLS, as defined in SIP RFC 3261, is a mandatory feature for proxies and can be used to secure the SIP signalling on a hop-by-hop basis (not end-to-end)." +--- + +## Admin Guide + + +### Overview + + +TLS, as defined in SIP RFC 3261, is a mandatory feature for proxies +and can be used to secure the SIP signalling on a hop-by-hop basis +(not end-to-end). TLS works on top of TCP. DTLS, or TLS over UDP is +already defined by IETF and may become available in the future. + + +### History + + +The TLS support was originally developed by Peter Griffiths and posted +as a patch on SER development mailing list. Thanks to Cesc +Santasusana, several problems were fixed and some improvements were +added. + + +The TLS support was simultaneously added in both projects. In SER, +the support was committed in a separate "experimental" +CVS tree, as patch to the main CVS tree. In OpenSIPS, the support was +integrated directly into the CVS tree, as a built-in component, and is +part of stable OpenSIPS since release >=1.0.0. + + +Starting with OpenSIPS 2.1, the TLS has been moved to a separate +transport module, that implements the more generic Transport +Interface. + + +### Scenario + + +By the increased number of providers the SIP world is continuously +growing. More users means more calls and more calls means a high +probability for a user to receive calls from totally unknown people +or, in the worst case, to receive unwanted calls. To prevent this, a +defense mechanism must be adopted by the SIP provider. Since only the +called user is fully able to classify a call as being unwanted, the +SIP server, based on all information regarding the call should notify +the user about the desirability of the call. Information like the +caller domain, the received source or the incoming protocol can be +very useful for a SIP server to establish the nature of the call. + + +As this information is quite limited, is very improbable for a server +to be able detect the unwanted calls - there are many calls that it +cannot predict anything about its status (neutral calls). So, instead +on alerting the called user about unwanted calls, the server can +notify the user about calls that are considered trusted - calls for +which the server is 100% sure there are not unwanted. + + +So, a trust concept must be defined for SIP servers. Which calls +are trusted and which are not? A call is trusted if the caller can +be identify as a trustable user - a user about we have reliable +information. + + +Since all the user from its domain are authenticated (or should be), +a SIP server can consider all the calls generated by its user as +trusted. Now we have to extend the trust concept to the multi-domain +level. A mutual agreement, between several domains, can establish a +trusting relationship. So, a domain (called A) will consider also as +trusted calls all the calls generated by user from a different domain +(called B) and vice-versa. But just an agreement is not enough; since +the authentication information is strictly limited to a domain +(a domain can authenticate only its own user, not the user from other +domains), there is still the problem of checking the authenticity of +the caller - he can impersonate (by a false FROM header) a user from +a domain that is trusted. + + +The answer to this problem is TLS (Transport Layer Security). All +calls via domain A and domain B will be done via TLS. Authentication +in origin domain plus TLS transport between domains will make the +call 100% trusted for the target domain. + + +For such a mechanism to work, the following requirements must be met: + + +- all UA must have set as outbound proxy their home server. +- all SIP servers must authenticated all the calls generated by +their own users. +- all SIP servers must relay the calls generated be their +user to a trusted domain via TLS. + + +Based on this, a server can classify as trusted a call for one of +its user only if the call is also generated by one of its users or +is the call is received from a trusted domain ( which is equivalent +with a call received via TLS). Untrusted call will be calls received +from users belonging to untrusted domains or from users from trusted +domains, but whose calls are not routed via their home server +(so, they are not authenticated by there home servers). + + +Once the server is able to tell if the call is trusted or not, the +still open issue is about the mechanism used by server to notify the +called user about the nature of the incoming call. + + +One way to do it is by remotely changing the ringing type of the +called user's phone. This can be done by inserting special header +into the INVITE request. Such feature is supported by now by several +hardphones like CISCO ATA, CISCO 7960 and SNOM. This phones can +change their ringing tone based on the present or content of the +"Alert-Info" SIP header as follows: + + +- *CISCO ATA* - it has 4 pre-defined +ringing types. The Alert-Info header must look like +"Alert-info: Bellcore-drX EOH" where X can be +between 1 and 4. Note that 1 is the phone default ringing tone. +- *CISCO 7960* - it has 2 pre-defined +ringing types and the possibility of uploading new ones. +The "Alert-Info" header must look like +"Alert-info: X EOH" where X can be whatever number. +When this header is present, the phones will not change the +ringing tone, but the ringing pattern. Normally, the phone rings +like [ring.........ring..........ring] where [ring] is the +ringing tone; if the header is present, the ringing pattern will +be [ring.ring.........ring.ring........]. So, to be able to hear +some difference between the two patterns (and not only as length), +its strongly recommended to have a highly asymmetric ringing type +(as the pre-defined are not!!). +- *SNOM* - The "Alert-Info" +header must look like "Alert-info: URL EOH"" where +URL can be a HTTP URL (for example) from where the phone can +retrieve a ringing tone. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_openssl* or *tls_wolfssl*, +depending on the desired TLS library +- *tls_mgm*. + + +#### Dependencies of external libraries + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +All these parameters can be used from the opensips.cfg file, +to configure the behavior of OpenSIPS-TLS. + + +#### listen=interface + + +Not specific to TLS. Allows to specify the protocol +(udp, tcp, tls), the IP address and the port where the +listening server will be. + + +```opensips title="Set listen variable" +... +socket= tls:1.2.3.4:5061 +... +``` + + +#### tls_port (integer) + + +The default port to be used for all TLS related operation. Be +careful as the default port impacts both the SIP listening part +(if no port is defined in the TLS listeners) and the SIP sending +part (if the destination URI has no explicit port). + + +If you want to change only the listening port for TLS, use the port +option in the SIP listener defintion. + + +*Default value is 5061.* + + +```opensips title="Set tls_port variable" +... +modparam("proto_tls", "tls_port", 5062) +... +``` + + +#### tls_crlf_pingpong (integer) + + +Send CRLF pong (\r\n) to incoming CRLFCRLF ping messages over TLS. +By default it is enabled (1). + + +*Default value is 1 (enabled).* + + +```opensips title="Set tls_crlf_pingpong parameter" +... +modparam("proto_tls", "tls_crlf_pingpong", 0) +... +``` + + +#### tls_crlf_drop (integer) + + +Drop CRLF (\r\n) ping messages. When this parameter is enabled, +the TLS layer drops packets that contains a single CRLF message. +If a CRLFCRLF message is received, it is handled according to the +*tls_crlf_pingpong* parameter. + + +*Default value is 0 (disabled).* + + +```opensips title="Set tls_crlf_drop parameter" +... +modparam("proto_tls", "tls_crlf_drop", 1) +... +``` + + +#### tls_max_msg_chunks (integer) + + +The maximum number of chunks that a SIP message is expected to +arrive via TLS. If a packet is received more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending the +traffic very fragmented in order to decrease server performance). + + +*Default value is 4.* + + +```opensips title="Set tls_max_msg_chunks parameter" +... +modparam("proto_tls", "tls_max_msg_chunks", 8) +... +``` + + +#### cert_check_on_conn_reusage (integer) + + +This parameter turns on or off the extra checking/matching of the +TLS domain (SSL certificate) when comes to reusing an existing TLS +connection. Without this extra check, only IP and port of the +connections will be check (in order to re-use an existing connection). +With this extra check, the connection to be reused must have the same +SSL certificate as the one set for the current signaling operation. + + +This checking is done only when comes to send SIP traffic via TLS and +it is applied only against connections that were created / initiated +by OpenSIPS (as TLS client). Any accepte connection (as TLS server) will +automatically match (the extra test will be skipped). + + +*Default value is 0 (disabled).* + + +```opensips title="Set cert_check_on_conn_reusage parameter" +... +modparam("proto_tls", "cert_check_on_conn_reusage", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. +For each connection that is created an event containing information +about the client and server certificates, master key and network layer +information shall be sent. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("proto_tls", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for tls is on or not. You still need to define +[tls trace destination](#param_trace_destination)in order to work, but this value will be +controlled using mi function [mi tls trace](#mi_tls_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_tls", "trace_on", 1) +... +``` + + +#### trace_filter_route (string) + + +Define the name of a route in which you can filter which connections will +be trace and which connections won't be. In this route you will have +information regarding source and destination ips and ports for the current +connection. To disable tracing for a specific connection the last call in +this route must be **drop**, any other exit +mode resulting in tracing the current connection ( of course you still +have to define a [tls trace destination](#param_trace_destination) and trace must be +on at the time this connection is opened. + + +> [!IMPORTANT] +> Filtering on ip addresses and ports can be made using **$si** and **$sp** for matching +> either the entity that is connecting to OpenSIPS or the entity to which +> OpenSIPS is connecting. The name might be misleading (**$si** meaning the source ip if you read the docs) but in reality +> it is simply the socket other than the OpenSIPS socket. In order to match +> OpenSIPS interface (either the one that accepted the connection or the one +> that initiated a connection) **$socket_in(ip)** (ip) and +> **$socket_in(port)** (port) can be used. + + +> [!WARNING] +> If [trace on](#param_trace_on) is set to 0 or tracing is deactived via the mi command [mi trace](#mi_trace) this route won't be called. + + +```opensips title="Set trace_filter_route parameter" +... +modparam("proto_tls", "trace_filter_route", "tls_filter") +... +/* all tls connections will go through this route if tracing is activated + * and a trace destination is defined */ +route[tls_filter] { + ... + /* all connections opened from/by ip 1.1.1.1:8000 will be traced + on interface 1.1.1.10:5060(opensips listener) + all the other connections won't be */ + if ( $si == "1.1.1.1" && $sp == 8000 && + $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) + exit; + else + drop; +} +... +``` + + +#### tls_handshake_timeout (integer) + + +Sets the timeout (in milliseconds) for the SSL handshake sequence to complete. +It may be necessary to increase this value when using a CPU intensive cipher +for the connection to allow time for keys to be generated and processed. + + +The timeout is invoked during acceptance of a new connection (inbound) and +during the wait period when a new session is being initiated (outbound). + + +*Default value is 100.* + + +```opensips title="Set tls_handshake_timeout variable" +... +modparam("proto_tls", "tls_handshake_timeout", 200) # number of milliseconds +... +``` + + +#### tls_send_timeout (integer) + + +Sets the timeout (in milliseconds) for the send operations to complete + + +The send timeout is invoked for all TLS write operations, excluding +the handshake process (see: tls_handshake_timeout) + + +*Default value is 100.* + + +```opensips title="Set tls_send_timeout variable" +... +modparam("proto_tls", "tls_send_timeout", 200) # number of milliseconds +... +``` + + +#### tls_async (integer) + + +If the TLS connect and write operations should be done in an +asynchronous mode (non-blocking connect and +write). If disabled, OpenSIPS will block and wait for TLS +operations like connect and write. + + +*Default value is 1 (enabled).* + + +```opensips title="Set tls_async variable" +... +modparam("proto_tls", "tls_async", 1) # enable async TLS +... +``` + + +#### tls_async_max_postponed_chunks (integer) + + +If *tls_async* is enabled, this specifies the +maximum number of SIP messages that can be stashed for later/async +writing. If the connection pending writes exceed this number, the +connection will be marked as broken and dropped. + + +*Default value is 32.* + + +```opensips title="Set tls_async_max_postponed_chunks parameter" +... +modparam("proto_tls", "tls_async_max_postponed_chunks", 16) +... +``` + + +#### tls_async_local_connect_timeout (integer) + + +If *tls_async* is enabled, this specifies the +number of milliseconds that a connect will be tried in blocking +mode (optimization). If the connect operation lasts more than +this, the connect will go to async mode and will be passed to tls +MAIN for polling. + + +*Default value is 100 ms.* + + +```opensips title="Set tls_async_local_connect_timeout parameter" +... +modparam("proto_tls", "tls_async_local_connect_timeout", 200) +... +``` + + +#### tls_async_handshake_timeout (integer) + + +If *tls_async* is enabled, this specifies the +number of milliseconds that a TLS handshake should be tried in blocking +mode (optimization). If the handshake operation lasts more than this, +the write will go to async mode and will be passed to tls MAIN for +polling. + + +*Default value is 10 ms.* + + +```opensips title="Set tls_async_handshake_timeout parameter" +... +modparam("proto_tls", "tls_async_handshake_timeout", 100) +... +``` + + +### Exported MI Functions + + +#### tls_trace + + +Name: *tls_trace* + + +Parameters: + + +- trace_mode(optional): set tls tracing on and off. This parameter +can be missing and the command will show the current tracing +status for this module( on or off ); +Possible values: + - on + - off + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi tls_trace on +``` + + +## Developer Guide + + +### TLS_SERVER + + +#### SSL data per connection + + +Each TLS connection, incoming or outgoing, creates an +SSL * object, where configuration inherited from the +SSL_CTX * and particular info on that socket are stored. +This SSL * structure is kept in OpenSIPS as long as the connection +is alive, as part of the "struct tcp_connection *" +object: + + +```c +... +struct tcp_connection *c; +SSL *ssl; + +/*create somehow SSL object*/ +c->extra_data = (void *) ssl; +ssl = (SSL *) c->extra_data; +... +``` + + +#### tls_print_errstack + + +void tls_print_errstack(void); + + +Dumps ssl error stack. + + +#### tls_tcpconn_init + + +int tls_tcpconn_init( struct tcp_connection *c, int fd); + + +Called when new tcp connection is accepted + + +#### tls_tcpconn_clean + + +void tls_tcpconn_clean( struct tcp_connection *c); + + +Shuts down the TLS connection. + + +#### tls_blocking_write + + +size_t tls_blocking_write( struct tcp_connection *c, int fd, +const char *buf, size_t len); + + +Writes a memory chunk in blocking mode (syncron). + + +#### tls_read + + +size_t tls_read( struct tcp_connection *c); + + +Reads from a TLS connection. Return the number of bytes read. + + +#### tls_fix_read_conn + + +void tls_tcpconn_clean( struct tcp_connection *c); + + +Shuts down the TLS connection. + + +## Frequently Asked Questions + + +**Q: Where can I post a question about TLS?** + + +Use one (the most appropriate) of the OpenSIPS mailing lists: + +Remember: first at all, check if your question wasn't already +answered. + + +**Q: How can I report a bug?** + + +Accumulate as much as possible information (OpenSIPS version, +opensips -V output, your OS (uname -a), OpenSIPS logs, network dumps, +core dump files, configuration file) +and send a mail to [http://lists.opensips.org/cgi-bin/mailman/listinfo/devel](http://lists.opensips.org/cgi-bin/mailman/listinfo/devel) + +Also you may try OpenSIPS's bug report web page: +https://opensips.org/pmwiki.php?n=Development.Tracker + + +**Q: How can I debug ssl/tls problems?** + + +Increase the log level in opensips.cfg (log_level=4) and watch +the log statements in syslog. + +Install the ssldump utility and start it. This will give you a trace +of the ssl/tls connections. + + +**Q: What is the difference between the TLS directory and the +TLSOPS module directory?** + + +The code in the TLS directory implements the TLS transport layer. +The TLSOPS module implements TLS related functions which +can be used in the routing script. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_tls/doc/contributors.xml b/modules/proto_tls/doc/contributors.xml deleted file mode 100644 index 4931e6a2295..00000000000 --- a/modules/proto_tls/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 63 - 35 - 1562 - 827 - - - 2. - Razvan Crainea (@razvancrainea) - 54 - 34 - 921 - 706 - - - 3. - Eseanu Marius Cristian (@eseanucristian) - 42 - 5 - 55 - 2133 - - - 4. - Ionut Ionita (@ionutrazvanionita) - 35 - 14 - 1232 - 576 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 20 - 14 - 186 - 213 - - - 6. - Liviu Chircu (@liviuchircu) - 15 - 12 - 49 - 118 - - - 7. - Maksym Sobolyev (@sobomax) - 6 - 4 - 20 - 35 - - - 8. - Bogdan Chifor - 5 - 2 - 141 - 1 - - - 9. - Vlad Paiu (@vladpaiu) - 4 - 2 - 84 - 3 - - - 10. - Dan Pascu (@danpascu) - 3 - 1 - 2 - 4 - - - -
-All remaining contributors: Nick Altmann (@nikbyte), James Stanley, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Feb 2015 - Jul 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2015 - Jun 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2015 - Jul 2024 - - - 4. - James Stanley - Dec 2023 - Dec 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Jul 2017 - Nov 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Feb 2023 - - - 7. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Dan Pascu (@danpascu) - Jan 2020 - Jan 2020 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Eseanu Marius Cristian (@eseanucristian), Bogdan Chifor, Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Zero King (@l2dy), Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Eseanu Marius Cristian (@eseanucristian), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/proto_tls/doc/proto_tls.xml b/modules/proto_tls/doc/proto_tls.xml deleted file mode 100644 index 63b393cf331..00000000000 --- a/modules/proto_tls/doc/proto_tls.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - proto_tls module - &osipsname; - - - - &admin; - - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - ©right; 2013 Secusmart GmbH - ©right; 2006 enum.at - ©right; 2005 &voicesystem; - ©right; 2005 Cesc Santasusana - diff --git a/modules/proto_tls/doc/proto_tls_admin.xml b/modules/proto_tls/doc/proto_tls_admin.xml deleted file mode 100644 index 38a193f4294..00000000000 --- a/modules/proto_tls/doc/proto_tls_admin.xml +++ /dev/null @@ -1,634 +0,0 @@ - - - - &adminguide; - -
- Overview - - TLS, as defined in SIP RFC 3261, is a mandatory feature for proxies - and can be used to secure the SIP signalling on a hop-by-hop basis - (not end-to-end). TLS works on top of TCP. DTLS, or TLS over UDP is - already defined by IETF and may become available in the future. - -
- -
- History - - The TLS support was originally developed by Peter Griffiths and posted - as a patch on SER development mailing list. Thanks to Cesc - Santasusana, several problems were fixed and some improvements were - added. - - - The TLS support was simultaneously added in both projects. In SER, - the support was committed in a separate experimental - CVS tree, as patch to the main CVS tree. In OpenSIPS, the support was - integrated directly into the CVS tree, as a built-in component, and is - part of stable OpenSIPS since release >=1.0.0. - - - Starting with OpenSIPS 2.1, the TLS has been moved to a separate - transport module, that implements the more generic Transport - Interface. - -
- -
- Scenario - - By the increased number of providers the SIP world is continuously - growing. More users means more calls and more calls means a high - probability for a user to receive calls from totally unknown people - or, in the worst case, to receive unwanted calls. To prevent this, a - defense mechanism must be adopted by the SIP provider. Since only the - called user is fully able to classify a call as being unwanted, the - SIP server, based on all information regarding the call should notify - the user about the desirability of the call. Information like the - caller domain, the received source or the incoming protocol can be - very useful for a SIP server to establish the nature of the call. - - - As this information is quite limited, is very improbable for a server - to be able detect the unwanted calls - there are many calls that it - cannot predict anything about its status (neutral calls). So, instead - on alerting the called user about unwanted calls, the server can - notify the user about calls that are considered trusted - calls for - which the server is 100% sure there are not unwanted. - - - So, a trust concept must be defined for SIP servers. Which calls - are trusted and which are not? A call is trusted if the caller can - be identify as a trustable user - a user about we have reliable - information. - - - Since all the user from its domain are authenticated (or should be), - a SIP server can consider all the calls generated by its user as - trusted. Now we have to extend the trust concept to the multi-domain - level. A mutual agreement, between several domains, can establish a - trusting relationship. So, a domain (called A) will consider also as - trusted calls all the calls generated by user from a different domain - (called B) and vice-versa. But just an agreement is not enough; since - the authentication information is strictly limited to a domain - (a domain can authenticate only its own user, not the user from other - domains), there is still the problem of checking the authenticity of - the caller - he can impersonate (by a false FROM header) a user from - a domain that is trusted. - - - The answer to this problem is TLS (Transport Layer Security). All - calls via domain A and domain B will be done via TLS. Authentication - in origin domain plus TLS transport between domains will make the - call 100% trusted for the target domain. - - - For such a mechanism to work, the following requirements must be met: - - - - - all UA must have set as outbound proxy their home server. - - - - - all SIP servers must authenticated all the calls generated by - their own users. - - - - all SIP servers must relay the calls generated be their - user to a trusted domain via TLS. - - - - - Based on this, a server can classify as trusted a call for one of - its user only if the call is also generated by one of its users or - is the call is received from a trusted domain ( which is equivalent - with a call received via TLS). Untrusted call will be calls received - from users belonging to untrusted domains or from users from trusted - domains, but whose calls are not routed via their home server - (so, they are not authenticated by there home servers). - - - Once the server is able to tell if the call is trusted or not, the - still open issue is about the mechanism used by server to notify the - called user about the nature of the incoming call. - - - One way to do it is by remotely changing the ringing type of the - called user's phone. This can be done by inserting special header - into the INVITE request. Such feature is supported by now by several - hardphones like CISCO ATA, CISCO 7960 and SNOM. This phones can - change their ringing tone based on the present or content of the - "Alert-Info" SIP header as follows: - - - - CISCO ATA - it has 4 pre-defined - ringing types. The Alert-Info header must look like - Alert-info: Bellcore-drX EOH where X can be - between 1 and 4. Note that 1 is the phone default ringing tone. - - - - CISCO 7960 - it has 2 pre-defined - ringing types and the possibility of uploading new ones. - The Alert-Info header must look like - Alert-info: X EOH where X can be whatever number. - When this header is present, the phones will not change the - ringing tone, but the ringing pattern. Normally, the phone rings - like [ring.........ring..........ring] where [ring] is the - ringing tone; if the header is present, the ringing pattern will - be [ring.ring.........ring.ring........]. So, to be able to hear - some difference between the two patterns (and not only as length), - its strongly recommended to have a highly asymmetric ringing type - (as the pre-defined are not!!). - - - - SNOM - The Alert-Info - header must look like Alert-info: URL EOH" where - URL can be a HTTP URL (for example) from where the phone can - retrieve a ringing tone. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_openssl or tls_wolfssl, - depending on the desired TLS library - - - - - tls_mgm. - - - - -
-
- Dependencies of external libraries - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- &osips; Exported parameters - - All these parameters can be used from the opensips.cfg file, - to configure the behavior of &osips;-TLS. - - -
- <varname>listen</varname>=interface - - Not specific to TLS. Allows to specify the protocol - (udp, tcp, tls), the IP address and the port where the - listening server will be. - - - Set <varname>listen</varname> variable - -... -socket= tls:1.2.3.4:5061 -... - - -
- -
- <varname>tls_port</varname> (integer) - - The default port to be used for all TLS related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the TLS listeners) and the SIP sending - part (if the destination URI has no explicit port). - - - If you want to change only the listening port for TLS, use the port - option in the SIP listener defintion. - - - Default value is 5061. - - - Set <varname>tls_port</varname> variable - -... -modparam("proto_tls", "tls_port", 5062) -... - - -
- -
- <varname>tls_crlf_pingpong</varname> (integer) - - Send CRLF pong (\r\n) to incoming CRLFCRLF ping messages over TLS. - By default it is enabled (1). - - - - Default value is 1 (enabled). - - - - Set <varname>tls_crlf_pingpong</varname> parameter - -... -modparam("proto_tls", "tls_crlf_pingpong", 0) -... - - -
-
- <varname>tls_crlf_drop</varname> (integer) - - Drop CRLF (\r\n) ping messages. When this parameter is enabled, - the TLS layer drops packets that contains a single CRLF message. - If a CRLFCRLF message is received, it is handled according to the - tls_crlf_pingpong parameter. - - - - Default value is 0 (disabled). - - - - Set <varname>tls_crlf_drop</varname> parameter - -... -modparam("proto_tls", "tls_crlf_drop", 1) -... - - -
- -
- <varname>tls_max_msg_chunks</varname> (integer) - - The maximum number of chunks that a SIP message is expected to - arrive via TLS. If a packet is received more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending the - traffic very fragmented in order to decrease server performance). - - - - Default value is 4. - - - - Set <varname>tls_max_msg_chunks</varname> parameter - -... -modparam("proto_tls", "tls_max_msg_chunks", 8) -... - - -
- -
- <varname>cert_check_on_conn_reusage</varname> (integer) - - This parameter turns on or off the extra checking/matching of the - TLS domain (SSL certificate) when comes to reusing an existing TLS - connection. Without this extra check, only IP and port of the - connections will be check (in order to re-use an existing connection). - With this extra check, the connection to be reused must have the same - SSL certificate as the one set for the current signaling operation. - - - This checking is done only when comes to send SIP traffic via TLS and - it is applied only against connections that were created / initiated - by OpenSIPS (as TLS client). Any accepte connection (as TLS server) will - automatically match (the extra test will be skipped). - - - - Default value is 0 (disabled). - - - - Set <varname>cert_check_on_conn_reusage</varname> parameter - -... -modparam("proto_tls", "cert_check_on_conn_reusage", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - For each connection that is created an event containing information - about the client and server certificates, master key and network layer - information shall be sent. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_tls", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for tls is on or not. You still need to define - in order to work, but this value will be - controlled using mi function . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_tls", "trace_on", 1) -... - - -
- -
- <varname>trace_filter_route</varname> (string) - - Define the name of a route in which you can filter which connections will - be trace and which connections won't be. In this route you will have - information regarding source and destination ips and ports for the current - connection. To disable tracing for a specific connection the last call in - this route must be drop, any other exit - mode resulting in tracing the current connection ( of course you still - have to define a and trace must be - on at the time this connection is opened. - - - IMPORTANT - Filtering on ip addresses and ports can be made using - $si and $sp for matching - either the entity that is connecting to &osips; or the entity to which - &osips; is connecting. The name might be misleading ( - $si meaning the source ip if you read the docs) but in reality - it is simply the socket other than the &osips; socket. In order to match - &osips; interface (either the one that accepted the connection or the one - that initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - - - WARNING: IF is - set to 0 or tracing is deactived via the mi command - this route won't be called. - - - Default value is none(no route is set). - - - Set <varname>trace_filter_route</varname> parameter - -... -modparam("proto_tls", "trace_filter_route", "tls_filter") -... -/* all tls connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[tls_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) - exit; - else - drop; -} -... - - -
- -
- <varname>tls_handshake_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the SSL handshake sequence to complete. - It may be necessary to increase this value when using a CPU intensive cipher - for the connection to allow time for keys to be generated and processed. - - - The timeout is invoked during acceptance of a new connection (inbound) and - during the wait period when a new session is being initiated (outbound). - - - Default value is 100. - - - Set <varname>tls_handshake_timeout</varname> variable - -... -modparam("proto_tls", "tls_handshake_timeout", 200) # number of milliseconds -... - - -
- -
- <varname>tls_send_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the send operations to complete - - - The send timeout is invoked for all TLS write operations, excluding - the handshake process (see: tls_handshake_timeout) - - - Default value is 100. - - - Set <varname>tls_send_timeout</varname> variable - -... -modparam("proto_tls", "tls_send_timeout", 200) # number of milliseconds -... - - -
- -
- <varname>tls_async</varname> (integer) - - If the TLS connect and write operations should be done in an - asynchronous mode (non-blocking connect and - write). If disabled, OpenSIPS will block and wait for TLS - operations like connect and write. - - - Default value is 1 (enabled). - - - Set <varname>tls_async</varname> variable - -... -modparam("proto_tls", "tls_async", 1) # enable async TLS -... - - -
- -
- <varname>tls_async_max_postponed_chunks</varname> (integer) - - If tls_async is enabled, this specifies the - maximum number of SIP messages that can be stashed for later/async - writing. If the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - - - Default value is 32. - - - - Set <varname>tls_async_max_postponed_chunks</varname> parameter - -... -modparam("proto_tls", "tls_async_max_postponed_chunks", 16) -... - - -
-
- <varname>tls_async_local_connect_timeout</varname> (integer) - - If tls_async is enabled, this specifies the - number of milliseconds that a connect will be tried in blocking - mode (optimization). If the connect operation lasts more than - this, the connect will go to async mode and will be passed to tls - MAIN for polling. - - - - Default value is 100 ms. - - - - Set <varname>tls_async_local_connect_timeout</varname> parameter - -... -modparam("proto_tls", "tls_async_local_connect_timeout", 200) -... - - -
-
- <varname>tls_async_handshake_timeout</varname> (integer) - - If tls_async is enabled, this specifies the - number of milliseconds that a TLS handshake should be tried in blocking - mode (optimization). If the handshake operation lasts more than this, - the write will go to async mode and will be passed to tls MAIN for - polling. - - - - Default value is 10 ms. - - - - Set <varname>tls_async_handshake_timeout</varname> parameter - -... -modparam("proto_tls", "tls_async_handshake_timeout", 100) -... - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">tls_trace</function> - - - - - - - Name: tls_trace - - - Parameters: - - - trace_mode(optional): set tls tracing on and off. This parameter - can be missing and the command will show the current tracing - status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi tls_trace on - -
-
-
diff --git a/modules/proto_tls/doc/proto_tls_devel.xml b/modules/proto_tls/doc/proto_tls_devel.xml deleted file mode 100644 index a789877fd8a..00000000000 --- a/modules/proto_tls/doc/proto_tls_devel.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - - - &develguide; - -
- TLS_SERVER -
- SSL data per connection - - Each TLS connection, incoming or outgoing, creates an - SSL * object, where configuration inherited from the - SSL_CTX * and particular info on that socket are stored. - This SSL * structure is kept in &osips; as long as the connection - is alive, as part of the struct tcp_connection * - object: - -... -struct tcp_connection *c; -SSL *ssl; - -/*create somehow SSL object*/ -c->extra_data = (void *) ssl; -ssl = (SSL *) c->extra_data; -... - - -
-
- tls_print_errstack - - void tls_print_errstack(void); - - - Dumps ssl error stack. - -
-
- tls_tcpconn_init - - int tls_tcpconn_init( struct tcp_connection *c, int fd); - - - Called when new tcp connection is accepted - -
-
- tls_tcpconn_clean - - void tls_tcpconn_clean( struct tcp_connection *c); - - - Shuts down the TLS connection. - -
-
- tls_blocking_write - - size_t tls_blocking_write( struct tcp_connection *c, int fd, - const char *buf, size_t len); - - - Writes a memory chunk in blocking mode (syncron). - -
-
- tls_read - - size_t tls_read( struct tcp_connection *c); - - - Reads from a TLS connection. Return the number of bytes read. - -
-
- tls_fix_read_conn - - void tls_tcpconn_clean( struct tcp_connection *c); - - - Shuts down the TLS connection. - -
-
- -
diff --git a/modules/proto_tls/doc/proto_tls_faq.xml b/modules/proto_tls/doc/proto_tls_faq.xml deleted file mode 100644 index cd82e491e3b..00000000000 --- a/modules/proto_tls/doc/proto_tls_faq.xml +++ /dev/null @@ -1,127 +0,0 @@ - - - - &faqguide; - - - - Where can I post a question about TLS? - - - - Use one (the most appropriate) of the &osips; mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - Remember: first at all, check if your question wasn't already - answered. - - - - - - How can I report a bug? - - - - Accumulate as much as possible information (&osips; version, - opensips -V output, your OS (uname -a), &osips; logs, network dumps, - core dump files, configuration file) - and send a mail to &osipsdevlink; - - - Also you may try OpenSIPS's bug report web page: - https://opensips.org/pmwiki.php?n=Development.Tracker - - - - - - How can I debug ssl/tls problems? - - - - Increase the log level in opensips.cfg (log_level=4) and watch - the log statements in syslog. - - - Install the ssldump utility and start it. This will give you a trace - of the ssl/tls connections. - - - - - - What is the difference between the TLS directory and the - TLSOPS module directory? - - - - - The code in the TLS directory implements the TLS transport layer. - The TLSOPS module implements TLS related functions which - can be used in the routing script. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - - - diff --git a/modules/proto_ws/README b/modules/proto_ws/README deleted file mode 100644 index 7602f585f5d..00000000000 --- a/modules/proto_ws/README +++ /dev/null @@ -1,354 +0,0 @@ -proto_ws Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. ws_port (integer) - 1.3.2. ws_send_timeout (integer) - 1.3.3. ws_max_msg_chunks (integer) - 1.3.4. trace_destination (string) - 1.3.5. trace_on (int) - 1.3.6. trace_filter_route (string) - 1.3.7. require_origin (int) - - 1.4. Exported MI Functions - - 1.4.1. ws_trace - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set ws_port parameter - 1.2. Set ws_send_timeout parameter - 1.3. Set ws_max_msg_chunks parameter - 1.4. Set trace_destination parameter - 1.5. Set trace_on parameter - 1.6. Set trace_filter_route parameter - 1.7. Set require_origin parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The WebSocket protocol (RFC 6455) provides an end-to-end - full-duplex communication channel between two web-based - applications. This allows WebSocket enabled browsers to connect - to a WebSocket server and exchange any type of data. RFC 7118 - provides the specifications for transporting SIP messages over - the WebSocket protocol. - - The proto_ws module is transport module that provides - communication over the WebSocket protocol. This module is fully - compliant with the RFC 7118, thus allowing browsers to act as - SIP clients for the OpenSIPS proxy. - - The current implementation acts both as WebSocket server and - client, thus it can accept connections from WebSocket clients - and can also initiate connections to another WebSocket server. - After the connection is established, messages can flow in both - directions. - - OpenSIPS supports the following WebSocket operations: - * text and binary - can both send and receive WebSocket - messages that contain text or binary body - * close - messages used to safely close the WebSocket - communication using a 2-messages handshake - * ping - responds with pong messages. There is no mechanism - to trigger ping messages. - * pong - sent when a ping message is received. OpenSIPS, - absorbes the pong messages received. - - Once loaded, you will be able to define WebSocket listeners in - your script. To add a listener, you have to add its IP, and - optionally the listening port, after the mpath parameter, - similar to this example: - -... -mpath=/path/to/modules -... -socket=ws:127.0.0.1 # change with the listening IP -socket=ws:127.0.0.1:5060 # change with the listening IP and port -... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. ws_port (integer) - - The default port to be used for all WS related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the WS listeners) and the SIP sending - part (if the destination WS URI has no explicit port). - - If you want to change only the listening port for WS, use the - port option in the SIP listener defintion. - - Default value is 80. - - Example 1.1. Set ws_port parameter -... -modparam("proto_ws", "ws_port", 8080) -... - -1.3.2. ws_send_timeout (integer) - - Time in milliseconds after a WebSocket connection will be - closed if it is not available for blocking writing in this - interval (and OpenSIPS wants to send something on it). - - Default value is 100 ms. - - Example 1.2. Set ws_send_timeout parameter -... -modparam("proto_ws", "ws_send_timeout", 200) -... - -1.3.3. ws_max_msg_chunks (integer) - - The maximum number of chunks in which a SIP message is expected - to arrive via WebSocket. If a received packet is more - fragmented than this, the connection is dropped (either the - connection is very overloaded and this leads to high - fragmentation - or we are the victim of an ongoing attack where - the attacker is sending very fragmented traffic in order to - decrease server performance). - - Default value is 4. - - Example 1.3. Set ws_max_msg_chunks parameter -... -modparam("proto_ws", "ws_max_msg_chunks", 8) -... - -1.3.4. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. Network events such as - connect, accept and connection closed events shall be traced - along with errors that could appear in the process. For each - connection that is created an event containing information - about http request and reply belonging to web socket protocol - handshake and network layer information shall be sent. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.4. Set trace_destination parameter -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;versio -n=3") - -modparam("proto_ws", "trace_destination", "hep_dest") -... - -1.3.5. trace_on (int) - - This controls whether tracing for ws is on or not. You still - need to define trace_destinationin order to work, but this - value will be controlled using mi function ws_trace. - Default value is 0(tracing inactive). - - Example 1.5. Set trace_on parameter -... -modparam("proto_ws", "trace_on", 1) -... - -1.3.6. trace_filter_route (string) - - Define the name of a route in which you can filter which - connections will be trace and which connections won't be. In - this route you will have information regarding source and - destination ips and ports for the current connection. To - disable tracing for a specific connection the last call in this - route must be drop, any other exit mode resulting in tracing - the current connection ( of course you still have to define a - trace_destination and trace must be on at the time this - connection is opened. - - IMPORTANT Filtering on ip addresses and ports can be made using - $si and $sp for matching either the entity that is connecting - to OpenSIPS or the entity to which OpenSIPS is connecting. The - name might be misleading ( $si meaning the source ip if you - read the docs) but in reality it is simply the socket other - than the OpenSIPS socket. In order to match OpenSIPS interface - (either the one that accepted the connection or the one that - initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - WARNING: IF trace_on is set to 0 or tracing is deactived via - the mi command ws_trace this route won't be called. - Default value is none(no route is set). - - Example 1.6. Set trace_filter_route parameter -... -modparam("proto_ws", "trace_filter_route", "ws_filter") -... -/* all ws connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[ws_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 506 -0) - exit; - else - drop; -} -... - -1.3.7. require_origin (int) - - Controls whether the module should require the Origin header or - not. - Default value is 1(require Origin header). - - Example 1.7. Set require_origin parameter -... -modparam("proto_ws", "require_origin", no) -... - -1.4. Exported MI Functions - -1.4.1. ws_trace - - Name: ws_trace - - Parameters: - * trace_mode(optional): set ws tracing on and off. This - parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - + on - + off - - MI FIFO Command Format: - opensips-cli -x mi ws_trace on - -Chapter 2. Frequently Asked Questions - - 2.1. - - Can OpenSIPS act as a WebSocket client? - - Yes, starting with OpenSIPS 2.2, it can act as a WebSocket - client. - - 2.2. - - Does OpenSIPS support WebSocket message fragmentation? - - No, WebSocket fragmentation mechanism is not supported. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 98 49 4086 827 - 2. Ionut Ionita (@ionutrazvanionita) 22 14 609 114 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 19 16 138 51 - 4. Liviu Chircu (@liviuchircu) 16 11 128 141 - 5. Vlad Patrascu (@rvlad-patrascu) 8 5 97 74 - 6. Maksym Sobolyev (@sobomax) 7 5 36 35 - 7. Vlad Paiu (@vladpaiu) 5 3 5 3 - 8. Nick Altmann (@nikbyte) 4 2 5 5 - 9. Dan Shields 3 1 4 2 - 10. Peter Lemenkov (@lemenkov) 3 1 2 2 - - All remaining contributors: James Stanley, Julián Moreno - Patiño. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Mar 2015 - Jul 2025 - 2. Nick Altmann (@nikbyte) May 2021 - Feb 2025 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2017 - Apr 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2017 - Nov 2023 - 5. Vlad Paiu (@vladpaiu) Mar 2015 - Oct 2023 - 6. James Stanley Mar 2023 - Mar 2023 - 7. Liviu Chircu (@liviuchircu) Mar 2015 - Apr 2022 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - Oct 2021 - 9. Dan Shields Aug 2021 - Aug 2021 - 10. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Julián Moreno Patiño. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita - (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_ws/README.md b/modules/proto_ws/README.md new file mode 100644 index 00000000000..d7eee38cbed --- /dev/null +++ b/modules/proto_ws/README.md @@ -0,0 +1,296 @@ +--- +title: "proto_ws Module" +description: "The WebSocket protocol ([RFC 6455](http://tools.ietf.org/html/rfc6455)) provides an end-to-end full-duplex communication channel between two web-based applications." +--- + +## Admin Guide + + +### Overview + + +The WebSocket protocol ([RFC 6455](http://tools.ietf.org/html/rfc6455)) +provides an end-to-end full-duplex communication channel between two web-based applications. +This allows WebSocket enabled browsers to connect to a WebSocket server +and exchange any type of data. +[RFC 7118](http://tools.ietf.org/html/rfc7118) +provides the specifications for transporting SIP messages over the WebSocket protocol. + + +The **proto_ws** module is transport module that provides +communication over the WebSocket protocol. This module is fully compliant with the +[RFC 7118](http://tools.ietf.org/html/rfc7118), thus allowing browsers +to act as SIP clients for the OpenSIPS proxy. + + +The current implementation acts both as WebSocket server and client, thus it can +accept connections from WebSocket clients and can also initiate connections to another +WebSocket server. After the connection is established, messages can flow in +both directions. + + +OpenSIPS supports the following WebSocket operations: + + +- text and binary - can both send and receive WebSocket messages that contain text or binary body +- close - messages used to safely close the WebSocket communication using a 2-messages handshake +- ping - responds with pong messages. There is no mechanism to trigger ping messages. +- pong - sent when a ping message is received. OpenSIPS, absorbes the pong messages received. + + +Once loaded, you will be able to define WebSocket listeners in your script. To +add a listener, you have to add its IP, and optionally the listening port, +*after* the `mpath` parameter, similar to this +example: + +```opensips +... +mpath=/path/to/modules +... +socket=ws:127.0.0.1 # change with the listening IP +socket=ws:127.0.0.1:5060 # change with the listening IP and port +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### ws_port (integer) + + +The default port to be used for all WS related operation. Be careful +as the default port impacts both the SIP listening part (if no port is +defined in the WS listeners) and the SIP sending part (if the +destination WS URI has no explicit port). + + +If you want to change only the listening port for WS, use the port +option in the SIP listener defintion. + + +*Default value is 80.* + + +```c title="Set ws_port parameter" +... +modparam("proto_ws", "ws_port", 8080) +... +``` + + +#### ws_send_timeout (integer) + + +Time in milliseconds after a WebSocket connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set ws_send_timeout parameter" +... +modparam("proto_ws", "ws_send_timeout", 200) +... +``` + + +#### ws_max_msg_chunks (integer) + + +The maximum number of chunks in which a SIP message is expected to +arrive via WebSocket. If a received packet is more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending very +fragmented traffic in order to decrease server performance). + + +*Default value is 4.* + + +```opensips title="Set ws_max_msg_chunks parameter" +... +modparam("proto_ws", "ws_max_msg_chunks", 8) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. +For each connection that is created an event containing information +about http request and reply belonging to web socket protocol +handshake and network layer information shall be sent. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("proto_ws", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for ws is on or not. You still need to define +[trace destination](#param_trace_destination)in order to work, but this value will be +controlled using mi function [mi ws trace](#mi_ws_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_ws", "trace_on", 1) +... +``` + + +#### trace_filter_route (string) + + +Define the name of a route in which you can filter which connections will +be trace and which connections won't be. In this route you will have +information regarding source and destination ips and ports for the current +connection. To disable tracing for a specific connection the last call in +this route must be **drop**, any other exit +mode resulting in tracing the current connection ( of course you still +have to define a [trace destination](#param_trace_destination) and trace must be +on at the time this connection is opened. + + +> [!IMPORTANT] +> Filtering on ip addresses and ports can be made using **$si** and **$sp** for matching +> either the entity that is connecting to OpenSIPS or the entity to which +> OpenSIPS is connecting. The name might be misleading (**$si** meaning the source ip if you read the docs) but in reality +> it is simply the socket other than the OpenSIPS socket. In order to match +> OpenSIPS interface (either the one that accepted the connection or the one +> that initiated a connection) **$socket_in(ip)** (ip) and +> **$socket_in(port)** (port) can be used. + + +> [!WARNING] +> If [trace on](#param_trace_on) is +> set to 0 or tracing is deactived via the mi command [mi trace](#mi_trace) +> this route won't be called. + + +```opensips title="Set trace_filter_route parameter" +... +modparam("proto_ws", "trace_filter_route", "ws_filter") +... +/* all ws connections will go through this route if tracing is activated + * and a trace destination is defined */ +route[ws_filter] { + ... + /* all connections opened from/by ip 1.1.1.1:8000 will be traced + on interface 1.1.1.10:5060(opensips listener) + all the other connections won't be */ + if ( $si == "1.1.1.1" && $sp == 8000 && + $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) + exit; + else + drop; +} +... +``` + + +#### require_origin (int) + + +Controls whether the module should require the Origin header or not. + + +```opensips title="Set require_origin parameter" +... +modparam("proto_ws", "require_origin", no) +... +``` + + +### Exported MI Functions + + +#### ws_trace + + +Name: *ws_trace* + + +Parameters: + + +- trace_mode(optional): set ws tracing on and off. This parameter +can be missing and the command will show the current tracing +status for this module( on or off ); +Possible values: + - on + - off + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi ws_trace on +``` + + +## Frequently Asked Questions + + +**Q: Can OpenSIPS act as a WebSocket client?** + + +Yes, starting with OpenSIPS 2.2, it can act as a WebSocket client. + + +**Q: Does OpenSIPS support WebSocket message fragmentation?** + + +No, WebSocket fragmentation mechanism is not supported. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_ws/doc/contributors.xml b/modules/proto_ws/doc/contributors.xml deleted file mode 100644 index 87c1a74002e..00000000000 --- a/modules/proto_ws/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 98 - 49 - 4086 - 827 - - - 2. - Ionut Ionita (@ionutrazvanionita) - 22 - 14 - 609 - 114 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 19 - 16 - 138 - 51 - - - 4. - Liviu Chircu (@liviuchircu) - 16 - 11 - 128 - 141 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 8 - 5 - 97 - 74 - - - 6. - Maksym Sobolyev (@sobomax) - 7 - 5 - 36 - 35 - - - 7. - Vlad Paiu (@vladpaiu) - 5 - 3 - 5 - 3 - - - 8. - Nick Altmann (@nikbyte) - 4 - 2 - 5 - 5 - - - 9. - Dan Shields - 3 - 1 - 4 - 2 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: James Stanley, Julián Moreno Patiño. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Mar 2015 - Jul 2025 - - - 2. - Nick Altmann (@nikbyte) - May 2021 - Feb 2025 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2017 - Apr 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2017 - Nov 2023 - - - 5. - Vlad Paiu (@vladpaiu) - Mar 2015 - Oct 2023 - - - 6. - James Stanley - Mar 2023 - Mar 2023 - - - 7. - Liviu Chircu (@liviuchircu) - Mar 2015 - Apr 2022 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Oct 2021 - - - 9. - Dan Shields - Aug 2021 - Aug 2021 - - - 10. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/proto_ws/doc/proto_ws.xml b/modules/proto_ws/doc/proto_ws.xml deleted file mode 100644 index 714a9060513..00000000000 --- a/modules/proto_ws/doc/proto_ws.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - proto_ws Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/proto_ws/doc/proto_ws_admin.xml b/modules/proto_ws/doc/proto_ws_admin.xml deleted file mode 100644 index 5b24ea1acb9..00000000000 --- a/modules/proto_ws/doc/proto_ws_admin.xml +++ /dev/null @@ -1,339 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The WebSocket protocol (RFC 6455) - provides an end-to-end full-duplex communication channel between two web-based applications. - This allows WebSocket enabled browsers to connect to a WebSocket server - and exchange any type of data. - RFC 7118 - provides the specifications for transporting SIP messages over the WebSocket protocol. - - - The proto_ws module is transport module that provides - communication over the WebSocket protocol. This module is fully compliant with the - RFC 7118, thus allowing browsers - to act as SIP clients for the &osips; proxy. - - - The current implementation acts both as WebSocket server and client, thus it can - accept connections from WebSocket clients and can also initiate connections to another - WebSocket server. After the connection is established, messages can flow in - both directions. - - &osips; supports the following WebSocket operations: - - - text and binary - can both send and receive WebSocket messages that contain text or binary body - - - close - messages used to safely close the WebSocket communication using a 2-messages handshake - - - ping - responds with pong messages. There is no mechanism to trigger ping messages. - - - pong - sent when a ping message is received. &osips;, absorbes the pong messages received. - - - - - Once loaded, you will be able to define WebSocket listeners in your script. To - add a listener, you have to add its IP, and optionally the listening port, - after the mpath parameter, similar to this - example: - - -... -mpath=/path/to/modules -... -socket=ws:127.0.0.1 # change with the listening IP -socket=ws:127.0.0.1:5060 # change with the listening IP and port -... - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>ws_port</varname> (integer) - - The default port to be used for all WS related operation. Be careful - as the default port impacts both the SIP listening part (if no port is - defined in the WS listeners) and the SIP sending part (if the - destination WS URI has no explicit port). - - - If you want to change only the listening port for WS, use the port - option in the SIP listener defintion. - - - - Default value is 80. - - - - Set <varname>ws_port</varname> parameter - -... -modparam("proto_ws", "ws_port", 8080) -... - - -
- -
- <varname>ws_send_timeout</varname> (integer) - - Time in milliseconds after a WebSocket connection will be closed if it is - not available for blocking writing in this interval (and &osips; wants - to send something on it). - - - - Default value is 100 ms. - - - - Set <varname>ws_send_timeout</varname> parameter - -... -modparam("proto_ws", "ws_send_timeout", 200) -... - - -
-
- <varname>ws_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a SIP message is expected to - arrive via WebSocket. If a received packet is more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - - - Default value is 4. - - - - Set <varname>ws_max_msg_chunks</varname> parameter - -... -modparam("proto_ws", "ws_max_msg_chunks", 8) -... - - -
-
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - For each connection that is created an event containing information - about http request and reply belonging to web socket protocol - handshake and network layer information shall be sent. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_ws", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for ws is on or not. You still need to define - in order to work, but this value will be - controlled using mi function . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_ws", "trace_on", 1) -... - - -
- -
- <varname>trace_filter_route</varname> (string) - - Define the name of a route in which you can filter which connections will - be trace and which connections won't be. In this route you will have - information regarding source and destination ips and ports for the current - connection. To disable tracing for a specific connection the last call in - this route must be drop, any other exit - mode resulting in tracing the current connection ( of course you still - have to define a and trace must be - on at the time this connection is opened. - - - - IMPORTANT - Filtering on ip addresses and ports can be made using - $si and $sp for matching - either the entity that is connecting to &osips; or the entity to which - &osips; is connecting. The name might be misleading ( - $si meaning the source ip if you read the docs) but in reality - it is simply the socket other than the &osips; socket. In order to match - &osips; interface (either the one that accepted the connection or the one - that initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - - - WARNING: IF is - set to 0 or tracing is deactived via the mi command - this route won't be called. - - - Default value is none(no route is set). - - - Set <varname>trace_filter_route</varname> parameter - -... -modparam("proto_ws", "trace_filter_route", "ws_filter") -... -/* all ws connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[ws_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) - exit; - else - drop; -} -... - - -
-
- <varname>require_origin</varname> (int) - - Controls whether the module should require the Origin header or not. - - - Default value is 1(require Origin header). - - - Set <varname>require_origin</varname> parameter - -... -modparam("proto_ws", "require_origin", no) -... - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">ws_trace</function> - - - - - - - Name: ws_trace - - - Parameters: - - - trace_mode(optional): set ws tracing on and off. This parameter - can be missing and the command will show the current tracing - status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi ws_trace on - -
-
- -
diff --git a/modules/proto_ws/doc/proto_ws_faq.xml b/modules/proto_ws/doc/proto_ws_faq.xml deleted file mode 100644 index ee98180f9e8..00000000000 --- a/modules/proto_ws/doc/proto_ws_faq.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - &faqguide; - - - - - Can &osips; act as a WebSocket client? - - - - - Yes, starting with &osips; 2.2, it can act as a WebSocket client. - - - - - - - Does &osips; support WebSocket message fragmentation? - - - - - No, WebSocket fragmentation mechanism is not supported. - - - - - - diff --git a/modules/proto_ws/ws_handshake_common.h b/modules/proto_ws/ws_handshake_common.h index 64d485eaf9a..55720f546f1 100644 --- a/modules/proto_ws/ws_handshake_common.h +++ b/modules/proto_ws/ws_handshake_common.h @@ -1618,6 +1618,13 @@ static int ws_read_http(struct tcp_connection *c, struct tcp_req *r) case '8': case '9': r->content_len=r->content_len*10+(*p-'0'); + if (r->content_len>=TCP_BUF_SIZE) { + LM_ERR("Content-Length value %d bigger than the " + "reading buffer\n", r->content_len); + r->error = TCP_REQ_BAD_LEN; + r->state = H_SKIP; + r->content_len = 0; + } break; case '\r': case ' ': diff --git a/modules/proto_wss/README b/modules/proto_wss/README deleted file mode 100644 index 29111fc9563..00000000000 --- a/modules/proto_wss/README +++ /dev/null @@ -1,426 +0,0 @@ -proto_wss Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. Dependencies of external libraries - - 1.3. Exported Parameters - - 1.3.1. listen=interface - 1.3.2. wss_port (integer) - 1.3.3. wss_max_msg_chunks (integer) - 1.3.4. wss_resource (string) - 1.3.5. wss_handshake_timeout (integer) - 1.3.6. cert_check_on_conn_reusage (integer) - 1.3.7. trace_destination (string) - 1.3.8. trace_on (int) - 1.3.9. trace_filter_route (string) - 1.3.10. wss_tls_handshake_timeout (integer) - 1.3.11. wss_send_timeout (integer) - 1.3.12. require_origin (int) - - 1.4. Exported MI Functions - - 1.4.1. wss_trace - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set listen variable - 1.2. Set wss_port variable - 1.3. Set wss_max_msg_chunks parameter - 1.4. Set wss_resource parameter - 1.5. Set wss_handshake_timeout parameter - 1.6. Set cert_check_on_conn_reusage parameter - 1.7. Set trace_destination parameter - 1.8. Set trace_on parameter - 1.9. Set trace_filter_route parameter - 1.10. Set wss_tls_handshake_timeout variable - 1.11. Set wss_send_timeout variable - 1.12. Set require_origin parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The WSS (Secure WebSocket) module provides the ability to - communicate with a WebSocket (RFC 6455) client or server over a - secure (TLS encrypted) channel. As part of the WebRTC - specifications, this protocol can be used to provide secure - VoIP calls to HTTPS enabled browsers. - - This module behaves as any other transport protocol module: in - order to use it, you must define one or more listeners that - will handle the secure WebSocket traffic, after the mpath - parameter: - -... -mpath=/path/to/modules -... -socket=wss:10.0.0.1 # change with the listening IP -socket=wss:10.0.0.1:5060 # change with the listening IP and port -... - - Besides that, you need to define the TLS parameters for - securing the connection. This is done through the tls_mgm - module interface, similar to the proto_tls module: - -modparam("tls_mgm", "certificate", "/certs/biloxy.com/cert.pem") -modparam("tls_mgm", "private_key", "/certs/biloxy.com/privkey.pem") -modparam("tls_mgm", "ca_list", "/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "tlsv1") -modparam("tls_mgm", "verify_cert", "1") -modparam("tls_mgm", "require_cert", "1") - - Check the tls_mgm module documentation for more info. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_openssl or tls_wolfssl, depending on the desired TLS - library - * tls_mgm. - -1.2.2. Dependencies of external libraries - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - - All these parameters can be used from the opensips.cfg file, to - configure the behavior of OpenSIPS-WSS. - -1.3.1. listen=interface - - This is a global parameter that specifies what interface/IP and - port should handle WSS traffic. - - Example 1.1. Set listen variable -... -socket= wss:1.2.3.4:44344 -... - -1.3.2. wss_port (integer) - - The default port to be used for all WSS related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the WSS listeners) and the SIP - sending part (if the destination WSS URI has no explicit port). - - If you want to change only the listening port for WSS, use the - port option in the SIP listener defintion. - - Default value is 443. - - Example 1.2. Set wss_port variable -... -modparam("proto_wss", "wss_port", 44344) -... - -1.3.3. wss_max_msg_chunks (integer) - - The maximum number of chunks in which a SIP message is expected - to arrive via WSS. If a received packet is more fragmented than - this, the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - Default value is 4. - - Example 1.3. Set wss_max_msg_chunks parameter -... -modparam("proto_wss", "wss_max_msg_chunks", 8) -... - -1.3.4. wss_resource (string) - - The resource queried for when a WebSocket handshake is - initiated. - - Default value is “/”. - - Example 1.4. Set wss_resource parameter -... -modparam("proto_wss", "wss_resource", "/wss") -... - -1.3.5. wss_handshake_timeout (integer) - - This parameter specifies the time in milliseconds the proto_wss - module waits for a WebSocket handshake reply from a WebSocket - server. - - Default value is 100. - - Example 1.5. Set wss_handshake_timeout parameter -... -modparam("proto_wss", "wss_handshake_timeout", 300) -... - -1.3.6. cert_check_on_conn_reusage (integer) - - This parameter turns on or off the extra checking/matching of - the TLS domain (SSL certificate) when comes to reusing an - existing TLS connection. Without this extra check, only IP and - port of the connections will be check (in order to re-use an - existing connection). With this extra check, the connection to - be reused must have the same SSL certificate as the one set for - the current signaling operation. - - This checking is done only when comes to send SIP traffic via - TLS and it is applied only against connections that were - created / initiated by OpenSIPS (as TLS client). Any accepte - connection (as TLS server) will automatically match (the extra - test will be skipped). - - Default value is 0 (disabled). - - Example 1.6. Set cert_check_on_conn_reusage parameter -... -modparam("proto_wss", "cert_check_on_conn_reusage", 1) -... - -1.3.7. trace_destination (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. Network events such as - connect, accept and connection closed events shall be traced - along with errors that could appear in the process. For each - connection that is created an event containing information - about the client and server certificate, master key, http - request and reply belonging to web socket protocol handshake - and network layer information shall be sent. - - WARNING: A tracing module must be loaded in order for this - parameter to work. (for example proto_hep). - - Default value is none(not defined). - - Example 1.7. Set trace_destination parameter -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;versio -n=3") - -modparam("proto_wss", "trace_destination", "hep_dest") -... - -1.3.8. trace_on (int) - - This controls whether tracing for wss is on or not. You still - need to define trace_destinationin order to work, but this - value will be controlled using mi function wss_trace. - Default value is 0(tracing inactive). - - Example 1.8. Set trace_on parameter -... -modparam("proto_wss", "trace_on", 1) -... - -1.3.9. trace_filter_route (string) - - Define the name of a route in which you can filter which - connections will be trace and which connections won't be. In - this route you will have information regarding source and - destination ips and ports for the current connection. To - disable tracing for a specific connection the last call in this - route must be drop, any other exit mode resulting in tracing - the current connection ( of course you still have to define a - trace_destination and trace must be on at the time this - connection is opened. - - IMPORTANT Filtering on ip addresses and ports can be made using - $si and $sp for matching either the entity that is connecting - to OpenSIPS or the entity to which OpenSIPS is connecting. The - name might be misleading ( $si meaning the source ip if you - read the docs) but in reality it is simply the socket other - than the OpenSIPS socket. In order to match OpenSIPS interface - (either the one that accepted the connection or the one that - initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - WARNING: IF trace_on is set to 0 or tracing is deactived via - the mi command wss_trace this route won't be called. - Default value is none(no route is set). - - Example 1.9. Set trace_filter_route parameter -... -modparam("proto_wss", "trace_filter_route", "wss_filter") -... -/* all wss connections will go through this route if tracing is activate -d - * and a trace destination is defined */ -route[wss_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 506 -0) - exit; - else - drop; -} -... - -1.3.10. wss_tls_handshake_timeout (integer) - - Sets the timeout (in milliseconds) for the SSL handshake - sequence to complete. It may be necessary to increase this - value when using a CPU intensive cipher for the connection to - allow time for keys to be generated and processed. - - The timeout is invoked during acceptance of a new connection - (inbound) and during the wait period when a new session is - being initiated (outbound). - - Default value is 100. - - Example 1.10. Set wss_tls_handshake_timeout variable - -param("proto_wss", "wss_tls_handshake_timeout", 200) # number of millise -conds - - -1.3.11. wss_send_timeout (integer) - - Sets the timeout (in milliseconds) for the send operations to - complete - - The send timeout is invoked for all TLS write operations, - excluding the handshake process (see: - wss_tls_handshake_timeout) - - Default value is 100. - - Example 1.11. Set wss_send_timeout variable - -modparam("proto_wss", "wss_send_timeout", 200) # number of milliseconds - - -1.3.12. require_origin (int) - - Controls whether the module should require the Origin header or - not. - Default value is 1(require Origin header). - - Example 1.12. Set require_origin parameter - -modparam("proto_wss", "require_origin", no) - - -1.4. Exported MI Functions - -1.4.1. wss_trace - - Name: wss_trace - - Parameters: - * trace_mode(optional): set wss tracing on and off. This - parameter can be missing and the command will show the - current tracing status for this module( on or off ); - Possible values: - + on - + off - - MI FIFO Command Format: - opensips-cli -x mi wss_trace on - -Chapter 2. Frequently Asked Questions - - 2.1. - - Does OpenSIPS support fragmented Secure WebSocket messages? - - No, the WebSocket fragmentation mechanism is not supported. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 34 24 786 126 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 19 15 243 27 - 3. Vlad Patrascu (@rvlad-patrascu) 17 13 131 113 - 4. Ionut Ionita (@ionutrazvanionita) 15 10 362 19 - 5. Liviu Chircu (@liviuchircu) 10 8 48 59 - 6. Maksym Sobolyev (@sobomax) 6 4 17 33 - 7. Dan Pascu (@danpascu) 3 1 3 5 - 8. Nick Altmann (@nikbyte) 3 1 2 2 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jan 2016 - Jul 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2017 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2016 - May 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2016 - Apr 2022 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Oct 2021 - 6. Nick Altmann (@nikbyte) May 2021 - May 2021 - 7. Dan Pascu (@danpascu) Jan 2020 - Jan 2020 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Ionut Ionita (@ionutrazvanionita) Mar 2017 - Apr 2017 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita - (@ionutrazvanionita). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com diff --git a/modules/proto_wss/README.md b/modules/proto_wss/README.md new file mode 100644 index 00000000000..184ffcd5e0e --- /dev/null +++ b/modules/proto_wss/README.md @@ -0,0 +1,379 @@ +--- +title: "proto_wss Module" +description: "The WSS (Secure WebSocket) module provides the ability to communicate with a WebSocket ([RFC 6455](http://tools.ietf.org/html/rfc6455)) client or server over a secure (TLS encrypted) channel." +--- + +## Admin Guide + + +### Overview + + +The WSS (Secure WebSocket) module provides the ability to communicate with +a WebSocket ([RFC +6455](http://tools.ietf.org/html/rfc6455)) client or server over a secure (TLS encrypted) channel. +As part of the [WebRTC](https://webrtc.org/) +specifications, this protocol can be used to provide secure VoIP calls to +HTTPS enabled browsers. + + +This module behaves as any other transport protocol module: in order to +use it, you must define one or more listeners that will handle the secure +WebSocket traffic, *after* the `mpath` +parameter: + +```opensips +... +mpath=/path/to/modules +... +socket=wss:10.0.0.1 # change with the listening IP +socket=wss:10.0.0.1:5060 # change with the listening IP and port +... +``` + +Besides that, you need to define the TLS parameters for securing the connection. This is done through the *tls_mgm* module interface, similar to the *proto_tls* module: + +```opensips +modparam("tls_mgm", "certificate", "/certs/biloxy.com/cert.pem") +modparam("tls_mgm", "private_key", "/certs/biloxy.com/privkey.pem") +modparam("tls_mgm", "ca_list", "/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "tlsv1") +modparam("tls_mgm", "verify_cert", "1") +modparam("tls_mgm", "require_cert", "1") +``` +Check the *tls_mgm* module documentation for more info. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_openssl* or *tls_wolfssl*, +depending on the desired TLS library +- *tls_mgm*. + + +#### Dependencies of external libraries + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +All these parameters can be used from the opensips.cfg file, +to configure the behavior of OpenSIPS-WSS. + + +#### listen=interface + + +This is a global parameter that specifies what interface/IP and +port should handle WSS traffic. + + +```opensips title="Set listen variable" +... +socket= wss:1.2.3.4:44344 +... +``` + + +#### wss_port (integer) + + +The default port to be used for all WSS related operation. Be +careful as the default port impacts both the SIP listening part +(if no port is defined in the WSS listeners) and the SIP sending +part (if the destination WSS URI has no explicit port). + + +If you want to change only the listening port for WSS, use the port +option in the SIP listener defintion. + + +*Default value is 443.* + + +```opensips title="Set wss_port variable" +... +modparam("proto_wss", "wss_port", 44344) +... +``` + + +#### wss_max_msg_chunks (integer) + + +The maximum number of chunks in which a SIP message is expected to +arrive via WSS. If a received packet is more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending very +fragmented traffic in order to decrease server performance). + + +*Default value is 4.* + + +```opensips title="Set wss_max_msg_chunks parameter" +... +modparam("proto_wss", "wss_max_msg_chunks", 8) +... +``` + + +#### wss_resource (string) + + +The resource queried for when a WebSocket handshake is initiated. + + +*Default value is "/".* + + +```opensips title="Set wss_resource parameter" +... +modparam("proto_wss", "wss_resource", "/wss") +... +``` + + +#### wss_handshake_timeout (integer) + + +This parameter specifies the time in milliseconds the proto_wss module +waits for a WebSocket handshake reply from a WebSocket server. + + +*Default value is 100.* + + +```opensips title="Set wss_handshake_timeout parameter" +... +modparam("proto_wss", "wss_handshake_timeout", 300) +... +``` + + +#### cert_check_on_conn_reusage (integer) + + +This parameter turns on or off the extra checking/matching of the +TLS domain (SSL certificate) when comes to reusing an existing TLS +connection. Without this extra check, only IP and port of the +connections will be check (in order to re-use an existing connection). +With this extra check, the connection to be reused must have the same +SSL certificate as the one set for the current signaling operation. + + +This checking is done only when comes to send SIP traffic via TLS and +it is applied only against connections that were created / initiated +by OpenSIPS (as TLS client). Any accepte connection (as TLS server) will +automatically match (the extra test will be skipped). + + +*Default value is 0 (disabled).* + + +```opensips title="Set cert_check_on_conn_reusage parameter" +... +modparam("proto_wss", "cert_check_on_conn_reusage", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. +For each connection that is created an event containing information +about the client and server certificate, master key, http request and +reply belonging to web socket protocol handshake and network layer +information shall be sent. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") +modparam("proto_wss", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for wss is on or not. You still need to define +[trace destination](#param_trace_destination)in order to work, but this value will be +controlled using mi function [mi wss trace](#mi_wss_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_wss", "trace_on", 1) +... +``` + + +#### trace_filter_route (string) + + +Define the name of a route in which you can filter which connections will +be trace and which connections won't be. In this route you will have +information regarding source and destination ips and ports for the current +connection. To disable tracing for a specific connection the last call in +this route must be **drop**, any other exit +mode resulting in tracing the current connection ( of course you still +have to define a [trace destination](#param_trace_destination) and trace must be +on at the time this connection is opened. + + +> [!IMPORTANT] +> Filtering on ip addresses and ports can be made using **$si** and **$sp** for matching +> either the entity that is connecting to OpenSIPS or the entity to which +> OpenSIPS is connecting. The name might be misleading (**$si** meaning the source ip if you read the docs) but in reality +> it is simply the socket other than the OpenSIPS socket. In order to match +> OpenSIPS interface (either the one that accepted the connection or the one +> that initiated a connection) **$socket_in(ip)** (ip) and +> **$socket_in(port)** (port) can be used. + + +> [!WARNING] +> If [trace on](#param_trace_on) is +> set to 0 or tracing is deactived via the mi command [mi trace](#mi_trace) +> this route won't be called. + + +```opensips title="Set trace_filter_route parameter" +... +modparam("proto_wss", "trace_filter_route", "wss_filter") +... +/* all wss connections will go through this route if tracing is activated + * and a trace destination is defined */ +route[wss_filter] { + ... + /* all connections opened from/by ip 1.1.1.1:8000 will be traced + on interface 1.1.1.10:5060(opensips listener) + all the other connections won't be */ + if ( $si == "1.1.1.1" && $sp == 8000 && + $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) + exit; + else + drop; +} +... +``` + + +#### wss_tls_handshake_timeout (integer) + + +Sets the timeout (in milliseconds) for the SSL handshake sequence to complete. +It may be necessary to increase this value when using a CPU intensive cipher +for the connection to allow time for keys to be generated and processed. + + +The timeout is invoked during acceptance of a new connection (inbound) and +during the wait period when a new session is being initiated (outbound). + + +*Default value is 100.* + + +```opensips title="Set wss_tls_handshake_timeout variable" +param("proto_wss", "wss_tls_handshake_timeout", 200) # number of milliseconds +``` + + +#### wss_send_timeout (integer) + + +Sets the timeout (in milliseconds) for the send operations to complete + + +The send timeout is invoked for all TLS write operations, excluding +the handshake process (see: wss_tls_handshake_timeout) + + +*Default value is 100.* + + +```opensips title="Set wss_send_timeout variable" +modparam("proto_wss", "wss_send_timeout", 200) # number of milliseconds +``` + + +#### require_origin (int) + + +Controls whether the module should require the Origin header or not. + + +```opensips title="Set require_origin parameter" +modparam("proto_wss", "require_origin", no) +``` + + +### Exported MI Functions + + +#### wss_trace + + +Name: *wss_trace* + + +Parameters: + + +- trace_mode(optional): set wss tracing on and off. This parameter +can be missing and the command will show the current tracing +status for this module( on or off ); +Possible values: + - on + - off + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi wss_trace on +``` + + +## Frequently Asked Questions + + +**Q: Does OpenSIPS support fragmented Secure WebSocket messages?** + + +No, the WebSocket fragmentation mechanism is not supported. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/proto_wss/doc/contributors.xml b/modules/proto_wss/doc/contributors.xml deleted file mode 100644 index ac443eae75c..00000000000 --- a/modules/proto_wss/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 34 - 24 - 786 - 126 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 19 - 15 - 243 - 27 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 17 - 13 - 131 - 113 - - - 4. - Ionut Ionita (@ionutrazvanionita) - 15 - 10 - 362 - 19 - - - 5. - Liviu Chircu (@liviuchircu) - 10 - 8 - 48 - 59 - - - 6. - Maksym Sobolyev (@sobomax) - 6 - 4 - 17 - 33 - - - 7. - Dan Pascu (@danpascu) - 3 - 1 - 3 - 5 - - - 8. - Nick Altmann (@nikbyte) - 3 - 1 - 2 - 2 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jan 2016 - Jul 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2017 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2016 - May 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2016 - Apr 2022 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Oct 2021 - - - 6. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 7. - Dan Pascu (@danpascu) - Jan 2020 - Jan 2020 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Mar 2017 - Apr 2017 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ionut Ionita (@ionutrazvanionita). -
- -
diff --git a/modules/proto_wss/doc/proto_wss.xml b/modules/proto_wss/doc/proto_wss.xml deleted file mode 100644 index 2bbe7195ae3..00000000000 --- a/modules/proto_wss/doc/proto_wss.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - proto_wss Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/proto_wss/doc/proto_wss_admin.xml b/modules/proto_wss/doc/proto_wss_admin.xml deleted file mode 100644 index 4f6bc9054b2..00000000000 --- a/modules/proto_wss/doc/proto_wss_admin.xml +++ /dev/null @@ -1,444 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The WSS (Secure WebSocket) module provides the ability to communicate with - a WebSocket (RFC - 6455) client or server over a secure (TLS encrypted) channel. - As part of the WebRTC - specifications, this protocol can be used to provide secure VoIP calls to - HTTPS enabled browsers. - - - This module behaves as any other transport protocol module: in order to - use it, you must define one or more listeners that will handle the secure - WebSocket traffic, after the mpath - parameter: - - -... -mpath=/path/to/modules -... -socket=wss:10.0.0.1 # change with the listening IP -socket=wss:10.0.0.1:5060 # change with the listening IP and port -... - - - Besides that, you need to define the TLS parameters for securing the connection. This is done through the tls_mgm module interface, similar to the proto_tls module: - - -modparam("tls_mgm", "certificate", "/certs/biloxy.com/cert.pem") -modparam("tls_mgm", "private_key", "/certs/biloxy.com/privkey.pem") -modparam("tls_mgm", "ca_list", "/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "tlsv1") -modparam("tls_mgm", "verify_cert", "1") -modparam("tls_mgm", "require_cert", "1") - - - Check the tls_mgm module documentation for more info. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_openssl or tls_wolfssl, - depending on the desired TLS library - - - - - tls_mgm. - - - - -
-
- Dependencies of external libraries - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - - All these parameters can be used from the opensips.cfg file, - to configure the behavior of &osips;-WSS. - - -
- <varname>listen</varname>=interface - - This is a global parameter that specifies what interface/IP and - port should handle WSS traffic. - - - Set <varname>listen</varname> variable - -... -socket= wss:1.2.3.4:44344 -... - - -
- -
- <varname>wss_port</varname> (integer) - - The default port to be used for all WSS related operation. Be - careful as the default port impacts both the SIP listening part - (if no port is defined in the WSS listeners) and the SIP sending - part (if the destination WSS URI has no explicit port). - - - If you want to change only the listening port for WSS, use the port - option in the SIP listener defintion. - - - Default value is 443. - - - Set <varname>wss_port</varname> variable - -... -modparam("proto_wss", "wss_port", 44344) -... - - -
- -
- <varname>wss_max_msg_chunks</varname> (integer) - - The maximum number of chunks in which a SIP message is expected to - arrive via WSS. If a received packet is more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending very - fragmented traffic in order to decrease server performance). - - - - Default value is 4. - - - - Set <varname>wss_max_msg_chunks</varname> parameter - -... -modparam("proto_wss", "wss_max_msg_chunks", 8) -... - - -
- -
- <varname>wss_resource</varname> (string) - - The resource queried for when a WebSocket handshake is initiated. - - - - Default value is /. - - - - Set <varname>wss_resource</varname> parameter - -... -modparam("proto_wss", "wss_resource", "/wss") -... - - -
-
- <varname>wss_handshake_timeout</varname> (integer) - - This parameter specifies the time in milliseconds the proto_wss module - waits for a WebSocket handshake reply from a WebSocket server. - - - - Default value is 100. - - - - Set <varname>wss_handshake_timeout</varname> parameter - -... -modparam("proto_wss", "wss_handshake_timeout", 300) -... - - -
- -
- <varname>cert_check_on_conn_reusage</varname> (integer) - - This parameter turns on or off the extra checking/matching of the - TLS domain (SSL certificate) when comes to reusing an existing TLS - connection. Without this extra check, only IP and port of the - connections will be check (in order to re-use an existing connection). - With this extra check, the connection to be reused must have the same - SSL certificate as the one set for the current signaling operation. - - - This checking is done only when comes to send SIP traffic via TLS and - it is applied only against connections that were created / initiated - by OpenSIPS (as TLS client). Any accepte connection (as TLS server) will - automatically match (the extra test will be skipped). - - - - Default value is 0 (disabled). - - - - Set <varname>cert_check_on_conn_reusage</varname> parameter - -... -modparam("proto_wss", "cert_check_on_conn_reusage", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - For each connection that is created an event containing information - about the client and server certificate, master key, http request and - reply belonging to web socket protocol handshake and network layer - information shall be sent. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_wss", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for wss is on or not. You still need to define - in order to work, but this value will be - controlled using mi function . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_wss", "trace_on", 1) -... - - -
- -
- <varname>trace_filter_route</varname> (string) - - Define the name of a route in which you can filter which connections will - be trace and which connections won't be. In this route you will have - information regarding source and destination ips and ports for the current - connection. To disable tracing for a specific connection the last call in - this route must be drop, any other exit - mode resulting in tracing the current connection ( of course you still - have to define a and trace must be - on at the time this connection is opened. - - - IMPORTANT - Filtering on ip addresses and ports can be made using - $si and $sp for matching - either the entity that is connecting to &osips; or the entity to which - &osips; is connecting. The name might be misleading ( - $si meaning the source ip if you read the docs) but in reality - it is simply the socket other than the &osips; socket. In order to match - &osips; interface (either the one that accepted the connection or the one - that initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - - - WARNING: IF is - set to 0 or tracing is deactived via the mi command - this route won't be called. - - - Default value is none(no route is set). - - - Set <varname>trace_filter_route</varname> parameter - -... -modparam("proto_wss", "trace_filter_route", "wss_filter") -... -/* all wss connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[wss_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) - exit; - else - drop; -} -... - - -
- -
- <varname>wss_tls_handshake_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the SSL handshake sequence to complete. - It may be necessary to increase this value when using a CPU intensive cipher - for the connection to allow time for keys to be generated and processed. - - - The timeout is invoked during acceptance of a new connection (inbound) and - during the wait period when a new session is being initiated (outbound). - - - Default value is 100. - - - Set <varname>wss_tls_handshake_timeout</varname> variable - - -param("proto_wss", "wss_tls_handshake_timeout", 200) # number of milliseconds - - - -
- -
- <varname>wss_send_timeout</varname> (integer) - - Sets the timeout (in milliseconds) for the send operations to complete - - - The send timeout is invoked for all TLS write operations, excluding - the handshake process (see: wss_tls_handshake_timeout) - - - Default value is 100. - - - Set <varname>wss_send_timeout</varname> variable - - -modparam("proto_wss", "wss_send_timeout", 200) # number of milliseconds - - - -
- -
- <varname>require_origin</varname> (int) - - Controls whether the module should require the Origin header or not. - - - Default value is 1(require Origin header). - - - Set <varname>require_origin</varname> parameter - - -modparam("proto_wss", "require_origin", no) - - - -
-
- - -
- Exported MI Functions - -
- - <function moreinfo="none">wss_trace</function> - - - - - - - Name: wss_trace - - - Parameters: - - - trace_mode(optional): set wss tracing on and off. This parameter - can be missing and the command will show the current tracing - status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi wss_trace on - -
-
- -
diff --git a/modules/proto_wss/doc/proto_wss_faq.xml b/modules/proto_wss/doc/proto_wss_faq.xml deleted file mode 100644 index 67576dabcbf..00000000000 --- a/modules/proto_wss/doc/proto_wss_faq.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - &faqguide; - - - - - Does &osips; support fragmented Secure WebSocket messages? - - - - - No, the WebSocket fragmentation mechanism is not supported. - - - - - - diff --git a/modules/proto_wss/proto_wss.c b/modules/proto_wss/proto_wss.c index 569ef43d717..aea43793b95 100644 --- a/modules/proto_wss/proto_wss.c +++ b/modules/proto_wss/proto_wss.c @@ -304,6 +304,8 @@ static int wss_conn_init(struct tcp_connection* c) if (!dom) { LM_ERR("no TLS %s domain found\n", (c->flags&F_CONN_ACCEPTED?"server":"client")); + c->proto_data = NULL; + shm_free(d); return -1; } diff --git a/modules/pua/README b/modules/pua/README deleted file mode 100644 index 54eecac23c6..00000000000 --- a/modules/pua/README +++ /dev/null @@ -1,592 +0,0 @@ -Presence User Agent Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. PUA clustering - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. hash_size (int) - 1.4.2. db_url (str) - 1.4.3. db_table (str) - 1.4.4. min_expires (int) - 1.4.5. default_expires (int) - 1.4.6. update_period (int) - 1.4.7. cluster_id (int) - 1.4.8. cluster_sharing_tag (int) - - 1.5. Exported Functions - - 1.5.1. pua_update_contact() - - 1.6. Installation - - 2. Developer Guide - - 2.1. bind_pua(pua_api_t* api) - 2.2. send_publish - 2.3. send_subscribe - 2.4. is_dialog - 2.5. register_puacb - 2.6. add_event - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hash_size parameter - 1.2. Set db_url parameter - 1.3. Set db_table parameter - 1.4. Set min_expires parameter - 1.5. Set default_expires parameter - 1.6. Set update_period parameter - 1.7. Set cluster_id parameter - 1.8. Set cluster_sharing_tag parameter - 1.9. pua_update_contact usage - 2.1. pua_api structure - 2.2. pua_is_dialog usage example - 2.3. register_puacb usage example - 2.4. add_event usage example - -Chapter 1. Admin Guide - -1.1. Overview - - This module offer the internal support for OpenSIPS to act as a - Presence User Agent client, by sending Subscribe and Publish - messages. - - Note that the module does NOT provide any functionality to be - used directly from the script, but it is providing this PUA - client support (via an internal API) for other event-specific - modules to do PUA client operations. - - Some of modules build on top of the PUA module are pua_mi, - pua_usrloc, pua_dialoginfo, pua_bla and pua_xmpp. The pua_mi - offer the possibility to publish any kind of information or - subscribing to a resource through fifo. The pua_usrloc module - calls a function exported by pua modules to publish elementary - presence information, such as basic status "open" or "closed", - for clients that do not implement client-to-server presence. - The pua_dialoginfo provideds BLF support, by publishing the - status of the participants into a call (like ringing, - established, terminated). Through pua_bla , BRIDGED LINE - APPEARANCE features are added to OpenSIPs. The pua_xmpp module - represents a gateway between SIP and XMPP, so that jabber and - SIP clients can exchange presence information. - - The module use cache to store presentity list and writes to - database on timer to be able to recover upon restart. - - Notice: This module must not be used in no fork mode (the - locking mechanism used may cause deadlock in no fork mode). - -1.2. PUA clustering - - Starting 3.2, the module was extended with clustering support - also. This means multiple OpenSIPS instance, configured with - PUA module, may work together. For example, the publishing for - a certain presentity may be done via different node (PUA - OpenSIPS instance) in the cluster. - - The clustering support is a mixture of DB sharing and OpenSIPS - clustering. The OpenSIPS clustering layer is used for - broadcasting notifications with the cluster when a presentity - is modified by one of the nodes (so that, the other nodes in - cluster may refresh the presentity via DB. - - The shared DB is used by sharing between the nodes the actual - presentity data. A node caches into memory only the - presentities created by the node or the presentitites the node - worked with. A presentity record may be loaded into memory - (from DB) if the node needs to perform an operation with that - presentity. - - IMPORTANT: because the actual presentity data is shared between - the nodes via DB (the clustering layer is used for - notifications only), it is important to set a very low update - interval for the DB (for data being flushed from memoryc cache - into DB), to get the DB content updated as realtime as - possible. See the the update_period, module parameter, with - recomanded values like 2-5 seconds. - - On the OpenSIPS clustering layer, the PUA module use the - sharing-tags mechanism in order to control (between all the - nodes in the cluster) which node is responsible for performing - the expiring operation on the presentity (like sending the - PUBLISH with expires 0). - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database modules. - * tm. - * clusterer, if the cluster_id module parameter is set and - clustering support activated. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml. - -1.4. Exported Parameters - -1.4.1. hash_size (int) - - The size of the hash table used for storing Subscribe and - Publish information. This parameter will be used as the power - of 2 when computing table size. - - Default value is “9”. - - Example 1.1. Set hash_size parameter -... -modparam("pua", "hash_size", 11) -... - -1.4.2. db_url (str) - - Database url. - - Default value is - “>mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.2. Set db_url parameter -... -modparam("pua", "db_url" "dbdriver://username:password@dbhost/dbname") -... - -1.4.3. db_table (str) - - The name of the database table. - - Default value is “pua”. - - Example 1.3. Set db_table parameter -... -modparam("pua", "db_table", "pua") -... - -1.4.4. min_expires (int) - - The inferior expires limit for both Publish and Subscribe. - - Default value is “300”. - - Example 1.4. Set min_expires parameter -... -modparam("pua", "min_expires", 0) -... - -1.4.5. default_expires (int) - - The default expires value used in case this information is not - provisioned. - - Default value is “3600”. - - Example 1.5. Set default_expires parameter -... -modparam("pua", "default_expires", 3600) -... - -1.4.6. update_period (int) - - The interval at which the information in database and hash - table should be updated. In the case of the hash table updating - is deleting expired messages. - - Default value is “30”. - - IMPORTANT - if you use clustering support for this module, set - a low value here, like 2-5, see the clustering chapter above. - - Example 1.6. Set update_period parameter -... -modparam("pua", "update_period", 100) -... - -1.4.7. cluster_id (int) - - The cluster ID where the PUA data should be replicated/shared. - This parameter is to be used only if clustering mode is needed. - In order to understand the concept of a cluster ID, please see - the clusterer module. - - For more on PUA clustering see the Section 1.2, “PUA - clustering” chapter. - - Default value is “None”. - - Example 1.7. Set cluster_id parameter -... -modparam("pua", "cluster_id", 10) -... - -1.4.8. cluster_sharing_tag (int) - - The clustering share-tag to be used by the PUA module when - creating any new presentity record. The tag will by used to - decide which OpenSIPS instance (owning the tag as active) will - be responsible for expiring this presentity. This parameter is - to be used only if clustering mode is needed. In order to - understand the concept of sharing TAG, please see the clusterer - module. - - For more on PUA clustering see the Section 1.2, “PUA - clustering” chapter. - - Default value is “NULL”. - - Example 1.8. Set cluster_sharing_tag parameter -... -modparam("pua", "cluster_sharing_tag", "vip") -... - -1.5. Exported Functions - -1.5.1. pua_update_contact() - - The remote target can be updated by the Contact of a subsequent - in dialog request. In the PUA watcher case (sending a SUBSCRIBE - messages), this means that the remote target for the following - Subscribe messages can be updated at any time by the contact of - a Notify message. If this function is called on request route - on receiving a Notify message, it will try to update the stored - remote target. - - This function can be used from REQUEST_ROUTE. - - Return code: - * 1 - if success. - * -1 - if error. - - Example 1.9. pua_update_contact usage -... -if($rm=="NOTIFY") - pua_update_contact(); -... - -1.6. Installation - - The module requires 1 table in OpenSIPS database: pua. The SQL - syntax to create it can be found in presence_xml-create.sql - script in the database directories in the opensips/scripts - folder. You can also find the complete database documentation - on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer Guide - - The module provides the following functions that can be used in - other OpenSIPS modules. - -2.1. bind_pua(pua_api_t* api) - - This function binds the pua modules and fills the structure - with the two exported function. - - Example 2.1. pua_api structure -... -typedef struct pua_api { - send_subscribe_t send_subscribe; - send_publish_t send_publish; - query_dialog_t is_dialog; - register_puacb_t register_puacb; - add_pua_event_t add_event; -} pua_api_t; -... - -2.2. send_publish - - Field type: -... -typedef int (*send_publish_t)(publ_info_t* publ); -... - - This function receives as a parameter a structure with Publish - required information and sends a Publish message. - - The structure received as a parameter: -... -typedef struct publ_info - - str id; /* (optional )a value unique for one combination - of pres_uri and flag */ - str* pres_uri; /* the presentity uri */ - str* body; /* the body of the Publish message; - can be NULL in case of an update expires*/ - int expires; /* the expires value that will be used in - Publish Expires header*/ - int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE - if missing it will be established according - to the result of the search in hash table*/ - int source_flag; /* flag identifying the resource ; - supported values: UL_PUBLISH, MI_PUBLISH, - BLA_PUBLISH, XMPP_PUBLISH*/ - int event; /* the event flag; - supported values: PRESENCE_EVENT, BLA_EVENT, - MWI_EVENT */ - str content_type; /* the content_type of the body if present - (optional if the same as the default value - for that event)*/ - str* etag; /* (optional) the value of the etag the request - should match */ - str* extra_headers /* (optional) extra_headers that should be added - to Publish msg*/ - publrpl_cb_t* cbrpl;/* callback function to be called when receiving - the reply for the sent request */ - void* cbparam; /* extra parameter for tha callback function */ - - str outbound_proxy; /* the outbound proxy to be used when sending - the Publish requ -est*/ - -}publ_info_t; -... - - The callback function type: -... -typedef int (publrpl_cb_t)(struct sip_msg* reply, void* extra_param); -... - -2.3. send_subscribe - - Field type: -... -typedef int (*send_subscribe_t)(subs_info_t* subs); -... - - This function receives as a parameter a structure with - Subscribe required information and sends a Subscribe message. - - The structure received as a parameter: -... -typedef struct subs_info - - str id; /* an id value unique for one combination - of pres_uri and flag */ - str* pres_uri; /* the presentity uri */ - str* watcher_uri; /* the watcher uri */ - str* contact; /* the uri that will be used in - Contact header*/ - str* remote_target; /* the uri that will be used as R-URI - for the Subscribe message(not compulsory; - if not set the value of the pres_uri field - is used) */ - str* outbound_proxy; /* the outbound_proxy to use when sending the - Subscribe request*/ - int event; /* the event flag; supported value: - PRESENCE_EVENT, BLA_EVENT, PWINFO_EVENT*/ - int expires; /* the expires value that will be used in - Subscribe Expires header */ - int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE - not compulsory */ - int source_flag; /* flag identifying the resource ; - supported values: MI_SUBSCRIBE, - BLA_SUBSCRIBE, XMPP_SUBSCRIBE, - XMPP_INITIAL_SUBS */ -}subs_info_t; -... - -2.4. is_dialog - - Field type: -... -typedef int (*query_dialog_t)(ua_pres_t* presentity); -... - - This function checks is the parameter corresponds to a stored - Subscribe initiated dialog. - - Example 2.2. pua_is_dialog usage example -... - if(pua_is_dialog(dialog) < 0) - { - LM_ERR("querying dialog\n"); - goto error; - } -... - -2.5. register_puacb - - Field type: -... -typedef int (*register_puacb_t)(int types, pua_cb f, void* param ); -... - - This function registers a callback to be called on receiving - the reply message for a sent Subscribe request. The type - parameter should be set the same as the source_flag for that - request. The function registered as callback for pua should be - of type pua_cb , which is: typedef void (pua_cb)(ua_pres_t* - hentity, struct msg_start * fl); The parameters are the dialog - structure for that request and the first line of the reply - message. - - Example 2.3. register_puacb usage example -... - if(pua.register_puacb(XMPP_SUBSCRIBE, Sipreply2Xmpp, NULL) & 0) - { - LM_ERR("Could not register callback\n"); - return -1; - } -... - -2.6. add_event - - Field type: -... -typedef int (*add_pua_event_t)(int ev_flag, char* name, - char* content_type,evs_process_body_t* process_body); - -- ev_flag : an event flag defined as a macro in pua module -- name : the event name to be used in Event request headers -- content_type: the default content_type for Publish body for - that event (NULL if winfo event) -- process_body: function that processes the received body before - using it to construct the PUBLISH request - (NULL if winfo event) -... - - This function allows registering new events to the pua module. - Now there are 4 events supported by the pua module: presence, - presence;winfo, message-summary, dialog;sla. These events are - registered from within the pua module. - - Filed type for process_body: -... -typedef int (evs_process_body_t)(struct publ_info* publ, - str** final_body, int ver, str* tuple); -- publ : the structure received as a parameter in send_publish - function ( initial body found in publ->body) -- final_body: the pointer where the result(final_body) should be stored -- ver : a counter for the sent Publish requests - (used for winfo events) -- tuple : a unique identifier for the resource; - if an initial Publish it should be returned as a result - and it will be stored for that record, otherwise it will - be given as a parameter; -... - - Example 2.4. add_event usage example -... - if(pua.add_event((PRESENCE_EVENT, "presence", "application/pidf+ -xml", - pres_process_body) & 0) - { - LM_ERR("Could not register new event\n"); - return -1; - } -... - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 279 106 11549 4540 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 73 53 1114 550 - 3. Liviu Chircu (@liviuchircu) 22 12 256 395 - 4. Ovidiu Sas (@ovidiusas) 17 13 230 109 - 5. Daniel-Constantin Mierla (@miconda) 12 8 144 97 - 6. Razvan Crainea (@razvancrainea) 10 7 76 83 - 7. Edson Gellert Schubert 10 1 0 501 - 8. Saúl Ibarra Corretgé (@saghul) 9 5 243 31 - 9. Henning Westerholt (@henningw) 7 4 86 76 - 10. Vlad Patrascu (@rvlad-patrascu) 6 4 30 20 - - All remaining contributors: Vlad Paiu (@vladpaiu), Juha - Heinanen (@juha-h), Walter Doekes (@wdoekes), Denis Bilenko, - Vallimamod Abdullah, Alex Hermann, Maksym Sobolyev (@sobomax), - Damien Sandras (@dsandras), Sergio Gutierrez, Konstantin - Bokarius, Elena-Ramona Modroiu, John Riordan, Ken Rice, Peter - Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), UnixDev, Zero - King (@l2dy), Carsten Bock, Stanislaw Pitucha, Dan Pascu - (@danpascu), Julien Blache. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2007 - Apr 2024 - 4. Carsten Bock Mar 2024 - Mar 2024 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Sep 2021 - 7. Razvan Crainea (@razvancrainea) Feb 2012 - Jan 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Ovidiu Sas (@ovidiusas) Nov 2010 - Feb 2016 - - All remaining contributors: Dusan Klinec (@ph4r05), Damien - Sandras (@dsandras), Saúl Ibarra Corretgé (@saghul), Vlad Paiu - (@vladpaiu), Anca Vamanu, Vallimamod Abdullah, Alex Hermann, - Stanislaw Pitucha, Walter Doekes (@wdoekes), John Riordan, - UnixDev, Sergio Gutierrez, Denis Bilenko, Henning Westerholt - (@henningw), Dan Pascu (@danpascu), Daniel-Constantin Mierla - (@miconda), Juha Heinanen (@juha-h), Konstantin Bokarius, Edson - Gellert Schubert, Julien Blache, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad - Patrascu (@rvlad-patrascu), Saúl Ibarra Corretgé (@saghul), - Razvan Crainea (@razvancrainea), Anca Vamanu, Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Juha Heinanen (@juha-h), Konstantin Bokarius, Edson Gellert - Schubert, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/pua/README.md b/modules/pua/README.md new file mode 100644 index 00000000000..9662587d559 --- /dev/null +++ b/modules/pua/README.md @@ -0,0 +1,586 @@ +--- +title: "Presence User Agent Module" +description: "This module offer the internal support for OpenSIPS to act as a Presence User Agent client, by sending Subscribe and Publish messages." +--- + +## Admin Guide + + +### Overview + + +This module offer the internal support for OpenSIPS to act as a +Presence User Agent client, by sending Subscribe and Publish messages. + + +Note that the module does NOT provide any functionality to be used +directly from the script, but it is providing this PUA client support +(via an internal API) for other event-specific modules to do PUA +client operations. + + +Some of modules build on top of the PUA module are pua_mi, pua_usrloc, +pua_dialoginfo, pua_bla and pua_xmpp. +The pua_mi offer the possibility to publish any kind of information +or subscribing to a resource through fifo. The pua_usrloc module calls +a function exported by pua modules to publish elementary presence +information, such as basic status "open" or "closed", for clients that +do not implement client-to-server presence. +The pua_dialoginfo provideds BLF support, by publishing the status of +the participants into a call (like ringing, established, terminated). +Through pua_bla , BRIDGED LINE APPEARANCE features are added to +OpenSIPs. +The pua_xmpp module represents a gateway between SIP and XMPP, so +that jabber and SIP clients can exchange presence information. + + +The module use cache to store presentity list and writes to database +on timer to be able to recover upon restart. + + +> [!NOTE] +> This module must not be used in no fork mode (the locking +> mechanism used may cause deadlock in no fork mode). + + +### PUA clustering + + +Starting 3.2, the module was extended with clustering support also. This +means multiple OpenSIPS instance, configured with PUA module, may work +together. For example, the publishing for a certain presentity may be done +via different node (PUA OpenSIPS instance) in the cluster. + + +The clustering support is a mixture of DB sharing and OpenSIPS clustering. +The OpenSIPS clustering layer is used for broadcasting notifications with +the cluster when a presentity is modified by one of the nodes (so that, +the other nodes in cluster may refresh the presentity via DB. + + +The shared DB is used by sharing between the nodes the actual presentity +data. A node caches into memory only the presentities created by the node +or the presentitites the node worked with. A presentity record may be +loaded into memory (from DB) if the node needs to perform an operation +with that presentity. + + +> [!IMPORTANT] +> Because the actual presentity data is shared between the nodes +> via DB (the clustering layer is used for notifications only), it is +> important to set a very low update interval for the DB (for data being +> flushed from memoryc cache into DB), to get the DB content updated as +> realtime as possible. See the the [update period](#param_update_period), +> module parameter, with recomanded values like 2-5 seconds. + + +On the OpenSIPS clustering layer, the PUA module use the sharing-tags +mechanism in order to control (between all the nodes in the cluster) which +node is responsible for performing the expiring operation on the +presentity (like sending the PUBLISH with expires 0). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database modules*. +- *tm*. +- *clusterer*, if the cluster_id +module parameter is set and clustering support activated. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml*. + + +### Exported Parameters + + +#### hash_size (int) + + +The size of the hash table used for storing Subscribe and +Publish information. +This parameter will be used as the power of 2 when computing table size. + + +*Default value is "9".* + + +```opensips title="Set hash_size parameter" +... +modparam("pua", "hash_size", 11) +... +``` + + +#### db_url (str) + + +Database url. + + +*Default value is ">mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("pua", "db_url" "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### db_table (str) + + +The name of the database table. + + +*Default value is "pua".* + + +```opensips title="Set db_table parameter" +... +modparam("pua", "db_table", "pua") +... +``` + + +#### min_expires (int) + + +The inferior expires limit for both Publish and Subscribe. + + +*Default value is "300".* + + +```opensips title="Set min_expires parameter" +... +modparam("pua", "min_expires", 0) +... +``` + + +#### default_expires (int) + + +The default expires value used in case this information is not provisioned. + + +*Default value is "3600".* + + +```opensips title="Set default_expires parameter" +... +modparam("pua", "default_expires", 3600) +... +``` + + +#### update_period (int) + + +The interval at which the information in database and hash table +should be updated. In the case of the hash table updating is +deleting expired messages. + + +*Default value is "30".* + + +> [!IMPORTANT] +> If you use clustering support for this module, set a low +> value here, like 2-5, see the clustering chapter above. + + +```opensips title="Set update_period parameter" +... +modparam("pua", "update_period", 100) +... +``` + + +#### cluster_id (int) + + +The cluster ID where the PUA data should be replicated/shared. +This parameter is to be used only if clustering mode is needed. +In order to understand the concept of a cluster ID, please see the +*clusterer* module. + + +For more on PUA clustering see the +[pua clustering](#pua_clustering) chapter. + + +*Default value is "None".* + + +```opensips title="Set cluster_id parameter" +... +modparam("pua", "cluster_id", 10) +... +``` + + +#### cluster_sharing_tag (int) + + +The clustering share-tag to be used by the PUA module when creating +any new presentity record. The tag will by used to decide which +OpenSIPS instance (owning the tag as active) will be responsible +for expiring this presentity. +This parameter is to be used only if clustering mode is needed. +In order to understand the concept of sharing TAG, please see the +*clusterer* module. + + +For more on PUA clustering see the +[pua clustering](#pua_clustering) chapter. + + +*Default value is "NULL".* + + +```opensips title="Set cluster_sharing_tag parameter" +... +modparam("pua", "cluster_sharing_tag", "vip") +... +``` + + +### Exported Functions + + +#### pua_update_contact() + + +The remote target can be updated by the Contact of a subsequent in +dialog request. In the PUA watcher case (sending a SUBSCRIBE messages), +this means that the remote target for the following Subscribe messages +can be updated at any time by the contact of a Notify message. +If this function is called on request route on receiving a Notify +message, it will try to update the stored remote target. + + +This function can be used from REQUEST_ROUTE. + + +*Return code:* + + +- *1 - if success*. +- *-1 - if error*. + + +```opensips title="pua_update_contact usage" +... +if($rm=="NOTIFY") + pua_update_contact(); +... +``` + + +### Installation + + +The module requires 1 table in OpenSIPS database: pua. The SQL +syntax to create it can be found in presence_xml-create.sql +script in the database directories in the opensips/scripts folder. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +## Developer Guide + + +The module provides the following functions that can be used +in other OpenSIPS modules. + + +### bind_pua(pua_api_t* api) + + +This function binds the pua modules and fills the structure +with the two exported function. + + +```c title="pua_api structure" +... +typedef struct pua_api { + send_subscribe_t send_subscribe; + send_publish_t send_publish; + query_dialog_t is_dialog; + register_puacb_t register_puacb; + add_pua_event_t add_event; +} pua_api_t; +... +``` + + +### send_publish + + +Field type: + + +```c +... +typedef int (*send_publish_t)(publ_info_t* publ); +... + +``` + + +This function receives as a parameter a structure with Publish +required information and sends a Publish message. + + +The structure received as a parameter: + + +```c +... +typedef struct publ_info + + str id; /* (optional )a value unique for one combination + of pres_uri and flag */ + str* pres_uri; /* the presentity uri */ + str* body; /* the body of the Publish message; + can be NULL in case of an update expires*/ + int expires; /* the expires value that will be used in + Publish Expires header*/ + int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE + if missing it will be established according + to the result of the search in hash table*/ + int source_flag; /* flag identifying the resource ; + supported values: UL_PUBLISH, MI_PUBLISH, + BLA_PUBLISH, XMPP_PUBLISH*/ + int event; /* the event flag; + supported values: PRESENCE_EVENT, BLA_EVENT, + MWI_EVENT */ + str content_type; /* the content_type of the body if present + (optional if the same as the default value + for that event)*/ + str* etag; /* (optional) the value of the etag the request + should match */ + str* extra_headers /* (optional) extra_headers that should be added + to Publish msg*/ + publrpl_cb_t* cbrpl;/* callback function to be called when receiving + the reply for the sent request */ + void* cbparam; /* extra parameter for tha callback function */ + + str outbound_proxy; /* the outbound proxy to be used when sending + the Publish request*/ + +}publ_info_t; +... + +``` + + +The callback function type: + + +```c +... +typedef int (publrpl_cb_t)(struct sip_msg* reply, void* extra_param); +... + +``` + + +### send_subscribe + + +Field type: + + +```c +... +typedef int (*send_subscribe_t)(subs_info_t* subs); +... +``` + + +This function receives as a parameter a structure with Subscribe +required information and sends a Subscribe message. + + +The structure received as a parameter: + + +```c +... +typedef struct subs_info + + str id; /* an id value unique for one combination + of pres_uri and flag */ + str* pres_uri; /* the presentity uri */ + str* watcher_uri; /* the watcher uri */ + str* contact; /* the uri that will be used in + Contact header*/ + str* remote_target; /* the uri that will be used as R-URI + for the Subscribe message(not compulsory; + if not set the value of the pres_uri field + is used) */ + str* outbound_proxy; /* the outbound_proxy to use when sending the + Subscribe request*/ + int event; /* the event flag; supported value: + PRESENCE_EVENT, BLA_EVENT, PWINFO_EVENT*/ + int expires; /* the expires value that will be used in + Subscribe Expires header */ + int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE + not compulsory */ + int source_flag; /* flag identifying the resource ; + supported values: MI_SUBSCRIBE, + BLA_SUBSCRIBE, XMPP_SUBSCRIBE, + XMPP_INITIAL_SUBS */ +}subs_info_t; +... +``` + + +### is_dialog + + +Field type: + + +```c +... +typedef int (*query_dialog_t)(ua_pres_t* presentity); +... + +``` + + +This function checks is the parameter corresponds to a stored +Subscribe initiated dialog. + + +```opensips title="pua_is_dialog usage example" +... + if(pua_is_dialog(dialog) < 0) + { + LM_ERR("querying dialog\n"); + goto error; + } +... +``` + + +### register_puacb + + +Field type: + + +```c +... +typedef int (*register_puacb_t)(int types, pua_cb f, void* param ); +... + +``` + + +This function registers a callback to be called on receiving the reply message +for a sent Subscribe request. +The type parameter should be set the same as the source_flag for that request. +The function registered as callback for pua should be of type pua_cb , which is: +typedef void (pua_cb)(ua_pres_t* hentity, struct msg_start * fl); +The parameters are the dialog structure for that request and the first line of the +reply message. + + +```c title="register_puacb usage example" +... + if(pua.register_puacb(XMPP_SUBSCRIBE, Sipreply2Xmpp, NULL) & 0) + { + LM_ERR("Could not register callback\n"); + return -1; + } +... + +``` + + +### add_event + + +Field type: + + +```c +... +typedef int (*add_pua_event_t)(int ev_flag, char* name, + char* content_type,evs_process_body_t* process_body); + +- ev_flag : an event flag defined as a macro in pua module +- name : the event name to be used in Event request headers +- content_type: the default content_type for Publish body for + that event (NULL if winfo event) +- process_body: function that processes the received body before + using it to construct the PUBLISH request + (NULL if winfo event) +... + +``` + + +This function allows registering new events to the pua module. +Now there are 4 events supported by the pua module: presence, +presence;winfo, message-summary, dialog;sla. These events are registered +from within the pua module. + + +Filed type for process_body: + + +```c +... +typedef int (evs_process_body_t)(struct publ_info* publ, + str** final_body, int ver, str* tuple); +- publ : the structure received as a parameter in send_publish + function ( initial body found in publ->body) +- final_body: the pointer where the result(final_body) should be stored +- ver : a counter for the sent Publish requests + (used for winfo events) +- tuple : a unique identifier for the resource; + if an initial Publish it should be returned as a result + and it will be stored for that record, otherwise it will + be given as a parameter; +... + +``` + + +```c title="add_event usage example" +... + if(pua.add_event((PRESENCE_EVENT, "presence", "application/pidf+xml", + pres_process_body) & 0) + { + LM_ERR("Could not register new event\n"); + return -1; + } +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua/add_events.c b/modules/pua/add_events.c index 923d1a4abcb..af6483c507e 100644 --- a/modules/pua/add_events.c +++ b/modules/pua/add_events.c @@ -159,7 +159,6 @@ int pres_process_body(publ_info_t* publ, str** fin_body, int ver, str* tuple) doc= NULL; *fin_body= body; - xmlMemoryDump(); xmlCleanupParser(); return 1; @@ -171,4 +170,3 @@ int pres_process_body(publ_info_t* publ, str** fin_body, int ver, str* tuple) return -1; } - diff --git a/modules/pua/doc/contributors.xml b/modules/pua/doc/contributors.xml deleted file mode 100644 index a3fd1ee4487..00000000000 --- a/modules/pua/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 279 - 106 - 11549 - 4540 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 73 - 53 - 1114 - 550 - - - 3. - Liviu Chircu (@liviuchircu) - 22 - 12 - 256 - 395 - - - 4. - Ovidiu Sas (@ovidiusas) - 17 - 13 - 230 - 109 - - - 5. - Daniel-Constantin Mierla (@miconda) - 12 - 8 - 144 - 97 - - - 6. - Razvan Crainea (@razvancrainea) - 10 - 7 - 76 - 83 - - - 7. - Edson Gellert Schubert - 10 - 1 - 0 - 501 - - - 8. - Saúl Ibarra Corretgé (@saghul) - 9 - 5 - 243 - 31 - - - 9. - Henning Westerholt (@henningw) - 7 - 4 - 86 - 76 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 30 - 20 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Juha Heinanen (@juha-h), Walter Doekes (@wdoekes), Denis Bilenko, Vallimamod Abdullah, Alex Hermann, Maksym Sobolyev (@sobomax), Damien Sandras (@dsandras), Sergio Gutierrez, Konstantin Bokarius, Elena-Ramona Modroiu, John Riordan, Ken Rice, Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), UnixDev, Zero King (@l2dy), Carsten Bock, Stanislaw Pitucha, Dan Pascu (@danpascu), Julien Blache. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2007 - Apr 2024 - - - 4. - Carsten Bock - Mar 2024 - Mar 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Sep 2021 - - - 7. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jan 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Ovidiu Sas (@ovidiusas) - Nov 2010 - Feb 2016 - - - -
-All remaining contributors: Dusan Klinec (@ph4r05), Damien Sandras (@dsandras), Saúl Ibarra Corretgé (@saghul), Vlad Paiu (@vladpaiu), Anca Vamanu, Vallimamod Abdullah, Alex Hermann, Stanislaw Pitucha, Walter Doekes (@wdoekes), John Riordan, UnixDev, Sergio Gutierrez, Denis Bilenko, Henning Westerholt (@henningw), Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Juha Heinanen (@juha-h), Konstantin Bokarius, Edson Gellert Schubert, Julien Blache, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Saúl Ibarra Corretgé (@saghul), Razvan Crainea (@razvancrainea), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Juha Heinanen (@juha-h), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu. -
- -
diff --git a/modules/pua/doc/pua.xml b/modules/pua/doc/pua.xml deleted file mode 100644 index 69832af843a..00000000000 --- a/modules/pua/doc/pua.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Presence User Agent Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - - - diff --git a/modules/pua/doc/pua_admin.xml b/modules/pua/doc/pua_admin.xml deleted file mode 100644 index cf066a89fad..00000000000 --- a/modules/pua/doc/pua_admin.xml +++ /dev/null @@ -1,359 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module offer the internal support for OpenSIPS to act as a - Presence User Agent client, by sending Subscribe and Publish messages. - - - Note that the module does NOT provide any functionality to be used - directly from the script, but it is providing this PUA client support - (via an internal API) for other event-specific modules to do PUA - client operations. - - - Some of modules build on top of the PUA module are pua_mi, pua_usrloc, - pua_dialoginfo, pua_bla and pua_xmpp. - The pua_mi offer the possibility to publish any kind of information - or subscribing to a resource through fifo. The pua_usrloc module calls - a function exported by pua modules to publish elementary presence - information, such as basic status "open" or "closed", for clients that - do not implement client-to-server presence. - The pua_dialoginfo provideds BLF support, by publishing the status of - the participants into a call (like ringing, established, terminated). - Through pua_bla , BRIDGED LINE APPEARANCE features are added to - OpenSIPs. - The pua_xmpp module represents a gateway between SIP and XMPP, so - that jabber and SIP clients can exchange presence information. - - - The module use cache to store presentity list and writes to database - on timer to be able to recover upon restart. - - - Notice: This module must not be used in no fork mode (the locking - mechanism used may cause deadlock in no fork mode). - -
- -
- PUA clustering - - Starting 3.2, the module was extended with clustering support also. This - means multiple OpenSIPS instance, configured with PUA module, may work - together. For example, the publishing for a certain presentity may be done - via different node (PUA OpenSIPS instance) in the cluster. - - - The clustering support is a mixture of DB sharing and OpenSIPS clustering. - The OpenSIPS clustering layer is used for broadcasting notifications with - the cluster when a presentity is modified by one of the nodes (so that, - the other nodes in cluster may refresh the presentity via DB. - - - The shared DB is used by sharing between the nodes the actual presentity - data. A node caches into memory only the presentities created by the node - or the presentitites the node worked with. A presentity record may be - loaded into memory (from DB) if the node needs to perform an operation - with that presentity. - - - IMPORTANT: because the actual presentity data is shared between the nodes - via DB (the clustering layer is used for notifications only), it is - important to set a very low update interval for the DB (for data being - flushed from memoryc cache into DB), to get the DB content updated as - realtime as possible. See the the , - module parameter, with recomanded values like 2-5 seconds. - - - On the OpenSIPS clustering layer, the PUA module use the sharing-tags - mechanism in order to control (between all the nodes in the cluster) which - node is responsible for performing the expiring operation on the - presentity (like sending the PUBLISH with expires 0). - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database modules. - - - - - tm. - - - - - clusterer, if the cluster_id - module parameter is set and clustering support activated. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml. - - - - -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (int) - - The size of the hash table used for storing Subscribe and - Publish information. - This parameter will be used as the power of 2 when computing table size. - - - Default value is 9. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("pua", "hash_size", 11) -... - - -
-
- <varname>db_url</varname> (str) - - Database url. - - - Default value is >&defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("pua", "db_url" "&exampledb;") -... - - -
-
- <varname>db_table</varname> (str) - - The name of the database table. - - - Default value is pua. - - - - Set <varname>db_table</varname> parameter - -... -modparam("pua", "db_table", "pua") -... - - -
-
- <varname>min_expires</varname> (int) - - The inferior expires limit for both Publish and Subscribe. - - - Default value is 300. - - - - Set <varname>min_expires</varname> parameter - -... -modparam("pua", "min_expires", 0) -... - - -
-
- <varname>default_expires</varname> (int) - - The default expires value used in case this information is not provisioned. - - - Default value is 3600. - - - - Set <varname>default_expires</varname> parameter - -... -modparam("pua", "default_expires", 3600) -... - - -
-
- <varname>update_period</varname> (int) - - The interval at which the information in database and hash table - should be updated. In the case of the hash table updating is - deleting expired messages. - - - Default value is 30. - - - - IMPORTANT - if you use clustering support for this module, set a low - value here, like 2-5, see the clustering chapter above. - - - Set <varname>update_period</varname> parameter - -... -modparam("pua", "update_period", 100) -... - - -
- -
- <varname>cluster_id</varname> (int) - - The cluster ID where the PUA data should be replicated/shared. - This parameter is to be used only if clustering mode is needed. - In order to understand the concept of a cluster ID, please see the - clusterer module. - - - For more on PUA clustering see the - chapter. - - - Default value is None. - - - - Set <varname>cluster_id</varname> parameter - -... -modparam("pua", "cluster_id", 10) -... - - -
- -
- <varname>cluster_sharing_tag</varname> (int) - - The clustering share-tag to be used by the PUA module when creating - any new presentity record. The tag will by used to decide which - OpenSIPS instance (owning the tag as active) will be responsible - for expiring this presentity. - This parameter is to be used only if clustering mode is needed. - In order to understand the concept of sharing TAG, please see the - clusterer module. - - - For more on PUA clustering see the - chapter. - - - Default value is NULL. - - - - Set <varname>cluster_sharing_tag</varname> parameter - -... -modparam("pua", "cluster_sharing_tag", "vip") -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">pua_update_contact()</function> - - - The remote target can be updated by the Contact of a subsequent in - dialog request. In the PUA watcher case (sending a SUBSCRIBE messages), - this means that the remote target for the following Subscribe messages - can be updated at any time by the contact of a Notify message. - If this function is called on request route on receiving a Notify - message, it will try to update the stored remote target. - - - This function can be used from REQUEST_ROUTE. - - - Return code: - - - - 1 - if success. - - - - - -1 - if error. - - - - - - - <function>pua_update_contact</function> usage - -... -if($rm=="NOTIFY") - pua_update_contact(); -... - - -
-
- - -
- Installation - - The module requires 1 table in OpenSIPS database: pua. The SQL - syntax to create it can be found in presence_xml-create.sql - script in the database directories in the opensips/scripts folder. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- - -
- diff --git a/modules/pua/doc/pua_devel.xml b/modules/pua/doc/pua_devel.xml deleted file mode 100644 index 9707a79d2f7..00000000000 --- a/modules/pua/doc/pua_devel.xml +++ /dev/null @@ -1,279 +0,0 @@ - - - - - &develguide; - - The module provides the following functions that can be used - in other &osips; modules. - -
- - <function moreinfo="none">bind_pua(pua_api_t* api)</function> - - - This function binds the pua modules and fills the structure - with the two exported function. - - - <function>pua_api</function> structure - -... -typedef struct pua_api { - send_subscribe_t send_subscribe; - send_publish_t send_publish; - query_dialog_t is_dialog; - register_puacb_t register_puacb; - add_pua_event_t add_event; -} pua_api_t; -... - - - -
- - -
- - <function moreinfo="none">send_publish</function> - - - Field type: - -... -typedef int (*send_publish_t)(publ_info_t* publ); -... - - - - This function receives as a parameter a structure with Publish - required information and sends a Publish message. - - - The structure received as a parameter: - - -... -typedef struct publ_info - - str id; /* (optional )a value unique for one combination - of pres_uri and flag */ - str* pres_uri; /* the presentity uri */ - str* body; /* the body of the Publish message; - can be NULL in case of an update expires*/ - int expires; /* the expires value that will be used in - Publish Expires header*/ - int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE - if missing it will be established according - to the result of the search in hash table*/ - int source_flag; /* flag identifying the resource ; - supported values: UL_PUBLISH, MI_PUBLISH, - BLA_PUBLISH, XMPP_PUBLISH*/ - int event; /* the event flag; - supported values: PRESENCE_EVENT, BLA_EVENT, - MWI_EVENT */ - str content_type; /* the content_type of the body if present - (optional if the same as the default value - for that event)*/ - str* etag; /* (optional) the value of the etag the request - should match */ - str* extra_headers /* (optional) extra_headers that should be added - to Publish msg*/ - publrpl_cb_t* cbrpl;/* callback function to be called when receiving - the reply for the sent request */ - void* cbparam; /* extra parameter for tha callback function */ - - str outbound_proxy; /* the outbound proxy to be used when sending - the Publish request*/ - -}publ_info_t; -... - - - The callback function type: - -... -typedef int (publrpl_cb_t)(struct sip_msg* reply, void* extra_param); -... - - -
- -
- - <function moreinfo="none">send_subscribe</function> - - - Field type: - -... -typedef int (*send_subscribe_t)(subs_info_t* subs); -... - - - - This function receives as a parameter a structure with Subscribe - required information and sends a Subscribe message. - - - The structure received as a parameter: - -... -typedef struct subs_info - - str id; /* an id value unique for one combination - of pres_uri and flag */ - str* pres_uri; /* the presentity uri */ - str* watcher_uri; /* the watcher uri */ - str* contact; /* the uri that will be used in - Contact header*/ - str* remote_target; /* the uri that will be used as R-URI - for the Subscribe message(not compulsory; - if not set the value of the pres_uri field - is used) */ - str* outbound_proxy; /* the outbound_proxy to use when sending the - Subscribe request*/ - int event; /* the event flag; supported value: - PRESENCE_EVENT, BLA_EVENT, PWINFO_EVENT*/ - int expires; /* the expires value that will be used in - Subscribe Expires header */ - int flag; /* it can be : INSERT_TYPE or UPDATE_TYPE - not compulsory */ - int source_flag; /* flag identifying the resource ; - supported values: MI_SUBSCRIBE, - BLA_SUBSCRIBE, XMPP_SUBSCRIBE, - XMPP_INITIAL_SUBS */ -}subs_info_t; -... - - -
-
- - <function moreinfo="none">is_dialog</function> - - - Field type: - -... -typedef int (*query_dialog_t)(ua_pres_t* presentity); -... - - - - This function checks is the parameter corresponds to a stored - Subscribe initiated dialog. - - - <function>pua_is_dialog </function>usage example - -... - if(pua_is_dialog(dialog) < 0) - { - LM_ERR("querying dialog\n"); - goto error; - } -... - - -
- -
- - <function moreinfo="none">register_puacb</function> - - - Field type: - -... -typedef int (*register_puacb_t)(int types, pua_cb f, void* param ); -... - - - - - This function registers a callback to be called on receiving the reply message - for a sent Subscribe request. - The type parameter should be set the same as the source_flag for that request. - The function registered as callback for pua should be of type pua_cb , which is: - typedef void (pua_cb)(ua_pres_t* hentity, struct msg_start * fl); - The parameters are the dialog structure for that request and the first line of the - reply message. - - - <function>register_puacb </function>usage example - -... - if(pua.register_puacb(XMPP_SUBSCRIBE, Sipreply2Xmpp, NULL) & 0) - { - LM_ERR("Could not register callback\n"); - return -1; - } -... - - -
- -
- - <function moreinfo="none">add_event</function> - - - Field type: - -... -typedef int (*add_pua_event_t)(int ev_flag, char* name, - char* content_type,evs_process_body_t* process_body); - -- ev_flag : an event flag defined as a macro in pua module -- name : the event name to be used in Event request headers -- content_type: the default content_type for Publish body for - that event (NULL if winfo event) -- process_body: function that processes the received body before - using it to construct the PUBLISH request - (NULL if winfo event) -... - - - - This function allows registering new events to the pua module. - Now there are 4 events supported by the pua module: presence, - presence;winfo, message-summary, dialog;sla. These events are registered - from within the pua module. - - - Filed type for process_body: - -... -typedef int (evs_process_body_t)(struct publ_info* publ, - str** final_body, int ver, str* tuple); -- publ : the structure received as a parameter in send_publish - function ( initial body found in publ->body) -- final_body: the pointer where the result(final_body) should be stored -- ver : a counter for the sent Publish requests - (used for winfo events) -- tuple : a unique identifier for the resource; - if an initial Publish it should be returned as a result - and it will be stored for that record, otherwise it will - be given as a parameter; -... - - - - <function>add_event </function>usage example - -... - if(pua.add_event((PRESENCE_EVENT, "presence", "application/pidf+xml", - pres_process_body) & 0) - { - LM_ERR("Could not register new event\n"); - return -1; - } -... - - - -
- -
- diff --git a/modules/pua_bla/README b/modules/pua_bla/README deleted file mode 100644 index 406563d83ee..00000000000 --- a/modules/pua_bla/README +++ /dev/null @@ -1,241 +0,0 @@ -PUA Bridged Line Appearances - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_domain(str) - 1.3.2. header_name(str) - 1.3.3. outbound_proxy(str) - 1.3.4. server_address(str) - 1.3.5. presence_server(str) - - 1.4. Exported Functions - - 1.4.1. bla_set_flag() - 1.4.2. bla_handle_notify() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_domain parameter - 1.2. Set header_name parameter - 1.3. Set outbound_proxy parameter - 1.4. Set server_address parameter - 1.5. Set presence_server parameter - 1.6. bla_set_flag usage - 1.7. bla_handle_notify usage - -Chapter 1. Admin Guide - -1.1. Overview - - The pua_bla module enables Bridged Line Appearances support - according to the specifications in - draft-anil-sipping-bla-03.txt. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * usrloc. - * pua. - * presence. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml. - -1.3. Exported Parameters - -1.3.1. default_domain(str) - - The default domain for the registered users to be used when - constructing the uri for the registrar callback. - - Default value is “NULL”. - - Example 1.1. Set default_domain parameter -... -modparam("pua_bla", "default_domain", "opensips.org") -... - -1.3.2. header_name(str) - - The name of the header to be added to Publish requests. It will - contain the uri of the user agent that sent the Notify that is - transformed into Publish. It stops sending a Notification with - the same information to the sender. - - Default value is “NULL”. - - Example 1.2. Set header_name parameter -... -modparam("pua_bla", "header_name", "Sender") -... - -1.3.3. outbound_proxy(str) - - The outbound_proxy uri to be used when sending Subscribe - requests. - - Default value is “NULL”. - - Example 1.3. Set outbound_proxy parameter -... -modparam("pua_bla", "outbound_proxy", "sip:proxy@opensips.org") -... - -1.3.4. server_address(str) - - The IP address of the server. - - Example 1.4. Set server_address parameter -... -modparam("pua_bla", "server_address", "sip:bla@160.34.23.12") -... - -1.3.5. presence_server(str) - - The address of the presence server - will be used as an - outbound proxy when sending PUBLISH requests. It is optional. - - Default value is “NULL”. - - Example 1.5. Set presence_server parameter -... -modparam("pua_bla", "presence_server", "sip:pa@opensips.org") -... - -1.4. Exported Functions - -1.4.1. bla_set_flag() - - The function is used to mark REGISTER requests made to a BLA - AOR. The modules subscribes to the registered contacts for - dialog;sla event. - - Example 1.6. bla_set_flag usage -... -if(is_method("REGISTER") && $tu=~"bla_aor@opensips.org") - bla_set_flag(); -... - -1.4.2. bla_handle_notify() - - The function handles Notify requests sent from phones on the - same BLA to the server. The message is transformed in Publish - request and passed to presence module for further handling. in - case of a successful processing a 2xx reply should be sent. - - Example 1.7. bla_handle_notify usage -... -if(is_method("NOTIFY") && $tu=~"bla_aor@opensips.org") -{ - if( bla_handle_notify() ) - t_reply(200, "OK"); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 57 27 1961 779 - 2. Liviu Chircu (@liviuchircu) 17 14 58 73 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 16 13 43 61 - 4. Daniel-Constantin Mierla (@miconda) 9 7 17 15 - 5. Razvan Crainea (@razvancrainea) 8 6 12 13 - 6. Vlad Patrascu (@rvlad-patrascu) 7 5 20 18 - 7. Ovidiu Sas (@ovidiusas) 4 2 15 4 - 8. Vlad Paiu (@vladpaiu) 3 1 6 16 - 9. Sergio Gutierrez 3 1 4 4 - 10. Maksym Sobolyev (@sobomax) 3 1 3 3 - - All remaining contributors: Konstantin Bokarius, Juha Heinanen - (@juha-h), Ezequiel Lovelle (@lovelle), Ken Rice, Peter - Lemenkov (@lemenkov), Edson Gellert Schubert, Stanislaw - Pitucha. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Nov 2025 - 2. Ken Rice Sep 2025 - Sep 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Jan 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ezequiel Lovelle (@lovelle) Oct 2014 - Oct 2014 - 9. Ovidiu Sas (@ovidiusas) Dec 2010 - Jan 2013 - 10. Vlad Paiu (@vladpaiu) Aug 2011 - Aug 2011 - - All remaining contributors: Anca Vamanu, Stanislaw Pitucha, - Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen - (@juha-h). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca Vamanu, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/pua_bla/README.md b/modules/pua_bla/README.md new file mode 100644 index 00000000000..72dcbe2d99a --- /dev/null +++ b/modules/pua_bla/README.md @@ -0,0 +1,167 @@ +--- +title: "PUA BLA module" +description: "The pua_bla module enables Bridged Line Appearances support according to the specifications in draft-anil-sipping-bla-03.txt." +--- + +## Admin Guide + + +### Overview + + +The pua_bla module enables Bridged Line Appearances support according to +the specifications in draft-anil-sipping-bla-03.txt. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *usrloc*. +- *pua*. +- *presence*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml*. + + +### Exported Parameters + + +#### default_domain(str) + + +The default domain for the registered users to be used when +constructing the uri for the registrar callback. + + +*Default value is "NULL".* + + +```opensips title="Set default_domain parameter" +... +modparam("pua_bla", "default_domain", "opensips.org") +... +``` + + +#### header_name(str) + + +The name of the header to be added to Publish requests. +It will contain the uri of the user agent that sent the +Notify that is transformed into Publish. It stops sending +a Notification with the same information to the sender. + + +*Default value is "NULL".* + + +```opensips title="Set header_name parameter" +... +modparam("pua_bla", "header_name", "Sender") +... +``` + + +#### outbound_proxy(str) + + +The outbound_proxy uri to be used when sending Subscribe requests. + + +*Default value is "NULL".* + + +```opensips title="Set outbound_proxy parameter" +... +modparam("pua_bla", "outbound_proxy", "sip:proxy@opensips.org") +... +``` + + +#### server_address(str) + + +The IP address of the server. + + +```opensips title="Set server_address parameter" +... +modparam("pua_bla", "server_address", "sip:bla@160.34.23.12") +... +``` + + +#### presence_server(str) + + +The address of the presence server - will be used as +an outbound proxy when sending PUBLISH requests. +It is optional. + + +*Default value is "NULL".* + + +```opensips title="Set presence_server parameter" +... +modparam("pua_bla", "presence_server", "sip:pa@opensips.org") +... +``` + + +### Exported Functions + + +#### bla_set_flag() + + +The function is used to mark REGISTER requests made to a BLA AOR. +The modules subscribes to the registered contacts for dialog;sla +event. + + +```opensips title="bla_set_flag usage" +... +if(is_method("REGISTER") && $tu=~"bla_aor@opensips.org") + bla_set_flag(); +... +``` + + +#### bla_handle_notify() + + +The function handles Notify requests sent from phones on the +same BLA to the server. The message is transformed in Publish +request and passed to presence module for further handling. +in case of a successful processing a 2xx reply should be sent. + + +```opensips title="bla_handle_notify usage" +... +if(is_method("NOTIFY") && $tu=~"bla_aor@opensips.org") +{ + if( bla_handle_notify() ) + t_reply(200, "OK"); +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_bla/doc/contributors.xml b/modules/pua_bla/doc/contributors.xml deleted file mode 100644 index 13365ac885e..00000000000 --- a/modules/pua_bla/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 57 - 27 - 1961 - 779 - - - 2. - Liviu Chircu (@liviuchircu) - 17 - 14 - 58 - 73 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 16 - 13 - 43 - 61 - - - 4. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 17 - 15 - - - 5. - Razvan Crainea (@razvancrainea) - 8 - 6 - 12 - 13 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 7 - 5 - 20 - 18 - - - 7. - Ovidiu Sas (@ovidiusas) - 4 - 2 - 15 - 4 - - - 8. - Vlad Paiu (@vladpaiu) - 3 - 1 - 6 - 16 - - - 9. - Sergio Gutierrez - 3 - 1 - 4 - 4 - - - 10. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - -
-All remaining contributors: Konstantin Bokarius, Juha Heinanen (@juha-h), Ezequiel Lovelle (@lovelle), Ken Rice, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Stanislaw Pitucha. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Nov 2025 - - - 2. - Ken Rice - Sep 2025 - Sep 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jan 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ezequiel Lovelle (@lovelle) - Oct 2014 - Oct 2014 - - - 9. - Ovidiu Sas (@ovidiusas) - Dec 2010 - Jan 2013 - - - 10. - Vlad Paiu (@vladpaiu) - Aug 2011 - Aug 2011 - - - -
-All remaining contributors: Anca Vamanu, Stanislaw Pitucha, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/pua_bla/doc/pua_bla.xml b/modules/pua_bla/doc/pua_bla.xml deleted file mode 100644 index 683bc8e93cf..00000000000 --- a/modules/pua_bla/doc/pua_bla.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - PUA Bridged Line Appearances - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - diff --git a/modules/pua_bla/doc/pua_bla_admin.xml b/modules/pua_bla/doc/pua_bla_admin.xml deleted file mode 100644 index b42a7781ead..00000000000 --- a/modules/pua_bla/doc/pua_bla_admin.xml +++ /dev/null @@ -1,207 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The pua_bla module enables Bridged Line Appearances support according to - the specifications in draft-anil-sipping-bla-03.txt. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - usrloc. - - - - - pua. - - - - - presence. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml. - - - - -
-
-
- Exported Parameters -
- <varname>default_domain</varname>(str) - - The default domain for the registered users to be used when - constructing the uri for the registrar callback. - - - Default value is NULL. - - - - Set <varname>default_domain</varname> parameter - -... -modparam("pua_bla", "default_domain", "opensips.org") -... - - -
-
- <varname>header_name</varname>(str) - - The name of the header to be added to Publish requests. - It will contain the uri of the user agent that sent the - Notify that is transformed into Publish. It stops sending - a Notification with the same information to the sender. - - - Default value is NULL. - - - - Set <varname>header_name</varname> parameter - -... -modparam("pua_bla", "header_name", "Sender") -... - - -
- -
- <varname>outbound_proxy</varname>(str) - - The outbound_proxy uri to be used when sending Subscribe requests. - - - Default value is NULL. - - - - Set <varname>outbound_proxy</varname> parameter - -... -modparam("pua_bla", "outbound_proxy", "sip:proxy@opensips.org") -... - - -
-
- <varname>server_address</varname>(str) - - The IP address of the server. - - - Set <varname>server_address</varname> parameter - -... -modparam("pua_bla", "server_address", "sip:bla@160.34.23.12") -... - - -
- -
- <varname>presence_server</varname>(str) - - The address of the presence server - will be used as - an outbound proxy when sending PUBLISH requests. - It is optional. - - - Default value is NULL. - - - - Set <varname>presence_server</varname> parameter - -... -modparam("pua_bla", "presence_server", "sip:pa@opensips.org") -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">bla_set_flag()</function> - - - The function is used to mark REGISTER requests made to a BLA AOR. - The modules subscribes to the registered contacts for dialog;sla - event. - - - - - <function>bla_set_flag</function> usage - -... -if(is_method("REGISTER") && $tu=~"bla_aor@opensips.org") - bla_set_flag(); -... - - - -
-
- - <function moreinfo="none">bla_handle_notify()</function> - - - The function handles Notify requests sent from phones on the - same BLA to the server. The message is transformed in Publish - request and passed to presence module for further handling. - in case of a successful processing a 2xx reply should be sent. - - - - - <function>bla_handle_notify</function> usage - -... -if(is_method("NOTIFY") && $tu=~"bla_aor@opensips.org") -{ - if( bla_handle_notify() ) - t_reply(200, "OK"); -} -... - - - -
-
- -
- diff --git a/modules/pua_dialoginfo/README b/modules/pua_dialoginfo/README deleted file mode 100644 index 0fe995ee480..00000000000 --- a/modules/pua_dialoginfo/README +++ /dev/null @@ -1,594 +0,0 @@ -pua dialoginfo - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. include_callid (int) - 1.3.2. include_tags (int) - 1.3.3. include_localremote (int) - 1.3.4. caller_confirmed (int) - 1.3.5. publish_on_trying (int) - 1.3.6. nopublish_flag (str) - 1.3.7. presence_server (string) - 1.3.8. caller_spec_param (string) - 1.3.9. callee_spec_param (string) - 1.3.10. osips_ps (int) - - 1.4. Exported Functions - - 1.4.1. dialoginfo_set([side]) - 1.4.2. dialoginfo_set_branch_callee(callee) - 1.4.3. dialoginfo_mute_branch([side]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set include_callid parameter - 1.2. Set include_tags parameter - 1.3. Set include_localremote parameter - 1.4. Set caller_confirmed parameter - 1.5. Set publish_on_trying parameter to 0 - 1.6. Set publish_on_trying parameter to 1 - 1.7. Set nopublish_flag parameter - 1.8. Set presence_server parameter - 1.9. Set caller_spec_param parameter - 1.10. Set caller_spec_param parameter - 1.11. Set osips_ps parameter - 1.12. dialoginfo_set usage - 1.13. dialoginfo_set_branch_callee usage - 1.14. dialoginfo_mute_branch usage - -Chapter 1. Admin Guide - -1.1. Overview - - The pua_dialoginfo retrieves dialog state information from the - dialog module and PUBLISHes the dialog-information using the - pua module. Thus, in combination with the presence_xml module - this can be used to derive dialog-info from the dialog module - and NOTIFY the subscribed watchers about dialog-info changes. - This can be used for example with SNOM and Linksys phones. - - Note: This implements dialog-info according to RFC 4235 and is - not compatible with the BLA feature defined in - draft-anil-sipping-bla-03.txt. (Actually the BLA draft is - really crap as it changes SIP semantics) - - The module is based on code (copy/paste) from pua_usrloc and - nat_traversal module. - - Following you will show some examples of an dialog-info XML - document taken from RFC 4235. This will help you to understand - the meaning of the module parameters: - - - - - early - - - - - The root element is the "dialog-info". It contains the - namespace, the version (which must be incremented for each new - PUBLISH for this certain dialog), the state (this module only - supports state=full) and the entity for which we publish the - dialog-info. - - The "dialog" element must contain an id parameter. The id - parameter is usually different to the optional call-id - parameter (which is the call-id of the INVITE request) as an - INVITE can create multiple dialogs (forked request). But as the - dialog module does not support multiple dialogs created by a - single transaction, the pua_dialoginfo module sets the id - parameter to the same value as the call-id parameter. The - "local-tag" indicates the local tag of the entity. The - remote-tag indicates the tag of the remote party. The - "direction" indicates if the entity was the initator of the - dialog or the recepient (aka if the entity sent or received the - first INVITE). - - The "state" element describes the state of the dialog state - machine and must be either: trying, proceeding, early, - confirmed or terminated. - - The dialog element can contain optional "local" and "remote" - elements which describes the local and the remote party in more - detail, for example: - - - - - early - - sip:alice@example.com - - - - sip:bob@example.org - - - - - - - The local and remote elements are needed to implement call - pickup. For example if the above XML document is received by - somebody who SUBSCRIBEd the dialog-info of Alice, then it can - pick-up the call by sending an INVITE to Bob (actually I am not - sure if it should use the URI in the identity element or the - URI in the target parameter) which contains a Replaces header - which contains the call-id and the tags. This was tested - successfully with Linksys SPA962 phones and with SNOM 320 - Firmware 7.3.7 (you have to set the function key to - "Extension"). - - A dialog-info XML document may contain multiple "dialog" - elements, for example if the entity has multiple ongoing - dialogs. For example the following XML document shows a - confirmed dialog and an early (probably a second incoming call) - dialog. - - - - - confirmed - - - early - - - - - To enable dialoginfo notifications for a certain dialog, you - must call dialoginfo_set() function for that dialog. This - function can take one parameter which through which you can - tell the module to publish dialoginfo only for one side of the - call. This is useful because you want to store dialoginfo only - for the local users, and you can decide from the script if the - call parties are local users and give the correct parameter to - this function to tell it to send generate dialoginfo only for - the local users. The possible values are : "A" - corresponding - to generate dialoginfo only for the caller and "B" - generate - dialoginfo only for the callee. If no parameter is given, the - module will generate dialoginfo for both parties. It is - possible to specify what URIs should be used for caller and - callee by setting the the pseudovariables with the names - defined as module parameter "caller_spec_param" and - "callee_spec_param" before calling dialoginfo_set() function. - Please read the description of this parameters in Exported - Parameters section. If this parameters are not set, the default - sources will be used, From header for the caller and display - name in To header + RURI for the callee. - - As the dialog module callbacks only address a certain dialog, - the pua_dialoginfo always PUBLISHes XML documents with a single - "dialog" element. If an entity has multiple concurrent dialogs, - the pua_dialoginfo module will send PUBLISH for each dialog. - These multiple "presenties" can be aggregated by the - presence_dialoginfo module into a single XML document with - multiple "dialog" elements. Please see the description of the - presence_dialoginfo module for details about the aggregation. - - If there are problems with the callbacks from dialog module and - you want to debug them you define PUA_DIALOGINFO_DEBUG in - pua_dialoginfo.c and recompile. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog. - * pua. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml. - -1.3. Exported Parameters - -1.3.1. include_callid (int) - - If this parameter is set, the optional call-id will be put into - the dialog element. This is needed for call-pickup features. - - Default value is “1”. - - Example 1.1. Set include_callid parameter -... -modparam("pua_dialoginfo", "include_callid", 0) -... - -1.3.2. include_tags (int) - - If this parameter is set, the local and remote tag will be put - into the dialog element. This is needed for call-pickup - features. - - Default value is “1”. - - Example 1.2. Set include_tags parameter -... -modparam("pua_dialoginfo", "include_tags", 0) -... - -1.3.3. include_localremote (int) - - If this parameter is set, the optional local and remote - elements will be put into the dialog element. This is needed - for call-pickup features. - - Default value is “1”. - - Example 1.3. Set include_localremote parameter -... -modparam("pua_dialoginfo", "include_localremote", 0) -... - -1.3.4. caller_confirmed (int) - - Usually the dialog-info of the caller will be "trying -> early - -> confirmed" and the dialog-info of the callee will be "early - -> confirmed". On some phones the function LED will start - blinking if the state is early, regardless if is is the caller - or the callee (indicated with the "direction" parameter). To - avoid blinking LEDs for the caller, you can enable this - parameter. Then the state of the caller will be singaled as - "confirmed" even in "early" state. This is a workaround for the - buggy Linksys SPA962 phones. SNOM phones work well with the - default setting. - - Default value is “0”. - - Example 1.4. Set caller_confirmed parameter -... -modparam("pua_dialoginfo", "caller_confirmed", 1) -... - -1.3.5. publish_on_trying (int) - - Usually the dialog-info of the caller will be "trying -> early - -> confirmed". The "trying" state will be triggered as soon as - you call dialoginfo_set() on the caller, while "early" is - triggered as soon as the callee is ringing (triggered by a 180 - or 183 provisional reply). Sometimes, it is advisable to be - notified only when the callee reaches the early state and not - before. In other cases, it is advisable to notify the early - state. This setting allows controlling the behavior. - - The intended purpose of this parameter is to reduce the rate of - notifications (see RFC4235, section 3.10. Rate of - Notifications). - - Default value is “0”. - - Example 1.5. Set publish_on_trying parameter to 0 -... -modparam("pua_dialoginfo", "publish_on_trying", 0) - -# Successful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |<-100-----| | -# | | | | -# | |<-18x-----| | -# |<-18x-----|--PUBLISH(early)------>| -# | | | | -# | |<-200-----| | -# |<-200-----|--PUBLISH(confirmed)-->| -# |--ACK---->| | | -# | |--ACK---->| | -# | | | | -# -# -# Unsuccessful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |<-100-----| | -# | | | | -# | |<-456xx---| | -# |<-456xx---|--ACK---->| | -# |--ACK---->| | | -... - - Example 1.6. Set publish_on_trying parameter to 1 -... -modparam("pua_dialoginfo", "publish_on_trying", 1) - -# Successful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |--PUBLISH(trying)----->| -# | |<-100-----| | -# | | | | -# | |<-18x-----| | -# |<-18x-----|--PUBLISH(early)------>| -# | | | | -# | |<-200-----| | -# |<-200-----|--PUBLISH(confirmed)-->| -# |--ACK---->| | | -# | |--ACK---->| | -# | | | | -# -# -# Unsuccessful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |--PUBLISH(trying)----->| -# | |<-100-----| | -# | | | | -# | |<-456xx---| | -# | |--PUBLISH(terminated)->| -# |<-456xx---|--ACK---->| | -# |--ACK---->| | | -... - -1.3.6. nopublish_flag (str) - - By default, reINVITEs will trigger a PUBLISH. They are actually - the only in-dialog request for which it makes sense. In some - cases, it does not make sense to republish a dialog state. - (e.g. when handling a B2BUA reINVITE). This setting defines the - flag that needs to be set in the request route to prevent the - generation of a PUBLISH request in case of a specific reINVITE. - - Example 1.7. Set nopublish_flag parameter -... -modparam("pua_dialoginfo", "nopublish_flag", "no_publish") -... - -1.3.7. presence_server (string) - - The address of the presence server, where the PUBLISH messages - should be sent (not compulsory). - - Example 1.8. Set presence_server parameter -... -modparam("pua_dialoginfo", "presence_server", "sip:ps@opensips.org:5060" -) -... - -1.3.8. caller_spec_param (string) - - The name of the pseudovariable that will hold a custom caller - URI. If this variable is not set, the information in From - header is used. If you want to use another caller definition, - you have to fill in this pseudovariable before calling - dialoginfo_set() function. The format of the string resemples - the format of To/From SIP headers: "display_name" or - "sip_uri". - - Example 1.9. Set caller_spec_param parameter -... -modparam("pua_dialoginfo", "caller_spec_param", "$avp(10)") -... - -1.3.9. callee_spec_param (string) - - The name of the pseudovariable that will hold the callee URI. - If this variable will not be set, the callee information used - will be made of To display uri + RURI. the. The format of the - string to set this pseudovariable to is the same as described - in caller_spec_param section. - - Example 1.10. Set caller_spec_param parameter -... -modparam("pua_dialoginfo", "callee_spec_param", "$avp(11)") -... - -1.3.10. osips_ps (int) - - It is advisable to specify if you use a different presence - server than OpenSIPS presence server, by setting this parameter - to 0. By default, a trick (version in the Publish body is set - '0000000') is used when working with Opensips Presence Server - to make the processing faster and this might not be accepted by - other presence servers. - - Default value is “1”. - - Example 1.11. Set osips_ps parameter -... -modparam("pua_dialoginfo", "osips_ps", 0) -... - -1.4. Exported Functions - -1.4.1. dialoginfo_set([side]) - - This function must be called for INVITE messages that - initialize a dialog for which dialoginfo information must be - published. - - Meaning of the parameters: - * side (string, optional) - can be "A" or/and "B" for caller - or callee PUBLISH only - if missing, both sides will be - published. - - Example 1.12. dialoginfo_set usage -... - if(is_method("INVITE")) - if($ru =~ "opensips.org") - dialoginfo_set(); -... - -1.4.2. dialoginfo_set_branch_callee(callee) - - This function is to be used only from a branch route for - setting a per-branch callee/peer specification. This peer value - will be used onyl for the dialoginfo record created for that - particular branch. - - This function makes sense only in call forking (serial / - parallel) scenarios, where a caller may be in relation with - multiple different callees. - - Meaning of the parameters: - * callee (string) - a SIP nams addr description of the callee - (the name_addr format is '[display] ' or 'uri', as in - the To or From headers) - - Example 1.13. dialoginfo_set_branch_callee usage -... -branch_route[out] -{ -.... - #align the published info with the RURI of the branch - dialoginfo_set_branch_callee("sip:$rU@opensips.org"); -... -} - -1.4.3. dialoginfo_mute_branch([side]) - - This function must be called for INVITE messages, in the branch - route only, in order to mute the publishing of the dialoginfo - information for caller/callee/both parties involved in that - branch. - - Meaning of the parameters: - * side (string, optional) - can be "A" or/and "B" for caller - or callee muting only - if missing, both sides will be - muted. - - Example 1.14. dialoginfo_mute_branch usage -... - branch_route[out] { - # mute publishing for callee side if not a local domain - if (!is_domain_local("$rd")) - dialoginfo_mute_branch("B"); - } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 58 34 1205 742 - 2. Anca Vamanu 26 16 713 231 - 3. Liviu Chircu (@liviuchircu) 13 10 44 78 - 4. Razvan Crainea (@razvancrainea) 12 10 19 18 - 5. Klaus Darilion 11 1 1109 0 - 6. Vlad Patrascu (@rvlad-patrascu) 9 6 117 120 - 7. Ovidiu Sas (@ovidiusas) 7 5 104 9 - 8. Vallimamod Abdullah 5 2 97 75 - 9. Damien Sandras (@dsandras) 4 2 93 1 - 10. Vlad Paiu (@vladpaiu) 4 2 29 15 - - All remaining contributors: Walter Doekes (@wdoekes), Stanislaw - Pitucha, Maksym Sobolyev (@sobomax), Peter Lemenkov - (@lemenkov), Zero King (@l2dy), Aron Podrigal (@ar45). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2009 - Jun 2021 - 5. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2020 - 6. Zero King (@l2dy) Mar 2020 - Mar 2020 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 8. Aron Podrigal (@ar45) Jan 2019 - Jan 2019 - 9. Ovidiu Sas (@ovidiusas) Sep 2010 - Jan 2014 - 10. Damien Sandras (@dsandras) Jul 2013 - Aug 2013 - - All remaining contributors: Vlad Paiu (@vladpaiu), Anca Vamanu, - Vallimamod Abdullah, Stanislaw Pitucha, Walter Doekes - (@wdoekes), Klaus Darilion. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Ovidiu - Sas (@ovidiusas), Damien Sandras (@dsandras), Vallimamod - Abdullah, Anca Vamanu, Walter Doekes (@wdoekes), Klaus - Darilion. - - Documentation Copyrights: - - Copyright © 2014 VoIP Embedded, Inc. - - Copyright © 2008 Klaus Darilion IPCom - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/pua_dialoginfo/README.md b/modules/pua_dialoginfo/README.md new file mode 100644 index 00000000000..8d05f49ab0b --- /dev/null +++ b/modules/pua_dialoginfo/README.md @@ -0,0 +1,546 @@ +--- +title: "PUA dialoginfo module" +description: "The pua_dialoginfo retrieves dialog state information from the dialog module and PUBLISHes the dialog-information using the pua module." +--- + +## Admin Guide + + +### Overview + + +The pua_dialoginfo retrieves dialog state information from the +dialog module and PUBLISHes the dialog-information using the pua +module. Thus, in combination with the presence_xml module this can +be used to derive dialog-info from the dialog module and NOTIFY +the subscribed watchers about dialog-info changes. This can be used +for example with SNOM and Linksys phones. + + +> [!NOTE] +> This implements dialog-info according to RFC 4235 and is not +> compatible with the BLA feature defined in draft-anil-sipping-bla-03.txt. +> (Actually the BLA draft is really crap as it changes SIP semantics) + + +The module is based on code (copy/paste) from pua_usrloc and nat_traversal +module. + + +Following you will show some examples of an dialog-info XML document taken +from RFC 4235. This will help you to understand the meaning of the module +parameters: + + +```xml + + + + early + + +``` + + +The root element is the "dialog-info". It contains the namespace, the +version (which must be incremented for each new PUBLISH for this certain +dialog), the state (this module only supports state=full) and the entity +for which we publish the dialog-info. + + +The "dialog" element must contain an id parameter. The id parameter is +usually different to the optional call-id parameter (which is the call-id of the +INVITE request) as an INVITE can create multiple dialogs (forked request). But +as the dialog module does not support multiple dialogs created by a single +transaction, the pua_dialoginfo module sets the id parameter to the same +value as the call-id parameter. The "local-tag" indicates the local tag of the +entity. The remote-tag indicates the tag of the remote party. The "direction" +indicates if the entity was the initator of the dialog or the recepient (aka +if the entity sent or received the first INVITE). + + +The "state" element describes the state of the dialog state machine and must be +either: trying, proceeding, early, confirmed or terminated. + + +The dialog element can contain optional "local" and "remote" elements which +describes the local and the remote party in more detail, for example: + + +```xml + + + + early + + sip:alice@example.com + + + + sip:bob@example.org + + + + +``` + + +The local and remote elements are needed to implement call pickup. For example if +the above XML document is received by somebody who SUBSCRIBEd the dialog-info of +Alice, then it can pick-up the call by sending an INVITE to Bob (actually I am not +sure if it should use the URI in the identity element or the URI in the target +parameter) which contains a Replaces header which contains the call-id and the tags. +This was tested successfully with Linksys SPA962 phones and with SNOM 320 Firmware 7.3.7 +(you have to set the function key to "Extension"). + + +A dialog-info XML document may contain multiple "dialog" elements, for +example if the entity has multiple ongoing dialogs. For example the +following XML document shows a confirmed dialog and an early (probably +a second incoming call) dialog. + + +```xml + + + + confirmed + + + early + + +``` + + +To enable dialoginfo notifications for a certain dialog, you must call +[dialoginfo set](#func_dialoginfo_set) function for that dialog. +This function can take one parameter which through which you can tell the +module to publish dialoginfo only for one side of the call. This is useful +because you want to store dialoginfo only for the local users, and you can +decide from the script if the call parties are local users and give the correct +parameter to this function to tell it to send generate dialoginfo only for the +local users. The possible values are : "A" - corresponding to generate dialoginfo +only for the caller and "B" - generate dialoginfo only for the callee. If no parameter +is given, the module will generate dialoginfo for both parties. + +It is possible to specify what URIs should be used for caller and callee by setting the +the pseudovariables with the names defined as module parameter "caller_spec_param" and +"callee_spec_param" before calling [dialoginfo set](#func_dialoginfo_set) function. +Please read the description of this parameters in +[exported parameters](#exported_parameters) section. If this parameters are +not set, the default sources will be used, From header for the caller +and display name in To header + RURI for the callee. + + +As the dialog module callbacks only address a certain dialog, the pua_dialoginfo +always PUBLISHes XML documents with a single "dialog" element. If an entity +has multiple concurrent dialogs, the pua_dialoginfo module will send PUBLISH for +each dialog. These multiple "presenties" can be aggregated by the presence_dialoginfo +module into a single XML document with multiple "dialog" elements. Please see the +description of the presence_dialoginfo module for details about the aggregation. + + +If there are problems with the callbacks from dialog module and you want to +debug them you define PUA_DIALOGINFO_DEBUG in pua_dialoginfo.c and recompile. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog*. +- *pua*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml*. + + +### Exported Parameters + + +#### include_callid (int) + + +If this parameter is set, the optional call-id will be put into the +dialog element. This is needed for call-pickup features. + + +*Default value is "1".* + + +```opensips title="Set include_callid parameter" +... +modparam("pua_dialoginfo", "include_callid", 0) +... +``` + + +#### include_tags (int) + + +If this parameter is set, the local and remote tag will be put +into the dialog element. This is needed for call-pickup features. + + +*Default value is "1".* + + +```opensips title="Set include_tags parameter" +... +modparam("pua_dialoginfo", "include_tags", 0) +... +``` + + +#### include_localremote (int) + + +If this parameter is set, the optional local and remote elements +will be put into the dialog element. This is needed for call-pickup +features. + + +*Default value is "1".* + + +```opensips title="Set include_localremote parameter" +... +modparam("pua_dialoginfo", "include_localremote", 0) +... +``` + + +#### caller_confirmed (int) + + +Usually the dialog-info of the caller will be +"trying -> early -> confirmed" and the dialog-info of the callee +will be "early -> confirmed". On some phones the function LED +will start blinking if the state is early, regardless if is is the +caller or the callee (indicated with the "direction" parameter). +To avoid blinking LEDs for the caller, you can enable this parameter. +Then the state of the caller will be singaled as "confirmed" even +in "early" state. This is a workaround for the buggy Linksys SPA962 +phones. SNOM phones work well with the default setting. + + +*Default value is "0".* + + +```opensips title="Set caller_confirmed parameter" +... +modparam("pua_dialoginfo", "caller_confirmed", 1) +... +``` + + +#### publish_on_trying (int) + + +Usually the dialog-info of the caller will be +"trying -> early -> confirmed". The "trying" state will be triggered as soon +as you call [dialoginfo set](#func_dialoginfo_set) on the caller, while "early" is triggered +as soon as the callee is ringing (triggered by a 180 or 183 provisional reply). +Sometimes, it is advisable to be notified only when the callee reaches +the early state and not before. In other cases, it is advisable to +notify the early state. This setting allows controlling the behavior. + + +The intended purpose of this parameter is to reduce the rate of notifications +(see RFC4235, section 3.10. Rate of Notifications). + + +*Default value is "0".* + + +```opensips title="Set publish_on_trying parameter to 0" +... +modparam("pua_dialoginfo", "publish_on_trying", 0) + +# Successful call scenario: +# +# UAC proxy UAS presence server +# |--INVITE->| | | +# |<-100-----|--INVITE->| | +# | |<-100-----| | +# | | | | +# | |<-18x-----| | +# |<-18x-----|--PUBLISH(early)------>| +# | | | | +# | |<-200-----| | +# |<-200-----|--PUBLISH(confirmed)-->| +# |--ACK---->| | | +# | |--ACK---->| | +# | | | | +# +# +# Unsuccessful call scenario: +# +# UAC proxy UAS presence server +# |--INVITE->| | | +# |<-100-----|--INVITE->| | +# | |<-100-----| | +# | | | | +# | |<-456xx---| | +# |<-456xx---|--ACK---->| | +# |--ACK---->| | | +... +``` + + +```opensips title="Set publish_on_trying parameter to 1" +... +modparam("pua_dialoginfo", "publish_on_trying", 1) + +# Successful call scenario: +# +# UAC proxy UAS presence server +# |--INVITE->| | | +# |<-100-----|--INVITE->| | +# | |--PUBLISH(trying)----->| +# | |<-100-----| | +# | | | | +# | |<-18x-----| | +# |<-18x-----|--PUBLISH(early)------>| +# | | | | +# | |<-200-----| | +# |<-200-----|--PUBLISH(confirmed)-->| +# |--ACK---->| | | +# | |--ACK---->| | +# | | | | +# +# +# Unsuccessful call scenario: +# +# UAC proxy UAS presence server +# |--INVITE->| | | +# |<-100-----|--INVITE->| | +# | |--PUBLISH(trying)----->| +# | |<-100-----| | +# | | | | +# | |<-456xx---| | +# | |--PUBLISH(terminated)->| +# |<-456xx---|--ACK---->| | +# |--ACK---->| | | +... +``` + + +#### nopublish_flag (str) + + +By default, reINVITEs will trigger a PUBLISH. They are actually +the only in-dialog request for which it makes sense. +In some cases, it does not make sense to republish a dialog state. +(e.g. when handling a B2BUA reINVITE). +This setting defines the flag that needs to be set in the request +route to prevent the generation of a PUBLISH request in case of a +specific reINVITE. + + +```opensips title="Set nopublish_flag parameter" +... +modparam("pua_dialoginfo", "nopublish_flag", "no_publish") +... +``` + + +#### presence_server (string) + + +The address of the presence server, where the PUBLISH messages +should be sent (not compulsory). + + +```opensips title="Set presence_server parameter" +... +modparam("pua_dialoginfo", "presence_server", "sip:ps@opensips.org:5060") +... +``` + + +#### caller_spec_param (string) + + +The name of the pseudovariable that will hold a custom caller URI. +If this variable is not set, the information in From header is used. +If you want to use another caller definition, you have to fill in this +pseudovariable before calling [dialoginfo set](#func_dialoginfo_set) +function. The format of the string +resemples the format of To/From SIP headers: +"display_name" or "sip_uri". + + +```opensips title="Set caller_spec_param parameter" +... +modparam("pua_dialoginfo", "caller_spec_param", "$avp(10)") +... + +``` + + +#### callee_spec_param (string) + + +The name of the pseudovariable that will hold the callee URI. +If this variable will not be set, the callee information used +will be made of To display uri + RURI. +the. The format of the string to set this pseudovariable to is +the same as described in caller_spec_param section. + + +```opensips title="Set caller_spec_param parameter" +... +modparam("pua_dialoginfo", "callee_spec_param", "$avp(11)") +... + +``` + + +#### osips_ps (int) + + +It is advisable to specify if you use a different presence server +than OpenSIPS presence server, by setting this parameter to 0. +By default, a trick (version in the Publish body is set '0000000') is +used when working with Opensips Presence Server +to make the processing faster and this might not be accepted by other +presence servers. + + +*Default value is "1".* + + +```opensips title="Set osips_ps parameter" +... +modparam("pua_dialoginfo", "osips_ps", 0) +... + +``` + + +### Exported Functions + + +#### dialoginfo_set([side]) + + +This function must be called for INVITE messages that initialize a +dialog for which dialoginfo information must be published. + + +Meaning of the parameters: + + +- *side* (string, optional) - can be "A" or/and "B" +for caller or callee PUBLISH only - if missing, both sides will +be published. + + +```opensips title="dialoginfo_set usage" +... + if(is_method("INVITE")) + if($ru =~ "opensips.org") + dialoginfo_set(); +... + +``` + + +#### dialoginfo_set_branch_callee(callee) + + +This function is to be used only from a branch route for setting +a per-branch callee/peer specification. This peer value will be used +onyl for the dialoginfo record created for that particular branch. + + +This function makes sense only in call forking (serial / parallel) +scenarios, where a caller may be in relation with multiple different +callees. + + +Meaning of the parameters: + + +- *callee* (string) - a SIP nams addr description of +the callee (the name_addr format is '[display] ' or +'uri', as in the To or From headers) + + +```opensips title="dialoginfo_set_branch_callee usage" +... +branch_route[out] +{ +.... + #align the published info with the RURI of the branch + dialoginfo_set_branch_callee("sip:$rU@opensips.org"); +... +} + +``` + + +#### dialoginfo_mute_branch([side]) + + +This function must be called for INVITE messages, in the branch route +only, in order to mute the publishing of the dialoginfo information +for caller/callee/both parties involved in that branch. + + +Meaning of the parameters: + + +- *side* (string, optional) - can be +"A" or/and "B" for caller or callee muting only - if missing, +both sides will be muted. + + +```opensips title="dialoginfo_mute_branch usage" +... + branch_route[out] { + # mute publishing for callee side if not a local domain + if (!is_domain_local("$rd")) + dialoginfo_mute_branch("B"); + } +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_dialoginfo/doc/contributors.xml b/modules/pua_dialoginfo/doc/contributors.xml deleted file mode 100644 index 49a8e0e04a1..00000000000 --- a/modules/pua_dialoginfo/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 58 - 34 - 1205 - 742 - - - 2. - Anca Vamanu - 26 - 16 - 713 - 231 - - - 3. - Liviu Chircu (@liviuchircu) - 13 - 10 - 44 - 78 - - - 4. - Razvan Crainea (@razvancrainea) - 12 - 10 - 19 - 18 - - - 5. - Klaus Darilion - 11 - 1 - 1109 - 0 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 9 - 6 - 117 - 120 - - - 7. - Ovidiu Sas (@ovidiusas) - 7 - 5 - 104 - 9 - - - 8. - Vallimamod Abdullah - 5 - 2 - 97 - 75 - - - 9. - Damien Sandras (@dsandras) - 4 - 2 - 93 - 1 - - - 10. - Vlad Paiu (@vladpaiu) - 4 - 2 - 29 - 15 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Stanislaw Pitucha, Maksym Sobolyev (@sobomax), Peter Lemenkov (@lemenkov), Zero King (@l2dy), Aron Podrigal (@ar45). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2009 - Jun 2021 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2020 - - - 6. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 8. - Aron Podrigal (@ar45) - Jan 2019 - Jan 2019 - - - 9. - Ovidiu Sas (@ovidiusas) - Sep 2010 - Jan 2014 - - - 10. - Damien Sandras (@dsandras) - Jul 2013 - Aug 2013 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Anca Vamanu, Vallimamod Abdullah, Stanislaw Pitucha, Walter Doekes (@wdoekes), Klaus Darilion. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Ovidiu Sas (@ovidiusas), Damien Sandras (@dsandras), Vallimamod Abdullah, Anca Vamanu, Walter Doekes (@wdoekes), Klaus Darilion. -
- -
diff --git a/modules/pua_dialoginfo/doc/pua_dialoginfo.xml b/modules/pua_dialoginfo/doc/pua_dialoginfo.xml deleted file mode 100644 index 9304a2b7ba7..00000000000 --- a/modules/pua_dialoginfo/doc/pua_dialoginfo.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - pua dialoginfo - &osips; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2014 VoIP Embedded, Inc. - ©right; 2008 Klaus Darilion IPCom - ©right; 2006 &voicesystem; - - - diff --git a/modules/pua_dialoginfo/doc/pua_dialoginfo_admin.xml b/modules/pua_dialoginfo/doc/pua_dialoginfo_admin.xml deleted file mode 100644 index 7cc850312c8..00000000000 --- a/modules/pua_dialoginfo/doc/pua_dialoginfo_admin.xml +++ /dev/null @@ -1,603 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The pua_dialoginfo retrieves dialog state information from the - dialog module and PUBLISHes the dialog-information using the pua - module. Thus, in combination with the presence_xml module this can - be used to derive dialog-info from the dialog module and NOTIFY - the subscribed watchers about dialog-info changes. This can be used - for example with SNOM and Linksys phones. - - - Note: This implements dialog-info according to RFC 4235 and is not - compatible with the BLA feature defined in draft-anil-sipping-bla-03.txt. - (Actually the BLA draft is really crap as it changes SIP semantics) - - - The module is based on code (copy/paste) from pua_usrloc and nat_traversal - module. - - - Following you will show some examples of an dialog-info XML document taken - from RFC 4235. This will help you to understand the meaning of the module - parameters: - - - - - - early - - -]]> - - - The root element is the "dialog-info". It contains the namespace, the - version (which must be incremented for each new PUBLISH for this certain - dialog), the state (this module only supports state=full) and the entity - for which we publish the dialog-info. - - - - - The "dialog" element must contain an id parameter. The id parameter is - usually different to the optional call-id parameter (which is the call-id of the - INVITE request) as an INVITE can create multiple dialogs (forked request). But - as the dialog module does not support multiple dialogs created by a single - transaction, the pua_dialoginfo module sets the id parameter to the same - value as the call-id parameter. The "local-tag" indicates the local tag of the - entity. The remote-tag indicates the tag of the remote party. The "direction" - indicates if the entity was the initator of the dialog or the recepient (aka - if the entity sent or received the first INVITE). - - - - - The "state" element describes the state of the dialog state machine and must be - either: trying, proceeding, early, confirmed or terminated. - - - - - The dialog element can contain optional "local" and "remote" elements which - describes the local and the remote party in more detail, for example: - - - - - - early - - sip:alice@example.com - - - - sip:bob@example.org - - - - -]]> - - - The local and remote elements are needed to implement call pickup. For example if - the above XML document is received by somebody who SUBSCRIBEd the dialog-info of - Alice, then it can pick-up the call by sending an INVITE to Bob (actually I am not - sure if it should use the URI in the identity element or the URI in the target - parameter) which contains a Replaces header which contains the call-id and the tags. - This was tested successfully with Linksys SPA962 phones and with SNOM 320 Firmware 7.3.7 - (you have to set the function key to "Extension"). - - - - - A dialog-info XML document may contain multiple "dialog" elements, for - example if the entity has multiple ongoing dialogs. For example the - following XML document shows a confirmed dialog and an early (probably - a second incoming call) dialog. - - - - - - confirmed - - - early - - -]]> - - - To enable dialoginfo notifications for a certain dialog, you must call - function for that dialog. - This function can take one parameter which through which you can tell the - module to publish dialoginfo only for one side of the call. This is useful - because you want to store dialoginfo only for the local users, and you can - decide from the script if the call parties are local users and give the correct - parameter to this function to tell it to send generate dialoginfo only for the - local users. The possible values are : "A" - corresponding to generate dialoginfo - only for the caller and "B" - generate dialoginfo only for the callee. If no parameter - is given, the module will generate dialoginfo for both parties. - - It is possible to specify what URIs should be used for caller and callee by setting the - the pseudovariables with the names defined as module parameter "caller_spec_param" and - "callee_spec_param" before calling function. - Please read the description of this parameters in - section. If this parameters are - not set, the default sources will be used, From header for the caller - and display name in To header + RURI for the callee. - - - As the dialog module callbacks only address a certain dialog, the pua_dialoginfo - always PUBLISHes XML documents with a single "dialog" element. If an entity - has multiple concurrent dialogs, the pua_dialoginfo module will send PUBLISH for - each dialog. These multiple "presenties" can be aggregated by the presence_dialoginfo - module into a single XML document with multiple "dialog" elements. Please see the - description of the presence_dialoginfo module for details about the aggregation. - - - - - If there are problems with the callbacks from dialog module and you want to - debug them you define PUA_DIALOGINFO_DEBUG in pua_dialoginfo.c and recompile. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog. - - - - - pua. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml. - - - - -
-
- -
- Exported Parameters - -
- <varname>include_callid</varname> (int) - - If this parameter is set, the optional call-id will be put into the - dialog element. This is needed for call-pickup features. - - - Default value is 1. - - - Set <varname>include_callid</varname> parameter - -... -modparam("pua_dialoginfo", "include_callid", 0) -... - - -
- -
- <varname>include_tags</varname> (int) - - If this parameter is set, the local and remote tag will be put - into the dialog element. This is needed for call-pickup features. - - - Default value is 1. - - - Set <varname>include_tags</varname> parameter - -... -modparam("pua_dialoginfo", "include_tags", 0) -... - - -
- -
- <varname>include_localremote</varname> (int) - - If this parameter is set, the optional local and remote elements - will be put into the dialog element. This is needed for call-pickup - features. - - - Default value is 1. - - - Set <varname>include_localremote</varname> parameter - -... -modparam("pua_dialoginfo", "include_localremote", 0) -... - - -
- -
- <varname>caller_confirmed</varname> (int) - - Usually the dialog-info of the caller will be - "trying -> early -> confirmed" and the dialog-info of the callee - will be "early -> confirmed". On some phones the function LED - will start blinking if the state is early, regardless if is is the - caller or the callee (indicated with the "direction" parameter). - To avoid blinking LEDs for the caller, you can enable this parameter. - Then the state of the caller will be singaled as "confirmed" even - in "early" state. This is a workaround for the buggy Linksys SPA962 - phones. SNOM phones work well with the default setting. - - - Default value is 0. - - - Set <varname>caller_confirmed</varname> parameter - -... -modparam("pua_dialoginfo", "caller_confirmed", 1) -... - - -
- -
- <varname>publish_on_trying</varname> (int) - - Usually the dialog-info of the caller will be - "trying -> early -> confirmed". The "trying" state will be triggered as soon - as you call on the caller, while "early" is triggered - as soon as the callee is ringing (triggered by a 180 or 183 provisional reply). - Sometimes, it is advisable to be notified only when the callee reaches - the early state and not before. In other cases, it is advisable to - notify the early state. This setting allows controlling the behavior. - - - The intended purpose of this parameter is to reduce the rate of notifications - (see RFC4235, section 3.10. Rate of Notifications). - - - Default value is 0. - - - Set <varname>publish_on_trying</varname> parameter to 0 - -... -modparam("pua_dialoginfo", "publish_on_trying", 0) - -# Successful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |<-100-----| | -# | | | | -# | |<-18x-----| | -# |<-18x-----|--PUBLISH(early)------>| -# | | | | -# | |<-200-----| | -# |<-200-----|--PUBLISH(confirmed)-->| -# |--ACK---->| | | -# | |--ACK---->| | -# | | | | -# -# -# Unsuccessful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |<-100-----| | -# | | | | -# | |<-456xx---| | -# |<-456xx---|--ACK---->| | -# |--ACK---->| | | -... - - - - Set <varname>publish_on_trying</varname> parameter to 1 - -... -modparam("pua_dialoginfo", "publish_on_trying", 1) - -# Successful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |--PUBLISH(trying)----->| -# | |<-100-----| | -# | | | | -# | |<-18x-----| | -# |<-18x-----|--PUBLISH(early)------>| -# | | | | -# | |<-200-----| | -# |<-200-----|--PUBLISH(confirmed)-->| -# |--ACK---->| | | -# | |--ACK---->| | -# | | | | -# -# -# Unsuccessful call scenario: -# -# UAC proxy UAS presence server -# |--INVITE->| | | -# |<-100-----|--INVITE->| | -# | |--PUBLISH(trying)----->| -# | |<-100-----| | -# | | | | -# | |<-456xx---| | -# | |--PUBLISH(terminated)->| -# |<-456xx---|--ACK---->| | -# |--ACK---->| | | -... - - -
- -
- <varname>nopublish_flag</varname> (str) - - By default, reINVITEs will trigger a PUBLISH. They are actually - the only in-dialog request for which it makes sense. - In some cases, it does not make sense to republish a dialog state. - (e.g. when handling a B2BUA reINVITE). - This setting defines the flag that needs to be set in the request - route to prevent the generation of a PUBLISH request in case of a - specific reINVITE. - - - Set <varname>nopublish_flag</varname> parameter - -... -modparam("pua_dialoginfo", "nopublish_flag", "no_publish") -... - - -
- -
- <varname>presence_server</varname> (string) - - The address of the presence server, where the PUBLISH messages - should be sent (not compulsory). - - - Set <varname>presence_server</varname> parameter - -... -modparam("pua_dialoginfo", "presence_server", "sip:ps@opensips.org:5060") -... - - -
- -
- <varname>caller_spec_param</varname> (string) - - The name of the pseudovariable that will hold a custom caller URI. - If this variable is not set, the information in From header is used. - If you want to use another caller definition, you have to fill in this - pseudovariable before calling - function. The format of the string - resemples the format of To/From SIP headers: - "display_name<sip_uri>" or "sip_uri". - - - Set <varname>caller_spec_param</varname> parameter - -... -modparam("pua_dialoginfo", "caller_spec_param", "$avp(10)") -... - - -
- -
- <varname>callee_spec_param</varname> (string) - - The name of the pseudovariable that will hold the callee URI. - If this variable will not be set, the callee information used - will be made of To display uri + RURI. - the. The format of the string to set this pseudovariable to is - the same as described in caller_spec_param section. - - - Set <varname>caller_spec_param</varname> parameter - -... -modparam("pua_dialoginfo", "callee_spec_param", "$avp(11)") -... - - -
- -
- <varname>osips_ps</varname> (int) - - It is advisable to specify if you use a different presence server - than OpenSIPS presence server, by setting this parameter to 0. - By default, a trick (version in the Publish body is set '0000000') is - used when working with Opensips Presence Server - to make the processing faster and this might not be accepted by other - presence servers. - - - Default value is 1. - - - Set <varname>osips_ps</varname> parameter - -... -modparam("pua_dialoginfo", "osips_ps", 0) -... - - -
- - -
- -
- Exported Functions -
- - <function moreinfo="none">dialoginfo_set([side])</function> - - - This function must be called for INVITE messages that initialize a - dialog for which dialoginfo information must be published. - - - Meaning of the parameters: - - - - side (string, optional) - can be "A" or/and "B" - for caller or callee PUBLISH only - if missing, both sides will - be published. - - - - <function>dialoginfo_set</function> usage - -... - if(is_method("INVITE")) - if($ru =~ "opensips.org") - dialoginfo_set(); -... - - -
- -
- - <function moreinfo="none">dialoginfo_set_branch_callee(callee)</function> - - - This function is to be used only from a branch route for setting - a per-branch callee/peer specification. This peer value will be used - onyl for the dialoginfo record created for that particular branch. - - - This function makes sense only in call forking (serial / parallel) - scenarios, where a caller may be in relation with multiple different - callees. - - - Meaning of the parameters: - - - - callee (string) - a SIP nams addr description of - the callee (the name_addr format is '[display] <uri>' or - 'uri', as in the To or From headers) - - - - - <function>dialoginfo_set_branch_callee</function> usage - -... -branch_route[out] -{ -.... - #align the published info with the RURI of the branch - dialoginfo_set_branch_callee("sip:$rU@opensips.org"); -... -} - - -
- -
- - <function moreinfo="none">dialoginfo_mute_branch([side])</function> - - - This function must be called for INVITE messages, in the branch route - only, in order to mute the publishing of the dialoginfo information - for caller/callee/both parties involved in that branch. - - - Meaning of the parameters: - - - - side (string, optional) - can be - "A" or/and "B" for caller or callee muting only - if missing, - both sides will be muted. - - - - <function>dialoginfo_mute_branch</function> usage - -... - branch_route[out] { - # mute publishing for callee side if not a local domain - if (!is_domain_local("$rd")) - dialoginfo_mute_branch("B"); - } -... - - -
- -
- -
- diff --git a/modules/pua_dialoginfo/pua_dialoginfo.c b/modules/pua_dialoginfo/pua_dialoginfo.c index b5f4d7902c1..881634c7003 100644 --- a/modules/pua_dialoginfo/pua_dialoginfo.c +++ b/modules/pua_dialoginfo/pua_dialoginfo.c @@ -200,7 +200,44 @@ __tm_sendpublish(struct cell *t, int type, struct tmcb_params *_params) peer = &(param->peer); entity = &(param->entity); - /* this is triggered only for TMCB_RESPONSE_IN */ + if (type==TMCB_ON_FAILURE) { + /* the transaction completed with a failure - explicitly terminate + * any branches still in "early" state which never received a final + * negative reply (e.g. UAS went silent after sending 180), otherwise + * their published state will linger until it expires */ + if (get_callid(_params->req, &callid) < 0) + return; + + if (include_tags) { + if(parse_from_header( _params->req )<0 + || parse_to_header( _params->req )<0 ) { + LM_ERR("failed to parse the request\n"); + return; + } + ftag = &(get_from(_params->req)->tag_value); + ttag = &(get_to(_params->req)->tag_value); + } else { + ftag = ttag = NULL; + } + + /* note: this callback runs under the transaction's reply lock, + * so it is safe to test/set the bitmasks here */ + for (branch=t->first_branch; branchnr_of_outgoings; branch++) { + if ((param->bitmask_early & (((long long)1) << branch)) && + !(param->bitmask_failed & (((long long)1) << branch))) + continue; + param->bitmask_failed |= (((long long)1)<flags & DLG_PUB_A) + dialog_publish("terminated", entity, peer, + &callid, branch, 1, 0, ftag, ttag); + if (param->flags & DLG_PUB_B) + dialog_publish("terminated", peer, entity, + &callid, branch, 0, 0, ttag, ftag); + } + return; + } + + /* from here on, handling of TMCB_RESPONSE_IN */ branch = tm_api.get_branch_index(); LM_DBG("TM event %d [%d/%d] received, entity [%.*s], peer [%.*s]," @@ -266,7 +303,7 @@ __tm_sendpublish(struct cell *t, int type, struct tmcb_params *_params) /* depending on the reply code, see what to publish */ if (_params->code<180 && _params->code>=100) { - expire = t->uac[branch].request.fr_timer.time_out - get_ticks(); + expire = DEFAULT_CREATED_LIFETIME; if (publish_on_trying) { if (should_publish_A( param->flags, mute_val.s)) dialog_publish("trying", entity, peer, @@ -292,7 +329,7 @@ __tm_sendpublish(struct cell *t, int type, struct tmcb_params *_params) lock_release(&t->reply_mutex); if (n) { - expire = t->uac[branch].request.fr_timer.time_out - get_ticks(); + expire = DEFAULT_CREATED_LIFETIME; if (should_publish_A( param->flags, mute_val.s)) dialog_publish(caller_confirmed?"confirmed":"early", entity, peer, @@ -653,7 +690,6 @@ int dialoginfo_process_body(struct publ_info* publ, str** fin_body, if (*fin_body == NULL) LM_DBG("NULL fin_body\n"); - xmlMemoryDump(); xmlCleanupParser(); return 1; @@ -662,7 +698,6 @@ int dialoginfo_process_body(struct publ_info* publ, str** fin_body, xmlFreeDoc(doc); if (body) pkg_free(body); - xmlMemoryDump(); xmlCleanupParser(); return -1; } @@ -1017,8 +1052,9 @@ int dialoginfo_set(struct sip_msg* msg, str* flag_s) return -1; } - /* register TM callback to get access to recevied replies */ - if (tm_api.register_tmcb( msg, NULL, TMCB_RESPONSE_IN, + /* register TM callback to get access to recevied replies and to + * the transaction failure (to clean up dangling early states) */ + if (tm_api.register_tmcb( msg, NULL, TMCB_RESPONSE_IN|TMCB_ON_FAILURE, __tm_sendpublish, (void*)param_tm, free_cb_param) != 1) { LM_ERR("cannot register TM callback for incoming replies\n"); goto end; @@ -1200,4 +1236,3 @@ int set_mute_branch(struct sip_msg* msg, str* parties) return 1; } - diff --git a/modules/pua_mi/README b/modules/pua_mi/README deleted file mode 100644 index d6ab3005966..00000000000 --- a/modules/pua_mi/README +++ /dev/null @@ -1,212 +0,0 @@ -PUA MI - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. presence_server (str) - - 1.4. Exported Functions - 1.5. Exported MI functions - - 1.5.1. pua_publish - 1.5.2. pua_subscribe - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set presence_server parameter - 1.2. pua_publish FIFO example - 1.3. pua_subscribe FIFO example - -Chapter 1. Admin Guide - -1.1. Overview - - The pua_mi offers the possibility to publish presence - information and subscribe to presence information via MI - transports. - - Using this module you can create independent - applications/scripts to publish not sip-related information - (e.g., system resources like CPU-usage, memory, number of - active subscribers ...). Also, this module allows non-SIP - speaking applications to subscribe presence information kept in - a SIP presence server. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * pua - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.3. Exported Parameters - -1.3.1. presence_server (str) - - The the address of the presence server. If set, it will be used - as outbound proxy when sending PUBLISH requests. - - Example 1.1. Set presence_server parameter -... -modparam("pua_mi", "presence_server", "sip:pa@opensips.org:5075") -... - -1.4. Exported Functions - - The module does not export functions to be used in - configuration script. - -1.5. Exported MI functions - -1.5.1. pua_publish - - Command parameters: - * presentity_uri - e.g. sip:system@opensips.org - * expires - Relative expires time in seconds (e.g. 3600). - * event_package - Event package that is target of published - information (e.g. presence). - * content_type (optional) - Content type of published - information (e.g. application/pidf+xml). If this parameter - is provided, the body parameter is also required. - * etag (optional) - ETag that publish should match. - * extra_headers (optional) - Extra headers added to PUBLISH - request. - * body (optioanl) - The body of the publish request - containing published information or missing if no published - information. It has to be a single line for FIFO transport. - If this parameter is provided, the content_type parameter - is also required. - - Example 1.2. pua_publish FIFO example -... - -opensips-cli -x mi pua_publish sip:system@opensips.org 3600 presence app -lication/pidf+xml openawayCPU:16 MEM:476 - - -1.5.2. pua_subscribe - - Command parameters: - * presentity_uri - e.g. sip:presentity@opensips.org - * watcher_uri - e.g. sip:watcher@opensips.org - * event_package - * expires - Relative time in seconds for the desired validity - of the subscription. - - Example 1.3. pua_subscribe FIFO example -... - -opensips-cli -x mi pua_subscribe sip:system@opensips.org sip:400@opensip -s.org presence 3600 - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 31 15 1246 267 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 15 13 42 53 - 3. Liviu Chircu (@liviuchircu) 11 9 26 43 - 4. Razvan Crainea (@razvancrainea) 11 9 16 17 - 5. Juha Heinanen (@juha-h) 11 7 160 73 - 6. Vlad Patrascu (@rvlad-patrascu) 11 4 293 226 - 7. Daniel-Constantin Mierla (@miconda) 9 7 32 29 - 8. Ovidiu Sas (@ovidiusas) 3 1 13 2 - 9. Maksym Sobolyev (@sobomax) 3 1 3 3 - 10. Konstantin Bokarius 3 1 2 5 - - All remaining contributors: Ken Rice, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Nov 2020 - 5. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2006 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - 9. Anca Vamanu Nov 2006 - Aug 2010 - 10. Juha Heinanen (@juha-h) Apr 2007 - May 2008 - - All remaining contributors: Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Julien - Blache. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Anca - Vamanu, Juha Heinanen (@juha-h), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/pua_mi/README.md b/modules/pua_mi/README.md new file mode 100644 index 00000000000..4f4a32cfabd --- /dev/null +++ b/modules/pua_mi/README.md @@ -0,0 +1,131 @@ +--- +title: "PUA MI" +description: "The pua_mi offers the possibility to publish presence information and subscribe to presence information via MI transports." +--- + +## Admin Guide + + +### Overview + + +The pua_mi offers the possibility to publish presence +information and subscribe to presence information via MI +transports. + + +Using this module you can create independent applications/scripts to +publish not sip-related information (e.g., system resources like +CPU-usage, memory, number of active subscribers ...). +Also, this module allows non-SIP speaking applications +to subscribe presence information kept in a SIP presence +server. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *pua* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### presence_server (str) + + +The the address of the presence server. If set, it will be +used as outbound proxy when sending PUBLISH requests. + + +```opensips title="Set presence_server parameter" +... +modparam("pua_mi", "presence_server", "sip:pa@opensips.org:5075") +... + +``` + + +### Exported Functions + + +The module does not export functions to be used +in configuration script. + + +### Exported MI Functions + + +#### pua_publish + + +Command parameters: + + +- *presentity_uri* + - e.g. sip:system@opensips.org +- *expires* + - Relative expires time in +seconds (e.g. 3600). +- *event_package* + - Event package that is +target of published information (e.g. presence). +- *content_type* (optional) + - Content type of published +information (e.g. application/pidf+xml). If this parameter +is provided, the *body* parameter is also required. +- *etag* (optional) + - ETag that publish should +match. +- *extra_headers* (optional) + - Extra headers added to PUBLISH +request. +- *body* (optioanl) + - The body of the publish +request containing published information or missing if +no published information. +It has to be a single line for FIFO transport. If this parameter +is provided, the *content_type* parameter is also required. + + +```bash title="pua_publish FIFO example" +opensips-cli -x mi pua_publish sip:system@opensips.org 3600 presence application/pidf+xml openawayCPU:16 MEM:476 +``` + + +#### pua_subscribe + + +Command parameters: + + +- *presentity_uri* - e.g. sip:presentity@opensips.org +- *watcher_uri* - e.g. sip:watcher@opensips.org +- *event_package* +- *expires* - Relative time in seconds for the desired validity of the subscription. + + +```bash title="pua_subscribe FIFO example" +opensips-cli -x mi pua_subscribe sip:system@opensips.org sip:400@opensips.org presence 3600 +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_mi/doc/contributors.xml b/modules/pua_mi/doc/contributors.xml deleted file mode 100644 index 925ec982b3b..00000000000 --- a/modules/pua_mi/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 31 - 15 - 1246 - 267 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 15 - 13 - 42 - 53 - - - 3. - Liviu Chircu (@liviuchircu) - 11 - 9 - 26 - 43 - - - 4. - Razvan Crainea (@razvancrainea) - 11 - 9 - 16 - 17 - - - 5. - Juha Heinanen (@juha-h) - 11 - 7 - 160 - 73 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 11 - 4 - 293 - 226 - - - 7. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 32 - 29 - - - 8. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 13 - 2 - - - 9. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - 10. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - -
-All remaining contributors: Ken Rice, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Nov 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2006 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - 9. - Anca Vamanu - Nov 2006 - Aug 2010 - - - 10. - Juha Heinanen (@juha-h) - Apr 2007 - May 2008 - - - -
-All remaining contributors: Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Julien Blache. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Anca Vamanu, Juha Heinanen (@juha-h), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/pua_mi/doc/pua_mi.xml b/modules/pua_mi/doc/pua_mi.xml deleted file mode 100644 index cf0f3d28ce9..00000000000 --- a/modules/pua_mi/doc/pua_mi.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - PUA MI - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - - - diff --git a/modules/pua_mi/doc/pua_mi_admin.xml b/modules/pua_mi/doc/pua_mi_admin.xml deleted file mode 100644 index 61b16ae5510..00000000000 --- a/modules/pua_mi/doc/pua_mi_admin.xml +++ /dev/null @@ -1,201 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The pua_mi offers the possibility to publish presence - information and subscribe to presence information via MI - transports. - - - Using this module you can create independent applications/scripts to - publish not sip-related information (e.g., system resources like - CPU-usage, memory, number of active subscribers ...). - Also, this module allows non-SIP speaking applications - to subscribe presence information kept in a SIP presence - server. - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - - pua - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - none - - - -
-
- -
- Exported Parameters -
- <varname>presence_server</varname> (str) - - The the address of the presence server. If set, it will be - used as outbound proxy when sending PUBLISH requests. - - - Set <varname>presence_server</varname> parameter - -... -modparam("pua_mi", "presence_server", "sip:pa@opensips.org:5075") -... - - -
-
- -
- Exported Functions - The module does not export functions to be used - in configuration script. -
-
- Exported MI functions -
- - <function moreinfo="none">pua_publish</function> - - - Command parameters: - - - - - presentity_uri - - e.g. sip:system@opensips.org - - - - - expires - - Relative expires time in - seconds (e.g. 3600). - - - - - event_package - - Event package that is - target of published information (e.g. presence). - - - - - content_type (optional) - - Content type of published - information (e.g. application/pidf+xml). If this parameter - is provided, the body parameter is also required. - - - - - etag (optional) - - ETag that publish should - match. - - - - - extra_headers (optional) - - Extra headers added to PUBLISH - request. - - - - - body (optioanl) - - The body of the publish - request containing published information or missing if - no published information. - It has to be a single line for FIFO transport. If this parameter - is provided, the content_type parameter is also required. - - - - - <function>pua_publish</function> FIFO example - -... -openawayCPU:16 MEM:476 -]]> - - -
- -
- - <function moreinfo="none">pua_subscribe</function> - - - Command parameters: - - - - - presentity_uri - - e.g. sip:presentity@opensips.org - - - - - watcher_uri - - e.g. sip:watcher@opensips.org - - - - - - event_package - - - - - expires - - Relative time in seconds for the desired validity of the subscription. - - - - - <function>pua_subscribe</function> FIFO example - -... - - - -
-
-
- diff --git a/modules/pua_reginfo/README b/modules/pua_reginfo/README deleted file mode 100644 index b924a92e10f..00000000000 --- a/modules/pua_reginfo/README +++ /dev/null @@ -1,322 +0,0 @@ -pua_reginfo Module - -Carsten Bock - - - -Edited by - -Carsten Bock - - - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Parameters - - 1.3.1. default_domain(str) - 1.3.2. publish_reginfo(int) - 1.3.3. outbound_proxy(str) - 1.3.4. server_address(str) - 1.3.5. ul_domain(str) - 1.3.6. ul_identities_key(str) - - 1.4. Functions - - 1.4.1. reginfo_handle_notify(uldomain) - 1.4.2. reginfo_subscribe(uri[, expires]) - 1.4.3. reginfo_update(aor) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_domain parameter - 1.2. Set publish_reginfo parameter - 1.3. Set outbound_proxy parameter - 1.4. Set server_address parameter - 1.5. Set ul_domain parameter - 1.6. Set ul_identities_key parameter - 1.7. reginfo_handle_notify usage - 1.8. reginfo_subscribe usage - 1.9. reginfo_subscribe usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module publishes information about "reg"-events according - to to RFC 3680. This can be used distribute the - registration-info status to the subscribed watchers. - - This module "PUBLISH"es information when a new user registers - at this server (e.g. when "save()" is called) to users, which - have subscribed for the reg-info for this user. - - This module can "SUBSCRIBE" for information at another server, - so it will receive "NOTIFY"-requests, when the information - about a user changes. - - And finally, it can process received "NOTIFY" requests and it - will update the local registry accordingly. - - Use cases for this might be: - * Keeping different Servers in Sync regarding the location - database - * Get notified, when a user registers: A presence-server, - which handles offline message storage for an account, would - get notified, when the user comes online. - * A client could subscribe to its own registration-status, so - he would get notified as soon as his account gets - administratively unregistered. - * ... - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * pua. - * usrloc. - -1.2.2. External Libraries or Applications - - None. - -1.3. Parameters - -1.3.1. default_domain(str) - - The default domain for the registered users to be used when - constructing the uri for the registrar callback. - - Default value is “NULL”. - - Example 1.1. Set default_domain parameter -... -modparam("pua_reginfo", "default_domain", "kamailio.org") -... - -1.3.2. publish_reginfo(int) - - Whether or not to generate PUBLISH requests. - - Default value is “1” (enabled). - - Example 1.2. Set publish_reginfo parameter -... -modparam("pua_reginfo", "publish_reginfo", 0) -... - -1.3.3. outbound_proxy(str) - - The outbound_proxy uri to be used when sending Subscribe and - Publish requests. - - Default value is “NULL”. - - Example 1.3. Set outbound_proxy parameter -... -modparam("pua_reginfo", "outbound_proxy", "sip:proxy@kamailio.org") -... - -1.3.4. server_address(str) - - The IP address of the server. - - Example 1.4. Set server_address parameter -... -modparam("pua_reginfo", "server_address", "sip:reginfo@160.34.23.12") -... - -1.3.5. ul_domain(str) - - The domain for for querying the usrloc-database. - - Default value is “NULL” (not set). - - Example 1.5. Set ul_domain parameter -... -modparam("pua_reginfo", "ul_domain", "location") -... - -1.3.6. ul_identities_key(str) - - The Key, which may be used for retrieving multiple public - identies for a user. - - Default value is “NULL” (not set). - - Example 1.6. Set ul_identities_key parameter -... -modparam("pua_reginfo", "ul_identities_key", "identities") -... -onreply_route[register_reply] { - if (t_check_status("200") && $hdr(P-Associated-URI)) { - ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associat -ed-URI)"); - reginfo_update("$tU@$td"); - } -} - -... - -1.4. Functions - -1.4.1. reginfo_handle_notify(uldomain) - - This function processes received "NOTIFY"-requests and updates - the local registry accordingly. - - This method does not create any SIP-Response, this has to be - done by the script-writer. - - The parameter has to correspond to user location table (domain) - where to store the record. - - Return codes: - * 2 - contacts successfully updated, but no more contacts - online now. - 1 - contacts successfully updated and at at least one - contact still registered. - -1 - Invalid NOTIFY or other error (see log-file) - - Example 1.7. reginfo_handle_notify usage -... -if(is_method("NOTIFY")) - if (reginfo_handle_notify("location")) - send_reply("202", "Accepted"); -... - -1.4.2. reginfo_subscribe(uri[, expires]) - - This function will subscribe for reginfo-information at the - given server URI. - - Meaning of the parameters is as follows: - * uri - SIP-URI of the server, where to subscribe, may - contain pseudo-variables. - expires - Expiration date for this subscription, in seconds - (default 3600) - - Example 1.8. reginfo_subscribe usage -... -route { - t_on_reply("1"); - t_relay(); -} - -reply_route[1] { - if (t_check_status("200")) - reginfo_subscribe("$ru"); -} -... - -1.4.3. reginfo_update(aor) - - Explicitly update the presence status, e.g., when new - information is learned. This may trigger a new NOTIFY towards - subscribed entities; at least it will update the internal - information for subsequent subscribe and notifies. - - This is done implicitly, when a registration is updated. - However, when a registration was just updated with additional - information like identities, this is not triggered - automatically. - - Meaning of the parameters is as follows: - * aor - The AOR to be updated. - - Example 1.9. reginfo_subscribe usage -... -modparam("pua_reginfo", "ul_domain", "location") -modparam("pua_reginfo", "ul_identities_key", "identities") -... -onreply_route[register_reply] { - if (t_check_status("200") && $hdr(P-Associated-URI)) { - ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associat -ed-URI)"); - reginfo_update("$tU@$td"); - } -} - -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Carsten Bock 18 1 1930 0 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 16 19 - 3. Liviu Chircu (@liviuchircu) 3 1 2 3 - 4. Ken Rice 3 1 2 2 - 5. Peter Lemenkov (@lemenkov) 3 1 1 1 - 6. Razvan Crainea (@razvancrainea) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Peter Lemenkov (@lemenkov) Feb 2025 - Feb 2025 - 3. Razvan Crainea (@razvancrainea) Jan 2025 - Jan 2025 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2024 - Apr 2024 - 5. Liviu Chircu (@liviuchircu) Apr 2024 - Apr 2024 - 6. Carsten Bock Mar 2024 - Mar 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Carsten - Bock. - - Documentation Copyrights: - - Copyright © 2011-2023 Carsten Bock, carsten@ng-voice.com, - http://www.ng-voice.com diff --git a/modules/pua_reginfo/README.md b/modules/pua_reginfo/README.md new file mode 100644 index 00000000000..fe24eeff4ff --- /dev/null +++ b/modules/pua_reginfo/README.md @@ -0,0 +1,275 @@ +--- +title: "PUA reginfo Module" +description: "This module publishes information about \"reg\"-events according to to RFC 3680." +--- + +## Admin Guide + + +### Overview + + +This module publishes information about "reg"-events according to +to RFC 3680. This can be used distribute the registration-info +status to the subscribed watchers. + + +This module "PUBLISH"es information when a new user registers +at this server (e.g. when "save()" is called) to users, which have +subscribed for the reg-info for this user. + + +This module can "SUBSCRIBE" for information at another server, so it +will receive "NOTIFY"-requests, when the information about a user +changes. + + +And finally, it can process received "NOTIFY" requests and it will +update the local registry accordingly. + + +Use cases for this might be: + + +- Keeping different Servers in Sync regarding +the location database +- Get notified, when a user registers: A presence-server, +which handles offline message storage for an account, would get +notified, when the user comes online. +- A client could subscribe to its own registration-status, +so he would get notified as soon as his account gets administratively +unregistered. +- ... + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *pua*. +- *usrloc*. + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### default_domain(str) + + +The default domain for the registered users to be used when +constructing the uri for the registrar callback. + + +*Default value is "NULL".* + + +```opensips title="Set default_domain parameter" +... +modparam("pua_reginfo", "default_domain", "opensips.org") +... +``` + + +#### publish_reginfo(int) + + +Whether or not to generate PUBLISH requests. + + +*Default value is "1" (enabled).* + + +```opensips title="Set publish_reginfo parameter" +... +modparam("pua_reginfo", "publish_reginfo", 0) +... +``` + + +#### outbound_proxy(str) + + +The outbound_proxy uri to be used when sending Subscribe and Publish requests. + + +*Default value is "NULL".* + + +```opensips title="Set outbound_proxy parameter" +... +modparam("pua_reginfo", "outbound_proxy", "sip:proxy@opensips.org") +... +``` + + +#### server_address(str) + + +The IP address of the server. + + +```opensips title="Set server_address parameter" +... +modparam("pua_reginfo", "server_address", "sip:reginfo@160.34.23.12") +... +``` + + +#### ul_domain(str) + + +The domain for for querying the usrloc-database. + + +*Default value is "NULL" (not set).* + + +```opensips title="Set ul_domain parameter" +... +modparam("pua_reginfo", "ul_domain", "location") +... +``` + + +#### ul_identities_key(str) + + +The Key, which may be used for retrieving multiple public identies +for a user. + + +*Default value is "NULL" (not set).* + + +```opensips title="Set ul_identities_key parameter" +... +modparam("pua_reginfo", "ul_identities_key", "identities") +... +onreply_route[register_reply] { + if (t_check_status("200") && $hdr(P-Associated-URI)) { + ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associated-URI)"); + reginfo_update("$tU@$td"); + } +} + +... +``` + + +### Exported Functions + + +#### reginfo_handle_notify(uldomain) + + +This function processes received "NOTIFY"-requests and updates +the local registry accordingly. + + +This method does not create any SIP-Response, this has to be done +by the script-writer. + + +The parameter has to correspond to user location table (domain) +where to store the record. + + +Return codes: + + +- *2* - contacts successfully updated, +but no more contacts online now. +*1* - contacts successfully updated and at +at least one contact still registered. +*-1* - Invalid NOTIFY or other error (see log-file) + + +```opensips title="reginfo_handle_notify usage" +... +if(is_method("NOTIFY")) + if (reginfo_handle_notify("location")) + send_reply("202", "Accepted"); +... +``` + + +#### reginfo_subscribe(uri[, expires]) + + +This function will subscribe for reginfo-information at the given +server URI. + + +Meaning of the parameters is as follows: + + +- *uri* - SIP-URI of the server, where to subscribe, +may contain pseudo-variables. +*expires* - Expiration date for this subscription, in seconds (default 3600) + + +```opensips title="reginfo_subscribe usage" +... +route { + t_on_reply("1"); + t_relay(); +} + +reply_route[1] { + if (t_check_status("200")) + reginfo_subscribe("$ru"); +} +... +``` + + +#### reginfo_update(aor) + + +Explicitly update the presence status, e.g., when new information +is learned. This may trigger a new NOTIFY towards subscribed +entities; at least it will update the internal information for +subsequent subscribe and notifies. + + +This is done implicitly, when a registration is updated. However, +when a registration was just updated with additional information like +identities, this is not triggered automatically. + + +Meaning of the parameters is as follows: + + +- *aor* - The AOR to be updated. + + +```opensips title="reginfo_subscribe usage" +... +modparam("pua_reginfo", "ul_domain", "location") +modparam("pua_reginfo", "ul_identities_key", "identities") +... +onreply_route[register_reply] { + if (t_check_status("200") && $hdr(P-Associated-URI)) { + ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associated-URI)"); + reginfo_update("$tU@$td"); + } +} + +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_reginfo/doc/contributors.xml b/modules/pua_reginfo/doc/contributors.xml deleted file mode 100644 index 3d2b9c46f83..00000000000 --- a/modules/pua_reginfo/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Carsten Bock - 18 - 1 - 1930 - 0 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 16 - 19 - - - 3. - Liviu Chircu (@liviuchircu) - 3 - 1 - 2 - 3 - - - 4. - Ken Rice - 3 - 1 - 2 - 2 - - - 5. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 6. - Razvan Crainea (@razvancrainea) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Feb 2025 - Feb 2025 - - - 3. - Razvan Crainea (@razvancrainea) - Jan 2025 - Jan 2025 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2024 - Apr 2024 - - - 5. - Liviu Chircu (@liviuchircu) - Apr 2024 - Apr 2024 - - - 6. - Carsten Bock - Mar 2024 - Mar 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Carsten Bock. -
- -
diff --git a/modules/pua_reginfo/doc/pua_reginfo.xml b/modules/pua_reginfo/doc/pua_reginfo.xml deleted file mode 100644 index 1903ea98db6..00000000000 --- a/modules/pua_reginfo/doc/pua_reginfo.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - pua_reginfo Module - &osipsname; - - - Carsten - Bock - carsten@ng-voice.com - - - Carsten - Bock - carsten@ng-voice.com - - - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011-2023 Carsten Bock, carsten@ng-voice.com, http://www.ng-voice.com - - - - - diff --git a/modules/pua_reginfo/doc/pua_reginfo_admin.xml b/modules/pua_reginfo/doc/pua_reginfo_admin.xml deleted file mode 100644 index 9b3f276a247..00000000000 --- a/modules/pua_reginfo/doc/pua_reginfo_admin.xml +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - This module publishes information about "reg"-events according to - to RFC 3680. This can be used distribute the registration-info - status to the subscribed watchers. - - - This module "PUBLISH"es information when a new user registers - at this server (e.g. when "save()" is called) to users, which have - subscribed for the reg-info for this user. - - - This module can "SUBSCRIBE" for information at another server, so it - will receive "NOTIFY"-requests, when the information about a user - changes. - - - And finally, it can process received "NOTIFY" requests and it will - update the local registry accordingly. - - - Use cases for this might be: - - Keeping different Servers in Sync regarding - the location database - - Get notified, when a user registers: A presence-server, - which handles offline message storage for an account, would get - notified, when the user comes online. - - A client could subscribe to its own registration-status, - so he would get notified as soon as his account gets administratively - unregistered. - - ... - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - pua. - - - - - usrloc. - - - - -
- -
- External Libraries or Applications - - None. - -
-
-
- Parameters -
- <varname>default_domain</varname>(str) - - The default domain for the registered users to be used when - constructing the uri for the registrar callback. - - - Default value is NULL. - - - - Set <varname>default_domain</varname> parameter - -... -modparam("pua_reginfo", "default_domain", "kamailio.org") -... - - -
-
- <varname>publish_reginfo</varname>(int) - - Whether or not to generate PUBLISH requests. - - - Default value is 1 (enabled). - - - - Set <varname>publish_reginfo</varname> parameter - -... -modparam("pua_reginfo", "publish_reginfo", 0) -... - - -
-
- <varname>outbound_proxy</varname>(str) - - The outbound_proxy uri to be used when sending Subscribe and Publish requests. - - - Default value is NULL. - - - - Set <varname>outbound_proxy</varname> parameter - -... -modparam("pua_reginfo", "outbound_proxy", "sip:proxy@kamailio.org") -... - - -
-
- <varname>server_address</varname>(str) - - The IP address of the server. - - - Set <varname>server_address</varname> parameter - -... -modparam("pua_reginfo", "server_address", "sip:reginfo@160.34.23.12") -... - - -
-
- <varname>ul_domain</varname>(str) - - The domain for for querying the usrloc-database. - - - Default value is NULL (not set). - - - - Set <varname>ul_domain</varname> parameter - -... -modparam("pua_reginfo", "ul_domain", "location") -... - - -
-
- <varname>ul_identities_key</varname>(str) - - The Key, which may be used for retrieving multiple public identies - for a user. - - - Default value is NULL (not set). - - - - Set <varname>ul_identities_key</varname> parameter - -... -modparam("pua_reginfo", "ul_identities_key", "identities") -... -onreply_route[register_reply] { - if (t_check_status("200") && $hdr(P-Associated-URI)) { - ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associated-URI)"); - reginfo_update("$tU@$td"); - } -} - -... - - -
-
-
- Functions -
- - <function moreinfo="none">reginfo_handle_notify(uldomain)</function> - - - This function processes received "NOTIFY"-requests and updates - the local registry accordingly. - - - This method does not create any SIP-Response, this has to be done - by the script-writer. - - - The parameter has to correspond to user location table (domain) - where to store the record. - - Return codes: - - - - 2 - contacts successfully updated, - but no more contacts online now. - - - 1 - contacts successfully updated and at - at least one contact still registered. - - - -1 - Invalid NOTIFY or other error (see log-file) - - - - - - <function>reginfo_handle_notify</function> usage - -... -if(is_method("NOTIFY")) - if (reginfo_handle_notify("location")) - send_reply("202", "Accepted"); -... - - -
-
- - <function moreinfo="none">reginfo_subscribe(uri[, expires])</function> - - - This function will subscribe for reginfo-information at the given - server URI. - - Meaning of the parameters is as follows: - - - - uri - SIP-URI of the server, where to subscribe, - may contain pseudo-variables. - - - expires - Expiration date for this subscription, in seconds (default 3600) - - - - - <function>reginfo_subscribe</function> usage - -... -route { - t_on_reply("1"); - t_relay(); -} - -reply_route[1] { - if (t_check_status("200")) - reginfo_subscribe("$ru"); -} -... - - -
-
- - <function moreinfo="none">reginfo_update(aor)</function> - - - Explicitly update the presence status, e.g., when new information - is learned. This may trigger a new NOTIFY towards subscribed - entities; at least it will update the internal information for - subsequent subscribe and notifies. - - - This is done implicitly, when a registration is updated. However, - when a registration was just updated with additional information like - identities, this is not triggered automatically. - - Meaning of the parameters is as follows: - - - - aor - The AOR to be updated. - - - - - <function>reginfo_subscribe</function> usage - -... -modparam("pua_reginfo", "ul_domain", "location") -modparam("pua_reginfo", "ul_identities_key", "identities") -... -onreply_route[register_reply] { - if (t_check_status("200") && $hdr(P-Associated-URI)) { - ul_add_key("location", "$tU@$td", "identities", "$hdr(P-Associated-URI)"); - reginfo_update("$tU@$td"); - } -} - -... - - -
-
- -
diff --git a/modules/pua_reginfo/notify.c b/modules/pua_reginfo/notify.c index 1443822b8ee..23314d4c199 100644 --- a/modules/pua_reginfo/notify.c +++ b/modules/pua_reginfo/notify.c @@ -82,7 +82,7 @@ int process_contact(udomain_t *domain, urecord_t **ul_record, str aor, case EVENT_REFRESHED: /* In case, no record exists and new one should be created, * create a new entry for this user in the usrloc-DB */ - if(ul.insert_urecord(domain, &aor, ul_record, 0) < 0) { + if(ul.insert_urecord(domain, &aor, ul_record, 0, NULL, NULL) < 0) { LM_ERR("failed to insert new user-record\n"); ret = RESULT_ERROR; goto done; diff --git a/modules/pua_usrloc/README b/modules/pua_usrloc/README deleted file mode 100644 index 2ea7ae609c8..00000000000 --- a/modules/pua_usrloc/README +++ /dev/null @@ -1,196 +0,0 @@ -PUA Usrloc - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_domain (str) - 1.3.2. entity_prefix (str) - 1.3.3. presence_server (str) - - 1.4. Exported Functions - - 1.4.1. pua_set_publish() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_domain parameter - 1.2. Set presentity_prefix parameter - 1.3. Set presence_server parameter - 1.4. pua_set_publish usage - -Chapter 1. Admin Guide - -1.1. Overview - - The pua_usrloc is the connector between usrloc and pua modules. - It creates the environment to send PUBLISH requests for user - location records, on specific events (e.g., when new record is - added in usrloc, a PUBLISH with status open (online) is issued; - when expires, it sends closed (offline)). - - Using this module, phones which have no support for presence - can be seen as online/offline. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * usrloc. - * pua. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml. - -1.3. Exported Parameters - -1.3.1. default_domain (str) - - The default domain to use when constructing the presentity uri - if it is missing from recorded aor. - - Default value is “NULL”. - - Example 1.1. Set default_domain parameter -... -modparam("pua_usrloc", "default_domain", "opensips.org") -... - -1.3.2. entity_prefix (str) - - The prefix when construstructing entity attribute to be added - to presence node in xml pidf. (ex: pres:user@domain ). - - Default value is “NULL”. - - Example 1.2. Set presentity_prefix parameter -... -modparam("pua_usrloc", "entity_prefix", "pres") -... - -1.3.3. presence_server (str) - - The the address of the presence server. If set, it will be used - as outbound proxy when sending PUBLISH requests. - - Example 1.3. Set presence_server parameter -... -modparam("pua_usrloc", "presence_server", "sip:pa@opensips.org:5075") -... - -1.4. Exported Functions - -1.4.1. pua_set_publish() - - The function is used to mark REGISTER requests that have to - issue a PUBLISH. The PUBLISH is issued when REGISTER is saved - in location table. - - Example 1.4. pua_set_publish usage -... -if(is_method("REGISTER") && $fu=~"john@opensips.org") - pua_set_publish(); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 35 17 1245 365 - 2. Liviu Chircu (@liviuchircu) 16 14 54 57 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 15 13 46 60 - 4. Razvan Crainea (@razvancrainea) 13 11 14 22 - 5. Daniel-Constantin Mierla (@miconda) 10 8 25 19 - 6. Vlad Patrascu (@rvlad-patrascu) 5 3 14 7 - 7. Ovidiu Sas (@ovidiusas) 4 2 14 2 - 8. Peter Lemenkov (@lemenkov) 4 2 5 4 - 9. Maksym Sobolyev (@sobomax) 3 1 4 4 - 10. Konstantin Bokarius 3 1 2 5 - - All remaining contributors: Elena-Ramona Modroiu, Juha Heinanen - (@juha-h), Ken Rice, Walter Doekes (@wdoekes), Edson Gellert - Schubert, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Jan 2023 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2007 - Apr 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Ovidiu Sas (@ovidiusas) Jan 2013 - Mar 2014 - 9. Walter Doekes (@wdoekes) Apr 2010 - Apr 2010 - 10. Anca Vamanu Nov 2006 - Oct 2009 - - All remaining contributors: Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha - Heinanen (@juha-h), Julien Blache, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca - Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/pua_usrloc/README.md b/modules/pua_usrloc/README.md new file mode 100644 index 00000000000..7bc9701a3d1 --- /dev/null +++ b/modules/pua_usrloc/README.md @@ -0,0 +1,120 @@ +--- +title: "PUA Usrloc" +description: "The pua_usrloc is the connector between usrloc and pua modules." +--- + +## Admin Guide + + +### Overview + + +The pua_usrloc is the connector between usrloc and pua modules. +It creates the environment to send PUBLISH requests for user +location records, on specific events (e.g., when new record is +added in usrloc, a PUBLISH with status open (online) is issued; +when expires, it sends closed (offline)). + + +Using this module, phones which have no support for presence can +be seen as online/offline. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *usrloc*. +- *pua*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml*. + + +### Exported Parameters + + +#### default_domain (str) + + +The default domain to use when constructing the presentity +uri if it is missing from recorded aor. + + +*Default value is "NULL".* + + +```opensips title="Set default_domain parameter" +... +modparam("pua_usrloc", "default_domain", "opensips.org") +... +``` + + +#### entity_prefix (str) + + +The prefix when construstructing entity attribute to be added to +presence node in xml pidf. +(ex: pres:user@domain ). + + +*Default value is "NULL".* + + +```opensips title="Set presentity_prefix parameter" +... +modparam("pua_usrloc", "entity_prefix", "pres") +... +``` + + +#### presence_server (str) + + +The the address of the presence server. If set, it will be +used as outbound proxy when sending PUBLISH requests. + + +```opensips title="Set presence_server parameter" +... +modparam("pua_usrloc", "presence_server", "sip:pa@opensips.org:5075") +... + +``` + + +### Exported Functions + + +#### pua_set_publish() + + +The function is used to mark REGISTER requests that have to +issue a PUBLISH. The PUBLISH is issued when REGISTER is saved +in location table. + + +```opensips title="pua_set_publish usage" +... +if(is_method("REGISTER") && $fu=~"john@opensips.org") + pua_set_publish(); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_usrloc/doc/contributors.xml b/modules/pua_usrloc/doc/contributors.xml deleted file mode 100644 index ac3b06c02f9..00000000000 --- a/modules/pua_usrloc/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 35 - 17 - 1245 - 365 - - - 2. - Liviu Chircu (@liviuchircu) - 16 - 14 - 54 - 57 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 15 - 13 - 46 - 60 - - - 4. - Razvan Crainea (@razvancrainea) - 13 - 11 - 14 - 22 - - - 5. - Daniel-Constantin Mierla (@miconda) - 10 - 8 - 25 - 19 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 14 - 7 - - - 7. - Ovidiu Sas (@ovidiusas) - 4 - 2 - 14 - 2 - - - 8. - Peter Lemenkov (@lemenkov) - 4 - 2 - 5 - 4 - - - 9. - Maksym Sobolyev (@sobomax) - 3 - 1 - 4 - 4 - - - 10. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Juha Heinanen (@juha-h), Ken Rice, Walter Doekes (@wdoekes), Edson Gellert Schubert, Julien Blache. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jan 2023 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2007 - Apr 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Mar 2014 - - - 9. - Walter Doekes (@wdoekes) - Apr 2010 - Apr 2010 - - - 10. - Anca Vamanu - Nov 2006 - Oct 2009 - - - -
-All remaining contributors: Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h), Julien Blache, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu. -
- -
diff --git a/modules/pua_usrloc/doc/pua_usrloc.xml b/modules/pua_usrloc/doc/pua_usrloc.xml deleted file mode 100644 index 71a03dbe34e..00000000000 --- a/modules/pua_usrloc/doc/pua_usrloc.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - PUA Usrloc - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - - - - diff --git a/modules/pua_usrloc/doc/pua_usrloc_admin.xml b/modules/pua_usrloc/doc/pua_usrloc_admin.xml deleted file mode 100644 index 850c4e6daa2..00000000000 --- a/modules/pua_usrloc/doc/pua_usrloc_admin.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The pua_usrloc is the connector between usrloc and pua modules. - It creates the environment to send PUBLISH requests for user - location records, on specific events (e.g., when new record is - added in usrloc, a PUBLISH with status open (online) is issued; - when expires, it sends closed (offline)). - - - Using this module, phones which have no support for presence can - be seen as online/offline. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - usrloc. - - - - - pua. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml. - - - - -
-
-
- Exported Parameters -
- <varname>default_domain</varname> (str) - - The default domain to use when constructing the presentity - uri if it is missing from recorded aor. - - - Default value is NULL. - - - - Set <varname>default_domain</varname> parameter - -... -modparam("pua_usrloc", "default_domain", "opensips.org") -... - - -
-
- <varname>entity_prefix</varname> (str) - - The prefix when construstructing entity attribute to be added to - presence node in xml pidf. - (ex: pres:user@domain ). - - - Default value is NULL. - - - - Set <varname>presentity_prefix</varname> parameter - -... -modparam("pua_usrloc", "entity_prefix", "pres") -... - - -
- -
- <varname>presence_server</varname> (str) - - The the address of the presence server. If set, it will be - used as outbound proxy when sending PUBLISH requests. - - - Set <varname>presence_server</varname> parameter - -... -modparam("pua_usrloc", "presence_server", "sip:pa@opensips.org:5075") -... - - -
- - -
-
- Exported Functions -
- - <function moreinfo="none">pua_set_publish()</function> - - - The function is used to mark REGISTER requests that have to - issue a PUBLISH. The PUBLISH is issued when REGISTER is saved - in location table. - - - - - <function>pua_set_publish</function> usage - -... -if(is_method("REGISTER") && $fu=~"john@opensips.org") - pua_set_publish(); -... - - - -
- -
- -
- diff --git a/modules/pua_xmpp/README b/modules/pua_xmpp/README deleted file mode 100644 index f380e8d0058..00000000000 --- a/modules/pua_xmpp/README +++ /dev/null @@ -1,235 +0,0 @@ -Presence User Agent for XMPP (Presence gateway between SIP and XMPP) - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. server_address(str) - 1.3.2. presence_server (str) - - 1.4. Exported Functions - - 1.4.1. pua_xmpp_notify() - 1.4.2. pua_xmpp_req_winfo(request_uri, expires) - - 1.5. Filtering - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set server_address parameter - 1.2. Set presence_server parameter - 1.3. Notify2Xmpp usage - 1.4. xmpp_send_winfo usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is a gateway for presence between SIP and XMPP. - - It translates one format into another and uses xmpp, pua and - presence modules to manage the transmition of presence state - information. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * presence. - * pua. - * xmpp. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml. - -1.3. Exported Parameters - -1.3.1. server_address(str) - - The IP address of the server. - - Example 1.1. Set server_address parameter -... -modparam("pua_xmpp", "server_address", "sip:sa@opensips.org:5060") -... - -1.3.2. presence_server (str) - - The the address of the presence server. If set, it will be used - as outbound proxy when sending PUBLISH requests. - - Example 1.2. Set presence_server parameter -... -modparam("pua_xmpp", "presence_server", "sip:pa@opensips.org:5075") -... - -1.4. Exported Functions - - Functions exported to be used in configuration file. - -1.4.1. pua_xmpp_notify() - - Function that handles Notify messages addressed to a user from - an xmpp domain. It requires filtering after method and domain - in configuration file. If the function is successful, a 2xx - reply must be sent. - - This function can be used from REQUEST_ROUTE. - - Example 1.3. Notify2Xmpp usage -... - if( is_method("NOTIFY") && $ru=~"sip:.+@sip-xmpp.siphub.ro") - { - if(Notify2Xmpp()) - t_reply(200, "OK"); - exit; - } -... - -1.4.2. pua_xmpp_req_winfo(request_uri, expires) - - Function called when a Subscribe addressed to a user from a - xmpp domain is received. It calls sending a Subscribe for winfo - for the user, and the following Notify with dialog-info is - translated into a subscription in xmpp. It also requires - filtering in configuration file, after method, domain and - event(only for presence). - - Parameters: - * request_uri (string) - * expires (int) - value of Expires header field in received - Subscribe. - - This function can be used from REQUEST_ROUTE. - - Example 1.4. xmpp_send_winfo usage -... - if( is_method("SUBSCRIBE")) - { - handle_subscribe(); - if($ru=~"sip:.+@sip-xmpp.siphub.ro" && $hdr(Event)== "pr -esence") - { - pua_xmpp_req_winfo($ruri, $hdr(Expires)); - } - t_release(); - } - -... - -1.5. Filtering - - Instead of "sip-xmpp.siphub.ro" in the example you should use - the value set for the xmpp module parameter named - 'gateway_domain'. - -Chapter 2. Developer Guide - - The module provides no function to be used in other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 59 17 3287 806 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 16 13 59 81 - 3. Liviu Chircu (@liviuchircu) 14 11 40 63 - 4. Razvan Crainea (@razvancrainea) 13 11 24 33 - 5. Daniel-Constantin Mierla (@miconda) 10 8 27 21 - 6. Vlad Patrascu (@rvlad-patrascu) 7 4 34 69 - 7. Ovidiu Sas (@ovidiusas) 3 1 14 2 - 8. Sergio Gutierrez 3 1 5 5 - 9. Vlad Paiu (@vladpaiu) 3 1 4 14 - 10. Konstantin Bokarius 3 1 3 5 - - All remaining contributors: Juha Heinanen (@juha-h), Maksym - Sobolyev (@sobomax), Ken Rice, Peter Lemenkov (@lemenkov), - Walter Doekes (@wdoekes), Edson Gellert Schubert, Stanislaw - Pitucha. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2007 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - 9. Vlad Paiu (@vladpaiu) Aug 2011 - Aug 2011 - 10. Stanislaw Pitucha Jul 2010 - Jul 2010 - - All remaining contributors: Walter Doekes (@wdoekes), Anca - Vamanu, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen - (@juha-h). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca Vamanu, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/pua_xmpp/README.md b/modules/pua_xmpp/README.md new file mode 100644 index 00000000000..fdda4869b09 --- /dev/null +++ b/modules/pua_xmpp/README.md @@ -0,0 +1,155 @@ +--- +title: "PUA XMPP module" +description: "This module is a gateway for presence between SIP and XMPP." +--- + +## Admin Guide + + +### Overview + + +This module is a gateway for presence between SIP and XMPP. + + +It translates one format into another and uses xmpp, pua and presence +modules to manage the transmition of presence state information. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *presence*. +- *pua*. +- *xmpp*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml*. + + +### Exported Parameters + + +#### server_address(str) + + +The IP address of the server. + + +```opensips title="Set server_address parameter" +... +modparam("pua_xmpp", "server_address", "sip:sa@opensips.org:5060") +... +``` + + +#### presence_server (str) + + +The the address of the presence server. If set, it will be +used as outbound proxy when sending PUBLISH requests. + + +```opensips title="Set presence_server parameter" +... +modparam("pua_xmpp", "presence_server", "sip:pa@opensips.org:5075") +... +``` + + +### Exported Functions + + +Functions exported to be used in configuration file. + + +#### pua_xmpp_notify() + + +Function that handles Notify messages addressed to a user from +an xmpp domain. It requires filtering after method and domain in +configuration file. If the function is successful, a 2xx reply must +be sent. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Notify2Xmpp usage" +... + if( is_method("NOTIFY") && $ru=~"sip:.+@sip-xmpp.siphub.ro") + { + if(Notify2Xmpp()) + t_reply(200, "OK"); + exit; + } +... +``` + + +#### pua_xmpp_req_winfo(request_uri, expires) + + +Function called when a Subscribe addressed to a user from a +xmpp domain is received. It calls sending a Subscribe for +winfo for the user, and the following Notify with dialog-info +is translated into a subscription in xmpp. +It also requires filtering in configuration file, after method, +domain and event(only for presence). + + +Parameters: + + +- *request_uri* (string) +- *expires* (int) - value of Expires header field +in received Subscribe. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="xmpp_send_winfo usage" +... + if( is_method("SUBSCRIBE")) + { + handle_subscribe(); + if($ru=~"sip:.+@sip-xmpp.siphub.ro" && $hdr(Event)== "presence") + { + pua_xmpp_req_winfo($ruri, $hdr(Expires)); + } + t_release(); + } +... +``` + + +### Filtering + + +Instead of "sip-xmpp.siphub.ro" in the example you should use the value +set for the xmpp module parameter named 'gateway_domain'. + + +## Developer Guide + + +The module provides no function to be used in other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/pua_xmpp/doc/contributors.xml b/modules/pua_xmpp/doc/contributors.xml deleted file mode 100644 index cf47c36e511..00000000000 --- a/modules/pua_xmpp/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 59 - 17 - 3287 - 806 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 16 - 13 - 59 - 81 - - - 3. - Liviu Chircu (@liviuchircu) - 14 - 11 - 40 - 63 - - - 4. - Razvan Crainea (@razvancrainea) - 13 - 11 - 24 - 33 - - - 5. - Daniel-Constantin Mierla (@miconda) - 10 - 8 - 27 - 21 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 7 - 4 - 34 - 69 - - - 7. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 14 - 2 - - - 8. - Sergio Gutierrez - 3 - 1 - 5 - 5 - - - 9. - Vlad Paiu (@vladpaiu) - 3 - 1 - 4 - 14 - - - 10. - Konstantin Bokarius - 3 - 1 - 3 - 5 - - - -
-All remaining contributors: Juha Heinanen (@juha-h), Maksym Sobolyev (@sobomax), Ken Rice, Peter Lemenkov (@lemenkov), Walter Doekes (@wdoekes), Edson Gellert Schubert, Stanislaw Pitucha. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2007 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - 9. - Vlad Paiu (@vladpaiu) - Aug 2011 - Aug 2011 - - - 10. - Stanislaw Pitucha - Jul 2010 - Jul 2010 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Anca Vamanu, Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/pua_xmpp/doc/pua_xmpp.xml b/modules/pua_xmpp/doc/pua_xmpp.xml deleted file mode 100644 index 4f6cdfddf2f..00000000000 --- a/modules/pua_xmpp/doc/pua_xmpp.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - Presence User Agent for XMPP (Presence gateway between SIP and XMPP) - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - - - diff --git a/modules/pua_xmpp/doc/pua_xmpp_admin.xml b/modules/pua_xmpp/doc/pua_xmpp_admin.xml deleted file mode 100644 index 156ff318b3a..00000000000 --- a/modules/pua_xmpp/doc/pua_xmpp_admin.xml +++ /dev/null @@ -1,180 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is a gateway for presence between SIP and XMPP. - - - It translates one format into another and uses xmpp, pua and presence - modules to manage the transmition of presence state information. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - presence. - - - - - pua. - - - - - xmpp. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml. - - - - -
-
- -
- Exported Parameters -
- <varname>server_address</varname>(str) - - The IP address of the server. - - - Set <varname>server_address</varname> parameter - -... -modparam("pua_xmpp", "server_address", "sip:sa@opensips.org:5060") -... - - -
- -
- <varname>presence_server</varname> (str) - - The the address of the presence server. If set, it will be - used as outbound proxy when sending PUBLISH requests. - - - Set <varname>presence_server</varname> parameter - -... -modparam("pua_xmpp", "presence_server", "sip:pa@opensips.org:5075") -... - - -
- -
- -
- Exported Functions - - Functions exported to be used in configuration file. - -
- - <function moreinfo="none">pua_xmpp_notify()</function> - - - Function that handles Notify messages addressed to a user from - an xmpp domain. It requires filtering after method and domain in - configuration file. If the function is successful, a 2xx reply must - be sent. - - - This function can be used from REQUEST_ROUTE. - - - <function>Notify2Xmpp</function> usage - -... - if( is_method("NOTIFY") && $ru=~"sip:.+@sip-xmpp.siphub.ro") - { - if(Notify2Xmpp()) - t_reply(200, "OK"); - exit; - } -... - - -
- -
- - <function moreinfo="none">pua_xmpp_req_winfo(request_uri, expires)</function> - - - Function called when a Subscribe addressed to a user from a - xmpp domain is received. It calls sending a Subscribe for - winfo for the user, and the following Notify with dialog-info - is translated into a subscription in xmpp. - It also requires filtering in configuration file, after method, - domain and event(only for presence). - - Parameters: - - - request_uri (string) - - - expires (int) - value of Expires header field - in received Subscribe. - - - - This function can be used from REQUEST_ROUTE. - - - <function>xmpp_send_winfo</function> usage - -... - if( is_method("SUBSCRIBE")) - { - handle_subscribe(); - if($ru=~"sip:.+@sip-xmpp.siphub.ro" && $hdr(Event)== "presence") - { - pua_xmpp_req_winfo($ruri, $hdr(Expires)); - } - t_release(); - } - -... - - -
-
-
- Filtering - - Instead of "sip-xmpp.siphub.ro" in the example you should use the value - set for the xmpp module parameter named 'gateway_domain'. - -
- - -
- diff --git a/modules/pua_xmpp/doc/pua_xmpp_devel.xml b/modules/pua_xmpp/doc/pua_xmpp_devel.xml deleted file mode 100644 index 3f193031a33..00000000000 --- a/modules/pua_xmpp/doc/pua_xmpp_devel.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - &develguide; - - The module provides no function to be used in other &osips; modules. - - - - diff --git a/modules/pua_xmpp/simple2xmpp.c b/modules/pua_xmpp/simple2xmpp.c index c67c8b82f54..ecd144a583f 100644 --- a/modules/pua_xmpp/simple2xmpp.c +++ b/modules/pua_xmpp/simple2xmpp.c @@ -491,7 +491,6 @@ int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id, xmlBufferFree(buffer); xmlCleanupParser(); - xmlMemoryDump(); if(sip_doc) xmlFreeDoc(sip_doc); @@ -509,7 +508,6 @@ int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id, if(buffer) xmlBufferFree(buffer); xmlCleanupParser(); - xmlMemoryDump(); return -1; @@ -637,7 +635,6 @@ int winfo2xmpp(str* to_uri, str* body, str* id) xmlFreeDoc(notify_doc); xmlCleanupParser(); - xmlMemoryDump(); return 0; error: @@ -651,7 +648,6 @@ int winfo2xmpp(str* to_uri, str* body, str* id) if(buffer) xmlBufferFree(buffer); xmlCleanupParser(); - xmlMemoryDump(); return -1; } @@ -873,4 +869,3 @@ int Sipreply2Xmpp(ua_pres_t* hentity, struct sip_msg * msg) return -1; } - diff --git a/modules/pua_xmpp/xmpp2simple.c b/modules/pua_xmpp/xmpp2simple.c index 445c998c5b1..2ab003b9f5b 100644 --- a/modules/pua_xmpp/xmpp2simple.c +++ b/modules/pua_xmpp/xmpp2simple.c @@ -127,7 +127,6 @@ void pres_Xmpp2Sip(char *msg, int type, void *param) xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); return ; error: @@ -135,7 +134,6 @@ void pres_Xmpp2Sip(char *msg, int type, void *param) if(doc) xmlFreeDoc(doc); xmlCleanupParser(); - xmlMemoryDump(); return ; } @@ -501,4 +499,3 @@ int presence_subscribe(xmlNodePtr pres_node, int expires,int flag) error: return -1; } - diff --git a/modules/python/Makefile b/modules/python/Makefile index 1c5e1006c20..3f2418770b6 100644 --- a/modules/python/Makefile +++ b/modules/python/Makefile @@ -10,7 +10,11 @@ auto_gen= NAME=python.so ifeq (,$(PYTHON)) -PYTHON=python +PYTHON := $(shell command -v python3 2>/dev/null || command -v python 2>/dev/null) +endif + +ifeq (,$(PYTHON)) +$(error Python interpreter not found; install python3 or set PYTHON=/path/to/python) endif PYTHON_VERSION=${shell ${PYTHON} -c "import sysconfig;print(sysconfig.get_config_var('VERSION'))"} diff --git a/modules/python/README b/modules/python/README deleted file mode 100644 index d3f556d5291..00000000000 --- a/modules/python/README +++ /dev/null @@ -1,237 +0,0 @@ -Python Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. script_name (string) - 1.3.2. mod_init_function (string) - 1.3.3. child_init_method (string) - - 1.4. Exported Functions - - 1.4.1. python_exec(method_name [, extra_args]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set script_name parameter - 1.2. Set mod_init_function parameter - 1.3. Set child_init_method parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module can be used to efficiently run Python code directly - from the OpenSIPS script, without executing the python - interpreter. - - The module provides the means to load a python module and run - its functions. Each function has to receive the SIP message as - parameter, and optionally some extra arguments passed from the - script. - - In order to run Python functions, one has to load the module - that contains them, by specifying the script name using the - script_name parameter. The module has to contain the following - components: - * A class that contains all the methods that can be invoked - from the script. - * A method within the class that is called when a SIP child - is created. The method should receive an integer parameter, - which represents the rank of the child, and must return 0 - or positive in case the function was executed successfully, - or negative otherwise. The name of this method is specified - by the child_init_method parameter. - * A global function that initializes the Python module and - returns an object from the class whose functions will be - invoked by the script. The name of the global function is - indicated by the mod_init_method parameter. - - A minimal example of a Python script that satisfies these - requirements is: - def mod_init(): - return SIPMsg() - - class SIPMsg: - def child_init(self, rank): - return 0 - - A function from the object returned above can be executed from - the script using the python_exec() script function. The python - method has to receive the following parameters: - * The SIP message, that has the structure detailed below - * Optionally, a string passed from the script - - The SIP message received as parameter by the function has the - following fields and methods: - * Type - the type of the message, either SIP_REQUEST or - SIP_REPLY - * Method - the method of the message - * Status - the status of the message, available only for - replies - * RURI - the R-URI of the message, available only for - requests - * src_address - the (IP, port) tuple representing source - address of the message - * dst_address - the (IP, port) tuple representing the - destination address (OpenSIPS address) of the message - * copy() - copies the current SIP message in a new object - * rewrite_ruri() - changes the R-URI of the message; - available only for requests - * set_dst_uri() - sets the destination URI of the message; - available only for requests - * getHeader() - returns the header of a message - * call_function() - calls built-in script function or - function exported by other module - * get_pseudoVar(name) - returns the value of the the - pseudo-variable specified by the name as Unicode string. - * set_pseudoVar(name, value) - sets pseudo-variable using - Unicode string value. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * python-dev - provides the Python bindings. - -1.3. Exported Parameters - -1.3.1. script_name (string) - - The script that contains the Python module. - - Default value is “/usr/local/etc/opensips/handler.py”. - - Example 1.1. Set script_name parameter -... -modparam("python", "script_name", "/usr/local/bin/opensips_handler.py") -... - -1.3.2. mod_init_function (string) - - The method used to initialize the Python module and return the - object. - - Default value is “mod_init”. - - Example 1.2. Set mod_init_function parameter -... -modparam("python", "mod_init_function", "module_initializer") -... - -1.3.3. child_init_method (string) - - The method called for each child process. - - Default value is “child_init”. - - Example 1.3. Set child_init_method parameter -... -modparam("python", "child_init_method", "child_initializer") -... - -1.4. Exported Functions - -1.4.1. python_exec(method_name [, extra_args]) - - This function is used to execute a method from the Python - module loaded. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Meaning of the parameters is as follows: - * method_name (string) - name of the method called - * extra_args (string, optional) - extra arguments that can be - passed from the script to the python function. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Maksym Sobolyev (@sobomax) 24 11 1321 25 - 2. Razvan Crainea (@razvancrainea) 21 14 502 101 - 3. Vlad Patrascu (@rvlad-patrascu) 13 9 204 113 - 4. Liviu Chircu (@liviuchircu) 9 6 30 61 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 36 48 - 6. Peter Lemenkov (@lemenkov) 5 3 7 7 - 7. importos 3 1 104 4 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Mar 2015 - Sep 2025 - 2. Peter Lemenkov (@lemenkov) Jun 2018 - Aug 2025 - 3. Maksym Sobolyev (@sobomax) Dec 2009 - Oct 2024 - 4. importos Nov 2020 - Nov 2020 - 5. Liviu Chircu (@liviuchircu) Jul 2014 - Jan 2020 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Nov 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Apr 2019 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: importos, Vlad Patrascu (@rvlad-patrascu), - Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan - Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2009 Sippy Software, Inc. diff --git a/modules/python/README.md b/modules/python/README.md new file mode 100644 index 00000000000..453071dfa29 --- /dev/null +++ b/modules/python/README.md @@ -0,0 +1,195 @@ +--- +title: "Python Module" +description: "This module can be used to efficiently run Python code directly from the OpenSIPS script, without executing the *python* interpreter." +--- + +## Admin Guide + + +### Overview + + +This module can be used to efficiently run Python code directly from +the OpenSIPS script, without executing the *python* +interpreter. + + +The module provides the means to load a python module and run +its functions. Each function has to receive the SIP message as +parameter, and optionally some extra arguments passed from the +script. + + +In order to run Python functions, one has to load the module +that contains them, by specifying the script name using the +*script_name* parameter. The module has to contain +the following components: + + +- A class that contains all the methods that can be invoked from the +script. +- A method within the class that is called when a SIP child is created. +The method should receive an integer parameter, which represents the +rank of the child, and must return 0 or positive in case the function +was executed successfully, or negative otherwise. The name of this +method is specified by the *child_init_method* +parameter. +- A global function that initializes the Python module and returns an +object from the class whose functions will be invoked by the script. +The name of the global function is indicated by the +*mod_init_method* parameter. + + +A minimal example of a Python script that satisfies these requirements +is: + + +```c + def mod_init(): + return SIPMsg() + + class SIPMsg: + def child_init(self, rank): + return 0 + +``` + + +A function from the object returned above can be executed from the +script using the *python_exec()* script function. The +python method has to receive the following parameters: + + +- The SIP message, that has the structure detailed below +- Optionally, a string passed from the script + + +The SIP message received as parameter by the function has the following +fields and methods: + + +- *Type* - the type of the message, either +*SIP_REQUEST* or *SIP_REPLY* +- *Method* - the method of the message +- *Status* - the status of the message, available only +for replies +- *RURI* - the R-URI of the message, available only for +requests +- *src_address* - the (IP, port) tuple representing +source address of the message +- *dst_address* - the (IP, port) tuple representing +the destination address (OpenSIPS address) of the message +- *copy()* - copies the current SIP message in a new +object +- *rewrite_ruri()* - changes the R-URI of the message; +available only for requests +- *set_dst_uri()* - sets the destination URI of the +message; available only for requests +- *getHeader()* - returns the header of a message +- *call_function()* - calls built-in script function +or function exported by other module +- *get_pseudoVar(name)* - returns the value of the +the pseudo-variable specified by the *name* as +Unicode string. +- *set_pseudoVar(name, value)* - sets pseudo-variable +using Unicode string *value*. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *python-dev* - provides the Python bindings. + + +### Exported Parameters + + +#### script_name (string) + + +The script that contains the Python module. + + +*Default value is "/usr/local/etc/opensips/handler.py".* + + +```opensips title="Set script_name parameter" +... +modparam("python", "script_name", "/usr/local/bin/opensips_handler.py") +... +``` + + +#### mod_init_function (string) + + +The method used to initialize the Python module and return the object. + + +*Default value is "mod_init".* + + +```opensips title="Set mod_init_function parameter" +... +modparam("python", "mod_init_function", "module_initializer") +... +``` + + +#### child_init_method (string) + + +The method called for each child process. + + +*Default value is "child_init".* + + +```opensips title="Set child_init_method parameter" +... +modparam("python", "child_init_method", "child_initializer") +... +``` + + +### Exported Functions + + +#### python_exec(method_name [, extra_args]) + + +This function is used to execute a method from the Python module +loaded. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE and BRANCH_ROUTE. + + +Meaning of the parameters is as follows: + + +- *method_name* (string) - name of the method called +- *extra_args* (string, optional) - extra arguments that can +be passed from the script to the python function. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/python/doc/contributors.xml b/modules/python/doc/contributors.xml deleted file mode 100644 index bcf61cbd1a1..00000000000 --- a/modules/python/doc/contributors.xml +++ /dev/null @@ -1,157 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Maksym Sobolyev (@sobomax) - 24 - 11 - 1321 - 25 - - - 2. - Razvan Crainea (@razvancrainea) - 21 - 14 - 502 - 101 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 13 - 9 - 204 - 113 - - - 4. - Liviu Chircu (@liviuchircu) - 9 - 6 - 30 - 61 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 36 - 48 - - - 6. - Peter Lemenkov (@lemenkov) - 5 - 3 - 7 - 7 - - - 7. - importos - 3 - 1 - 104 - 4 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Mar 2015 - Sep 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jun 2018 - Aug 2025 - - - 3. - Maksym Sobolyev (@sobomax) - Dec 2009 - Oct 2024 - - - 4. - importos - Nov 2020 - Nov 2020 - - - 5. - Liviu Chircu (@liviuchircu) - Jul 2014 - Jan 2020 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Nov 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Apr 2019 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: importos, Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/python/doc/python.xml b/modules/python/doc/python.xml deleted file mode 100644 index ca1b8025504..00000000000 --- a/modules/python/doc/python.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Python Module - &osipsname; - - - - &admin; - - &contrib; - - &docCopyrights; - ©right; 2009 Sippy Software, Inc. - diff --git a/modules/python/doc/python_admin.xml b/modules/python/doc/python_admin.xml deleted file mode 100644 index 7de6d964447..00000000000 --- a/modules/python/doc/python_admin.xml +++ /dev/null @@ -1,262 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module can be used to efficiently run Python code directly from - the &osips; script, without executing the python - interpreter. - - - - The module provides the means to load a python module and run - its functions. Each function has to receive the SIP message as - parameter, and optionally some extra arguments passed from the - script. - - - - In order to run Python functions, one has to load the module - that contains them, by specifying the script name using the - script_name parameter. The module has to contain - the following components: - - - A class that contains all the methods that can be invoked from the - script. - - - A method within the class that is called when a SIP child is created. - The method should receive an integer parameter, which represents the - rank of the child, and must return 0 or positive in case the function - was executed successfully, or negative otherwise. The name of this - method is specified by the child_init_method - parameter. - - - A global function that initializes the Python module and returns an - object from the class whose functions will be invoked by the script. - The name of the global function is indicated by the - mod_init_method parameter. - - - - - A minimal example of a Python script that satisfies these requirements - is: - - def mod_init(): - return SIPMsg() - - class SIPMsg: - def child_init(self, rank): - return 0 - - - - - A function from the object returned above can be executed from the - script using the python_exec() script function. The - python method has to receive the following parameters: - - - The SIP message, that has the structure detailed below - - - Optionally, a string passed from the script - - - - - - The SIP message received as parameter by the function has the following - fields and methods: - - - Type - the type of the message, either - SIP_REQUEST or SIP_REPLY - - - Method - the method of the message - - - Status - the status of the message, available only - for replies - - - RURI - the R-URI of the message, available only for - requests - - - src_address - the (IP, port) tuple representing - source address of the message - - - dst_address - the (IP, port) tuple representing - the destination address (&osips; address) of the message - - - copy() - copies the current SIP message in a new - object - - - rewrite_ruri() - changes the R-URI of the message; - available only for requests - - - set_dst_uri() - sets the destination URI of the - message; available only for requests - - - getHeader() - returns the header of a message - - - call_function() - calls built-in script function - or function exported by other module - - - get_pseudoVar(name) - returns the value of the - the pseudo-variable specified by the name as - Unicode string. - - - set_pseudoVar(name, value) - sets pseudo-variable - using Unicode string value. - - - - - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - python-dev - provides the Python bindings. - - - - -
-
- -
- Exported Parameters -
- <varname>script_name</varname> (string) - - The script that contains the Python module. - - - - Default value is /usr/local/etc/opensips/handler.py. - - - - Set <varname>script_name</varname> parameter - -... -modparam("python", "script_name", "/usr/local/bin/opensips_handler.py") -... - - -
-
- <varname>mod_init_function</varname> (string) - - The method used to initialize the Python module and return the object. - - - - Default value is mod_init. - - - - Set <varname>mod_init_function</varname> parameter - -... -modparam("python", "mod_init_function", "module_initializer") -... - - -
-
- <varname>child_init_method</varname> (string) - - The method called for each child process. - - - - Default value is child_init. - - - - Set <varname>child_init_method</varname> parameter - -... -modparam("python", "child_init_method", "child_initializer") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">python_exec(method_name [, extra_args])</function> - - - This function is used to execute a method from the Python module - loaded. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Meaning of the parameters is as follows: - - - - method_name (string) - name of the method called - - - - - extra_args (string, optional) - extra arguments that can - be passed from the script to the python function. - - - -
-
- -
- diff --git a/modules/qos/README b/modules/qos/README deleted file mode 100644 index a25ac93a4f7..00000000000 --- a/modules/qos/README +++ /dev/null @@ -1,246 +0,0 @@ -QOS Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. qos_flag (string) - - 1.5. Exported Functions - 1.6. Exported Statistics - 1.7. Exported MI Functions - 1.8. Exported Pseudo-Variables - 1.9. Installation and Running - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. register_qoscb (qos, type, cb, param) - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set qos_flag parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The qos module provides a way to keep track of per dialog SDP - session(s). - -1.2. How it works - - The qos module uses the dialog module to be notified of any new - or updated dialogs. It will then look for and extract the SDP - session (if present) from SIP requests and replies and keep - track of it for the entire life of a dialog. - - All of this happens with a properly configured dialog and qos - module and setting the dialog flag and the qos flag at the time - any INVITE sip message is seen. There is no config script - function call required to set the SDP session tracking - mechanism. See the dialog module users guide for more - information. - - A dialog can have one or more SDP sessions active in one of the - following states: - * pending - only one end point of the SDP session is known. - * negotiated - both end points of the SDP session are known. - - An SDP session can be established in one of the following - scenarios: - * INVITE/200ok - typical "INVITE" and "200 OK" SDP exchange. - * 200ok/ACK - "200 OK" and "ACK" SDP exchange (for calls - starting with an empty INVITE). - * 183/PRACK - early media via "183 Session Progress" and - "PRACK" (see rfc3959 for more information) - not - implemented yet. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog - dialog module and its decencies (tm). - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. qos_flag (string) - - Keeping with OpenSIPS, the module will not do anything to any - message unless instructed to do so via the config script. You - must set the qos_flag value in the setflag() call of the INVITE - you want the qos module to process. But before you can do that, - you need to tell the qos module which flag value you are - assigning to qos. - - In most cases when ever you create a new dialog via - create_dialog() function,you will want to set the qos flag. If - create_dialog() is not called and the qos flag is set, it will - not have any effect. - - This parameter must be set of the module will not load. - - Default value is “Not set!”. - - Example 1.1. Set qos_flag parameter -... -modparam("qos", "qos_flag", "QOS_FLAG") -... -route { - ... - if ($rm=="INVITE") { - setflag(QOS_FLAG); # Set the qos flag - create_dialog(); # create the dialog - } - ... -} - -1.5. Exported Functions - - There are no exported functions that could be used in scripts. - -1.6. Exported Statistics - - There are no exported statistics for the qos module. - -1.7. Exported MI Functions - - There are no exported MI functions for the qos module. Check - the dialog MI functions for a way to inspect the internals of a - dialog. - -1.8. Exported Pseudo-Variables - - There are no exported pseudo-variables for the qos module. - -1.9. Installation and Running - - Just load the module and remember to set the flag. - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. register_qoscb (qos, type, cb, param) - - Register a new callback to the qos. - - Meaning of the parameters is as follows: - * struct qos_ctx_st* qos - qos to register callback to. If - maybe NULL only for QOSCB_CREATED callback type, which is - not a per qos type. - * int type - types of callbacks; more types may be register - for the same callback function; only QOSCB_CREATED must be - register alone. Possible types: - + QOSCB_CREATED - called when a new qos context is - created - it's a global type (not associated to any - qos). - + QOSCB_ADD_SDP - called when a new SDP was added to the - qos context - it's a per qos type. - + QOSCB_UPDATE_SDP - called when an existing SDP is - updated - it's a per qos type. - + QOSCB_REMOVE_SDP - called when an existing SDP is - removed - it's a per qos type. - + QOSCB_TERMINATED - called when the qos is terminated. - * qos_cb cb - callback function to be called. Prototype is: - “void (qos_cb) (struct qos_ctx_st *qos, int type, struct - qos_cb_params *params); ” - * void *param - parameter to be passed to the callback - function. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 23 3 2152 13 - 2. Liviu Chircu (@liviuchircu) 16 13 41 72 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 10 8 25 16 - 4. Razvan Crainea (@razvancrainea) 9 7 19 19 - 5. Vlad Patrascu (@rvlad-patrascu) 8 5 99 96 - 6. Vlad Paiu (@vladpaiu) 3 1 5 6 - 7. Maksym Sobolyev (@sobomax) 3 1 3 3 - 8. Ezequiel Lovelle (@lovelle) 3 1 1 1 - 9. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Oct 2011 - Jul 2020 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2009 - May 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Ezequiel Lovelle (@lovelle) Oct 2014 - Oct 2014 - 8. Ovidiu Sas (@ovidiusas) Dec 2008 - May 2012 - 9. Vlad Paiu (@vladpaiu) Jun 2011 - Jun 2011 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov - (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Ovidiu Sas - (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2008 SOMA Networks, Inc. diff --git a/modules/qos/README.md b/modules/qos/README.md new file mode 100644 index 00000000000..a81165bd5b4 --- /dev/null +++ b/modules/qos/README.md @@ -0,0 +1,197 @@ +--- +title: "QOS Module" +description: "The qos module provides a way to keep track of per dialog SDP session(s)." +--- + +## Admin Guide + + +### Overview + + +The qos module provides a way to keep track of +per dialog SDP session(s). + + +### How it works + + +The qos module uses the dialog module to be notified of +any new or updated dialogs. It will then look for and extract +the SDP session (if present) from SIP requests and replies and +keep track of it for the entire life of a dialog. + + +All of this happens with a properly configured dialog +and qos module and setting the dialog flag and the qos flag at +the time any INVITE sip message is seen. There is no +config script function call required to set the SDP session +tracking mechanism. See the dialog module users guide for +more information. + + +A dialog can have one or more SDP sessions active in one +of the following states: + + +- *pending* - only one end point of the +SDP session is known. +- *negotiated* - both end points of the +SDP session are known. + + +An SDP session can be established in one of the following +scenarios: + + +- *INVITE/200ok* - typical "INVITE" and +"200 OK" SDP exchange. +- *200ok/ACK* - "200 OK" and "ACK" SDP +exchange (for calls starting with an empty INVITE). +- *183/PRACK* - early media via "183 +Session Progress" and "PRACK" (see rfc3959 for more information) - +not implemented yet. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded +before this module: + + +- *dialog* - dialog module and +its decencies (tm). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### qos_flag (string) + + +Keeping with OpenSIPS, the module will not do +anything to any message unless instructed to do so via +the config script. You must set the qos_flag +value in the setflag() call of the INVITE you want the +qos module to process. But before you can do that, you +need to tell the qos module which flag value you are +assigning to qos. + + +In most cases when ever you create a new dialog +via create_dialog() function,you will want to set the qos flag. +If create_dialog() is not called and the qos flag is set, +it will not have any effect. + + +This parameter must be set of the module will +not load. + + +*Default value is "Not set!".* + + +```opensips title="Set qos_flag parameter" +... +modparam("qos", "qos_flag", "QOS_FLAG") +... +route { + ... + if ($rm=="INVITE") { + setflag(QOS_FLAG); # Set the qos flag + create_dialog(); # create the dialog + } + ... +} +``` + + +### Exported Functions + + +There are no exported functions that could be used in scripts. + + +### Exported Statistics + + +There are no exported statistics for the qos module. + + +### Exported MI Functions + + +There are no exported MI functions for the qos module. +Check the dialog MI functions for a way to inspect the internals +of a dialog. + + +### Exported Pseudo-Variables + + +There are no exported pseudo-variables for the qos module. + + +### Installation and Running + + +Just load the module and remember to set the flag. + + +## Developer Guide + + +### Available Functions + + +#### register_qoscb (qos, type, cb, param) + + +Register a new callback to the qos. + + +Meaning of the parameters is as follows: + + +- *struct qos_ctx_st* qos* - qos to +register callback to. If maybe NULL only for QOSCB_CREATED callback +type, which is not a per qos type. +- *int type* - types of callbacks; more +types may be register for the same callback function; only +QOSCB_CREATED must be register alone. Possible types: + - *QOSCB_CREATED* - called when a new + qos context is created - it's a global type (not associated to + any qos). + - *QOSCB_ADD_SDP* - called when a new SDP + was added to the qos context - it's a per qos type. + - *QOSCB_UPDATE_SDP* - called when an + existing SDP is updated - it's a per qos type. + - *QOSCB_REMOVE_SDP* - called when an + existing SDP is removed - it's a per qos type. + - *QOSCB_TERMINATED* - called when the + qos is terminated. +- *qos_cb cb* - callback function to be +called. Prototype is: "void (qos_cb) +(struct qos_ctx_st *qos, int type, struct qos_cb_params *params); +" +- *void *param* - parameter to be passed to +the callback function. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/qos/doc/contributors.xml b/modules/qos/doc/contributors.xml deleted file mode 100644 index a76bc9518a5..00000000000 --- a/modules/qos/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 23 - 3 - 2152 - 13 - - - 2. - Liviu Chircu (@liviuchircu) - 16 - 13 - 41 - 72 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 10 - 8 - 25 - 16 - - - 4. - Razvan Crainea (@razvancrainea) - 9 - 7 - 19 - 19 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 8 - 5 - 99 - 96 - - - 6. - Vlad Paiu (@vladpaiu) - 3 - 1 - 5 - 6 - - - 7. - Maksym Sobolyev (@sobomax) - 3 - 1 - 3 - 3 - - - 8. - Ezequiel Lovelle (@lovelle) - 3 - 1 - 1 - 1 - - - 9. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Oct 2011 - Jul 2020 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2009 - May 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Ezequiel Lovelle (@lovelle) - Oct 2014 - Oct 2014 - - - 8. - Ovidiu Sas (@ovidiusas) - Dec 2008 - May 2012 - - - 9. - Vlad Paiu (@vladpaiu) - Jun 2011 - Jun 2011 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/qos/doc/qos.xml b/modules/qos/doc/qos.xml deleted file mode 100644 index c342cf9a5ae..00000000000 --- a/modules/qos/doc/qos.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - QOS Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 SOMA Networks, Inc. - - diff --git a/modules/qos/doc/qos_admin.xml b/modules/qos/doc/qos_admin.xml deleted file mode 100644 index d2a51c64009..00000000000 --- a/modules/qos/doc/qos_admin.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The qos module provides a way to keep track of - per dialog SDP session(s). -
- -
- How it works - - The qos module uses the dialog module to be notified of - any new or updated dialogs. It will then look for and extract - the SDP session (if present) from SIP requests and replies and - keep track of it for the entire life of a dialog. - - All of this happens with a properly configured dialog - and qos module and setting the dialog flag and the qos flag at - the time any INVITE sip message is seen. There is no - config script function call required to set the SDP session - tracking mechanism. See the dialog module users guide for - more information. - - A dialog can have one or more SDP sessions active in one - of the following states: - - - pending - only one end point of the - SDP session is known. - - - - negotiated - both end points of the - SDP session are known. - - - - - - An SDP session can be established in one of the following - scenarios: - - - INVITE/200ok - typical "INVITE" and - "200 OK" SDP exchange. - - - - 200ok/ACK - "200 OK" and "ACK" SDP - exchange (for calls starting with an empty INVITE). - - - - 183/PRACK - early media via "183 - Session Progress" and "PRACK" (see rfc3959 for more information) - - not implemented yet. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded - before this module: - - - - dialog - dialog module and - its decencies (tm). - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>qos_flag</varname> (string) - - Keeping with &osips;, the module will not do - anything to any message unless instructed to do so via - the config script. You must set the qos_flag - value in the setflag() call of the INVITE you want the - qos module to process. But before you can do that, you - need to tell the qos module which flag value you are - assigning to qos. - - In most cases when ever you create a new dialog - via create_dialog() function,you will want to set the qos flag. - If create_dialog() is not called and the qos flag is set, - it will not have any effect. - - This parameter must be set of the module will - not load. - - - - Default value is Not set!. - - - - Set <varname>qos_flag</varname> parameter - -... -modparam("qos", "qos_flag", "QOS_FLAG") -... -route { - ... - if ($rm=="INVITE") { - setflag(QOS_FLAG); # Set the qos flag - create_dialog(); # create the dialog - } - ... -} - - -
- -
-
- Exported Functions - There are no exported functions that could be used in scripts. - -
- -
- Exported Statistics - There are no exported statistics for the qos module. -
- -
- Exported MI Functions - There are no exported MI functions for the qos module. - Check the dialog MI functions for a way to inspect the internals - of a dialog. - -
- -
- Exported Pseudo-Variables - There are no exported pseudo-variables for the qos module. - -
- -
- Installation and Running - Just load the module and remember to set the flag. - -
-
- diff --git a/modules/qos/doc/qos_devel.xml b/modules/qos/doc/qos_devel.xml deleted file mode 100644 index 31bb8f6b6b3..00000000000 --- a/modules/qos/doc/qos_devel.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - &develguide; -
- Available Functions - -
- - <function moreinfo="none">register_qoscb (qos, type, cb, param)</function> - - Register a new callback to the qos. - Meaning of the parameters is as follows: - - - struct qos_ctx_st* qos - qos to - register callback to. If maybe NULL only for QOSCB_CREATED callback - type, which is not a per qos type. - - - - int type - types of callbacks; more - types may be register for the same callback function; only - QOSCB_CREATED must be register alone. Possible types: - - - QOSCB_CREATED - called when a new - qos context is created - it's a global type (not associated to - any qos). - - - - QOSCB_ADD_SDP - called when a new SDP - was added to the qos context - it's a per qos type. - - - - QOSCB_UPDATE_SDP - called when an - existing SDP is updated - it's a per qos type. - - - - QOSCB_REMOVE_SDP - called when an - existing SDP is removed - it's a per qos type. - - - - QOSCB_TERMINATED - called when the - qos is terminated. - - - - - - - qos_cb cb - callback function to be - called. Prototype is: void (qos_cb) - (struct qos_ctx_st *qos, int type, struct qos_cb_params *params); - - - - - void *param - parameter to be passed to - the callback function. - - - -
- -
- -
- diff --git a/modules/qrouting/README b/modules/qrouting/README deleted file mode 100644 index f878aeb43ea..00000000000 --- a/modules/qrouting/README +++ /dev/null @@ -1,546 +0,0 @@ -qrouting (Quality-based Routing) Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Monitored Statistics - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - - 1.4. Exported Parameters - - 1.4.1. db_url (string) - 1.4.2. table_name (string) - 1.4.3. algorithm (integer) - 1.4.4. history_span (integer) - 1.4.5. sampling_interval (integer) - 1.4.6. extra_stats (string) - 1.4.7. min_samples_asr (integer) - 1.4.8. min_samples_ccr (integer) - 1.4.9. min_samples_pdd (integer) - 1.4.10. min_samples_ast (integer) - 1.4.11. min_samples_acd (integer) - 1.4.12. event_bad_dst_threshold (string) - 1.4.13. decimal_digits (string) - - 1.5. Exported Functions - - 1.5.1. qr_set_xstat(rule_id, gw_name, stat_name, - inc_by, [part], [inc_total]) - - 1.5.2. qr_disable_dst(rule_id, dst_name, [part]) - 1.5.3. qr_enable_dst(rule_id, dst_name, [part]) - - 1.6. Exported MI Functions - - 1.6.1. qr_reload - 1.6.2. qr_status - 1.6.3. qr_disable_dst - 1.6.4. qr_enable_dst - - 1.7. Exported Events - - 1.7.1. E_QROUTING_BAD_DST - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the db_url parameter - 1.2. Setting the table_name parameter - 1.3. Setting the algorithm parameter - 1.4. Setting the connection_timeout parameter - 1.5. Setting the connect_poll_interval parameter - 1.6. Setting the extra_stats parameter - 1.7. Setting the min_samples_asr parameter - 1.8. Setting the min_samples_ccr parameter - 1.9. Setting the min_samples_pdd parameter - 1.10. Setting the min_samples_ast parameter - 1.11. Setting the min_samples_acd parameter - 1.12. Setting the event_bad_dst_threshold parameter - 1.13. Setting the decimal_digits parameter - 1.14. qr_set_xstat() usage - 1.15. qr_disable_dst() usage - 1.16. qr_enable_dst() usage - -Chapter 1. Admin Guide - -1.1. Overview - - qrouting is a module which sits on top of drouting, dialog and - tm and performs live tracking of a series of essential gateway - signaling quality indicators (i.e. ASR, CCR, PDD, AST, ACD -- - more details below). Thus, qrouting is able to adjust the - prefix routing behavior at runtime, by dynamically re-ordering - the gateways based on how well they perform during live - traffic, such that: - * well-performing gateways get prioritized for routing - * gateways which show a degradation in signaling quality are - demoted to the end of the routing list - -1.2. Monitored Statistics - - The module keeps track of a series of statistics, for each - drouting (prefix, destination) pair, where a "destination" may - be either a gateway or a carrier. The statistics are: - * ASR (Answer Seizure Ratio) - the percentage of telephone - calls which are answered (200 reply status code). - * CCR (Call Completion Ratio) - the percentage of telephone - calls which are answered back by the gateway, excluding - 5xx, 6xx reply codes and internal 408 timeouts. The - following is always true: CCR >= ASR. - * PDD (Post Dial Delay) - the duration, in milliseconds, - between the receival of the initial INVITE and the receival - of the first 180/183 provisional reply (the call state - advances to "ringing"). - * AST (Average Setup Time) - the duration, in milliseconds, - between the receival of the initial INVITE and the receival - of the first 200 OK reply (the call state advances to - "answered"). The following is always true: AST >= PDD. - * ACD (Average Call Duration) - the duration, in seconds, - between the receival of the initial INVITE and the receival - of the first BYE request from either participant (the call - state advances to "ended"). - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded for this module to work: - * an SQL DB module, offering access to the "qr_profiles" - table - * tm - * dialog - * drouting - -1.4. Exported Parameters - -1.4.1. db_url (string) - - An SQL database URL. - - Default value is NULL. - - Example 1.1. Setting the db_url parameter - -modparam("qrouting", "db_url", "mysql://opensips:opensipsrw@localhost/op -ensips") - -1.4.2. table_name (string) - - The name of the quality-based routing profiles table. - - Default value is "qr_profiles". - - Example 1.2. Setting the table_name parameter - -modparam("qrouting", "table_name", "qr_profiles_bak") - -1.4.3. algorithm (integer) - - Quality-based destination selection/balancing algorithm to use. - - Possible values: - * "dynamic-weights" - for each prefix, all destinations start - with equal weights and receive an equal share of the - traffic. As signaling statistics are gathered for the - destinations, the ones which underperform will receive less - traffic, based on the "penalty" columns of the qr_profiles - table - * "best-dest-first" - for each prefix, the 1st (i.e. best - scoring) destination will receive all the traffic as long - as its quality stays the same. Initially, all destinations - start with a perfect score. This score may degrade if one - or more signaling statistics fall below the "warn" or - "crit" thresholds during routing, case in which the - destinations will be sorted accordingly and traffic will be - routed to the newly determined 1st position in the list - NOTE: for optimal results when using the "best-dest-first" - algorithm, the destinations must be provisioned in - descending order of their expected quality! (i.e. best - quality gateways must be placed towards the start of the - list) - - Default value is "dynamic-weights". - - Example 1.3. Setting the algorithm parameter - -modparam("qrouting", "algorithm", "best-dest-first") - -1.4.4. history_span (integer) - - The duration (in minutes) that a gateway's statistics for a - given call will be kept for. - - Default value is 30 minutes. - - Example 1.4. Setting the connection_timeout parameter - -modparam("qrouting", "history_span", 15) - -1.4.5. sampling_interval (integer) - - The duration (in seconds) of the statistics sampling window. - Every sampling_interval seconds, the accumulated statistics - during the most recent sampling window get added to each - gateway, while the oldest sampled interval statistics are - subtracted (rotated away) from each gateway. - - A lower value will lead to a closer to realtime adjustment to - traffic changes, but it will also increase CPU usage and - internal contention due to locking. - - Default value is 5 seconds. - - Example 1.5. Setting the connect_poll_interval parameter - -modparam("qrouting", "sampling_interval", 5) - -1.4.6. extra_stats (string) - - A semicolon-separated list of custom statistics to be - additionally kept and monitored by the module. In order to - gather these statistics, the module expects the script writer - to call qr_set_xstat() whenever they want to increment a custom - statistic for a (prefix, destination) tuple. - - Extra statistics come in two flavours: positive (a higher value - is better, e.g. ASR) or negative (a lower value is better, e.g. - PDD). The flavour determines the comparison operator to be used - against the statistics's thresholds, and can be specified by - prepending "+" or "-", respectively, in front of the - statistic's name (see example below). - - The minimally accepted number of samples for each statistic may - be changed using the optional / suffix. Default - value: 30 samples (minimum). - - The thresholds and penalties for a custom statistic must be - provided via the qr_profiles table, by extending it with 4 - columns for each extra statistic, named according to these - templates: - * warn_threshold_ - * crit_threshold_ - * warn_penalty_ - * crit_penalty_ - - Default value is NULL. - - Example 1.6. Setting the extra_stats parameter - -modparam("qrouting", "extra_stats", "+mos/60; +r_factor; -503_replies/10 -0") - -1.4.7. min_samples_asr (integer) - - The minimally accepted amount of sampled ASR statistics for - each (prefix, destination) pair before they can be taken into - account. As long as the number of samples stays below this - limit, the ASR statistic of the pair is assumed to be healthy. - - Default value is 30. - - Example 1.7. Setting the min_samples_asr parameter - -modparam("qrouting", "min_samples_asr", 50) - -1.4.8. min_samples_ccr (integer) - - The minimally accepted amount of sampled CCR statistics for - each (prefix, destination) pair before they can be taken into - account. As long as the number of samples stays below this - limit, the CCR statistic of the pair is assumed to be healthy. - - Default value is 30. - - Example 1.8. Setting the min_samples_ccr parameter - -modparam("qrouting", "min_samples_ccr", 50) - -1.4.9. min_samples_pdd (integer) - - The minimally accepted amount of sampled PDD statistics for - each (prefix, destination) pair before they can be taken into - account. As long as the number of samples stays below this - limit, the PDD statistic of the pair is assumed to be healthy. - - Default value is 10. - - Example 1.9. Setting the min_samples_pdd parameter - -modparam("qrouting", "min_samples_pdd", 15) - -1.4.10. min_samples_ast (integer) - - The minimally accepted amount of sampled AST statistics for - each (prefix, destination) pair before they can be taken into - account. As long as the number of samples stays below this - limit, the AST statistic of the pair is assumed to be healthy. - - Default value is 10. - - Example 1.10. Setting the min_samples_ast parameter - -modparam("qrouting", "min_samples_ast", 15) - -1.4.11. min_samples_acd (integer) - - The minimally accepted amount of sampled ACD statistics for - each (prefix, destination) pair before they can be taken into - account. As long as the number of samples stays below this - limit, the ACD statistic of the pair is assumed to be healthy. - - Default value is 20. - - Example 1.11. Setting the min_samples_acd parameter - -modparam("qrouting", "min_samples_acd", 30) - -1.4.12. event_bad_dst_threshold (string) - - The minimally accepted quality of a (prefix, destination) - combination, given as a quoted floating point number in the [0, - 1] interval. Whenever a (prefix, destination) combination - receives a score below this threshold, the E_QROUTING_BAD_DST - event will be triggered. - - Default value is NULL (not set). - - Example 1.12. Setting the event_bad_dst_threshold parameter - -modparam("qrouting", "event_bad_dst_threshold", "0.5") - -1.4.13. decimal_digits (string) - - The amount of decimal digits to use in logging or MI output. - - Default value is 2. - - Example 1.13. Setting the decimal_digits parameter - -modparam("qrouting", "decimal_digits", 4) - -1.5. Exported Functions - -1.5.1. qr_set_xstat(rule_id, gw_name, stat_name, inc_by, [part], -[inc_total]) - - Provide a new sample value for an extra statistic on a given - (prefix, gateway) combination. Extra statistics may be defined - using the extra_stats module parameter. - - Parameters: - * rule_id (integer) - database id of the drouting rule - holding the prefix and its destinations - * gw_name (string) - gateway to account the statistic for. - The gateway must be part of the above rule's destinations. - * stat_name (string) - statistic to account - * inc_by (string) - quoted floating point number, - representing the amount to add to the stat - * part (string, optional, default: 'Default') - the drouting - partition to use - * inc_total (string, optional, default: 1) - the amount to - add to the total stat counter. Usually, this value should - be 1, but it may make sense to set it to 0 when a custom - statistic needs to be set a 2nd, 3rd, etc. time across the - duration of the same established call. - - This function can be used from any route. - - Example 1.14. qr_set_xstat() usage - -# the MoS is set exactly once per call, so we can omit "inc_total" -$var(rule_id) = 1574; -$var(gw_name) = "GW-28"; -$var(mos_score) = "4.28"; -qr_set_xstat($var(rule_id), $var(gw_name), "mos", $var(mos_score)); - -1.5.2. qr_disable_dst(rule_id, dst_name, [part]) - - Within a given routing rule, temporarily remove the given - gateway or carrier from routing, until they are re-enabled via - qr_enable_dst() or qr_enable_dst. The removal effect will be - lost on an OpenSIPS restart. - - Parameters: - * rule_id (integer) - database id of the drouting rule - * dst_name (string) - gateway or carrier to disable - * part (string, optional) - drouting partition - - This function can be used from any route. - - Example 1.15. qr_disable_dst() usage - -# the signaling quality for @rule_id through @dst_name is degrading, rem -ove it! -event_route [E_QROUTING_BAD_DST] -{ - qr_disable_dst($param(rule_id), $param(dst_name), $param(partiti -on)); -} - -1.5.3. qr_enable_dst(rule_id, dst_name, [part]) - - Within a given routing rule, re-introduce the given gateway or - carrier into the routing process. - - Parameters: - * rule_id (integer) - database id of the drouting rule - * dst_name (string) - gateway or carrier to disable - * part (string, optional) - drouting partition - - This function can be used from any route. - - Example 1.16. qr_enable_dst() usage - -# the ban has expired, let's re-enable this gateway and see how it behav -es -qr_enable_dst($param(rule_id), $param(dst_name), $param(partition)); - -1.6. Exported MI Functions - -1.6.1. qr_reload - - Reload all quality-based routing rules from the SQL database. - - MI FIFO Command Format: - -opensips-cli -x mi qr_reload - -1.6.2. qr_status - - Inspect the signaling quality statistics of the current - history_span for all drouting gateways in all partitions, with - various levels of filtering. - - Parameters: - * partition (optional) - a specific drouting partition to - list statistics for - * rule_id (optional) - a specific drouting rule database id - to list statistics for - * dst_name (optional) - a specific gateway or carrier name to - list statistics for - - MI FIFO Command Format: - -opensips-cli -x mi qr_status -opensips-cli -x mi qr_status pstn -opensips-cli -x mi qr_status pstn 11 MY-GW-3 -opensips-cli -x mi qr_status pstn 17 MY-CARR-7 - -1.6.3. qr_disable_dst - - Within a given routing rule, temporarily remove the given - gateway or carrier from routing, until they are re-enabled - manually. The removal effect will be lost on an OpenSIPS - restart. - - Parameters: - * partition (optional) - drouting partition - * rule_id - database id of the drouting rule - * dst_name - gateway or carrier to disable - - MI FIFO Command Format: - -opensips-cli -x mi qr_disable_dst 14 MY-CARR-7 -opensips-cli -x mi qr_disable_dst pstn 81 MY-GW-3 - -1.6.4. qr_enable_dst - - Within a given routing rule, re-introduce the given gateway or - carrier into the routing process. - - Parameters: - * partition (optional) - drouting partition - * rule_id - database id of the drouting rule - * dst_name - gateway or carrier to enable - - MI FIFO Command Format: - -opensips-cli -x mi qr_enable_dst 14 MY-CARR-7 -opensips-cli -x mi qr_enable_dst pstn 81 MY-GW-3 - -1.7. Exported Events - -1.7.1. E_QROUTING_BAD_DST - - This event may be raised during routing, asynchronously, - whenever the score of a (prefix, destination) pair falls below - event_bad_dst_threshold. - - Parameters: - * partition - drouting partition name - * rule_id - database id of the drouting rule - * dst_name - name of the concerned gateway or carrier - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 152 65 4818 2748 - 2. Mihai Tiganus (@tallicamike) 49 15 2955 509 - 3. Maksym Sobolyev (@sobomax) 6 4 6 7 - 4. Zero King (@l2dy) 3 1 1 1 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 2 1 0 3 - 6. Razvan Crainea (@razvancrainea) 2 1 0 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Oct 2020 - Feb 2023 - 2. Liviu Chircu (@liviuchircu) Jan 2020 - Apr 2021 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2020 - Mar 2020 - 4. Zero King (@l2dy) Mar 2020 - Mar 2020 - 5. Razvan Crainea (@razvancrainea) Feb 2020 - Feb 2020 - 6. Mihai Tiganus (@tallicamike) Aug 2014 - Nov 2014 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2020 www.opensips-solutions.com diff --git a/modules/qrouting/README.md b/modules/qrouting/README.md new file mode 100644 index 00000000000..8ea3196cfaa --- /dev/null +++ b/modules/qrouting/README.md @@ -0,0 +1,563 @@ +--- +title: "Quality-based Routing Module" +description: "*qrouting* is a module which sits on top of [drouting](../drouting/doc/drouting.html), [dialog](../dialog/doc/dialog.html) and [tm](../tm/doc/tm.html) and performs live tracking of a series of essential gateway signaling quality indicators (i.e. ASR, CCR, PDD, AST, ACD -- more details below)." +--- + +## Admin Guide + + +### Overview + + +*qrouting* is a module which sits on top of +[drouting](../drouting/doc/drouting.html), +[dialog](../dialog/doc/dialog.html) and +[tm](../tm/doc/tm.html) and performs live +tracking of a series of essential gateway signaling quality indicators +(i.e. ASR, CCR, PDD, AST, ACD -- more details below). Thus, qrouting is +able to adjust the prefix routing behavior at runtime, by dynamically +re-ordering the gateways based on how well they perform during live +traffic, such that: + + +- well-performing gateways get prioritized for routing +- gateways which show a degradation in signaling quality are +demoted to the end of the routing list + + +### Monitored Statistics + + +The module keeps track of a series of statistics, for each drouting +**(prefix, destination)** pair, where a +"destination" may be either a gateway or a carrier. The statistics are: + + +- ASR (Answer Seizure Ratio) - the percentage of telephone +calls which are answered (200 reply status code). +- CCR (Call Completion Ratio) - the percentage of telephone +calls which are answered back by the gateway, excluding +5xx, 6xx reply codes and internal 408 timeouts. The following +is always true: CCR >= ASR. +- PDD (Post Dial Delay) - the duration, in milliseconds, +between the receival of the initial INVITE and the receival +of the first 180/183 provisional reply (the call state +advances to *"ringing"*). +- AST (Average Setup Time) - the duration, in milliseconds, +between the receival of the initial INVITE and the receival +of the first 200 OK reply (the call state advances to +*"answered"*). The following is always +true: AST >= PDD. +- ACD (Average Call Duration) - the duration, in seconds, +between the receival of the initial INVITE and the receival +of the first BYE request from either participant (the call +state advances to *"ended"*). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded for this module to work: + + +- *an SQL DB module, offering access to the +"qr_profiles" table* +- *tm* +- *dialog* +- *drouting* + + +### Exported Parameters + + +#### db_url (string) + + +An SQL database URL. + + +*Default value is **NULL**.* + + +```opensips title="Setting the db_url parameter" +modparam("qrouting", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") +``` + + +#### table_name (string) + + +The name of the quality-based routing profiles table. + + +*Default value is **"qr_profiles"**.* + + +```opensips title="Setting the table_name parameter" +modparam("qrouting", "table_name", "qr_profiles_bak") +``` + + +#### algorithm (integer) + + +Quality-based destination selection/balancing algorithm to use. + + +Possible values: + + +- **"dynamic-weights"** - +for each prefix, all destinations start with equal +weights and receive an equal share of the traffic. As +signaling statistics are gathered for the destinations, the +ones which underperform will receive less traffic, +based on the "penalty" columns of the +*qr_profiles* table +- **"best-dest-first"** - for each +prefix, the 1st (i.e. *best scoring*) +destination will receive all the traffic as long as its +quality stays the same. Initially, all destinations start +with a perfect score. This score may degrade if one or +more signaling statistics fall below the "warn" or "crit" +thresholds during routing, case in which the destinations +will be sorted accordingly and traffic will be routed to +the newly determined 1st position in the list +*NOTE*: for optimal results when +using the "best-dest-first" algorithm, the destinations +must be provisioned in descending order of their +expected quality! (i.e. best quality gateways must be +placed towards the start of the list) + + +*Default value is **"dynamic-weights"**.* + + +```opensips title="Setting the algorithm parameter" +modparam("qrouting", "algorithm", "best-dest-first") +``` + + +#### history_span (integer) + + +The duration (in minutes) that a gateway's statistics for a given call +will be kept for. + + +*Default value is **30** minutes.* + + +```opensips title="Setting the connection_timeout parameter" +modparam("qrouting", "history_span", 15) +``` + + +#### sampling_interval (integer) + + +The duration (in seconds) of the statistics sampling window. Every +*[sampling interval](#param_sampling_interval)* seconds, +the accumulated statistics during the most recent sampling window get +added to each gateway, while the oldest sampled interval statistics are +subtracted (rotated away) from each gateway. + + +A lower value will lead to a closer to realtime adjustment to traffic +changes, but it will also increase CPU usage and internal contention +due to locking. + + +*Default value is **5** seconds.* + + +```opensips title="Setting the connect_poll_interval parameter" +modparam("qrouting", "sampling_interval", 5) +``` + + +#### extra_stats (string) + + +A semicolon-separated list of custom statistics to be additionally kept +and monitored by the module. In order to gather these statistics, the +module expects the script writer to call +[qr set xstat](#func_qr_set_xstat) whenever they want to increment a +custom statistic for a (prefix, destination) tuple. + + +Extra statistics come in two flavours: *positive* +(a higher value is better, e.g. ASR) or *negative* +(a lower value is better, e.g. PDD). The flavour determines the +comparison operator to be used against the statistics's thresholds, and +can be specified by prepending **"+"** or +**"-"**, respectively, in front +of the statistic's name (see example below). + + +The minimally accepted number of samples for each statistic may be +changed using the optional **/** +suffix. Default value: **30** samples +(minimum). + + +The thresholds and penalties for a custom statistic must be provided +via the *qr_profiles* table, by extending it with 4 +columns for each extra statistic, named according to these +templates: + + +- warn_threshold_** +- crit_threshold_** +- warn_penalty_** +- crit_penalty_** + + +*Default value is **NULL**.* + + +```opensips title="Setting the extra_stats parameter" +modparam("qrouting", "extra_stats", "+mos/60; +r_factor; -503_replies/100") +``` + + +#### min_samples_asr (integer) + + +The minimally accepted amount of sampled ASR statistics for each +(prefix, destination) pair before they can be taken into account. As +long as the number of samples stays below this limit, the ASR statistic +of the pair is assumed to be healthy. + + +*Default value is **30**.* + + +```opensips title="Setting the min_samples_asr parameter" +modparam("qrouting", "min_samples_asr", 50) +``` + + +#### min_samples_ccr (integer) + + +The minimally accepted amount of sampled CCR statistics for each +(prefix, destination) pair before they can be taken into account. As +long as the number of samples stays below this limit, the CCR statistic +of the pair is assumed to be healthy. + + +*Default value is **30**.* + + +```opensips title="Setting the min_samples_ccr parameter" +modparam("qrouting", "min_samples_ccr", 50) +``` + + +#### min_samples_pdd (integer) + + +The minimally accepted amount of sampled PDD statistics for each +(prefix, destination) pair before they can be taken into account. As +long as the number of samples stays below this limit, the PDD statistic +of the pair is assumed to be healthy. + + +*Default value is **10**.* + + +```opensips title="Setting the min_samples_pdd parameter" +modparam("qrouting", "min_samples_pdd", 15) +``` + + +#### min_samples_ast (integer) + + +The minimally accepted amount of sampled AST statistics for each +(prefix, destination) pair before they can be taken into account. As +long as the number of samples stays below this limit, the AST statistic +of the pair is assumed to be healthy. + + +*Default value is **10**.* + + +```opensips title="Setting the min_samples_ast parameter" +modparam("qrouting", "min_samples_ast", 15) +``` + + +#### min_samples_acd (integer) + + +The minimally accepted amount of sampled ACD statistics for each +(prefix, destination) pair before they can be taken into account. As +long as the number of samples stays below this limit, the ACD statistic +of the pair is assumed to be healthy. + + +*Default value is **20**.* + + +```opensips title="Setting the min_samples_acd parameter" +modparam("qrouting", "min_samples_acd", 30) +``` + + +#### event_bad_dst_threshold (string) + + +The minimally accepted quality of a (prefix, destination) combination, +given as a quoted floating point number in the [0, 1] interval. +Whenever a (prefix, destination) combination receives a score below +this threshold, the [E QROUTING BAD DST](#event_e_qrouting_bad_dst) event +will be triggered. + + +*Default value is **NULL** (not set).* + + +```opensips title="Setting the event_bad_dst_threshold parameter" +modparam("qrouting", "event_bad_dst_threshold", "0.5") +``` + + +#### decimal_digits (string) + + +The amount of decimal digits to use in logging or MI output. + + +*Default value is **2**.* + + +```opensips title="Setting the decimal_digits parameter" +modparam("qrouting", "decimal_digits", 4) +``` + + +### Exported Functions + + +#### qr_set_xstat(rule_id, gw_name, stat_name, inc_by, [part], [inc_total]) + + +Provide a new sample value for an extra statistic on a given (prefix, +gateway) combination. Extra statistics may be defined using the +[extra stats](#param_extra_stats) module parameter. + + +Parameters: + + +- *rule_id (integer)* - database id of the +drouting rule holding the prefix and its destinations +- *gw_name (string)* - gateway to account the +statistic for. The gateway must be part of the above rule's +destinations. +- *stat_name (string)* - statistic to account +- *inc_by (string)* - quoted floating point +number, representing the amount to add to the stat +- *part (string, optional, default: 'Default')* - +the drouting partition to use +- *inc_total (string, optional, default: 1)* - +the amount to add to the total stat counter. Usually, this +value should be 1, but it may make sense to set it to 0 when a +custom statistic needs to be set a 2nd, 3rd, etc. time across +the duration of the same established call. + + +This function can be used from any route. + + +```opensips title="qr_set_xstat() usage" +# the MoS is set exactly once per call, so we can omit "inc_total" +$var(rule_id) = 1574; +$var(gw_name) = "GW-28"; +$var(mos_score) = "4.28"; +qr_set_xstat($var(rule_id), $var(gw_name), "mos", $var(mos_score)); + +``` + + +#### qr_disable_dst(rule_id, dst_name, [part]) + + +Within a given routing rule, temporarily remove the given gateway or +carrier from routing, until they are re-enabled via +[qr enable dst](#func_qr_enable_dst) or [mi qr enable dst](#mi_qr_enable_dst). +The removal effect will be lost on an OpenSIPS restart. + + +Parameters: + + +- *rule_id (integer)* - database id of the +drouting rule +- *dst_name (string)* - gateway or carrier +to disable +- *part (string, optional)* - drouting partition + + +This function can be used from any route. + + +```opensips title="qr_disable_dst() usage" +# the signaling quality for @rule_id through @dst_name is degrading, remove it! +event_route [E_QROUTING_BAD_DST] +{ + qr_disable_dst($param(rule_id), $param(dst_name), $param(partition)); +} + +``` + + +#### qr_enable_dst(rule_id, dst_name, [part]) + + +Within a given routing rule, re-introduce the given gateway or +carrier into the routing process. + + +Parameters: + + +- *rule_id (integer)* - database id of the +drouting rule +- *dst_name (string)* - gateway or carrier +to disable +- *part (string, optional)* - drouting partition + + +This function can be used from any route. + + +```opensips title="qr_enable_dst() usage" +# the ban has expired, let's re-enable this gateway and see how it behaves +qr_enable_dst($param(rule_id), $param(dst_name), $param(partition)); +``` + + +### Exported MI Functions + + +#### qr_reload + + +Reload all quality-based routing rules from the SQL database. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi qr_reload +``` + + +#### qr_status + + +Inspect the signaling quality statistics of the current +[history span](#param_history_span) for all drouting gateways in all +partitions, with various levels of filtering. + + +Parameters: + + +- *partition (optional)* - a specific +drouting partition to list statistics for +- *rule_id (optional)* - a specific drouting +rule database id to list statistics for +- *dst_name (optional)* - a specific gateway or +carrier name to list statistics for + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi qr_status +opensips-cli -x mi qr_status pstn +opensips-cli -x mi qr_status pstn 11 MY-GW-3 +opensips-cli -x mi qr_status pstn 17 MY-CARR-7 +``` + + +#### qr_disable_dst + + +Within a given routing rule, temporarily remove the given gateway or +carrier from routing, until they are re-enabled manually. The removal +effect will be lost on an OpenSIPS restart. + + +Parameters: + + +- *partition (optional)* - drouting partition +- *rule_id* - database id of the drouting rule +- *dst_name* - gateway or carrier to disable + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi qr_disable_dst 14 MY-CARR-7 +opensips-cli -x mi qr_disable_dst pstn 81 MY-GW-3 +``` + + +#### qr_enable_dst + + +Within a given routing rule, re-introduce the given gateway or +carrier into the routing process. + + +Parameters: + + +- *partition (optional)* - drouting partition +- *rule_id* - database id of the drouting rule +- *dst_name* - gateway or carrier to enable + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi qr_enable_dst 14 MY-CARR-7 +opensips-cli -x mi qr_enable_dst pstn 81 MY-GW-3 +``` + + +### Exported Events + + +#### E_QROUTING_BAD_DST + + +This event may be raised during routing, asynchronously, whenever the +score of a (prefix, destination) pair falls below +[event bad dst threshold](#param_event_bad_dst_threshold). + + +Parameters: + + +- *partition* - drouting partition name +- *rule_id* - database id of the drouting rule +- *dst_name* - name of the concerned gateway or carrier + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/qrouting/doc/contributors.xml b/modules/qrouting/doc/contributors.xml deleted file mode 100644 index 1e696b6bb6d..00000000000 --- a/modules/qrouting/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 152 - 65 - 4818 - 2748 - - - 2. - Mihai Tiganus (@tallicamike) - 49 - 15 - 2955 - 509 - - - 3. - Maksym Sobolyev (@sobomax) - 6 - 4 - 6 - 7 - - - 4. - Zero King (@l2dy) - 3 - 1 - 1 - 1 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 2 - 1 - 0 - 3 - - - 6. - Razvan Crainea (@razvancrainea) - 2 - 1 - 0 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Oct 2020 - Feb 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Jan 2020 - Apr 2021 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2020 - Mar 2020 - - - 4. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Feb 2020 - Feb 2020 - - - 6. - Mihai Tiganus (@tallicamike) - Aug 2014 - Nov 2014 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/qrouting/doc/qrouting.xml b/modules/qrouting/doc/qrouting.xml deleted file mode 100644 index 362aefb97fa..00000000000 --- a/modules/qrouting/doc/qrouting.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - qrouting (Quality-based Routing) Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2020 &osipssol; - - diff --git a/modules/qrouting/doc/qrouting_admin.xml b/modules/qrouting/doc/qrouting_admin.xml deleted file mode 100644 index d07379271ca..00000000000 --- a/modules/qrouting/doc/qrouting_admin.xml +++ /dev/null @@ -1,734 +0,0 @@ - - - - -&adminguide; - -
- Overview - - qrouting is a module which sits on top of - drouting, - dialog and - tm and performs live - tracking of a series of essential gateway signaling quality indicators - (i.e. ASR, CCR, PDD, AST, ACD -- more details below). Thus, qrouting is - able to adjust the prefix routing behavior at runtime, by dynamically - re-ordering the gateways based on how well they perform during live - traffic, such that: - - - well-performing gateways get prioritized for routing - - - gateways which show a degradation in signaling quality are - demoted to the end of the routing list - - - -
- -
- Monitored Statistics - - The module keeps track of a series of statistics, for each drouting - (prefix, destination) pair, where a - "destination" may be either a gateway or a carrier. The statistics are: - - - ASR (Answer Seizure Ratio) - the percentage of telephone - calls which are answered (200 reply status code). - - - - CCR (Call Completion Ratio) - the percentage of telephone - calls which are answered back by the gateway, excluding - 5xx, 6xx reply codes and internal 408 timeouts. The following - is always true: CCR >= ASR. - - - - PDD (Post Dial Delay) - the duration, in milliseconds, - between the receival of the initial INVITE and the receival - of the first 180/183 provisional reply (the call state - advances to "ringing"). - - - - AST (Average Setup Time) - the duration, in milliseconds, - between the receival of the initial INVITE and the receival - of the first 200 OK reply (the call state advances to - "answered"). The following is always - true: AST >= PDD. - - - - ACD (Average Call Duration) - the duration, in seconds, - between the receival of the initial INVITE and the receival - of the first BYE request from either participant (the call - state advances to "ended"). - - - - -
- - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded for this module to work: - - an SQL DB module, offering access to the - "qr_profiles" table - tm - dialog - drouting - - -
-
- -
- Exported Parameters - -
- <varname>db_url</varname> (string) - - An SQL database URL. - - - - Default value is NULL. - - - - Setting the <varname>db_url</varname> parameter - - -modparam("qrouting", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") - - -
- -
- <varname>table_name</varname> (string) - - The name of the quality-based routing profiles table. - - - - Default value is "qr_profiles". - - - - Setting the <varname>table_name</varname> parameter - - -modparam("qrouting", "table_name", "qr_profiles_bak") - - -
- -
- <varname>algorithm</varname> (integer) - - Quality-based destination selection/balancing algorithm to use. - - - Possible values: - - - - "dynamic-weights" - - for each prefix, all destinations start with equal - weights and receive an equal share of the traffic. As - signaling statistics are gathered for the destinations, the - ones which underperform will receive less traffic, - based on the "penalty" columns of the - qr_profiles table - - - - - "best-dest-first" - for each - prefix, the 1st (i.e. best scoring) - destination will receive all the traffic as long as its - quality stays the same. Initially, all destinations start - with a perfect score. This score may degrade if one or - more signaling statistics fall below the "warn" or "crit" - thresholds during routing, case in which the destinations - will be sorted accordingly and traffic will be routed to - the newly determined 1st position in the list - - - NOTE: for optimal results when - using the "best-dest-first" algorithm, the destinations - must be provisioned in descending order of their - expected quality! (i.e. best quality gateways must be - placed towards the start of the list) - - - - - - - Default value is "dynamic-weights". - - - - Setting the <varname>algorithm</varname> parameter - - -modparam("qrouting", "algorithm", "best-dest-first") - - -
- -
- <varname>history_span</varname> (integer) - - The duration (in minutes) that a gateway's statistics for a given call - will be kept for. - - - - Default value is 30 minutes. - - - - Setting the <varname>connection_timeout</varname> parameter - - -modparam("qrouting", "history_span", 15) - - -
- -
- <varname>sampling_interval</varname> (integer) - - The duration (in seconds) of the statistics sampling window. Every - seconds, - the accumulated statistics during the most recent sampling window get - added to each gateway, while the oldest sampled interval statistics are - subtracted (rotated away) from each gateway. - - - A lower value will lead to a closer to realtime adjustment to traffic - changes, but it will also increase CPU usage and internal contention - due to locking. - - - - Default value is 5 seconds. - - - - Setting the <varname>connect_poll_interval</varname> parameter - - -modparam("qrouting", "sampling_interval", 5) - - -
- -
- <varname>extra_stats</varname> (string) - - A semicolon-separated list of custom statistics to be additionally kept - and monitored by the module. In order to gather these statistics, the - module expects the script writer to call - whenever they want to increment a - custom statistic for a (prefix, destination) tuple. - - - - Extra statistics come in two flavours: positive - (a higher value is better, e.g. ASR) or negative - (a lower value is better, e.g. PDD). The flavour determines the - comparison operator to be used against the statistics's thresholds, and - can be specified by prepending "+" or - "-", respectively, in front - of the statistic's name (see example below). - - - - The minimally accepted number of samples for each statistic may be - changed using the optional /<min_samples> - suffix. Default value: 30 samples - (minimum). - - - - The thresholds and penalties for a custom statistic must be provided - via the qr_profiles table, by extending it with 4 - columns for each extra statistic, named according to these - templates: - - warn_threshold_<STAT> - crit_threshold_<STAT> - warn_penalty_<STAT> - crit_penalty_<STAT> - - - - - - Default value is NULL. - - - - Setting the <varname>extra_stats</varname> parameter - - -modparam("qrouting", "extra_stats", "+mos/60; +r_factor; -503_replies/100") - - -
- -
- <varname>min_samples_asr</varname> (integer) - - The minimally accepted amount of sampled ASR statistics for each - (prefix, destination) pair before they can be taken into account. As - long as the number of samples stays below this limit, the ASR statistic - of the pair is assumed to be healthy. - - - - Default value is 30. - - - - Setting the <varname>min_samples_asr</varname> parameter - - -modparam("qrouting", "min_samples_asr", 50) - - -
- -
- <varname>min_samples_ccr</varname> (integer) - - The minimally accepted amount of sampled CCR statistics for each - (prefix, destination) pair before they can be taken into account. As - long as the number of samples stays below this limit, the CCR statistic - of the pair is assumed to be healthy. - - - - Default value is 30. - - - - Setting the <varname>min_samples_ccr</varname> parameter - - -modparam("qrouting", "min_samples_ccr", 50) - - -
- -
- <varname>min_samples_pdd</varname> (integer) - - The minimally accepted amount of sampled PDD statistics for each - (prefix, destination) pair before they can be taken into account. As - long as the number of samples stays below this limit, the PDD statistic - of the pair is assumed to be healthy. - - - - Default value is 10. - - - - Setting the <varname>min_samples_pdd</varname> parameter - - -modparam("qrouting", "min_samples_pdd", 15) - - -
- -
- <varname>min_samples_ast</varname> (integer) - - The minimally accepted amount of sampled AST statistics for each - (prefix, destination) pair before they can be taken into account. As - long as the number of samples stays below this limit, the AST statistic - of the pair is assumed to be healthy. - - - - Default value is 10. - - - - Setting the <varname>min_samples_ast</varname> parameter - - -modparam("qrouting", "min_samples_ast", 15) - - -
- -
- <varname>min_samples_acd</varname> (integer) - - The minimally accepted amount of sampled ACD statistics for each - (prefix, destination) pair before they can be taken into account. As - long as the number of samples stays below this limit, the ACD statistic - of the pair is assumed to be healthy. - - - - Default value is 20. - - - - Setting the <varname>min_samples_acd</varname> parameter - - -modparam("qrouting", "min_samples_acd", 30) - - -
- -
- <varname>event_bad_dst_threshold</varname> (string) - - The minimally accepted quality of a (prefix, destination) combination, - given as a quoted floating point number in the [0, 1] interval. - Whenever a (prefix, destination) combination receives a score below - this threshold, the event - will be triggered. - - - - Default value is NULL (not set). - - - - Setting the <varname>event_bad_dst_threshold</varname> parameter - - -modparam("qrouting", "event_bad_dst_threshold", "0.5") - - -
- -
- <varname>decimal_digits</varname> (string) - - The amount of decimal digits to use in logging or MI output. - - - - Default value is 2. - - - - Setting the <varname>decimal_digits</varname> parameter - - -modparam("qrouting", "decimal_digits", 4) - - -
- -
- - - -
- Exported Functions - -
- - <function moreinfo="none">qr_set_xstat(rule_id, gw_name, stat_name, - inc_by, [part], [inc_total])</function> - - - Provide a new sample value for an extra statistic on a given (prefix, - gateway) combination. Extra statistics may be defined using the - module parameter. - - Parameters: - - - rule_id (integer) - database id of the - drouting rule holding the prefix and its destinations - - - gw_name (string) - gateway to account the - statistic for. The gateway must be part of the above rule's - destinations. - - - stat_name (string) - statistic to account - - - inc_by (string) - quoted floating point - number, representing the amount to add to the stat - - - part (string, optional, default: 'Default') - - the drouting partition to use - - - inc_total (string, optional, default: 1) - - the amount to add to the total stat counter. Usually, this - value should be 1, but it may make sense to set it to 0 when a - custom statistic needs to be set a 2nd, 3rd, etc. time across - the duration of the same established call. - - - - This function can be used from any route. - - - <function>qr_set_xstat()</function> usage - - -# the MoS is set exactly once per call, so we can omit "inc_total" -$var(rule_id) = 1574; -$var(gw_name) = "GW-28"; -$var(mos_score) = "4.28"; -qr_set_xstat($var(rule_id), $var(gw_name), "mos", $var(mos_score)); - - -
- -
- - <function moreinfo="none">qr_disable_dst(rule_id, dst_name, [part])</function> - - - Within a given routing rule, temporarily remove the given gateway or - carrier from routing, until they are re-enabled via - or . - The removal effect will be lost on an OpenSIPS restart. - - Parameters: - - - rule_id (integer) - database id of the - drouting rule - - - dst_name (string) - gateway or carrier - to disable - - - part (string, optional) - drouting partition - - - - This function can be used from any route. - - - <function>qr_disable_dst()</function> usage - - -# the signaling quality for @rule_id through @dst_name is degrading, remove it! -event_route [E_QROUTING_BAD_DST] -{ - qr_disable_dst($param(rule_id), $param(dst_name), $param(partition)); -} - - -
- -
- - <function moreinfo="none">qr_enable_dst(rule_id, dst_name, [part])</function> - - - Within a given routing rule, re-introduce the given gateway or - carrier into the routing process. - - Parameters: - - - rule_id (integer) - database id of the - drouting rule - - - dst_name (string) - gateway or carrier - to disable - - - part (string, optional) - drouting partition - - - - This function can be used from any route. - - - <function>qr_enable_dst()</function> usage - - -# the ban has expired, let's re-enable this gateway and see how it behaves -qr_enable_dst($param(rule_id), $param(dst_name), $param(partition)); - - -
- -
- - - -
- Exported MI Functions - -
- <function moreinfo="none">qr_reload</function> - - - Reload all quality-based routing rules from the SQL database. - - - MI FIFO Command Format: - - - - -opensips-cli -x mi qr_reload - -
- -
- <function moreinfo="none">qr_status</function> - - - Inspect the signaling quality statistics of the current - for all drouting gateways in all - partitions, with various levels of filtering. - - Parameters: - - - partition (optional) - a specific - drouting partition to list statistics for - - - rule_id (optional) - a specific drouting - rule database id to list statistics for - - - dst_name (optional) - a specific gateway or - carrier name to list statistics for - - - - MI FIFO Command Format: - - - - -opensips-cli -x mi qr_status -opensips-cli -x mi qr_status pstn -opensips-cli -x mi qr_status pstn 11 MY-GW-3 -opensips-cli -x mi qr_status pstn 17 MY-CARR-7 - -
- -
- <function moreinfo="none">qr_disable_dst</function> - - - Within a given routing rule, temporarily remove the given gateway or - carrier from routing, until they are re-enabled manually. The removal - effect will be lost on an OpenSIPS restart. - - Parameters: - - - partition (optional) - drouting partition - - - rule_id - database id of the drouting rule - - - dst_name - gateway or carrier to disable - - - - MI FIFO Command Format: - - - - -opensips-cli -x mi qr_disable_dst 14 MY-CARR-7 -opensips-cli -x mi qr_disable_dst pstn 81 MY-GW-3 - -
- -
- <function moreinfo="none">qr_enable_dst</function> - - - Within a given routing rule, re-introduce the given gateway or - carrier into the routing process. - - Parameters: - - - partition (optional) - drouting partition - - - rule_id - database id of the drouting rule - - - dst_name - gateway or carrier to enable - - - - MI FIFO Command Format: - - - - -opensips-cli -x mi qr_enable_dst 14 MY-CARR-7 -opensips-cli -x mi qr_enable_dst pstn 81 MY-GW-3 - -
- -
- - - -
- Exported Events -
- - <function moreinfo="none">E_QROUTING_BAD_DST</function> - - - This event may be raised during routing, asynchronously, whenever the - score of a (prefix, destination) pair falls below - . - - Parameters: - - - partition - drouting partition name - - - rule_id - database id of the drouting rule - - - dst_name - name of the concerned gateway or carrier - - -
- -
- -
diff --git a/modules/rabbitmq_consumer/README b/modules/rabbitmq_consumer/README deleted file mode 100644 index aed3bf49fb4..00000000000 --- a/modules/rabbitmq_consumer/README +++ /dev/null @@ -1,250 +0,0 @@ -RabbitMQ Consumer Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. connection_id (string) - 1.3.2. connect_timeout (integer) - 1.3.3. retry_timeout (integer) - 1.3.4. use_tls (integer) - - 1.4. Exported Functions - 1.5. Exported Events - - 1.5.1. - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set connection_id parameter - 1.2. Setting the connect_timeout parameter - 1.3. Setting the retry_timeout parameter - 1.4. Set the use_tls parameter - -Chapter 1. Admin Guide - -1.1. Overview - - RabbitMQ Consumer (http://www.rabbitmq.com/) is an open source - messaging server. It's purpose is to manage received messages - in queues, taking advantage of the flexible AMQP protocol. - - Using this module you can subscribe consumers to a RabbitMQ - broker in order to receive AMQP messages for specified queues. - The messages will be delivered by triggering events through the - OpenSIPS Event Interface. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_mgm if use_tls is enabled. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * librabbitmq-dev - - NOte that the module is not compatible with versions 0.4 or - below of the librabbitmq-dev library. - -1.3. Exported Parameters - -1.3.1. connection_id (string) - - Specify the configuration for a RabbitMQ connection. It - contains a set of parameters used to customize the connection - to the server as well as the consumer subscription. The format - of the parameter is param1=value1; param2=value2;. The uri, - queue and event parameters are mandatory. - - This parameter can be set multiple times, for each RabbitMQ - connection. - - The following parameters can be used: - * uri - Mandatory parameter - a full amqp URI as described - here. Missing fields in the URI will receive default - values, such as: user: guest, password: guest, host: - localhost, vhost: /, port: 5672. TLS connections are - specified using an amqps URI. - * queue - Mandatory parameter - the name of the RabbitMQ - queue to subscribe a consumer to. This parameter is - mandatory. - * event - Mandatory parameter - the name of the OpenSIPS - event that will be triggered for each AMQP message - received. - * ack - flag that indicates to the broker that messages will - be acknowledged upon receival. If you do not set this flag, - the server will not expect ACKs and OpenSIPS will not send - them. - * exclusive - flag that indicates to the broker that - exclusive consumer access is requested, meaning only this - consumer can access the queue. - * frame_max - the maximum size of an AMQP frame. Default size - is 131072. - * heartbeat - interval in seconds used to send heartbeat - messages. Default is disabled. - * tls_domain - indicates which TLS domain (as defined using - the tls_mgm module) to use for this connection. This must - be an amqps URI and the use_tls module parameter must be - enabled. - - Example 1.1. Set connection_id parameter -... -# connection to a RabbitMQ server on localhost, default port -# with a 5 seconds interval for heartbeat messages -modparam("rabbitmq_consumer", "connection_id", - "uri = amqp://127.0.0.1; queue = myqueue1; event = E_Q1_MSG; heartbe -at = 5;") -... -# consumer that acknowledges messages -modparam("rabbitmq_consumer", "connection_id", - "uri = amqp://127.0.0.1; queue = myqueue2; event = E_Q2_MSG; ack;") -... -# TLS connection -modparam("rabbitmq_consumer", "connection_id", - "uri = amqps://127.0.0.1; queue = myqueue3; event = E_Q3_MSG; tls_do -main=rmq;") -... - -1.3.2. connect_timeout (integer) - - The maximally allowed duration (in milliseconds) for the - establishment of a TCP connection with a RabbitMQ server. - - Default value is “500” (milliseconds). - - Example 1.2. Setting the connect_timeout parameter -... -modparam("rabbitmq_consumer", "connect_timeout", 1000) -... - -1.3.3. retry_timeout (integer) - - The interval (in milliseconds) after which OpenSIPS will try to - re-establish a failed AMQP connection to a RabbitMQ server. - - Default value is “5000” (milliseconds). - - Example 1.3. Setting the retry_timeout parameter -... -modparam("rabbitmq_consumer", "retry_timeout", 10000) -... - -1.3.4. use_tls (integer) - - Setting this parameter will allow you to use TLS for broker - connections. In order to enable TLS for a specific connection, - you can use the "tls_domain=dom_name" parameter in the - configuration specified through the connection_id module - parameter. - - When using this parameter, you must also ensure that tls_mgm is - loaded and properly configured. Refer to the the module for - additional info regarding TLS client domains. - - Default value is 0 (not enabled) - - Example 1.4. Set the use_tls parameter -... -modparam("tls_mgm", "client_domain", "rmq") -modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") -modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") -modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") -... -modparam("rabbitmq_consumer", "use_tls", 1) -... - -1.4. Exported Functions - - The module does not export any script functions. - -1.5. Exported Events - - An event with a custom name, as set in the event field of the - connection_id parameter, will be raised for each AMQP message - received. - - Parameters: - * body - the AMQP message body. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 18 5 1375 9 - 2. Maksym Sobolyev (@sobomax) 6 4 6 6 - 3. Razvan Crainea (@razvancrainea) 6 4 6 1 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 1 2 - 5. Ken Rice 3 1 1 1 - 6. Liviu Chircu (@liviuchircu) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2024 - Jun 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2020 - Feb 2023 - 4. Vlad Patrascu (@rvlad-patrascu) Apr 2019 - Dec 2020 - 5. Razvan Crainea (@razvancrainea) May 2019 - Jul 2020 - 6. Liviu Chircu (@liviuchircu) Jul 2019 - Jul 2019 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2019 www.opensips-solutions.com diff --git a/modules/rabbitmq_consumer/README.md b/modules/rabbitmq_consumer/README.md new file mode 100644 index 00000000000..bf45a3cfe40 --- /dev/null +++ b/modules/rabbitmq_consumer/README.md @@ -0,0 +1,207 @@ +--- +title: "RabbitMQ Consumer Module" +description: "*RabbitMQ Consumer* ([http://www.rabbitmq.com/](http://www.rabbitmq.com/)) is an open source messaging server." +--- + +## Admin Guide + + +### Overview + + +*RabbitMQ Consumer* +([http://www.rabbitmq.com/](http://www.rabbitmq.com/)) +is an open source messaging server. It's purpose is to +manage received messages in queues, taking advantage of +the flexible AMQP protocol. + + +Using this module you can subscribe consumers to a RabbitMQ broker in order +to receive AMQP messages for specified queues. The messages will be delivered +by triggering events through the OpenSIPS Event Interface. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_mgm* if [use tls](#param_use_tls) is enabled. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *librabbitmq-dev* + + +> [!NOTE] +> The module is not compatible with versions 0.4 or below of +> the librabbitmq-dev library. + + +### Exported Parameters + + +#### connection_id (string) + + +Specify the configuration for a RabbitMQ connection. It contains a set +of parameters used to customize the connection to the server as well as +the consumer subscription. The format of the parameter is +*param1=value1; param2=value2;*. +The *uri*, *queue* and +*event* parameters are mandatory. + + +This parameter can be set multiple times, for each RabbitMQ +connection. + + +The following parameters can be used: + + +- *uri* - Mandatory parameter - a full +*amqp* URI as described +[here](https://www.rabbitmq.com/uri-spec.html). +Missing fields in the URI will receive default values, +such as: *user: guest*, +*password: guest*, +*host: localhost*, +*vhost: /*, +*port: 5672*. TLS connections are specified +using an *amqps* URI. +- *queue* - Mandatory parameter - the name of the +RabbitMQ queue to subscribe a consumer to. This parameter is mandatory. +- *event* - Mandatory parameter - the name of the OpenSIPS +event that will be triggered for each AMQP message received. +- *ack* - flag that indicates to the broker +that messages will be acknowledged upon receival. If you do not +set this flag, the server will not expect ACKs and OpenSIPS will not +send them. +- *exclusive* - flag that indicates to the broker +that exclusive consumer access is requested, meaning only this consumer +can access the queue. +- *frame_max* - the maximum size of an AMQP +frame. Default size is 131072. +- *heartbeat* - interval in seconds used +to send heartbeat messages. Default is disabled. +- *tls_domain* - indicates which TLS domain (as +defined using the *tls_mgm* module) to use for +this connection. This must be an *amqps* URI and +the [use tls](#param_use_tls) module parameter must be enabled. + + +```opensips title="Set connection_id parameter" +... +# connection to a RabbitMQ server on localhost, default port +# with a 5 seconds interval for heartbeat messages +modparam("rabbitmq_consumer", "connection_id", + "uri = amqp://127.0.0.1; queue = myqueue1; event = E_Q1_MSG; heartbeat = 5;") +... +# consumer that acknowledges messages +modparam("rabbitmq_consumer", "connection_id", + "uri = amqp://127.0.0.1; queue = myqueue2; event = E_Q2_MSG; ack;") +... +# TLS connection +modparam("rabbitmq_consumer", "connection_id", + "uri = amqps://127.0.0.1; queue = myqueue3; event = E_Q3_MSG; tls_domain=rmq;") +... + +``` + + +#### connect_timeout (integer) + + +The maximally allowed duration (in milliseconds) for the establishment +of a TCP connection with a RabbitMQ server. + + +*Default value is "500" (milliseconds).* + + +```opensips title="Setting the connect_timeout parameter" +... +modparam("rabbitmq_consumer", "connect_timeout", 1000) +... +``` + + +#### retry_timeout (integer) + + +The interval (in milliseconds) after which OpenSIPS will try to +re-establish a failed AMQP connection to a RabbitMQ server. + + +*Default value is "5000" (milliseconds).* + + +```opensips title="Setting the retry_timeout parameter" +... +modparam("rabbitmq_consumer", "retry_timeout", 10000) +... +``` + + +#### use_tls (integer) + + +Setting this parameter will allow you to use TLS for broker connections. +In order to enable TLS for a specific connection, you can use the +"tls_domain=*dom_name*" parameter in the configuration +specified through the [connection id](#param_connection_id) module parameter. + + +When using this parameter, you must also ensure that +*tls_mgm* is loaded and properly configured. Refer to +the the module for additional info regarding TLS client domains. + + +*Default value is **0** (not enabled)* + + +```opensips title="Set the use_tls parameter" +... +modparam("tls_mgm", "client_domain", "rmq") +modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") +modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") +modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") +... +modparam("rabbitmq_consumer", "use_tls", 1) +... +``` + + +### Exported Functions + + +The module does not export any script functions. + + +### Exported Events + + +An event with a custom name, as set in the *event* +field of the [connection id](#param_connection_id) parameter, +will be raised for each AMQP message received. + + +Parameters: + + +- *body* - the AMQP message body. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rabbitmq_consumer/doc/contributors.xml b/modules/rabbitmq_consumer/doc/contributors.xml deleted file mode 100644 index d487352e528..00000000000 --- a/modules/rabbitmq_consumer/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 18 - 5 - 1375 - 9 - - - 2. - Maksym Sobolyev (@sobomax) - 6 - 4 - 6 - 6 - - - 3. - Razvan Crainea (@razvancrainea) - 6 - 4 - 6 - 1 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 1 - 2 - - - 5. - Ken Rice - 3 - 1 - 1 - 1 - - - 6. - Liviu Chircu (@liviuchircu) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2024 - Jun 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2020 - Feb 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Apr 2019 - Dec 2020 - - - 5. - Razvan Crainea (@razvancrainea) - May 2019 - Jul 2020 - - - 6. - Liviu Chircu (@liviuchircu) - Jul 2019 - Jul 2019 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/rabbitmq_consumer/doc/rabbitmq_consumer.xml b/modules/rabbitmq_consumer/doc/rabbitmq_consumer.xml deleted file mode 100644 index 1f69b77a9ba..00000000000 --- a/modules/rabbitmq_consumer/doc/rabbitmq_consumer.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - RabbitMQ Consumer Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2019 &osipssol; - diff --git a/modules/rabbitmq_consumer/doc/rabbitmq_consumer_admin.xml b/modules/rabbitmq_consumer/doc/rabbitmq_consumer_admin.xml deleted file mode 100644 index a8da3cb2a75..00000000000 --- a/modules/rabbitmq_consumer/doc/rabbitmq_consumer_admin.xml +++ /dev/null @@ -1,265 +0,0 @@ - - - - - &adminguide; - -
- Overview - - RabbitMQ Consumer - (http://www.rabbitmq.com/) - is an open source messaging server. It's purpose is to - manage received messages in queues, taking advantage of - the flexible AMQP protocol. - - - Using this module you can subscribe consumers to a RabbitMQ broker in order - to receive AMQP messages for specified queues. The messages will be delivered - by triggering events through the &osips; Event Interface. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_mgm if is enabled. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - - librabbitmq-dev - - - - - NOte that the module is not compatible with versions 0.4 or below of - the librabbitmq-dev library. - -
- -
- -
- Exported Parameters - -
- <varname>connection_id</varname> (string) - - Specify the configuration for a RabbitMQ connection. It contains a set - of parameters used to customize the connection to the server as well as - the consumer subscription. The format of the parameter is - param1=value1; param2=value2;. - The uri, queue and - event parameters are mandatory. - - - This parameter can be set multiple times, for each RabbitMQ - connection. - - - The following parameters can be used: - - - - uri - Mandatory parameter - a full - amqp URI as described - here. - Missing fields in the URI will receive default values, - such as: user: guest, - password: guest, - host: localhost, - vhost: /, - port: 5672. TLS connections are specified - using an amqps URI. - - - - - queue - Mandatory parameter - the name of the - RabbitMQ queue to subscribe a consumer to. This parameter is mandatory. - - - - - event - Mandatory parameter - the name of the &osips; - event that will be triggered for each AMQP message received. - - - - - ack - flag that indicates to the broker - that messages will be acknowledged upon receival. If you do not - set this flag, the server will not expect ACKs and &osips; will not - send them. - - - - - exclusive - flag that indicates to the broker - that exclusive consumer access is requested, meaning only this consumer - can access the queue. - - - - - frame_max - the maximum size of an AMQP - frame. Default size is 131072. - - - - - heartbeat - interval in seconds used - to send heartbeat messages. Default is disabled. - - - - - tls_domain - indicates which TLS domain (as - defined using the tls_mgm module) to use for - this connection. This must be an amqps URI and - the module parameter must be enabled. - - - - - - Set <varname>connection_id</varname> parameter - -... -# connection to a RabbitMQ server on localhost, default port -# with a 5 seconds interval for heartbeat messages -modparam("rabbitmq_consumer", "connection_id", - "uri = amqp://127.0.0.1; queue = myqueue1; event = E_Q1_MSG; heartbeat = 5;") -... -# consumer that acknowledges messages -modparam("rabbitmq_consumer", "connection_id", - "uri = amqp://127.0.0.1; queue = myqueue2; event = E_Q2_MSG; ack;") -... -# TLS connection -modparam("rabbitmq_consumer", "connection_id", - "uri = amqps://127.0.0.1; queue = myqueue3; event = E_Q3_MSG; tls_domain=rmq;") -... - - -
- -
- <varname>connect_timeout</varname> (integer) - - The maximally allowed duration (in milliseconds) for the establishment - of a TCP connection with a RabbitMQ server. - - - - Default value is 500 (milliseconds). - - - - Setting the <varname>connect_timeout</varname> parameter - -... -modparam("rabbitmq_consumer", "connect_timeout", 1000) -... - - -
- -
- <varname>retry_timeout</varname> (integer) - - The interval (in milliseconds) after which &osips; will try to - re-establish a failed AMQP connection to a RabbitMQ server. - - - - Default value is 5000 (milliseconds). - - - - Setting the <varname>retry_timeout</varname> parameter - -... -modparam("rabbitmq_consumer", "retry_timeout", 10000) -... - - -
- -
- <varname>use_tls</varname> (integer) - - Setting this parameter will allow you to use TLS for broker connections. - In order to enable TLS for a specific connection, you can use the - "tls_domain=dom_name" parameter in the configuration - specified through the module parameter. - - - When using this parameter, you must also ensure that - tls_mgm is loaded and properly configured. Refer to - the the module for additional info regarding TLS client domains. - - - - Default value is 0 (not enabled) - - - - Set the <varname>use_tls</varname> parameter - -... -modparam("tls_mgm", "client_domain", "rmq") -modparam("tls_mgm", "certificate", "[rmq]/etc/pki/tls/certs/rmq.pem") -modparam("tls_mgm", "private_key", "[rmq]/etc/pki/tls/private/rmq.key") -modparam("tls_mgm", "ca_list", "[rmq]/etc/pki/tls/certs/ca.pem") -... -modparam("rabbitmq_consumer", "use_tls", 1) -... - - -
- -
- - -
- Exported Functions - The module does not export any script functions. -
- -
- Exported Events -
- - An event with a custom name, as set in the event - field of the parameter, - will be raised for each AMQP message received. - - Parameters: - - - body - the AMQP message body. - - -
- -
- -
diff --git a/modules/rate_cacher/README b/modules/rate_cacher/README deleted file mode 100644 index 9c66c4ddd0c..00000000000 --- a/modules/rate_cacher/README +++ /dev/null @@ -1,660 +0,0 @@ -RATE_CACHER Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. vendors_db_url (str) - 1.3.2. vendors_db_table (str) - 1.3.3. vendors_hash_size (int) - 1.3.4. clients_db_url (str) - 1.3.5. clients_db_table (str) - 1.3.6. clients_hash_size (int) - 1.3.7. rates_db_url (str) - 1.3.8. rates_db_table (str) - - 1.4. Exported Functions - - 1.4.1. - get_client_price(client_id,is_wholesale,dialle - d_no,prefix_pvar,destination_pvar,price_pvar - ,minimum_pvar,increment_pvar) - - 1.4.2. - get_vendor_price(vendor_id,dialled_no,prefix_p - var,destination_pvar,price_pvar,minimum_pvar - ,increment_pvar) - - 1.4.3. - cost_based_filtering(client_id,is_wholesale,ve - ndors_csv,dialled_no,desired_margin,out_vend - or_csv) - - 1.4.4. - cost_based_ordering(client_id,is_wholesale,ven - dors_csv,dialled_no,desired_margin,out_vendo - r_csv) - - 1.5. Exported MI Functions - - 1.5.1. rc_addVendor - 1.5.2. rc_deleteVendor - 1.5.3. rc_reloadVendorRate - 1.5.4. rc_deleteVendorRate - 1.5.5. rc_getVendorPrice - 1.5.6. rc_addClient - 1.5.7. rc_deleteClient - 1.5.8. rc_reloadClientRate - 1.5.9. rc_deleteClientRate - 1.5.10. rc_getClientPrice - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the vendors_db_url parameter - 1.2. Setting the vendors_db_table parameter - 1.3. Setting the vendors_hash_size parameter - 1.4. Setting the clients_db_url parameter - 1.5. Setting the clients_db_table parameter - 1.6. Setting the vendors_hash_size parameter - 1.7. Setting the rates_db_url parameter - 1.8. Setting the rates_db_table parameter - 1.9. get_client_price usage - 1.10. get_vendor_price usage - 1.11. cost_based_filtering usage - 1.12. cost_based_ordering usage - -Chapter 1. Admin Guide - -1.1. Overview - - The rate_cacher module provides a means of caching and - real-time querying of the ratesheets assigned to your clients - and / or vendors. It also allows for real-time cost-based - routing and cost-based filtering. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules.. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. vendors_db_url (str) - - The DB URL for querying the Vendors used by the module - - Default value is “NULL”. - - Example 1.1. Setting the vendors_db_url parameter -... -modparam("rate_cacher", "vendors_db_url", "mysql://opensips:opensipsrw@l -ocalhost/opensips") -... - -1.3.2. vendors_db_table (str) - - The DB Table for querying the Vendors used by the module - - Default value is “rc_vendors”. - - Example 1.2. Setting the vendors_db_table parameter -... -modparam("rate_cacher", "vendors_db_table", "my_vendors_view") -... - -1.3.3. vendors_hash_size (int) - - The size of the hash table internally used to keep the vendors. - A larger table is much faster but consumes more memory. The - hash size must be a power of 2 number. - - Default value is “256”. - - Example 1.3. Setting the vendors_hash_size parameter -... -modparam("rate_cacher", "vendors_hash_size", 1024) -... - -1.3.4. clients_db_url (str) - - The DB URL for querying the Clients used by the module - - Default value is “NULL”. - - Example 1.4. Setting the clients_db_url parameter -... -modparam("rate_cacher", "clients_db_url", "mysql://opensips:opensipsrw@l -ocalhost/opensips") -... - -1.3.5. clients_db_table (str) - - The DB Table for querying the Clients used by the module - - Default value is “rc_clients”. - - Example 1.5. Setting the clients_db_table parameter -... -modparam("rate_cacher", "clients_db_table", "my_clients_view") -... - -1.3.6. clients_hash_size (int) - - The size of the hash table internally used to keep the clients. - A larger table is much faster but consumes more memory. The - hash size must be a power of 2 number. - - Default value is “256”. - - Example 1.6. Setting the vendors_hash_size parameter -... -modparam("rate_cacher", "clients_hash_size", 1024) -... - -1.3.7. rates_db_url (str) - - The DB URL for querying the Ratesheets used by the module - - Default value is “NULL”. - - Example 1.7. Setting the rates_db_url parameter -... -modparam("rate_cacher", "rates_db_url", "mysql://opensips:opensipsrw@loc -alhost/opensips") -... - -1.3.8. rates_db_table (str) - - The DB Table for querying the Ratesheets used by the module - - Default value is “rc_ratesheets”. - - Example 1.8. Setting the rates_db_table parameter -... -modparam("rate_cacher", "rates_db_table", "my_clients_view") -... - -1.4. Exported Functions - -1.4.1. -get_client_price(client_id,is_wholesale,dialled_no,prefix_pvar,destin -ation_pvar,price_pvar,minimum_pvar,increment_pvar) - - For a call originating from the provided Client ID, on a - wholesale or retail quality, going to dialled_no, the function - will matched the dialled number against the client's ratesheet - and return the matched prefix, destination, price, minimum and - increment. - - The client_id pseudo-var will hold the client_id originating - this call - - The is_wholesale pseudo-var will contain either a 1 or a 0, - depending on whether the call is wholesale or retail ( see - client ratesheet provisioning ). - - The dialled_no pseudo-var contains the DNIS - the dialled - number for the current call. It needs to be in E164 format, - without the leading + - - The prefix pseudo-var will contain the matched prefix from the - client's ratesheet - - The destination pseudo-var will contain the matched destination - from the client's ratesheet - - The price pseudo-var will contain the matched price from the - client's ratesheet - - The minimum pseudo-var will contain the matched minimum from - the client's ratesheet - - The increment pseudo-var will contain the matched increment - from the client's ratesheet - - Possible parameter types - * ALL Parameters - String/Integer or pseudo-variables - - This function can be used from any route. - - Example 1.9. get_client_price usage -... -if (get_client_price("my_client",1,"4072794242",$var(prefix),$var(dest), -$var(price),$var(min),$var(inc))) { - xlog("We matched $var(prefix) , $var(dest) , $va -r(price) , $var(min) , $var(inc) for the client's ratesheet\n"); - } - -... - -1.4.2. -get_vendor_price(vendor_id,dialled_no,prefix_pvar,destination_pvar,pr -ice_pvar,minimum_pvar,increment_pvar) - - For a call originating going to the provided vendor ID, going - to dialled_no, the function will matched the dialled number - against the vendor's ratesheet and return the matched prefix, - destination, price, minimum and increment. - - The vendor_id pseudo-var will hold the vendor_id - - The dialled_no pseudo-var contains the DNIS - the dialled - number for the current call. It needs to be in E164 format, - without the leading + - - The prefix pseudo-var will contain the matched prefix from the - vendor's ratesheet - - The destination pseudo-var will contain the matched destination - from the vendor's ratesheet - - The price pseudo-var will contain the matched price from the - vendor's ratesheet - - The minimum pseudo-var will contain the matched minimum from - the vendor's ratesheet - - The increment pseudo-var will contain the matched increment - from the vendor's ratesheet - - Possible parameter types - * ALL Parameters - String/Integer or pseudo-variables - - This function can be used from any route. - - Example 1.10. get_vendor_price usage -... -if (get_vendor_price("my_vendor","4072794242",$var(prefix),$var(dest),$v -ar(price),$var(min),$var(inc))) { - xlog("We matched $var(prefix) , $var(dest) , $va -r(price) , $var(min) , $var(inc) for the vendor's ratesheet\n"); - } - -... - -1.4.3. -cost_based_filtering(client_id,is_wholesale,vendors_csv,dialled_no,de -sired_margin,out_vendor_csv) - - For a call originating from the provided Client ID, on a - wholesale or retail quality, going to dialled_no, the function - removes the Vendors ( from the vendor_csv list ) which do not - pass the desired_margin condition, and sets the out_vendor_csv - variable to the list of Vendor that meet the margin condition, - while maintaining the initial order provided in the vendor_csv - variable. - - The client_id pseudo-var will hold the client_id originating - this call - - The is_wholesale pseudo-var will contain either a 1 or a 0, - depending on whether the call is wholesale or retail ( see - client ratesheet provisioning ). - - The vendors_csv pseudo-var contains a list of Vendors that need - to be filtered based on the desired margin ( keep just those - that match your desired percentage margin for this call ) - - The dialled_no pseudo-var contains the DNIS - the dialled - number for the current call. It needs to be in E164 format, - without the leading + - - The desired_margin pseudo-var contains the minimum Integer - margin that the script writer wants to achieve, based on the - Client sell and Vendor buy prices. The formula used is : - vendor_margin=(client_price - results[i])*100/client_price) . - If the vendor_margin is higher than the desired_margin, then - the Vendor is ok to use. The desired margin can be positive ( - call will be profitable ) or negative ( the call will cause a - loss ). - - The out_vendors_csv pseudo-var is an output parameter, and the - pvar will get populated with the CSV list of Vendors that meet - the desired margin condition - - Possible parameter types - * ALL Parameters - String/Integer or pseudo-variables - - This function can be used from a REQUEST or FAILURE route. - - Example 1.11. cost_based_filtering usage -... - - -# If we get a call from testClient on it's wholesale quality, -# going to number 40720018124, and we have to pick from the list -# of vendors 'testVendor,testVendor2' based on a a profit margin -# of 0 ( we do not want to lose money on this call ), -# then $avp(out_vendor_csv) will have the vendors that we need -# to use based on the above call characteristics, the order of the -# vendors that was provided in $avp(carrierlist) and the desired margin -$avp(client_id)="testClient"; -$avp(is_ws)=1; -$avp(carrierlist)="testVendor,testVendor2"; -$avp(dnis)="40720018124"; -$avp(profit_margin)=0; - -if (cost_based_filtering("$avp(client_id)","$avp(is_ws)","$avp(carrierli -st)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { - xlog("XXX - Out of the $avp(carrierlist) carriers, we should onl -y use $avp(out_vendor_result) \n"); -... - -1.4.4. -cost_based_ordering(client_id,is_wholesale,vendors_csv,dialled_no,des -ired_margin,out_vendor_csv) - - For a call originating from the provided Client ID, on a - wholesale or retail quality, going to dialled_no, the function - removes the Vendors ( from the vendor_csv list ) which do not - pass the desired_margin condition, and sets th out_vendor_csv - variable to the list of Vendor that meet the margin condition, - in descending order of their margin ( from most profitable - Vendor to least profitable Vendor that still meets the margin - condition ) - - The client_id pseudo-var will hold the client_id originating - this call - - The is_wholesale pseudo-var will contain either a 1 or a 0, - depending on whether the call is wholesale or retail ( see - client ratesheet provisioning ). - - The vendors_csv pseudo-var contains a list of Vendors that need - to be filtered based on the desired margin ( keep just those - that match your desired percentage margin for this call ) - - The dialled_no pseudo-var contains the DNIS - the dialled - number for the current call. It needs to be in E164 format, - without the leading + - - The desired_margin pseudo-var contains the minimum Integer - margin that the script writer wants to achieve, based on the - Client sell and Vendor buy prices. The formula used is : - vendor_margin=(client_price - results[i])*100/client_price) . - If the vendor_margin is higher than the desired_margin, then - the Vendor is ok to use. The desired margin can be positive ( - call will be profitable ) or negative ( the call will cause a - loss ). - - The out_vendors_csv pseudo-var is an output parameter, and the - pvar will get populated with the CSV list of Vendors that meet - the desired margin condition - - Possible parameter types - * ALL Parameters - String/Integer or pseudo-variables - - This function can be used from any route. - - Example 1.12. cost_based_ordering usage -... -# If we get a call from testClient on it's wholesale quality, -# going to number 40720018124, and we have to pick from the list -# of vendors 'testVendor,testVendor2' based on a a profit margin -# of 0 ( we do not want to lose money on this call ), -# then $avp(out_vendor_csv) will have the vendors that we need -# to use based on the above call characteristics, and the desired margin -# The order in $avp(carrierlist) does not matter, the vendors will be -# ordered from most profitable to least profitable -$avp(client_id)="testClient"; -$avp(is_ws)=1; -$avp(carrierlist)="testVendor,testVendor2"; -$avp(dnis)="40720018124"; -$avp(profit_margin)=0; - -if (cost_based_ordering("$avp(client_id)","$avp(is_ws)","$avp(carrierlis -t)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { - xlog("XXX - Out of the $avp(carrierlist) carriers, we should onl -y use $avp(out_vendor_result) , in the provided order\n"); - -... - -1.5. Exported MI Functions - -1.5.1. rc_addVendor - - Adds a new Vendor, without assigning any ratesheet to it. - - Name: rc_addVendor - - Parameters : - * vendorName - name of the Vendor to be added - - MI FIFO Command Format: -## Add a new Vendor -# opensips-cli -x mi rc_addVendor myNewVendor - -1.5.2. rc_deleteVendor - - Removes a vendor from memory, along with the ratesheet asigned - with it ( if any ) - - Name: rc_deleteVendor - - Parameters : - * vendorName - name of the Vendor to be deleted - - MI FIFO Command Format: -## Delete a Vendor -# opensipss-cli -x mi rc_deleteVendor myNewVendor - -1.5.3. rc_reloadVendorRate - - Reloads the provided ratesheet and assigns it to the Vendor - - Name: rc_reloadVendorRate - - Parameters : - * vendorName - name of the Vendor - * ratesheet_id - ID of the ratesheet to be reloaded and - assigned - - MI FIFO Command Format: -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_reloadVendorRate myVendor 3 - -1.5.4. rc_deleteVendorRate - - Deletes the assigned ratesheet from the Vendor - - Name: rc_deleteVendorRate - - Parameters : - * vendorName - name of the Vendor - - MI FIFO Command Format: -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_deleteVendorRate myVendor - -1.5.5. rc_getVendorPrice - - Fetches all the ratesheet information ( destination name, - price, minimum, increment ) for the provided Vendor and dialled - number - - Name: rc_getVendorPrice - - Parameters : - * vendorName - name of the Vendor - * dialledNumber - number to match in the above Vendor's - ratesheet - - MI FIFO Command Format: -## Query for the price of myVendor for the 4072731825 number -#/usr/local/bin/opensips-cli -x mi rc_getVendorPrice myVendor 4072731825 -{ - "prefix": "40727", - "destination": "ROMANIA MOBILE VODAFONE", - "price": 0.05, - "minimum": 1, - "increment": 1, - "currency": "USD" -} - -1.5.6. rc_addClient - - Adds a new Client, without assigning any ratesheet to it. - - Name: rc_addClient - - Parameters : - * clientName - name of the Client to be added - - MI FIFO Command Format: -## Add a new Client -# opensips-cli -x mi fifo rc_addClient myNewClient - -1.5.7. rc_deleteClient - - Removes a Client from memory, along with the ratesheet asigned - with it ( if any ) - - Name: rc_deleteClient - - Parameters : - * clientName - name of the Client to be deleted - - MI FIFO Command Format: -## Delete a Client -# opensips-cli -x mi rc_deleteClient myClient - -1.5.8. rc_reloadClientRate - - Reloads the provided ratesheet and assigns it to the Client - - Name: rc_reloadClientRate - - Parameters : - * clientName - name of the Cient - * isWholesale - is the ratesheet assigned on the wholesale or - retail quality - * ratesheet_id - ID of the ratesheet to be reloaded and - assigned - - MI FIFO Command Format: -## Reloads the Client's wholesale Ratesheet, assigning it rate id 3 -# opensips-cli -x mi rc_reloadClientRate myClient 1 3 - -1.5.9. rc_deleteClientRate - - Deletes the assigned ratesheet from the Client - - Name: rc_deleteClientRate - - Parameters : - * ClientName - name of the Client - * isWholesale - delete the wholesale or retail ratesheet - - MI FIFO Command Format: -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_deleteVendorRate myVendor - -1.5.10. rc_getClientPrice - - Fetches all the ratesheet information ( destination name, - price, minimum, increment ) for the provided Client, on the - specified quality ( wholesale vs retail ) and dialled number - - Name: rc_getClientPrice - - Parameters : - * ClientName - name of the Client - * isWholesale - wholesale = 1, retail = 0 - * dialledNumber - number to match in the above Client's - ratesheet - - MI FIFO Command Format: -## Query for the price of myClient, on the retail quality, for the 40727 -31825 number -#/usr/local/bin/opensips-cli -x mi rc_getClientPrice myClient 0 40727318 -25 -{ - "prefix": "40727", - "destination": "ROMANIA MOBILE VODAFONE", - "price": 0.03, - "minimum": 1, - "increment": 1, - "currency": "USD" -} - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 31 3 3167 1 - 2. Maksym Sobolyev (@sobomax) 5 3 18 19 - 3. Callum 4 2 3 3 - 4. Razvan Crainea (@razvancrainea) 3 1 6 4 - 5. Artiom Druz 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Jan 2021 - Feb 2023 - 2. Callum Nov 2022 - Nov 2022 - 3. Artiom Druz Jul 2021 - Jul 2021 - 4. Vlad Paiu (@vladpaiu) Mar 2020 - Jul 2020 - 5. Razvan Crainea (@razvancrainea) Jul 2020 - Jul 2020 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Callum, Vlad Paiu (@vladpaiu). diff --git a/modules/rate_cacher/README.md b/modules/rate_cacher/README.md new file mode 100644 index 00000000000..3032fbf3beb --- /dev/null +++ b/modules/rate_cacher/README.md @@ -0,0 +1,649 @@ +--- +title: "RATE_CACHER Module" +description: "The *rate_cacher* module provides a means of caching and real-time querying of the ratesheets assigned to your clients and / or vendors." +--- + +## Admin Guide + + +### Overview + + +The *rate_cacher* module provides a means of caching +and real-time querying of the ratesheets assigned to your clients and / or vendors. +It also allows for real-time cost-based routing and cost-based filtering. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules.*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### vendors_db_url (str) + + +The DB URL for querying the Vendors used by the module + + +*Default value is "NULL".* + + +```opensips title="Setting the vendors_db_url parameter" +... +modparam("rate_cacher", "vendors_db_url", "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### vendors_db_table (str) + + +The DB Table for querying the Vendors used by the module + + +*Default value is "rc_vendors".* + + +```opensips title="Setting the vendors_db_table parameter" +... +modparam("rate_cacher", "vendors_db_table", "my_vendors_view") +... +``` + + +#### vendors_hash_size (int) + + +The size of the hash table internally used to keep the vendors. A +larger table is much faster but consumes more memory. The hash size +must be a power of 2 number. + + +*Default value is "256".* + + +```opensips title="Setting the vendors_hash_size parameter" +... +modparam("rate_cacher", "vendors_hash_size", 1024) +... +``` + + +#### clients_db_url (str) + + +The DB URL for querying the Clients used by the module + + +*Default value is "NULL".* + + +```opensips title="Setting the clients_db_url parameter" +... +modparam("rate_cacher", "clients_db_url", "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### clients_db_table (str) + + +The DB Table for querying the Clients used by the module + + +*Default value is "rc_clients".* + + +```opensips title="Setting the clients_db_table parameter" +... +modparam("rate_cacher", "clients_db_table", "my_clients_view") +... +``` + + +#### clients_hash_size (int) + + +The size of the hash table internally used to keep the clients. A +larger table is much faster but consumes more memory. The hash size +must be a power of 2 number. + + +*Default value is "256".* + + +```opensips title="Setting the vendors_hash_size parameter" +... +modparam("rate_cacher", "clients_hash_size", 1024) +... +``` + + +#### rates_db_url (str) + + +The DB URL for querying the Ratesheets used by the module + + +*Default value is "NULL".* + + +```opensips title="Setting the rates_db_url parameter" +... +modparam("rate_cacher", "rates_db_url", "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### rates_db_table (str) + + +The DB Table for querying the Ratesheets used by the module + + +*Default value is "rc_ratesheets".* + + +```opensips title="Setting the rates_db_table parameter" +... +modparam("rate_cacher", "rates_db_table", "my_clients_view") +... +``` + + +### Exported Functions + + +#### get_client_price(client_id,is_wholesale,dialled_no,prefix_pvar,destination_pvar,price_pvar,minimum_pvar,increment_pvar) + + +For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function will matched the dialled number against the client's ratesheet and return the matched prefix, destination, price, minimum and increment. + + +The *client_id* pseudo-var will hold the client_id originating this call + + +The *is_wholesale* pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). + + +The *dialled_no* pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + + + +The *prefix* pseudo-var will contain the matched prefix from the client's ratesheet + + +The *destination* pseudo-var will contain the matched destination from the client's ratesheet + + +The *price* pseudo-var will contain the matched price from the client's ratesheet + + +The *minimum* pseudo-var will contain the matched minimum from the client's ratesheet + + +The *increment* pseudo-var will contain the matched increment from the client's ratesheet + + +Possible parameter types + + +- *ALL Parameters* - String/Integer or pseudo-variables + + +This function can be used from any route. + + +```opensips title="get_client_price usage" +... +if (get_client_price("my_client",1,"4072794242",$var(prefix),$var(dest),$var(price),$var(min),$var(inc))) { + xlog("We matched $var(prefix) , $var(dest) , $var(price) , $var(min) , $var(inc) for the client's ratesheet\n"); + } + +... +``` + + +#### get_vendor_price(vendor_id,dialled_no,prefix_pvar,destination_pvar,price_pvar,minimum_pvar,increment_pvar) + + +For a call originating going to the provided vendor ID, going to dialled_no, the function will matched the dialled number against the vendor's ratesheet and return the matched prefix, destination, price, minimum and increment. + + +The *vendor_id* pseudo-var will hold the vendor_id + + +The *dialled_no* pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + + + +The *prefix* pseudo-var will contain the matched prefix from the vendor's ratesheet + + +The *destination* pseudo-var will contain the matched destination from the vendor's ratesheet + + +The *price* pseudo-var will contain the matched price from the vendor's ratesheet + + +The *minimum* pseudo-var will contain the matched minimum from the vendor's ratesheet + + +The *increment* pseudo-var will contain the matched increment from the vendor's ratesheet + + +Possible parameter types + + +- *ALL Parameters* - String/Integer or pseudo-variables + + +This function can be used from any route. + + +```opensips title="get_vendor_price usage" +... +if (get_vendor_price("my_vendor","4072794242",$var(prefix),$var(dest),$var(price),$var(min),$var(inc))) { + xlog("We matched $var(prefix) , $var(dest) , $var(price) , $var(min) , $var(inc) for the vendor's ratesheet\n"); + } + +... +``` + + +#### cost_based_filtering(client_id,is_wholesale,vendors_csv,dialled_no,desired_margin,out_vendor_csv) + + +For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function removes the Vendors ( from the vendor_csv list ) which do not pass the desired_margin condition, and sets the out_vendor_csv variable to the list of Vendor that meet the margin condition, while maintaining the initial order provided in the vendor_csv variable. + + +The *client_id* pseudo-var will hold the client_id originating this call + + +The *is_wholesale* pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). + + +The *vendors_csv* pseudo-var contains a list of Vendors that need to be filtered based on the desired margin ( keep just those that match your desired percentage margin for this call ) + + +The *dialled_no* pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + + + +The *desired_margin* pseudo-var contains the minimum Integer margin that the script writer wants to achieve, based on the Client sell and Vendor buy prices. The formula used is : vendor_margin=(client_price - results[i])*100/client_price) . If the vendor_margin is higher than the desired_margin, then the Vendor is ok to use. The desired margin can be positive ( call will be profitable ) or negative ( the call will cause a loss ). + + +The *out_vendors_csv* pseudo-var is an output parameter, and the pvar will get populated with the CSV list of Vendors that meet the desired margin condition + + +Possible parameter types + + +- *ALL Parameters* - String/Integer or pseudo-variables + + +This function can be used from a REQUEST or FAILURE route. + + +```opensips title="cost_based_filtering usage" +... +# If we get a call from testClient on it's wholesale quality, +# going to number 40720018124, and we have to pick from the list +# of vendors 'testVendor,testVendor2' based on a a profit margin +# of 0 ( we do not want to lose money on this call ), +# then $avp(out_vendor_csv) will have the vendors that we need +# to use based on the above call characteristics, the order of the +# vendors that was provided in $avp(carrierlist) and the desired margin +$avp(client_id)="testClient"; +$avp(is_ws)=1; +$avp(carrierlist)="testVendor,testVendor2"; +$avp(dnis)="40720018124"; +$avp(profit_margin)=0; + +if (cost_based_filtering("$avp(client_id)","$avp(is_ws)","$avp(carrierlist)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { + xlog("XXX - Out of the $avp(carrierlist) carriers, we should only use $avp(out_vendor_result) \n"); +... +``` + + +#### cost_based_ordering(client_id,is_wholesale,vendors_csv,dialled_no,desired_margin,out_vendor_csv) + + +For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function removes the Vendors ( from the vendor_csv list ) which do not pass the desired_margin condition, and sets th out_vendor_csv variable to the list of Vendor that meet the margin condition, in descending order of their margin ( from most profitable Vendor to least profitable Vendor that still meets the margin condition ) + + +The *client_id* pseudo-var will hold the client_id originating this call + + +The *is_wholesale* pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). + + +The *vendors_csv* pseudo-var contains a list of Vendors that need to be filtered based on the desired margin ( keep just those that match your desired percentage margin for this call ) + + +The *dialled_no* pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + + + +The *desired_margin* pseudo-var contains the minimum Integer margin that the script writer wants to achieve, based on the Client sell and Vendor buy prices. The formula used is : vendor_margin=(client_price - results[i])*100/client_price) . If the vendor_margin is higher than the desired_margin, then the Vendor is ok to use. The desired margin can be positive ( call will be profitable ) or negative ( the call will cause a loss ). + + +The *out_vendors_csv* pseudo-var is an output parameter, and the pvar will get populated with the CSV list of Vendors that meet the desired margin condition + + +Possible parameter types + + +- *ALL Parameters* - String/Integer or pseudo-variables + + +This function can be used from any route. + + +```opensips title="cost_based_ordering usage" +... +# If we get a call from testClient on it's wholesale quality, +# going to number 40720018124, and we have to pick from the list +# of vendors 'testVendor,testVendor2' based on a a profit margin +# of 0 ( we do not want to lose money on this call ), +# then $avp(out_vendor_csv) will have the vendors that we need +# to use based on the above call characteristics, and the desired margin +# The order in $avp(carrierlist) does not matter, the vendors will be +# ordered from most profitable to least profitable +$avp(client_id)="testClient"; +$avp(is_ws)=1; +$avp(carrierlist)="testVendor,testVendor2"; +$avp(dnis)="40720018124"; +$avp(profit_margin)=0; + +if (cost_based_ordering("$avp(client_id)","$avp(is_ws)","$avp(carrierlist)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { + xlog("XXX - Out of the $avp(carrierlist) carriers, we should only use $avp(out_vendor_result) , in the provided order\n"); +... +``` + + +### Exported MI Functions + + +#### rc_addVendor + + +Adds a new Vendor, without assigning any ratesheet to it. + + +Name: *rc_addVendor* + + +Parameters : + + +- *vendorName* - name of the Vendor to be added + + +MI FIFO Command Format: + + +```bash +## Add a new Vendor +$ opensips-cli -x mi rc_addVendor myNewVendor +``` + + +#### rc_deleteVendor + + +Removes a vendor from memory, along with the ratesheet asigned with it ( if any ) + + +Name: *rc_deleteVendor* + + +Parameters : + + +- *vendorName* - name of the Vendor to be deleted + + +MI FIFO Command Format: + + +```bash +## Delete a Vendor +$ opensipss-cli -x mi rc_deleteVendor myNewVendor +``` + + +#### rc_reloadVendorRate + + +Reloads the provided ratesheet and assigns it to the Vendor + + +Name: *rc_reloadVendorRate* + + +Parameters : + + +- *vendorName* - name of the Vendor +- *ratesheet_id* - ID of the ratesheet to be reloaded and assigned + + +MI FIFO Command Format: + + +```bash +## Reloads a Vendor Ratesheet +$ opensips-cli -x mi rc_reloadVendorRate myVendor 3 +``` + + +#### rc_deleteVendorRate + + +Deletes the assigned ratesheet from the Vendor + + +Name: *rc_deleteVendorRate* + + +Parameters : + + +- *vendorName* - name of the Vendor + + +MI FIFO Command Format: + + +```bash +## Reloads a Vendor Ratesheet +$ opensips-cli -x mi rc_deleteVendorRate myVendor +``` + + +#### rc_getVendorPrice + + +Fetches all the ratesheet information ( destination name, price, minimum, increment ) for the provided Vendor and dialled number + + +Name: *rc_getVendorPrice* + + +Parameters : + + +- *vendorName* - name of the Vendor +- *dialledNumber* - number to match in the above Vendor's ratesheet + + +MI FIFO Command Format: + + +```bash +## Query for the price of myVendor for the 4072731825 number +#/usr/local/bin/opensips-cli -x mi rc_getVendorPrice myVendor 4072731825 +{ + "prefix": "40727", + "destination": "ROMANIA MOBILE VODAFONE", + "price": 0.05, + "minimum": 1, + "increment": 1, + "currency": "USD" +} +``` + + +#### rc_addClient + + +Adds a new Client, without assigning any ratesheet to it. + + +Name: *rc_addClient* + + +Parameters : + + +- *clientName* - name of the Client to be added + + +MI FIFO Command Format: + + +```bash +## Add a new Client +$ opensips-cli -x mi fifo rc_addClient myNewClient +``` + + +#### rc_deleteClient + + +Removes a Client from memory, along with the ratesheet asigned with it ( if any ) + + +Name: *rc_deleteClient* + + +Parameters : + + +- *clientName* - name of the Client to be deleted + + +MI FIFO Command Format: + + +```bash +## Delete a Client +$ opensips-cli -x mi rc_deleteClient myClient +``` + + +#### rc_reloadClientRate + + +Reloads the provided ratesheet and assigns it to the Client + + +Name: *rc_reloadClientRate* + + +Parameters : + + +- *clientName* - name of the Cient +- *isWholesale* - is the ratesheet assigned on the wholesale or retail quality +- *ratesheet_id* - ID of the ratesheet to be reloaded and assigned + + +MI FIFO Command Format: + + +```bash +## Reloads the Client's wholesale Ratesheet, assigning it rate id 3 +$ opensips-cli -x mi rc_reloadClientRate myClient 1 3 +``` + + +#### rc_deleteClientRate + + +Deletes the assigned ratesheet from the Client + + +Name: *rc_deleteClientRate* + + +Parameters : + + +- *ClientName* - name of the Client +- *isWholesale* - delete the wholesale or retail ratesheet + + +MI FIFO Command Format: + + +```bash +## Reloads a Vendor Ratesheet +$ opensips-cli -x mi rc_deleteVendorRate myVendor +``` + + +#### rc_getClientPrice + + +Fetches all the ratesheet information ( destination name, price, minimum, increment ) for the provided Client, on the specified quality ( wholesale vs retail ) and dialled number + + +Name: *rc_getClientPrice* + + +Parameters : + + +- *ClientName* - name of the Client +- *isWholesale* - wholesale = 1, retail = 0 +- *dialledNumber* - number to match in the above Client's ratesheet + + +MI FIFO Command Format: + + +```bash +## Query for the price of myClient, on the retail quality, for the 4072731825 number +#/usr/local/bin/opensips-cli -x mi rc_getClientPrice myClient 0 4072731825 +{ + "prefix": "40727", + "destination": "ROMANIA MOBILE VODAFONE", + "price": 0.03, + "minimum": 1, + "increment": 1, + "currency": "USD" +} +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rate_cacher/doc/contributors.xml b/modules/rate_cacher/doc/contributors.xml deleted file mode 100644 index e2b852d36d9..00000000000 --- a/modules/rate_cacher/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 31 - 3 - 3167 - 1 - - - 2. - Maksym Sobolyev (@sobomax) - 5 - 3 - 18 - 19 - - - 3. - Callum - 4 - 2 - 3 - 3 - - - 4. - Razvan Crainea (@razvancrainea) - 3 - 1 - 6 - 4 - - - 5. - Artiom Druz - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Jan 2021 - Feb 2023 - - - 2. - Callum - Nov 2022 - Nov 2022 - - - 3. - Artiom Druz - Jul 2021 - Jul 2021 - - - 4. - Vlad Paiu (@vladpaiu) - Mar 2020 - Jul 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Jul 2020 - Jul 2020 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Callum, Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/rate_cacher/doc/rate_cacher.xml b/modules/rate_cacher/doc/rate_cacher.xml deleted file mode 100644 index f63ab660db1..00000000000 --- a/modules/rate_cacher/doc/rate_cacher.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - RATE_CACHER Module - - - - &admin; - &faq; - &contrib; - diff --git a/modules/rate_cacher/doc/rate_cacher_admin.xml b/modules/rate_cacher/doc/rate_cacher_admin.xml deleted file mode 100644 index 9062ab790db..00000000000 --- a/modules/rate_cacher/doc/rate_cacher_admin.xml +++ /dev/null @@ -1,745 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The rate_cacher module provides a means of caching - and real-time querying of the ratesheets assigned to your clients and / or vendors. - It also allows for real-time cost-based routing and cost-based filtering. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules.. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
- -
- -
- Exported Parameters -
- <varname>vendors_db_url</varname> (str) - - The DB URL for querying the Vendors used by the module - - - - Default value is NULL. - - - - Setting the <varname>vendors_db_url</varname> parameter - -... -modparam("rate_cacher", "vendors_db_url", "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>vendors_db_table</varname> (str) - - The DB Table for querying the Vendors used by the module - - - - Default value is rc_vendors. - - - - Setting the <varname>vendors_db_table</varname> parameter - -... -modparam("rate_cacher", "vendors_db_table", "my_vendors_view") -... - - -
- -
- <varname>vendors_hash_size</varname> (int) - - The size of the hash table internally used to keep the vendors. A - larger table is much faster but consumes more memory. The hash size - must be a power of 2 number. - - - - Default value is 256. - - - - Setting the <varname>vendors_hash_size</varname> parameter - -... -modparam("rate_cacher", "vendors_hash_size", 1024) -... - - -
- -
- <varname>clients_db_url</varname> (str) - - The DB URL for querying the Clients used by the module - - - - Default value is NULL. - - - - Setting the <varname>clients_db_url</varname> parameter - -... -modparam("rate_cacher", "clients_db_url", "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>clients_db_table</varname> (str) - - The DB Table for querying the Clients used by the module - - - - Default value is rc_clients. - - - - Setting the <varname>clients_db_table</varname> parameter - -... -modparam("rate_cacher", "clients_db_table", "my_clients_view") -... - - -
- -
- <varname>clients_hash_size</varname> (int) - - The size of the hash table internally used to keep the clients. A - larger table is much faster but consumes more memory. The hash size - must be a power of 2 number. - - - - Default value is 256. - - - - Setting the <varname>vendors_hash_size</varname> parameter - -... -modparam("rate_cacher", "clients_hash_size", 1024) -... - - -
- - -
- <varname>rates_db_url</varname> (str) - - The DB URL for querying the Ratesheets used by the module - - - - Default value is NULL. - - - - Setting the <varname>rates_db_url</varname> parameter - -... -modparam("rate_cacher", "rates_db_url", "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>rates_db_table</varname> (str) - - The DB Table for querying the Ratesheets used by the module - - - - Default value is rc_ratesheets. - - - - Setting the <varname>rates_db_table</varname> parameter - -... -modparam("rate_cacher", "rates_db_table", "my_clients_view") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">get_client_price(client_id,is_wholesale,dialled_no,prefix_pvar,destination_pvar,price_pvar,minimum_pvar,increment_pvar)</function> - - - For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function will matched the dialled number against the client's ratesheet and return the matched prefix, destination, price, minimum and increment. - - - The client_id pseudo-var will hold the client_id originating this call - - - The is_wholesale pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). - - - The dialled_no pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + - - - The prefix pseudo-var will contain the matched prefix from the client's ratesheet - - - The destination pseudo-var will contain the matched destination from the client's ratesheet - - - The price pseudo-var will contain the matched price from the client's ratesheet - - - The minimum pseudo-var will contain the matched minimum from the client's ratesheet - - - The increment pseudo-var will contain the matched increment from the client's ratesheet - - - Possible parameter types - - - ALL Parameters - String/Integer or pseudo-variables - - - - - This function can be used from any route. - - - <function moreinfo="none">get_client_price</function> usage - -... -if (get_client_price("my_client",1,"4072794242",$var(prefix),$var(dest),$var(price),$var(min),$var(inc))) { - xlog("We matched $var(prefix) , $var(dest) , $var(price) , $var(min) , $var(inc) for the client's ratesheet\n"); - } - -... - - -
-
- - <function moreinfo="none">get_vendor_price(vendor_id,dialled_no,prefix_pvar,destination_pvar,price_pvar,minimum_pvar,increment_pvar)</function> - - - For a call originating going to the provided vendor ID, going to dialled_no, the function will matched the dialled number against the vendor's ratesheet and return the matched prefix, destination, price, minimum and increment. - - - The vendor_id pseudo-var will hold the vendor_id - - - The dialled_no pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + - - - The prefix pseudo-var will contain the matched prefix from the vendor's ratesheet - - - The destination pseudo-var will contain the matched destination from the vendor's ratesheet - - - The price pseudo-var will contain the matched price from the vendor's ratesheet - - - The minimum pseudo-var will contain the matched minimum from the vendor's ratesheet - - - The increment pseudo-var will contain the matched increment from the vendor's ratesheet - - - Possible parameter types - - - ALL Parameters - String/Integer or pseudo-variables - - - - - This function can be used from any route. - - - <function moreinfo="none">get_vendor_price</function> usage - -... -if (get_vendor_price("my_vendor","4072794242",$var(prefix),$var(dest),$var(price),$var(min),$var(inc))) { - xlog("We matched $var(prefix) , $var(dest) , $var(price) , $var(min) , $var(inc) for the vendor's ratesheet\n"); - } - -... - - -
- -
- - <function moreinfo="none">cost_based_filtering(client_id,is_wholesale,vendors_csv,dialled_no,desired_margin,out_vendor_csv)</function> - - - For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function removes the Vendors ( from the vendor_csv list ) which do not pass the desired_margin condition, and sets the out_vendor_csv variable to the list of Vendor that meet the margin condition, while maintaining the initial order provided in the vendor_csv variable. - - - The client_id pseudo-var will hold the client_id originating this call - - - The is_wholesale pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). - - - The vendors_csv pseudo-var contains a list of Vendors that need to be filtered based on the desired margin ( keep just those that match your desired percentage margin for this call ) - - - The dialled_no pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + - - - The desired_margin pseudo-var contains the minimum Integer margin that the script writer wants to achieve, based on the Client sell and Vendor buy prices. The formula used is : vendor_margin=(client_price - results[i])*100/client_price) . If the vendor_margin is higher than the desired_margin, then the Vendor is ok to use. The desired margin can be positive ( call will be profitable ) or negative ( the call will cause a loss ). - - - The out_vendors_csv pseudo-var is an output parameter, and the pvar will get populated with the CSV list of Vendors that meet the desired margin condition - - - Possible parameter types - - - ALL Parameters - String/Integer or pseudo-variables - - - - - This function can be used from a REQUEST or FAILURE route. - - - <function moreinfo="none">cost_based_filtering</function> usage - -... - - -# If we get a call from testClient on it's wholesale quality, -# going to number 40720018124, and we have to pick from the list -# of vendors 'testVendor,testVendor2' based on a a profit margin -# of 0 ( we do not want to lose money on this call ), -# then $avp(out_vendor_csv) will have the vendors that we need -# to use based on the above call characteristics, the order of the -# vendors that was provided in $avp(carrierlist) and the desired margin -$avp(client_id)="testClient"; -$avp(is_ws)=1; -$avp(carrierlist)="testVendor,testVendor2"; -$avp(dnis)="40720018124"; -$avp(profit_margin)=0; - -if (cost_based_filtering("$avp(client_id)","$avp(is_ws)","$avp(carrierlist)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { - xlog("XXX - Out of the $avp(carrierlist) carriers, we should only use $avp(out_vendor_result) \n"); -... - - -
- -
- - <function moreinfo="none">cost_based_ordering(client_id,is_wholesale,vendors_csv,dialled_no,desired_margin,out_vendor_csv)</function> - - - For a call originating from the provided Client ID, on a wholesale or retail quality, going to dialled_no, the function removes the Vendors ( from the vendor_csv list ) which do not pass the desired_margin condition, and sets th out_vendor_csv variable to the list of Vendor that meet the margin condition, in descending order of their margin ( from most profitable Vendor to least profitable Vendor that still meets the margin condition ) - - - The client_id pseudo-var will hold the client_id originating this call - - - The is_wholesale pseudo-var will contain either a 1 or a 0, depending on whether the call is wholesale or retail ( see client ratesheet provisioning ). - - - The vendors_csv pseudo-var contains a list of Vendors that need to be filtered based on the desired margin ( keep just those that match your desired percentage margin for this call ) - - - The dialled_no pseudo-var contains the DNIS - the dialled number for the current call. It needs to be in E164 format, without the leading + - - - The desired_margin pseudo-var contains the minimum Integer margin that the script writer wants to achieve, based on the Client sell and Vendor buy prices. The formula used is : vendor_margin=(client_price - results[i])*100/client_price) . If the vendor_margin is higher than the desired_margin, then the Vendor is ok to use. The desired margin can be positive ( call will be profitable ) or negative ( the call will cause a loss ). - - - The out_vendors_csv pseudo-var is an output parameter, and the pvar will get populated with the CSV list of Vendors that meet the desired margin condition - - - Possible parameter types - - - ALL Parameters - String/Integer or pseudo-variables - - - - - This function can be used from any route. - - - <function moreinfo="none">cost_based_ordering</function> usage - -... -# If we get a call from testClient on it's wholesale quality, -# going to number 40720018124, and we have to pick from the list -# of vendors 'testVendor,testVendor2' based on a a profit margin -# of 0 ( we do not want to lose money on this call ), -# then $avp(out_vendor_csv) will have the vendors that we need -# to use based on the above call characteristics, and the desired margin -# The order in $avp(carrierlist) does not matter, the vendors will be -# ordered from most profitable to least profitable -$avp(client_id)="testClient"; -$avp(is_ws)=1; -$avp(carrierlist)="testVendor,testVendor2"; -$avp(dnis)="40720018124"; -$avp(profit_margin)=0; - -if (cost_based_ordering("$avp(client_id)","$avp(is_ws)","$avp(carrierlist)","$avp(dnis)","$avp(profit_margin)","$avp(out_vendor_result)")) { - xlog("XXX - Out of the $avp(carrierlist) carriers, we should only use $avp(out_vendor_result) , in the provided order\n"); - -... - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">rc_addVendor</function> - - - Adds a new Vendor, without assigning any ratesheet to it. - - - Name: rc_addVendor - - Parameters : - - - vendorName - name of the Vendor to be added - - - - MI FIFO Command Format: - - -## Add a new Vendor -# opensips-cli -x mi rc_addVendor myNewVendor - -
- -
- - <function moreinfo="none">rc_deleteVendor</function> - - - Removes a vendor from memory, along with the ratesheet asigned with it ( if any ) - - - Name: rc_deleteVendor - - Parameters : - - - vendorName - name of the Vendor to be deleted - - - - MI FIFO Command Format: - - -## Delete a Vendor -# opensipss-cli -x mi rc_deleteVendor myNewVendor - -
- -
- - <function moreinfo="none">rc_reloadVendorRate</function> - - - Reloads the provided ratesheet and assigns it to the Vendor - - - Name: rc_reloadVendorRate - - Parameters : - - - vendorName - name of the Vendor - - - ratesheet_id - ID of the ratesheet to be reloaded and assigned - - - - MI FIFO Command Format: - - -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_reloadVendorRate myVendor 3 - -
- -
- - <function moreinfo="none">rc_deleteVendorRate</function> - - - Deletes the assigned ratesheet from the Vendor - - - Name: rc_deleteVendorRate - - Parameters : - - - vendorName - name of the Vendor - - - - MI FIFO Command Format: - - -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_deleteVendorRate myVendor - -
- -
- - <function moreinfo="none">rc_getVendorPrice</function> - - - Fetches all the ratesheet information ( destination name, price, minimum, increment ) for the provided Vendor and dialled number - - - Name: rc_getVendorPrice - - Parameters : - - - vendorName - name of the Vendor - - - dialledNumber - number to match in the above Vendor's ratesheet - - - - MI FIFO Command Format: - - -## Query for the price of myVendor for the 4072731825 number -#/usr/local/bin/opensips-cli -x mi rc_getVendorPrice myVendor 4072731825 -{ - "prefix": "40727", - "destination": "ROMANIA MOBILE VODAFONE", - "price": 0.05, - "minimum": 1, - "increment": 1, - "currency": "USD" -} - -
- -
- - <function moreinfo="none">rc_addClient</function> - - - Adds a new Client, without assigning any ratesheet to it. - - - Name: rc_addClient - - Parameters : - - - clientName - name of the Client to be added - - - - MI FIFO Command Format: - - -## Add a new Client -# opensips-cli -x mi fifo rc_addClient myNewClient - -
- -
- - <function moreinfo="none">rc_deleteClient</function> - - - Removes a Client from memory, along with the ratesheet asigned with it ( if any ) - - - Name: rc_deleteClient - - Parameters : - - - clientName - name of the Client to be deleted - - - - MI FIFO Command Format: - - -## Delete a Client -# opensips-cli -x mi rc_deleteClient myClient - -
- -
- - <function moreinfo="none">rc_reloadClientRate</function> - - - Reloads the provided ratesheet and assigns it to the Client - - - Name: rc_reloadClientRate - - Parameters : - - - clientName - name of the Cient - - - isWholesale - is the ratesheet assigned on the wholesale or retail quality - - - ratesheet_id - ID of the ratesheet to be reloaded and assigned - - - - MI FIFO Command Format: - - -## Reloads the Client's wholesale Ratesheet, assigning it rate id 3 -# opensips-cli -x mi rc_reloadClientRate myClient 1 3 - -
- -
- - <function moreinfo="none">rc_deleteClientRate</function> - - - Deletes the assigned ratesheet from the Client - - - Name: rc_deleteClientRate - - Parameters : - - - ClientName - name of the Client - - - isWholesale - delete the wholesale or retail ratesheet - - - - MI FIFO Command Format: - - -## Reloads a Vendor Ratesheet -# opensips-cli -x mi rc_deleteVendorRate myVendor - -
- -
- - <function moreinfo="none">rc_getClientPrice</function> - - - Fetches all the ratesheet information ( destination name, price, minimum, increment ) for the provided Client, on the specified quality ( wholesale vs retail ) and dialled number - - - Name: rc_getClientPrice - - Parameters : - - - ClientName - name of the Client - - - isWholesale - wholesale = 1, retail = 0 - - - dialledNumber - number to match in the above Client's ratesheet - - - - MI FIFO Command Format: - - -## Query for the price of myClient, on the retail quality, for the 4072731825 number -#/usr/local/bin/opensips-cli -x mi rc_getClientPrice myClient 0 4072731825 -{ - "prefix": "40727", - "destination": "ROMANIA MOBILE VODAFONE", - "price": 0.03, - "minimum": 1, - "increment": 1, - "currency": "USD" -} - - -
- -
- -
diff --git a/modules/ratelimit/README b/modules/ratelimit/README deleted file mode 100644 index ac9e94c02a9..00000000000 --- a/modules/ratelimit/README +++ /dev/null @@ -1,753 +0,0 @@ -ratelimit Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Use Cases - 1.3. Static Rate Limiting Algorithms - - 1.3.1. Tail Drop Algorithm (TAILDROP) - 1.3.2. Random Early Detection Algorithm (RED) - 1.3.3. Slot Based Taildropping (SBT) - 1.3.4. Network Algorithm (NETWORK) - - 1.4. Dynamic Rate Limiting Algorithms - - 1.4.1. Feedback Algorithm (FEEDBACK) - - 1.5. Dependencies - - 1.5.1. OpenSIPS Modules - 1.5.2. External Libraries or Applications - - 1.6. Exported Parameters - - 1.6.1. timer_interval (integer) - 1.6.2. limit_per_interval (integer) - 1.6.3. expire_time (integer) - 1.6.4. hash_size (integer) - 1.6.5. default_algorithm (string) - 1.6.6. cachedb_url (string) - 1.6.7. db_prefix (string) - 1.6.8. repl_buffer_threshold (string) - 1.6.9. repl_timer_interval (string) - 1.6.10. repl_timer_expire (string) - 1.6.11. pipe_replication_cluster (integer) - 1.6.12. window_size (int) - 1.6.13. slot_period (int) - - 1.7. Exported Functions - - 1.7.1. rl_check(name, limit[, algorithm]) - 1.7.2. rl_dec_count(name) - 1.7.3. rl_reset_count(name) - 1.7.4. rl_values(ret_avp, regexp) - - 1.8. Exported MI Functions - - 1.8.1. rl_list - 1.8.2. rl_dump_pipe - 1.8.3. rl_reset_pipe - 1.8.4. rl_set_pid - 1.8.5. rl_get_pid - 1.8.6. rl_bin_status - - 1.9. Exported Pseudo-Variables - - 1.9.1. $rl_count(name) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set timer_interval parameter - 1.2. Set limit_per_interval parameter - 1.3. Set expire_time parameter - 1.4. Set hash_size parameter - 1.5. Set default_algorithm parameter - 1.6. Set cachedb_url parameter - 1.7. Set db_prefix parameter - 1.8. Set repl_buffer_threshold parameter - 1.9. Set repl_timer_interval parameter - 1.10. Set repl_timer_expire parameter - 1.11. Set pipe_replication_cluster parameter - 1.12. Set window_size parameter - 1.13. Set slot_period parameter - 1.14. rl_check usage - 1.15. rl_dec_count usage - 1.16. rl_reset_count usage - 1.17. rl_values usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements rate limiting for SIP requests. In - contrast to the PIKE module this limits the flow based on a per - SIP request type basis and not per source IP. The latest - sources allow you to dynamically group several messages into - some entities and limit the traffic based on them. The MI - interface can be used to change tunables while running - OpenSIPS. - - This module is integrated with the OpenSIPS Key-Value - Interface, providing support for distributed rate limiting - using Redis or Memcached CacheDB backends. The internal - limiting data will no longer be kept on each OpenSIPS instance. - It will be stored in the distributed Key-Value database and - queried by each instance before deciding if a SIP message - should be blocked or not. - - To achieve a distributed ratelimit feature, the module can also - replicate its pipes counters to different OpenSIPS instances - using the clusterer module. To do that, define the - pipe_replication_cluster parameter in your configuration - script. - - Starting with OpenSIPS 3.2, choosing whether to replicate a - pipe over CacheDB backends or bin replication is triggered by - the flags specified when the pipe is created: adding the /r - suffix to the pipe's name will replicate through CacheDB, and - adding /b will replicate through bin/clusterer. - -1.2. Use Cases - - Limiting the rate messages are processed on a system directly - influences the load. The ratelimit module can be used to - protect a single host or to protect an OpenSIPS cluster when - run on the dispatching box in front. - - Distributed limiting is useful when the rate limit should be - performed not only on a specific node, but on the entire - platform. - - NOTE: that this behavior only makes sense when the pipe - algorithm used is TAILDROP or RED. - - A sample configuration snippet might look like this: -... - if (!rl_check($rU, 50, "TAILDROP")) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - - Upon every incoming request listed above rl_check is invoked - and the entity identified by the R-URI user is checked. It - returns an OK code if the current per request load is below the - configured threshold. If the load is exceeded the function - returns an error and an administrator can discard requests with - a stateless response. - -1.3. Static Rate Limiting Algorithms - - The ratelimit module supports two different static algorithms - to be used by rl_check to determine whether a message should be - blocked or not. - -1.3.1. Tail Drop Algorithm (TAILDROP) - - This is a trivial algorithm that imposes some risks when used - in conjunction with long timer intervals. At the start of each - interval an internal counter is reset and incremented for each - incoming message. Once the counter hits the configured limit - rl_check returns an error. - - The downside of this algorithm is that it can lead to SIP - client synchronization. During a relatively long interval only - the first requests (i.e. REGISTERs) would make it through. - Following messages (i.e. RE-REGISTERs) will all hit the SIP - proxy at the same time when a common Expire timer expired. - Other requests will be retransmissed after given time, the same - on all devices with the same firmware/by the same vendor. - -1.3.2. Random Early Detection Algorithm (RED) - - Random Early Detection tries to circumvent the synchronization - problem imposed by the tail drop algorithm by measuring the - average load and adapting the drop rate dynamically. When - running with the RED algorithm OpenSIPS will return errors to - the OpenSIPS routing engine every n'th packet trying to evenly - spread the measured load of the last timer interval onto the - current interval. As a negative side effect OpenSIPS might drop - messages although the limit might not be reached within the - interval. Decrease the timer interval if you encounter this. - -1.3.3. Slot Based Taildropping (SBT) - - SBT holds a window consisting of one or more slots. You can set - the window_size parameter(seconds) which means for how long we - should look back to count the calls and slot_period - parameter(miliseconds) which tells how granular the algorithm - should be. The number of slots will be window_size/slot_period. - If, for example, you have window_size= slot_period=1 second, - then after each second you shall lose the call count, but if - you set the slot_period to 100 milliseconds, then when your - call will be outside the window, the calls in the first 100 - milliseconds shall be dropped, and the rest in the next 900 - shall be kept. - -1.3.4. Network Algorithm (NETWORK) - - This algorithm relies on information provided by network - interfaces. The total amount of bytes waiting to be consumed on - all the network interfaces is retrieved once every - timer_interval seconds. If the returned amount exceeds the - limit specified in the modparam, rl_check returns an error. - -1.4. Dynamic Rate Limiting Algorithms - - When running OpenSIPS on different machines, one has to adjust - the drop rates for the static algorithms to maintain a sub 100% - load average or packets start getting dropped in the network - stack. While this is not in itself difficult, it isn't neither - accurate nor trivial: another server taking a notable fraction - of the cpu time will require re-tuning the parameters. - - While tuning the drop rates from the outside based on a certain - factor is possible, having the algorithm run inside ratelimit - permits tuning the rates based on internal server parameters - and is somewhat more flexible (or it will be when support for - external load factors - as opposed to cpu load - is added). - -1.4.1. Feedback Algorithm (FEEDBACK) - - Using the PID Controller model (see Wikipedia page), the drop - rate is adjusted dynamically based on the load factor so that - the load factor always drifts towards the specified limit (or - setpoint, in PID terms). - - As reading the cpu load average is relatively expensive - (opening /proc/stat, parsing it, etc), this only happens once - every timer_interval seconds and consequently the FEEDBACK - value is only at these intervals recomputed. This in turn makes - it difficult for the drop rate to adjust quickly. Worst case - scenarios are request rates going up/down instantly by - thousands - it takes up to 20 seconds for the controller to - adapt to the new request rate. - - Generally though, as real life request rates drift by less, - adapting should happen much faster. - - IMPORTANT NOTE: as this algorithm is diven by the load factor, - the values for the limits must be between 0 and 100 (as - percentages) and the limits for all the checks and pipes must - be the same (only one value). Again, this limitation are - specific to this algorithm and not to the implementation. - -1.5. Dependencies - -1.5.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.5.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.6. Exported Parameters - -1.6.1. timer_interval (integer) - - The timer interval in seconds when the Network and Feedback - algorithms run their queries, and the other algorithms reset - their counters. - - IMPORTANT: A too small value may lead to performance penalties - due to timer process overloading. - - Default value is 10. - - Example 1.1. Set timer_interval parameter -... -modparam("ratelimit", "timer_interval", 5) -... - -1.6.2. limit_per_interval (integer) - - This parameter configures the way that a pipe's limit is - specified in the rl_check function and only affects the - Taildrop and RED algorithms. A value of 1 means that the limit - is set per-timer_interval while a value of 0 means per-second. - - Default value is 0(limit per-second). - - Example 1.2. Set limit_per_interval parameter -... -modparam("ratelimit", "limit_per_interval", 1) -... - -1.6.3. expire_time (integer) - - This parameter specifies how long a pipe should be kept in - memory after it becomes idle (no more operations are performed - on the pipe) until deleted. - - Default value is 3600. - - Example 1.3. Set expire_time parameter -... -modparam("ratelimit", "expire_time", 1800) -... - -1.6.4. hash_size (integer) - - The size of the hash table internally used to keep the pipes. A - larger table is much faster but consumes more memory. The hash - size must be a power of 2 number. - - Default value is 1024. - - Example 1.4. Set hash_size parameter -... -modparam("ratelimit", "hash_size", 512) -... - -1.6.5. default_algorithm (string) - - Specifies which algorithm should be assumed in case it isn't - explicitly specified in the rl_check function. - - Default value is "TAILDROP". - - Example 1.5. Set default_algorithm parameter -... -modparam("ratelimit", "default_algorithm", "RED") -... - -1.6.6. cachedb_url (string) - - Enables distributed rate limiting and specifies the backend - that should be used by the CacheDB interface. - - Default value is "disabled". - - Example 1.6. Set cachedb_url parameter -... -modparam("ratelimit", "cachedb_url", "redis://root:root@127.0.0.1/") -... - -1.6.7. db_prefix (string) - - Specifies what prefix should be added to the pipe name. This is - only used when distributed rate limiting is enabled. - - Default value is "rl_pipe_". - - Example 1.7. Set db_prefix parameter -... -modparam("ratelimit", "db_prefix", "ratelimit_") -... - -1.6.8. repl_buffer_threshold (string) - - Used to specify the length of the buffer used by the binary - replication, in bytes, when a flush should be performed - the - pipes gathered until then should be sent on the network. This - is used to avoid using large amount of memory for pipes - replication. - - Default value is 32767 bytes. - - Example 1.8. Set repl_buffer_threshold parameter -... -modparam("ratelimit", "repl_buffer_threshold", 500) -... - -1.6.9. repl_timer_interval (string) - - Timer in milliseconds, used to specify how often the module - should replicate its counters to the other instances. - - Default value is 200 ms. - - Example 1.9. Set repl_timer_interval parameter -... -modparam("ratelimit", "repl_timer_interval", 100) -... - -1.6.10. repl_timer_expire (string) - - Timer in seconds, used to specify when the counter received - from a different instance should no longer be taken into - account. This is used to prevent obsolete values, in case an - instance stops replicating its counters. - - Default value is 10 s. - - Example 1.10. Set repl_timer_expire parameter -... -modparam("ratelimit", "repl_timer_expire", 10) -... - -1.6.11. pipe_replication_cluster (integer) - - Specifies the cluster ID where pipes will be replicated to and - received from. - - Default value is 0. (no replication) - - Example 1.11. Set pipe_replication_cluster parameter -... -modparam("ratelimit", "pipe_replication_cluster", 1) -... - -1.6.12. window_size (int) - - How long the history in SBT should be in seconds. - - Default value is “10”. - - Example 1.12. Set window_size parameter -... -modparam("ratelimit", "window_size", 5) -... - -1.6.13. slot_period (int) - - Value of one slot in milliseconds. This parameter determines - how granular the algorithm should be. The number of slots will - be determined by window_size/slot_period. - - Default value is “200”. - - Example 1.13. Set slot_period parameter -... -modparam("ratelimit", "window_size", 5) -#we will have 50 slots of 100 milliseconds -modparam("ratelimit", "slot_period", 100) -... - -1.7. Exported Functions - -1.7.1. rl_check(name, limit[, algorithm]) - - Check the current request against the pipe identified by name - and changes/updates the limit. If no pipe is found, then a new - one is created with the specified limit and algorithm, if - specified. If the algorithm parameter doesn't exist, the - default one is used. - - NOTE: A pipe's algorithm cannot be dynamically changed. Only - the one specified when the pipe was created will be considered. - - NOTE: This function increments the pipe's counter every time it - is called, even if the call should be declined. Therefore If - you are using ratelimit to limit only successful traffic, you - need to explicitely decrease the counter for the declined calls - using the rl_dec_count() function. - - The method will return an error code if the limit for the - matched pipe is reached. - - Meaning of the parameters is as follows: - * name (string) - this is the name that identifies the pipe - which should be checked. One can also specify the /s suffix - to indicate the pipe should be replicated over cached, or - /b to replicate over bin/clusterer interface. - * limit (int) - this specifies the threshold limit of the - pipe. It is strongly related to the algorithm used. Note - that the limit should be specified as per-second, not - per-timer_interval. - * algorithm (string, optional) - this parameter reffers to - the algorithm used to check the pipe. If it is not set, the - default value is used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, - TIMER_ROUTE and EVENT_ROUTE. - - Example 1.14. rl_check usage -... - # perform a pipe match for all INVITE methods using RED algorith -m - if (is_method("INVITE")) { - if (!rl_check("pipe_INVITE", 100, "RED")) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; - }; -... - # use default algorithm for each different gateway - $var(limit) = 10; - if (!rl_check("gw_$ru", $var(limit))) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - # count only successful calls - if (!rl_check("gw_$ru", 100)) { - rl_dec_count("gw_$ru"); - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - -1.7.2. rl_dec_count(name) - - This function decreases a counter that could have been - previously increased by rl_check function. - - Meaning of the parameters is as follows: - * name (string) - identifies the name of the pipe. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, - TIMER_ROUTE and EVENT_ROUTE. - - Example 1.15. rl_dec_count usage -... - if (!rl_check("gw_$ru", 100, "TAILDROP")) { - exit; - } else { - rl_dec_count("gw_$ru"); - }; -... - -1.7.3. rl_reset_count(name) - - This function resets a counter that could have been previously - increased by rl_check function. - - Meaning of the parameters is as follows: - * name - identifies the name of the pipe. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, - TIMER_ROUTE and EVENT_ROUTE. - - Example 1.16. rl_reset_count usage -... - if (!rl_check("gw_$ru", 100, "TAILDROP")) { - exit; - } else { - rl_reset_count("gw_$ru"); - }; -... - -1.7.4. rl_values(ret_avp, regexp) - - Returns all the available pipes' names in the ret_avp output - variable. - - Meaning of the parameters is as follows: - * ret_avp (string) - an AVP where the pipes' names will be - stored. - * regexp (regex, optional) - a regular expression used to - filter the names of the pipes. If missing, all the pipes - are returned. - - This function can be used from any route. - - Example 1.17. rl_values usage -... - rl_values($avp(values)); - for ($var(pipe) in $(avp(values)[*])) - xlog("RATELIMIT: $var(pipe): $rl_count($var(pipe))\n"); -... - -1.8. Exported MI Functions - -1.8.1. rl_list - - Lists the parameters and variabiles in the ratelimit module. - - Name: rl_list - - Parameters: - * pipe (optional) - indicates the name of the single pipe to - be listed. - * filter (optional) - a pattern used to filter the active - pipes to be listed. The filter is a shell wildcard pattern - (see glob(7)). - * filter_out (optional) - a pattern used to filter out the - active pipes NOT to be listed. The filter is a shell - wildcard pattern (see glob(7)). - - Note that you cannot combine multiple paramters when calling - this function. If using parameters, only one is accepted. - - If no parameter are passed to the function, all the active - pipes are listed. - - MI FIFO Command Format: - opensips-cli -x mi rl_list pipe=gw_10.0.0.1 - opensips-cli -x mi rl_list filter=gw_* - -1.8.2. rl_dump_pipe - - Exposes all the details about the current runtime data - (specific to the pipe's algorithm) of a pipe. Currently make - sense for SBT. - - Name: rl_dump_pipe - - Parameters: - * pipe - indicates the name of the pipe. - - MI FIFO Command Format: - opensips-cli -x mi rl_dump_pipe gw_10.0.0.1 - -1.8.3. rl_reset_pipe - - Resets the counter of a specified pipe. - - Name: rl_reset_pipe - - Parameters: - * pipe - indicates the name of the pipe whose counter should - be reset. - - MI FIFO Command Format: - opensips-cli -x mi rl_reset_pipe gw_10.0.0.1 - -1.8.4. rl_set_pid - - Sets the PID Controller parameters for the Feedback Algorithm. - - Name: rl_set_pid - - Parameters: - * ki - the integral parameter. - * kp - the proportional parameter. - * kd - the derivative parameter. - - MI FIFO Command Format: - opensips-cli -x mi rl_set_pid 0.5 0.5 0.5 - -1.8.5. rl_get_pid - - Gets the list of in use PID Controller parameters. - - Name: rl_get_pid - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi rl_get_pid - -1.8.6. rl_bin_status - - Dumps each destination used for replication, as well as the - timestamp of the last message received from them. - - Name: rl_bin_status - - Parameters: none - - MI FIFO Command Format: - opensips-cli -x mi rl_bin_status - -1.9. Exported Pseudo-Variables - -1.9.1. $rl_count(name) - - Returns the counter of a pipe. The variable is read-only. - - NULL will be returned if the pipe does not exist. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 136 63 3289 2700 - 2. Ovidiu Sas (@ovidiusas) 39 17 2481 44 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 35 29 299 137 - 4. Vlad Patrascu (@rvlad-patrascu) 31 17 359 558 - 5. Liviu Chircu (@liviuchircu) 27 21 131 193 - 6. Eseanu Marius Cristian (@eseanucristian) 13 6 329 195 - 7. Daniel-Constantin Mierla (@miconda) 9 7 24 18 - 8. Maksym Sobolyev (@sobomax) 6 4 8 9 - 9. Ionut Ionita (@ionutrazvanionita) 5 1 244 3 - 10. Ionel Cerghit (@ionel-cerghit) 4 2 34 24 - - All remaining contributors: Henning Westerholt (@henningw), - Walter Doekes (@wdoekes), Peter Lemenkov (@lemenkov), Robert - Moss, Arnaud Boussus, Sergio Gutierrez, Stanislaw Pitucha, Bill - Hau, Konstantin Bokarius, Vlad Paiu (@vladpaiu), Julián Moreno - Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Sep 2011 - May 2025 - 2. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2008 - Jul 2023 - 4. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2021 - 5. Robert Moss Feb 2021 - Feb 2021 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 7. Vlad Patrascu (@rvlad-patrascu) Jul 2016 - Apr 2019 - 8. Ionel Cerghit (@ionel-cerghit) Jul 2015 - Dec 2016 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Ionut Ionita (@ionutrazvanionita) Dec 2015 - Dec 2015 - - All remaining contributors: Eseanu Marius Cristian - (@eseanucristian), Bill Hau, Walter Doekes (@wdoekes), Vlad - Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Stanislaw Pitucha, - Arnaud Boussus, Sergio Gutierrez, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut - Ionita (@ionutrazvanionita), Eseanu Marius Cristian - (@eseanucristian), Walter Doekes (@wdoekes), Arnaud Boussus, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, - Henning Westerholt (@henningw), Ovidiu Sas (@ovidiusas), Edson - Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2011 OpenSIPS Foundation - - Copyright © 2008 VoIP Embedded Inc. - - Copyright © 2006 Freenet Cityline GmbH diff --git a/modules/ratelimit/README.md b/modules/ratelimit/README.md new file mode 100644 index 00000000000..90842f7b3d7 --- /dev/null +++ b/modules/ratelimit/README.md @@ -0,0 +1,789 @@ +--- +title: "ratelimit Module" +description: "This module implements rate limiting for SIP requests." +--- + +## Admin Guide + + +### Overview + + +This module implements rate limiting for SIP requests. In contrast to +the PIKE module this limits the flow based on a per SIP request type +basis and not per source IP. The latest sources allow you to +dynamically group several messages into some entities and limit the +traffic based on them. The MI interface can be used to change +tunables while running OpenSIPS. + + +This module is integrated with the OpenSIPS Key-Value Interface, +providing support for distributed rate limiting using Redis or Memcached +CacheDB backends. The internal limiting data will no longer be kept on each +OpenSIPS instance. It will be stored in the distributed Key-Value database +and queried by each instance before deciding if a SIP message should be +blocked or not. + + +To achieve a distributed ratelimit feature, the module can also replicate +its pipes counters to different OpenSIPS instances using the clusterer module. +To do that, define the *pipe_replication_cluster* parameter +in your configuration script. + + +Starting with OpenSIPS 3.2, choosing whether to replicate a pipe over +CacheDB backends or bin replication is triggered by the flags specified +when the pipe is created: adding the */r* suffix to the +pipe's name will replicate through CacheDB, and adding */b* +will replicate through bin/clusterer. + + +### Use Cases + + +Limiting the rate messages are processed on a system directly +influences the load. The ratelimit module can be used to protect a +single host or to protect an OpenSIPS cluster when run on the +dispatching box in front. + + +Distributed limiting is useful when the rate limit should be +performed not only on a specific node, but on the entire platform. + + +> [!NOTE] +> This behavior only makes sense when the pipe algorithm +> used is TAILDROP or RED. + + +A sample configuration snippet might look like this: + + +```opensips +... + if (!rl_check($rU, 50, "TAILDROP")) { + sl_send_reply(503, "Server Unavailable"); + exit; + }; +... +``` + + +Upon every incoming request listed above rl_check is invoked and +the entity identified by the R-URI user is checked. It +returns an OK code if the current per request load is below the +configured threshold. If the load is exceeded the function returns an +error and an administrator can discard requests with a stateless +response. + + +### Static Rate Limiting Algorithms + + +The ratelimit module supports two different static algorithms +to be used by rl_check to determine whether a message should be +blocked or not. + + +#### Tail Drop Algorithm (TAILDROP) + + +This is a trivial algorithm that imposes some risks when used in +conjunction with long timer intervals. At the start of each interval +an internal counter is reset and incremented for each incoming +message. Once the counter hits the configured limit rl_check returns +an error. + + +The downside of this algorithm is that it can lead to SIP client +synchronization. During a relatively long interval only the first +requests (i.e. REGISTERs) would make it through. Following messages +(i.e. RE-REGISTERs) will all hit the SIP proxy at the same time when a +common Expire timer expired. Other requests will be retransmissed +after given time, the same on all devices with the same firmware/by +the same vendor. + + +#### Random Early Detection Algorithm (RED) + + +Random Early Detection tries to circumvent the synchronization problem +imposed by the tail drop algorithm by measuring the average load and +adapting the drop rate dynamically. When running with the RED +algorithm OpenSIPS will return errors to the OpenSIPS +routing engine every n'th packet trying to evenly spread the measured +load of the last timer interval onto the current interval. As a +negative side effect OpenSIPS might drop messages although the limit might +not be reached within the interval. Decrease the timer interval if you +encounter this. + + +#### Slot Based Taildropping (SBT) + + +SBT holds a window consisting of one or more slots. You can set the +*window_size* parameter(seconds) which means for +how long we should look back to count the calls and +*slot_period* parameter(miliseconds) which tells +how granular the algorithm should be. The number of slots will be +*window_size*/*slot_period*. +If, for example, you have *window_size*= +*slot_period*=1 second, then after each second +you shall lose the call count, but if you set the +*slot_period* to 100 milliseconds, then when your +call will be outside the window, the calls in the first 100 milliseconds +shall be dropped, and the rest in the next 900 shall be kept. + + +#### Network Algorithm (NETWORK) + + +This algorithm relies on information provided by network interfaces. +The total amount of bytes waiting to be consumed on all the network +interfaces is retrieved once every timer_interval seconds. +If the returned amount exceeds the limit specified in the modparam, +rl_check returns an error. + + +### Dynamic Rate Limiting Algorithms + + +When running OpenSIPS on different machines, one has to adjust the drop +rates for the static algorithms to maintain a sub 100% load average or +packets start getting dropped in the network stack. While this is not +in itself difficult, it isn't neither accurate nor trivial: another +server taking a notable fraction of the cpu time will require re-tuning +the parameters. + + +While tuning the drop rates from the outside based on a certain factor +is possible, having the algorithm run inside ratelimit permits tuning +the rates based on internal server parameters and is somewhat more +flexible (or it will be when support for external load factors - as +opposed to cpu load - is added). + + +#### Feedback Algorithm (FEEDBACK) + + +Using the PID Controller model +(see [Wikipedia page](http://en.wikipedia.org/wiki/PID_controller)), +the drop rate is adjusted dynamically based on the load factor so that +the load factor always drifts towards the specified limit (or setpoint, +in PID terms). + + +As reading the cpu load average is relatively expensive (opening /proc/stat, +parsing it, etc), this only happens once every timer_interval seconds and +consequently the FEEDBACK value is only at these intervals recomputed. This +in turn makes it difficult for the drop rate to adjust quickly. Worst case +scenarios are request rates going up/down instantly by thousands - it takes +up to 20 seconds for the controller to adapt to the new request rate. + + +Generally though, as real life request rates drift by less, adapting should +happen much faster. + + +> [!IMPORTANT] +> As this algorithm is diven by the load factor, the values +> for the limits must be between 0 and 100 (as percentages) and the limits +> for all the checks and pipes must be the same (only one value). Again, this +> limitation are specific to this algorithm and not to the implementation. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### timer_interval (integer) + + +The timer interval in seconds when the Network and Feedback algorithms +run their queries, and the other algorithms reset their counters. + + +> [!IMPORTANT] +> A too small value may lead to performance penalties due to +> timer process overloading. + + +*Default value is 10.* + + +```opensips title="Set timer_interval parameter" +... +modparam("ratelimit", "timer_interval", 5) +... +``` + + +#### limit_per_interval (integer) + + +This parameter configures the way that a pipe's limit is specified +in the *rl_check* function and only affects the +Taildrop and RED algorithms. A value of 1 means that the limit is +set per-*timer_interval* while a value of 0 means per-second. + + +*Default value is 0(limit per-second).* + + +```opensips title="Set limit_per_interval parameter" +... +modparam("ratelimit", "limit_per_interval", 1) +... +``` + + +#### expire_time (integer) + + +This parameter specifies how long a pipe should be kept in memory +after it becomes idle (no more operations are performed on the pipe) +until deleted. + + +*Default value is 3600.* + + +```opensips title="Set expire_time parameter" +... +modparam("ratelimit", "expire_time", 1800) +... +``` + + +#### hash_size (integer) + + +The size of the hash table internally used to keep the pipes. +A larger table is much faster but consumes more memory. The hash size +must be a power of 2 number. + + +*Default value is 1024.* + + +```opensips title="Set hash_size parameter" +... +modparam("ratelimit", "hash_size", 512) +... +``` + + +#### default_algorithm (string) + + +Specifies which algorithm should be assumed in case it isn't +explicitly specified in the *rl_check* function. + + +*Default value is "TAILDROP".* + + +```opensips title="Set default_algorithm parameter" +... +modparam("ratelimit", "default_algorithm", "RED") +... +``` + + +#### cachedb_url (string) + + +Enables distributed rate limiting and specifies the backend +that should be used by the CacheDB interface. + + +*Default value is "disabled".* + + +```opensips title="Set cachedb_url parameter" +... +modparam("ratelimit", "cachedb_url", "redis://root:root@127.0.0.1/") +... +``` + + +#### db_prefix (string) + + +Specifies what prefix should be added to the pipe name. This is +only used when distributed rate limiting is enabled. + + +*Default value is "rl_pipe_".* + + +```opensips title="Set db_prefix parameter" +... +modparam("ratelimit", "db_prefix", "ratelimit_") +... +``` + + +#### repl_buffer_threshold (string) + + +Used to specify the length of the buffer used by the binary +replication, in bytes, when a flush should be performed - the pipes +gathered until then should be sent on the network. This is used +to avoid using large amount of memory for pipes replication. + + +*Default value is 32767 bytes.* + + +```opensips title="Set repl_buffer_threshold parameter" +... +modparam("ratelimit", "repl_buffer_threshold", 500) +... +``` + + +#### repl_timer_interval (string) + + +Timer in milliseconds, used to specify how often the module +should replicate its counters to the other instances. + + +*Default value is 200 ms.* + + +```opensips title="Set repl_timer_interval parameter" +... +modparam("ratelimit", "repl_timer_interval", 100) +... +``` + + +#### repl_timer_expire (string) + + +Timer in seconds, used to specify when the counter received +from a different instance should no longer be taken into account. +This is used to prevent obsolete values, in case an instance stops +replicating its counters. + + +*Default value is 10 s.* + + +```opensips title="Set repl_timer_expire parameter" +... +modparam("ratelimit", "repl_timer_expire", 10) +... +``` + + +#### pipe_replication_cluster (integer) + + +Specifies the cluster ID where pipes will be replicated to and +received from. + + +*Default value is 0. (no replication)* + + +```opensips title="Set pipe_replication_cluster parameter" +... +modparam("ratelimit", "pipe_replication_cluster", 1) +... +``` + + +#### window_size (int) + + +How long the history in SBT should be in seconds. + + +*Default value is "10".* + + +```opensips title="Set window_size parameter" +... +modparam("ratelimit", "window_size", 5) +... +``` + + +#### slot_period (int) + + +Value of one slot in milliseconds. This parameter determines +how granular the algorithm should be. The number of slots will be +determined by window_size/slot_period. + + +*Default value is "200".* + + +```opensips title="Set slot_period parameter" +... +modparam("ratelimit", "window_size", 5) +#we will have 50 slots of 100 milliseconds +modparam("ratelimit", "slot_period", 100) +... +``` + + +### Exported Functions + + +#### rl_check(name, limit[, algorithm]) + + +Check the current request against the pipe identified by name and +changes/updates the limit. If no pipe is found, then a new one is +created with the specified limit and algorithm, if specified. If the +algorithm parameter doesn't exist, the default one is used. + + +> [!NOTE] +> A pipe's algorithm cannot be dynamically changed. Only the one +> specified when the pipe was created will be considered. + + +> [!NOTE] +> This function increments the pipe's counter every time it is +> called, even if the call should be declined. Therefore If you are using +> ratelimit to limit only successful traffic, you need to explicitely +> decrease the counter for the declined calls using the +> *rl_dec_count()* function. + + +The method will return an error code if the limit for the +matched pipe is reached. + + +Meaning of the parameters is as follows: + + +- *name* (string) - this is the name that identifies +the pipe which should be checked. One can also specify the +*/s* suffix to indicate the pipe +should be replicated over cached, or */b* +to replicate over bin/clusterer interface. +- *limit* (int) - this specifies the threshold +limit of the pipe. It is strongly related to the algorithm +used. Note that the limit should be specified as per-second, not +per-timer_interval. +- *algorithm* (string, optional) - this parameter +reffers to the algorithm used to check the pipe. If it is +not set, the default value is used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. + + +```opensips title="rl_check usage" +... + # perform a pipe match for all INVITE methods using RED algorithm + if (is_method("INVITE")) { + if (!rl_check("pipe_INVITE", 100, "RED")) { + sl_send_reply(503, "Server Unavailable"); + exit; + }; + }; +... + # use default algorithm for each different gateway + $var(limit) = 10; + if (!rl_check("gw_$ru", $var(limit))) { + sl_send_reply(503, "Server Unavailable"); + exit; + }; +... + # count only successful calls + if (!rl_check("gw_$ru", 100)) { + rl_dec_count("gw_$ru"); + sl_send_reply(503, "Server Unavailable"); + exit; + }; +... +``` + + +#### rl_dec_count(name) + + +This function decreases a counter that could have been previously +increased by *rl_check* function. + + +Meaning of the parameters is as follows: + + +- *name* (string) - identifies the name of the pipe. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. + + +```opensips title="rl_dec_count usage" +... + if (!rl_check("gw_$ru", 100, "TAILDROP")) { + exit; + } else { + rl_dec_count("gw_$ru"); + }; +... +``` + + +#### rl_reset_count(name) + + +This function resets a counter that could have been previously +increased by *rl_check* function. + + +Meaning of the parameters is as follows: + + +- *name* - identifies the name of the pipe. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. + + +```opensips title="rl_reset_count usage" +... + if (!rl_check("gw_$ru", 100, "TAILDROP")) { + exit; + } else { + rl_reset_count("gw_$ru"); + }; +... +``` + + +#### rl_values(ret_avp, regexp) + + +Returns all the available pipes' names in the *ret_avp* +output variable. + + +Meaning of the parameters is as follows: + + +- *ret_avp* (string) - an AVP where the pipes' +names will be stored. +- *regexp* (regex, optional) - a regular expression +used to filter the names of the pipes. If missing, all the pipes +are returned. + + +This function can be used from any route. + + +```opensips title="rl_values usage" +... + rl_values($avp(values)); + for ($var(pipe) in $(avp(values)[*])) + xlog("RATELIMIT: $var(pipe): $rl_count($var(pipe))\n"); +... +``` + + +### Exported MI Functions + + +#### rl_list + + +Lists the parameters and variabiles in the ratelimit module. + + +Name: *rl_list* + + +Parameters: + + +- *pipe* (optional) - indicates the name of the +single pipe to be listed. +- *filter* (optional) - a pattern used to filter +the active pipes to be listed. The filter is a shell wildcard +pattern (see glob(7)). +- *filter_out* (optional) - a pattern used to +filter out the active pipes NOT to be listed. +The filter is a shell wildcard pattern (see glob(7)). + + +> [!NOTE] +> You cannot combine multiple paramters when calling this +> function. If using parameters, only one is accepted. + + +If no parameter are passed to the function, all the active pipes +are listed. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_list pipe=gw_10.0.0.1 +opensips-cli -x mi rl_list filter=gw_* +``` + + +#### rl_dump_pipe + + +Exposes all the details about the current runtime data (specific to the +pipe's algorithm) of a pipe. Currently make sense for SBT. + + +Name: *rl_dump_pipe* + + +Parameters: + + +- *pipe* - indicates the name of the pipe. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_dump_pipe gw_10.0.0.1 +``` + + +#### rl_reset_pipe + + +Resets the counter of a specified pipe. + + +Name: *rl_reset_pipe* + + +Parameters: + + +- *pipe* - indicates the name of the pipe whose +counter should be reset. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_reset_pipe gw_10.0.0.1 +``` + + +#### rl_set_pid + + +Sets the PID Controller parameters for the Feedback Algorithm. + + +Name: *rl_set_pid* + + +Parameters: + + +- *ki* - the integral parameter. +- *kp* - the proportional parameter. +- *kd* - the derivative parameter. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_set_pid 0.5 0.5 0.5 +``` + + +#### rl_get_pid + + +Gets the list of in use PID Controller parameters. + + +Name: *rl_get_pid* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_get_pid +``` + + +#### rl_bin_status + + +Dumps each destination used for replication, as well as +the timestamp of the last message received from them. + + +Name: *rl_bin_status* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rl_bin_status +``` + + +### Exported Pseudo-Variables + + +#### $rl_count(name) + + +Returns the counter of a pipe. The variable is read-only. + + +NULL will be returned if the pipe does not exist. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/ratelimit/doc/contributors.xml b/modules/ratelimit/doc/contributors.xml deleted file mode 100644 index acc70a6c286..00000000000 --- a/modules/ratelimit/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 136 - 63 - 3289 - 2700 - - - 2. - Ovidiu Sas (@ovidiusas) - 39 - 17 - 2481 - 44 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 35 - 29 - 299 - 137 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 31 - 17 - 359 - 558 - - - 5. - Liviu Chircu (@liviuchircu) - 27 - 21 - 131 - 193 - - - 6. - Eseanu Marius Cristian (@eseanucristian) - 13 - 6 - 329 - 195 - - - 7. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 24 - 18 - - - 8. - Maksym Sobolyev (@sobomax) - 6 - 4 - 8 - 9 - - - 9. - Ionut Ionita (@ionutrazvanionita) - 5 - 1 - 244 - 3 - - - 10. - Ionel Cerghit (@ionel-cerghit) - 4 - 2 - 34 - 24 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Walter Doekes (@wdoekes), Peter Lemenkov (@lemenkov), Robert Moss, Arnaud Boussus, Sergio Gutierrez, Stanislaw Pitucha, Bill Hau, Konstantin Bokarius, Vlad Paiu (@vladpaiu), Julián Moreno Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Sep 2011 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2008 - Jul 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2021 - - - 5. - Robert Moss - Feb 2021 - Feb 2021 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - Jul 2016 - Apr 2019 - - - 8. - Ionel Cerghit (@ionel-cerghit) - Jul 2015 - Dec 2016 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Dec 2015 - Dec 2015 - - - -
-All remaining contributors: Eseanu Marius Cristian (@eseanucristian), Bill Hau, Walter Doekes (@wdoekes), Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Stanislaw Pitucha, Arnaud Boussus, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Eseanu Marius Cristian (@eseanucristian), Walter Doekes (@wdoekes), Arnaud Boussus, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Henning Westerholt (@henningw), Ovidiu Sas (@ovidiusas), Edson Gellert Schubert. -
- -
diff --git a/modules/ratelimit/doc/ratelimit.xml b/modules/ratelimit/doc/ratelimit.xml deleted file mode 100644 index e6ef9ea2940..00000000000 --- a/modules/ratelimit/doc/ratelimit.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - ratelimit Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011 OpenSIPS Foundation - ©right; 2008 VoIP Embedded Inc. - ©right; 2006 Freenet Cityline GmbH - diff --git a/modules/ratelimit/doc/ratelimit_admin.xml b/modules/ratelimit/doc/ratelimit_admin.xml deleted file mode 100644 index 6288a93049c..00000000000 --- a/modules/ratelimit/doc/ratelimit_admin.xml +++ /dev/null @@ -1,871 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements rate limiting for SIP requests. In contrast to - the PIKE module this limits the flow based on a per SIP request type - basis and not per source IP. The latest sources allow you to - dynamically group several messages into some entities and limit the - traffic based on them. The MI interface can be used to change - tunables while running OpenSIPS. - - - This module is integrated with the &osips; Key-Value Interface, - providing support for distributed rate limiting using Redis or Memcached - CacheDB backends. The internal limiting data will no longer be kept on each - &osips; instance. It will be stored in the distributed Key-Value database - and queried by each instance before deciding if a SIP message should be - blocked or not. - - - To achieve a distributed ratelimit feature, the module can also replicate - its pipes counters to different &osips; instances using the clusterer module. - To do that, define the pipe_replication_cluster parameter - in your configuration script. - - - Starting with &osips; 3.2, choosing whether to replicate a pipe over - CacheDB backends or bin replication is triggered by the flags specified - when the pipe is created: adding the /r suffix to the - pipe's name will replicate through CacheDB, and adding /b - will replicate through bin/clusterer. - -
-
- Use Cases - - Limiting the rate messages are processed on a system directly - influences the load. The ratelimit module can be used to protect a - single host or to protect an OpenSIPS cluster when run on the - dispatching box in front. - - - Distributed limiting is useful when the rate limit should be - performed not only on a specific node, but on the entire platform. - - - NOTE: that this behavior only makes sense when the pipe algorithm - used is TAILDROP or RED. - - - A sample configuration snippet might look like this: - - -... - if (!rl_check($rU, 50, "TAILDROP")) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - - - Upon every incoming request listed above rl_check is invoked and - the entity identified by the R-URI user is checked. It - returns an OK code if the current per request load is below the - configured threshold. If the load is exceeded the function returns an - error and an administrator can discard requests with a stateless - response. - -
-
- Static Rate Limiting Algorithms - - The ratelimit module supports two different static algorithms - to be used by rl_check to determine whether a message should be - blocked or not. - -
- Tail Drop Algorithm (TAILDROP) - - This is a trivial algorithm that imposes some risks when used in - conjunction with long timer intervals. At the start of each interval - an internal counter is reset and incremented for each incoming - message. Once the counter hits the configured limit rl_check returns - an error. - - - The downside of this algorithm is that it can lead to SIP client - synchronization. During a relatively long interval only the first - requests (i.e. REGISTERs) would make it through. Following messages - (i.e. RE-REGISTERs) will all hit the SIP proxy at the same time when a - common Expire timer expired. Other requests will be retransmissed - after given time, the same on all devices with the same firmware/by - the same vendor. - -
-
- Random Early Detection Algorithm (RED) - - Random Early Detection tries to circumvent the synchronization problem - imposed by the tail drop algorithm by measuring the average load and - adapting the drop rate dynamically. When running with the RED - algorithm OpenSIPS will return errors to the OpenSIPS - routing engine every n'th packet trying to evenly spread the measured - load of the last timer interval onto the current interval. As a - negative side effect OpenSIPS might drop messages although the limit might - not be reached within the interval. Decrease the timer interval if you - encounter this. - -
-
- Slot Based Taildropping (SBT) - - SBT holds a window consisting of one or more slots. You can set the - window_size parameter(seconds) which means for - how long we should look back to count the calls and - slot_period parameter(miliseconds) which tells - how granular the algorithm should be. The number of slots will be - window_size/slot_period. - If, for example, you have window_size= - slot_period=1 second, then after each second - you shall lose the call count, but if you set the - slot_period to 100 milliseconds, then when your - call will be outside the window, the calls in the first 100 milliseconds - shall be dropped, and the rest in the next 900 shall be kept. - -
-
- Network Algorithm (NETWORK) - - This algorithm relies on information provided by network interfaces. - The total amount of bytes waiting to be consumed on all the network - interfaces is retrieved once every timer_interval seconds. - If the returned amount exceeds the limit specified in the modparam, - rl_check returns an error. - -
-
-
- Dynamic Rate Limiting Algorithms - - When running &osips; on different machines, one has to adjust the drop - rates for the static algorithms to maintain a sub 100% load average or - packets start getting dropped in the network stack. While this is not - in itself difficult, it isn't neither accurate nor trivial: another - server taking a notable fraction of the cpu time will require re-tuning - the parameters. - - - While tuning the drop rates from the outside based on a certain factor - is possible, having the algorithm run inside ratelimit permits tuning - the rates based on internal server parameters and is somewhat more - flexible (or it will be when support for external load factors - as - opposed to cpu load - is added). - -
- Feedback Algorithm (FEEDBACK) - - Using the PID Controller model - (see Wikipedia page), - the drop rate is adjusted dynamically based on the load factor so that - the load factor always drifts towards the specified limit (or setpoint, - in PID terms). - - - As reading the cpu load average is relatively expensive (opening /proc/stat, - parsing it, etc), this only happens once every timer_interval seconds and - consequently the FEEDBACK value is only at these intervals recomputed. This - in turn makes it difficult for the drop rate to adjust quickly. Worst case - scenarios are request rates going up/down instantly by thousands - it takes - up to 20 seconds for the controller to adapt to the new request rate. - - - Generally though, as real life request rates drift by less, adapting should - happen much faster. - - - IMPORTANT NOTE: as this algorithm is diven by the load factor, the values - for the limits must be between 0 and 100 (as percentages) and the limits - for all the checks and pipes must be the same (only one value). Again, this - limitation are specific to this algorithm and not to the implementation. - -
-
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>timer_interval</varname> (integer) - - The timer interval in seconds when the Network and Feedback algorithms - run their queries, and the other algorithms reset their counters. - - - IMPORTANT: A too small value may lead to performance penalties due to - timer process overloading. - - - - Default value is 10. - - - - Set <varname>timer_interval</varname> parameter - -... -modparam("ratelimit", "timer_interval", 5) -... - - -
- -
- <varname>limit_per_interval</varname> (integer) - - This parameter configures the way that a pipe's limit is specified - in the rl_check function and only affects the - Taildrop and RED algorithms. A value of 1 means that the limit is - set per-timer_interval while a value of 0 means per-second. - - - - Default value is 0(limit per-second). - - - - Set <varname>limit_per_interval</varname> parameter - -... -modparam("ratelimit", "limit_per_interval", 1) -... - - -
- -
- <varname>expire_time</varname> (integer) - - This parameter specifies how long a pipe should be kept in memory - after it becomes idle (no more operations are performed on the pipe) - until deleted. - - - - Default value is 3600. - - - - Set <varname>expire_time</varname> parameter - -... -modparam("ratelimit", "expire_time", 1800) -... - - -
-
- <varname>hash_size</varname> (integer) - - The size of the hash table internally used to keep the pipes. - A larger table is much faster but consumes more memory. The hash size - must be a power of 2 number. - - - - Default value is 1024. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("ratelimit", "hash_size", 512) -... - - -
-
- <varname>default_algorithm</varname> (string) - - Specifies which algorithm should be assumed in case it isn't - explicitly specified in the rl_check function. - - - - Default value is "TAILDROP". - - - - Set <varname>default_algorithm</varname> parameter - -... -modparam("ratelimit", "default_algorithm", "RED") -... - - -
-
- <varname>cachedb_url</varname> (string) - - Enables distributed rate limiting and specifies the backend - that should be used by the CacheDB interface. - - - - Default value is "disabled". - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("ratelimit", "cachedb_url", "redis://root:root@127.0.0.1/") -... - - -
-
- <varname>db_prefix</varname> (string) - - Specifies what prefix should be added to the pipe name. This is - only used when distributed rate limiting is enabled. - - - - Default value is "rl_pipe_". - - - - Set <varname>db_prefix</varname> parameter - -... -modparam("ratelimit", "db_prefix", "ratelimit_") -... - - -
-
- <varname>repl_buffer_threshold</varname> (string) - - Used to specify the length of the buffer used by the binary - replication, in bytes, when a flush should be performed - the pipes - gathered until then should be sent on the network. This is used - to avoid using large amount of memory for pipes replication. - - - - Default value is 32767 bytes. - - - - Set <varname>repl_buffer_threshold</varname> parameter - -... -modparam("ratelimit", "repl_buffer_threshold", 500) -... - - -
-
- <varname>repl_timer_interval</varname> (string) - - Timer in milliseconds, used to specify how often the module - should replicate its counters to the other instances. - - - - Default value is 200 ms. - - - - Set <varname>repl_timer_interval</varname> parameter - -... -modparam("ratelimit", "repl_timer_interval", 100) -... - - -
-
- <varname>repl_timer_expire</varname> (string) - - Timer in seconds, used to specify when the counter received - from a different instance should no longer be taken into account. - This is used to prevent obsolete values, in case an instance stops - replicating its counters. - - - - Default value is 10 s. - - - - Set <varname>repl_timer_expire</varname> parameter - -... -modparam("ratelimit", "repl_timer_expire", 10) -... - - -
-
- <varname>pipe_replication_cluster</varname> (integer) - - Specifies the cluster ID where pipes will be replicated to and - received from. - - - - Default value is 0. (no replication) - - - - Set <varname>pipe_replication_cluster</varname> parameter - -... -modparam("ratelimit", "pipe_replication_cluster", 1) -... - - -
- -
- <varname>window_size</varname> (int) - - How long the history in SBT should be in seconds. - - - - Default value is 10. - - - - Set <varname>window_size</varname> parameter - -... -modparam("ratelimit", "window_size", 5) -... - - -
- -
- <varname>slot_period</varname> (int) - - Value of one slot in milliseconds. This parameter determines - how granular the algorithm should be. The number of slots will be - determined by window_size/slot_period. - - - - Default value is 200. - - - - Set <varname>slot_period</varname> parameter - -... -modparam("ratelimit", "window_size", 5) -#we will have 50 slots of 100 milliseconds -modparam("ratelimit", "slot_period", 100) -... - - -
- - - -
-
- Exported Functions -
- - <function moreinfo="none">rl_check(name, limit[, algorithm]) - </function> - - - Check the current request against the pipe identified by name and - changes/updates the limit. If no pipe is found, then a new one is - created with the specified limit and algorithm, if specified. If the - algorithm parameter doesn't exist, the default one is used. - - - NOTE: A pipe's algorithm cannot be dynamically changed. Only the one - specified when the pipe was created will be considered. - - - NOTE: This function increments the pipe's counter every time it is - called, even if the call should be declined. Therefore If you are using - ratelimit to limit only successful traffic, you need to explicitely - decrease the counter for the declined calls using the - rl_dec_count() function. - - - The method will return an error code if the limit for the - matched pipe is reached. - - Meaning of the parameters is as follows: - - - - name (string) - this is the name that identifies - the pipe which should be checked. One can also specify the - /s suffix to indicate the pipe - should be replicated over cached, or /b - to replicate over bin/clusterer interface. - - - - - limit (int) - this specifies the threshold - limit of the pipe. It is strongly related to the algorithm - used. Note that the limit should be specified as per-second, not - per-timer_interval. - - - - - algorithm (string, optional) - this parameter - reffers to the algorithm used to check the pipe. If it is - not set, the default value is used. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. - - - <function>rl_check</function> usage - -... - # perform a pipe match for all INVITE methods using RED algorithm - if (is_method("INVITE")) { - if (!rl_check("pipe_INVITE", 100, "RED")) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; - }; -... - # use default algorithm for each different gateway - $var(limit) = 10; - if (!rl_check("gw_$ru", $var(limit))) { - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - # count only successful calls - if (!rl_check("gw_$ru", 100)) { - rl_dec_count("gw_$ru"); - sl_send_reply(503, "Server Unavailable"); - exit; - }; -... - - -
-
- - <function moreinfo="none">rl_dec_count(name)</function> - - - This function decreases a counter that could have been previously - increased by rl_check function. - - Meaning of the parameters is as follows: - - - name (string) - identifies the name of the pipe. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. - - - <function>rl_dec_count</function> usage - -... - if (!rl_check("gw_$ru", 100, "TAILDROP")) { - exit; - } else { - rl_dec_count("gw_$ru"); - }; -... - - -
-
- - <function moreinfo="none">rl_reset_count(name)</function> - - - This function resets a counter that could have been previously - increased by rl_check function. - - Meaning of the parameters is as follows: - - - name - identifies the name of the pipe. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE, ERROR_ROUTE, LOCAL_ROUTE, TIMER_ROUTE and EVENT_ROUTE. - - - <function>rl_reset_count</function> usage - -... - if (!rl_check("gw_$ru", 100, "TAILDROP")) { - exit; - } else { - rl_reset_count("gw_$ru"); - }; -... - - -
-
- - <function moreinfo="none">rl_values(ret_avp, regexp)</function> - - - Returns all the available pipes' names in the ret_avp - output variable. - - Meaning of the parameters is as follows: - - - ret_avp (string) - an AVP where the pipes' - names will be stored. - - - - regexp (regex, optional) - a regular expression - used to filter the names of the pipes. If missing, all the pipes - are returned. - - - - - This function can be used from any route. - - - <function>rl_values</function> usage - -... - rl_values($avp(values)); - for ($var(pipe) in $(avp(values)[*])) - xlog("RATELIMIT: $var(pipe): $rl_count($var(pipe))\n"); -... - - -
- -
- -
- Exported MI Functions -
- - <function moreinfo="none">rl_list</function> - - - Lists the parameters and variabiles in the ratelimit module. - - - Name: rl_list - - Parameters: - - - pipe (optional) - indicates the name of the - single pipe to be listed. - - - filter (optional) - a pattern used to filter - the active pipes to be listed. The filter is a shell wildcard - pattern (see glob(7)). - - - filter_out (optional) - a pattern used to - filter out the active pipes NOT to be listed. - The filter is a shell wildcard pattern (see glob(7)). - - - - Note that you cannot combine multiple paramters when calling this - function. If using parameters, only one is accepted. - - - If no parameter are passed to the function, all the active pipes - are listed. - - - MI FIFO Command Format: - - - opensips-cli -x mi rl_list pipe=gw_10.0.0.1 - opensips-cli -x mi rl_list filter=gw_* - -
-
- - <function moreinfo="none">rl_dump_pipe</function> - - - Exposes all the details about the current runtime data (specific to the - pipe's algorithm) of a pipe. Currently make sense for SBT. - - - Name: rl_dump_pipe - - Parameters: - - - pipe - indicates the name of the pipe. - - - - MI FIFO Command Format: - - - opensips-cli -x mi rl_dump_pipe gw_10.0.0.1 - -
-
- - <function moreinfo="none">rl_reset_pipe</function> - - - Resets the counter of a specified pipe. - - - Name: rl_reset_pipe - - Parameters: - - - pipe - indicates the name of the pipe whose - counter should be reset. - - - - MI FIFO Command Format: - - - opensips-cli -x mi rl_reset_pipe gw_10.0.0.1 - -
-
- - <function moreinfo="none">rl_set_pid</function> - - - Sets the PID Controller parameters for the Feedback Algorithm. - - - Name: rl_set_pid - - Parameters: - - - ki - the integral parameter. - - - kp - the proportional parameter. - - - kd - the derivative parameter. - - - - MI FIFO Command Format: - - - opensips-cli -x mi rl_set_pid 0.5 0.5 0.5 - -
-
- - <function moreinfo="none">rl_get_pid</function> - - - Gets the list of in use PID Controller parameters. - - - Name: rl_get_pid - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi rl_get_pid - -
-
- - <function moreinfo="none">rl_bin_status</function> - - - Dumps each destination used for replication, as well as - the timestamp of the last message received from them. - - - Name: rl_bin_status - - Parameters: none - - MI FIFO Command Format: - - - opensips-cli -x mi rl_bin_status - -
-
- -
- Exported Pseudo-Variables - -
- <varname>$rl_count(name)</varname> - - Returns the counter of a pipe. The variable is read-only. - - - NULL will be returned if the pipe does not exist. - -
- -
-
- diff --git a/modules/regex/Makefile b/modules/regex/Makefile index 79a15083959..d09aa245bce 100644 --- a/modules/regex/Makefile +++ b/modules/regex/Makefile @@ -8,12 +8,16 @@ NAME=regex.so # the autodetection # CROSS_COMPILE=true +PCRE_LIB ?= pcre2-8 +PCRE_VERSION ?= $(word 1,$(subst -, , $(PCRE_LIB))) +PCRE_CONFIG ?= $(PCRE_VERSION)-config + ifeq ($(CROSS_COMPILE),) PCRE_BUILDER := $(shell \ - if which pcre-config >/dev/null 2>/dev/null; then \ - echo 'pcre-config'; \ - elif pkg-config --exists libcre; then \ - echo 'pkg-config libpcre'; \ + if which $(PCRE_CONFIG) >/dev/null 2>/dev/null; then \ + echo '$(PCRE_CONFIG)'; \ + elif pkg-config --exists lib$(PCRE_LIB); then \ + echo 'pkg-config lib$(PCRE_LIB)'; \ fi) endif @@ -21,10 +25,12 @@ ifeq ($(PCRE_BUILDER),) DEFS += -I$(SYSBASE)/include \ -I$(LOCALBASE)/include LIBS += -L$(SYSBASE)/lib \ - -L$(LOCALBASE)/lib -lpcre + -L$(LOCALBASE)/lib -l$(PCRE_LIB) else DEFS += $(shell $(PCRE_BUILDER) --cflags) - LIBS += $(shell $(PCRE_BUILDER) --libs) + LIBS += $(shell $(PCRE_BUILDER) --libs 2>/dev/null) \ + $(shell $(PCRE_BUILDER) --libs$(word 2,$(subst -, ,$(PCRE_LIB))) 2>/dev/null) endif +DEFS += -D$(shell echo $(PCRE_VERSION) | tr 'a-z' 'A-Z')_LIB include ../../Makefile.modules diff --git a/modules/regex/README b/modules/regex/README deleted file mode 100644 index 292407e96a3..00000000000 --- a/modules/regex/README +++ /dev/null @@ -1,492 +0,0 @@ -Regex Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. file (string) - 1.3.2. max_groups (int) - 1.3.3. group_max_size (int) - 1.3.4. pcre_caseless (int) - 1.3.5. pcre_multiline (int) - 1.3.6. pcre_dotall (int) - 1.3.7. pcre_extended (int) - - 1.4. Exported Functions - - 1.4.1. pcre_match (string, pcre_regex) - 1.4.2. pcre_match_group (string [, group]) - - 1.5. Exported MI Functions - - 1.5.1. regex_reload - 1.5.2. regex_match - 1.5.3. regex_match_group - - 1.6. Installation and Running - - 1.6.1. File format - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set file parameter - 1.2. Set max_groups parameter - 1.3. Set group_max_size parameter - 1.4. Set pcre_caseless parameter - 1.5. Set pcre_multiline parameter - 1.6. Set pcre_dotall parameter - 1.7. Set pcre_extended parameter - 1.8. pcre_match usage (forcing case insensitive) - 1.9. pcre_match usage (using "end of line" symbol) - 1.10. pcre_match_group usage - 1.11. regex file - 1.12. Using with pua_usrloc - 1.13. Incorrect groups file - -Chapter 1. Admin Guide - -1.1. Overview - - This module offers matching operations against regular - expressions using the powerful PCRE library. - - A text file containing regular expressions categorized in - groups is compiled when the module is loaded, storing the - compiled PCRE objects in an array. A function to match a string - or pseudo-variable against any of these groups is provided. The - text file can be modified and reloaded at any time via a MI - command. The module also offers a function to perform a PCRE - matching operation against a regular expression provided as - function parameter. - - For a detailed list of PCRE features read the man page of the - library. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libpcre-dev - the development libraries of PCRE. - -1.3. Exported Parameters - -1.3.1. file (string) - - Text file containing the regular expression groups. It must be - set in order to enable the group matching function. - - Default value is “NULL”. - - Example 1.1. Set file parameter -... -modparam("regex", "file", "/etc/opensips/regex_groups") -... - -1.3.2. max_groups (int) - - Max number of regular expression groups in the text file. - - Default value is “20”. - - Example 1.2. Set max_groups parameter -... -modparam("regex", "max_groups", 40) -... - -1.3.3. group_max_size (int) - - Max content size of a group in the text file. - - Default value is “8192”. - - Example 1.3. Set group_max_size parameter -... -modparam("regex", "group_max_size", 16384) -... - -1.3.4. pcre_caseless (int) - - If this options is set, matching is done caseless. It is - equivalent to Perl's /i option, and it can be changed within a - pattern by a (?i) or (?-i) option setting. - - Default value is “0”. - - Example 1.4. Set pcre_caseless parameter -... -modparam("regex", "pcre_caseless", 1) -... - -1.3.5. pcre_multiline (int) - - By default, PCRE treats the subject string as consisting of a - single line of characters (even if it actually contains - newlines). The "start of line" metacharacter (^) matches only - at the start of the string, while the "end of line" - metacharacter ($) matches only at the end of the string, or - before a terminating newline. - - When this option is set, the "start of line" and "end of line" - constructs match immediately following or immediately before - internal newlines in the subject string, respectively, as well - as at the very start and end. This is equivalent to Perl's /m - option, and it can be changed within a pattern by a (?m) or - (?-m) option setting. If there are no newlines in a subject - string, or no occurrences of ^ or $ in a pattern, setting this - option has no effect. - - Default value is “0”. - - Example 1.5. Set pcre_multiline parameter -... -modparam("regex", "pcre_multiline", 1) -... - -1.3.6. pcre_dotall (int) - - If this option is set, a dot metacharater in the pattern - matches all characters, including those that indicate newline. - Without it, a dot does not match when the current position is - at a newline. This option is equivalent to Perl's /s option, - and it can be changed within a pattern by a (?s) or (?-s) - option setting. - - Default value is “0”. - - Example 1.6. Set pcre_dotall parameter -... -modparam("regex", "pcre_dotall", 1) -... - -1.3.7. pcre_extended (int) - - If this option is set, whitespace data characters in the - pattern are totally ignored except when escaped or inside a - character class. Whitespace does not include the VT character - (code 11). In addition, characters between an unescaped # - outside a character class and the next newline, inclusive, are - also ignored. This is equivalent to Perl's /x option, and it - can be changed within a pattern by a (?x) or (?-x) option - setting. - - Default value is “0”. - - Example 1.7. Set pcre_extended parameter -... -modparam("regex", "pcre_extended", 1) -... - -1.4. Exported Functions - -1.4.1. pcre_match (string, pcre_regex) - - Matches the given string parameter against the regular - expression pcre_regex, which is compiled into a PCRE object. - Returns TRUE if it matches, FALSE otherwise. - - Meaning of the parameters is as follows: - * string - String to compare. - * pcre_regex (string) - Regular expression to be compiled in - a PCRE object. - - NOTE: To use the "end of line" symbol '$' in the pcre_regex - parameter use '$$'. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.8. pcre_match usage (forcing case insensitive) -... -if (pcre_match("$ua", "(?i)^twinkle")) { - xlog("L_INFO", "User-Agent matches\n"); -} -... - - Example 1.9. pcre_match usage (using "end of line" symbol) -... -if (pcre_match($rU, "^user[1234]$$")) { # Will be converted to "^user[1 -234]$" - xlog("L_INFO", "RURI username matches\n"); -} -... - -1.4.2. pcre_match_group (string [, group]) - - It uses the groups readed from the text file (see - Section 1.6.1, “File format”) to match the given string - parameter against the compiled regular expression in group - number group. Returns TRUE if it matches, FALSE otherwise. - - Meaning of the parameters is as follows: - * string - String to compare. - * group (int) - group to use in the operation. If not - specified then 0 (the first group) is used. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.10. pcre_match_group usage -... -if (pcre_match_group($rU, 2)) { - xlog("L_INFO", "RURI username matches group 2\n"); -} -... - -1.5. Exported MI Functions - -1.5.1. regex_reload - - Causes regex module to re-read the content of the text file and - re-compile the regular expressions. The number of groups in the - file can be modified safely. - - Name: regex_reload - - Parameters: none - - MI FIFO Command Format: -... -opensips-cli -x mi regex_reload -... - -1.5.2. regex_match - - Matches the given string parameter against the regular - expression pcre_regex. Returns "Match" if it matches, "Not - Match" otherwise. - - Name: regex_match - - Parameters: - * string - * pcre_regex - - MI FIFO Command Format: -... -opensips-cli -x mi regex_match string="1234" pcre_regex="^1234$" -"Match" -opensips-cli -x mi regex_match string="1234" pcre_regex="^1235$" -"Not Match" -... - -1.5.3. regex_match_group - - It uses the groups readed from the text file to match the given - string parameter against the compiled regular expression in - group number group. Returns "Match" if it matches, "Not Match" - otherwise. - - Name: regex_match_group - - Parameters: - * string - * group - - MI FIFO Command Format: -... -opensips-cli -x mi regex_match_group string="1234" group="0" -"Match" -opensips-cli -x mi regex_match_group string="1234" group="1" -"Not Match" -... - -1.6. Installation and Running - -1.6.1. File format - - The file contains regular expressions categorized in groups. - Each group starts with "[number]" line. Lines starting by - space, tab, CR, LF or # (comments) are ignored. Each regular - expression must take up just one line, this means that a - regular expression can't be splitted in various lines. - - An example of the file format would be the following: - - Example 1.11. regex file -### List of User-Agents publishing presence status -[0] - -# Softphones -^Twinkle/1 -^X-Lite -^eyeBeam -^Bria -^SIP Communicator -^Linphone - -# Deskphones -^Snom - -# Others -^SIPp -^PJSUA - - -### Blacklisted source IP's -[1] - -^190\.232\.250\.226$ -^122\.5\.27\.125$ -^86\.92\.112\. - - -### Free PSTN destinations in Spain -[2] - -^1\d{3}$ -^((\+|00)34)?900\d{6}$ - - The module compiles the text above to the following regular - expressions: -group 0: ((^Twinkle/1)|(^X-Lite)|(^eyeBeam)|(^Bria)|(^SIP Communicator)| - (^Linphone)|(^Snom)|(^SIPp)|(^PJSUA)) -group 1: ((^190\.232\.250\.226$)|(^122\.5\.27\.125$)|(^86\.92\.112\.)) -group 2: ((^1\d{3}$)|(^((\+|00)34)?900\d{6}$)) - - The first group can be used to avoid auto-generated PUBLISH - (pua_usrloc module) for UA's already supporting presence: - - Example 1.12. Using with pua_usrloc -route[REGISTER] { - if (! pcre_match_group("$ua", 0)) { - xlog("L_INFO", "Auto-generated PUBLISH for $fu ($ua)\n"); - pua_set_publish(); - } - save("location"); - exit; -} - - NOTE: It's important to understand that the numbers in each - group header ([number]) must start by 0. If not, the real group - number will not match the number appearing in the file. For - example, the following text file: - - Example 1.13. Incorrect groups file -[1] -^aaa -^bbb - -[2] -^ccc -^ddd - - will generate the following regular expressions: -group 0: ((^aaa)|(^bbb)) -group 1: ((^ccc)|(^ddd)) - - Note that the real index doesn't match the group number in the - file. This is, compiled group 0 always points to the first - group in the file, regardless of its number in the file. In - fact, the group number appearing in the file is used for - nothing but for delimiting different groups. - - NOTE: A line containing a regular expression cannot start by - '[' since it would be treated as a new group. The same for - lines starting by space, tab, or '#' (they would be ignored by - the parser). As a workaround, using brackets would work: -[0] -([0-9]{9}) -( #abcde) -( qwerty) - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Iñaki Baz Castillo 15 3 1242 2 - 2. Razvan Crainea (@razvancrainea) 14 12 43 26 - 3. Liviu Chircu (@liviuchircu) 12 10 25 42 - 4. Vlad Patrascu (@rvlad-patrascu) 9 6 63 88 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 12 7 - 6. MonkeyTester 6 3 188 14 - 7. Norman Brandinger (@NormB) 5 3 4 4 - 8. Sergio Gutierrez 3 1 19 1 - 9. Ovidiu Sas (@ovidiusas) 3 1 13 11 - 10. Anca Vamanu 3 1 6 3 - - All remaining contributors: Maksym Sobolyev (@sobomax), Ken - Rice, Marius Zbihlei. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Razvan Crainea (@razvancrainea) Sep 2011 - Aug 2023 - 3. MonkeyTester Aug 2023 - Aug 2023 - 4. Norman Brandinger (@NormB) Apr 2023 - Apr 2023 - 5. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2009 - Apr 2019 - 8. Liviu Chircu (@liviuchircu) Mar 2014 - Nov 2018 - 9. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - 10. Marius Zbihlei Sep 2010 - Sep 2010 - - All remaining contributors: Iñaki Baz Castillo, Anca Vamanu, - Sergio Gutierrez. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: MonkeyTester, Vlad Patrascu (@rvlad-patrascu), - Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), - Bogdan-Andrei Iancu (@bogdan-iancu), Iñaki Baz Castillo. - - Documentation Copyrights: - - Copyright © 2009 Iñaki Baz Castillo diff --git a/modules/regex/README.md b/modules/regex/README.md new file mode 100644 index 00000000000..09d619c29c3 --- /dev/null +++ b/modules/regex/README.md @@ -0,0 +1,480 @@ +--- +title: "Regex Module" +description: "This module offers matching operations against regular expressions using the powerful [PCRE](http://www.pcre.org/) library." +--- + +## Admin Guide + + +### Overview + + +This module offers matching operations against regular expressions using the +powerful [PCRE](http://www.pcre.org/) library. + + +A text file containing regular expressions categorized in groups is compiled +when the module is loaded, storing the compiled PCRE objects in an array. A +function to match a string or pseudo-variable against any of these groups is +provided. The text file can be modified and reloaded at any time via a MI command. +The module also offers a function to perform a PCRE matching operation against a +regular expression provided as function parameter. + + +For a detailed list of PCRE features read the +[man page](http://www.pcre.org/pcre.txt) of the library. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libpcre-dev - the development libraries of [PCRE](http://www.pcre.org/)*. + + +### Exported Parameters + + +#### file (string) + + +Text file containing the regular expression groups. It must be set in order +to enable the group matching function. + + +*Default value is "NULL".* + + +```opensips title="Set file parameter" +... +modparam("regex", "file", "/etc/opensips/regex_groups") +... +``` + + +#### max_groups (int) + + +Max number of regular expression groups in the text file. + + +*Default value is "20".* + + +```opensips title="Set max_groups parameter" +... +modparam("regex", "max_groups", 40) +... +``` + + +#### group_max_size (int) + + +Max content size of a group in the text file. + + +*Default value is "8192".* + + +```opensips title="Set group_max_size parameter" +... +modparam("regex", "group_max_size", 16384) +... +``` + + +#### pcre_caseless (int) + + +If this options is set, matching is done caseless. It is equivalent to +Perl's /i option, and it can be changed within a pattern by a (?i) or +(?-i) option setting. + + +*Default value is "0".* + + +```opensips title="Set pcre_caseless parameter" +... +modparam("regex", "pcre_caseless", 1) +... +``` + + +#### pcre_multiline (int) + + +By default, PCRE treats the subject string as consisting of a single line +of characters (even if it actually contains newlines). The "start of line" +metacharacter (^) matches only at the start of the string, while the "end +of line" metacharacter ($) matches only at the end of the string, or before +a terminating newline. + + +When this option is set, the "start of line" and "end of line" constructs +match immediately following or immediately before internal newlines in the +subject string, respectively, as well as at the very start and end. This is +equivalent to Perl's /m option, and it can be changed within a pattern by a +(?m) or (?-m) option setting. If there are no newlines in a subject string, +or no occurrences of ^ or $ in a pattern, setting this option has no effect. + + +*Default value is "0".* + + +```opensips title="Set pcre_multiline parameter" +... +modparam("regex", "pcre_multiline", 1) +... +``` + + +#### pcre_dotall (int) + + +If this option is set, a dot metacharater in the pattern matches all characters, +including those that indicate newline. Without it, a dot does not match when +the current position is at a newline. This option is equivalent to Perl's /s +option, and it can be changed within a pattern by a (?s) or (?-s) option setting. + + +*Default value is "0".* + + +```opensips title="Set pcre_dotall parameter" +... +modparam("regex", "pcre_dotall", 1) +... +``` + + +#### pcre_extended (int) + + +If this option is set, whitespace data characters in the pattern are totally +ignored except when escaped or inside a character class. Whitespace does not +include the VT character (code 11). In addition, characters between an +unescaped # outside a character class and the next newline, inclusive, are +also ignored. This is equivalent to Perl's /x option, and it can be changed +within a pattern by a (?x) or (?-x) option setting. + + +*Default value is "0".* + + +```opensips title="Set pcre_extended parameter" +... +modparam("regex", "pcre_extended", 1) +... +``` + + +### Exported Functions + + +#### pcre_match (string, pcre_regex) + + +Matches the given string parameter against the regular expression pcre_regex, +which is compiled into a PCRE object. Returns TRUE if it matches, FALSE +otherwise. + + +Meaning of the parameters is as follows: + + +- *string* - String to compare. +- *pcre_regex* (string) - Regular expression to be compiled +in a PCRE object. + + +> [!NOTE] +> To use the "end of line" symbol '$' in the pcre_regex parameter use '$$'. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="pcre_match usage (forcing case insensitive)" +... +if (pcre_match("$ua", "(?i)^twinkle")) { + xlog("L_INFO", "User-Agent matches\n"); +} +... +``` + + +```opensips title="pcre_match usage (using 'end of line' symbol)" +... +if (pcre_match($rU, "^user[1234]$$")) { # Will be converted to "^user[1234]$" + xlog("L_INFO", "RURI username matches\n"); +} +... +``` + + +#### pcre_match_group (string [, group]) + + +It uses the groups readed from the text file +(see [file format id](#file_format)) to match the given string +parameter against the compiled regular expression in group number group. +Returns TRUE if it matches, FALSE otherwise. + + +Meaning of the parameters is as follows: + + +- *string* - String to compare. +- *group* (int) - group to use in the operation. +If not specified then 0 (the first group) is used. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="pcre_match_group usage" +... +if (pcre_match_group($rU, 2)) { + xlog("L_INFO", "RURI username matches group 2\n"); +} +... +``` + + +### Exported MI Functions + + +#### regex_reload + + +Causes regex module to re-read the content of the text file +and re-compile the regular expressions. The number of groups +in the file can be modified safely. + + +Name: *regex_reload* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +... +opensips-cli -x mi regex_reload +... +``` + + +#### regex_match + + +Matches the given string parameter against the regular expression pcre_regex. +Returns "Match" if it matches, "Not Match" otherwise. + + +Name: *regex_match* + + +Parameters: + + +- string +- pcre_regex + + +MI FIFO Command Format: + + +```bash +... +opensips-cli -x mi regex_match string="1234" pcre_regex="^1234$" +"Match" +opensips-cli -x mi regex_match string="1234" pcre_regex="^1235$" +"Not Match" +... +``` + + +#### regex_match_group + + +It uses the groups readed from the text file to match the given string parameter against the compiled +regular expression in group number group. Returns "Match" if it matches, "Not Match" otherwise. + + +Name: *regex_match_group* + + +Parameters: + + +- string +- group + + +MI FIFO Command Format: + + +```bash +... +opensips-cli -x mi regex_match_group string="1234" group="0" +"Match" +opensips-cli -x mi regex_match_group string="1234" group="1" +"Not Match" +... +``` + + +### Installation and Running + + +#### File format + + +The file contains regular expressions categorized in groups. Each +group starts with "[number]" line. Lines starting by space, tab, +CR, LF or # (comments) are ignored. Each regular expression must +take up just one line, this means that a regular expression can't +be splitted in various lines. + + +An example of the file format would be the following: + + +```c title="regex file" +### List of User-Agents publishing presence status +[0] + +# Softphones +^Twinkle/1 +^X-Lite +^eyeBeam +^Bria +^SIP Communicator +^Linphone + +# Deskphones +^Snom + +# Others +^SIPp +^PJSUA + + +### Blacklisted source IP's +[1] + +^190\.232\.250\.226$ +^122\.5\.27\.125$ +^86\.92\.112\. + + +### Free PSTN destinations in Spain +[2] + +^1\d{3}$ +^((\+|00)34)?900\d{6}$ +``` + + +The module compiles the text above to the following regular +expressions: + + +```c +group 0: ((^Twinkle/1)|(^X-Lite)|(^eyeBeam)|(^Bria)|(^SIP Communicator)| + (^Linphone)|(^Snom)|(^SIPp)|(^PJSUA)) +group 1: ((^190\.232\.250\.226$)|(^122\.5\.27\.125$)|(^86\.92\.112\.)) +group 2: ((^1\d{3}$)|(^((\+|00)34)?900\d{6}$)) +``` + + +The first group can be used to avoid auto-generated PUBLISH (pua_usrloc +module) for UA's already supporting presence: + + +```opensips title="Using with pua_usrloc" +route[REGISTER] { + if (! pcre_match_group("$ua", 0)) { + xlog("L_INFO", "Auto-generated PUBLISH for $fu ($ua)\n"); + pua_set_publish(); + } + save("location"); + exit; +} +``` + + +> [!NOTE] +> It's important to understand that the numbers in each group +> header ([number]) must start by 0. If not, the real group number +> will not match the number appearing in the file. For example, the +> following text file: + + +```c title="Incorrect groups file" +[1] +^aaa +^bbb + +[2] +^ccc +^ddd +``` + + +will generate the following regular expressions: + + +```c +group 0: ((^aaa)|(^bbb)) +group 1: ((^ccc)|(^ddd)) +``` + + +> [!NOTE] +> The real index doesn't match the group number in the file. This +> is, compiled group 0 always points to the first group in the file, regardless +> of its number in the file. In fact, the group number appearing in the file is +> used for nothing but for delimiting different groups. + + +> [!NOTE] +> A line containing a regular expression cannot start by '[' since it +> would be treated as a new group. The same for lines starting by space, tab, +> or '#' (they would be ignored by the parser). As a workaround, using brackets +> would work: + + ```c + [0] + ([0-9]{9}) + ( #abcde) + ( qwerty) + ``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/regex/doc/contributors.xml b/modules/regex/doc/contributors.xml deleted file mode 100644 index f514700cd0f..00000000000 --- a/modules/regex/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Iñaki Baz Castillo - 15 - 3 - 1242 - 2 - - - 2. - Razvan Crainea (@razvancrainea) - 14 - 12 - 43 - 26 - - - 3. - Liviu Chircu (@liviuchircu) - 12 - 10 - 25 - 42 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 9 - 6 - 63 - 88 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 12 - 7 - - - 6. - MonkeyTester - 6 - 3 - 188 - 14 - - - 7. - Norman Brandinger (@NormB) - 5 - 3 - 4 - 4 - - - 8. - Sergio Gutierrez - 3 - 1 - 19 - 1 - - - 9. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 13 - 11 - - - 10. - Anca Vamanu - 3 - 1 - 6 - 3 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Ken Rice, Marius Zbihlei. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Sep 2011 - Aug 2023 - - - 3. - MonkeyTester - Aug 2023 - Aug 2023 - - - 4. - Norman Brandinger (@NormB) - Apr 2023 - Apr 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2009 - Apr 2019 - - - 8. - Liviu Chircu (@liviuchircu) - Mar 2014 - Nov 2018 - - - 9. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - 10. - Marius Zbihlei - Sep 2010 - Sep 2010 - - - -
-All remaining contributors: Iñaki Baz Castillo, Anca Vamanu, Sergio Gutierrez. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: MonkeyTester, Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Iñaki Baz Castillo. -
- -
diff --git a/modules/regex/doc/regex.xml b/modules/regex/doc/regex.xml deleted file mode 100644 index 69ab27122e4..00000000000 --- a/modules/regex/doc/regex.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Regex Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 Iñaki Baz Castillo - - - - diff --git a/modules/regex/doc/regex_admin.xml b/modules/regex/doc/regex_admin.xml deleted file mode 100644 index 56a64a4cb47..00000000000 --- a/modules/regex/doc/regex_admin.xml +++ /dev/null @@ -1,582 +0,0 @@ - - - - - &adminguide; - -
- Overview - - - This module offers matching operations against regular expressions using the - powerful PCRE library. - - - - A text file containing regular expressions categorized in groups is compiled - when the module is loaded, storing the compiled PCRE objects in an array. A - function to match a string or pseudo-variable against any of these groups is - provided. The text file can be modified and reloaded at any time via a MI command. - The module also offers a function to perform a PCRE matching operation against a - regular expression provided as function parameter. - - - - For a detailed list of PCRE features read the - man page of the library. - - -
- -
- - Dependencies - -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other OpenSIPS modules. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libpcre-dev - the development libraries of PCRE. - - - - -
- -
- -
- Exported Parameters - -
- <varname>file</varname> (string) - - Text file containing the regular expression groups. It must be set in order - to enable the group matching function. - - - Default value is NULL. - - - Set <varname>file</varname> parameter - -... -modparam("regex", "file", "/etc/opensips/regex_groups") -... - - -
- -
- <varname>max_groups</varname> (int) - - Max number of regular expression groups in the text file. - - - Default value is 20. - - - Set <varname>max_groups</varname> parameter - -... -modparam("regex", "max_groups", 40) -... - - -
- -
- <varname>group_max_size</varname> (int) - - Max content size of a group in the text file. - - - Default value is 8192. - - - Set <varname>group_max_size</varname> parameter - -... -modparam("regex", "group_max_size", 16384) -... - - -
- -
- <varname>pcre_caseless</varname> (int) - - If this options is set, matching is done caseless. It is equivalent to - Perl's /i option, and it can be changed within a pattern by a (?i) or - (?-i) option setting. - - - Default value is 0. - - - Set <varname>pcre_caseless</varname> parameter - -... -modparam("regex", "pcre_caseless", 1) -... - - -
- -
- <varname>pcre_multiline</varname> (int) - - By default, PCRE treats the subject string as consisting of a single line - of characters (even if it actually contains newlines). The "start of line" - metacharacter (^) matches only at the start of the string, while the "end - of line" metacharacter ($) matches only at the end of the string, or before - a terminating newline. - - - When this option is set, the "start of line" and "end of line" constructs - match immediately following or immediately before internal newlines in the - subject string, respectively, as well as at the very start and end. This is - equivalent to Perl's /m option, and it can be changed within a pattern by a - (?m) or (?-m) option setting. If there are no newlines in a subject string, - or no occurrences of ^ or $ in a pattern, setting this option has no effect. - - - Default value is 0. - - - Set <varname>pcre_multiline</varname> parameter - -... -modparam("regex", "pcre_multiline", 1) -... - - -
- -
- <varname>pcre_dotall</varname> (int) - - If this option is set, a dot metacharater in the pattern matches all characters, - including those that indicate newline. Without it, a dot does not match when - the current position is at a newline. This option is equivalent to Perl's /s - option, and it can be changed within a pattern by a (?s) or (?-s) option setting. - - - Default value is 0. - - - Set <varname>pcre_dotall</varname> parameter - -... -modparam("regex", "pcre_dotall", 1) -... - - -
- -
- <varname>pcre_extended</varname> (int) - - If this option is set, whitespace data characters in the pattern are totally - ignored except when escaped or inside a character class. Whitespace does not - include the VT character (code 11). In addition, characters between an - unescaped # outside a character class and the next newline, inclusive, are - also ignored. This is equivalent to Perl's /x option, and it can be changed - within a pattern by a (?x) or (?-x) option setting. - - - Default value is 0. - - - Set <varname>pcre_extended</varname> parameter - -... -modparam("regex", "pcre_extended", 1) -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">pcre_match (string, pcre_regex)</function> - - - - Matches the given string parameter against the regular expression pcre_regex, - which is compiled into a PCRE object. Returns TRUE if it matches, FALSE - otherwise. - - - Meaning of the parameters is as follows: - - - - - string - String to compare. - - - - - pcre_regex (string) - Regular expression to be compiled - in a PCRE object. - - - - - - NOTE: To use the "end of line" symbol '$' in the pcre_regex parameter use '$$'. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - - <function>pcre_match</function> usage (forcing case insensitive) - - -... -if (pcre_match("$ua", "(?i)^twinkle")) { - xlog("L_INFO", "User-Agent matches\n"); -} -... - - - - - - <function>pcre_match</function> usage (using "end of line" symbol) - - -... -if (pcre_match($rU, "^user[1234]$$")) { # Will be converted to "^user[1234]$" - xlog("L_INFO", "RURI username matches\n"); -} -... - - - -
- -
- - <function moreinfo="none">pcre_match_group (string [, group])</function> - - - - It uses the groups readed from the text file - (see ) to match the given string - parameter against the compiled regular expression in group number group. - Returns TRUE if it matches, FALSE otherwise. - - - Meaning of the parameters is as follows: - - - - - string - String to compare. - - - - - group (int) - group to use in the operation. - If not specified then 0 (the first group) is used. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - - - <function>pcre_match_group</function> usage - - -... -if (pcre_match_group($rU, 2)) { - xlog("L_INFO", "RURI username matches group 2\n"); -} -... - - - -
- -
- -
- Exported MI Functions - -
- - <function moreinfo="none">regex_reload</function> - - - - Causes regex module to re-read the content of the text file - and re-compile the regular expressions. The number of groups - in the file can be modified safely. - - - - Name: regex_reload - - - Parameters: none - - - MI FIFO Command Format: - - - -... -opensips-cli -x mi regex_reload -... - -
- -
- - <function moreinfo="none">regex_match</function> - - - - Matches the given string parameter against the regular expression pcre_regex. - Returns "Match" if it matches, "Not Match" otherwise. - - - - Name: regex_match - - - Parameters: - - string - - pcre_regex - - - - MI FIFO Command Format: - - - -... -opensips-cli -x mi regex_match string="1234" pcre_regex="^1234$" -"Match" -opensips-cli -x mi regex_match string="1234" pcre_regex="^1235$" -"Not Match" -... - -
- -
- - <function moreinfo="none">regex_match_group</function> - - - - It uses the groups readed from the text file to match the given string parameter against the compiled - regular expression in group number group. Returns "Match" if it matches, "Not Match" otherwise. - - - - Name: regex_match_group - - - Parameters: - - string - - group - - - - MI FIFO Command Format: - - - -... -opensips-cli -x mi regex_match_group string="1234" group="0" -"Match" -opensips-cli -x mi regex_match_group string="1234" group="1" -"Not Match" -... - -
- -
- -
- Installation and Running - -
- File format - - - The file contains regular expressions categorized in groups. Each - group starts with "[number]" line. Lines starting by space, tab, - CR, LF or # (comments) are ignored. Each regular expression must - take up just one line, this means that a regular expression can't - be splitted in various lines. - - - - An example of the file format would be the following: - - - - regex file - -### List of User-Agents publishing presence status -[0] - -# Softphones -^Twinkle/1 -^X-Lite -^eyeBeam -^Bria -^SIP Communicator -^Linphone - -# Deskphones -^Snom - -# Others -^SIPp -^PJSUA - - -### Blacklisted source IP's -[1] - -^190\.232\.250\.226$ -^122\.5\.27\.125$ -^86\.92\.112\. - - -### Free PSTN destinations in Spain -[2] - -^1\d{3}$ -^((\+|00)34)?900\d{6}$ - - - - - - The module compiles the text above to the following regular - expressions: - - - -group 0: ((^Twinkle/1)|(^X-Lite)|(^eyeBeam)|(^Bria)|(^SIP Communicator)| - (^Linphone)|(^Snom)|(^SIPp)|(^PJSUA)) -group 1: ((^190\.232\.250\.226$)|(^122\.5\.27\.125$)|(^86\.92\.112\.)) -group 2: ((^1\d{3}$)|(^((\+|00)34)?900\d{6}$)) - - - - The first group can be used to avoid auto-generated PUBLISH (pua_usrloc - module) for UA's already supporting presence: - - - - Using with pua_usrloc - -route[REGISTER] { - if (! pcre_match_group("$ua", 0)) { - xlog("L_INFO", "Auto-generated PUBLISH for $fu ($ua)\n"); - pua_set_publish(); - } - save("location"); - exit; -} - - - - - NOTE: It's important to understand that the numbers in each group - header ([number]) must start by 0. If not, the real group number - will not match the number appearing in the file. For example, the - following text file: - - - - Incorrect groups file - -[1] -^aaa -^bbb - -[2] -^ccc -^ddd - - - - - will generate the following regular expressions: - - - -group 0: ((^aaa)|(^bbb)) -group 1: ((^ccc)|(^ddd)) - - - - Note that the real index doesn't match the group number in the file. This - is, compiled group 0 always points to the first group in the file, regardless - of its number in the file. In fact, the group number appearing in the file is - used for nothing but for delimiting different groups. - - - - NOTE: A line containing a regular expression cannot start by '[' since it - would be treated as a new group. The same for lines starting by space, tab, - or '#' (they would be ignored by the parser). As a workaround, using brackets - would work: - - - -[0] -([0-9]{9}) -( #abcde) -( qwerty) - - -
- -
- -
diff --git a/modules/regex/regex_mod.c b/modules/regex/regex_mod.c index 59d5a6724cb..b2be5378e5b 100644 --- a/modules/regex/regex_mod.c +++ b/modules/regex/regex_mod.c @@ -24,6 +24,7 @@ * 2009-01-14 initial version (Iñaki Baz Castillo) * 2023-08-12 export pcres_match to MI (Fabien Aunay) * 2023-08-12 export pcres_match_group to MI (Fabien Aunay) + * 2025-09-17 switch to libpcre2 (Steven Ayre) */ @@ -39,7 +40,38 @@ #include #include #include +#ifdef PCRE2_LIB +#define PCRE2_CODE_UNIT_WIDTH 8 +#define PCRE2_ERR int +#include +#else +#define pcre2_code pcre +#define PCRE2_SIZE int +#define PCRE2_ERR const char * +#define PCRE2_CASELESS PCRE_CASELESS +#define PCRE2_MULTILINE PCRE_MULTILINE +#define PCRE2_DOTALL PCRE_DOTALL +#define PCRE2_EXTENDED PCRE_EXTENDED +#define PCRE2_ERROR_NOMATCH PCRE_ERROR_NOMATCH +#define PCRE2_UCHAR unsigned char +#define PCRE2_SPTR char * +#define PCRE2_INFO_SIZE PCRE_INFO_SIZE +#define PCRE2_INFO_CAPTURECOUNT PCRE_INFO_CAPTURECOUNT +#define pcre2_pattern_info(subst_comp, flag, ret) \ + pcre_fullinfo(subst_comp, NULL, flag, ret) +#define pcre2_compile(pattern, _, flags, error, erroffset, ctx) \ + pcre_compile(pattern, flags, error, erroffset, NULL) +#define pcre2_code_free pcre_free +#define pcre2_get_error_message(error, error_str, error_str_len) \ + do { \ + int _len = strlen(error); \ + if (_len > error_str_len - 1) \ + _len = error_str_len - 1; \ + memcpy(error_str, error, _len); \ + error_str[_len] = '\0'; \ + } while (0) #include +#endif #include "../../sr_module.h" #include "../../dprint.h" #include "../../pt.h" @@ -56,6 +88,8 @@ #define MAX_GROUPS 20 /*!< Max number of groups */ #define GROUP_MAX_SIZE 8192 /*!< Max size of a group */ +#define ERROR_BUF_SIZE 100 + /* * Locking variables @@ -78,8 +112,8 @@ static int pcre_extended = 0; /* * Module internal parameter variables */ -static pcre **pcres; -static pcre ***pcres_addr; +static pcre2_code **pcres; +static pcre2_code ***pcres_addr; static int *num_pcres; static int pcre_options = 0x00000000; @@ -219,24 +253,24 @@ static int mod_init(void) /* PCRE options */ if (pcre_caseless != 0) { LM_DBG("PCRE CASELESS enabled\n"); - pcre_options = pcre_options | PCRE_CASELESS; + pcre_options = pcre_options | PCRE2_CASELESS; } if (pcre_multiline != 0) { LM_DBG("PCRE MULTILINE enabled\n"); - pcre_options = pcre_options | PCRE_MULTILINE; + pcre_options = pcre_options | PCRE2_MULTILINE; } if (pcre_dotall != 0) { LM_DBG("PCRE DOTALL enabled\n"); - pcre_options = pcre_options | PCRE_DOTALL; + pcre_options = pcre_options | PCRE2_DOTALL; } if (pcre_extended != 0) { LM_DBG("PCRE EXTENDED enabled\n"); - pcre_options = pcre_options | PCRE_EXTENDED; + pcre_options = pcre_options | PCRE2_EXTENDED; } LM_DBG("PCRE options: %i\n", pcre_options); /* Pointer to pcres */ - if ((pcres_addr = shm_malloc(sizeof(pcre **))) == 0) { + if ((pcres_addr = shm_malloc(sizeof(pcre2_code **))) == 0) { LM_ERR("no memory for pcres_addr\n"); goto err; } @@ -277,13 +311,14 @@ static int load_pcres(int action) FILE *f; char line[FILE_MAX_LINE]; char **patterns = NULL; - pcre *pcre_tmp = NULL; - int pcre_size; + pcre2_code *pcre_tmp = NULL; + size_t pcre_size; int pcre_rc; - const char *pcre_error; - int pcre_erroffset; + PCRE2_ERR pcre_error; + PCRE2_UCHAR pcre_error_str[ERROR_BUF_SIZE]; + PCRE2_SIZE pcre_erroffset; int num_pcres_tmp = 0; - pcre **pcres_tmp = NULL; + pcre2_code **pcres_tmp = NULL; /* Get the lock */ lock_get(reload_lock); @@ -418,7 +453,7 @@ static int load_pcres(int action) } /* Temporal pointer of pcres */ - if ((pcres_tmp = pkg_malloc(sizeof(pcre *) * num_pcres_tmp)) == 0) { + if ((pcres_tmp = pkg_malloc(sizeof(pcre2_code *) * num_pcres_tmp)) == 0) { LM_ERR("no more memory for pcres_tmp\n"); goto err; } @@ -429,14 +464,15 @@ static int load_pcres(int action) /* Compile the patters */ for (i=0; is, /* the subject string */ + string->len, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + NULL, /* output vector for substring information */ + 0); /* number of elements in the output vector */ +#else + match_data = pcre2_match_data_create(0, NULL); // no captures needed + + pcre_rc = pcre2_match( pcre_re, /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - string->s, /* the matching string */ - (int)(string->len), /* the length of the subject */ + (PCRE2_SPTR)string->s, /* the matching string */ + (PCRE2_SIZE)(string->len), /* the length of the subject */ 0, /* start at offset 0 in the string */ 0, /* default options */ - NULL, /* output vector for substring information */ - 0); /* number of elements in the output vector */ + match_data, /* match data block */ + NULL); /* match context */ + + pcre2_match_data_free(match_data); +#endif /* Matching failed: handle error cases */ if (pcre_rc < 0) { switch(pcre_rc) { - case PCRE_ERROR_NOMATCH: + case PCRE2_ERROR_NOMATCH: LM_DBG("'%s' doesn't match '%s'\n", string->s, regex.s); break; default: LM_DBG("matching error '%d'\n", pcre_rc); break; } - pcre_free(pcre_re); + pcre2_code_free(pcre_re); pkg_free(regex.s); return -1; } - pcre_free(pcre_re); + pcre2_code_free(pcre_re); pkg_free(regex.s); LM_DBG("'%s' matches '%s'\n", string->s, regex.s); return 1; @@ -606,6 +662,9 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre) { int num_pcre; int pcre_rc; +#ifdef PCRE2_LIB + pcre2_match_data *match_data; +#endif /* Check if group matching feature is enabled */ if (file == NULL) { @@ -625,22 +684,37 @@ static int w_pcre_match_group(struct sip_msg* _msg, str* string, int* _num_pcre) lock_get(reload_lock); +#ifndef PCRE2_LIB pcre_rc = pcre_exec( + (*pcres_addr)[num_pcre], /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + string->s, /* the subject string */ + string->len, /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + NULL, /* output vector for substring information */ + 0); /* number of elements in the output vector */ +#else + match_data = pcre2_match_data_create(0, NULL); // no captures needed + + pcre_rc = pcre2_match( (*pcres_addr)[num_pcre], /* the compiled pattern */ - NULL, /* no extra data - we didn't study the pattern */ - string->s, /* the matching string */ - (int)(string->len), /* the length of the subject */ + (PCRE2_SPTR)string->s, /* the matching string */ + (PCRE2_SIZE)(string->len), /* the length of the subject */ 0, /* start at offset 0 in the string */ 0, /* default options */ - NULL, /* output vector for substring information */ - 0); /* number of elements in the output vector */ + match_data, /* match data block */ + 0); /* match context */ + + pcre2_match_data_free(match_data); +#endif lock_release(reload_lock); /* Matching failed: handle error cases */ if (pcre_rc < 0) { switch(pcre_rc) { - case PCRE_ERROR_NOMATCH: + case PCRE2_ERROR_NOMATCH: LM_DBG("'%s' doesn't match pcres[%i]\n", string->s, num_pcre); break; default: diff --git a/modules/registrar/README b/modules/registrar/README deleted file mode 100644 index b5f2c0968b6..00000000000 --- a/modules/registrar/README +++ /dev/null @@ -1,1554 +0,0 @@ -registrar Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Path Support (RFC 3327) - 1.1.2. GRUU Support (RFC 5627) - 1.1.3. SIP Push Notification Support (RFC 8599) - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_expires (integer) - 1.3.2. min_expires (integer) - 1.3.3. max_expires (integer) - 1.3.4. default_q (integer) - 1.3.5. tcp_persistent_flag (string) - 1.3.6. realm_prefix (string) - 1.3.7. case_sensitive (integer) - 1.3.8. received_avp (str) - 1.3.9. received_param (string) - 1.3.10. expires_max_deviation (integer) - 1.3.11. max_contacts (integer) - 1.3.12. max_username_len (integer) - 1.3.13. max_domain_len (integer) - 1.3.14. max_aor_len (integer) - 1.3.15. max_contact_len (integer) - 1.3.16. retry_after (integer) - 1.3.17. sock_hdr_name (string) - 1.3.18. mcontact_avp (string) - 1.3.19. attr_avp (string) - 1.3.20. gruu_secret (string) - 1.3.21. disable_gruu (int) - 1.3.22. pn_enable (boolean) - 1.3.23. pn_providers (string) - 1.3.24. pn_ct_match_params (string) - 1.3.25. pn_pnsreg_interval (integer) - 1.3.26. pn_trigger_interval (integer) - 1.3.27. pn_skip_pn_interval (integer) - 1.3.28. pn_refresh_timeout (integer) - 1.3.29. pn_enable_purr (boolean) - - 1.4. Exported Functions - - 1.4.1. save(domain[, flags[, aor[, ownership_tag]]]) - - 1.4.2. remove(domain, AOR[, [contact][, [next_hop][, - [sip_instance], [bflag]]]]) - - 1.4.3. remove_ip_port(IP,Port, domain, [AOR]) - 1.4.4. lookup(domain [, flags [, aor]]) - 1.4.5. is_registered(domain ,[AOR]) - 1.4.6. is_contact_registered(domain - ,[AOR],[contact],[callid]) - - 1.4.7. is_ip_registered(domain - ,[AOR],IPvar,[PORTvar]) - - 1.4.8. add_sock_hdr(hdr_name) - - 1.5. Exported Asynchronous Functions - - 1.5.1. pn_process_purr(domain) - - 1.6. Exported Statistics - - 1.6.1. max_expires - 1.6.2. max_contacts - 1.6.3. defaults_expires - 1.6.4. accepted_regs - 1.6.5. rejected_regs - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_expires parameter - 1.2. Set min_expires parameter - 1.3. Set max_expires parameter - 1.4. Set default_q parameter - 1.5. Set tcp_persistent_flag parameter - 1.6. Set realm_prefix parameter - 1.7. Set case_sensitive parameter - 1.8. Set received_avp parameter - 1.9. Set received_param parameter - 1.10. Setting the expires_max_deviation parameter - 1.11. Set max_contacts parameter - 1.12. Setting the max_username_len module parameter - 1.13. Setting the max_domain_len module parameter - 1.14. Setting the max_aor_len module parameter - 1.15. Setting the max_contact_len module parameter - 1.16. Set retry_after parameter - 1.17. Set sock_hdr_namer parameter - 1.18. Set mcontact_avp parameter - 1.19. Set attr_avp parameter - 1.20. Set gruu_secret parameter - 1.21. Set gruu_secret parameter - 1.22. Setting the pn_enable parameter - 1.23. Setting the pn_providers parameter - 1.24. Setting the pn_ct_match_params parameter - 1.25. Setting the pn_pnsreg_interval parameter - 1.26. Setting the pn_trigger_interval parameter - 1.27. Setting the pn_skip_pn_interval parameter - 1.28. Setting the pn_refresh_timeout parameter - 1.29. Setting the pn_enable_purr parameter - 1.30. save usage - 1.31. remove usage - 1.32. remove_ip_port usage - 1.33. lookup usage - 1.34. is_registered usage - 1.35. is_contact_registered usage - 1.36. is_ip_registered usage - 1.37. add_sock_hdr usage - 1.38. async pn_process_purr() usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module contains SIP REGISTER request processing logic, per - RFC 3261. On top of this support, several extensions are - available: - -1.1.1. Path Support (RFC 3327) - - The registrar module includes SIP Path header field support - according to RFC 3327, for usage in registrars and - home-proxies. - - A call to save() stores, if path support is enabled in the - registrar module, the values of the Path Header(s) along with - the Contact information into usrloc. There are three modes for - building the reply to a REGISTER message which includes one or - more Path header fields: - * off - stores the value of the Path headers into usrloc - without passing it back to the UAC in the reply. - * lazy - stores the Path header and passes it back to the UAC - if Path-support is indicated by the “path” param in the - Supported HF. - * strict - rejects the registration with “420 Bad Extension” - if there's a Path header but no support for it is indicated - by the UAC. Otherwise it's stored and passed back to the - UAC. - - A call to lookup() always uses the Path header if found, and - inserts it as Route HF either in front of the first Route HF, - or after the last Via HF if no Route is present. It also sets - the destination URI to the first Path URI, thus overwriting the - received-URI, because NAT has to be handled at the - outbound-proxy of the UAC (the first hop after client's NAT). - - The whole process is transparent to the user, so no config - changes are required besides enabling one of the "p0" / "p1" / - "p2" flags when calling save(). - -1.1.2. GRUU Support (RFC 5627) - - The registrar module includes support for Globally Routable - User Agent URIs according to RFC 5627. - - A call to save() stores, if the phone supports GRUU, the values - of the SIP Instance along with the contact into usrloc. The - module will generate two types of GRUUs: - * public - exposes the underlying AOR, constructed just by - attaching the SIP Instance as the ;gr parameter value. - These are persistent, valid as long as the contact - registration is valid. - * temporary - hides the underlying AOR Each new Register - request leads to the construction of a new temporary GRUU, - while Register requests with a different Call-ID lead to - the invalidation of all the previous generated temporary - GRUUs. - - A call to lookup() will try to detect if the R-URI contains a - GRUU. If it does, it will route the request just for the - Contact that the specific AOR belongs to, without appending any - other branches. - - Even if the the GRUU handling during the registration process - is transparent to the user, so no config changes are required, - you need to take care of the GRUU specifics when handling - mid-dialog requests. - - As the GRUU will be present in the contact header of the - initial requests generated byt GRUU enabled devices, you will - have to also do a lookup() when receiving a mid-dialog request - with the GRUU indication in the RURI. - -1.1.3. SIP Push Notification Support (RFC 8599) - - The registrar module includes support for standards-based SIP - Push Notifications, per RFC 8599. Support for the basic version - of the draft can be enabled by switching pn_enable to true. The - module also includes optional support for sending Push - Notifications during long-lived dialogs (see RFC section 6), - through the pn_enable_purr switch. - - Essential mechanics behind the Push Notification (PN) support: - * the PN support is fully compatible with the existing logic - and enabling it does not impose any limitations, as the - registrar can simultaneously handle both SIP PN compliant - and standard SIP User Agents - * OpenSIPS will raise a E_UL_CONTACT_REFRESH event any time a - Push Notification needs to be sent to a PN-enabled contact. - The event includes the PN coordinates of the contact -- - they may be found in the Contact URI ('uri' event - parameter) and may be extracted using the {uri.param,name} - transformation. From here onwards, it is up to the script - developer to trigger the Push Notification (e.g. possibly - by sending an HTTP POST with the rest_client module), thus - forcing a re-registration from the device. - * REGISTER processing is unchanged -- PN-enabled UAs are - saved just as regular UAs, with the former ones - additionally having the 4 bitflag set in the "Flags" field - of any MI listing of contacts, for differentiation purposes - * initial INVITE processing is barely changed, with the - lookup() function now additionally returning a value of 2 - if the only found contacts were PN-enabled contacts, all - which required a Push Notification. This means that PNs - have been triggered for each of them and t_relay() is not - required, since they are not reachable until they - re-register! - Using the event_routing module, OpenSIPS will transparently - fork a new branch from the current INVITE on each - re-registration from these contacts within the accepted - pn_refresh_timeout - * mid-dialog requests: In some cases (e.g. long-lived - dialogs), a PN may be required before being able to route a - mid-dialog request to a SIP UA. The pn_process_purr() async - function will take care of triggering the PN event and - resuming the script as soon as a re-registration from the - concerned contact is received. - - For more information or examples, refer to the documentation of - the "pn_xxx" module parameters or the OpenSIPS blog posts - around the "SIP Push Notification" topic. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * usrloc - User Location Module. - * signaling - Signaling module. - * event_routing, if pn_enable is set to true. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. default_expires (integer) - - If the processed message contains neither Expires HFs nor - expires contact parameters, this value will be used for newly - created usrloc records. The parameter contains number of second - to expire (for example use 3600 for one hour). - - Default value is 3600. - - Example 1.1. Set default_expires parameter -... -modparam("registrar", "default_expires", 1800) -... - -1.3.2. min_expires (integer) - - The minimum expires value of a Contact, values lower than this - minimum will be automatically set to the minimum. Value 0 - disables the checking. - - Default value is 60. - - Example 1.2. Set min_expires parameter -... -modparam("registrar", "min_expires", 60) -... - -1.3.3. max_expires (integer) - - The maximum expires value of a Contact, values higher than this - maximum will be automatically set to the maximum. Value 0 - disables the checking. - - Default value is 0. - - Example 1.3. Set max_expires parameter -... -modparam("registrar", "max_expires", 120) -... - -1.3.4. default_q (integer) - - The parameter represents default q value for new contacts. - Because OpenSIPS doesn't support float parameter types, the - value in the parameter is divided by 1000 and stored as float. - For example, if you want default_q to be 0.38, use value 380 - here. - - Default value is 0. - - Example 1.4. Set default_q parameter -... -modparam("registrar", "default_q", 1000) -... - -1.3.5. tcp_persistent_flag (string) - - The parameter specifies the message flag to be used to control - the module behaviour regarding TCP connections. If the flag is - set for a REGISTER via TCP containing a TCP contact, the - module, via the “save()” function, will set the lifetime of the - TCP connection to the contact expire value. By doing this, the - TCP connection will stay on as long as the contact is valid. - - Default value is -1 (disabled). - - Example 1.5. Set tcp_persistent_flag parameter -... -modparam("registrar", "tcp_persistent_flag", "TCP_PERSIST_DURATION") -... - -1.3.6. realm_prefix (string) - - Prefix to be automatically strip from realm. As an alternative - to SRV records (not all SIP clients support SRV lookup), a - subdomain of the master domain can be defined for SIP purposes - (like sip.mydomain.net pointing to same IP address as the SRV - record for mydomain.net). By ignoring the realm_prefix "sip.", - at registration, sip.mydomain.net will be equivalent to - mydomain.net . - - Default value is NULL (none). - - Example 1.6. Set realm_prefix parameter -... -modparam("registrar", "realm_prefix", "sip.") -... - -1.3.7. case_sensitive (integer) - - If set to 1 then AOR comparison will be case sensitive (as - RFC3261 instructs), if set to 0 then AOR comparison will be - case insensitive. - - Default value is 1. - - Example 1.7. Set case_sensitive parameter -... -modparam("registrar", "case_sensitive", 0) -... - -1.3.8. received_avp (str) - - Registrar will store the value of the AVP configured by this - parameter in the received column in the user location database. - It will leave the column empty if the AVP is empty. The AVP - should contain a SIP URI consisting of the source IP, port, and - protocol of the REGISTER message being processed. - -Note - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - Default value is "NULL" (disabled). - - Example 1.8. Set received_avp parameter -... -modparam("registrar", "received_avp", "$avp(rcv)") -... - -1.3.9. received_param (string) - - The name of the parameter that will be appended to Contacts of - 200 OK when the received URI was set by nathelper module. - - Default value is "received". - - Example 1.9. Set received_param parameter -... -modparam("registrar", "received_param", "rcv") -... - -1.3.10. expires_max_deviation (integer) - - Set this parameter in order to add a random +/- deviation up to - and including the given value to the expiration interval of a - newly registered contact. For example, if this parameter is set - to 100 and a phone registers for 1800 sec, the final expiry - will be a random number in the [1700, 1900] interval. - - By randomizing the registration lifetimes of the contacts, the - server is better equipped to deal with a post-restart - registration storm, when all TCP connections are lost and a - significant portion of UAs will re-register at the same time. - Thanks to the contact lifetime randomization, the registration - storm will only happen once rather than, e.g., every 1800 - seconds following the restart. - - Default value is 0 (no deviation). - - Example 1.10. Setting the expires_max_deviation parameter -... -# add a random +/- 0-100 seconds to each registration lifetime -modparam("registrar", "expires_max_deviation", 100) -... - -1.3.11. max_contacts (integer) - - The parameter can be used to limit the number of contacts per - AOR (Address of Record) in the user location database. Value 0 - disables the check. - - This is the default value and will be used only if no other - value (for max_contacts) is passed as parameter to the save() - function. That's it - the function parameter overwride this - global parameter. - - Default value is 0. - - Example 1.11. Set max_contacts parameter -... -# Allow no more than 10 contacts per AOR -modparam("registrar", "max_contacts", 10) -... - -1.3.12. max_username_len (integer) - - The maximum length of the "username" part of an - Address-of-Record SIP URI. - - Default value is 64. - - Example 1.12. Setting the max_username_len module parameter -modparam("registrar", "max_username_len", 128) - -1.3.13. max_domain_len (integer) - - The maximum length of the "domain" part of an Address-of-Record - SIP URI. - - Default value is 64. - - Example 1.13. Setting the max_domain_len module parameter -modparam("registrar", "max_domain_len", 128) - -1.3.14. max_aor_len (integer) - - The maximum length of an Address-of-Record SIP URI. - - Default value is 256. - - Example 1.14. Setting the max_aor_len module parameter -modparam("registrar", "max_aor_len", 512) - -1.3.15. max_contact_len (integer) - - The maximum length of a Contact header field SIP URI. - - Default value is 255. - - Example 1.15. Setting the max_contact_len module parameter -modparam("registrar", "max_contact_len", 512) - -1.3.16. retry_after (integer) - - The registrar can generate 5xx reply to REGISTER in various - situations. It can, for example, happen when the max_contacts - parameter is set and the processing of REGISTER request would - exceed the limit. In this case the registrar would generate - "503 Service Unavailable" response. - - If you want to add the Retry-After header field in 5xx replies, - set this parameter to a value grater than zero (0 means do not - add the header field). See section 20.33 of RFC3261 for more - details. - - Default value is 0 (disabled). - - Example 1.16. Set retry_after parameter -... -modparam("registrar", "retry_after", 30) -... - -1.3.17. sock_hdr_name (string) - - Header which contains a socket description (proto:IP:port) to - override the received socket info. The header will be search - and used only if the flag 's' (Socket header) is set at - "save()" time. - - This makes sense only in multiple replicated servers scenarios. - - Default value is NULL. - - Example 1.17. Set sock_hdr_namer parameter -... -modparam("registrar", "sock_hdr_name", "Sock-Info") -... - -1.3.18. mcontact_avp (string) - - AVP to store the modified binding/contact that is set during - cached registrations scenario (when REGISTER is forwarded to - another registrar). The AVP will be used to extract the - "expires" value returned in the 200 OK by the main registrar. - - This makes sense only in cached registrations scenario, where - your OpenSIPS is caching registrations before forwarding them - to the main registrar. - - Default value is NULL. - - Example 1.18. Set mcontact_avp parameter -... -modparam("registrar", "mcontact_avp", "$avp(orig_ct)") -... -route { - ... - # before forwarding the REGISTER request, save the outgoing contact. - # Be SURE to do it after all the possible changes over the contact, - # like fix_nated_contact() - $avp(orig_ct) = $ct.fields(uri); - t_on_reply("do_save"); - t_relay("udp:ip:port"); - ... -} -... -onreply_route[do_save] { - if ($rs=="200") - save("location"); -} -... - -1.3.19. attr_avp (string) - - AVP to store specific additional information for each - registration. This information is read from the AVP and stored - (in memory, db or both) at every registrar 'save()'. When a - registrar 'lookup()' or 'is_registered()' function is called, - the stored information is pushed into a message branch - attribute with the same name as attr_avp (see - $msg.branch.attr() core variable) - - When doing parallel call forking, the contact attributes will - be pushed to the attributes of the corresponding branch - - Default value is NULL. - - Example 1.19. Set attr_avp parameter -# reading attributes from the attr_pvar when doing parallel forking -... -modparam("registrar", "attr_avp", "$avp(attr)") - -... -if (is_method("REGISTER")) { - $avp(attr) = "contact_info"; - save("location"); - exit; -} -... -lookup("location"); -# list all resulted branches and their attribute -$var(i) = 0; -while ($(msg.branch.uri[$var(i)])!=NULL) { - xlog("branch $var(i): $(msg.branch.uri[$var(i)]), attr=$(msg.bra -nch.attr(attr)[$var(i)])\n"); - $var(i) = $var(i) + 1; -} -.... -t_on_branch("parallel_fork"); -t_relay(); -... -branch_route [parallel_fork] { - xlog("Attributes for branch $T_branch_idx: $tm.branch.attr(attr) -\n"); -} - - -1.3.20. gruu_secret (string) - - The string that will be used in XORing when generating - temporary GRUUs. - - If not set, 'OpenSIPS' is the default secret. - - Example 1.20. Set gruu_secret parameter -... -modparam("registrar", "gruu_secret", "top_secret") -... - -1.3.21. disable_gruu (int) - - Globally disable GRUU handling - - Default value is 1 ( GRUU will not be handled ). - - Example 1.21. Set gruu_secret parameter -... -modparam("registrar", "disable_gruu", 0) -... - -1.3.22. pn_enable (boolean) - - Enable SIP Push Notification support (RFC 8599). If enabled, - Contact header field URIs which include all pn_ct_match_params - will be matched against existing bindings using only these - parameters. Otherwise, the module will attempt to match them as - usual, using the current usrloc matching_mode. - - Default value is false. - - Example 1.22. Setting the pn_enable parameter -... -modparam("registrar", "pn_enable", true) -... - -1.3.23. pn_providers (string) - - A list of supported Push Notification providers. While only - three possible values are defined by RFC 8599 ("apns", "fcm" - and "webpush"), non-standard values may be specified as well. - - Default value is NULL (not set). - - Example 1.23. Setting the pn_providers parameter -... -modparam("registrar", "pn_providers", "apns, fcm, webpush") -... - -1.3.24. pn_ct_match_params (string) - - The minimally required list of RFC 8599 parameters (custom ones - are accepted as well) which must be present in a Contact URI - and identically match an existing binding in order for the - binding to be refreshed during a SIP re-REGISTER. If at least - one such parameter is missing from a Contact header field URI, - the module will fall back to performing regular contact - matching. - - Note that if all above PN Contact URI parameters match an - existing binding, the match is considered to be successful - regardless if other parts of the SIP URI do not match (e.g. - hostname, port, other URI parameters, etc.). - - After calling lookup() or pn_process_purr(), the above - PN-related parameters will be automatically stripped from the - resulting Request and Contact URI event parameter, - respectively. - - Default value is "pn-provider, pn-prid, pn-param". - - Example 1.24. Setting the pn_ct_match_params parameter -... -modparam("registrar", "pn_ct_match_params", "pn-provider, pn-prid") -... - -1.3.25. pn_pnsreg_interval (integer) - - For devices capable of waking up and refreshing their binding - on their own (signified by the ";+sip.pnsreg" Contact header - field parameter), this setting denotes the prior-to-expiration - interval advertised by the server at which the device should - issue its binding refresh request. - - Default value is 130 (seconds before expiry). - - Example 1.25. Setting the pn_pnsreg_interval parameter -... -modparam("registrar", "pn_pnsreg_interval", 140) -... - -1.3.26. pn_trigger_interval (integer) - - If a binding refresh REGISTER request from a given SIP endpoint - does not arrive within at least pn_trigger_interval seconds - prior to expiration (e.g. because the device does not support - ";+sip.pnsreg" or because of other error conditions), the - E_UL_CONTACT_REFRESH usrloc event will be triggered. - - Once E_UL_CONTACT_REFRESH is triggered, the script writer - should use the RFC 8599 parameters from the Contact URI in - order to generate a Push Notification request to the PN - provider of the device, in order to cause the device to wake up - and re-register. - - Default value is 120 (seconds before expiry). - - Example 1.26. Setting the pn_trigger_interval parameter -... -modparam("registrar", "pn_trigger_interval", 130) -... - -1.3.27. pn_skip_pn_interval (integer) - - Following a successful (re)registration of a contact, this - setting denotes a time interval, in seconds, during which the - contact is assumed to be reachable, so any Push Notifications - will be skipped. - - Default value is 0 seconds (always generate Push - Notifications). - - Example 1.27. Setting the pn_skip_pn_interval parameter -... -modparam("registrar", "pn_skip_pn_interval", 10) -... - -1.3.28. pn_refresh_timeout (integer) - - This timeout starts counting following a lookup() or a - pn_process_purr() which triggers a Push Notification. The value - represents the maximum allowed sum of the duration required for - the Push Notification to be sent and the duration required for - the corresponding re-registration from the device to arrive. - - Once this timeout is exceeded for an initial or a mid-dialog - request, any further re-registrations which match the pending - Push Notification will no longer cause the desired effects. For - example: - * pending initial INVITE transactions will complete and will - no longer auto-fork an additional branch for each REGISTER - sent by the callee side - * pending BYE messages will time out and OpenSIPS will - attempt to route them despite not having received a - confirmation that the target device is actually reachable - - Default value is 6 seconds. - - Example 1.28. Setting the pn_refresh_timeout parameter -... -modparam("registrar", "pn_refresh_timeout", 10) -... - -1.3.29. pn_enable_purr (boolean) - - Enable the SIP Push Notification mechanism for long-lived - dialogs. If enabled, the registrar will include a - "+sip.pnspurr" Feature-Caps header field tag in 200 OK replies - to REGISTER requests. This tag represents a unique identifier - for the registration (PURR - Proxy Unique Registration - Reference). - - During dialog setup, each UA may include, in its Contact - header, the PURR value returned by OpenSIPS during - registration. By including the PURR (e.g. ";pn-purr=XXX"), an - agent indicates that it expects to be first awoken by a PN - before being able to receive a mid-dialog request sent by the - other party. - - When enabling this parameter, make sure to also add logic for - pn_process_purr(). - - Default value is false. - - Example 1.29. Setting the pn_enable_purr parameter -... -modparam("registrar", "pn_enable_purr", true) -... - -1.4. Exported Functions - -1.4.1. save(domain[, flags[, aor[, ownership_tag]]]) - - The function processes a REGISTER message. It can add, remove - or modify usrloc records depending on Contact and Expires HFs - in the REGISTER message. On success, 200 OK will be returned - listing all contacts that are currently in usrloc. On an error, - error message will be send with a short description in reason - phrase. - - Meaning of the parameters is as follows: - * domain (static string) - Logical domain within registrar. - If database is used then this must be name of the table - which stores the contacts. - * flags (string, optional) - string composed of one or more - of the following flags, comma-separated: - + 'memory-only' - (old m flag) save the contacts only in - memory cache without no DB operation; - + 'no-reply' - (old r flag) do not generate a SIP reply - to the current REGISTER request. - + 'max-contacts=[int]' - (old c flag) this flag can be - used to limit the number of contacts for this AOR - (Address of Record) in the user location database. - Value 0 disables the check. This parameter overrides - the global "max_contacts" module parameter. - + 'force-registration' - (old f flag) this flag can be - used to force the registration of NEW contacts even if - the maximum number of contacts is reached. In such a - case, older contacts will be removed to make space to - the new ones, without exceeding the maximum allowed - number. This flag makes sense only if "max-contacts" - is used. - + 'matching-mode=[val]' - (old M flag) How the matching - should be performed between the uploaded contacts (by - the currently handled REGISTER) and the already know - contacts (in memory or DB). This options will be used - only for the current operation and can be: - o '0' - contact URI matching only - o '1' - contact URI and SIP Call-ID matching - o '' - only the value of the given URI - param will be used for matching (for example - ) - + 'path-off' - (old p0 flag) (Path support - 'off' mode) - - The Path header is saved into usrloc, but is never - included in the reply. - + 'path-lazy' - (old p1 flag) (Path support - lazy mode) - The Path header is saved into usrloc, but is only - included in the reply if path support is indicated in - the registration request by the “path” option of the - “Supported” header. - + 'path-strict' - (old p2 flag) (Path support - strict - mode) - The path header is only saved into usrloc, if - path support is indicated in the registration request - by the “path” option of the “Supported” header. If no - path support is indicated, the request is rejected - with “420 - Bad Extension” and the header - “Unsupported: path” is included in the reply along - with the received “Path” header. This mode is the one - recommended by RFC-3327. - + 'path-received' - (old v flag) if set, the “received” - parameter of the first Path URI of a registration is - set as received-uri and the NAT branch flag is set for - this contact. This is useful if the registrar is - placed behind a SIP loadbalancer, which passes the - nat'ed UAC address as “received” parameter in it's - Path uri. - + 'only-request-contacts' - (old o flag) Only include - the REGISTER request's Contacts in the 200 OK reply, - in case the registration is successful. While this is - against RFC 3261, it may be useful in certain - scenarios. - + 'socket-header' - (old s flag) look into REGISTER - request for a header which contains a socket - description (proto:IP:port). This socket info will be - stored by register instead of the received socket - info. - + 'min-expires=[int]' - (old e flag) this flag can be - used to set minimum register expiration time. Values - lower than this minimum will be automatically set to - the minimum. Value 0 disables the checking. This - parameter overrides the global min_expires module - parameter. - + 'max-expires=[int]' - (old E flag) this flag can be - used to set maximum register expiration time. Values - higher than this maximum will be automatically set to - the maximum. Value 0 disables the checking. This - parameter overrides the global max_expires module - parameter. - This parameter is a string composed of a set of flags. - * aor (string, optional) - a custom AOR; if missing, the AOR - will be taken from the default place - the TO header URI. - * ownership_tag (string, optional) - a cluster-shared tag - (see the clusterer module documentation for more details) - which will be attached to each contact saved from the - current request. This tag is only relevant in clustered - user location scenarios and helps determine the current - logical owner node of a contact. This, in turn, is useful - in order to restrict nodes which are not currently - responsible for this contact from performing certain - actions (for example: incorrectly originating pings from a - non-owned virtual IP address in highly-available setups). - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - If you plan to use the “save()” function in reply route, please - refer to mcontact_avp module parameter. - - Example 1.30. save usage -... -# save into 'location', no flags, use default AOR (TO URI) -save("location"); -... -# save into 'location', do not update DB, max 5 contacts per AOR, -# use default AOR (TO URI) -save("location","memory-only, max-contacts=5"); -... -# save into 'location', no flags, use as AOR the FROM URI -save("location","",$fu); -... -# save into 'location', no DB update, force registration, take AOR from -AVP -save("location","memory-only, no-reply", $avp(aor)); -... -# save into 'location', mark the contacts with the "vip" ownership tag a -nd -# replicate these contacts to the backup node, which does not currently -own "vip" -save("location", , , "vip"); -... - -1.4.2. remove(domain, AOR[, [contact][, [next_hop][, [sip_instance], -[bflag]]]]) - - Explicitly remove contacts behind a given address-of-record. - - Meaning of the parameters is as follows: - * domain (static string - Logical domain within the - registrar. If a database is used, then this must be name of - the table which stores the contacts. - * AOR (string) - address-of-record to be searched (SIP URI) - * contact (string, optional) - SIP URI filter for the contact - to be removed. This must be the full SIP URI as used during - registered. - * next_hop (string, optional) - the next SIP IP - address/hostname on the way back to this contact. See the - section below for details on how the next hop is computed. - Hostnames are resolved before matching. - * sip_instance (string, optional) - a "+sip.instance" value - to be used for filtering purposes. - * blfag (string, optional) - a Branch Flag to be used for - filtering purposes. - - IMPORTANT: the IP address of each contact (for matching - purposes) is computed as follows: - * a. if a Path header is present, the hostname part of the - Path URI will be resolved as the contact's IP address. - * b. otherwise, if by using nathelper, the "Received" value - (source IP of the next hop) is set for a contact, this - becomes the chosen hostname to be resolved as the contact's - IP address. - * c. otherwise, the "hostname" part of the Contact header - field URI is chosen to be resolved as the contact's IP - address. - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - Example 1.31. remove usage -... -# remove all contacts belonging to the "bob" AOR -remove("location", "sip:bob@atlanta.com"); -... -# remove only bob's home phone contact -remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78"); -... -# remove all bob's phones which are behind "50.60.50.60" -# note that "contact" parameter has to be specified with NULL value even - though not used -$var(next_hop) = "50.60.50.60" -remove("location", "sip:bob@atlanta.com", , $var(next_hop)); -... -# remove bob's phone with contact "sip:bob@46.50.64.78" that is behind " -50.60.50.60" -remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78", "50.60. -50.60"); -... -# remove all contacts behind bob's mobile device X -remove("location", "sip:bob@atlanta.com", , , "") - -1.4.3. remove_ip_port(IP,Port, domain, [AOR]) - - Remove all contacts behind a specific IP and Port, optionally - filtering by AOR. - - Meaning of the parameters is as follows: - * IP (string) - IP of the Contact to be removed - * Port (integer) - Port of the Contact to be removed - * domain (static string - Logical domain within the - registrar. If a database is used, then this must be name of - the table which stores the contacts. - * AOR (string, optional) - address-of-record to be searched - (SIP URI) - - This function can be used from ALL ROUTES. - - Example 1.32. remove_ip_port usage -... -# remove all contacts behind 8.8.8.8 port 43213 -remove_ip_port("8.8.8.8",43213,"location"); -... -# remove only bob's contacts behind the 8.8.8.8:43213 host -remove_ip_port("8.8.8.8",43213,"location","sip:bob@atlanta.com"); -... - -1.4.4. lookup(domain [, flags [, aor]]) - - The functions extracts username from Request-URI and tries to - find all contacts for the username in usrloc. If there are no - such contacts, -1 will be returned. If there are such contacts, - Request-URI will be overwritten with the contact that has the - highest q value and optionally the rest will be appended to the - message (depending on append_branches parameter value). - - If the method_filtering option is enabled, the lookup function - will return only the contacts that support the method of the - processed request. - - Meaning of the parameters is as follows: - * domain (static string) - Name of table that should be used - for the lookup. - * flags (string, optional) - string composed of one or more - of the following flags, comma-separated: - + 'no-branches' - (old b flag) this flag controls how - the lookup() function processes multiple contacts. If - there are multiple contacts for the given username in - usrloc and this flag is not set, Request-URI will be - overwritten with the highest-q rated contact and the - rest will be appended to sip_msg structure and can be - later used by tm for forking. If the flag is set, only - Request-URI will be overwritten with the highest-q - rated contact and the rest will be left unprocessed. - + 'to-branches-only' - (old B flag) this flags forces - all found contacts to be uploaded only as branches (in - the destination set) and not at all in the R-URI of - the current message. Using this option allows the - lookup() function to also be used in the context of a - SIP reply. - + 'branch' - (old r flag) this flag enables searching - through existing branches for aor's and expanding them - to contacts. For example, you have got AOR A in your - ruri but you also want to forward your calls to AOR B. - In order to do this, you must put AOR B in a branch, - and if this flag enabled, the function will also - expand AOR B to contacts, which will be put back into - the branches. The AOR's that were in branches before - the function call shall be removed. - WARNING: if you want this flag activated, the - 'no-branches' flag must not be set, because by setting - that flag you won't allow lookup() to write in a - branch. - + 'method-filtering' - (old m flag) setting this flag - will enable contact filtering based on the supported - methods listed in the "Allow" header field during - registration. Contacts which did not present an - "Allow" header field during registration are assumed - to support all standard SIP methods. - + 'ua-filtering=[val]' (old u flag) (User-Agent - filtering) - this flag enables regexp filtering by - user-agent. It's useful with enabled append_branches - parameter. The value must use the format '/regexp/'. - + 'case-insensitive' (old i flag) - this flag enables - case insensitive filtering for the 'ua-filtering' - flag. - + 'extended-regexp' - (old e flag) this flag enables - using of extended regexp format for the 'ua-filtering' - flag. - + 'global' (old g flag) (Global lookup) - this flag is - only relevant with federated user location clustering. - If set, the lookup() function will not only perform - the classic in-memory "search-AoR-and-push-branches" - operation, but will also perform a metadata lookup and - append an additional branch for each returned result. - The "in-memory branches" correspond to local contacts - (current location), while the "metadata branches" - correspond to contacts available on one or more of the - remaining locations of the platform. - The AoR metadata consists of the minimally required - information in order for one of the VoIP platform's - locations (data centers) to advertise the presence of - a locally registered AoR for the global platform. - Specifically, this consists of two pieces of - information: - o the AoR (e.g. "vladimir@federation-cluster") - o the home IP (e.g. "10.0.0.223") - + 'max-ping-latency=[int]' - (old y flag) maximally - accepted contact pinging latency (microseconds). - Contacts of an AoR with a higher latency will be - discarded during lookup(). - + 'sort-by-latency' - (old Y flag) contacts will be - picked in ascending order of their last successful - pinging latency (fastest ping -> slowest ping). This - flag may work together with the "max-ping-latency" - flag. - * AOR (string, optional) - AOR to lookup for; if missing, the - RURI is used as AOR; - - Return codes: - * 1 - contacts found and successfully pushed as branches. - Contacts which required awakening prior to being reachable - are being notified via async Push Notifications. - * 2 - successfully started at least one async Push - Notification for the found contacts, however no extra - branches were populated (i.e. there is no need to call - t_relay()). - * -1 - no contact found. - * -2 - contacts found, but neither of them supports the - current SIP method. - * -3 - internal error during processing. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.33. lookup usage -... -lookup("location"); # simple lookup - #or -lookup("location", "method-filtering"); # lookup with method filtering - #or -lookup("location", "branch"); # lookup with aor branch search; - # all contacts except th -e first one shall be put - # in the branches - #or -lookup("location", "ua-filtering=/phone/i"); # lookup with user-agent fi -ltering - #or -lookup("location", "", $var(aor)); # simple lookup with AOR from var -switch ($retcode) { - case -1: - case -3: - sl_send_reply(404, "Not Found"); - exit; - case -2: - sl_send_reply(405, "Not Found"); - exit; -}; -... - -1.4.5. is_registered(domain ,[AOR]) - - The function returns true if an AOR is registered, false - otherwise. The function does not modify the message being - process. - - NOTE: if called for a reply (from onreply_route), you must pass - an AOR (as parameter), otherwise the function will fail. - - Meaning of the parameters is as follows: - * domain (static string) - Name of table that should be used - for the lookup. - * AOR (string, optional) - AOR to lookup for; if missing, the - source if the AOR is the "To" header for REGISTER request, - "From" header for any other sip request. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - Example 1.34. is_registered usage -... -/**/ -if (is_method("REGISTER")) { - /* automatically uses the URI from the To header */ - if (is_registered("location")) { - xlog("this AOR is registered\n") - ... - } -}; -/* check the From uri whether this aor is registered or not */ -if (is_registered("location",$fu)) { - xlog("caller is registered\n"); -} -... - -1.4.6. is_contact_registered(domain ,[AOR],[contact],[callid]) - - The function returns true if a contact and/or a callid from a - certain AOR is registered, false otherwise. The function does - not modify the message being process. - - Meaning of the parameters is as follows: - * domain (static string) - Name of table that should be used - for the lookup. - * AOR (string, optional) - AOR to lookup for; if missing, the - source if the AOR is the "To" header for REGISTER request, - "From" header for any other sip request. - * contact (contact, optional) (optional)- SIP URI to check if - there is a registration with this URI as cotact (this may - help you to make distinction between multiple registrations - for the same user/AOR). - * callid (string, optional) - callid to check if a contact if - registered with this callid (this may help you to make - distinction between newly registered contact (callid not - registered so far) and re-registration (callid already - registered). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - Example 1.35. is_contact_registered usage -... -/* block users which are not registered... */ -if (is_method("INVITE")) { - if (!is_contact_registered("location")) { - sl_send_reply(401, "Unauthorized"); - ... - } -} - -/* ... or check whether the 2nd Contact URI is registered or not */ -if (is_method("INVITE")) { - if (is_contact_registered("location", $fu, $(ct.fields(uri)[1])) -) - xlog("caller is registered\n"); -} -... - -1.4.7. is_ip_registered(domain ,[AOR],IPvar,[PORTvar]) - - The function returns true if there is at least one contact that - has been registered from the IP in the IPvar variable ( and - from the optional PORTvar variable ). The IP is matched against - the received host, if it exists, or the contact host otherwise. - This function does not modify the message being process. This - function replaces the old "is_other_contact" function. - - Meaning of the parameters is as follows: - * domain (static string) - Name of table that should be used - for the lookup. - * AOR (string, optional) - AOR to lookup for; if missing, the - source if the AOR is the "To" header for REGISTER request, - "From" header for any other sip request. - * IPvar (var) - the variable containing the IP matched - against the contact host or the received host (see above). - If the IPvar is an AVP containing multiple values/IPs, then - all the values are checked. - * PORTvar (var, optional) - the variable containing the port - to be matched against the contact host or the received host - (see above). If the IPvar is an AVP containing multiple - values/IPs, then the PORTvar is expected to contain the - same number of entries, and all the values are checked. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - Example 1.36. is_ip_registered usage -... -/* check the source ip whether it is already registered */ -if (is_method("REGISTER")) { - if (is_ip_registered("location",$tu,$si)) { - xlog("already registered from this ip\n"); - ... - } -}; -... - -1.4.8. add_sock_hdr(hdr_name) - - Adds to the current REGISTER request a new header with - “hdr_name” which contains the description of the received - socket (proto:ip:port) - - This makes sense only in multiple replicated servers scenarios. - - Meaning of the parameters is as follows: - * hdr_name (string) - header name to be used. - - This function can be used from REQUEST_ROUTE. - - Example 1.37. add_sock_hdr usage -... -add_sock_hdr("Sock-Info"); -... - -1.5. Exported Asynchronous Functions - -1.5.1. pn_process_purr(domain) - - Perform mid-dialog request processing, according to RFC 8599. - For such requests, search the R-URI and topmost Route header - field URI for a ";pn-purr" parameter value that both matches - the OpenSIPS PURR format and corresponds to an usrloc - registration. Once a usrloc contact is located, trigger an - E_UL_CONTACT_REFRESH event and place the request on async hold - for at most pn_refresh_timeout seconds, until a matching - REGISTER request arrives. - - If processing ends before triggering the Push Notification, the - request will no longer be put on async hold, with the resume - route being immediately called. - - Meaning of the parameters is as follows: - * domain (static string) - Logical domain within registrar. - If a database is used, then this must be name of the table - which stores the contacts. - - Return Codes - * 1 - Success, PN was launched. - * 2 - Success, but PN was not launched (due to missing PURR, - foreign PURR or offline contact) - * -1 - Internal Error - - Example 1.38. async pn_process_purr() usage -route { - ... - if (has_totag()) { - if (is_method("ACK") && t_check_trans()) { - t_relay(); - exit; - } - - if (!loose_route()) { - send_reply(404, "Not Found"); - exit; - } - - if (!is_method("ACK")) - async (pn_process_purr("location"), resume_route -); - - route(relay); - exit; - } -} - -route [resume_route] { - $var(rc) = $rc; - xlog("pn_process_purr() finished with $var(rc)\n"); - - ... -} - -1.6. Exported Statistics - -1.6.1. max_expires - - Value of max_expires parameter. - -1.6.2. max_contacts - - The value of max_contacts parameter. - -1.6.3. defaults_expires - - The value of default_expires parameter. - -1.6.4. accepted_regs - - Number of accepted registrations. - -1.6.5. rejected_regs - - Number of rejected registrations. - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with the old “append_branch” module parameter? - - It was removed as global option, as the “lookup” function takes - this option via the flag "b" (append Branches) See the - documentation of the “lookup” function. - - 2.2. - - What happened with the old “method_filtering” module parameter? - - It was removed as global option, as the “lookup” function takes - this option via the flag "m" (Method filtering) See the - documentation of the “lookup” function. - - 2.3. - - What happened with the old “sock_flag” module parameter? - - It was removed as global option, as the “save” function takes - this option via the flag "s" (Socket header) See the - documentation of the “save” function. - - 2.4. - - What happened with the old “use_path” and “path_mode” module - parameters? - - They were removed as global option, as the “save” function - takes these options via the flag "px" (path support) See the - documentation of the “save” function. - - 2.5. - - What happened with the old “path_use_received” module - parameter? - - It was removed as global option, as the “save” function takes - this option via the flag "v" (path receiVed) See the - documentation of the “save” function. - - 2.6. - - What happened with the old “nat_flag” module parameter? - - It was removed, as the module internally loads this value from - the “USRLOC” module (see the “nat_bflag” USRLOC parameter). - - 2.7. - - What happened with the old “use_domain” module parameter? - - It was removed, as the module internally loads this option from - the “USRLOC” module. This was done in order to simplify the - configuration. - - 2.8. - - What happened with the old “save_noreply” and “save_memory” - functions? - - There functions were merged into the new “save(domain,flags)” - functions. If a reply should be sent or if the DB should be - updated also is controlled via the flags. - - 2.9. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.10. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.11. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - - 2.12. - - What happened to the desc_time_order parameter? - - It was removed, as its functionality was mmigrate into usrloc - module, were there is a parameter with the same name. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 199 123 2864 3030 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 171 116 2426 2055 - 3. Jan Janak (@janakj) 122 73 3465 1102 - 4. Daniel-Constantin Mierla (@miconda) 23 19 160 105 - 5. Vlad Paiu (@vladpaiu) 21 12 729 96 - 6. Vlad Patrascu (@rvlad-patrascu) 21 9 243 497 - 7. Razvan Crainea (@razvancrainea) 20 15 267 75 - 8. Ionut Ionita (@ionutrazvanionita) 16 4 763 248 - 9. Jiri Kuthan (@jiriatipteldotorg) 15 9 538 45 - 10. Andreas Granig 13 7 527 36 - - All remaining contributors: Henning Westerholt (@henningw), - Maksym Sobolyev (@sobomax), Andrei Pelinescu-Onciul, Ovidiu Sas - (@ovidiusas), Juha Heinanen (@juha-h), Nick Altmann (@nikbyte), - Ancuta Onofrei, Elena-Ramona Modroiu, Peter Lemenkov - (@lemenkov), Dan Pascu (@danpascu), Sergio Gutierrez, Carsten - Bock, Jeffrey Magder, Kobi Eshun (@ekobi), Dudu Ben Moshe, - Marcus Hunger, Julián Moreno Patiño, Phil D'Amore, Klaus - Darilion, Irina-Maria Stanescu, Dmitry Semyonov, Konstantin - Bokarius, Andrej Solovjov, Jesus Rodrigues, Dusan Klinec - (@ph4r05), Ruslan Bukin, Saúl Ibarra Corretgé (@saghul), - @jalung, Tolga Tarhan, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Andrej Solovjov Jul 2025 - Jul 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Sep 2003 - May 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2013 - May 2025 - 4. Dudu Ben Moshe Feb 2024 - Feb 2024 - 5. Maksym Sobolyev (@sobomax) Jul 2004 - Nov 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 7. Razvan Crainea (@razvancrainea) Apr 2011 - Apr 2023 - 8. Vlad Paiu (@vladpaiu) Sep 2011 - Nov 2022 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2020 - 10. @jalung Aug 2017 - Aug 2017 - - All remaining contributors: Ovidiu Sas (@ovidiusas), Ionut - Ionita (@ionutrazvanionita), Julián Moreno Patiño, Dusan Klinec - (@ph4r05), Nick Altmann (@nikbyte), Tolga Tarhan, Saúl Ibarra - Corretgé (@saghul), Ruslan Bukin, Irina-Maria Stanescu, Kobi - Eshun (@ekobi), Phil D'Amore, Sergio Gutierrez, Klaus Darilion, - Henning Westerholt (@henningw), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus - Rodrigues, Dan Pascu (@danpascu), Ancuta Onofrei, Marcus - Hunger, Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Jeffrey - Magder, Carsten Bock, Andreas Granig, Dmitry Semyonov, Jan - Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan - (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Dudu Ben Moshe, Vlad Patrascu - (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Vlad Paiu - (@vladpaiu), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), Julián Moreno Patiño, Nick Altmann - (@nikbyte), Ovidiu Sas (@ovidiusas), Irina-Maria Stanescu, Kobi - Eshun (@ekobi), Sergio Gutierrez, Klaus Darilion, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Jesus Rodrigues, Marcus Hunger, Juha Heinanen - (@juha-h), Elena-Ramona Modroiu, Carsten Bock, Andreas Granig, - Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS - - Copyright © 2020 OpenSIPS Solutions diff --git a/modules/registrar/README.md b/modules/registrar/README.md new file mode 100644 index 00000000000..111d89b808d --- /dev/null +++ b/modules/registrar/README.md @@ -0,0 +1,1612 @@ +--- +title: "registrar Module" +description: "The module contains SIP REGISTER request processing logic, per RFC 3261." +--- + +## Admin Guide + + +### Overview + + +The module contains SIP REGISTER request processing logic, per RFC + 3261. On top of this support, several extensions are available: + + +#### Path Support (RFC 3327) + + +The registrar module includes SIP Path header field support +according to +[RFC 3327](https://tools.ietf.org/html/rfc3327), +for usage in registrars and home-proxies. + + +A call to *save()* stores, if path support is enabled +in the registrar module, the values of the Path +Header(s) along with the Contact information into usrloc. There are +three modes for building the reply to a REGISTER message which +includes one or more Path header fields: + + +- *off* - stores the value of the +Path headers into usrloc without passing it back to +the UAC in the reply. +- *lazy* - stores the Path header and +passes it back to the UAC if Path-support is indicated +by the "path" param in the Supported HF. +- *strict* - rejects the registration +with "420 Bad Extension" if there's a Path +header but no support for it is indicated by the UAC. +Otherwise it's stored and passed back to the UAC. + + +A call to *lookup()* always uses the Path header if +found, and inserts it as Route HF either in front of +the first Route HF, or after the last Via HF if no +Route is present. It also sets the destination URI to +the first Path URI, thus overwriting the received-URI, +because NAT has to be handled at the outbound-proxy of +the UAC (the first hop after client's NAT). + + +The whole process is transparent to the user, so no +config changes are required besides enabling one of the +"p0" / "p1" / "p2" flags when calling *save()*. + + +#### GRUU Support (RFC 5627) + + +The registrar module includes support for Globally Routable User +Agent URIs according to [RFC 5627](https://tools.ietf.org/html/rfc5627). + + +A call to *save()* stores, if the phone supports GRUU, +the values of the SIP Instance along with the contact into usrloc. +The module will generate two types of GRUUs: + + +- *public* - exposes the underlying AOR, +constructed just by attaching the SIP Instance as the ;gr +parameter value. These are persistent, valid as long as the +contact registration is valid. +- *temporary* - hides the underlying AOR +Each new Register request leads to the construction of a +new temporary GRUU, while Register requests with a different +Call-ID lead to the invalidation of all the previous generated +temporary GRUUs. + + +A call to *lookup()* will try to detect if the R-URI contains a +GRUU. If it does, it will route the request just for the Contact +that the specific AOR belongs to, without appending any other branches. + + +Even if the the GRUU handling during the registration process is +transparent to the user, so no config changes are required, you need +to take care of the GRUU specifics when handling mid-dialog requests. + + +As the GRUU will be present in the contact header of the initial +requests generated byt GRUU enabled devices, you will have to also +do a lookup() when receiving a mid-dialog request with the GRUU +indication in the RURI. + + +#### SIP Push Notification Support (RFC 8599) + + +The registrar module includes support for standards-based SIP Push +Notifications, per +[RFC 8599](https://tools.ietf.org/html/rfc8599). +Support for the basic version of the draft can be enabled by switching +[pn enable](#param_pn_enable) to *true*. The +module also includes optional support for sending Push Notifications +during long-lived dialogs ([see RFC section 6](https://tools.ietf.org/html/rfc8599#page-23)), +through the [pn enable purr](#param_pn_enable_purr) switch. + + +Essential mechanics behind the Push Notification (PN) support: + + +- the PN support is fully compatible with the existing logic and +enabling it does not impose any limitations, as the +registrar can simultaneously handle both SIP PN compliant +and standard SIP User Agents +- OpenSIPS will raise a +[E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +event any time a Push Notification needs to be sent to a +PN-enabled contact. The event includes the PN coordinates of +the contact -- they may be found in the Contact URI ('uri' +event parameter) and may be extracted using the {uri.param,name} +transformation. From here onwards, it is up to the script +developer to trigger the Push Notification (e.g. possibly by +sending an HTTP POST with the +[rest_client](../rest_client) module), thus forcing +a re-registration from the device. +- REGISTER processing is unchanged -- PN-enabled UAs are saved +just as regular UAs, with the former ones additionally having +the *4* bitflag set in the "Flags" field of +any MI listing of contacts, for differentiation purposes +- initial INVITE processing is barely changed, with the *lookup()* +function now additionally returning a value of +**2** if the only +found contacts were PN-enabled contacts, all which required a +Push Notification. This means that PNs have been triggered for +each of them and t_relay() is not required, since they are not +reachable until they re-register! +Using the event_routing module, OpenSIPS will transparently +fork a new branch from the current INVITE on each +re-registration from these contacts within the accepted +[pn refresh timeout](#param_pn_refresh_timeout) +- mid-dialog requests: In some cases (e.g. long-lived dialogs), +a PN may be required before being able to route a mid-dialog +request to a SIP UA. The [afunc pn process purr](#afunc_pn_process_purr) +async function will take care of triggering the PN event and +resuming the script as soon as a re-registration from the +concerned contact is received. + + +For more information or examples, refer to the documentation of the +"pn_xxx" module parameters or the OpenSIPS blog posts around the +"SIP Push Notification" topic. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *usrloc - User Location Module*. +- *signaling - Signaling module*. +- *event_routing*, +if [pn enable](#param_pn_enable) is set to *true*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### default_expires (integer) + + +If the processed message contains neither Expires +HFs nor expires contact parameters, this value +will be used for newly created usrloc records. The parameter contains +number of second to expire (for example use 3600 for one hour). + + +*Default value is 3600.* + + +```opensips title="Set default_expires parameter" +... +modparam("registrar", "default_expires", 1800) +... +``` + + +#### min_expires (integer) + + +The minimum expires value of a Contact, values lower than this +minimum will be automatically set to the minimum. Value 0 disables +the checking. + + +*Default value is 60.* + + +```opensips title="Set min_expires parameter" +... +modparam("registrar", "min_expires", 60) +... +``` + + +#### max_expires (integer) + + +The maximum expires value of a Contact, values higher than this +maximum will be automatically set to the maximum. Value 0 disables +the checking. + + +*Default value is 0.* + + +```opensips title="Set max_expires parameter" +... +modparam("registrar", "max_expires", 120) +... +``` + + +#### default_q (integer) + + +The parameter represents default q value for new contacts. Because +OpenSIPS doesn't support float parameter types, the value in the parameter +is divided by 1000 and stored as float. For example, if you want +default_q to be 0.38, use value 380 here. + + +*Default value is 0.* + + +```opensips title="Set default_q parameter" +... +modparam("registrar", "default_q", 1000) +... +``` + + +#### tcp_persistent_flag (string) + + +The parameter specifies the message flag to be used to control the +module behaviour regarding TCP connections. If the flag is set for a +REGISTER via TCP containing a TCP contact, the module, via the +"save()" function, will set the lifetime of the TCP +connection to the contact expire value. By doing this, the TCP +connection will stay on as long as the contact is valid. + + +*Default value is -1 (disabled).* + + +```opensips title="Set tcp_persistent_flag parameter" +... +modparam("registrar", "tcp_persistent_flag", "TCP_PERSIST_DURATION") +... +``` + + +#### realm_prefix (string) + + +Prefix to be automatically strip from realm. As an alternative to +SRV records (not all SIP clients support SRV lookup), a subdomain of +the master domain can be defined for SIP purposes (like +sip.mydomain.net pointing to same IP address as the SRV record for +mydomain.net). By ignoring the realm_prefix "sip.", at registration, +sip.mydomain.net will be equivalent to mydomain.net . + + +*Default value is NULL (none).* + + +```opensips title="Set realm_prefix parameter" +... +modparam("registrar", "realm_prefix", "sip.") +... +``` + + +#### case_sensitive (integer) + + +If set to 1 then AOR comparison will be case +sensitive (as RFC3261 instructs), if set to 0 then +AOR comparison will be case insensitive. + + +*Default value is 1.* + + +```opensips title="Set case_sensitive parameter" +... +modparam("registrar", "case_sensitive", 0) +... +``` + + +#### received_avp (str) + + +Registrar will store the value of the AVP configured by this +parameter in the received column in the user location database. +It will leave the column empty if the AVP is empty. The AVP should +contain a SIP URI consisting of the source IP, port, +and protocol of the REGISTER message being processed. + + +> [!NOTE] +> The value of this parameter should be the same as the value of +corresponding parameter of nathelper module. + + +*Default value is "NULL" (disabled).* + + +```opensips title="Set received_avp parameter" +... +modparam("registrar", "received_avp", "$avp(rcv)") +... +``` + + +#### received_param (string) + + +The name of the parameter that will be appended to Contacts of +200 OK when the received URI was set by nathelper module. + + +*Default value is "received".* + + +```opensips title="Set received_param parameter" +... +modparam("registrar", "received_param", "rcv") +... +``` + + +#### allow_dup_cseq (boolean) + + +Some SIP stacks will re-REGISTER using the same Call-ID and CSeq values. +While rejecting such requests is consistent with RFC 3261 § 10.3.7, enabling +this parameter instructs the registrar to accept them instead, +improving interoperability. + + +*Default value is *false* (duplicate CSeq is rejected).* + + +```opensips title="Setting the allow_dup_cseq parameter" +... +# loose RFC 3261 compliance: allow REGISTER requests with duplicate CSeq +modparam(" +``` + + +#### expires_max_deviation (integer) + + +Set this parameter in order to add a random +/- deviation up to +and including the given value to the expiration interval of a +newly registered contact. For example, if this parameter is set to +*100* and a phone registers for 1800 sec, the final +expiry will be a random number in the [1700, 1900] interval. +By randomizing the registration lifetimes of the contacts, the +server is better equipped to deal with a post-restart *registration +storm*, when all TCP connections are lost and a significant portion of +UAs will re-register at the same time. Thanks to the contact lifetime +randomization, the registration storm will only happen once rather +than, e.g., every 1800 seconds following the restart. + + +*Default value is 0 (no deviation).* + + +```opensips title="Setting the expires_max_deviation parameter" +... +# add a random +/- 0-100 seconds to each registration lifetime +modparam(" +``` + + +#### max_contacts (integer) + + +The parameter can be used to limit the number of contacts per +AOR (Address of Record) in the user location database. Value 0 +disables the check. +This is the default value and will be used only if no other value +(for max_contacts) is passed as parameter to the save() function. +That's it - the function parameter overwride this global parameter. + + +*Default value is 0.* + + +```opensips title="Set max_contacts parameter" +... +# Allow no more than 10 contacts per AOR +modparam(" +``` + + +#### max_username_len (integer) + + +The maximum length of the "username" part of an Address-of-Record SIP URI. + + +Default value is **64**. + + +```opensips title="Setting the *max_username_len* module parameter" +modparam(" +``` + + +#### max_domain_len (integer) + + +The maximum length of the "domain" part of an Address-of-Record SIP URI. + + +Default value is **64**. + + +```opensips title="Setting the *max_domain_len* module parameter" +modparam(" +``` + + +#### max_aor_len (integer) + + +The maximum length of an Address-of-Record SIP URI. + + +Default value is **256**. + + +```opensips title="Setting the *max_aor_len* module parameter" +modparam(" +``` + + +#### max_contact_len (integer) + + +The maximum length of a Contact header field SIP URI. + + +Default value is **255**. + + +```opensips title="Setting the *max_contact_len* module parameter" +modparam(" +``` + + +#### retry_after (integer) + + +The registrar can generate 5xx reply to REGISTER in various +situations. It can, for example, happen when the +`max_contacts` parameter is set and the +processing of REGISTER request would exceed the limit. In this case +the registrar would generate "503 Service Unavailable" response. + + +If you want to add the Retry-After header field in 5xx replies, set +this parameter to a value grater than zero (0 means do not add the +header field). See section 20.33 of RFC3261 for more details. + + +*Default value is 0 (disabled).* + + +```opensips title="Set retry_after parameter" +... +modparam("registrar", "retry_after", 30) +... + +``` + + +#### sock_hdr_name (string) + + +Header which contains a socket description (proto:IP:port) to override +the received socket info. The header will be search and used only if +the flag 's' (Socket header) is set at "save()" time. + + +This makes sense only in multiple replicated servers scenarios. + + +*Default value is NULL.* + + +```opensips title="Set sock_hdr_namer parameter" +... +modparam("registrar", "sock_hdr_name", "Sock-Info") +... + +``` + + +#### mcontact_avp (string) + + +AVP to store the modified binding/contact that is set during cached +registrations scenario (when REGISTER is forwarded to another +registrar). The AVP will be used to extract the "expires" value +returned in the 200 OK by the main registrar. + + +This makes sense only in cached registrations scenario, where your +OpenSIPS is caching registrations before forwarding them to the main +registrar. + + +*Default value is NULL.* + + +```opensips title="Set mcontact_avp parameter" +... +modparam("registrar", "mcontact_avp", "$avp(orig_ct)") +... +route { + ... + # before forwarding the REGISTER request, save the outgoing contact. + # Be SURE to do it after all the possible changes over the contact, + # like fix_nated_contact() + $avp(orig_ct) = $ct.fields(uri); + t_on_reply("do_save"); + t_relay("udp:ip:port"); + ... +} +... +onreply_route[do_save] { + if ($rs=="200") + save("location"); +} +... + +``` + + +#### attr_avp (string) + + +AVP to store specific additional information for each registration. +This information is read from the AVP and stored (in memory, db +or both) at every registrar 'save()'. When a registrar 'lookup()' or +'is_registered()' function is called, the stored information is +pushed into a message branch attribute with the same name as +*attr_avp* (see $msg.branch.attr() core variable) + + +When doing parallel call forking, the contact attributes will be +pushed to the attributes of the corresponding branch + + +*Default value is NULL.* + + +```opensips title="Set attr_avp parameter" +# reading attributes from the attr_pvar when doing parallel forking +... +modparam("registrar", "attr_avp", "$avp(attr)") + +... +if (is_method("REGISTER")) { + $avp(attr) = "contact_info"; + save("location"); + exit; +} +... +lookup("location"); +# list all resulted branches and their attribute +$var(i) = 0; +while ($(msg.branch.uri[$var(i)])!=NULL) { + xlog("branch $var(i): $(msg.branch.uri[$var(i)]), attr=$(msg.branch.attr(attr)[$var(i)])\n"); + $var(i) = $var(i) + 1; +} +.... +t_on_branch("parallel_fork"); +t_relay(); +... +branch_route [parallel_fork] { + xlog("Attributes for branch $T_branch_idx: $tm.branch.attr(attr)\n"); +} + + +``` + + +#### gruu_secret (string) + + +The string that will be used in XORing when generating +temporary GRUUs. + + +*If not set, 'OpenSIPS' is the default secret.* + + +```opensips title="Set gruu_secret parameter" +... +modparam("registrar", "gruu_secret", "top_secret") +... + +``` + + +#### disable_gruu (int) + + +Globally disable GRUU handling + + +*Default value is 1 ( GRUU will not be handled ).* + + +```opensips title="Set gruu_secret parameter" +... +modparam("registrar", "disable_gruu", 0) +... + +``` + + +#### pn_enable (boolean) + + +Enable SIP Push Notification support ([RFC 8599](https://tools.ietf.org/html/rfc8599)). +If enabled, Contact header field URIs which include all +[pn ct match params](#param_pn_ct_match_params) will be matched against +existing bindings using only these parameters. Otherwise, +the module will attempt to match them as usual, using the current +usrloc [matching_mode](../usrloc#param_matching_mode). + + +*Default value is **false**.* + + +```opensips title="Setting the pn_enable parameter" +... +modparam("registrar", "pn_enable", true) +... +``` + + +#### pn_providers (string) + + +A list of supported Push Notification providers. While only three +possible values are defined by RFC 8599 ("apns", "fcm" and "webpush"), +non-standard values may be specified as well. + + +*Default value is **NULL** +(not set).* + + +```opensips title="Setting the pn_providers parameter" +... +modparam("registrar", "pn_providers", "apns, fcm, webpush") +... +``` + + +#### pn_ct_match_params (string) + + +The minimally required list of RFC 8599 parameters (custom ones are +accepted as well) which must be present in a Contact URI and +identically match an existing binding in order for the binding +to be refreshed during a SIP re-REGISTER. If at least one such +parameter is missing from a Contact header field URI, the module +will fall back to performing regular contact matching. + + +> [!NOTE] +> If all above PN Contact URI parameters match an existing +> binding, the match is considered to be successful regardless if +> other parts of the SIP URI do not match (e.g. hostname, port, +> other URI parameters, etc.). + + +After calling *lookup()* or +[afunc pn process purr](#afunc_pn_process_purr), the above PN-related +parameters will be automatically stripped from the resulting +Request and Contact URI event parameter, respectively. + + +*Default value is **"pn-provider, pn-prid, pn-param"**.* + + +```opensips title="Setting the pn_ct_match_params parameter" +... +modparam("registrar", "pn_ct_match_params", "pn-provider, pn-prid") +... +``` + + +#### pn_pnsreg_interval (integer) + + +For devices capable of waking up and refreshing their binding on +their own (signified by the *";+sip.pnsreg"* +Contact header field parameter), this setting denotes the +prior-to-expiration interval advertised by the server at which the +device should issue its binding refresh request. + + +*Default value is **130** +(seconds before expiry).* + + +```opensips title="Setting the pn_pnsreg_interval parameter" +... +modparam("registrar", "pn_pnsreg_interval", 140) +... + +``` + + +#### pn_trigger_interval (integer) + + +If a binding refresh REGISTER request from a given SIP endpoint does +not arrive within at least [pn trigger interval](#param_pn_trigger_interval) +seconds prior to expiration (e.g. because the device does not +support *";+sip.pnsreg"* or because of other +error conditions), the [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +usrloc event will be triggered. + + +Once [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +is triggered, the script writer should use +the RFC 8599 parameters from the Contact URI in order to generate a +Push Notification request to the PN provider of the device, in +order to cause the device to wake up and re-register. + + +*Default value is **120** +(seconds before expiry).* + + +```opensips title="Setting the pn_trigger_interval parameter" +... +modparam("registrar", "pn_trigger_interval", 130) +... + +``` + + +#### pn_skip_pn_interval (integer) + + +Following a successful (re)registration of a contact, this setting +denotes a time interval, in seconds, during which the contact is +assumed to be reachable, so any Push Notifications will be skipped. + + +*Default value is **0** seconds +(always generate Push Notifications).* + + +```opensips title="Setting the pn_skip_pn_interval parameter" +... +modparam("registrar", "pn_skip_pn_interval", 10) +... +``` + + +#### pn_refresh_timeout (integer) + + +This timeout starts counting following a *lookup()* or a +[afunc pn process purr](#afunc_pn_process_purr) which +triggers a Push Notification. The value represents the maximum +allowed sum of the duration required for the Push Notification to +be sent and the duration required for the corresponding +re-registration from the device to arrive. + + +Once this timeout is exceeded for an initial or a mid-dialog +request, any further re-registrations which match the pending Push +Notification will no longer cause the desired effects. For example: + + +- pending initial INVITE transactions will complete and will no +longer auto-fork an additional branch for each REGISTER +sent by the callee side +- pending BYE messages will time out and OpenSIPS will attempt to +route them despite not having received a confirmation that the +target device is actually reachable + + +*Default value is **6** seconds.* + + +```opensips title="Setting the pn_refresh_timeout parameter" +... +modparam("registrar", "pn_refresh_timeout", 10) +... +``` + + +#### pn_enable_purr (boolean) + + +Enable the SIP Push Notification mechanism for long-lived dialogs. +If enabled, the registrar will include a +*"+sip.pnspurr"* +Feature-Caps header field tag in 200 OK replies to REGISTER +requests. This tag represents a unique identifier for the +registration (PURR - Proxy Unique Registration Reference). + + +During dialog setup, each UA may include, in its Contact header, +the PURR value returned by OpenSIPS during registration. By +including the PURR (e.g. ";pn-purr=XXX"), an agent indicates that +it expects to be first awoken by a PN before being able to receive +a mid-dialog request sent by the other party. + + +When enabling this parameter, make sure to also add logic for +[afunc pn process purr](#afunc_pn_process_purr). + + +*Default value is **false**.* + + +```opensips title="Setting the pn_enable_purr parameter" +... +modparam("registrar", "pn_enable_purr", true) +... +``` + + +### Exported Functions + + +#### save(domain[, flags[, aor[, ownership_tag]]]) + + +The function processes a REGISTER message. It can add, remove or +modify usrloc records depending on Contact and Expires HFs in the +REGISTER message. On success, 200 OK will be returned listing all +contacts that are currently in usrloc. On an error, error message +will be send with a short description in reason phrase. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Logical domain within +registrar. If database is used then this must be name of the table which +stores the contacts. +- *flags (string, optional)* - string composed of +one or more of the following flags, comma-separated: + + - *'memory-only'* - (old *m* flag) +save the contacts only in memory cache without no DB operation; + - *'no-reply'* - (old *r* flag) +do not generate a SIP reply to the current REGISTER request. + - *'max-contacts=[int]'* - (old *c* +flag) this flag can be used to limit the number of contacts for this +AOR (Address of Record) in the user location database. +Value 0 disables the check. This parameter overrides the +global "max_contacts" module parameter. + - *'force-registration'* - (old *f* +flag) this flag can be used to force the registration of NEW contacts +even if the maximum number of contacts is reached. In such +a case, older contacts will be removed to make space to the +new ones, without exceeding the maximum allowed number. +This flag makes sense only if "max-contacts" is used. + - *'matching-mode=[val]'* - (old *M* +flag) How the matching should be performed between the uploaded +contacts (by the currently handled REGISTER) and the +already know contacts (in memory or DB). This options will +be used only for the current operation and can be: + - *'0'* - contact URI matching + only + - *'1'* - contact URI and + SIP Call-ID matching + - *''* - only + the value of the given URI param will be used for + matching (for example ) + - *'path-off'* - (old *p0* flag) +(Path support - 'off' mode) - The Path header is saved into usrloc, +but is never included in the reply. + - *'path-lazy'* - (old *p1* flag) +(Path support - lazy mode) The Path header is saved into usrloc, but is only +included in the reply if path support is indicated in the +registration request by the "path" option +of the "Supported" header. + - *'path-strict'* - (old *p2* flag) +(Path support - strict mode) - The path header is only saved into usrloc, +if path support is indicated in the registration request by the +"path" option of the "Supported" +header. If no path support is indicated, the request is +rejected with "420 - Bad Extension" and the +header "Unsupported: path" is included in +the reply along with the received "Path" +header. This mode is the one recommended by RFC-3327. + - *'path-received'* - (old *v* flag) +if set, the "received" parameter of the first Path +URI of a registration is set as received-uri and the NAT +branch flag is set for this contact. This is useful if +the registrar is placed behind a SIP loadbalancer, which +passes the nat'ed UAC address as "received" +parameter in it's Path uri. + - *'only-request-contacts'* - (old *o* +flag) Only include the REGISTER request's Contacts in the 200 OK +reply, in case the registration is successful. While this +is against RFC 3261, it may be useful in certain scenarios. + - *'socket-header'* - (old +*s* flag) look into REGISTER request +for a header which contains a socket +description (proto:IP:port). This socket info will be +stored by register instead of the received socket info. + - *'min-expires=[int]'* - (old +*e* flag) this +flag can be used to set minimum register expiration time. +Values lower than this minimum will be automatically set +to the minimum. Value 0 disables the checking. +This parameter overrides the global +[min expires](#param_min_expires) module parameter. + - *'max-expires=[int]'* - (old +*E* flag) this +flag can be used to set maximum register expiration time. +Values higher than this maximum will be automatically set +to the maximum. Value 0 disables the checking. +This parameter overrides the global +[max expires](#param_max_expires) module parameter. +This parameter is a string composed of a set of flags. +- *aor (string, optional)* - a custom AOR; if missing, +the AOR will be taken from the default place - the TO header URI. +- *ownership_tag (string, optional)* - a cluster-shared +tag (see the clusterer module documentation for more details) which +will be attached to each contact saved from the current request. +This tag is only relevant in clustered user location scenarios and +helps determine the current logical owner node of a contact. This, +in turn, is useful in order to restrict nodes which are not +currently responsible for this contact from performing certain +actions (for example: incorrectly originating pings from a +non-owned virtual IP address in highly-available setups). + + +This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. + + +If you plan to use the "save()" function in reply route, +please refer to [mcontact avp](#param_mcontact_avp) module parameter. + + +```opensips title="save usage" +... +# save into 'location', no flags, use default AOR (TO URI) +save("location"); +... +# save into 'location', do not update DB, max 5 contacts per AOR, +# use default AOR (TO URI) +save("location","memory-only, max-contacts=5"); +... +# save into 'location', no flags, use as AOR the FROM URI +save("location","",$fu); +... +# save into 'location', no DB update, force registration, take AOR from AVP +save("location","memory-only, no-reply", $avp(aor)); +... +# save into 'location', mark the contacts with the "vip" ownership tag and +# replicate these contacts to the backup node, which does not currently own "vip" +save("location", , , "vip"); +... +``` + + +#### remove(domain, AOR[, [contact][, [next_hop][, [sip_instance], [bflag]]]]) + + +Explicitly remove contacts behind a given address-of-record. + + +Meaning of the parameters is as follows: + + +- *domain (static string* - Logical domain within the registrar. +If a database is used, then this must be name of the table which +stores the contacts. +- *AOR (string)* - address-of-record to be searched (SIP URI) +- *contact (string, optional)* - SIP URI filter +for the contact to be removed. This must be the full SIP URI +as used during registered. +- *next_hop (string, optional)* - the next +SIP IP address/hostname on the way back to this contact. See +the section below for details on how the next hop is +computed. Hostnames are resolved before matching. +- *sip_instance (string, optional)* - a +"+sip.instance" value to be used for filtering purposes. +- *blfag (string, optional)* - a +Branch Flag to be used for filtering purposes. + + +> [!IMPORTANT] +> The IP address of each +> contact (for matching purposes) is computed as follows: +> - a. if a Path header is present, the hostname part of the +> Path URI will be resolved as the contact's IP address. +> - b. otherwise, if by using nathelper, the "Received" value +> (source IP of the next hop) is set for a contact, this +> becomes the chosen hostname to be resolved as the contact's +> IP address. +> - c. otherwise, the "hostname" part of the Contact header +> field URI is chosen to be resolved as the contact's IP +> address. + + +This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. + + +```opensips title="remove usage" +... +# remove all contacts belonging to the "bob" AOR +remove("location", "sip:bob@atlanta.com"); +... +# remove only bob's home phone contact +remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78"); +... +# remove all bob's phones which are behind "50.60.50.60" +# note that "contact" parameter has to be specified with NULL value even though not used +$var(next_hop) = "50.60.50.60" +remove("location", "sip:bob@atlanta.com", , $var(next_hop)); +... +# remove bob's phone with contact "sip:bob@46.50.64.78" that is behind "50.60.50.60" +remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78", "50.60.50.60"); +... +# remove all contacts behind bob's mobile device X +remove("location", "sip:bob@atlanta.com", , , "") +``` + + +#### remove_ip_port(IP,Port, domain, [AOR]) + + +Remove all contacts behind a specific IP and Port, optionally filtering by AOR. + + +Meaning of the parameters is as follows: + + +- *IP (string)* - IP of the Contact to be removed +- *Port (integer)* - Port of the Contact to be removed +- *domain (static string* - Logical domain within the registrar. +If a database is used, then this must be name of the table which +stores the contacts. +- *AOR (string, optional)* - address-of-record to be searched (SIP URI) + + +This function can be used from ALL ROUTES. + + +```opensips title="remove_ip_port usage" +... +# remove all contacts behind 8.8.8.8 port 43213 +remove_ip_port("8.8.8.8",43213,"location"); +... +# remove only bob's contacts behind the 8.8.8.8:43213 host +remove_ip_port("8.8.8.8",43213,"location","sip:bob@atlanta.com"); +... +``` + + +#### lookup(domain [, flags [, aor]]) + + +The functions extracts username from Request-URI and tries to find +all contacts for the username in usrloc. If there are no such +contacts, -1 will be returned. If there are such contacts, +Request-URI will be overwritten with the contact that has +the highest q value and optionally the rest will be appended to +the message (depending on append_branches parameter value). + + +If the method_filtering option is enabled, the lookup function +will return only the contacts that support the method of the +processed request. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Name of table that +should be used for the lookup. +- *flags (string, optional) - string composed of one or more of +the following flags, comma-separated:* + + - *'no-branches'* - (old *b* flag) this +flag controls how the *lookup()* function processes multiple contacts. +If there are +multiple contacts for the given username in usrloc and this +flag is not set, Request-URI will be overwritten with the +highest-q rated contact and the rest will be appended to +sip_msg structure and can be later used by tm for forking. If +the flag is set, only Request-URI will be overwritten +with the highest-q rated contact and the rest will be left +unprocessed. + - *'to-branches-only'* - (old *B* flag) +this flags forces all found contacts to be uploaded only as branches (in the +destination set) and not at all in the R-URI of the +current message. Using this option allows the *lookup()* function to +also be used in the context of a SIP reply. + - *'branch'* - (old *r* flag) this flag +enables searching through existing branches for aor's and expanding +them to contacts. For example, you have got AOR A in your +ruri but you also want to forward your calls to AOR B. In order +to do this, you must put AOR B in a branch, and if this flag +enabled, the function will also expand AOR B to contacts, +which will be put back into the branches. The AOR's that were +in branches before the function call shall be removed. +**WARNING:** +*if you want this flag activated, +the 'no-branches' flag must not be set, because by setting +that flag you won't allow *lookup()* to write in a branch.* + - *'method-filtering'* - (old *m* flag) +setting this flag will enable contact filtering based on the supported methods +listed in the "Allow" header field during registration. +Contacts which did not present an "Allow" header field during +registration are assumed to support all standard SIP methods. + - *'ua-filtering=[val]'* (old *u* flag) +(User-Agent filtering) - this flag enables regexp filtering by user-agent. +It's useful with enabled append_branches parameter. The value must use the +format '/regexp/'. + - *'case-insensitive'* (old *i* flag) - +this flag enables case insensitive filtering for the 'ua-filtering' flag. + - *'extended-regexp'* - (old *e* flag) +this flag enables using of extended regexp format for the 'ua-filtering' flag. + - *'global'* (old *g* flag) (Global +lookup) - this flag is only relevant with federated user location clustering. +If set, the *lookup()* function will not only perform the classic +in-memory "search-AoR-and-push-branches" operation, but will +also perform a metadata lookup and append an additional branch +for each returned result. The "in-memory branches" correspond +to local contacts (current location), while the "metadata +branches" correspond to contacts available on one or more of +the remaining locations of the platform. +The AoR metadata consists of the minimally required information +in order for one of the VoIP platform's locations (data +centers) to advertise the presence of a locally registered AoR +for the global platform. Specifically, this consists of two +pieces of information: + + +the AoR (e.g. "vladimir@federation-cluster") + + +the home IP (e.g. "10.0.0.223") + - *'max-ping-latency=[int]'* - (old *y* +flag) maximally accepted contact pinging latency (microseconds). Contacts of an +AoR with a higher latency will be discarded during *lookup()*. + - *'sort-by-latency'* - (old *Y* flag) +contacts will be picked in ascending order of their last successful +pinging latency (fastest ping -> slowest ping). This flag may +work together with the "max-ping-latency" flag. +- *AOR (string, optional)* - AOR to lookup for; if +missing, the RURI is used as AOR; + + +Return codes: + + +- **1** - contacts found and successfully +pushed as branches. Contacts which required awakening prior to being +reachable are being notified via async Push Notifications. +- **2** - successfully started at least one +async Push Notification for the found contacts, however no extra branches +were populated (i.e. there is no need to call t_relay()). +- **-1** - no contact found. +- **-2** - contacts found, but neither of them +supports the current SIP method. +- **-3** - internal error during processing. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="lookup usage" +... +lookup("location"); # simple lookup + #or +lookup("location", "method-filtering"); # lookup with method filtering + #or +lookup("location", "branch"); # lookup with aor branch search; + # all contacts except the first one shall be put + # in the branches + #or +lookup("location", "ua-filtering=/phone/i"); # lookup with user-agent filtering + #or +lookup("location", "", $var(aor)); # simple lookup with AOR from var +switch ($retcode) { + case -1: + case -3: + sl_send_reply(404, "Not Found"); + exit; + case -2: + sl_send_reply(405, "Not Found"); + exit; +}; +... +``` + + +#### is_registered(domain ,[AOR]) + + +The function returns true if an AOR is registered, false otherwise. +The function does not modify the message being process. + + +> [!NOTE] +> If called for a reply (from onreply_route), you must pass an +> AOR (as parameter), otherwise the function will fail. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Name of table that +should be used for the lookup. +- *AOR (string, optional)* - AOR to lookup for; if +missing, the source if the AOR is the "To" header for REGISTER +request, "From" header for any other sip request. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. + + +```opensips title="is_registered usage" +... +/**/ +if (is_method("REGISTER")) { + /* automatically uses the URI from the To header */ + if (is_registered("location")) { + xlog("this AOR is registered\n") + ... + } +}; +/* check the From uri whether this aor is registered or not */ +if (is_registered("location",$fu)) { + xlog("caller is registered\n"); +} +... +``` + + +#### is_contact_registered(domain ,[AOR],[contact],[callid]) + + +The function returns true if a contact and/or a callid from a certain AOR is registered, false otherwise. +The function does not modify the message being process. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Name of table that should be +used for the lookup. +- *AOR (string, optional)* - AOR to lookup for; if +missing, the source if the AOR is the "To" header for REGISTER +request, "From" header for any other sip request. +- *contact (contact, optional)* (optional)- SIP +URI to check if there is a registration with this URI as cotact +(this may help you to make distinction between multiple +registrations for the same user/AOR). +- *callid (string, optional)* - callid to check if a +contact if registered with this callid (this may help you to +make distinction between newly registered contact (callid +not registered so far) and re-registration (callid already +registered). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. + + +```opensips title="is_contact_registered usage" +... +/* block users which are not registered... */ +if (is_method("INVITE")) { + if (!is_contact_registered("location")) { + sl_send_reply(401, "Unauthorized"); + ... + } +} + +/* ... or check whether the 2nd Contact URI is registered or not */ +if (is_method("INVITE")) { + if (is_contact_registered("location", $fu, $(ct.fields(uri)[1]))) + xlog("caller is registered\n"); +} +... +``` + + +#### is_ip_registered(domain ,[AOR],IPvar,[PORTvar]) + + +The function returns true if there is at least one contact that has +been registered from the IP in the IPvar variable ( and from the optional +PORTvar variable ). +The IP is matched against the received host, if it exists, or the contact host otherwise. +This function does not modify the message being process. This function +replaces the old "is_other_contact" function. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Name of table that should be +used for the lookup. +- *AOR (string, optional)* - AOR to lookup for; if +missing, the source if the AOR is the "To" header for REGISTER +request, "From" header for any other sip request. +- *IPvar (var)* - the variable containing the IP matched against +the contact host or the received host (see above). If the +*IPvar* is an AVP containing multiple values/IPs, +then all the values are checked. +- *PORTvar (var, optional)* - the variable containing the port to be +matched against the contact host or the received host (see above). If the +*IPvar* is an AVP containing multiple values/IPs, then the PORTvar +is expected to contain the same number of entries, and all the values are checked. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. + + +```opensips title="is_ip_registered usage" +... +/* check the source ip whether it is already registered */ +if (is_method("REGISTER")) { + if (is_ip_registered("location",$tu,$si)) { + xlog("already registered from this ip\n"); + ... + } +}; +... +``` + + +#### add_sock_hdr(hdr_name) + + +Adds to the current REGISTER request a new header with +"hdr_name" which contains the description of the +received socket (proto:ip:port) + + +This makes sense only in multiple replicated servers scenarios. + + +Meaning of the parameters is as follows: + + +- *hdr_name (string)* - header name to be used. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="add_sock_hdr usage" +... +add_sock_hdr("Sock-Info"); +... +``` + + +### Exported Asynchronous Functions + + +#### pn_process_purr(domain) + + +Perform mid-dialog request processing, according to RFC 8599. For +such requests, search the R-URI and topmost Route header field URI for +a *";pn-purr"* parameter value that both matches the +OpenSIPS PURR format and corresponds to an usrloc registration. Once a +usrloc contact is located, trigger an [E_UL_CONTACT_REFRESH](../usrloc#event_E_UL_CONTACT_REFRESH) +event and place the request on async hold for at most +[pn refresh timeout](#param_pn_refresh_timeout) seconds, until a matching +REGISTER request arrives. + + +If processing ends before triggering the Push Notification, the request +will no longer be put on async hold, with the resume route being +immediately called. + + +Meaning of the parameters is as follows: + + +- *domain (static string)* - Logical domain within +registrar. If a database is used, then this must be name of the +table which stores the contacts. + + +**Return Codes** + + +- **1** - Success, PN was launched. +- **2** - Success, +but PN was not launched (due to missing PURR, foreign PURR or +offline contact) +- **-1** - Internal Error + + +```opensips title="async pn_process_purr() usage" +route { + ... + if (has_totag()) { + if (is_method("ACK") && t_check_trans()) { + t_relay(); + exit; + } + + if (!loose_route()) { + send_reply(404, "Not Found"); + exit; + } + + if (!is_method("ACK")) + async (pn_process_purr("location"), resume_route); + + route(relay); + exit; + } +} + +route [resume_route] { + $var(rc) = $rc; + xlog("pn_process_purr() finished with $var(rc)\n"); + + ... +} +``` + + +### Exported Statistics + + +#### max_expires + + +Value of max_expires parameter. + + +#### max_contacts + + +The value of max_contacts parameter. + + +#### defaults_expires + + +The value of default_expires parameter. + + +#### accepted_regs + + +Number of accepted registrations. + + +#### rejected_regs + + +Number of rejected registrations. + + +## Frequently Asked Questions + + +**Q: What happened with the old "append_branch" module parameter?** + + +It was removed as global option, as the "lookup" +function takes this option via the flag "b" (append Branches) +See the documentation of the "lookup" function. + + +**Q: What happened with the old "method_filtering" module parameter?** + + +It was removed as global option, as the "lookup" +function takes this option via the flag "m" (Method filtering) +See the documentation of the "lookup" function. + + +**Q: What happened with the old "sock_flag" module parameter?** + + +It was removed as global option, as the "save" +function takes this option via the flag "s" (Socket header) +See the documentation of the "save" function. + + +**Q: What happened with the old "use_path" and "path_mode" module parameters?** + + +They were removed as global option, as the "save" +function takes these options via the flag "px" (path support) +See the documentation of the "save" function. + + +**Q: What happened with the old "path_use_received" module parameter?** + + +It was removed as global option, as the "save" +function takes this option via the flag "v" (path receiVed) +See the documentation of the "save" function. + + +**Q: What happened with the old "nat_flag" module parameter?** + + +It was removed, as the module internally loads this value from the +"USRLOC" module (see the "nat_bflag" +USRLOC parameter). + + +**Q: What happened with the old "use_domain" module parameter?** + + +It was removed, as the module internally loads this option from the +"USRLOC" module. This was done in order to simplify the +configuration. + + +**Q: What happened with the old "save_noreply" and "save_memory" functions?** + + +There functions were merged into the new +"save(domain,flags)" functions. If a reply should be +sent or if the DB should be updated also is controlled via the +flags. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +**Q: What happened to the desc_time_order parameter?** + + +It was removed, as its functionality was mmigrate into usrloc +module, were there is a parameter with the same name. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/registrar/doc/contributors.xml b/modules/registrar/doc/contributors.xml deleted file mode 100644 index 9da30c4983e..00000000000 --- a/modules/registrar/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 199 - 123 - 2864 - 3030 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 171 - 116 - 2426 - 2055 - - - 3. - Jan Janak (@janakj) - 122 - 73 - 3465 - 1102 - - - 4. - Daniel-Constantin Mierla (@miconda) - 23 - 19 - 160 - 105 - - - 5. - Vlad Paiu (@vladpaiu) - 21 - 12 - 729 - 96 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 21 - 9 - 243 - 497 - - - 7. - Razvan Crainea (@razvancrainea) - 20 - 15 - 267 - 75 - - - 8. - Ionut Ionita (@ionutrazvanionita) - 16 - 4 - 763 - 248 - - - 9. - Jiri Kuthan (@jiriatipteldotorg) - 15 - 9 - 538 - 45 - - - 10. - Andreas Granig - 13 - 7 - 527 - 36 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Maksym Sobolyev (@sobomax), Andrei Pelinescu-Onciul, Ovidiu Sas (@ovidiusas), Juha Heinanen (@juha-h), Nick Altmann (@nikbyte), Ancuta Onofrei, Elena-Ramona Modroiu, Peter Lemenkov (@lemenkov), Dan Pascu (@danpascu), Sergio Gutierrez, Carsten Bock, Jeffrey Magder, Kobi Eshun (@ekobi), Dudu Ben Moshe, Marcus Hunger, Julián Moreno Patiño, Phil D'Amore, Klaus Darilion, Irina-Maria Stanescu, Dmitry Semyonov, Konstantin Bokarius, Andrej Solovjov, Jesus Rodrigues, Dusan Klinec (@ph4r05), Ruslan Bukin, Saúl Ibarra Corretgé (@saghul), @jalung, Tolga Tarhan, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Andrej Solovjov - Jul 2025 - Jul 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Sep 2003 - May 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2013 - May 2025 - - - 4. - Dudu Ben Moshe - Feb 2024 - Feb 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Jul 2004 - Nov 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 7. - Razvan Crainea (@razvancrainea) - Apr 2011 - Apr 2023 - - - 8. - Vlad Paiu (@vladpaiu) - Sep 2011 - Nov 2022 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2020 - - - 10. - @jalung - Aug 2017 - Aug 2017 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Dusan Klinec (@ph4r05), Nick Altmann (@nikbyte), Tolga Tarhan, Saúl Ibarra Corretgé (@saghul), Ruslan Bukin, Irina-Maria Stanescu, Kobi Eshun (@ekobi), Phil D'Amore, Sergio Gutierrez, Klaus Darilion, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Dan Pascu (@danpascu), Ancuta Onofrei, Marcus Hunger, Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Jeffrey Magder, Carsten Bock, Andreas Granig, Dmitry Semyonov, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Dudu Ben Moshe, Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Vlad Paiu (@vladpaiu), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Irina-Maria Stanescu, Kobi Eshun (@ekobi), Sergio Gutierrez, Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Marcus Hunger, Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Carsten Bock, Andreas Granig, Jan Janak (@janakj). -
- -
diff --git a/modules/registrar/doc/registrar.xml b/modules/registrar/doc/registrar.xml deleted file mode 100644 index ce3899e78b8..00000000000 --- a/modules/registrar/doc/registrar.xml +++ /dev/null @@ -1,42 +0,0 @@ - -registrar"> -save()"> -lookup()"> - - - - - - - - - - - - - - - - -%docentities; - -]> - - - - registrar Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - ©right; 2020 &OSS; - diff --git a/modules/registrar/doc/registrar_admin.xml b/modules/registrar/doc/registrar_admin.xml deleted file mode 100644 index 07eeabbca8d..00000000000 --- a/modules/registrar/doc/registrar_admin.xml +++ /dev/null @@ -1,1069 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module contains SIP REGISTER request processing logic, per RFC - 3261. On top of this support, several extensions are available: - - - &supported_rfc; - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - usrloc - User Location Module. - - - - - signaling - Signaling module. - - - - - event_routing, - if is set to true. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>default_expires</varname> (integer) - - If the processed message contains neither Expires - HFs nor expires contact parameters, this value - will be used for newly created usrloc records. The parameter contains - number of second to expire (for example use 3600 for one hour). - - - - Default value is 3600. - - - - Set <varname>default_expires</varname> parameter - -... -modparam("registrar", "default_expires", 1800) -... - - -
-
- <varname>min_expires</varname> (integer) - - The minimum expires value of a Contact, values lower than this - minimum will be automatically set to the minimum. Value 0 disables - the checking. - - - - Default value is 60. - - - - Set <varname>min_expires</varname> parameter - -... -modparam("registrar", "min_expires", 60) -... - - -
-
- <varname>max_expires</varname> (integer) - - The maximum expires value of a Contact, values higher than this - maximum will be automatically set to the maximum. Value 0 disables - the checking. - - - - Default value is 0. - - - - Set <varname>max_expires</varname> parameter - -... -modparam("registrar", "max_expires", 120) -... - - -
- -
- <varname>default_q</varname> (integer) - - The parameter represents default q value for new contacts. Because - &osips; doesn't support float parameter types, the value in the parameter - is divided by 1000 and stored as float. For example, if you want - default_q to be 0.38, use value 380 here. - - - - Default value is 0. - - - - Set <varname>default_q</varname> parameter - -... -modparam("registrar", "default_q", 1000) -... - - -
- -
- <varname>tcp_persistent_flag</varname> (string) - - The parameter specifies the message flag to be used to control the - module behaviour regarding TCP connections. If the flag is set for a - REGISTER via TCP containing a TCP contact, the module, via the - save() function, will set the lifetime of the TCP - connection to the contact expire value. By doing this, the TCP - connection will stay on as long as the contact is valid. - - - - Default value is -1 (disabled). - - - - Set <varname>tcp_persistent_flag</varname> parameter - -... -modparam("registrar", "tcp_persistent_flag", "TCP_PERSIST_DURATION") -... - - -
- -
- <varname>realm_prefix</varname> (string) - - Prefix to be automatically strip from realm. As an alternative to - SRV records (not all SIP clients support SRV lookup), a subdomain of - the master domain can be defined for SIP purposes (like - sip.mydomain.net pointing to same IP address as the SRV record for - mydomain.net). By ignoring the realm_prefix "sip.", at registration, - sip.mydomain.net will be equivalent to mydomain.net . - - - - Default value is NULL (none). - - - - Set <varname>realm_prefix</varname> parameter - -... -modparam("registrar", "realm_prefix", "sip.") -... - - -
- - -
- <varname>case_sensitive</varname> (integer) - - If set to 1 then AOR comparison will be case - sensitive (as RFC3261 instructs), if set to 0 then - AOR comparison will be case insensitive. - - - - Default value is 1. - - - - Set <varname>case_sensitive</varname> parameter - -... -modparam("registrar", "case_sensitive", 0) -... - - -
- -
- <varname>received_avp</varname> (str) - - Registrar will store the value of the AVP configured by this - parameter in the received column in the user location database. - It will leave the column empty if the AVP is empty. The AVP should - contain a SIP URI consisting of the source IP, port, - and protocol of the REGISTER message being processed. - - - - The value of this parameter should be the same as the value of - corresponding parameter of nathelper module. - - - - - Default value is "NULL" (disabled). - - - - Set <varname>received_avp</varname> parameter - -... -modparam("registrar", "received_avp", "$avp(rcv)") -... - - -
- -
- <varname>received_param</varname> (string) - - The name of the parameter that will be appended to Contacts of - 200 OK when the received URI was set by nathelper module. - - - - Default value is "received". - - - - Set <varname>received_param</varname> parameter - -... -modparam("registrar", "received_param", "rcv") -... - - -
- - ®_modparams; - -
- <varname>retry_after</varname> (integer) - - The registrar can generate 5xx reply to REGISTER in various - situations. It can, for example, happen when the - max_contacts parameter is set and the - processing of REGISTER request would exceed the limit. In this case - the registrar would generate "503 Service Unavailable" response. - - - If you want to add the Retry-After header field in 5xx replies, set - this parameter to a value grater than zero (0 means do not add the - header field). See section 20.33 of RFC3261 for more details. - - - - Default value is 0 (disabled). - - - - Set <varname>retry_after</varname> parameter - -... -modparam("registrar", "retry_after", 30) -... - - -
- -
- <varname>sock_hdr_name</varname> (string) - - Header which contains a socket description (proto:IP:port) to override - the received socket info. The header will be search and used only if - the flag 's' (Socket header) is set at "save()" time. - - - This makes sense only in multiple replicated servers scenarios. - - - - Default value is NULL. - - - - Set <varname>sock_hdr_namer</varname> parameter - -... -modparam("registrar", "sock_hdr_name", "Sock-Info") -... - - -
- -
- <varname>mcontact_avp</varname> (string) - - AVP to store the modified binding/contact that is set during cached - registrations scenario (when REGISTER is forwarded to another - registrar). The AVP will be used to extract the "expires" value - returned in the 200 OK by the main registrar. - - - This makes sense only in cached registrations scenario, where your - OpenSIPS is caching registrations before forwarding them to the main - registrar. - - - - Default value is NULL. - - - - Set <varname>mcontact_avp</varname> parameter - -... -modparam("registrar", "mcontact_avp", "$avp(orig_ct)") -... -route { - ... - # before forwarding the REGISTER request, save the outgoing contact. - # Be SURE to do it after all the possible changes over the contact, - # like fix_nated_contact() - $avp(orig_ct) = $ct.fields(uri); - t_on_reply("do_save"); - t_relay("udp:ip:port"); - ... -} -... -onreply_route[do_save] { - if ($rs=="200") - save("location"); -} -... - - -
-
- <varname>attr_avp</varname> (string) - - AVP to store specific additional information for each registration. - This information is read from the AVP and stored (in memory, db - or both) at every registrar 'save()'. When a registrar 'lookup()' or - 'is_registered()' function is called, the stored information is - pushed into a message branch attribute with the same name as - attr_avp (see $msg.branch.attr() core variable) - - - When doing parallel call forking, the contact attributes will be - pushed to the attributes of the corresponding branch - - - - Default value is NULL. - - - - Set <varname>attr_avp</varname> parameter - -# reading attributes from the attr_pvar when doing parallel forking -... -modparam("registrar", "attr_avp", "$avp(attr)") - -... -if (is_method("REGISTER")) { - $avp(attr) = "contact_info"; - save("location"); - exit; -} -... -lookup("location"); -# list all resulted branches and their attribute -$var(i) = 0; -while ($(msg.branch.uri[$var(i)])!=NULL) { - xlog("branch $var(i): $(msg.branch.uri[$var(i)]), attr=$(msg.branch.attr(attr)[$var(i)])\n"); - $var(i) = $var(i) + 1; -} -.... -t_on_branch("parallel_fork"); -t_relay(); -... -branch_route [parallel_fork] { - xlog("Attributes for branch $T_branch_idx: $tm.branch.attr(attr)\n"); -} - - - -
-
- <varname>gruu_secret</varname> (string) - - The string that will be used in XORing when generating - temporary GRUUs. - - - - If not set, 'OpenSIPS' is the default secret. - - - - Set <varname>gruu_secret</varname> parameter - -... -modparam("registrar", "gruu_secret", "top_secret") -... - - -
-
- <varname>disable_gruu</varname> (int) - - Globally disable GRUU handling - - - - Default value is 1 ( GRUU will not be handled ). - - - - Set <varname>gruu_secret</varname> parameter - -... -modparam("registrar", "disable_gruu", 0) -... - - -
- - &pn_modparams; - -
- -
- Exported Functions -
- - <function moreinfo="none">save(domain[, flags[, aor[, ownership_tag]]])</function> - - - The function processes a REGISTER message. It can add, remove or - modify usrloc records depending on Contact and Expires HFs in the - REGISTER message. On success, 200 OK will be returned listing all - contacts that are currently in usrloc. On an error, error message - will be send with a short description in reason phrase. - - Meaning of the parameters is as follows: - - - - domain (static string) - Logical domain within - registrar. If database is used then this must be name of the table which - stores the contacts. - - - - - flags (string, optional) - string composed of - one or more of the following flags, comma-separated: - - - &save_common_flags; - - 'socket-header' - (old - s flag) look into REGISTER request - for a header which contains a socket - description (proto:IP:port). This socket info will be - stored by register instead of the received socket info. - - - - 'min-expires=[int]' - (old - e flag) this - flag can be used to set minimum register expiration time. - Values lower than this minimum will be automatically set - to the minimum. Value 0 disables the checking. - This parameter overrides the global - module parameter. - - - - 'max-expires=[int]' - (old - E flag) this - flag can be used to set maximum register expiration time. - Values higher than this maximum will be automatically set - to the maximum. Value 0 disables the checking. - This parameter overrides the global - module parameter. - - - - This parameter is a string composed of a set of flags. - - - - aor (string, optional) - a custom AOR; if missing, - the AOR will be taken from the default place - the TO header URI. - - - - - ownership_tag (string, optional) - a cluster-shared - tag (see the clusterer module documentation for more details) which - will be attached to each contact saved from the current request. - This tag is only relevant in clustered user location scenarios and - helps determine the current logical owner node of a contact. This, - in turn, is useful in order to restrict nodes which are not - currently responsible for this contact from performing certain - actions (for example: incorrectly originating pings from a - non-owned virtual IP address in highly-available setups). - - - - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - - If you plan to use the save() function in reply route, - please refer to module parameter. - - - <function>save</function> usage - -... -# save into 'location', no flags, use default AOR (TO URI) -save("location"); -... -# save into 'location', do not update DB, max 5 contacts per AOR, -# use default AOR (TO URI) -save("location","memory-only, max-contacts=5"); -... -# save into 'location', no flags, use as AOR the FROM URI -save("location","",$fu); -... -# save into 'location', no DB update, force registration, take AOR from AVP -save("location","memory-only, no-reply", $avp(aor)); -... -# save into 'location', mark the contacts with the "vip" ownership tag and -# replicate these contacts to the backup node, which does not currently own "vip" -save("location", , , "vip"); -... - - -
- -
- - <function moreinfo="none">remove(domain, AOR[, [contact][, [next_hop][, [sip_instance], [bflag]]]])</function> - - - Explicitly remove contacts behind a given address-of-record. - - Meaning of the parameters is as follows: - - - - domain (static string - Logical domain within the registrar. - If a database is used, then this must be name of the table which - stores the contacts. - - - - - AOR (string) - address-of-record to be searched (SIP URI) - - - - - contact (string, optional) - SIP URI filter - for the contact to be removed. This must be the full SIP URI - as used during registered. - - - - - next_hop (string, optional) - the next - SIP IP address/hostname on the way back to this contact. See - the section below for details on how the next hop is - computed. Hostnames are resolved before matching. - - - - - sip_instance (string, optional) - a - "+sip.instance" value to be used for filtering purposes. - - - - - blfag (string, optional) - a - Branch Flag to be used for filtering purposes. - - - - - IMPORTANT: the IP address of each - contact (for matching purposes) is computed as follows: - - - - a. if a Path header is present, the hostname part of the - Path URI will be resolved as the contact's IP address. - - - - - b. otherwise, if by using nathelper, the "Received" value - (source IP of the next hop) is set for a contact, this - becomes the chosen hostname to be resolved as the contact's - IP address. - - - - - c. otherwise, the "hostname" part of the Contact header - field URI is chosen to be resolved as the contact's IP - address. - - - - - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - - <function>remove</function> usage - -... -# remove all contacts belonging to the "bob" AOR -remove("location", "sip:bob@atlanta.com"); -... -# remove only bob's home phone contact -remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78"); -... -# remove all bob's phones which are behind "50.60.50.60" -# note that "contact" parameter has to be specified with NULL value even though not used -$var(next_hop) = "50.60.50.60" -remove("location", "sip:bob@atlanta.com", , $var(next_hop)); -... -# remove bob's phone with contact "sip:bob@46.50.64.78" that is behind "50.60.50.60" -remove("location", "sip:bob@atlanta.com", "sip:bob@46.50.64.78", "50.60.50.60"); -... -# remove all contacts behind bob's mobile device X -remove("location", "sip:bob@atlanta.com", , , "<urn:uuid:e5e68d40-f08a-4600-b82e-ff4d5d8c1a8f>") - - -
- -
- - <function moreinfo="none">remove_ip_port(IP,Port, domain, [AOR])</function> - - - Remove all contacts behind a specific IP and Port, optionally filtering by AOR. - - Meaning of the parameters is as follows: - - - - IP (string) - IP of the Contact to be removed - - - - - Port (integer) - Port of the Contact to be removed - - - - - domain (static string - Logical domain within the registrar. - If a database is used, then this must be name of the table which - stores the contacts. - - - - - AOR (string, optional) - address-of-record to be searched (SIP URI) - - - - - This function can be used from ALL ROUTES. - - - <function>remove_ip_port</function> usage - -... -# remove all contacts behind 8.8.8.8 port 43213 -remove_ip_port("8.8.8.8",43213,"location"); -... -# remove only bob's contacts behind the 8.8.8.8:43213 host -remove_ip_port("8.8.8.8",43213,"location","sip:bob@atlanta.com"); -... - - -
- -
- - <function moreinfo="none">lookup(domain [, flags [, aor]])</function> - - - The functions extracts username from Request-URI and tries to find - all contacts for the username in usrloc. If there are no such - contacts, -1 will be returned. If there are such contacts, - Request-URI will be overwritten with the contact that has - the highest q value and optionally the rest will be appended to - the message (depending on append_branches parameter value). - - - If the method_filtering option is enabled, the lookup function - will return only the contacts that support the method of the - processed request. - - Meaning of the parameters is as follows: - - - - domain (static string) - Name of table that - should be used for the lookup. - - - - &lookup_flags; - - - - AOR (string, optional) - AOR to lookup for; if - missing, the RURI is used as AOR; - - - - - &lookup_retcodes; - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>lookup</function> usage - -... -lookup("location"); # simple lookup - #or -lookup("location", "method-filtering"); # lookup with method filtering - #or -lookup("location", "branch"); # lookup with aor branch search; - # all contacts except the first one shall be put - # in the branches - #or -lookup("location", "ua-filtering=/phone/i"); # lookup with user-agent filtering - #or -lookup("location", "", $var(aor)); # simple lookup with AOR from var -switch ($retcode) { - case -1: - case -3: - sl_send_reply(404, "Not Found"); - exit; - case -2: - sl_send_reply(405, "Not Found"); - exit; -}; -... - - -
- -
- - <function moreinfo="none">is_registered(domain ,[AOR])</function> - - - The function returns true if an AOR is registered, false otherwise. - The function does not modify the message being process. - - - NOTE: if called for a reply (from onreply_route), you must pass an - AOR (as parameter), otherwise the function will fail. - - Meaning of the parameters is as follows: - - - - domain (static string) - Name of table that - should be used for the lookup. - - - - - AOR (string, optional) - AOR to lookup for; if - missing, the source if the AOR is the "To" header for REGISTER - request, "From" header for any other sip request. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - - <function>is_registered</function> usage - -... -/**/ -if (is_method("REGISTER")) { - /* automatically uses the URI from the To header */ - if (is_registered("location")) { - xlog("this AOR is registered\n") - ... - } -}; -/* check the From uri whether this aor is registered or not */ -if (is_registered("location",$fu)) { - xlog("caller is registered\n"); -} -... - - -
- - -
- - <function moreinfo="none">is_contact_registered(domain ,[AOR],[contact],[callid])</function> - - - The function returns true if a contact and/or a callid from a certain AOR is registered, false otherwise. - The function does not modify the message being process. - - Meaning of the parameters is as follows: - - - - domain (static string) - Name of table that should be - used for the lookup. - - - - - AOR (string, optional) - AOR to lookup for; if - missing, the source if the AOR is the "To" header for REGISTER - request, "From" header for any other sip request. - - - - - contact (contact, optional) (optional)- SIP - URI to check if there is a registration with this URI as cotact - (this may help you to make distinction between multiple - registrations for the same user/AOR). - - - - - callid (string, optional) - callid to check if a - contact if registered with this callid (this may help you to - make distinction between newly registered contact (callid - not registered so far) and re-registration (callid already - registered). - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - - <function>is_contact_registered</function> usage - -... -/* block users which are not registered... */ -if (is_method("INVITE")) { - if (!is_contact_registered("location")) { - sl_send_reply(401, "Unauthorized"); - ... - } -} - -/* ... or check whether the 2nd Contact URI is registered or not */ -if (is_method("INVITE")) { - if (is_contact_registered("location", $fu, $(ct.fields(uri)[1]))) - xlog("caller is registered\n"); -} -... - - -
- -
- - <function moreinfo="none">is_ip_registered(domain ,[AOR],IPvar,[PORTvar])</function> - - - The function returns true if there is at least one contact that has - been registered from the IP in the IPvar variable ( and from the optional - PORTvar variable ). - The IP is matched against the received host, if it exists, or the contact host otherwise. - This function does not modify the message being process. This function - replaces the old "is_other_contact" function. - - Meaning of the parameters is as follows: - - - - domain (static string) - Name of table that should be - used for the lookup. - - - - - AOR (string, optional) - AOR to lookup for; if - missing, the source if the AOR is the "To" header for REGISTER - request, "From" header for any other sip request. - - - - - IPvar (var) - the variable containing the IP matched against - the contact host or the received host (see above). If the - IPvar is an AVP containing multiple values/IPs, - then all the values are checked. - - - - - PORTvar (var, optional) - the variable containing the port to be - matched against the contact host or the received host (see above). If the - IPvar is an AVP containing multiple values/IPs, then the PORTvar - is expected to contain the same number of entries, and all the values are checked. - - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE. - - - <function>is_ip_registered</function> usage - -... -/* check the source ip whether it is already registered */ -if (is_method("REGISTER")) { - if (is_ip_registered("location",$tu,$si)) { - xlog("already registered from this ip\n"); - ... - } -}; -... - - -
- - - -
- - <function moreinfo="none">add_sock_hdr(hdr_name)</function> - - - Adds to the current REGISTER request a new header with - hdr_name which contains the description of the - received socket (proto:ip:port) - - - This makes sense only in multiple replicated servers scenarios. - - Meaning of the parameters is as follows: - - - - hdr_name (string) - header name to be used. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>add_sock_hdr</function> usage - -... -add_sock_hdr("Sock-Info"); -... - - -
-
- - -
- Exported Asynchronous Functions - - &pn_async_func; - -
- - -
- Exported Statistics -
- <varname>max_expires</varname> - - Value of max_expires parameter. - -
-
- <varname>max_contacts</varname> - - The value of max_contacts parameter. - -
-
- <varname>defaults_expires</varname> - - The value of default_expires parameter. - -
-
- <varname>accepted_regs</varname> - - Number of accepted registrations. - -
-
- <varname>rejected_regs</varname> - - Number of rejected registrations. - -
- -
- -
- diff --git a/modules/registrar/doc/registrar_faq.xml b/modules/registrar/doc/registrar_faq.xml deleted file mode 100644 index 528f3d60217..00000000000 --- a/modules/registrar/doc/registrar_faq.xml +++ /dev/null @@ -1,181 +0,0 @@ - - - - - &faqguide; - - - - - - What happened with the old append_branch module parameter? - - - - It was removed as global option, as the lookup - function takes this option via the flag "b" (append Branches) - See the documentation of the lookup function. - - - - - - - - What happened with the old method_filtering module parameter? - - - - It was removed as global option, as the lookup - function takes this option via the flag "m" (Method filtering) - See the documentation of the lookup function. - - - - - - - - What happened with the old sock_flag module parameter? - - - - It was removed as global option, as the save - function takes this option via the flag "s" (Socket header) - See the documentation of the save function. - - - - - - - - What happened with the old use_path and path_mode module parameters? - - - - They were removed as global option, as the save - function takes these options via the flag "px" (path support) - See the documentation of the save function. - - - - - - - - What happened with the old path_use_received module parameter? - - - - It was removed as global option, as the save - function takes this option via the flag "v" (path receiVed) - See the documentation of the save function. - - - - - - - - What happened with the old nat_flag module parameter? - - - - It was removed, as the module internally loads this value from the - USRLOC module (see the nat_bflag - USRLOC parameter). - - - - - - - What happened with the old use_domain module parameter? - - - - It was removed, as the module internally loads this option from the - USRLOC module. This was done in order to simplify the - configuration. - - - - - - - What happened with the old save_noreply and save_memory functions? - - - - There functions were merged into the new - save(domain,flags) functions. If a reply should be - sent or if the DB should be updated also is controlled via the - flags. - - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - What happened to the desc_time_order parameter? - - - - It was removed, as its functionality was mmigrate into usrloc - module, were there is a parameter with the same name. - - - - - - diff --git a/modules/registrar/reply.c b/modules/registrar/reply.c index 3ff205151b6..c442cd53e17 100644 --- a/modules/registrar/reply.c +++ b/modules/registrar/reply.c @@ -98,12 +98,25 @@ static struct { } contact = {0, 0, 0}; +static inline int calc_temp_gruu_raw_len(str* aor,str* instance,str *callid, + int time_len) +{ + if (instance->len < 2) { + LM_WARN("invalid +sip.instance value for GRUU contact\n"); + return -1; + } + + return time_len + aor->len + instance->len - 2 + callid->len + 3; /* and blank spaces */ +} + static inline int calc_temp_gruu_len(str* aor,str* instance,str *callid) { int time_len,temp_gr_len; int2str((unsigned long)get_act_time(),&time_len); - temp_gr_len = time_len + aor->len + instance->len - 2 + callid->len + 3; /* and blank spaces */ + temp_gr_len = calc_temp_gruu_raw_len(aor, instance, callid, time_len); + if (temp_gr_len < 0) + return -1; temp_gr_len = (temp_gr_len/3 + (temp_gr_len%3?1:0))*4; /* base64 encoding */ return temp_gr_len; } @@ -117,6 +130,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, { unsigned int len; int qlen; + int gruu_len; const struct socket_info *sock; len = 0; @@ -136,7 +150,9 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, + 1 /* dquote */ ; } - if (build_gruu && c->instance.s) { + if (build_gruu && c->instance.s && + (gruu_len = calc_temp_gruu_len(c->aor, &c->instance, + &c->callid)) >= 0) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); /* pub gruu */ len += PUB_GRUU_SIZE @@ -153,7 +169,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, + 1 /* quote */ + SIP_PROTO_SIZE + TEMP_GRUU_HEADER_SIZE - + calc_temp_gruu_len(c->aor,&c->instance,&c->callid) + + gruu_len + 1 /* @ */ + sock->name.len + 1 /* : */ @@ -164,7 +180,7 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, /* sip.instance */ len += SIP_INSTANCE_SIZE + 1 /* quote */ - + (c->instance.len - 2) + + c->instance.len + 1 /* quote */ ; } @@ -176,10 +192,9 @@ static inline unsigned int calc_buf_len(ucontact_t* c,int build_gruu, return len; } -#define MAX_TEMP_GRUU_SIZE 255 -static char temp_gruu_buf[MAX_TEMP_GRUU_SIZE]; +static str temp_gruu_buf; -/* Returns memory from a statically allocated buffer */ +/* Returns memory from a module-local reusable buffer */ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) { int time_len,i; @@ -187,8 +202,14 @@ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) char *time_str = int2str((unsigned long)get_act_time(),&time_len); str *magic; - *len = time_len + aor->len + instance->len + callid->len + 3 - 2; /* +3 blank spaces, -2 discarded chars of instance in memcpy below */ - p = temp_gruu_buf; + *len = calc_temp_gruu_raw_len(aor, instance, callid, time_len); + if (*len < 0) + return NULL; + + if (pkg_str_extend(&temp_gruu_buf, *len) < 0) + return NULL; + + p = temp_gruu_buf.s; memcpy(p,time_str,time_len); p+=time_len; @@ -204,15 +225,15 @@ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) memcpy(p,callid->s,callid->len); - LM_DBG("build temp gruu [%.*s]\n",*len,temp_gruu_buf); + LM_DBG("build temp gruu [%.*s]\n",*len,temp_gruu_buf.s); if (gruu_secret.s != NULL) magic = &gruu_secret; else magic = &default_gruu_secret; for (i=0;i<*len;i++) - temp_gruu_buf[i] ^= magic->s[i%magic->len]; - return temp_gruu_buf; + temp_gruu_buf.s[i] ^= magic->s[i%magic->len]; + return temp_gruu_buf.s; } /*! \brief @@ -222,7 +243,7 @@ char * build_temp_gruu(str *aor,str *instance,str *callid,int *len) int build_contact(ucontact_t* c,struct sip_msg *_m) { char *p, *cp, *tmpgr; - int fl, len,grlen; + int fl, len, grlen, gruu_len; int build_gruu = 0; const struct socket_info *sock; @@ -291,8 +312,17 @@ int build_contact(ucontact_t* c,struct sip_msg *_m) *p++ = '\"'; } - if (build_gruu && c->instance.s) { + if (build_gruu && c->instance.s && + (gruu_len = calc_temp_gruu_len(c->aor, &c->instance, + &c->callid)) >= 0) { sock = (c->sock)?(c->sock):(_m->rcv.bind_address); + tmpgr = build_temp_gruu(c->aor, &c->instance, &c->callid, + &grlen); + if (!tmpgr) { + contact.data_len = 0; + return -1; + } + /* build pub GRUU */ memcpy(p,PUB_GRUU,PUB_GRUU_SIZE); p += PUB_GRUU_SIZE; @@ -324,10 +354,9 @@ int build_contact(ucontact_t* c,struct sip_msg *_m) memcpy(p,TEMP_GRUU_HEADER,TEMP_GRUU_HEADER_SIZE); p += TEMP_GRUU_HEADER_SIZE; - tmpgr = build_temp_gruu(c->aor,&c->instance,&c->callid,&grlen); base64encode((unsigned char *)p, (unsigned char *)tmpgr,grlen); - p += calc_temp_gruu_len(c->aor,&c->instance,&c->callid); + p += gruu_len; *p++ = '@'; memcpy(p,sock->name.s,sock->name.len); p += sock->name.len; @@ -342,8 +371,8 @@ int build_contact(ucontact_t* c,struct sip_msg *_m) memcpy(p,SIP_INSTANCE,SIP_INSTANCE_SIZE); p += SIP_INSTANCE_SIZE; *p++ = '\"'; - memcpy(p,c->instance.s+1,c->instance.len-2); - p += c->instance.len-2; + memcpy(p,c->instance.s,c->instance.len); + p += c->instance.len; *p++ = '\"'; } } diff --git a/modules/registrar/save.c b/modules/registrar/save.c index ef290a18723..90e9d690007 100644 --- a/modules/registrar/save.c +++ b/modules/registrar/save.c @@ -261,7 +261,7 @@ static inline int insert_contacts(struct sip_msg* _m, contact_t* _c, } if (r==0) { - if (ul.insert_urecord(_d, _a, &r, 0) < 0) { + if (ul.insert_urecord(_d, _a, &r, 0, NULL, NULL) < 0) { rerrno = R_UL_NEW_R; LM_ERR("failed to insert new record structure\n"); goto error; @@ -400,7 +400,7 @@ static inline int update_contacts(struct sip_msg* _m, urecord_t* _r, calc_contact_expires(_m, _c->expires, &e, _sctx); /* search for the contact*/ - ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->cseq, + ret = ul.get_ucontact( _r, &_c->uri, ci->callid, REG_CSEQ_ADJUST(ci->cseq), &_sctx->cmatch, &c); if (ret==-1) { LM_ERR("invalid cseq for aor <%.*s>\n",_r->aor.len,_r->aor.s); diff --git a/modules/registrar/test/test.c b/modules/registrar/test/test.c index 7bad65aa134..c1748c0c1f7 100644 --- a/modules/registrar/test/test.c +++ b/modules/registrar/test/test.c @@ -22,6 +22,7 @@ #include "../../../dprint.h" #include "../../../dset.h" +#include "../../../data_lump_rpl.h" #include "../../../test/ut.h" #include "../../../parser/parse_methods.h" #include "../../../parser/msg_parser.h" @@ -30,6 +31,107 @@ #include "../../usrloc/usrloc.h" #include "../reg_mod.h" #include "../lookup.h" +#include "../reply.h" + + +static int (*saved_t_wait_for_new_branches)(struct sip_msg *msg, + unsigned int num_br); +static unsigned int pn_wait_branches; +static int pn_wait_calls; +static sig_send_reply_f saved_sig_reply; + + +static int test_t_wait_for_new_branches(struct sip_msg *msg, + unsigned int num_br) +{ + pn_wait_calls++; + pn_wait_branches = num_br; + return 1; +} + + +static int test_sig_reply(struct sip_msg *msg, int code, const str *reason, + str *tag) +{ + return 0; +} + + +static int mk_supported_register_req(struct sip_msg *msg) +{ + static char msgbuf[BUF_SIZE]; + int len; + + len = snprintf(msgbuf, BUF_SIZE, + "REGISTER sip:registrar.example.org SIP/2.0\r\n" + "Via: SIP/2.0/UDP 192.0.2.4:5060;branch=z9hG4bK%x%x\r\n" + "From: Alice ;tag=%x%x\r\n" + "To: Alice \r\n" + "CSeq: 1 REGISTER\r\n" + "Call-ID: %x%x%x%x\r\n" + "Max-Forwards: 70\r\n" + "Supported: gruu\r\n" + "Contact: \r\n" + "Content-Length: 0\r\n" + "\r\n", rand(), rand(), rand(), rand(), + rand(), rand(), rand(), rand()); + + memset(msg, 0, sizeof *msg); + msg->buf = msgbuf; + msg->len = len; + msg->ruri_q = Q_UNSPECIFIED; + + if (parse_msg(msgbuf, len, msg) != 0) { + LM_ERR("failed to parse test REGISTER msg\n"); + return -1; + } + + return 0; +} + + +static int str_contains_cstr(const str *haystack, const char *needle) +{ + int needle_len = strlen(needle); + int i; + + if (needle_len > haystack->len) + return 0; + + for (i = 0; i <= haystack->len - needle_len; i++) + if (!memcmp(haystack->s + i, needle, needle_len)) + return 1; + + return 0; +} + + +static void start_pn_wait_capture(void) +{ + saved_t_wait_for_new_branches = tmb.t_wait_for_new_branches; + tmb.t_wait_for_new_branches = test_t_wait_for_new_branches; + pn_wait_calls = 0; + pn_wait_branches = 0; +} + + +static void stop_pn_wait_capture(void) +{ + tmb.t_wait_for_new_branches = saved_t_wait_for_new_branches; +} + + +static void start_sig_reply_capture(void) +{ + saved_sig_reply = sigb.reply; + sigb.reply = test_sig_reply; +} + + +static void stop_sig_reply_capture(void) +{ + sigb.reply = saved_sig_reply; +} static void fill_ucontact_info(ucontact_info_t *ci) @@ -51,6 +153,62 @@ static void fill_ucontact_info(ucontact_info_t *ci) } +static void test_reply_sip_instance(void) +{ + int old_disable_gruu; + struct sip_msg msg; + struct socket_info sock; + ucontact_t contact; + struct lump_rpl *lump; + str aor = str_init("alice"); + + memset(&sock, 0, sizeof sock); + sock.name = str_init("registrar.example.org"); + sock.port_no_str = str_init("5060"); + + memset(&contact, 0, sizeof contact); + contact.aor = &aor; + contact.c = str_init("sip:alice@192.0.2.4"); + contact.expires = get_act_time() + 120; + contact.q = Q_UNSPECIFIED; + contact.instance = str_init(""); + contact.callid = str_init("reg-callid"); + contact.sock = &sock; + + ok(mk_supported_register_req(&msg) == 0, "reply instance: parse REGISTER"); + + old_disable_gruu = disable_gruu; + disable_gruu = 0; + start_sig_reply_capture(); + + ok(build_contact(&contact, &msg) == 0, "reply instance: build Contact"); + rerrno = R_FINE; + ok(send_reply(&msg, 0) == 0, "reply instance: send 200 OK"); + + lump = get_lump_rpl(&msg, LUMP_RPL_HDR); + ok(lump != NULL, "reply instance: Contact reply lump exists"); + ok(lump && str_contains_cstr(&lump->text, + "Contact: ;expires=120;pub-gruu=" + "\"sip:alice@registrar.example.org:5060;gr=" + "urn:uuid:00000000-0000-1000-8000-000A95A0E128\""), + "reply instance: pub-gruu keeps bare instance value"); + ok(lump && str_contains_cstr(&lump->text, + ";+sip.instance=\"\""), + "reply instance: +sip.instance keeps RFC 5626 angle brackets"); + ok(lump && !str_contains_cstr(&lump->text, + ";+sip.instance=\"urn:uuid:00000000-0000-1000-8000-000A95A0E128\""), + "reply instance: +sip.instance is not stripped to the old value"); + + if (lump) { + unlink_lump_rpl(&msg, lump); + free_lump_rpl(lump); + } + free_contact_buf(); + stop_sig_reply_capture(); + disable_gruu = old_disable_gruu; +} + + static void test_lookup(void) { udomain_t *d; @@ -59,6 +217,7 @@ static void test_lookup(void) ucontact_info_t ci; str aor = str_init("alice"); str aor_ruri = str_init("sip:alice@localhost"); + str extra_branch_uri = str_init("sip:parallel@127.0.0.3"); str ct1 = str_init("sip:cell@127.0.0.1:44444;" "pn-provider=apns;" "pn-prid=ZTY4ZDJlMzODE1NmUgKi0K;" @@ -77,7 +236,7 @@ static void test_lookup(void) ok(reg_lookup(&msg, d, NULL, NULL) == LOOKUP_NO_RESULTS, "lookup-1"); ul.lock_udomain(d, &aor); - ok(ul.insert_urecord(d, &aor, &r, 0) == 0, "create AoR"); + ok(ul.insert_urecord(d, &aor, &r, 0, NULL, NULL) == 0, "create AoR"); fill_ucontact_info(&ci); ci.methods = METHOD_UNDEF; @@ -107,28 +266,55 @@ static void test_lookup(void) ok(ul.insert_ucontact(r, &ct1, &ci, NULL, 1, &c) == 0, "insert ct1 (PN)"); set_ruri(&msg, &aor_ruri); + start_pn_wait_capture(); ok(reg_lookup(&msg, d, NULL, NULL) == LOOKUP_PN_SENT, "lookup-6"); + ok(pn_wait_calls == 1 && pn_wait_branches == 1, + "lookup-6: waits for PN branch"); + stop_pn_wait_capture(); fill_ucontact_info(&ci); ok(ul.insert_ucontact(r, &ct2, &ci, NULL, 1, &c) == 0, "insert ct2 (normal)"); set_ruri(&msg, &aor_ruri); + start_pn_wait_capture(); ok(reg_lookup(&msg, d, NULL, NULL) == LOOKUP_OK, "lookup-7"); + ok(pn_wait_calls == 1 && pn_wait_branches == 2, + "lookup-7: waits for PN and regular branch"); + stop_pn_wait_capture(); /* the PN contact should just trigger a PN without becoming a branch */ ok(str_match(&msg.new_uri, &ct2), "lookup-7: R-URI is ct2"); + { + struct msg_branch branch; + + memset(&branch, 0, sizeof branch); + branch.uri = extra_branch_uri; + branch.q = Q_UNSPECIFIED; + ok(append_msg_branch(&branch) == 1, "append extra branch"); + + set_ruri(&msg, &aor_ruri); + start_pn_wait_capture(); + ok(reg_lookup(&msg, d, NULL, NULL) == LOOKUP_OK, "lookup-7b"); + ok(pn_wait_calls == 1 && pn_wait_branches == 3, + "lookup-7b: waits for existing, regular and PN branches"); + stop_pn_wait_capture(); + clear_dset(); + } + /* test the "r" flag (branch lookup) */ { str aor2 = str_init("bob"), aor3 = str_init("carol"); struct msg_branch branch; + clear_dset(); + ul.lock_udomain(d, &aor2); - ok(ul.insert_urecord(d, &aor2, &r, 0) == 0, "create AoR 2"); + ok(ul.insert_urecord(d, &aor2, &r, 0, NULL, NULL) == 0, "create AoR 2"); ul.unlock_udomain(d, &aor2); ul.lock_udomain(d, &aor3); - ok(ul.insert_urecord(d, &aor3, &r, 0) == 0, "create AoR 3"); + ok(ul.insert_urecord(d, &aor3, &r, 0, NULL, NULL) == 0, "create AoR 3"); fill_ucontact_info(&ci); ci.methods = METHOD_UNDEF; ok(ul.insert_ucontact(r, &ct2, &ci, NULL, 1, &c) == 0, "insert Contact for AoR 3"); @@ -190,4 +376,5 @@ void mod_tests(void) { test_lookup(); test_purr(); + test_reply_sip_instance(); } diff --git a/modules/rest_client/README b/modules/rest_client/README deleted file mode 100644 index de705dac902..00000000000 --- a/modules/rest_client/README +++ /dev/null @@ -1,788 +0,0 @@ -rest_client Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. TCP Connection Reusage - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. curl_timeout (integer) - 1.4.2. connection_timeout (integer) - 1.4.3. connect_poll_interval (integer) - 1.4.4. max_async_transfers (integer) - 1.4.5. max_transfer_size (integer) - 1.4.6. ssl_verifypeer (integer) - 1.4.7. ssl_verifyhost (integer) - 1.4.8. ssl_capath (integer) - 1.4.9. curl_http_version (integer) - 1.4.10. enable_expect_100 (boolean) - 1.4.11. no_concurrent_connects (boolean) - 1.4.12. curl_conn_lifetime (integer) - - 1.5. Exported Functions - - 1.5.1. rest_get(url, body_pv, [ctype_pv], - [retcode_pv]) - - 1.5.2. rest_post(url, send_body, [send_ctype], - recv_body_pv, [recv_ctype_pv], [retcode_pv]) - - 1.5.3. rest_put(url, send_body, [send_ctype], - recv_body_pv[, [recv_ctype_pv][, - [retcode_pv]]]) - - 1.5.4. rest_append_hf(txt) - 1.5.5. rest_init_client_tls(tls_client_domain) - - 1.6. Exported Asynchronous Functions - - 1.6.1. rest_get(url, body_pv[, [ctype_pv][, - [retcode_pv]]]) - - 1.6.2. rest_post(url, send_body_pv, [send_ctype_pv], - recv_body_pv[, [recv_ctype_pv][, - [retcode_pv]]]) - - 1.6.3. rest_put(url, send_body_pv, [send_ctype_pv], - recv_body_pv[, [recv_ctype_pv][, - [retcode_pv]]]) - - 1.7. Exported script transformations - - 1.7.1. {rest.escape} - 1.7.2. {rest.unescape} - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the curl_timeout parameter - 1.2. Setting the connection_timeout parameter - 1.3. Setting the connect_poll_interval parameter - 1.4. Setting the max_async_transfers parameter - 1.5. Setting the max_transfer_size parameter - 1.6. Setting the ssl_verifypeer parameter - 1.7. Setting the ssl_verifyhost parameter - 1.8. Setting the ssl_capath parameter - 1.9. Setting the curl_http_version parameter - 1.10. Setting the enable_expect_100 parameter - 1.11. Setting the no_concurrent_connects parameter - 1.12. Setting the curl_conn_lifetime parameter - 1.13. rest_get usage - 1.14. rest_post usage - 1.15. rest_put usage - 1.16. rest_append_hf usage - 1.17. rest_init_client_tls usage - 1.18. async rest_get usage - 1.19. async rest_post usage - 1.20. async rest_put usage - 1.21. rest.escape usage - 1.22. rest.unescape usage - -Chapter 1. Admin Guide - -1.1. Overview - - The rest_client module provides a means of interacting with an - HTTP server by doing RESTful queries, such as GET, POST and - PUT. - -1.2. TCP Connection Reusage - - Unless specified otherwise by the server through a "Connection: - close" indication, the module will keep and reuse the TCP - connections it creates as much as possible, regardless if the - script writer performs blocking or asynchronous HTTP requests. - These connections are not shared among OpenSIPS workers — each - worker maintains its own set of connections. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules.. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libcurl. - -1.4. Exported Parameters - -1.4.1. curl_timeout (integer) - - The maximum allowed time for any HTTP(S) transfer to complete. - This interval is inclusive of the initial connect time window, - hence the value of this parameter must be greater than or equal - to connection_timeout. - - Default value is “20” seconds. - - Example 1.1. Setting the curl_timeout parameter -... -modparam("rest_client", "curl_timeout", 10) -... - -1.4.2. connection_timeout (integer) - - The maximum allowed time to establish a connection with the - server. - - Default value is “20” seconds. - - Example 1.2. Setting the connection_timeout parameter -... -modparam("rest_client", "connection_timeout", 4) -... - -1.4.3. connect_poll_interval (integer) - - Only relevant with async requests. Allows complete control over - how quickly we want to detect libcurl's completed blocking - TCP/TLS handshakes, so the async transfers can be put in the - background. A lower connect_poll_interval may speed up all - async HTTP transfers, but will also increase CPU usage. - - Default value is “20” milliseconds. - - Example 1.3. Setting the connect_poll_interval parameter -... -modparam("rest_client", "connect_poll_interval", 2) -... - -1.4.4. max_async_transfers (integer) - - Maximum number of asynchronous HTTP transfers a single OpenSIPS - worker is allowed to run simultaneously. As long as this - threshold is reached for a worker, all new async transfers it - attempts to perform will be done in a blocking manner, with - appropriate logging warnings. - - Default value is “100”. - - Example 1.4. Setting the max_async_transfers parameter -... -modparam("rest_client", "max_async_transfers", 300) -... - -1.4.5. max_transfer_size (integer) - - The maximum allowed size of a single transfer (download). - Reaching this limit during a transfer will cause the transfer - to stop immediately, returning error -10 at script level. A - value of 0 will disable the check. - - Default value is “10240” (KB). - - Example 1.5. Setting the max_transfer_size parameter -... -modparam("rest_client", "max_transfer_size", 64) -... - -1.4.6. ssl_verifypeer (integer) - - Set this to 0 in order to disable the verification of the - remote peer's certificate. Verification is done using a default - bundle of CA certificates which come with libcurl. - - Default value is “1” (enabled). - - Example 1.6. Setting the ssl_verifypeer parameter -... -modparam("rest_client", "ssl_verifypeer", 0) -... - -1.4.7. ssl_verifyhost (integer) - - Set this to 0 in order to disable the verification that the - remote peer actually corresponds to the server listed in the - certificate. - - Default value is “1” (enabled). - - Example 1.7. Setting the ssl_verifyhost parameter -... -modparam("rest_client", "ssl_verifyhost", 0) -... - -1.4.8. ssl_capath (integer) - - An optional path for CA certificates to be used for host - verifications. - - Example 1.8. Setting the ssl_capath parameter -... -modparam("rest_client", "ssl_capath", "/home/opensips/ca_certificates") -... - -1.4.9. curl_http_version (integer) - - Use a specific HTTP version for all requests. Possible values: - - * 0 (default) - use whatever is deemed fit by libcurl - * 1 - enforce HTTP 1.0 requests - * 2 - enforce HTTP 1.1 requests - * 3 - attempt HTTP 2 requests. Fall back to HTTP 1.1 if HTTP - 2 cannot be negotiated with the server. Requires libcurl - 7.33.0+. - * 4 - attempt HTTP 2 over TLS (HTTPS) only. Fall back to HTTP - 1.1 if HTTP 2 cannot be negotiated with the HTTPS server. - For clear text HTTP servers, use HTTP 1.1. Requires libcurl - 7.47.0+. - * 5 - Issue non-TLS HTTP requests using HTTP 2 without HTTP - 1.1 Upgrade. It requires prior knowledge that the server - supports HTTP 2 straight away. HTTPS requests will still do - HTTP/2 the standard way with negotiated protocol version in - the TLS handshake. Requires libcurl 7.49.0+. - - more details here, where the documentation for this setting was - inspired (read: pilfered) from - - Example 1.9. Setting the curl_http_version parameter -... -modparam("rest_client", "curl_http_version", 3) -... - -1.4.10. enable_expect_100 (boolean) - - Include a "Expect: 100-continue" HTTP header field whenever the - body size of a POST or PUT request exceeds 1024 bytes. Once - enabled, the timeout for waiting for a "100 Continue" reply - from the server is 1 second, after which the body upload will - begin. - - Default value is “false” (disabled). - - Example 1.10. Setting the enable_expect_100 parameter -... -modparam("rest_client", "enable_expect_100", true) -... - -1.4.11. no_concurrent_connects (boolean) - - Set to true in order to only allow one OpenSIPS worker to - connect to a given URL hostname at a time. While a worker is - connecting, all other workers will receive error code -4 - (already connecting) when attempting to perform any rest_client - operation to the same hostname, regardless if the operation is - sync or async. - - For sync transfers, the scope of the worker process - serialization extends to the entire cURL transfer (TCP connect - + upload + download), as all three phases take place within a - single cURL library call. - - This parameter may be useful in order to prevent system outages - caused by concurrent blocking of all OpenSIPS workers on a - failed (hanging) HTTP service, with no more free workers being - left to process incoming SIP packets. - - Default value is “false” (disabled). - - Example 1.11. Setting the no_concurrent_connects parameter -... -modparam("rest_client", "no_concurrent_connects", true) -... - -1.4.12. curl_conn_lifetime (integer) - - Only relevant when no_concurrent_connects is enabled. By - setting this parameter, script developers can leverage the - connection reusage capabilities of libcURL and entirely skip - the "no concurrent transfers" logic on a given SIP worker, - should that worker already be known to have a TCP connection to - the target URL hostname (established by a previous rest_xxx() - function call). - - The parameter denotes the lifetime, in seconds, of TCP - connections kept within libcURL for reusage, a setting which is - often operating system dependant, and which may also be - affected by enabling/disabling keepalives. Consult your - operating system's and/or libcurl's documentation for further - information on the max lifetime of your cURL TCP connections. - - Default value is 0 (disabled). - - Example 1.12. Setting the curl_conn_lifetime parameter -... -modparam("rest_client", "curl_conn_lifetime", 1800) -... - -1.5. Exported Functions - -1.5.1. rest_get(url, body_pv, [ctype_pv], [retcode_pv]) - - Perform a blocking HTTP GET on the given url and return a - representation of the resource. - - Parameters: - * url (string) - * body_pv (var) - output variable which will hold the body of - the HTTP response. - * ctype_pv (var, optional) - output variable which will - contain the value of the "Content-Type:" header of the - response. - * retcode_pv (var, optional) - output variable which will - retain the status code of the HTTP response. A 0 status - code value means no HTTP reply arrived at all. - - Return Codes - * 1 - Success - * -1 - Connection Refused. - * -2 - Connection Timeout (the connection_timeout was - exceeded before a TCP connection could be established) - * -3 - Transfer Timeout (the curl_timeout was exceeded before - the last byte was received). The retcode_pv may be set to - 200 or 0, depending whether a 200 OK was received or not. - If it was, the body_pv will contain partially downloaded - data, use at your own risk! (we recommend you only use this - data for logging / debugging purposes) - * -4 - Already Connecting (another OpenSIPS worker is already - connecting to this URL hostname. Consult - no_concurrent_connects for more info). - * -10 - Internal Error (out of memory, unexpected libcurl - error, etc.) - - This function can be used from any route. - - Example 1.13. rest_get usage -... -# Example of querying a REST service to get the credit of an account -$var(rc) = rest_get("https://getcredit.org/?account=$fU", - $var(credit), - $var(ct), - $var(rcode)); -if ($var(rc) < 0) { - xlog("rest_get() failed with $var(rc), acc=$fU\n"); - send_reply(500, "Server Internal Error"); - exit; -} - -if ($var(rcode) != 200) { - xlog("L_INFO", "rest_get() rcode=$var(rcode), acc=$fU\n"); - send_reply(403, "Forbidden"); - exit; -} -... - -1.5.2. rest_post(url, send_body, [send_ctype], recv_body_pv, -[recv_ctype_pv], [retcode_pv]) - - Perform a blocking HTTP POST on the given url. - - Note that the send_body parameter can also accept a - format-string but it cannot be larger than 1024 bytes. For - larger messages, you must build them in a pseudo-variable and - pass it to the function. - - Parameters: - * url (string) - * send_body (string) - The request body. - * send_ctype (string, optional) - The MIME Content-Type - header for the request. The default is - "application/x-www-form-urlencoded" - * recv_body_pv (var) - output variable which will hold the - body of the HTTP response. - * recv_ctype_pv (var, optional) - output variable which will - contain the value of the "Content-Type" header of the - response - * retcode_pv (var, optional) - output variable which will - retain the status code of the HTTP response. A 0 status - code value means no HTTP reply arrived at all. - - Return Codes - * 1 - Success - * -1 - Connection Refused. - * -2 - Connection Timeout (the connection_timeout was - exceeded before a TCP connection could be established) - * -3 - Transfer Timeout (the curl_timeout was exceeded before - the last byte was received). The retcode_pv may be set to - 200 or 0, depending whether a 200 OK was received or not. - If it was, the body_pv will contain partially downloaded - data, use at your own risk! (we recommend you only use this - data for logging / debugging purposes) - * -4 - Already Connecting (another OpenSIPS worker is already - connecting to this URL hostname. Consult - no_concurrent_connects for more info). - * -10 - Internal Error (out of memory, unexpected libcurl - error, etc.) - - This function can be used from any route. - - Example 1.14. rest_post usage -... -# Creating a resource using a RESTful service with an HTTP POST request -$var(rc) = rest_post("https://myserver.org/register_user", - $fU, , $var(body), $var(ct), $var(rcode)); -if ($var(rc) < 0) { - xlog("rest_post() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 1"); - exit; -} - -if ($var(rcode) != 200) { - xlog("rest_post() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 2"); - exit; -} -... - - -1.5.3. rest_put(url, send_body, [send_ctype], recv_body_pv[, -[recv_ctype_pv][, [retcode_pv]]]) - - Perform a blocking HTTP PUT on the given url. - - Similar to rest_post(), the send_body_pv parameter can also - accept a format-string but it cannot be larger than 1024 bytes. - For larger messages, you must build them in a pseudo-variable - and pass it to the function. - - Parameters: - * url (string) - * send_body (string) - The request body. - * send_ctype (string, optional) - The MIME Content-Type - header for the request. The default is - "application/x-www-form-urlencoded" - * recv_body_pv (var) - output variable which will hold the - body of the HTTP response. - * recv_ctype_pv (var, optional) - output variable which will - contain the value of the "Content-Type" header of the - response - * retcode_pv (var, optional) - output variable which will - retain the status code of the HTTP response. A 0 status - code value means no HTTP reply arrived at all. - - Return Codes - * 1 - Success - * -1 - Connection Refused. - * -2 - Connection Timeout (the connection_timeout was - exceeded before a TCP connection could be established) - * -3 - Transfer Timeout (the curl_timeout was exceeded before - the last byte was received). The retcode_pv may be set to - 200 or 0, depending whether a 200 OK was received or not. - If it was, the body_pv will contain partially downloaded - data, use at your own risk! (we recommend you only use this - data for logging / debugging purposes) - * -4 - Already Connecting (another OpenSIPS worker is already - connecting to this URL hostname. Consult - no_concurrent_connects for more info). - * -10 - Internal Error (out of memory, unexpected libcurl - error, etc.) - - This function can be used from any route. - - Example 1.15. rest_put usage -... -# Creating/Updating a resource using a RESTful service with an HTTP PUT -request -$var(rc) = rest_put("https://myserver.org/users/$fU", - $var(userinfo), , $var(body), $var(ct), $var(rcode)) -; -if ($var(rc) < 0) { - xlog("rest_put() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 3"); - exit; -} - -if ($var(rcode) != 200) { - xlog("rest_put() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 4"); - exit; -} -... - -1.5.4. rest_append_hf(txt) - - Append txt to the HTTP headers of the subsequent request. - Multiple headers can be appended by making multiple calls - before executing a request. - - The contents of txt should adhere to the specification for HTTP - headers (ex. Field: Value) - - Parameters - * txt (string) - - This function can be used from any route. - - Example 1.16. rest_append_hf usage -... -# Example of querying a REST service requiring additional headers - -rest_append_hf("Authorization: Bearer mF_9.B5f-4.1JqM"); -$var(rc) = rest_get("http://getcredit.org/?account=$fU", $var(credit)); -... - -1.5.5. rest_init_client_tls(tls_client_domain) - - Force a specific TLS domain to be used at most once, during the - next GET/POST/PUT request. Refer to the tls_mgm module for - additional info regarding TLS client domains. - - If using this function, you must also ensure that tls_mgm is - loaded and properly configured. - - Parameters - * tls_client_domain (string) - - This function can be used from any route. - - Example 1.17. rest_init_client_tls usage -... -rest_init_client_tls("dom1"); -if (!rest_get("https://example.com")) - xlog("query failed\n"); -... - -1.6. Exported Asynchronous Functions - -1.6.1. rest_get(url, body_pv[, [ctype_pv][, [retcode_pv]]]) - - Perform an asynchronous HTTP GET. This function behaves exactly - the same as rest_get() (in terms of input, output and - processing), but in a non-blocking manner. Script execution is - suspended until the entire content of the HTTP response is - available. - - Example 1.18. async rest_get usage -route { - ... - async(rest_get("http://getcredit.org/?account=$fU", - $var(credit), , $var(rcode)), resume); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_get() failed with $var(rc), acc=$fU\n") -; - send_reply(500, "Server Internal Error"); - exit; - } - - if ($var(rcode) != 200) { - xlog("L_INFO", "async rest_get() rcode=$var(rcode), acc= -$fU\n"); - send_reply(403, "Forbidden"); - exit; - } - - ... -} - -1.6.2. rest_post(url, send_body_pv, [send_ctype_pv], recv_body_pv[, -[recv_ctype_pv][, [retcode_pv]]]) - - Perform an asynchronous HTTP POST. This function behaves - exactly the same as rest_post() (in terms of input, output and - processing), but in a non-blocking manner. Script execution is - suspended until the entire content of the HTTP response is - available. - - Example 1.19. async rest_post usage -route { - ... - async(rest_post("http://myserver.org/register_user", - $fU, , $var(body), $var(ct), $var(rcode)), resum -e); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_post() failed with $var(rc), user=$fU\n -"); - send_reply(500, "Server Internal Error 1"); - exit; - } - if ($var(rcode) != 200) { - xlog("async rest_post() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 2"); - exit; - } - - ... -} - - -1.6.3. rest_put(url, send_body_pv, [send_ctype_pv], recv_body_pv[, -[recv_ctype_pv][, [retcode_pv]]]) - - Perform an asynchronous HTTP PUT. This function behaves exactly - the same as rest_put() (in terms of input, output and - processing), but in a non-blocking manner. Script execution is - suspended until the entire content of the HTTP response is - available. - - Example 1.20. async rest_put usage -route { - ... - async(rest_put("http://myserver.org/users/$fU", $var(userinfo), -, - $var(body), $var(ct), $var(rcode)), resume); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_put() failed with $var(rc), user=$fU\n" -); - send_reply(500, "Server Internal Error 3"); - exit; - } - if ($var(rcode) != 200) { - xlog("async rest_put() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 4"); - exit; - } - - ... -} - -1.7. Exported script transformations - - The module also provides a way for encoding and decoding - parameters contained in an arbitrary script variable, in - accordance with RFC3986. This is done by applying a - transformation to a script variable containing the data to be - encoded. The value of the original variable is not altered and - a corresponding string value is returned. The transformation is - performed through libcurl API method curl_easy_escape (or - curl_escape for libcurl < 7.15.4). - -1.7.1. {rest.escape} - - The result of this transformation is to produce percent encoded - string value which can be safely used in URI construction. - - There are no parameters for this transformation. - - Example 1.21. rest.escape usage -... -# This example would produce log entry: "Output: call%40example.com%26sa -fe%3Dfalse" -$var(tmp) = "call@example.com&safe=false"; -xlog("Output: $(var(tmp){rest.escape})\n"); - -# Encode call ID before transmission: -$var(rc) = rest_get("https://call-info.org/?id=$(ci{rest.escape})", $var -(body_pv)); -... - -1.7.2. {rest.unescape} - - The result of this transformation is to decode percent encoded - string values. - - There are no parameters for this transformation. - - Example 1.22. rest.unescape usage -... -# This example would produce log entry: "Output: 1+1=2!" -$var(tmp) = "1%2B1%3D2%21"; -xlog("Output: $(var(tmp){rest.unescape})\n"); - -# This example would produce log entry: "OpenSIPs, tastes better with ev -ery SIP!" -$var(tmp) = "OpenSIPs%2C%20tastes%20better%20with%20every%20SIP%21"; -xlog("$(var(tmp){rest.unescape})\n"); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 150 86 4034 1785 - 2. Ionut Ionita (@ionutrazvanionita) 23 12 663 262 - 3. Vlad Patrascu (@rvlad-patrascu) 17 8 336 345 - 4. Razvan Crainea (@razvancrainea) 15 13 41 17 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 8 6 115 48 - 6. Jarrod Baumann (@jarrodb) 6 3 131 32 - 7. Agalya Ramachandran (@AgalyaR) 6 2 354 1 - 8. Callum Guy (@spacetourist) 6 2 281 8 - 9. Ryan Bullock (@rrb3942) 5 2 91 77 - 10. Aron Podrigal (@ar45) 4 2 15 7 - - All remaining contributors: Peter Lemenkov (@lemenkov), Maksym - Sobolyev (@sobomax), John Burke (@john08burke), Vlad Paiu - (@vladpaiu), Andrey Vorobiev (@andrey-vorobiev). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Nov 2025 - 2. Vlad Paiu (@vladpaiu) Nov 2025 - Nov 2025 - 3. Peter Lemenkov (@lemenkov) Jun 2018 - Oct 2025 - 4. Liviu Chircu (@liviuchircu) Mar 2013 - Sep 2024 - 5. Aron Podrigal (@ar45) Sep 2024 - Sep 2024 - 6. Maksym Sobolyev (@sobomax) Oct 2020 - Feb 2023 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2021 - 8. John Burke (@john08burke) Apr 2021 - Apr 2021 - 9. Callum Guy (@spacetourist) Jan 2020 - Jan 2020 - 10. Razvan Crainea (@razvancrainea) Aug 2015 - Nov 2019 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Andrey Vorobiev (@andrey-vorobiev), Ryan Bullock (@rrb3942), - Agalya Ramachandran (@AgalyaR), Jarrod Baumann (@jarrodb). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Callum Guy - (@spacetourist), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Agalya - Ramachandran (@AgalyaR), Jarrod Baumann (@jarrodb), - Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/rest_client/README.md b/modules/rest_client/README.md new file mode 100644 index 00000000000..9a414bc3f72 --- /dev/null +++ b/modules/rest_client/README.md @@ -0,0 +1,756 @@ +--- +title: "rest_client Module" +description: "The *rest_client* module provides a means of interacting with an HTTP server by doing RESTful queries, such as GET, POST and PUT." +--- + +## Admin Guide + + +### Overview + + +The *rest_client* module provides a means of interacting +with an HTTP server by doing RESTful queries, such as GET, POST and PUT. + + +### TCP Connection Reusage + + +Unless specified otherwise by the server through a "Connection: close" +indication, the module will keep and reuse the TCP connections it creates +as much as possible, regardless if the script writer performs blocking or +asynchronous HTTP requests. These connections are not shared among OpenSIPS +workers — each worker maintains its own set of connections. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules.*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *libcurl*. + + +### Exported Parameters + + +#### curl_timeout (integer) + + +The maximum allowed time for any HTTP(S) transfer to complete. This +interval is inclusive of the initial connect time window, hence the value +of this parameter must be greater than or equal to +[connection timeout](#param_connection_timeout). + + +*Default value is "20" seconds.* + + +```opensips title="Setting the curl_timeout parameter" +... +modparam("rest_client", "curl_timeout", 10) +... +``` + + +#### connection_timeout (integer) + + +The maximum allowed time to establish a connection with the server. + + +*Default value is "20" seconds.* + + +```opensips title="Setting the connection_timeout parameter" +... +modparam("rest_client", "connection_timeout", 4) +... +``` + + +#### connect_poll_interval (integer) + + +Only relevant with async requests. Allows complete control over how +quickly we want to detect libcurl's completed blocking TCP/TLS handshakes, +so the async transfers can be put in the background. A lower +[connect poll interval](#param_connect_poll_interval) may speed up all async +HTTP transfers, but will also increase CPU usage. + + +*Default value is "20" milliseconds.* + + +```opensips title="Setting the connect_poll_interval parameter" +... +modparam("rest_client", "connect_poll_interval", 2) +... +``` + + +#### max_async_transfers (integer) + + +Maximum number of asynchronous HTTP transfers *a single* +OpenSIPS worker is allowed to run simultaneously. As long as this threshold +is reached for a worker, all new async transfers it attempts to perform +will be done in a blocking manner, with appropriate logging warnings. + + +*Default value is "100".* + + +```opensips title="Setting the max_async_transfers parameter" +... +modparam("rest_client", "max_async_transfers", 300) +... +``` + + +#### max_transfer_size (integer) + + +The maximum allowed size of a single transfer (download). Reaching +this limit during a transfer will cause the transfer to stop +immediately, returning error -10 at script level. A value of +**0** will disable the check. + + +*Default value is "10240" (KB).* + + +```opensips title="Setting the max_transfer_size parameter" +... +modparam("rest_client", "max_transfer_size", 64) +... +``` + + +#### ssl_verifypeer (integer) + + +Set this to 0 in order to disable the verification of the remote peer's +certificate. Verification is done using a default bundle of CA certificates +which come with libcurl. + + +*Default value is "1" (enabled).* + + +```opensips title="Setting the ssl_verifypeer parameter" +... +modparam("rest_client", "ssl_verifypeer", 0) +... +``` + + +#### ssl_verifyhost (integer) + + +Set this to 0 in order to disable the verification that the remote peer +actually corresponds to the server listed in the certificate. + + +*Default value is "1" (enabled).* + + +```opensips title="Setting the ssl_verifyhost parameter" +... +modparam("rest_client", "ssl_verifyhost", 0) +... +``` + + +#### ssl_capath (integer) + + +An optional path for CA certificates to be used for host verifications. + + +```opensips title="Setting the ssl_capath parameter" +... +modparam("rest_client", "ssl_capath", "/home/opensips/ca_certificates") +... +``` + + +#### curl_http_version (integer) + + +Use a specific HTTP version for all requests. Possible values: + + +- 0 (default) - use whatever is deemed fit by libcurl +- 1 - enforce HTTP 1.0 requests +- 2 - enforce HTTP 1.1 requests +- 3 - attempt HTTP 2 requests. Fall back to HTTP 1.1 if HTTP 2 +cannot be negotiated with the server. Requires libcurl 7.33.0+. +- 4 - attempt HTTP 2 over TLS (HTTPS) only. Fall back to HTTP +1.1 if HTTP 2 cannot be negotiated with the HTTPS server. +For clear text HTTP servers, use HTTP 1.1. +Requires libcurl 7.47.0+. +- 5 - Issue non-TLS HTTP requests using HTTP 2 without HTTP 1.1 +Upgrade. It requires prior knowledge that the server supports +HTTP 2 straight away. HTTPS requests will still do HTTP/2 the +standard way with negotiated protocol version in the TLS +handshake. Requires libcurl 7.49.0+. + + +*more details [here](https://curl.haxx.se/libcurl/c/CURLOPT_HTTP_VERSION.html), where the documentation for +this setting was inspired (read: pilfered) from* + + +```opensips title="Setting the curl_http_version parameter" +... +modparam("rest_client", "curl_http_version", 3) +... +``` + + +#### enable_expect_100 (boolean) + + +Include a "Expect: 100-continue" HTTP header field whenever the body +size of a POST or PUT request exceeds 1024 bytes. Once enabled, the +timeout for waiting for a "100 Continue" reply from the server is 1 +second, after which the body upload will begin. + + +*Default value is "false" (disabled).* + + +```opensips title="Setting the enable_expect_100 parameter" +... +modparam("rest_client", "enable_expect_100", true) +... +``` + + +#### no_concurrent_connects (boolean) + + +Set to *true* in order to only allow one OpenSIPS +worker to connect to a given URL hostname at a time. While a worker +is connecting, all other workers will receive error code +**-4 (already connecting)** when attempting +to perform any rest_client operation to the same hostname, regardless if +the operation is sync or async. + + +For sync transfers, the scope of the worker process serialization +extends to the entire cURL transfer (TCP connect + upload + download), +as all three phases take place within a single cURL library call. + + +This parameter may be useful in order to prevent system outages caused +by concurrent blocking of all OpenSIPS workers on a failed (hanging) +HTTP service, with no more free workers being left to process incoming +SIP packets. + + +*Default value is "false" (disabled).* + + +```opensips title="Setting the no_concurrent_connects parameter" +... +modparam("rest_client", "no_concurrent_connects", true) +... +``` + + +#### curl_conn_lifetime (integer) + + +Only relevant when [no concurrent connects](#param_no_concurrent_connects) is enabled. +By setting this parameter, script developers can leverage the connection +reusage capabilities of libcURL and entirely skip the "no concurrent transfers" +logic on a given SIP worker, should that worker already be known to have a TCP +connection to the target URL hostname +(established by a previous rest_xxx() function call). + + +The parameter denotes the lifetime, in seconds, of TCP connections kept +within libcURL for reusage, a setting which is often operating system +dependant, and which may also be affected by enabling/disabling keepalives. +Consult your operating system's and/or libcurl's documentation for further +information on the max lifetime of your cURL TCP connections. + + +*Default value is *0* (disabled).* + + +```opensips title="Setting the curl_conn_lifetime parameter" +... +modparam("rest_client", "curl_conn_lifetime", 1800) +... +``` + + +### Exported Functions + + +#### rest_get(url, body_pv, [ctype_pv], [retcode_pv]) + + +Perform a blocking HTTP GET on the given *url* and +return a representation of the resource. + + +Parameters: + + +- *url* (string) +- *body_pv* (var) - output variable which will hold the +body of the HTTP response. +- *ctype_pv* (var, optional) - output variable which will +contain the value of the "Content-Type:" header of the response. +- *retcode_pv* (var, optional) - output variable which will +retain the status code of the HTTP response. +A **0** status code value means no HTTP +reply arrived at all. + + +**Return Codes** + + +- **1** - Success +- **-1** - Connection Refused. +- **-2** - Connection Timeout +(the [connection timeout](#param_connection_timeout) was exceeded +before a TCP connection could be established) +- **-3** - Transfer Timeout +(the [curl timeout](#param_curl_timeout) was exceeded before the +last byte was received). The *retcode_pv* may +be set to 200 or 0, depending whether a 200 OK was received or not. +If it was, the *body_pv* will contain partially +downloaded data, use at your own risk! (we recommend you only use +this data for logging / debugging purposes) +- **-4** - Already Connecting +(another OpenSIPS worker is already connecting to this URL hostname. +Consult [no concurrent connects](#param_no_concurrent_connects) for more info). +- **-10** - Internal Error (out of +memory, unexpected libcurl error, etc.) + + +This function can be used from any route. + + +```opensips title="rest_get usage" +... +# Example of querying a REST service to get the credit of an account +$var(rc) = rest_get("https://getcredit.org/?account=$fU", + $var(credit), + $var(ct), + $var(rcode)); +if ($var(rc) < 0) { + xlog("rest_get() failed with $var(rc), acc=$fU\n"); + send_reply(500, "Server Internal Error"); + exit; +} + +if ($var(rcode) != 200) { + xlog("L_INFO", "rest_get() rcode=$var(rcode), acc=$fU\n"); + send_reply(403, "Forbidden"); + exit; +} +... +``` + + +#### rest_post(url, send_body, [send_ctype], recv_body_pv, [recv_ctype_pv], [retcode_pv]) + + +Perform a blocking HTTP POST on the given *url*. + + +> [!NOTE] +> The *send_body* parameter can also accept a format-string +> but it cannot be larger than 1024 bytes. For larger messages, you must build them in a +> pseudo-variable and pass it to the function. + + +Parameters: + + +- *url* (string) +- *send_body* (string) - The request body. +- *send_ctype* (string, optional) - The MIME +Content-Type header for the request. The default is +*"application/x-www-form-urlencoded"* +- *recv_body_pv* (var) - output variable which +will hold the body of the HTTP response. +- *recv_ctype_pv* (var, optional) - output +variable which will contain the value of the "Content-Type" +header of the response +- *retcode_pv* (var, optional) - output variable +which will retain the status code of the HTTP response. +A **0** status code value means no HTTP +reply arrived at all. + + +**Return Codes** + + +- **1** - Success +- **-1** - Connection Refused. +- **-2** - Connection Timeout +(the [connection timeout](#param_connection_timeout) was exceeded +before a TCP connection could be established) +- **-3** - Transfer Timeout +(the [curl timeout](#param_curl_timeout) was exceeded before the +last byte was received). The *retcode_pv* may +be set to 200 or 0, depending whether a 200 OK was received or not. +If it was, the *body_pv* will contain partially +downloaded data, use at your own risk! (we recommend you only use +this data for logging / debugging purposes) +- **-4** - Already Connecting +(another OpenSIPS worker is already connecting to this URL hostname. +Consult [no concurrent connects](#param_no_concurrent_connects) for more info). +- **-10** - Internal Error (out of +memory, unexpected libcurl error, etc.) + + +This function can be used from any route. + + +```opensips title="rest_post usage" +... +# Creating a resource using a RESTful service with an HTTP POST request +$var(rc) = rest_post("https://myserver.org/register_user", + $fU, , $var(body), $var(ct), $var(rcode)); +if ($var(rc) < 0) { + xlog("rest_post() failed with $var(rc), user=$fU\n"); + send_reply(500, "Server Internal Error 1"); + exit; +} + +if ($var(rcode) != 200) { + xlog("rest_post() rcode=$var(rcode), user=$fU\n"); + send_reply(500, "Server Internal Error 2"); + exit; +} +... +``` + + +#### rest_put(url, send_body, [send_ctype], recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) + + +Perform a blocking HTTP PUT on the given *url*. + + +Similar to [rest post](#func_rest_post), the *send_body_pv* +parameter can also accept a format-string but it cannot be larger than 1024 bytes. For +larger messages, you must build them in a pseudo-variable and pass it to the function. + + +Parameters: + + +- *url* (string) +- *send_body* (string) - The request body. +- *send_ctype* (string, optional) - The MIME +Content-Type header for the request. The default is +*"application/x-www-form-urlencoded"* +- *recv_body_pv* (var) - output variable which +will hold the body of the HTTP response. +- *recv_ctype_pv* (var, optional) - output variable +which will contain the value of the "Content-Type" header of the response +- *retcode_pv* (var, optional) - output variable +which will retain the status code of the HTTP response. +A **0** status code value means no HTTP +reply arrived at all. + + +**Return Codes** + + +- **1** - Success +- **-1** - Connection Refused. +- **-2** - Connection Timeout +(the [connection timeout](#param_connection_timeout) was exceeded +before a TCP connection could be established) +- **-3** - Transfer Timeout +(the [curl timeout](#param_curl_timeout) was exceeded before the +last byte was received). The *retcode_pv* may +be set to 200 or 0, depending whether a 200 OK was received or not. +If it was, the *body_pv* will contain partially +downloaded data, use at your own risk! (we recommend you only use +this data for logging / debugging purposes) +- **-4** - Already Connecting +(another OpenSIPS worker is already connecting to this URL hostname. +Consult [no concurrent connects](#param_no_concurrent_connects) for more info). +- **-10** - Internal Error (out of +memory, unexpected libcurl error, etc.) + + +This function can be used from any route. + + +```opensips title="rest_put usage" +... +# Creating/Updating a resource using a RESTful service with an HTTP PUT request +$var(rc) = rest_put("https://myserver.org/users/$fU", + $var(userinfo), , $var(body), $var(ct), $var(rcode)); +if ($var(rc) < 0) { + xlog("rest_put() failed with $var(rc), user=$fU\n"); + send_reply(500, "Server Internal Error 3"); + exit; +} + +if ($var(rcode) != 200) { + xlog("rest_put() rcode=$var(rcode), user=$fU\n"); + send_reply(500, "Server Internal Error 4"); + exit; +} +... +``` + + +#### rest_append_hf(txt) + + +Append *txt* to the HTTP headers of the subsequent request. +Multiple headers can be appended by making multiple calls +before executing a request. + + +The contents of *txt* should adhere to the +specification for HTTP headers (ex. Field: Value) + + +Parameters + + +- *txt* (string) + + +This function can be used from any route. + + +```opensips title="rest_append_hf usage" +... +# Example of querying a REST service requiring additional headers + +rest_append_hf("Authorization: Bearer mF_9.B5f-4.1JqM"); +$var(rc) = rest_get("http://getcredit.org/?account=$fU", $var(credit)); +... + +``` + + +#### rest_init_client_tls(tls_client_domain) + + +Force a specific TLS domain to be used at most once, during the next +GET/POST/PUT request. Refer to the tls_mgm module for additional info +regarding TLS client domains. + + +If using this function, you must also ensure that tls_mgm is loaded +and properly configured. + + +Parameters + + +- *tls_client_domain* (string) + + +This function can be used from any route. + + +```opensips title="rest_init_client_tls usage" +... +rest_init_client_tls("dom1"); +if (!rest_get("https://example.com")) + xlog("query failed\n"); +... + +``` + + +### Exported Asynchronous Functions + + +#### rest_get(url, body_pv[, [ctype_pv][, [retcode_pv]]]) + + +Perform an asynchronous HTTP GET. This function behaves exactly the same as +**[rest get](#func_rest_get)** +(in terms of input, output and processing), +but in a non-blocking manner. Script execution is suspended until the +entire content of the HTTP response is available. + + +```opensips title="async rest_get usage" +route { + ... + async(rest_get("http://getcredit.org/?account=$fU", + $var(credit), , $var(rcode)), resume); +} + +route [resume] { + $var(rc) = $rc; + if ($var(rc) < 0) { + xlog("async rest_get() failed with $var(rc), acc=$fU\n"); + send_reply(500, "Server Internal Error"); + exit; + } + + if ($var(rcode) != 200) { + xlog("L_INFO", "async rest_get() rcode=$var(rcode), acc=$fU\n"); + send_reply(403, "Forbidden"); + exit; + } + + ... +} +``` + + +#### rest_post(url, send_body_pv, [send_ctype_pv], recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) + + +Perform an asynchronous HTTP POST. This function behaves exactly the same as +**[rest post](#func_rest_post)** (in +terms of input, output and processing), but in a non-blocking manner. +Script execution is suspended until the entire content of the HTTP +response is available. + + +```opensips title="async rest_post usage" +route { + ... + async(rest_post("http://myserver.org/register_user", + $fU, , $var(body), $var(ct), $var(rcode)), resume); +} + +route [resume] { + $var(rc) = $rc; + if ($var(rc) < 0) { + xlog("async rest_post() failed with $var(rc), user=$fU\n"); + send_reply(500, "Server Internal Error 1"); + exit; + } + if ($var(rcode) != 200) { + xlog("async rest_post() rcode=$var(rcode), user=$fU\n"); + send_reply(500, "Server Internal Error 2"); + exit; + } + + ... +} +``` + + +#### rest_put(url, send_body_pv, [send_ctype_pv], recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) + + +Perform an asynchronous HTTP PUT. This function behaves exactly the same as +**[rest put](#func_rest_put)** (in +terms of input, output and processing), but in a non-blocking manner. +Script execution is suspended until the entire content of the HTTP +response is available. + + +```opensips title="async rest_put usage" +route { + ... + async(rest_put("http://myserver.org/users/$fU", $var(userinfo), , + $var(body), $var(ct), $var(rcode)), resume); +} + +route [resume] { + $var(rc) = $rc; + if ($var(rc) < 0) { + xlog("async rest_put() failed with $var(rc), user=$fU\n"); + send_reply(500, "Server Internal Error 3"); + exit; + } + if ($var(rcode) != 200) { + xlog("async rest_put() rcode=$var(rcode), user=$fU\n"); + send_reply(500, "Server Internal Error 4"); + exit; + } + + ... +} +``` + + +### Exported script transformations + + +The module also provides a way for encoding and decoding parameters +contained in an arbitrary script variable, in accordance with +RFC3986. This is done by applying a transformation to a script +variable containing the data to be encoded. The value of the +original variable is not altered and a corresponding string value +is returned. The transformation is performed through libcurl API +method curl_easy_escape (or curl_escape for libcurl < 7.15.4). + + +#### {rest.escape} + + +The result of this transformation is to produce percent encoded string value which can be safely used in URI construction. + + +There are no parameters for this transformation. + + +```opensips title="rest.escape usage" +... +# This example would produce log entry: "Output: call%40example.com%26safe%3Dfalse" +$var(tmp) = "call@example.com&safe=false"; +xlog("Output: $(var(tmp){rest.escape})\n"); + +# Encode call ID before transmission: +$var(rc) = rest_get("https://call-info.org/?id=$(ci{rest.escape})", $var(body_pv)); +... + +``` + + +#### {rest.unescape} + + +The result of this transformation is to decode percent encoded string values. + + +There are no parameters for this transformation. + + +```opensips title="rest.unescape usage" +... +# This example would produce log entry: "Output: 1+1=2!" +$var(tmp) = "1%2B1%3D2%21"; +xlog("Output: $(var(tmp){rest.unescape})\n"); + +# This example would produce log entry: "OpenSIPs, tastes better with every SIP!" +$var(tmp) = "OpenSIPs%2C%20tastes%20better%20with%20every%20SIP%21"; +xlog("$(var(tmp){rest.unescape})\n"); +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rest_client/doc/contributors.xml b/modules/rest_client/doc/contributors.xml deleted file mode 100644 index 75e5e538985..00000000000 --- a/modules/rest_client/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 150 - 86 - 4034 - 1785 - - - 2. - Ionut Ionita (@ionutrazvanionita) - 23 - 12 - 663 - 262 - - - 3. - Vlad Patrascu (@rvlad-patrascu) - 17 - 8 - 336 - 345 - - - 4. - Razvan Crainea (@razvancrainea) - 15 - 13 - 41 - 17 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 8 - 6 - 115 - 48 - - - 6. - Jarrod Baumann (@jarrodb) - 6 - 3 - 131 - 32 - - - 7. - Agalya Ramachandran (@AgalyaR) - 6 - 2 - 354 - 1 - - - 8. - Callum Guy (@spacetourist) - 6 - 2 - 281 - 8 - - - 9. - Ryan Bullock (@rrb3942) - 5 - 2 - 91 - 77 - - - 10. - Aron Podrigal (@ar45) - 4 - 2 - 15 - 7 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Maksym Sobolyev (@sobomax), John Burke (@john08burke), Vlad Paiu (@vladpaiu), Andrey Vorobiev (@andrey-vorobiev). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Nov 2025 - - - 2. - Vlad Paiu (@vladpaiu) - Nov 2025 - Nov 2025 - - - 3. - Peter Lemenkov (@lemenkov) - Jun 2018 - Oct 2025 - - - 4. - Liviu Chircu (@liviuchircu) - Mar 2013 - Sep 2024 - - - 5. - Aron Podrigal (@ar45) - Sep 2024 - Sep 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Oct 2020 - Feb 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2021 - - - 8. - John Burke (@john08burke) - Apr 2021 - Apr 2021 - - - 9. - Callum Guy (@spacetourist) - Jan 2020 - Jan 2020 - - - 10. - Razvan Crainea (@razvancrainea) - Aug 2015 - Nov 2019 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Andrey Vorobiev (@andrey-vorobiev), Ryan Bullock (@rrb3942), Agalya Ramachandran (@AgalyaR), Jarrod Baumann (@jarrodb). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Callum Guy (@spacetourist), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Agalya Ramachandran (@AgalyaR), Jarrod Baumann (@jarrodb), Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/rest_client/doc/rest_client.xml b/modules/rest_client/doc/rest_client.xml deleted file mode 100644 index 8151176efde..00000000000 --- a/modules/rest_client/doc/rest_client.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - rest_client Module - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - diff --git a/modules/rest_client/doc/rest_client_admin.xml b/modules/rest_client/doc/rest_client_admin.xml deleted file mode 100644 index 58fe01296c6..00000000000 --- a/modules/rest_client/doc/rest_client_admin.xml +++ /dev/null @@ -1,845 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The rest_client module provides a means of interacting - with an HTTP server by doing RESTful queries, such as GET, POST and PUT. - -
- -
- TCP Connection Reusage - - Unless specified otherwise by the server through a "Connection: close" - indication, the module will keep and reuse the TCP connections it creates - as much as possible, regardless if the script writer performs blocking or - asynchronous HTTP requests. These connections are not shared among OpenSIPS - workers — each worker maintains its own set of connections. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules.. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - libcurl. - - - - -
-
- -
- Exported Parameters -
- <varname>curl_timeout</varname> (integer) - - The maximum allowed time for any HTTP(S) transfer to complete. This - interval is inclusive of the initial connect time window, hence the value - of this parameter must be greater than or equal to - . - - - - Default value is 20 seconds. - - - - Setting the <varname>curl_timeout</varname> parameter - -... -modparam("rest_client", "curl_timeout", 10) -... - - -
- -
- <varname>connection_timeout</varname> (integer) - - The maximum allowed time to establish a connection with the server. - - - - Default value is 20 seconds. - - - - Setting the <varname>connection_timeout</varname> parameter - -... -modparam("rest_client", "connection_timeout", 4) -... - - -
- -
- <varname>connect_poll_interval</varname> (integer) - - Only relevant with async requests. Allows complete control over how - quickly we want to detect libcurl's completed blocking TCP/TLS handshakes, - so the async transfers can be put in the background. A lower - may speed up all async - HTTP transfers, but will also increase CPU usage. - - - - Default value is 20 milliseconds. - - - - Setting the <varname>connect_poll_interval</varname> parameter - -... -modparam("rest_client", "connect_poll_interval", 2) -... - - -
- -
- <varname>max_async_transfers</varname> (integer) - - Maximum number of asynchronous HTTP transfers a single - OpenSIPS worker is allowed to run simultaneously. As long as this threshold - is reached for a worker, all new async transfers it attempts to perform - will be done in a blocking manner, with appropriate logging warnings. - - - - Default value is 100. - - - - Setting the <varname>max_async_transfers</varname> parameter - -... -modparam("rest_client", "max_async_transfers", 300) -... - - -
- -
- <varname>max_transfer_size</varname> (integer) - - The maximum allowed size of a single transfer (download). Reaching - this limit during a transfer will cause the transfer to stop - immediately, returning error -10 at script level. A value of - 0 will disable the check. - - - - Default value is 10240 (KB). - - - - Setting the <varname>max_transfer_size</varname> parameter - -... -modparam("rest_client", "max_transfer_size", 64) -... - - -
- -
- <varname>ssl_verifypeer</varname> (integer) - - Set this to 0 in order to disable the verification of the remote peer's - certificate. Verification is done using a default bundle of CA certificates - which come with libcurl. - - - - Default value is 1 (enabled). - - - - Setting the <varname>ssl_verifypeer</varname> parameter - -... -modparam("rest_client", "ssl_verifypeer", 0) -... - - -
- -
- <varname>ssl_verifyhost</varname> (integer) - - Set this to 0 in order to disable the verification that the remote peer - actually corresponds to the server listed in the certificate. - - - - Default value is 1 (enabled). - - - - Setting the <varname>ssl_verifyhost</varname> parameter - -... -modparam("rest_client", "ssl_verifyhost", 0) -... - - -
- -
- <varname>ssl_capath</varname> (integer) - - An optional path for CA certificates to be used for host verifications. - - - Setting the <varname>ssl_capath</varname> parameter - -... -modparam("rest_client", "ssl_capath", "/home/opensips/ca_certificates") -... - - -
- -
- <varname>curl_http_version</varname> (integer) - - Use a specific HTTP version for all requests. Possible values: - - - - - 0 (default) - use whatever is deemed fit by libcurl - - - 1 - enforce HTTP 1.0 requests - - - 2 - enforce HTTP 1.1 requests - - - 3 - attempt HTTP 2 requests. Fall back to HTTP 1.1 if HTTP 2 - cannot be negotiated with the server. Requires libcurl 7.33.0+. - - - - 4 - attempt HTTP 2 over TLS (HTTPS) only. Fall back to HTTP - 1.1 if HTTP 2 cannot be negotiated with the HTTPS server. - For clear text HTTP servers, use HTTP 1.1. - Requires libcurl 7.47.0+. - - - - 5 - Issue non-TLS HTTP requests using HTTP 2 without HTTP 1.1 - Upgrade. It requires prior knowledge that the server supports - HTTP 2 straight away. HTTPS requests will still do HTTP/2 the - standard way with negotiated protocol version in the TLS - handshake. Requires libcurl 7.49.0+. - - - - - - more details - here, where the documentation for - this setting was inspired (read: pilfered) from - - - Setting the <varname>curl_http_version</varname> parameter - -... -modparam("rest_client", "curl_http_version", 3) -... - - -
- -
- <varname>enable_expect_100</varname> (boolean) - - Include a "Expect: 100-continue" HTTP header field whenever the body - size of a POST or PUT request exceeds 1024 bytes. Once enabled, the - timeout for waiting for a "100 Continue" reply from the server is 1 - second, after which the body upload will begin. - - - - Default value is false (disabled). - - - - Setting the <varname>enable_expect_100</varname> parameter - -... -modparam("rest_client", "enable_expect_100", true) -... - - -
- -
- <varname>no_concurrent_connects</varname> (boolean) - - Set to true in order to only allow one OpenSIPS - worker to connect to a given URL hostname at a time. While a worker - is connecting, all other workers will receive error code - -4 (already connecting) when attempting - to perform any rest_client operation to the same hostname, regardless if - the operation is sync or async. - - - For sync transfers, the scope of the worker process serialization - extends to the entire cURL transfer (TCP connect + upload + download), - as all three phases take place within a single cURL library call. - - - This parameter may be useful in order to prevent system outages caused - by concurrent blocking of all OpenSIPS workers on a failed (hanging) - HTTP service, with no more free workers being left to process incoming - SIP packets. - - - - Default value is false (disabled). - - - - Setting the <varname>no_concurrent_connects</varname> parameter - -... -modparam("rest_client", "no_concurrent_connects", true) -... - - -
- -
- <varname>curl_conn_lifetime</varname> (integer) - - Only relevant when is enabled. - By setting this parameter, script developers can leverage the connection - reusage capabilities of libcURL and entirely skip the "no concurrent transfers" - logic on a given SIP worker, should that worker already be known to have a TCP - connection to the target URL hostname - (established by a previous rest_xxx() function call). - - - The parameter denotes the lifetime, in seconds, of TCP connections kept - within libcURL for reusage, a setting which is often operating system - dependant, and which may also be affected by enabling/disabling keepalives. - Consult your operating system's and/or libcurl's documentation for further - information on the max lifetime of your cURL TCP connections. - - - - Default value is 0 (disabled). - - - - Setting the <varname>curl_conn_lifetime</varname> parameter - -... -modparam("rest_client", "curl_conn_lifetime", 1800) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">rest_get(url, body_pv, [ctype_pv], [retcode_pv])</function> - - - Perform a blocking HTTP GET on the given url and - return a representation of the resource. - - Parameters: - - - url (string) - - - body_pv (var) - output variable which will hold the - body of the HTTP response. - - - ctype_pv (var, optional) - output variable which will - contain the value of the "Content-Type:" header of the response. - - - retcode_pv (var, optional) - output variable which will - retain the status code of the HTTP response. - A 0 status code value means no HTTP - reply arrived at all. - - - - &rest_return_codes; - - - This function can be used from any route. - - - <function moreinfo="none">rest_get</function> usage - -... -# Example of querying a REST service to get the credit of an account -$var(rc) = rest_get("https://getcredit.org/?account=$fU", - $var(credit), - $var(ct), - $var(rcode)); -if ($var(rc) < 0) { - xlog("rest_get() failed with $var(rc), acc=$fU\n"); - send_reply(500, "Server Internal Error"); - exit; -} - -if ($var(rcode) != 200) { - xlog("L_INFO", "rest_get() rcode=$var(rcode), acc=$fU\n"); - send_reply(403, "Forbidden"); - exit; -} -... - - -
-
- - <function moreinfo="none">rest_post(url, send_body, [send_ctype], - recv_body_pv, [recv_ctype_pv], [retcode_pv]) - </function> - - - Perform a blocking HTTP POST on the given url. - - - Note that the send_body parameter can also accept a format-string - but it cannot be larger than 1024 bytes. For larger messages, you must build them in a - pseudo-variable and pass it to the function. - - - Parameters: - - - url (string) - - - send_body (string) - The request body. - - - send_ctype (string, optional) - The MIME - Content-Type header for the request. The default is - "application/x-www-form-urlencoded" - - - recv_body_pv (var) - output variable which - will hold the body of the HTTP response. - - - recv_ctype_pv (var, optional) - output - variable which will contain the value of the "Content-Type" - header of the response - - - retcode_pv (var, optional) - output variable - which will retain the status code of the HTTP response. - A 0 status code value means no HTTP - reply arrived at all. - - - - &rest_return_codes; - - - This function can be used from any route. - - - <function moreinfo="none">rest_post</function> usage - -... -# Creating a resource using a RESTful service with an HTTP POST request -$var(rc) = rest_post("https://myserver.org/register_user", - $fU, , $var(body), $var(ct), $var(rcode)); -if ($var(rc) < 0) { - xlog("rest_post() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 1"); - exit; -} - -if ($var(rcode) != 200) { - xlog("rest_post() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 2"); - exit; -} -... - - - -
-
- - <function moreinfo="none">rest_put(url, send_body, [send_ctype], - recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) - </function> - - - Perform a blocking HTTP PUT on the given url. - - - Similar to , the send_body_pv - parameter can also accept a format-string but it cannot be larger than 1024 bytes. For - larger messages, you must build them in a pseudo-variable and pass it to the function. - - - Parameters: - - - url (string) - - - send_body (string) - The request body. - - - send_ctype (string, optional) - The MIME - Content-Type header for the request. The default is - "application/x-www-form-urlencoded" - - - recv_body_pv (var) - output variable which - will hold the body of the HTTP response. - - - recv_ctype_pv (var, optional) - output variable - which will contain the value of the "Content-Type" header of the response - - - retcode_pv (var, optional) - output variable - which will retain the status code of the HTTP response. - A 0 status code value means no HTTP - reply arrived at all. - - - - &rest_return_codes; - - - This function can be used from any route. - - - <function moreinfo="none">rest_put</function> usage - -... -# Creating/Updating a resource using a RESTful service with an HTTP PUT request -$var(rc) = rest_put("https://myserver.org/users/$fU", - $var(userinfo), , $var(body), $var(ct), $var(rcode)); -if ($var(rc) < 0) { - xlog("rest_put() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 3"); - exit; -} - -if ($var(rcode) != 200) { - xlog("rest_put() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 4"); - exit; -} -... - - -
-
- - <function moreinfo="none">rest_append_hf(txt)</function> - - - Append txt to the HTTP headers of the subsequent request. - Multiple headers can be appended by making multiple calls - before executing a request. - - - The contents of txt should adhere to the - specification for HTTP headers (ex. Field: Value) - - Parameters - - - txt (string) - - - - This function can be used from any route. - - - <function moreinfo="none">rest_append_hf</function> usage - -... -# Example of querying a REST service requiring additional headers - -rest_append_hf("Authorization: Bearer mF_9.B5f-4.1JqM"); -$var(rc) = rest_get("http://getcredit.org/?account=$fU", $var(credit)); -... - - -
-
- - <function moreinfo="none">rest_init_client_tls(tls_client_domain)</function> - - - Force a specific TLS domain to be used at most once, during the next - GET/POST/PUT request. Refer to the tls_mgm module for additional info - regarding TLS client domains. - - - If using this function, you must also ensure that tls_mgm is loaded - and properly configured. - - Parameters - - - tls_client_domain (string) - - - - This function can be used from any route. - - - <function moreinfo="none">rest_init_client_tls</function> usage - -... -rest_init_client_tls("dom1"); -if (!rest_get("https://example.com")) - xlog("query failed\n"); -... - - -
-
- -
- Exported Asynchronous Functions -
- - <function moreinfo="none">rest_get(url, body_pv[, [ctype_pv][, [retcode_pv]]]) - </function> - - - Perform an asynchronous HTTP GET. This function behaves exactly the same as - - (in terms of input, output and processing), - but in a non-blocking manner. Script execution is suspended until the - entire content of the HTTP response is available. - - - <function moreinfo="none">async rest_get</function> usage - -route { - ... - async(rest_get("http://getcredit.org/?account=$fU", - $var(credit), , $var(rcode)), resume); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_get() failed with $var(rc), acc=$fU\n"); - send_reply(500, "Server Internal Error"); - exit; - } - - if ($var(rcode) != 200) { - xlog("L_INFO", "async rest_get() rcode=$var(rcode), acc=$fU\n"); - send_reply(403, "Forbidden"); - exit; - } - - ... -} - - -
- -
- - <function moreinfo="none">rest_post(url, send_body_pv, [send_ctype_pv], - recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) - </function> - - - Perform an asynchronous HTTP POST. This function behaves exactly the same as - (in - terms of input, output and processing), but in a non-blocking manner. - Script execution is suspended until the entire content of the HTTP - response is available. - - - <function moreinfo="none">async rest_post</function> usage - -route { - ... - async(rest_post("http://myserver.org/register_user", - $fU, , $var(body), $var(ct), $var(rcode)), resume); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_post() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 1"); - exit; - } - if ($var(rcode) != 200) { - xlog("async rest_post() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 2"); - exit; - } - - ... -} - - - -
- -
- - <function moreinfo="none">rest_put(url, send_body_pv, [send_ctype_pv], - recv_body_pv[, [recv_ctype_pv][, [retcode_pv]]]) - </function> - - - Perform an asynchronous HTTP PUT. This function behaves exactly the same as - (in - terms of input, output and processing), but in a non-blocking manner. - Script execution is suspended until the entire content of the HTTP - response is available. - - - <function moreinfo="none">async rest_put</function> usage - -route { - ... - async(rest_put("http://myserver.org/users/$fU", $var(userinfo), , - $var(body), $var(ct), $var(rcode)), resume); -} - -route [resume] { - $var(rc) = $rc; - if ($var(rc) < 0) { - xlog("async rest_put() failed with $var(rc), user=$fU\n"); - send_reply(500, "Server Internal Error 3"); - exit; - } - if ($var(rcode) != 200) { - xlog("async rest_put() rcode=$var(rcode), user=$fU\n"); - send_reply(500, "Server Internal Error 4"); - exit; - } - - ... -} - - -
- -
- -
- Exported script transformations - - The module also provides a way for encoding and decoding parameters - contained in an arbitrary script variable, in accordance with - RFC3986. This is done by applying a transformation to a script - variable containing the data to be encoded. The value of the - original variable is not altered and a corresponding string value - is returned. The transformation is performed through libcurl API - method curl_easy_escape (or curl_escape for libcurl < 7.15.4). - - -
- - <varname>{rest.escape}</varname> - - - The result of this transformation is to produce percent encoded string value which can be safely used in URI construction. - - - There are no parameters for this transformation. - - - <varname>rest.escape</varname> usage - -... -# This example would produce log entry: "Output: call%40example.com%26safe%3Dfalse" -$var(tmp) = "call@example.com&safe=false"; -xlog("Output: $(var(tmp){rest.escape})\n"); - -# Encode call ID before transmission: -$var(rc) = rest_get("https://call-info.org/?id=$(ci{rest.escape})", $var(body_pv)); -... - - - -
- -
- - <varname>{rest.unescape}</varname> - - - The result of this transformation is to decode percent encoded string values. - - - There are no parameters for this transformation. - - - <varname>rest.unescape</varname> usage - -... -# This example would produce log entry: "Output: 1+1=2!" -$var(tmp) = "1%2B1%3D2%21"; -xlog("Output: $(var(tmp){rest.unescape})\n"); - -# This example would produce log entry: "OpenSIPs, tastes better with every SIP!" -$var(tmp) = "OpenSIPs%2C%20tastes%20better%20with%20every%20SIP%21"; -xlog("$(var(tmp){rest.unescape})\n"); -... - - - -
- -
- -
diff --git a/modules/rest_client/doc/rest_return_codes.xml b/modules/rest_client/doc/rest_return_codes.xml deleted file mode 100644 index 26bbeb5b16c..00000000000 --- a/modules/rest_client/doc/rest_return_codes.xml +++ /dev/null @@ -1,38 +0,0 @@ -Return Codes - - - 1 - Success - - - - -1 - Connection Refused. - - - - -2 - Connection Timeout - (the was exceeded - before a TCP connection could be established) - - - - -3 - Transfer Timeout - (the was exceeded before the - last byte was received). The retcode_pv may - be set to 200 or 0, depending whether a 200 OK was received or not. - If it was, the body_pv will contain partially - downloaded data, use at your own risk! (we recommend you only use - this data for logging / debugging purposes) - - - - -4 - Already Connecting - (another OpenSIPS worker is already connecting to this URL hostname. - Consult for more info). - - - - -10 - Internal Error (out of - memory, unexpected libcurl error, etc.) - - - diff --git a/modules/rest_client/rest_cb.c b/modules/rest_client/rest_cb.c index fb390ffdecc..8cc84e5707e 100644 --- a/modules/rest_client/rest_cb.c +++ b/modules/rest_client/rest_cb.c @@ -43,7 +43,7 @@ size_t write_func(char *ptr, size_t size, size_t nmemb, void *body) str *buff = (str *)body; #ifdef EXTRA_DEBUG - LM_DBG("got body piece! bs: %lu, blocks: %lu\n", size, nmemb); + LM_DBG("got body piece! bs: %zu, blocks: %zu\n", size, nmemb); #endif if (len == 0) @@ -108,4 +108,3 @@ size_t header_func(char *ptr, size_t size, size_t nmemb, void *userdata) return len; } - diff --git a/modules/rls/README b/modules/rls/README deleted file mode 100644 index 79611304e1b..00000000000 --- a/modules/rls/README +++ /dev/null @@ -1,432 +0,0 @@ -Resource List Server - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. rlsubs_table(str) - 1.3.2. rlpres_table(str) - 1.3.3. clean_period (int) - 1.3.4. waitn_time (int) - 1.3.5. max_expires (int) - 1.3.6. hash_size (int) - 1.3.7. xcap_root (str) - 1.3.8. to_presence_code (int) - 1.3.9. rls_event (str) - 1.3.10. presence_server (str) - 1.3.11. contact_user (str) - - 1.4. Exported Functions - - 1.4.1. rls_handle_subscribe() - 1.4.2. rls_handle_notify() - - 1.5. Exported MI Functions - - 1.5.1. rls_update_subscriptions - - 1.6. Installation - - 2. Developer Guide - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set rlsubs_table parameter - 1.2. Set rlpres_table parameter - 1.3. Set clean_period parameter - 1.4. Set waitn_time parameter - 1.5. Set max_expires parameter - 1.6. Set hash_size parameter - 1.7. Set hash_size parameter - 1.8. Set to_presence_code parameter - 1.9. Set rls_event parameter - 1.10. Set presence_server parameter - 1.11. Set contact_user parameter - 1.12. rls_handle_subscribe usage - 1.13. rls_handle_notify usage - -Chapter 1. Admin Guide - -1.1. Overview - - The modules is a Resource List Server implementation following - the specification in RFC 4662 and RFC 4826. - - The server is independent from local presence servers, - retrieving presence information with Subscribe-Notify messages. - - The module uses the presence module as a library, as it - requires a resembling mechanism for handling Subscribe. - Therefore, in case the local presence server is not collocated - on the same machine with the RL server, the presence module - should be loaded in a library mode only (see doc for presence - module). - - It handles subscription to lists in an event independent - way.The default event is presence, but if some other events are - to be handled by the server, they should be added using the - module parameter "rls_events". - - It works with XCAP server for storage. There is also the - possibility to configure it to work in an integrated_xcap - server mode, when it only queries database for the resource - lists documents. This is useful in a small architecture when - all the clients use an integrated server and there are no - references to exterior documents in their lists. - - The same as presence module, it has a caching mode with - periodical update in database for subscribe information. The - information retrieved with Notify messages is stored in - database only. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - * signaling. - * tm. - * presence- in a library mode. - * pua. - * xcap. - -1.2.2. External Libraries or Applications - - * libxml-dev. - -1.3. Exported Parameters - -1.3.1. rlsubs_table(str) - - The name of the db table where resource lists subscription - information is stored. - - Default value is “rls_watchers”. - - Example 1.1. Set rlsubs_table parameter -... -modparam("rls", "rlsubs_table", "rls_subscriptions") -... - -1.3.2. rlpres_table(str) - - The name of the db table where notified event specific - information is stored. - - Default value is “rls_presentity”. - - Example 1.2. Set rlpres_table parameter -... -modparam("rls", "rlpres_table", "rls_notify") -... - -1.3.3. clean_period (int) - - The period at which to check for expired information. - - Default value is “100”. - - Example 1.3. Set clean_period parameter -... -modparam("rls", "clean_period", 100) -... - -1.3.4. waitn_time (int) - - The timer period at which the server should attempt to send - Notifies with the updated presence state of the subscribed list - or watcher information. - - Default value is “50”. - - Example 1.4. Set waitn_time parameter -... -modparam("rls", "waitn_time", 10) -... - -1.3.5. max_expires (int) - - The maximum accepted expires for a subscription to a list. - - Default value is “7200”. - - Example 1.5. Set max_expires parameter -... -modparam("rls", "max_expires", 10800) -... - -1.3.6. hash_size (int) - - The dimension of the hash table used to store subscription to a - list. This parameter will be used as the power of 2 when - computing table size. - - Default value is “9 (512)”. - - Example 1.6. Set hash_size parameter -... -modparam("rls", "hash_size", 11) -... - -1.3.7. xcap_root (str) - - The address of the xcap server. - - Default value is “NULL”. - - Example 1.7. Set hash_size parameter -... -modparam("rls", "xcap_root", "http://192.168.2.132/xcap-root:800") -... - -1.3.8. to_presence_code (int) - - The code to be returned by rls_handle_subscribe function if the - processed Subscribe is not a resource list Subscribe. This code - can be used in an architecture with presence and rls servers - collocated on the same machine, to call handle_subscribe on the - message causing this code. - - Default value is “0”. - - Example 1.8. Set to_presence_code parameter -... -modparam("rls", "to_presence_code", 10) -... - -1.3.9. rls_event (str) - - The default event that RLS handles is presence. If some other - events should also be handled by RLS they should be added using - this parameter. It can be set more than once. - - Default value is “"presence"”. - - Example 1.9. Set rls_event parameter -... -modparam("rls", "rls_event", "dialog;sla") -... - -1.3.10. presence_server (str) - - The address of the presence server. It will be used as outbound - proxy for Subscribe requests sent by the RLS server to bouncing - on and off the proxy and having to include special processing - for this messages in the proxy's configuration file. - - Example 1.10. Set presence_server parameter -... -modparam("rls", "presence_server", "sip:pres@opensips.org:5060") -... - -1.3.11. contact_user (str) - - This is the username that will be used in the Contact header - for the 200 OK replies to SUBSCRIBE and in the following - in-dialog NOTIFY requests, as well as for the SUBSCRIBE - requests that are generated by the RLS server. The IP address, - port and transport for the Contact will be automatically - determined based on the interface where the SUBSCRIBE was - received or sent from. - - If set to an empty string, no username will be added to the - contact and the contact will be built just out of the IP, port - and transport. - - Default value is “rls”. - - Example 1.11. Set contact_user parameter -... -modparam("rls", "contact_user", "rls") -... - -1.4. Exported Functions - -1.4.1. rls_handle_subscribe() - - This function detects if a Subscribe message should be handled - by RLS. If not it replies with the configured to_presence_code. - If it is, it extracts the dialog info and sends aggregate - Notify requests with information for the list. - - This function can be used from REQUEST_ROUTE. - - Example 1.12. rls_handle_subscribe usage -... -For presence and rls on the same machine: - modparam(rls, "to_presence_code", 10) - - if(is_method("SUBSCRIBE")) - { - $var(ret_code)= rls_handle_subscribe(); - - if($var(ret_code)== 10) - handle_subscribe(); - - t_release(); - } - -For rls only: - if(is_method("SUBSCRIBE")) - { - rls_handle_subscribe(); - t_release(); - } - -... - -1.4.2. rls_handle_notify() - - This function has to be called for Notify messages sent by - presence servers in reply to the Subscribe messages sent by - RLS. - - This function can be used from REQUEST_ROUTE. - - It can return 3 codes: - * 1 - the Notify was inside a dialog that was recognized by - the RLS server and was processed successfully. - * 2 - the Notify did not belog to a dialog initiated by the - RLS server. - * -1 - an error occurred during processing. - - Example 1.13. rls_handle_notify usage -... -if($rm=="NOTIFY") - rls_handle_notify(); -... - -1.5. Exported MI Functions - -1.5.1. rls_update_subscriptions - - Triggers updating backend subscriptions after a resources-list - or rls-services document has been updated. - - Name: rls_update_subscriptions - - Parameters: - * presentity_uri : the uri of the user who made the change - and whose subscriptions should be updated - - MI FIFO Command Format: -opensips-cli -x mi rls_update_subscriptions sip:alice@atlanta.com - -1.6. Installation - - The module requires 2 table in OpenSIPS database: - rls_presentity and rls_watchers.The SQL syntax to create them - can be found in rls-create.sql script in the database - directories in the opensips/scripts folder. You can also find - the complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Developer Guide - - The module provides no functions to be used in other OpenSIPS - modules. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 101 41 5335 863 - 2. Saúl Ibarra Corretgé (@saghul) 40 18 1150 710 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 25 21 110 137 - 4. Dan Pascu (@danpascu) 15 10 127 138 - 5. Razvan Crainea (@razvancrainea) 14 12 20 38 - 6. Liviu Chircu (@liviuchircu) 14 11 58 79 - 7. Daniel-Constantin Mierla (@miconda) 9 7 18 15 - 8. Vlad Patrascu (@rvlad-patrascu) 7 5 28 35 - 9. Henning Westerholt (@henningw) 7 3 164 114 - 10. Vlad Paiu (@vladpaiu) 5 3 11 41 - - All remaining contributors: Walter Doekes (@wdoekes), Maksym - Sobolyev (@sobomax), Stanislaw Pitucha, Ovidiu Sas - (@ovidiusas), Sergio Gutierrez, Konstantin Bokarius, UnixDev, - John Riordan, Julián Moreno Patiño, Ken Rice, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2020 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2008 - Mar 2020 - 6. Dan Pascu (@danpascu) Aug 2008 - Jul 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 8. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 9. Julián Moreno Patiño Feb 2016 - Feb 2016 - 10. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - - All remaining contributors: Saúl Ibarra Corretgé (@saghul), - Vlad Paiu (@vladpaiu), Anca Vamanu, Stanislaw Pitucha, Walter - Doekes (@wdoekes), John Riordan, UnixDev, Sergio Gutierrez, - Henning Westerholt (@henningw), Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Dan Pascu (@danpascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Walter - Doekes (@wdoekes), Anca Vamanu, Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/rls/README.md b/modules/rls/README.md new file mode 100644 index 00000000000..3c5207f8e06 --- /dev/null +++ b/modules/rls/README.md @@ -0,0 +1,389 @@ +--- +title: "Resource List Server" +description: "The modules is a Resource List Server implementation following the specification in RFC 4662 and RFC 4826." +--- + +## Admin Guide + + +### Overview + + +The modules is a Resource List Server implementation following the +specification in RFC 4662 and RFC 4826. + + +The server is independent from local presence servers, retrieving presence +information with Subscribe-Notify messages. + + +The module uses the presence module as a library, as it requires a resembling +mechanism for handling Subscribe. Therefore, in case the local presence server +is not collocated on the same machine with the RL server, the presence module +should be loaded in a library mode only (see doc for presence module). + + +It handles subscription to lists in an event independent way.The default event +is presence, but if some other events are to be handled by the server, they +should be added using the module parameter "rls_events". + + +It works with XCAP server for storage. There is also the possibility to +configure it to work in an integrated_xcap server mode, when it only +queries database for the resource lists documents. This is useful in a +small architecture when all the clients use an integrated server and there +are no references to exterior documents in their lists. + + +The same as presence module, it has a caching mode with periodical update +in database for subscribe information. The information retrieved with Notify +messages is stored in database only. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. +- *signaling*. +- *tm*. +- *presence- in a library mode*. +- *pua*. +- *xcap*. + + +#### External Libraries or Applications + + +- *libxml-dev*. + + +### Exported Parameters + + +#### rlsubs_table(str) + + +The name of the db table where resource lists subscription +information is stored. + + +*Default value is "rls_watchers".* + + +```opensips title="Set rlsubs_table parameter" +... +modparam("rls", "rlsubs_table", "rls_subscriptions") +... +``` + + +#### rlpres_table(str) + + +The name of the db table where notified event specific +information is stored. + + +*Default value is "rls_presentity".* + + +```opensips title="Set rlpres_table parameter" +... +modparam("rls", "rlpres_table", "rls_notify") +... +``` + + +#### clean_period (int) + + +The period at which to check for expired information. + + +*Default value is "100".* + + +```opensips title="Set clean_period parameter" +... +modparam("rls", "clean_period", 100) +... +``` + + +#### waitn_time (int) + + +The timer period at which the server should attempt to send +Notifies with the updated presence state of the subscribed list +or watcher information. + + +*Default value is "50".* + + +```opensips title="Set waitn_time parameter" +... +modparam("rls", "waitn_time", 10) +... +``` + + +#### max_expires (int) + + +The maximum accepted expires for a subscription to a list. + + +*Default value is "7200".* + + +```opensips title="Set max_expires parameter" +... +modparam("rls", "max_expires", 10800) +... + +``` + + +#### hash_size (int) + + +The dimension of the hash table used to store subscription to a list. +This parameter will be used as the power of 2 when computing table size. + + +*Default value is "9 (512)".* + + +```opensips title="Set hash_size parameter" +... +modparam("rls", "hash_size", 11) +... + +``` + + +#### xcap_root (str) + + +The address of the xcap server. + + +*Default value is "NULL".* + + +```opensips title="Set hash_size parameter" +... +modparam("rls", "xcap_root", "http://192.168.2.132/xcap-root:800") +... + +``` + + +#### to_presence_code (int) + + +The code to be returned by rls_handle_subscribe function +if the processed Subscribe is not a resource list Subscribe. +This code can be used in an architecture with presence and rls +servers collocated on the same machine, to call handle_subscribe +on the message causing this code. + + +*Default value is "0".* + + +```opensips title="Set to_presence_code parameter" +... +modparam("rls", "to_presence_code", 10) +... + +``` + + +#### rls_event (str) + + +The default event that RLS handles is presence. If some other +events should also be handled by RLS they should be added using +this parameter. It can be set more than once. + + +*Default value is ""presence"".* + + +```opensips title="Set rls_event parameter" +... +modparam("rls", "rls_event", "dialog;sla") +... + +``` + + +#### presence_server (str) + + +The address of the presence server. It will be used as outbound proxy for +Subscribe requests sent by the RLS server to bouncing on and off the +proxy and having to include special processing for this messages +in the proxy's configuration file. + + +```opensips title="Set presence_server parameter" +... +modparam("rls", "presence_server", "sip:pres@opensips.org:5060") +... + +``` + + +#### contact_user (str) + + +This is the username that will be used in the Contact header for the 200 OK +replies to SUBSCRIBE and in the following in-dialog NOTIFY requests, as well +as for the SUBSCRIBE requests that are generated by the RLS server. +The IP address, port and transport for the Contact will be automatically +determined based on the interface where the SUBSCRIBE was received or sent +from. + + +If set to an empty string, no username will be added to the contact and +the contact will be built just out of the IP, port and transport. + + +*Default value is "rls".* + + +```opensips title="Set contact_user parameter" +... +modparam("rls", "contact_user", "rls") +... + +``` + + +### Exported Functions + + +#### rls_handle_subscribe() + + +This function detects if a Subscribe message should be +handled by RLS. If not it replies with the configured +to_presence_code. If it is, it extracts the dialog info and sends +aggregate Notify requests with information for the list. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="rls_handle_subscribe usage" +... +For presence and rls on the same machine: + modparam(rls, "to_presence_code", 10) + + if(is_method("SUBSCRIBE")) + { + $var(ret_code)= rls_handle_subscribe(); + + if($var(ret_code)== 10) + handle_subscribe(); + + t_release(); + } + +For rls only: + if(is_method("SUBSCRIBE")) + { + rls_handle_subscribe(); + t_release(); + } + +... +``` + + +#### rls_handle_notify() + + +This function has to be called for Notify messages sent by presence +servers in reply to the Subscribe messages sent by RLS. + + +This function can be used from REQUEST_ROUTE. + + +It can return 3 codes: + + +- *1* - the Notify was inside a dialog that was +recognized by the RLS server and was processed successfully. +- *2* - the Notify did not belog to a dialog initiated +by the RLS server. +- *-1* - an error occurred during processing. + + +```opensips title="rls_handle_notify usage" +... +if($rm=="NOTIFY") + rls_handle_notify(); +... +``` + + +### Exported MI Functions + + +#### rls_update_subscriptions + + +Triggers updating backend subscriptions after a resources-list or rls-services document +has been updated. + + +Name: *rls_update_subscriptions* + + +Parameters: + + +- presentity_uri : the uri of the user who made the change +and whose subscriptions should be updated + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi rls_update_subscriptions sip:alice@atlanta.com + +``` + + +### Installation + + +The module requires 2 table in OpenSIPS database: rls_presentity +and rls_watchers.The SQL syntax to create them can be found in +rls-create.sql script in the database directories in +the opensips/scripts folder. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +## Developer Guide + + +The module provides no functions to be used in other OpenSIPS modules. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rls/doc/contributors.xml b/modules/rls/doc/contributors.xml deleted file mode 100644 index 77dbdfbbe8b..00000000000 --- a/modules/rls/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 101 - 41 - 5335 - 863 - - - 2. - Saúl Ibarra Corretgé (@saghul) - 40 - 18 - 1150 - 710 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 25 - 21 - 110 - 137 - - - 4. - Dan Pascu (@danpascu) - 15 - 10 - 127 - 138 - - - 5. - Razvan Crainea (@razvancrainea) - 14 - 12 - 20 - 38 - - - 6. - Liviu Chircu (@liviuchircu) - 14 - 11 - 58 - 79 - - - 7. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 18 - 15 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 7 - 5 - 28 - 35 - - - 9. - Henning Westerholt (@henningw) - 7 - 3 - 164 - 114 - - - 10. - Vlad Paiu (@vladpaiu) - 5 - 3 - 11 - 41 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Maksym Sobolyev (@sobomax), Stanislaw Pitucha, Ovidiu Sas (@ovidiusas), Sergio Gutierrez, Konstantin Bokarius, UnixDev, John Riordan, Julián Moreno Patiño, Ken Rice, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2020 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2008 - Mar 2020 - - - 6. - Dan Pascu (@danpascu) - Aug 2008 - Jul 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 8. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 9. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 10. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - -
-All remaining contributors: Saúl Ibarra Corretgé (@saghul), Vlad Paiu (@vladpaiu), Anca Vamanu, Stanislaw Pitucha, Walter Doekes (@wdoekes), John Riordan, UnixDev, Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Dan Pascu (@danpascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Walter Doekes (@wdoekes), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/rls/doc/rls.xml b/modules/rls/doc/rls.xml deleted file mode 100644 index eeafe4fc34f..00000000000 --- a/modules/rls/doc/rls.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - Resource List Server - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - - - diff --git a/modules/rls/doc/rls_admin.xml b/modules/rls/doc/rls_admin.xml deleted file mode 100644 index 01f895c6bb1..00000000000 --- a/modules/rls/doc/rls_admin.xml +++ /dev/null @@ -1,463 +0,0 @@ - - - - - &adminguide; - -
- Overview - The modules is a Resource List Server implementation following the - specification in RFC 4662 and RFC 4826. - - - The server is independent from local presence servers, retrieving presence - information with Subscribe-Notify messages. - - - The module uses the presence module as a library, as it requires a resembling - mechanism for handling Subscribe. Therefore, in case the local presence server - is not collocated on the same machine with the RL server, the presence module - should be loaded in a library mode only (see doc for presence module). - - - - It handles subscription to lists in an event independent way.The default event - is presence, but if some other events are to be handled by the server, they - should be added using the module parameter "rls_events". - - - It works with XCAP server for storage. There is also the possibility to - configure it to work in an integrated_xcap server mode, when it only - queries database for the resource lists documents. This is useful in a - small architecture when all the clients use an integrated server and there - are no references to exterior documents in their lists. - - - The same as presence module, it has a caching mode with periodical update - in database for subscribe information. The information retrieved with Notify - messages is stored in database only. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module. - - - - - signaling. - - - - - tm. - - - - - presence- in a library mode. - - - - - pua. - - - - - xcap. - - - - -
- -
- External Libraries or Applications - - - - libxml-dev. - - - - -
-
- -
- Exported Parameters -
- <varname>rlsubs_table</varname>(str) - - The name of the db table where resource lists subscription - information is stored. - - - Default value is rls_watchers. - - - - Set <varname>rlsubs_table</varname> parameter - -... -modparam("rls", "rlsubs_table", "rls_subscriptions") -... - - -
- -
- <varname>rlpres_table</varname>(str) - - The name of the db table where notified event specific - information is stored. - - - Default value is rls_presentity. - - - - Set <varname>rlpres_table</varname> parameter - -... -modparam("rls", "rlpres_table", "rls_notify") -... - - -
- -
- <varname>clean_period</varname> (int) - - The period at which to check for expired information. - - - Default value is 100. - - - - Set <varname>clean_period</varname> parameter - -... -modparam("rls", "clean_period", 100) -... - - -
- -
- <varname>waitn_time</varname> (int) - - The timer period at which the server should attempt to send - Notifies with the updated presence state of the subscribed list - or watcher information. - - - Default value is 50. - - - - Set <varname>waitn_time</varname> parameter - -... -modparam("rls", "waitn_time", 10) -... - - -
- -
- <varname>max_expires</varname> (int) - - The maximum accepted expires for a subscription to a list. - - - Default value is 7200. - - - - Set <varname>max_expires</varname> parameter - -... -modparam("rls", "max_expires", 10800) -... - - -
- -
- <varname>hash_size</varname> (int) - - The dimension of the hash table used to store subscription to a list. - This parameter will be used as the power of 2 when computing table size. - - - Default value is 9 (512). - - - - Set <varname>hash_size</varname> parameter - -... -modparam("rls", "hash_size", 11) -... - - -
- -
- <varname>xcap_root</varname> (str) - - The address of the xcap server. - - - Default value is NULL. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("rls", "xcap_root", "http://192.168.2.132/xcap-root:800") -... - - -
- -
- <varname>to_presence_code</varname> (int) - - The code to be returned by rls_handle_subscribe function - if the processed Subscribe is not a resource list Subscribe. - This code can be used in an architecture with presence and rls - servers collocated on the same machine, to call handle_subscribe - on the message causing this code. - - - Default value is 0. - - - - Set <varname>to_presence_code</varname> parameter - -... -modparam("rls", "to_presence_code", 10) -... - - -
- -
- <varname>rls_event</varname> (str) - - The default event that RLS handles is presence. If some other - events should also be handled by RLS they should be added using - this parameter. It can be set more than once. - - - Default value is "presence". - - - - Set <varname>rls_event</varname> parameter - -... -modparam("rls", "rls_event", "dialog;sla") -... - - -
- -
- <varname>presence_server</varname> (str) - - The address of the presence server. It will be used as outbound proxy for - Subscribe requests sent by the RLS server to bouncing on and off the - proxy and having to include special processing for this messages - in the proxy's configuration file. - - - Set <varname>presence_server</varname> parameter - -... -modparam("rls", "presence_server", "sip:pres@opensips.org:5060") -... - - -
- -
- <varname>contact_user</varname> (str) - - This is the username that will be used in the Contact header for the 200 OK - replies to SUBSCRIBE and in the following in-dialog NOTIFY requests, as well - as for the SUBSCRIBE requests that are generated by the RLS server. - The IP address, port and transport for the Contact will be automatically - determined based on the interface where the SUBSCRIBE was received or sent - from. - - - If set to an empty string, no username will be added to the contact and - the contact will be built just out of the IP, port and transport. - - - Default value is rls. - - - - Set <varname>contact_user</varname> parameter - -... -modparam("rls", "contact_user", "rls") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">rls_handle_subscribe()</function> - - - This function detects if a Subscribe message should be - handled by RLS. If not it replies with the configured - to_presence_code. If it is, it extracts the dialog info and sends - aggregate Notify requests with information for the list. - - - This function can be used from REQUEST_ROUTE. - - - <function>rls_handle_subscribe</function> usage - -... -For presence and rls on the same machine: - modparam(rls, "to_presence_code", 10) - - if(is_method("SUBSCRIBE")) - { - $var(ret_code)= rls_handle_subscribe(); - - if($var(ret_code)== 10) - handle_subscribe(); - - t_release(); - } - -For rls only: - if(is_method("SUBSCRIBE")) - { - rls_handle_subscribe(); - t_release(); - } - -... - - -
- -
- - <function moreinfo="none">rls_handle_notify()</function> - - - This function has to be called for Notify messages sent by presence - servers in reply to the Subscribe messages sent by RLS. - - - This function can be used from REQUEST_ROUTE. - - - It can return 3 codes: - - - - 1 - the Notify was inside a dialog that was - recognized by the RLS server and was processed successfully. - - - - - 2 - the Notify did not belog to a dialog initiated - by the RLS server. - - - - - -1 - an error occurred during processing. - - - - - - - - <function>rls_handle_notify</function> usage - -... -if($rm=="NOTIFY") - rls_handle_notify(); -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">rls_update_subscriptions</function> - - - Triggers updating backend subscriptions after a resources-list or rls-services document - has been updated. - - - Name: rls_update_subscriptions - - Parameters: - - - presentity_uri : the uri of the user who made the change - and whose subscriptions should be updated - - - - - MI FIFO Command Format: - - -opensips-cli -x mi rls_update_subscriptions sip:alice@atlanta.com - -
- -
- -
- Installation - - The module requires 2 table in OpenSIPS database: rls_presentity - and rls_watchers.The SQL syntax to create them can be found in - rls-create.sql script in the database directories in - the opensips/scripts folder. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- -
- diff --git a/modules/rls/doc/rls_devel.xml b/modules/rls/doc/rls_devel.xml deleted file mode 100644 index 7c7350ee45f..00000000000 --- a/modules/rls/doc/rls_devel.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - &develguide; - - The module provides no functions to be used in other &osips; modules. - - - diff --git a/modules/rr/README b/modules/rr/README deleted file mode 100644 index d7f09125451..00000000000 --- a/modules/rr/README +++ /dev/null @@ -1,617 +0,0 @@ -rr Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dialog support - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. append_fromtag (integer) - 1.4.2. enable_double_rr (integer) - 1.4.3. add_username (integer) - 1.4.4. enable_socket_mismatch_warning (integer) - - 1.5. Exported Functions - - 1.5.1. loose_route() - 1.5.2. record_route() and record_route(string) - 1.5.3. record_route_preset(string [, string2]) - 1.5.4. add_rr_param(param) - 1.5.5. check_route_param(re) - 1.5.6. is_direction(dir) - 1.5.7. Exported Pseudo-Variables - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. add_rr_param( msg, param) - 2.1.2. check_route_param( msg, re) - 2.1.3. is_direction( msg, dir) - 2.1.4. get_route_param( msg, name, val) - 2.1.5. register_rrcb( callback, param, prior) - - 2.2. Examples - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Dialog support in RR module - 1.2. Set append_fromtag parameter - 1.3. Set enable_double_rr parameter - 1.4. Set add_username parameter - 1.5. enable_socket_mismatch_warning usage - 1.6. loose_route usage - 1.7. record_route usage - 1.8. record_route_preset usage - 1.9. add_rr_param usage - 1.10. check_route_param usage - 1.11. is_direction usage - 2.1. Loading RR module's API from another module - -Chapter 1. Admin Guide - -1.1. Overview - - The module contains record routing logic - -1.2. Dialog support - - OpenSIPS is basically only a transaction statefull proxy, - without any dialog support build in. There are many - features/services which actually require dialog awareness, like - storing the information in the dialog creation stage, - information which will be used during the whole dialog - existence. - - The most urging example is NAT traversal, in dealing with the - within the dialog INVITEs (re-INVITEs). When processing the - initial INVITE, the proxy detects if the caller or callee is - behind some NAT and fixes the signalling and media parts - - since not all the detection mechanism are available for within - the dialog requests (like usrloc), to be able to fix - correspondingly the sequential requests, the proxy must - remember that the original request was NAT processed. There are - many other cases where dialog awareness fixes or helps. - - The solution is to store additional dialog-related information - in the routing set (Record-Route/Route headers), headers which - show up in all sequential requests. So any information added to - the Record-Route header will be found (with no direction - dependencies) in Route header (corresponding to the proxy - address). - - As storage container, the parameters of the Record-Route / - Route header will be used - Record-Route parameters mirroring - are reinforced by RFC 3261 (see 12.1.1 UAS behavior). - - For this purpose, the modules offers the following functions: - * add_rr_param() - see add_rr_param() - * check_route_param() - see check_route_param() - - Example 1.1. Dialog support in RR module - -UAC OpenSIPS PROXY UAS - ----- INVITE ------> record_route() ----- INVITE ----> - add_rr_param(";foo=true") - ---- reINVITE -----> loose_route() ---- reINVITE ---> - check_route_param(";foo=true") - -<-- reINVITE ------ loose_route() <--- reINVITE ---- - check_route_param(";foo=true") - -<------ BYE ------- loose_route() <----- BYE ------- - check_route_param(";foo=true") - - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. append_fromtag (integer) - - If turned on, request's from-tag is appended to record-route; - that's useful for understanding whether subsequent requests - (such as BYE) come from caller (route's from-tag==BYE's - from-tag) or callee (route's from-tag==BYE's to-tag) - - Default value is 1 (yes). - - Example 1.2. Set append_fromtag parameter -... -modparam("rr", "append_fromtag", 0) -... - -1.4.2. enable_double_rr (integer) - - There are some situations when the server needs to insert two - Record-Route header fields instead of one. For example when - using two disconnected networks or doing cross-protocol - forwarding from UDP->TCP. This parameter enables inserting of 2 - Record-Routes. The server will later remove both of them. - - Default value is 1 (yes). - - Example 1.3. Set enable_double_rr parameter -... -modparam("rr", "enable_double_rr", 0) -... - -1.4.3. add_username (integer) - - If set to a non 0 value (which means yes), the username part - will be also added in the Record-Route URI. - - Default value is 0 (no). - - Example 1.4. Set add_username parameter -... -modparam("rr", "add_username", 1) -... - -1.4.4. enable_socket_mismatch_warning (integer) - - When a preset record-route header is forced in OpenSIPS config - and the host from the record-route header is not the same as - the host server, a warning will be printed out in the logs. The - 'enable_socket_mismatch_warning' parameter enables or disables - the warning. When OpenSIPS is behind a NATed firewall, we don't - want this warning to be printed for every bridged call. - - Default value is 1 (yes). - - Example 1.5. enable_socket_mismatch_warning usage -... -modparam("rr", "enable_socket_mismatch_warning", 0) -... - -1.5. Exported Functions - -1.5.1. loose_route() - - The function performs routing of SIP requests which contain a - route set. The name is a little bit confusing, as this function - also routes requests which are in the “strict router” format. - - This function is usually used to route in-dialog requests (like - ACK, BYE, reINVITE). Nevertheless also out-of-dialog requests - can have a “pre-loaded route set” and my be routed with - loose_route. It also takes care of translating between - strict-routers and loose-router. - - The loose_route() function analyzes the Route headers in the - requests. If there is no Route header, the function returns - FALSE and routing should be done exclusivly via RURI. If a - Route header is found, the function returns TRUE and behaves as - described in section 16.12 of RFC 3261. The only exception is - for requests with preload Route headers (intial requests, - carrying a Route header): if there is only one Route header - indicating the local proxy, then the Route header is removed - and the function returns FALSE. - - The function is able to automatically detecting if it deals - with a 'strict' or 'loose' routing scenario (the difference is - how the SIP path is stored across the RURI and Route hdrs). To - make the difference between the two scenarios OpenSIPS has to - determine which SIP URI holds its address/domain - the RURI - (then it is a strict routing scenario) or the top Route URI - (then it is a loose route scenario). In order to check if the - SIP URI holds its address/domain, OpenSIPS checks the host URI - against the listening IPs/interfaces (as a static component) - and the domains listed from the "domain" module/table (as the - dynamic component). - - If there is a Route header but other parsing errors occur ( - like parsing the TO header to get the TAG ), the function also - returns FALSE. - - Make sure your loose_routing function can't be used by - attackers to bypass proxy authorization. - - The loose_routing topic is very complex. See the RFC3261 for - more details (grep for “route set” is a good starting point in - this comprehensive RFC). - - This function can be used from REQUEST_ROUTE. - - Example 1.6. loose_route usage -... -loose_route(); -... - -1.5.2. record_route() and record_route(string) - - The function adds a new Record-Route header field. The header - field will be inserted in the message before any other - Record-Route header fields. - - If any string is passed as parameter, it will be appended as - URI parameter to the Record-Route header. The string must - follow the “;name=value” scheme. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.7. record_route usage -... -record_route(); -... - -1.5.3. record_route_preset(string [, string2]) - - This function will put the string into Record-Route, don't use - unless you know what you are doing. - - Meaning of the parameters is as follows: - * string - String to be inserted into the first header field; - it may contain pseudo-variables. - * string2 (optional) - String to be inserted into the second - header field. - - Note: If 'string2' is present, then the 'string' param is - pointing to the outbound interface and the 'string2' param is - pointing to the inbound interface. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.8. record_route_preset usage -... -record_route_preset("1.2.3.4:5090"); -... - -1.5.4. add_rr_param(param) - - Adds a parameter to the Record-Route URI (param must be in - “;name=value” format. The function may be called also before or - after the record_route() call (see record_route()). - - Meaning of the parameters is as follows: - * param (string) - the URI parameter to be added. It must - follow the “;name=value” scheme. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.9. add_rr_param usage -... -add_rr_param(";nat=yes"); -... - -1.5.5. check_route_param(re) - - The function checks if the URI parameters of the local Route - header (corresponding to the local server) matches the given - regular expression. It must be call after loose_route() (see - loose_route()). - - Meaning of the parameters is as follows: - * re (string) - regular expression to check against the Route - URI parameters. - - This function can be used from REQUEST_ROUTE. - - Example 1.10. check_route_param usage -... -if (check_route_param("nat=yes")) { - setflag(6); -} -... - -1.5.6. is_direction(dir) - - The function checks the flow direction of the request. As for - checking it's used the “ftag” Route header parameter, the - append_fromtag (see append_fromtag module parameter must be - enabled. Also this must be called only after loose_route() (see - loose_route()). - - The function returns true if the “dir” is the same with the - request's flow direction. - - The “downstream” (UAC to UAS) direction is relative to the - initial request that created the dialog. - - Meaning of the parameters is as follows: - * dir (string) - the direction to be checked. It may be - “upstream” (from UAS to UAC) or “downstream” (UAC to UAS). - - This function can be used from REQUEST_ROUTE. - - Example 1.11. is_direction usage -... -if (is_direction("upstream")) { - xdbg("upstream request ($rm)\n"); -} -... - -1.5.7. Exported Pseudo-Variables - - Exported pseudo-variables are listed in the next sections. - -1.5.7.1. $rr_params - - $rr_params - the whole string of the Route parameters - this is - available only after calling loose_route() - -Chapter 2. Developer Guide - - The RR module provides an internal API to be used by other - OpenSIPS modules. The API offers support for SIP dialog based - functionalities - for more about the dialog support offered by - RR module, see Section 1.2, “Dialog support”. - - For internal(non-script) usage, the RR module offers to other - module the possibility to register callback functions to be - executed each time a local Route header is processed. The - callback function will receive as parameter the register - parameter and the Route header parameter string. - -2.1. Available Functions - -2.1.1. add_rr_param( msg, param) - - Adds a parameter to the requests's Record-Route URI (param must - be in “;name=value” format). - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - * struct sip_msg* msg - request that will has the parameter - “param” added to its Record-Route header. - * str* param - parameter to be added to the Record-Route - header - it must be in “;name=value” format. - -2.1.2. check_route_param( msg, re) - - The function checks for the request “msg” if the URI parameters - of the local Route header (corresponding to the local server) - matches the given regular expression “re”. It must be call - after the loose_route was done. - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - * struct sip_msg* msg - request that will has the Route - header parameters checked. - * regex_t* param - compiled regular expression to be checked - against the Route header parameters. - -2.1.3. is_direction( msg, dir) - - The function checks the flow direction of the request “msg”. As - for checking it's used the “ftag” Route header parameter, the - append_fromtag (see append_fromtag module parameter must be - enables. Also this must be call only after the loose_route is - done. - - The function returns 0 if the “dir” is the same with the - request's flow direction. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - * struct sip_msg* msg - request that will have the direction - checked. - * int dir - direction to be checked against. It may be - “RR_FLOW_UPSTREAM” or “RR_FLOW_DOWNSTREAM”. - -2.1.4. get_route_param( msg, name, val) - - The function search in to the “msg”'s Route header parameters - the parameter called “name” and returns its value into “val”. - It must be call only after the loose_route is done. - - The function returns 0 if parameter was found (even if it has - no value). Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - * struct sip_msg* msg - request that will have the Route - header parameter searched. - * str *name - contains the Route header parameter to be - serached. - * str *val - returns the value of the searched Route header - parameter if found. It might be empty string if the - parameter had no value. - -2.1.5. register_rrcb( callback, param, prior) - - The function register a new callback (along with its - parameter). The callback will be called when a loose route will - be performed for the local address. - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - * rr_cb_t callback - callback function to be registered. - * void *param - parameter to be passed to the callback - function. - * short prior - parameter to set the priority. If the - callback depends on another module, this parameter should - be greater than that module's priority. Otherwise, it - should be 0. - -2.2. Examples - - Example 2.1. Loading RR module's API from another module -... -#include "../rr/api.h" -... -struct rr_binds my_rrb; -... -... -/* load the RR API */ -if (load_rr_api( &my_rrb )!=0) { - LM_ERR("can't load RR API\n"); - goto error; -} -... -... -/* register a RR callback */ -if (my_rrb.register_rrcb(my_callback,0,0))!=0) { - LM_ERR("can't register RR callback\n"); - goto error; -} -... - -Chapter 3. Frequently Asked Questions - - 3.1. - - What happened with old enable_full_lr parameter - - The parameter is considered obsolete. It was only introduced to - allow compatibility with older SIP entities, that complained - about a lr parameter without a value. This behavior breaks RFC - 3261, and since nowadays most SIP stacks are fixed to conform - with the RFC, the parameter was removed. - - 3.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 3.3. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 3.4. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jan Janak (@janakj) 142 59 4374 2763 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 96 65 1915 843 - 3. Liviu Chircu (@liviuchircu) 19 16 72 105 - 4. Daniel-Constantin Mierla (@miconda) 19 14 244 92 - 5. Vlad Paiu (@vladpaiu) 15 10 333 88 - 6. Jiri Kuthan (@jiriatipteldotorg) 15 10 250 64 - 7. Razvan Crainea (@razvancrainea) 14 12 83 47 - 8. Andrei Pelinescu-Onciul 12 9 61 92 - 9. Anca Vamanu 9 3 191 206 - 10. Henning Westerholt (@henningw) 7 4 115 73 - - All remaining contributors: Vlad Patrascu (@rvlad-patrascu), - Maksym Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Dan Pascu - (@danpascu), Konstantin Bokarius, Saúl Ibarra Corretgé - (@saghul), Jesus Rodrigues, Julián Moreno Patiño, Norman - Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert - Schubert, Elena-Ramona Modroiu. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Oct 2013 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Jan 2002 - Nov 2022 - 4. Razvan Crainea (@razvancrainea) Aug 2010 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Julián Moreno Patiño Feb 2016 - Feb 2016 - 8. Ovidiu Sas (@ovidiusas) Oct 2010 - Jan 2015 - 9. Norman Brandinger (@NormB) Sep 2014 - Sep 2014 - 10. Saúl Ibarra Corretgé (@saghul) Mar 2012 - Mar 2012 - - All remaining contributors: Vlad Paiu (@vladpaiu), Anca Vamanu, - Dan Pascu (@danpascu), Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu, Jan - Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan - (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Vlad - Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Dan Pascu - (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan - Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2003 FhG FOKUS diff --git a/modules/rr/README.md b/modules/rr/README.md new file mode 100644 index 00000000000..d4eb7c2c8f3 --- /dev/null +++ b/modules/rr/README.md @@ -0,0 +1,603 @@ +--- +title: "rr Module" +description: "The module contains record routing logic" +--- + +## Admin Guide + + +### Overview + + +The module contains record routing logic + + +### Dialog support + + +OpenSIPS is basically *only* a transaction statefull +proxy, without any dialog support build in. There are many features/services +which actually require dialog awareness, like storing the information in +the dialog creation stage, information which will be used during the whole +dialog existence. + + +The most urging example is NAT traversal, in dealing with the within the +dialog INVITEs (re-INVITEs). When processing the initial INVITE, the proxy +detects if the caller or callee is behind some NAT and fixes the signalling +and media parts - since not all the detection mechanism are available for +within the dialog requests (like usrloc), to be able to fix correspondingly +the sequential requests, the proxy must remember that the original request +was NAT processed. There are many other cases where dialog awareness fixes +or helps. + + +The solution is to store additional dialog-related information in the +routing set (Record-Route/Route headers), headers which show up in all +sequential requests. So any information added to the Record-Route header +will be found (with no direction dependencies) in Route header +(corresponding to the proxy address). + + +As storage container, the parameters of the Record-Route / Route header +will be used - Record-Route parameters mirroring are reinforced by +RFC 3261 (see 12.1.1 UAS behavior). + + +For this purpose, the modules offers the following functions: + + +- add_rr_param() - see [add rr param](#func_add_rr_param) +- check_route_param() - see +[check route param](#func_check_route_param) + + +```c title="Dialog support in RR module" + +UAC OpenSIPS PROXY UAS + +---- INVITE ------> record_route() ----- INVITE ----> + add_rr_param(";foo=true") + +--- reINVITE -----> loose_route() ---- reINVITE ---> + check_route_param(";foo=true") + +<-- reINVITE ------ loose_route() <--- reINVITE ---- + check_route_param(";foo=true") + +<------ BYE ------- loose_route() <----- BYE ------- + check_route_param(";foo=true") + +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### append_fromtag (integer) + + +If turned on, request's from-tag is appended to record-route; that's +useful for understanding whether subsequent requests (such as BYE) come +from caller (route's from-tag==BYE's from-tag) or callee +(route's from-tag==BYE's to-tag) + + +*Default value is 1 (yes).* + + +```opensips title="Set append_fromtag parameter" +... +modparam("rr", "append_fromtag", 0) +... +``` + + +#### enable_double_rr (integer) + + +There are some situations when the server needs to insert two +Record-Route header fields instead of one. For example when using +two disconnected networks or doing cross-protocol forwarding from +UDP->TCP. This parameter enables inserting of 2 +Record-Routes. The server will later remove both of them. + + +*Default value is 1 (yes).* + + +```opensips title="Set enable_double_rr parameter" +... +modparam("rr", "enable_double_rr", 0) +... +``` + + +#### add_username (integer) + + +If set to a non 0 value (which means yes), the username part will +be also added in the Record-Route URI. + + +*Default value is 0 (no).* + + +```opensips title="Set add_username parameter" +... +modparam("rr", "add_username", 1) +... +``` + + +#### enable_socket_mismatch_warning (integer) + + +When a preset record-route header is forced in OpenSIPS config and the +host from the record-route header is not the same as the host server, +a warning will be printed out in the logs. +The 'enable_socket_mismatch_warning' parameter enables or disables the warning. +When OpenSIPS is behind a NATed firewall, we don't want this warning +to be printed for every bridged call. + + +*Default value is 1 (yes).* + + +```opensips title="enable_socket_mismatch_warning usage" +... +modparam("rr", "enable_socket_mismatch_warning", 0) +... +``` + + +### Exported Functions + + +#### loose_route() + + +The function performs routing of SIP requests which contain a route +set. The name is a little bit confusing, as this function also routes +requests which are in the "strict router" format. + + +This function is usually used to route in-dialog requests (like ACK, +BYE, reINVITE). Nevertheless also out-of-dialog requests can have a +"pre-loaded route set" and my be routed with loose_route. +It also takes care of translating between strict-routers and +loose-router. + + +The loose_route() function analyzes the Route headers in the requests. +If there is no Route header, the function returns FALSE and routing +should be done exclusivly via RURI. If a Route header is +found, the function returns TRUE and behaves as described in section +16.12 of RFC 3261. The only exception is for requests with preload +Route headers (intial requests, carrying a Route header): if there is +only one Route header indicating the local proxy, then the Route +header is removed and the function returns FALSE. + + +The function is able to automatically detecting if it deals with a +'strict' or 'loose' routing scenario (the difference is how the SIP +path is stored across the RURI and Route hdrs). To make the difference +between the two scenarios OpenSIPS has to determine which SIP URI +holds its address/domain - the RURI (then it is a strict routing +scenario) or the top Route URI (then it is a loose route scenario). +In order to check if the SIP URI holds its address/domain, OpenSIPS +checks the host URI against the listening IPs/interfaces (as a static +component) and the domains listed from the "domain" module/table (as +the dynamic component). + + +If there is a Route header but other parsing errors occur ( like +parsing the TO header to get the TAG ), the function also returns +FALSE. + + +Make sure your loose_routing function can't be used by attackers to +bypass proxy authorization. + + +The loose_routing topic is very complex. See the RFC3261 for more +details (grep for "route set" is a good starting point in +this comprehensive RFC). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="loose_route usage" +... +loose_route(); +... +``` + + +#### record_route() and record_route(string) + + +The function adds a new Record-Route header field. The header field +will be inserted in the message before any other Record-Route header +fields. + + +If any string is passed as parameter, it will be appended as URI +parameter to the Record-Route header. The string must follow the +";name=value" scheme. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="record_route usage" +... +record_route(); +... +``` + + +#### record_route_preset(string [, string2]) + + +This function will put the string into Record-Route, don't use +unless you know what you are doing. + + +Meaning of the parameters is as follows: + + +- *string* - String to be inserted into the +first header field; it may contain pseudo-variables. +- *string2* (optional) - String to be inserted into the +second header field. + + +> [!NOTE] +> If 'string2' is present, then the 'string' param is pointing to the +> outbound interface and the 'string2' param is pointing to the inbound interface. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="record_route_preset usage" +... +record_route_preset("1.2.3.4:5090"); +... +``` + + +#### add_rr_param(param) + + +Adds a parameter to the Record-Route URI (param must be in +";name=value" format. The function may be called also +before or after the record_route() call +(see [record route](#func_record_route)). + + +Meaning of the parameters is as follows: + + +- *param* (string) - the URI parameter to +be added. It must follow the ";name=value" scheme. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="add_rr_param usage" +... +add_rr_param(";nat=yes"); +... +``` + + +#### check_route_param(re) + + +The function checks if the URI parameters of the local Route +header (corresponding to the local server) matches the given regular +expression. It must be call after loose_route() +(see [loose route](#func_loose_route)). + + +Meaning of the parameters is as follows: + + +- *re* (string) - regular expression to check against the +Route URI parameters. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="check_route_param usage" +... +if (check_route_param("nat=yes")) { + setflag(6); +} +... +``` + + +#### is_direction(dir) + + +The function checks the flow direction of the request. +As for checking it's used the "ftag" Route header +parameter, the append_fromtag (see [append fromtag](#param_append_fromtag) +module parameter must be enabled. Also this must be called only after +loose_route() (see [loose route](#func_loose_route)). + + +The function returns true if the "dir" is the same with +the request's flow direction. + + +The "downstream" (UAC to UAS) direction is relative to the +initial request that created the dialog. + + +Meaning of the parameters is as follows: + + +- *dir* (string) - the direction to be +checked. It may be "upstream" (from UAS to UAC) or +"downstream" (UAC to UAS). + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="is_direction usage" +... +if (is_direction("upstream")) { + xdbg("upstream request ($rm)\n"); +} +... +``` + + +#### Exported Pseudo-Variables + + +Exported pseudo-variables are listed in the next sections. + + +##### $rr_params + + +*$rr_params* - the whole string of the Route +parameters - this is available only after calling loose_route() + + +## Developer Guide + + +The RR module provides an internal API to be used by +other OpenSIPS modules. The API offers support for +SIP dialog based functionalities - for more about the dialog support +offered by RR module, see [RR dialog id](#dialog_support). + + +For internal(non-script) usage, the RR module offers to other module the +possibility to register callback functions to be executed each time a +local Route header is processed. The callback function will receive as +parameter the register parameter and the Route header parameter string. + + +### Available Functions + + +#### add_rr_param( msg, param) + + +Adds a parameter to the requests's Record-Route URI (param must be in +";name=value" format). + + +The function returns 0 on success. Otherwise, -1 is returned. + + +Meaning of the parameters is as follows: + + +- *struct sip_msg* msg* - request that +will has the parameter "param" added to its +Record-Route header. +- *str* param* - parameter to be added +to the Record-Route header - it must be in +";name=value" format. + + +#### check_route_param( msg, re) + + +The function checks for the request "msg" if the URI +parameters of the local Route header (corresponding to the local +server) matches the given regular expression "re". +It must be call after the loose_route was done. + + +The function returns 0 on success. Otherwise, -1 is returned. + + +Meaning of the parameters is as follows: + + +- *struct sip_msg* msg* - request that +will has the Route header parameters checked. +- *regex_t* param* - compiled regular +expression to be checked against the Route header parameters. + + +#### is_direction( msg, dir) + + +The function checks the flow direction of the request +"msg". As for checking it's used the "ftag" +Route header parameter, the append_fromtag (see +[append fromtag](#param_append_fromtag) module parameter +must be enables. Also this must be call only after the loose_route is +done. + + +The function returns 0 if the "dir" is the same with +the request's flow direction. Otherwise, -1 is returned. + + +Meaning of the parameters is as follows: + + +- *struct sip_msg* msg* - request that +will have the direction checked. +- *int dir* - direction to be checked +against. It may be "RR_FLOW_UPSTREAM" or +"RR_FLOW_DOWNSTREAM". + + +#### get_route_param( msg, name, val) + + +The function search in to the "msg"'s Route header +parameters the parameter called "name" and returns its +value into "val". It must be call only after the +loose_route is done. + + +The function returns 0 if parameter was found (even if it has no value). +Otherwise, -1 is returned. + + +Meaning of the parameters is as follows: + + +- *struct sip_msg* msg* - request that +will have the Route header parameter searched. +- *str *name* - contains the Route header +parameter to be serached. +- *str *val* - returns the value of the +searched Route header parameter if found. It might be empty +string if the parameter had no value. + + +#### register_rrcb( callback, param, prior) + + +The function register a new callback (along with its parameter). The +callback will be called when a loose route will be performed for the +local address. + + +The function returns 0 on success. Otherwise, -1 is returned. + + +Meaning of the parameters is as follows: + + +- *rr_cb_t callback* - callback +function to be registered. +- *void *param* - parameter to be passed +to the callback function. +- *short prior* - parameter to set the priority. +If the callback depends on another module, this parameter should be greater +than that module's priority. Otherwise, it should be 0. + + +### Examples + + +```c title="Loading RR module's API from another module" +... +#include "../rr/api.h" +... +struct rr_binds my_rrb; +... +... +/* load the RR API */ +if (load_rr_api( &my_rrb )!=0) { + LM_ERR("can't load RR API\n"); + goto error; +} +... +... +/* register a RR callback */ +if (my_rrb.register_rrcb(my_callback,0,0))!=0) { + LM_ERR("can't register RR callback\n"); + goto error; +} +... +``` + + +## Frequently Asked Questions + + +**Q: What happened with old enable_full_lr parameter** + + +The parameter is considered obsolete. It was only introduced to +allow compatibility with older SIP entities, that complained +about a lr parameter without a value. +This behavior breaks RFC 3261, and since nowadays most SIP stacks +are fixed to conform with the RFC, the parameter was removed. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rr/doc/contributors.xml b/modules/rr/doc/contributors.xml deleted file mode 100644 index e2b77d587ad..00000000000 --- a/modules/rr/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jan Janak (@janakj) - 142 - 59 - 4374 - 2763 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 96 - 65 - 1915 - 843 - - - 3. - Liviu Chircu (@liviuchircu) - 19 - 16 - 72 - 105 - - - 4. - Daniel-Constantin Mierla (@miconda) - 19 - 14 - 244 - 92 - - - 5. - Vlad Paiu (@vladpaiu) - 15 - 10 - 333 - 88 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 15 - 10 - 250 - 64 - - - 7. - Razvan Crainea (@razvancrainea) - 14 - 12 - 83 - 47 - - - 8. - Andrei Pelinescu-Onciul - 12 - 9 - 61 - 92 - - - 9. - Anca Vamanu - 9 - 3 - 191 - 206 - - - 10. - Henning Westerholt (@henningw) - 7 - 4 - 115 - 73 - - - -
-All remaining contributors: Vlad Patrascu (@rvlad-patrascu), Maksym Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu), Konstantin Bokarius, Saúl Ibarra Corretgé (@saghul), Jesus Rodrigues, Julián Moreno Patiño, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Elena-Ramona Modroiu. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Oct 2013 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jan 2002 - Nov 2022 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2010 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 8. - Ovidiu Sas (@ovidiusas) - Oct 2010 - Jan 2015 - - - 9. - Norman Brandinger (@NormB) - Sep 2014 - Sep 2014 - - - 10. - Saúl Ibarra Corretgé (@saghul) - Mar 2012 - Mar 2012 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Anca Vamanu, Dan Pascu (@danpascu), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/rr/doc/rr.xml b/modules/rr/doc/rr.xml deleted file mode 100644 index 3baa5ab4ab9..00000000000 --- a/modules/rr/doc/rr.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - rr Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005 &voicesystem; - ©right; 2003 &fhg; - - diff --git a/modules/rr/doc/rr_admin.xml b/modules/rr/doc/rr_admin.xml deleted file mode 100644 index 885a4ff757d..00000000000 --- a/modules/rr/doc/rr_admin.xml +++ /dev/null @@ -1,472 +0,0 @@ - - - - - &adminguide; - -
- Overview - The module contains record routing logic -
- - -
- Dialog support - &osips; is basically only a transaction statefull - proxy, without any dialog support build in. There are many features/services - which actually require dialog awareness, like storing the information in - the dialog creation stage, information which will be used during the whole - dialog existence. - - - The most urging example is NAT traversal, in dealing with the within the - dialog INVITEs (re-INVITEs). When processing the initial INVITE, the proxy - detects if the caller or callee is behind some NAT and fixes the signalling - and media parts - since not all the detection mechanism are available for - within the dialog requests (like usrloc), to be able to fix correspondingly - the sequential requests, the proxy must remember that the original request - was NAT processed. There are many other cases where dialog awareness fixes - or helps. - - - The solution is to store additional dialog-related information in the - routing set (Record-Route/Route headers), headers which show up in all - sequential requests. So any information added to the Record-Route header - will be found (with no direction dependencies) in Route header - (corresponding to the proxy address). - - - As storage container, the parameters of the Record-Route / Route header - will be used - Record-Route parameters mirroring are reinforced by - RFC 3261 (see 12.1.1 UAS behavior). - - - For this purpose, the modules offers the following functions: - - - - add_rr_param() - see - - - - check_route_param() - see - - - - - - Dialog support in RR module - - -UAC OpenSIPS PROXY UAS - ----- INVITE ------> record_route() ----- INVITE ----> - add_rr_param(";foo=true") - ---- reINVITE -----> loose_route() ---- reINVITE ---> - check_route_param(";foo=true") - -<-- reINVITE ------ loose_route() <--- reINVITE ---- - check_route_param(";foo=true") - -<------ BYE ------- loose_route() <----- BYE ------- - check_route_param(";foo=true") - - - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Parameters -
- <varname>append_fromtag</varname> (integer) - - If turned on, request's from-tag is appended to record-route; that's - useful for understanding whether subsequent requests (such as BYE) come - from caller (route's from-tag==BYE's from-tag) or callee - (route's from-tag==BYE's to-tag) - - - - Default value is 1 (yes). - - - - Set <varname>append_fromtag</varname> parameter - -... -modparam("rr", "append_fromtag", 0) -... - - -
- -
- <varname>enable_double_rr</varname> (integer) - - There are some situations when the server needs to insert two - Record-Route header fields instead of one. For example when using - two disconnected networks or doing cross-protocol forwarding from - UDP->TCP. This parameter enables inserting of 2 - Record-Routes. The server will later remove both of them. - - - - Default value is 1 (yes). - - - - Set <varname>enable_double_rr</varname> parameter - -... -modparam("rr", "enable_double_rr", 0) -... - - -
- -
- <varname>add_username</varname> (integer) - - If set to a non 0 value (which means yes), the username part will - be also added in the Record-Route URI. - - - - Default value is 0 (no). - - - - Set <varname>add_username</varname> parameter - -... -modparam("rr", "add_username", 1) -... - - -
- -
- <varname>enable_socket_mismatch_warning</varname> (integer) - - When a preset record-route header is forced in &osips; config and the - host from the record-route header is not the same as the host server, - a warning will be printed out in the logs. - The 'enable_socket_mismatch_warning' parameter enables or disables the warning. - When &osips; is behind a NATed firewall, we don't want this warning - to be printed for every bridged call. - - - - Default value is 1 (yes). - - - - <varname>enable_socket_mismatch_warning</varname> usage - -... -modparam("rr", "enable_socket_mismatch_warning", 0) -... - - -
-
- - -
- Exported Functions -
- - <function moreinfo="none">loose_route()</function> - - - The function performs routing of SIP requests which contain a route - set. The name is a little bit confusing, as this function also routes - requests which are in the strict router format. - - - This function is usually used to route in-dialog requests (like ACK, - BYE, reINVITE). Nevertheless also out-of-dialog requests can have a - pre-loaded route set and my be routed with loose_route. - It also takes care of translating between strict-routers and - loose-router. - - - The loose_route() function analyzes the Route headers in the requests. - If there is no Route header, the function returns FALSE and routing - should be done exclusivly via RURI. If a Route header is - found, the function returns TRUE and behaves as described in section - 16.12 of RFC 3261. The only exception is for requests with preload - Route headers (intial requests, carrying a Route header): if there is - only one Route header indicating the local proxy, then the Route - header is removed and the function returns FALSE. - - - The function is able to automatically detecting if it deals with a - 'strict' or 'loose' routing scenario (the difference is how the SIP - path is stored across the RURI and Route hdrs). To make the difference - between the two scenarios OpenSIPS has to determine which SIP URI - holds its address/domain - the RURI (then it is a strict routing - scenario) or the top Route URI (then it is a loose route scenario). - In order to check if the SIP URI holds its address/domain, OpenSIPS - checks the host URI against the listening IPs/interfaces (as a static - component) and the domains listed from the "domain" module/table (as - the dynamic component). - - - If there is a Route header but other parsing errors occur ( like - parsing the TO header to get the TAG ), the function also returns - FALSE. - - - Make sure your loose_routing function can't be used by attackers to - bypass proxy authorization. - - - The loose_routing topic is very complex. See the RFC3261 for more - details (grep for route set is a good starting point in - this comprehensive RFC). - - - This function can be used from REQUEST_ROUTE. - - - <function>loose_route</function> usage - -... -loose_route(); -... - - -
- -
- - <function moreinfo="none">record_route()</function> and - <function moreinfo="none">record_route(string)</function> - - - The function adds a new Record-Route header field. The header field - will be inserted in the message before any other Record-Route header - fields. - - - If any string is passed as parameter, it will be appended as URI - parameter to the Record-Route header. The string must follow the - ;name=value scheme. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>record_route</function> usage - -... -record_route(); -... - - -
- -
- - <function moreinfo="none">record_route_preset(string [, string2])</function> - - - This function will put the string into Record-Route, don't use - unless you know what you are doing. - - Meaning of the parameters is as follows: - - - - string - String to be inserted into the - first header field; it may contain pseudo-variables. - - - - - string2 (optional) - String to be inserted into the - second header field. - - - - - Note: If 'string2' is present, then the 'string' param is pointing to the - outbound interface and the 'string2' param is pointing to the inbound interface. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>record_route_preset</function> usage - -... -record_route_preset("1.2.3.4:5090"); -... - - -
- -
- - <function moreinfo="none">add_rr_param(param)</function> - - - Adds a parameter to the Record-Route URI (param must be in - ;name=value format. The function may be called also - before or after the record_route() call - (see ). - - Meaning of the parameters is as follows: - - - - param (string) - the URI parameter to - be added. It must follow the ;name=value scheme. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>add_rr_param</function> usage - -... -add_rr_param(";nat=yes"); -... - - -
- -
- - <function moreinfo="none">check_route_param(re)</function> - - The function checks if the URI parameters of the local Route - header (corresponding to the local server) matches the given regular - expression. It must be call after loose_route() - (see ). - - Meaning of the parameters is as follows: - - - - re (string) - regular expression to check against the - Route URI parameters. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>check_route_param</function> usage - -... -if (check_route_param("nat=yes")) { - setflag(6); -} -... - - -
- -
- - <function moreinfo="none">is_direction(dir)</function> - - The function checks the flow direction of the request. - As for checking it's used the ftag Route header - parameter, the append_fromtag (see - module parameter must be enabled. Also this must be called only after - loose_route() (see ). - - - The function returns true if the dir is the same with - the request's flow direction. - - - The downstream (UAC to UAS) direction is relative to the - initial request that created the dialog. - - Meaning of the parameters is as follows: - - - - dir (string) - the direction to be - checked. It may be upstream (from UAS to UAC) or - downstream (UAC to UAS). - - - - - This function can be used from REQUEST_ROUTE. - - - <function>is_direction</function> usage - -... -if (is_direction("upstream")) { - xdbg("upstream request ($rm)\n"); -} -... - - -
- -
- Exported Pseudo-Variables - - Exported pseudo-variables are listed in the next sections. - -
- $rr_params - - $rr_params - the whole string of the Route - parameters - this is available only after calling loose_route() - -
-
- -
-
- diff --git a/modules/rr/doc/rr_devel.xml b/modules/rr/doc/rr_devel.xml deleted file mode 100644 index d2456af5eb9..00000000000 --- a/modules/rr/doc/rr_devel.xml +++ /dev/null @@ -1,210 +0,0 @@ - - - - - &develguide; - - - The RR module provides an internal API to be used by - other &osips; modules. The API offers support for - SIP dialog based functionalities - for more about the dialog support - offered by RR module, see . - - - For internal(non-script) usage, the RR module offers to other module the - possibility to register callback functions to be executed each time a - local Route header is processed. The callback function will receive as - parameter the register parameter and the Route header parameter string. - - - -
- Available Functions - -
- - <function moreinfo="none">add_rr_param( msg, param)</function> - - - Adds a parameter to the requests's Record-Route URI (param must be in - ;name=value format). - - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - - - struct sip_msg* msg - request that - will has the parameter param added to its - Record-Route header. - - - - str* param - parameter to be added - to the Record-Route header - it must be in - ;name=value format. - - - -
- -
- - <function moreinfo="none">check_route_param( msg, re)</function> - - - The function checks for the request msg if the URI - parameters of the local Route header (corresponding to the local - server) matches the given regular expression re. - It must be call after the loose_route was done. - - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - - - struct sip_msg* msg - request that - will has the Route header parameters checked. - - - - regex_t* param - compiled regular - expression to be checked against the Route header parameters. - - - -
- -
- - <function moreinfo="none">is_direction( msg, dir)</function> - - - The function checks the flow direction of the request - msg. As for checking it's used the ftag - Route header parameter, the append_fromtag (see - module parameter - must be enables. Also this must be call only after the loose_route is - done. - - - The function returns 0 if the dir is the same with - the request's flow direction. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - - - struct sip_msg* msg - request that - will have the direction checked. - - - - int dir - direction to be checked - against. It may be RR_FLOW_UPSTREAM or - RR_FLOW_DOWNSTREAM. - - - -
- -
- - <function moreinfo="none">get_route_param( msg, name, val)</function> - - - The function search in to the msg's Route header - parameters the parameter called name and returns its - value into val. It must be call only after the - loose_route is done. - - - The function returns 0 if parameter was found (even if it has no value). - Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - - - struct sip_msg* msg - request that - will have the Route header parameter searched. - - - - str *name - contains the Route header - parameter to be serached. - - - - str *val - returns the value of the - searched Route header parameter if found. It might be empty - string if the parameter had no value. - - - -
- -
- - <function moreinfo="none">register_rrcb( callback, param, prior)</function> - - - The function register a new callback (along with its parameter). The - callback will be called when a loose route will be performed for the - local address. - - - The function returns 0 on success. Otherwise, -1 is returned. - - Meaning of the parameters is as follows: - - - rr_cb_t callback - callback - function to be registered. - - - - void *param - parameter to be passed - to the callback function. - - - - short prior - parameter to set the priority. - If the callback depends on another module, this parameter should be greater - than that module's priority. Otherwise, it should be 0. - - - -
-
- -
- Examples - - Loading RR module's API from another module - -... -#include "../rr/api.h" -... -struct rr_binds my_rrb; -... -... -/* load the RR API */ -if (load_rr_api( &my_rrb )!=0) { - LM_ERR("can't load RR API\n"); - goto error; -} -... -... -/* register a RR callback */ -if (my_rrb.register_rrcb(my_callback,0,0))!=0) { - LM_ERR("can't register RR callback\n"); - goto error; -} -... - - -
- -
- diff --git a/modules/rr/doc/rr_faq.xml b/modules/rr/doc/rr_faq.xml deleted file mode 100644 index 0c32fe608b5..00000000000 --- a/modules/rr/doc/rr_faq.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - &faqguide; - - - - - What happened with old enable_full_lr parameter - - - - The parameter is considered obsolete. It was only introduced to - allow compatibility with older SIP entities, that complained - about a lr parameter without a value. - This behavior breaks RFC 3261, and since nowadays most SIP stacks - are fixed to conform with the RFC, the parameter was removed. - - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/rr/loose.c b/modules/rr/loose.c index 91b6bc1f8b7..8d2edf51ec0 100644 --- a/modules/rr/loose.c +++ b/modules/rr/loose.c @@ -273,6 +273,7 @@ static inline int get_maddr_uri(str *uri, struct sip_uri *puri) { static char builturi[RH_MADDR_PARAM_MAX_LEN+1]; struct sip_uri turi; + int len; if(uri==NULL || uri->s==NULL) return RR_ERROR; @@ -295,6 +296,12 @@ static inline int get_maddr_uri(str *uri, struct sip_uri *puri) LM_ERR( "Too long maddr parameter\n"); return RR_ERROR; } + len = 4 + puri->maddr_val.len + + ((puri->port.len>0)?(1+puri->port.len):0); + if( len > RH_MADDR_PARAM_MAX_LEN ) { + LM_ERR( "Too long maddr URI\n"); + return RR_ERROR; + } memcpy( builturi, "sip:", 4 ); memcpy( builturi+4, puri->maddr_val.s, puri->maddr_val.len ); @@ -305,8 +312,7 @@ static inline int get_maddr_uri(str *uri, struct sip_uri *puri) puri->port.len); } - uri->len = 4+puri->maddr_val.len - + ((puri->port.len>0)?(1+puri->port.len):0); + uri->len = len; builturi[uri->len]='\0'; uri->s = builturi; diff --git a/modules/rtp.io/README b/modules/rtp.io/README deleted file mode 100644 index c332adbc16e..00000000000 --- a/modules/rtp.io/README +++ /dev/null @@ -1,129 +0,0 @@ -RTP.io Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - 1.3. Exported Parameters - - 1.3.1. rtpproxy_args(string) - - 1.4. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set rtpproxy_args parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The RTP.io module provides an integrated solution for handling - RTP traffic within OpenSIPS, 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 --enable-librtpproxy 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. - -1.2. Dependencies - -1.3. Exported Parameters - -1.3.1. rtpproxy_args(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. - - Example 1.1. Set rtpproxy_args parameter -... -modparam("rtp.io", "rtpproxy_args", "-m 12000 -M 15000 -l 0.0.0.0 -6 /:: -") -... - -1.4. Exported Functions - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Maksym Sobolyev (@sobomax) 7 1 660 0 - 2. Liviu Chircu (@liviuchircu) 2 1 3 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) May 2025 - May 2025 - 2. Maksym Sobolyev (@sobomax) Jun 2024 - Jun 2024 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Maksym Sobolyev (@sobomax). - - Documentation Copyrights: - - Copyright © 2023 Sippy Software, Inc. diff --git a/modules/rtp.io/README.md b/modules/rtp.io/README.md new file mode 100644 index 00000000000..e92d8bc976c --- /dev/null +++ b/modules/rtp.io/README.md @@ -0,0 +1,69 @@ +--- +title: "RTP.io Module" +description: "The RTP.io module provides an integrated solution for handling RTP traffic within OpenSIPS, enabling RTP relaying and processing directly inside the OpenSIPS process." +--- + +## Admin Guide + + +### Overview + + +The RTP.io module provides an integrated solution +for handling RTP traffic within OpenSIPS, 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 `--enable-librtpproxy` 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 + + +#### rtpproxy_args(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.* + + +```opensips title="Set rtpproxy_args parameter" +... +modparam("rtp.io", "rtpproxy_args", "-m 12000 -M 15000 -l 0.0.0.0 -6 /::") +... +``` + + +### Exported Functions + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rtp.io/doc/contributors.xml b/modules/rtp.io/doc/contributors.xml deleted file mode 100644 index 978dc4691c8..00000000000 --- a/modules/rtp.io/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Maksym Sobolyev (@sobomax) - 7 - 1 - 660 - 0 - - - 2. - Liviu Chircu (@liviuchircu) - 2 - 1 - 3 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - May 2025 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Jun 2024 - Jun 2024 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Maksym Sobolyev (@sobomax). -
- -
diff --git a/modules/rtp.io/doc/rtp.io.xml b/modules/rtp.io/doc/rtp.io.xml deleted file mode 100644 index 63f10a0d03b..00000000000 --- a/modules/rtp.io/doc/rtp.io.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%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 deleted file mode 100644 index 37e678046b7..00000000000 --- a/modules/rtp.io/doc/rtp.io_admin.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - &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_relay/README b/modules/rtp_relay/README deleted file mode 100644 index 44673dddfb9..00000000000 --- a/modules/rtp_relay/README +++ /dev/null @@ -1,699 +0,0 @@ -RTP Relay Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Multiple Branches - 1.3. RTP Relay Engines - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. route_offer (string) - 1.5.2. route_answer (string) - 1.5.3. route_delete (string) - 1.5.4. route_copy_offer (string) - 1.5.5. route_copy_answer (string) - 1.5.6. route_copy_delete (string) - - 1.6. Exported Functions - - 1.6.1. rtp_relay_engage(engine, [set]) - - 1.7. Exported MI Functions - - 1.7.1. rtp_relay_list - 1.7.2. rtp_relay_update - 1.7.3. rtp_relay_update_callid - - 1.8. Exported Pseudo-Variables - - 1.8.1. $rtp_relay - 1.8.2. $rtp_relay_peer - 1.8.3. $rtp_relay_ctx() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set route_offer parameter - 1.2. route_offer route usage - 1.3. Set route_answer parameter - 1.4. route_answer route usage - 1.5. Set route_delete parameter - 1.6. rtp_relay_delete route usage - 1.7. Set rtp_relay_copy_offer parameter - 1.8. Set rtp_relay_copy_offer usage - 1.9. Set rtp_relay_copy_answer parameter - 1.10. Set rtp_relay_copy_answer usage - 1.11. Set rtp_relay_copy_delete parameter - 1.12. Set rtp_relay_copy_delete usage - 1.13. rtp_relay_engage usage - 1.14. rtp_relay_list usage - 1.15. rtp_relay_update usage - 1.16. rtp_relay_update_callid usage - -Chapter 1. Admin Guide - -1.1. Overview - - The purpose of this module is to simplify the usage of - different RTP Relays Servers (such as RTPProxy, RTPEngine, - Media Proxy) in OpenSIPS scripting, as well as to provide - various complex features that rely on the usage of RTP relays - (such as media re-anchoring). - - The module provides the logic to engage a specific RTP relay in - a call during initial INVITE, and then it will handle the - entire communication with the RTP relay, until the call - terminates. - - Moreover, one can specify various flags that modify the way RTP - engines use each user agent's SDP - these flags are persistent - throughout the entire RTP session, and are being used for - further in-dialog requests. These flags can be specified - through the $rtp_relay and/or $rtp_relay_peer variables at - initial INVITE, and are then passed along with the RTP relay - context until the end of the call. They can also be modified - during sequential in-dialog requests. - - This is not a stand-alone module that communicates directly - with RTP relays, but rather a generic interface that is able to - interact with the modules that interact with each specific RTP - Relay (such as rtpproxy or rtpengine) and implement their - specific communication protocol. - -1.2. Multiple Branches - - The module is able to handle RTP relay for multiple branches, - with different flags flavors. Each branch can have its flags - tuned through the $rtp_relay variable - if the variable is - provisioned in the main route, then the flags are inherited by - all further branches, unless specifically modified per branch. - To modify a specific branch, one needs to specify the desired - branch index as variable index (i.e. $(rtp_relay[1]) = "cor"). - When provisioned in a branch route, the flags are only changed - for that specific branch. - - Starting with OpenSIPS 3.3, branches can be identified based on - their participant's to_tag. This features becomes handy when - using rtp_relay in B2B mode, where peers can no longer be - identified simply by an index. However, this feature works in - dialog secenatios as well. - - The multiple branches behavior is handled differently by the - back-end engine, depending on its capabilities. For example, - rtpengine is able to natively support calls with multiple - branches, whereas for rtpproxy, each branch is emulated in a - different session with a different call-id. - - When the call gets answered and a single branch remains active, - all the other branches are destroyed and only the established - branches remain active throughout the call. - -1.3. RTP Relay Engines - - The module does not perform any SDP mangling itself, it is just - an enabler of the different backends supported, such as - RTPProxy or RTPEngine. These backends are called RTP Relay - angines and they need to be specified when RTP Relay is being - engaged. - - Starting with OpenSIPS 3.6, the module has been enhanced with - an internal RTP Engine, which can be used to perform - manual/custom SDP mangling by running a set of routes when an - RTP event (such as offer, answer, delete) happens. This can be - enabled by engaging RTP Relay with the route engine. If the - defined routes are not being defined, then the SDP does not - change. For more information, please check the route_offer, - route_answer and route_delete parameters. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * Dialog module - used to keep track of in-dialog requests. - * RTP Relay module(s) - such rtpproxy, or rtpengine, or any - module that implements the rtp_relay interface. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. route_offer (string) - - Route that is being run when an SDP offer happens (i.e. an - INVITE with SDP is being processed). - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route - (see the return values section below). - * ip - optional, the IP being specified in the $rtp_relay - variable for the current peer. - * type - optional, the RTP type being specified in the - $rtp_relay variable for the current peer. - * in-iface - optional, the inbound interface that should be - used for this peer. - * out-iface - optional, the outbound interface that should be - used for this peer. - * ctx-flags - optional, global flags that are being specified - in the $rtp_relay_ctx variable. - * flags - optional, flags specified for this peer. - * peer - optional, peer flags specified for the corresponding - peer; - - When running the route, the following values are expected to be - returned: - * body - the newly created body to be offered. If not - returned, the body is left unchanged. - * node - optional, a node to be identified for further - routes/commands executed. - - Default value is “rtp_relay_offer”. - - Example 1.1. Set route_offer parameter -... -modparam("rtp_relay", "route_offer", "custom_rtp_offer") -... - - Example 1.2. route_offer route usage -... -route[rtp_relay_offer] { - # manually engaging RTPEngine, get the SDP, and replace it in th -e message - return (1, $var(body)); -} -... - -1.5.2. route_answer (string) - - Route that is being run when an SDP answer happens (i.e. a 183 - or 200 OK reply with SDP is being processed). - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route. - * ip - optional, the IP being specified in the $rtp_relay - variable for the current peer. - * type - optional, the RTP type being specified in the - $rtp_relay variable for the current peer. - * in-iface - optional, the inbound interface that should be - used for this peer. - * out-iface - optional, the outbound interface that should be - used for this peer. - * ctx->flags - optional, global flags that are being - specified in the $rtp_relay_ctx variable. - * flags - optional, flags specified for this peer. - * peer - optional, peer flags specified for the corresponding - peer; - - When running the route, the following values are expected to be - returned: - * body - the newly created body to be answered. If not - returned, the body is left unchanged. - - Default value is “rtp_relay_answer”. - - Example 1.3. Set route_answer parameter -... -modparam("rtp_relay", "route_answer", "custom_rtp_answer") -... - - Example 1.4. route_answer route usage -... -route[rtp_relay_answer] { - # again, manually engaging RTPEngine - rtpengine_answer(,, $var(body), $rb); - return (1, $var(body)); -} -... - -1.5.3. route_delete (string) - - Route that is being run when media should be disconnected (i.e. - a CANCEL or BYE is received). - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route - (see the return values section below). - * ctx->flags - optional, global flags that are being - specified in the $rtp_relay_ctx variable. - * delete - optional, delete flags specified in the - $rtp_relay_ctx variable. - - Return values are not needed. - - Default value is “rtp_relay_delete”. - - Example 1.5. Set route_delete parameter -... -modparam("rtp_relay", "route_delete", "custom_rtp_delete") -... - - Example 1.6. rtp_relay_delete route usage -... -route[rtp_relay_delete] { - # manually removing RTPEngine session - rtpengine_delete(); -} -... - -1.5.4. route_copy_offer (string) - - Route that is being executed when a new call's SDP is being - copied. - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route - (see the return values section below). - * flags - optional, flags that are being specified by the - module which is copying the SDP. - * copy-ctx - optional, an copy context identifier - this is a - user populated value returned after running a - route_copy_offer route (see the return values section - below). - - When running the route, the following values are expected to be - returned: - * copy-ctx - optional, a copy context identifier that can be - later used to identify the current copy session. - - Default value is “rtp_relay_copy_offer”. - - Example 1.7. Set rtp_relay_copy_offer parameter -... -modparam("rtp_relay", "route_copy_offer", "custom_rtp_copy_offer") -... - - Example 1.8. Set rtp_relay_copy_offer usage -... -route[rtp_relay_copy_offer] { - # instruct a media engine to fork media and assign an identifier - # that shall be stored in the $var(handle) variable - return (1, $var(handle)); -} -... - -1.5.5. route_copy_answer (string) - - Route that is being run when an SDP for the copied stream is - received. (i.e. a CANCEL or BYE is received). - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route - (see the return values section below). - * flags - optional, flags that are being specified by the - module which is copying the SDP. - * copy-ctx - optional, an copy context identifier - this is a - user populated value returned at the end of - route_copy_offer execution. - - Default value is “rtp_relay_copy_answer”. - - Example 1.9. Set rtp_relay_copy_answer parameter -... -modparam("rtp_relay", "route_copy_answer", "custom_rtp_copy_answer") -... - - Example 1.10. Set rtp_relay_copy_answer usage -... -route[rtp_relay_copy_answer] { - # feed the received $param(body) to the media engine that is for -king the call - # copy instance is identified by the $param(copy-ctx) variable -} -... - -1.5.6. route_copy_delete (string) - - Route that is being run when media fork should be removed. - - When the route is executed, the following parameters are being - populated: - * callid - the callid of the call being processed. - * from_tag - the from_tag of the call being processed. - * to_tag - the to_tag, if exists, of the call being - processed. - * branch - the branch that RTP relay is being engaed on - if - engaged in the main branch, -1 is used. - * body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - * set - the rtp relay set being used for the call. - * node - optional, an node Engine idenfifier - this is a user - populated value returned after running a route_offer route - (see the return values section below). - * flags - optional, flags that are being specified by the - module which is copying the SDP. - * copy-ctx - optional, an copy context identifier - this is a - user populated value returned at the end of - route_copy_offer execution. - - Return values are not needed. - - Default value is “rtp_relay_copy_delete”. - - Example 1.11. Set rtp_relay_copy_delete parameter -... -modparam("rtp_relay", "route_copy_delete", "custom_rtp_copy_delete") -... - - Example 1.12. Set rtp_relay_copy_delete usage -... -route[rtp_relay_copy_delete] { - # remove the copy instance is identified by the $param(copy-ctx) - variable -} -... - -1.6. Exported Functions - -1.6.1. rtp_relay_engage(engine, [set]) - - Engages the RTP Relay engine for the current initial INVITE. - After calling this function, the entire RTP relay communication - will be handled by the module itself, without having to - intervene for any further in-dialog requests/replies (unless - you specifically want to). - - The function is not performing the media requests on the spot, - but rather registers the hooks to automatically handle any - further media requests. - - The RTP session modifiers used are the ones provisioned through - the $rtp_relay and/or $rtp_relay_peer variables. - - The function can be called from the main request route - in - this case the RTP relay will be engaged for any further - branches created, or from the branch route - in this case the - RTP relay will only be engaged for the branch where it was - called, or that has an associated rtp_relay provisioned. - - Meaning of the parameters is as follows: - * engine(string) - the RTP relay engine to be used for the - call (i.e. rtpproxy, rtpengine or route) - * set(int, optional) - the set used for this call. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.13. rtp_relay_engage usage -... -if (is_method("INVITE") && !has_totag()) { - xlog("SCRIPT: engaging RTPProxy relay for all branches\n"); - $rtp_relay = "co"; - $rtp_relay_peer = "co"; - rtp_relay_engage("rtpproxy"); -} -... - -1.7. Exported MI Functions - -1.7.1. rtp_relay_list - - Lists all the RTP Relay sessions engaged. - - Parameters: - * engine - (optional) the RTP relay engine (i.e. rtpproxy or - rtpengine). - * set - (optional) the RTP relay set. When used, the engine - parameter must also be specified. - * node - (optional) the RTP relay node. When used, the engine - parameter must also be specified. - - Example 1.14. rtp_relay_list usage -... -## list all sessions -$ opensips-cli -x mi rtp_relay_list - -## list all sessions going through a specific RTP node -$ opensips-cli -x mi rtp_relay_list rtpproxy udp:127.0.0.1:2222 -... - -1.7.2. rtp_relay_update - - Updates/Re-engages the RTP relays in all ongoing RTP relay - sessions. - - This function can be used to trigger dialog in-dialog updates - for certain ongoing RTP sessions. For all matched sessions, it - re-engages an RTP Relay offer/answer session, then sends - re-INVITEs to call's participants to with the updated SDP. - - Note:Running the command without a filter (such as engine or - set) will cause all RTP relay sessions to be re-engaged. - - Note:When enforcing a new node, it is not guaranteed to be used - - if the node is not avaialble, but a different one is, the - active one will be chosen. - - Note:If the node is being changed, the module tries to unforce - the previous RTP relay session, even though it might not work. - - Parameters: - * engine - (optional) the RTP relay engine (i.e. rtpproxy or - rtpengine) to be used as filter. - * set - (optional) the RTP relay set to be used as filter. If - missing, the same set will be used as it was initially - engaged for. - * node - (optional) the RTP relay node to be used as filter. - * new_set - (optional) a new RTP Relay set to be used for the - call. - * new_node - (optional) a new RTP node to be used for the - call. If new_set is missing, the same set will be used. - - Example 1.15. rtp_relay_update usage -... -## update all sessions that are using rtpproxy -$ opensips-cli -x mi rtp_relay_update rtpproxy -... - -1.7.3. rtp_relay_update_callid - - Updates/Re-engages the RTP relays in all ongoing RTP relay - sessions. - - The function basically works in the same manner as - rtp_relay_update, but is to be used to update a specific - callid. In addition, one can also update the engine and flags - used for the particular session. - - Parameters: - * callid - the callid used to match the dialog to be updated. - * engine - (optional) the new RTP relay engine (i.e. rtpproxy - or rtpengine) to be used. If missing, the same initial - engine is used. - * set - (optional) the new RTP relay set to be used. If - missing, the default same set will be used as it was - initially engaged for. - * node - (optional) the RTP relay node to be used. If not - specified, the first available node is used. - * flags - (optional) a JSON contining the caller and/or - callee nodes, which contain new flags that should be used - for the session. Only explicitely specified flags will be - overwritten. - - Example 1.16. rtp_relay_update_callid usage -... -## update a call with a working RTPproxy node -$ opensips-cli -x mi rtp_relay_update_callid 1-3758963@127.0.0.1 rtpprox -y - -## update a call to use RTPEngine with a SRTP SDP for caller -$ opensips-cli -x mi rtp_relay_update_callid callid=1-3758963@127.0.0.1 -\ - flags='{ "caller":{"type":"SRTP", "flags":"replace-origin"}, - "callee":{"type":"RTP", "flags"="replace-origin"}}' -... - -1.8. Exported Pseudo-Variables - -1.8.1. $rtp_relay - - Is used to provision the RTP back-end flags for the current - peer - if used in the initial INVITE REQUEST route, it - provisions the flags of the caller, whereas if used in the - initial INVITE BRANCH/REPLY route, it provisions the callee's - flags. - - For a sequential request, the variable represents the flags - used for the UAC that generated the request. When used in a - reply, the other UAC's flags are provisioned. - - In an initial INVITE scope, the variable can be provisioned per - branch, by using the variable's index. - - For each UAC/peer, there are several flags that can be - configured: - * flags (default, when variable is used without a name) - are - the flags associated with the current UAC - they are passed - along with the offer command - * peer - these flags are passed along in the offer command, - but they are flags associated with the other UAC/peer - * ip - the IP that should be advertised in the resulted SDP. - * type - the RTP type used by the current UAC (currently only - used by rtpengine) - * iface - the interface used for the traffic coming from this - UAC. - * body - the body to be used for the UAC. - * delete - flags to be used when the media session is - terminated/deleted. - * disabled - provisioned as an integer, it is used to disable - RTP relay for this UAC. - -1.8.2. $rtp_relay_peer - - This variable has the same meaning and parameters as the - $rtp_relay variable, except that it is used to provision the - other UAC's flags, except the current one. All other fields are - similar. - -1.8.3. $rtp_relay_ctx() - - This variable can be used to provide information about the RTP - context, information that is not associated with any of the - involved peers. - - The following settings can be used: - * callid - The callid to be used for all communication with - the rtp server. If not specified, it is taken from the - message/dialog. - * from_tag - The from-tag to be used for all communication - with the rtp server. If not specified, it is taken from the - message/dialog. - * to_tag - The to-tag to be used for all communication with - the rtp server. If not specified, it is taken from the - message/dialog. - * flags - Generic flags to be sent to all offer/answer - requests. - * delete - flags sent when the relay session is terminated. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 183 104 7001 1207 - 2. Maksym Sobolyev (@sobomax) 6 4 10 11 - 3. Norman Brandinger (@NormB) 4 2 2 2 - 4. Vlad Patrascu (@rvlad-patrascu) 3 1 11 7 - 5. Liviu Chircu (@liviuchircu) 3 1 1 1 - 6. Vlad Paiu (@vladpaiu) 2 1 5 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Apr 2021 - Oct 2025 - 2. Liviu Chircu (@liviuchircu) Jun 2024 - Jun 2024 - 3. Norman Brandinger (@NormB) Mar 2024 - Jun 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 5. Vlad Patrascu (@rvlad-patrascu) Mar 2023 - Mar 2023 - 6. Vlad Paiu (@vladpaiu) Oct 2022 - Oct 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2021 OpenSIPS Solutions diff --git a/modules/rtp_relay/README.md b/modules/rtp_relay/README.md new file mode 100644 index 00000000000..7faa72997ba --- /dev/null +++ b/modules/rtp_relay/README.md @@ -0,0 +1,763 @@ +--- +title: "RTP Relay Module" +description: "The purpose of this module is to simplify the usage of different RTP Relays Servers (such as RTPProxy, RTPEngine, Media Proxy) in OpenSIPS scripting, as well as to provide various complex features that rely on the usage of RTP relays (such as media re-anchoring)." +--- + +## Admin Guide + + +### Overview + + +The purpose of this module is to simplify the usage of different +RTP Relays Servers (such as RTPProxy, RTPEngine, Media Proxy) +in OpenSIPS scripting, as well as to provide various complex +features that rely on the usage of RTP relays (such as media re-anchoring). + + +The module provides the logic to engage a specific RTP relay in +a call during initial INVITE, and then it will handle the entire +communication with the RTP relay, until the call terminates. + + +Moreover, one can specify various flags that modify the way RTP +engines use each user agent's SDP - these flags are persistent +throughout the entire RTP session, and are being used for further +in-dialog requests. These flags can be specified through the +[rtp relay](#pv_rtp_relay) and/or +[rtp relay peer](#pv_rtp_relay_peer) variables at initial INVITE, +and are then passed along with the RTP relay context until +the end of the call. They can also be modified during sequential +in-dialog requests. + + +This is not a stand-alone module that communicates directly with RTP relays, +but rather a generic interface that is able to interact with the +modules that interact with each specific RTP Relay +(such as *rtpproxy* or *rtpengine*) +and implement their specific communication protocol. + + +### Multiple Branches + + +The module is able to handle RTP relay for multiple branches, with +different flags flavors. Each branch can have its flags tuned through +the [rtp relay](#pv_rtp_relay) variable - if the variable +is provisioned in the main route, then the flags are inherited +by all further branches, unless specifically modified per branch. +To modify a specific branch, one needs to specify the desired +branch index as variable index +(i.e. *$(rtp_relay[1]) = "cor"*). +When provisioned in a branch route, the flags are only changed +for that specific branch. + + +Starting with OpenSIPS 3.3, branches can be identified based +on their participant's to_tag. This features becomes handy when +using *rtp_relay* in B2B mode, where peers +can no longer be identified simply by an index. However, this +feature works in dialog secenatios as well. + + +The multiple branches behavior is handled differently by the +back-end engine, depending on its capabilities. For example, +*rtpengine* is able to natively support calls +with multiple branches, whereas for *rtpproxy*, +each branch is emulated in a different session with a different +call-id. + + +When the call gets answered and a single branch remains active, +all the other branches are destroyed and only the established +branches remain active throughout the call. + + +### RTP Relay Engines + + +The module does not perform any SDP mangling itself, it is just an +enabler of the different backends supported, such as RTPProxy +or RTPEngine. These backends are called RTP Relay angines and they +need to be specified when RTP Relay is being engaged. + + +Starting with OpenSIPS 3.6, the module has been enhanced with an +internal RTP Engine, which can be used to perform +*manual/custom* SDP mangling by running a set of +routes when an RTP event (such as offer, answer, delete) happens. +This can be enabled by engaging RTP Relay with the *route* +engine. If the defined routes are not being defined, then the SDP does not +change. For more information, please check the +[route offer](#param_route_offer), +[route answer](#param_route_answer) and +[route delete](#param_route_delete) parameters. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *Dialog* module - used to keep track of in-dialog requests. +- *RTP Relay* module(s) - such *rtpproxy*, or +*rtpengine*, or any module that implements the +*rtp_relay* interface. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### route_offer (string) + + +Route that is being run when an SDP offer happens (i.e. +an INVITE with SDP is being processed). + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *body* - optional, if an explicit body is being used, +otherwise the message's body should be considered. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route (see the return values section +below). +- *ip* - optional, the IP being specified in the +[rtp relay](#pv_rtp_relay) variable for the current peer. +- *type* - optional, the RTP type being specified in the +[rtp relay](#pv_rtp_relay) variable for the current peer. +- *in-iface* - optional, the inbound interface +that should be used for this peer. +- *out-iface* - optional, the outbound interface +that should be used for this peer. +- *ctx-flags* - optional, global flags that are +being specified in the [rtp relay ctx](#pv_rtp_relay_ctx) variable. +- *flags* - optional, flags specified for this peer. +- *peer* - optional, peer flags specified for +the corresponding peer; + + +When running the route, the following values are expected to be returned: + + +*body* - the newly created body to be offered. If +not returned, the body is left unchanged. + + +*node* - optional, a node to be identified for further +routes/commands executed. +*Default value is "rtp_relay_offer".* + + +```opensips title="Set route_offer parameter" +... +modparam("rtp_relay", "route_offer", "custom_rtp_offer") +... +``` + + +```opensips title="route_offer route usage" +... +route[rtp_relay_offer] { + # manually engaging RTPEngine, get the SDP, and replace it in the message + return (1, $var(body)); +} +... +``` + + +#### route_answer (string) + + +Route that is being run when an SDP answer happens (i.e. +a 183 or 200 OK reply with SDP is being processed). + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *body* - optional, if an explicit body is being used, +otherwise the message's body should be considered. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route. +- *ip* - optional, the IP being specified in the +[rtp relay](#pv_rtp_relay) variable for the current peer. +- *type* - optional, the RTP type being specified in the +[rtp relay](#pv_rtp_relay) variable for the current peer. +- *in-iface* - optional, the inbound interface +that should be used for this peer. +- *out-iface* - optional, the outbound interface +that should be used for this peer. +- *ctx->flags* - optional, global flags that are +being specified in the [rtp relay ctx](#pv_rtp_relay_ctx) variable. +- *flags* - optional, flags specified for this peer. +- *peer* - optional, peer flags specified for +the corresponding peer; + + +When running the route, the following values are expected to be returned: + + +*body* - the newly created body to be answered. If +not returned, the body is left unchanged. +*Default value is "rtp_relay_answer".* + + +```opensips title="Set route_answer parameter" +... +modparam("rtp_relay", "route_answer", "custom_rtp_answer") +... +``` + + +```opensips title="route_answer route usage" +... +route[rtp_relay_answer] { + # again, manually engaging RTPEngine + rtpengine_answer(,, $var(body), $rb); + return (1, $var(body)); +} +... +``` + + +#### route_delete (string) + + +Route that is being run when media should be disconnected +(i.e. a CANCEL or BYE is received). + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *body* - optional, if an explicit body is being used, +otherwise the message's body should be considered. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route (see the return values section +below). +- *ctx->flags* - optional, global flags that are +being specified in the [rtp relay ctx](#pv_rtp_relay_ctx) variable. +- *delete* - optional, delete flags specified in the +[rtp relay ctx](#pv_rtp_relay_ctx) variable. + + +Return values are not needed. +*Default value is "rtp_relay_delete".* + + +```opensips title="Set route_delete parameter" +... +modparam("rtp_relay", "route_delete", "custom_rtp_delete") +... +``` + + +```opensips title="rtp_relay_delete route usage" +... +route[rtp_relay_delete] { + # manually removing RTPEngine session + rtpengine_delete(); +} +... +``` + + +#### route_copy_offer (string) + + +Route that is being executed when a new call's SDP is being copied. + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route (see the return values section +below). +- *flags* - optional, flags that are being specified +by the module which is copying the SDP. +- *copy-ctx* - optional, an copy context identifier - +this is a user populated value returned after running a +*route_copy_offer* route (see the return values +section below). + + +When running the route, the following values are expected to be returned: + + +*copy-ctx* - optional, a copy context identifier +that can be later used to identify the current copy session. +*Default value is "rtp_relay_copy_offer".* + + +```opensips title="Set rtp_relay_copy_offer parameter" +... +modparam("rtp_relay", "route_copy_offer", "custom_rtp_copy_offer") +... +``` + + +```opensips title="Set rtp_relay_copy_offer usage" +... +route[rtp_relay_copy_offer] { + # instruct a media engine to fork media and assign an identifier + # that shall be stored in the $var(handle) variable + return (1, $var(handle)); +} +... +``` + + +#### route_copy_answer (string) + + +Route that is being run when an SDP for the copied stream is received. +(i.e. a CANCEL or BYE is received). + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *body* - optional, if an explicit body is being used, +otherwise the message's body should be considered. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route (see the return values section +below). +- *flags* - optional, flags that are being specified +by the module which is copying the SDP. +- *copy-ctx* - optional, an copy context identifier - +this is a user populated value returned at the end of +*route_copy_offer* execution. + + +*Default value is "rtp_relay_copy_answer".* + + +```opensips title="Set rtp_relay_copy_answer parameter" +... +modparam("rtp_relay", "route_copy_answer", "custom_rtp_copy_answer") +... +``` + + +```opensips title="Set rtp_relay_copy_answer usage" +... +route[rtp_relay_copy_answer] { + # feed the received $param(body) to the media engine that is forking the call + # copy instance is identified by the $param(copy-ctx) variable +} +... +``` + + +#### route_copy_delete (string) + + +Route that is being run when media fork should be removed. + + +When the route is executed, the following parameters are +being populated: + + +- *callid* - the callid of the call being processed. +- *from_tag* - the from_tag of the call being processed. +- *to_tag* - the to_tag, if exists, of the call being processed. +- *branch* - the branch that RTP relay is being engaed +on - if engaged in the main branch, *-1* is used. +- *body* - optional, if an explicit body is being used, +otherwise the message's body should be considered. +- *set* - the rtp relay set being used for the call. +- *node* - optional, an node Engine idenfifier - this +is a user populated value returned after running a +*route_offer* route (see the return values section +below). +- *flags* - optional, flags that are being specified +by the module which is copying the SDP. +- *copy-ctx* - optional, an copy context identifier - +this is a user populated value returned at the end of +*route_copy_offer* execution. + + +Return values are not needed. + + +*Default value is "rtp_relay_copy_delete".* + + +```opensips title="Set rtp_relay_copy_delete parameter" +... +modparam("rtp_relay", "route_copy_delete", "custom_rtp_copy_delete") +... +``` + + +```opensips title="Set rtp_relay_copy_delete usage" +... +route[rtp_relay_copy_delete] { + # remove the copy instance is identified by the $param(copy-ctx) variable +} +... +``` + + +### Exported Functions + + +#### rtp_relay_engage(engine, [set]) + + +Engages the RTP Relay *engine* for the current initial +INVITE. After calling this function, the entire RTP relay communication +will be handled by the module itself, without having to intervene for any +further in-dialog requests/replies (unless you specifically want to). + + +The function is not performing the media requests on the spot, +but rather registers the hooks to automatically handle any +further media requests. + + +The RTP session modifiers used are the ones provisioned through the +[rtp relay](#pv_rtp_relay) and/or +[rtp relay peer](#pv_rtp_relay_peer) variables. + + +The function can be called from the main request route - in this case +the RTP relay will be engaged for any further branches created, or from +the branch route - in this case the RTP relay will only be engaged for +the branch where it was called, or that has an associated +*rtp_relay* provisioned. + + +When provisioning RTP relay flags for this function, note that +[rtp relay](#pv_rtp_relay) and +[rtp relay peer](#pv_rtp_relay_peer) are relative to the route where +they are used. In the main request route of the initial INVITE, +[rtp relay](#pv_rtp_relay) refers to the caller and +[rtp relay peer](#pv_rtp_relay_peer) refers to the callee. In a +branch route, [rtp relay](#pv_rtp_relay) refers to the current +callee branch and [rtp relay peer](#pv_rtp_relay_peer) refers to the +caller. + + +Meaning of the parameters is as follows: + + +- *engine(string)* - the RTP relay engine +to be used for the call (i.e. *rtpproxy*, +*rtpengine* or *route*) +- *set(int, optional)* - the set used for this call. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="rtp_relay_engage usage" +... +if (is_method("INVITE") && !has_totag()) { + xlog("SCRIPT: engaging RTPProxy relay for all branches\n"); + $rtp_relay = "co"; + $rtp_relay_peer = "co"; + rtp_relay_engage("rtpproxy"); +} +... + +``` + + +### Exported MI Functions + + +#### rtp_relay_list + + +Lists all the RTP Relay sessions engaged. + + +Parameters: + + +- *engine* - (optional) the RTP +relay engine (i.e. *rtpproxy* +or *rtpengine*). +- *set* - (optional) the RTP +relay set. When used, the *engine* +parameter must also be specified. +- *node* - (optional) the RTP +relay node. When used, the *engine* +parameter must also be specified. + + +```bash title="rtp_relay_list usage" +... +## list all sessions +$ opensips-cli -x mi rtp_relay_list + +## list all sessions going through a specific RTP node +$ opensips-cli -x mi rtp_relay_list rtpproxy udp:127.0.0.1:2222 +... + +``` + + +#### rtp_relay_update + + +Updates/Re-engages the RTP relays in all ongoing RTP relay sessions. + + +This function can be used to trigger dialog in-dialog +updates for certain ongoing RTP sessions. For all matched +sessions, it re-engages an RTP Relay offer/answer session, +then sends re-INVITEs to call's participants to with +the updated SDP. + + +> [!NOTE] +> Running the command without a filter +> (such as *engine* or *set*) +> will cause all RTP relay sessions to be +> re-engaged. + + +> [!NOTE] +> When enforcing a new node, +> it is not guaranteed to be used - if the node is not +> avaialble, but a different one is, the active one will +> be chosen. + + +> [!NOTE] +> If the node is being changed, +> the module tries to unforce the previous RTP relay +> session, even though it might not work. + + +Parameters: + + +- *engine* - (optional) the RTP +relay engine (i.e. *rtpproxy* +or *rtpengine*) to be used +as filter. +- *set* - (optional) the RTP +relay set to be used as filter. If missing, the +same set will be used as it was initially engaged +for. +- *node* - (optional) the RTP +relay node to be used as filter. +- *new_set* - (optional) a new RTP +Relay set to be used for the call. +- *new_node* - (optional) a new RTP +node to be used for the call. If +*new_set* is missing, the +same set will be used. + + +```bash title="rtp_relay_update usage" +... +## update all sessions that are using rtpproxy +$ opensips-cli -x mi rtp_relay_update rtpproxy +... +``` + + +#### rtp_relay_update_callid + + +Updates/Re-engages the RTP relays in all ongoing RTP relay sessions. + + +The function basically works in the same manner as +[mi rtp relay update](#mi_rtp_relay_update), but is to be +used to update a specific callid. In addition, one can +also update the *engine* and +*flags* used for the particular +session. + + +Parameters: + + +- *callid* - the callid used to +match the dialog to be updated. +- *engine* - (optional) the new RTP +relay engine (i.e. *rtpproxy* +or *rtpengine*) to be used. If +missing, the same initial engine is used. +- *set* - (optional) the new RTP +relay set to be used. If missing, the default +same set will be used as it was initially engaged +for. +- *node* - (optional) the RTP +relay node to be used. If not specified, the first +available node is used. +- *flags* - (optional) a JSON +contining the *caller* and/or +*callee* nodes, which contain +new flags that should be used for the session. Only +explicitely specified flags will be overwritten. + + +```bash title="rtp_relay_update_callid usage" +... +## update a call with a working RTPproxy node +$ opensips-cli -x mi rtp_relay_update_callid 1-3758963@127.0.0.1 rtpproxy + +## update a call to use RTPEngine with a SRTP SDP for caller +$ opensips-cli -x mi rtp_relay_update_callid callid=1-3758963@127.0.0.1 \ + flags='{ "caller":{"type":"SRTP", "flags":"replace-origin"}, + "callee":{"type":"RTP", "flags"="replace-origin"}}' +... +``` + + +### Exported Pseudo-Variables + + +#### $rtp_relay + + +Is used to provision the RTP back-end flags for the +current peer. This variable is scope-relative: in the +main request route of the initial INVITE it provisions +the caller, while in the branch route or replies of the +initial INVITE transaction it provisions the callee branch. + + +For a sequential request, the variable represents the +flags used for the UAC that generated the request. When +used in a reply, the other UAC's flags are provisioned. + + +Use [rtp relay peer](#pv_rtp_relay_peer) when the script +needs to provision the opposite side: in the main request +route of the initial INVITE it provisions the callee, while +in the branch route or replies of the initial INVITE +transaction it provisions the caller. + + +In an initial INVITE scope, the variable can be +provisioned per branch, by using the variable's index. + + +For each UAC/peer, there are several flags that can be +configured: + + +- *flags* (default, when +variable is used without a name) - are the flags associated +with the current UAC - they are passed along with the offer +command +- *peer* - these flags are +passed along in the offer command, but they are flags associated +with the other UAC/peer +- *ip* - the IP that should be +advertised in the resulted SDP. +- *type* - the RTP type used +by the current UAC (currently only used by *rtpengine*) +- *iface* - the interface +used for the traffic coming from this UAC. +- *body* - the body to be used +for the UAC. +- *delete* - flags to be used +when the media session is terminated/deleted. +- *disabled* - provisioned +as an integer, it is used to disable RTP relay for this UAC. + + +#### $rtp_relay_peer + + +This variable has the same meaning and parameters as the +[rtp relay](#pv_rtp_relay) variable, except that it +is used to provision the other UAC's flags, not the +current one. All other fields are similar. + + +#### $rtp_relay_ctx() + + +This variable can be used to provide information about the +RTP context, information that is not associated with any of +the involved peers. + + +The following settings can be used: + + +- *callid* - The callid +to be used for all communication with the rtp server. +If not specified, it is taken from the message/dialog. +- *from_tag* - The from-tag +to be used for all communication with the rtp server. +If not specified, it is taken from the message/dialog. +- *to_tag* - The to-tag +to be used for all communication with the rtp server. +If not specified, it is taken from the message/dialog. +- *flags* - Generic flags +to be sent to all offer/answer requests. +- *delete* - flags sent +when the relay session is terminated. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rtp_relay/doc/contributors.xml b/modules/rtp_relay/doc/contributors.xml deleted file mode 100644 index 348c6f9b1e3..00000000000 --- a/modules/rtp_relay/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 183 - 104 - 7001 - 1207 - - - 2. - Maksym Sobolyev (@sobomax) - 6 - 4 - 10 - 11 - - - 3. - Norman Brandinger (@NormB) - 4 - 2 - 2 - 2 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 3 - 1 - 11 - 7 - - - 5. - Liviu Chircu (@liviuchircu) - 3 - 1 - 1 - 1 - - - 6. - Vlad Paiu (@vladpaiu) - 2 - 1 - 5 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Apr 2021 - Oct 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jun 2024 - Jun 2024 - - - 3. - Norman Brandinger (@NormB) - Mar 2024 - Jun 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - Mar 2023 - Mar 2023 - - - 6. - Vlad Paiu (@vladpaiu) - Oct 2022 - Oct 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/rtp_relay/doc/rtp_relay.xml b/modules/rtp_relay/doc/rtp_relay.xml deleted file mode 100644 index 17dcfc265de..00000000000 --- a/modules/rtp_relay/doc/rtp_relay.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - RTP Relay Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2021 OpenSIPS Solutions - diff --git a/modules/rtp_relay/doc/rtp_relay_admin.xml b/modules/rtp_relay/doc/rtp_relay_admin.xml deleted file mode 100644 index a8fd844e43f..00000000000 --- a/modules/rtp_relay/doc/rtp_relay_admin.xml +++ /dev/null @@ -1,1104 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The purpose of this module is to simplify the usage of different - RTP Relays Servers (such as RTPProxy, RTPEngine, Media Proxy) - in &osips; scripting, as well as to provide various complex - features that rely on the usage of RTP relays (such as media re-anchoring). - - - The module provides the logic to engage a specific RTP relay in - a call during initial INVITE, and then it will handle the entire - communication with the RTP relay, until the call terminates. - - - Moreover, one can specify various flags that modify the way RTP - engines use each user agent's SDP - these flags are persistent - throughout the entire RTP session, and are being used for further - in-dialog requests. These flags can be specified through the - and/or - variables at initial INVITE, - and are then passed along with the RTP relay context until - the end of the call. They can also be modified during sequential - in-dialog requests. - - - This is not a stand-alone module that communicates directly with RTP relays, - but rather a generic interface that is able to interact with the - modules that interact with each specific RTP Relay - (such as rtpproxy or rtpengine) - and implement their specific communication protocol. - -
- -
- Multiple Branches - - The module is able to handle RTP relay for multiple branches, with - different flags flavors. Each branch can have its flags tuned through - the variable - if the variable - is provisioned in the main route, then the flags are inherited - by all further branches, unless specifically modified per branch. - To modify a specific branch, one needs to specify the desired - branch index as variable index - (i.e. $(rtp_relay[1]) = "cor"). - When provisioned in a branch route, the flags are only changed - for that specific branch. - - - Starting with &osips; 3.3, branches can be identified based - on their participant's to_tag. This features becomes handy when - using rtp_relay in B2B mode, where peers - can no longer be identified simply by an index. However, this - feature works in dialog secenatios as well. - - - The multiple branches behavior is handled differently by the - back-end engine, depending on its capabilities. For example, - rtpengine is able to natively support calls - with multiple branches, whereas for rtpproxy, - each branch is emulated in a different session with a different - call-id. - - - When the call gets answered and a single branch remains active, - all the other branches are destroyed and only the established - branches remain active throughout the call. - -
- -
- RTP Relay Engines - - The module does not perform any SDP mangling itself, it is just an - enabler of the different backends supported, such as RTPProxy - or RTPEngine. These backends are called RTP Relay angines and they - need to be specified when RTP Relay is being engaged. - - - Starting with &osips; 3.6, the module has been enhanced with an - internal RTP Engine, which can be used to perform - manual/custom SDP mangling by running a set of - routes when an RTP event (such as offer, answer, delete) happens. - This can be enabled by engaging RTP Relay with the route - engine. If the defined routes are not being defined, then the SDP does not - change. For more information, please check the - , - and - parameters. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - Dialog module - used to keep track of in-dialog requests. - - - - - RTP Relay module(s) - such rtpproxy, or - rtpengine, or any module that implements the - rtp_relay interface. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>route_offer</varname> (string) - - Route that is being run when an SDP offer happens (i.e. - an INVITE with SDP is being processed). - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route (see the return values section - below). - - - - - ip - optional, the IP being specified in the - variable for the current peer. - - - - - type - optional, the RTP type being specified in the - variable for the current peer. - - - - - in-iface - optional, the inbound interface - that should be used for this peer. - - - - - out-iface - optional, the outbound interface - that should be used for this peer. - - - - - ctx-flags - optional, global flags that are - being specified in the variable. - - - - - flags - optional, flags specified for this peer. - - - - - peer - optional, peer flags specified for - the corresponding peer; - - - - - - - When running the route, the following values are expected to be returned: - - - - body - the newly created body to be offered. If - not returned, the body is left unchanged. - - - - - node - optional, a node to be identified for further - routes/commands executed. - - - - - - Default value is rtp_relay_offer. - - - - Set <varname>route_offer</varname> parameter - -... -modparam("rtp_relay", "route_offer", "custom_rtp_offer") -... - - - - <varname>route_offer</varname> route usage - -... -route[rtp_relay_offer] { - # manually engaging RTPEngine, get the SDP, and replace it in the message - return (1, $var(body)); -} -... - - -
-
- <varname>route_answer</varname> (string) - - Route that is being run when an SDP answer happens (i.e. - a 183 or 200 OK reply with SDP is being processed). - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route. - - - - - ip - optional, the IP being specified in the - variable for the current peer. - - - - - type - optional, the RTP type being specified in the - variable for the current peer. - - - - - in-iface - optional, the inbound interface - that should be used for this peer. - - - - - out-iface - optional, the outbound interface - that should be used for this peer. - - - - - ctx->flags - optional, global flags that are - being specified in the variable. - - - - - flags - optional, flags specified for this peer. - - - - - peer - optional, peer flags specified for - the corresponding peer; - - - - - - - When running the route, the following values are expected to be returned: - - - - body - the newly created body to be answered. If - not returned, the body is left unchanged. - - - - - - Default value is rtp_relay_answer. - - - - Set <varname>route_answer</varname> parameter - -... -modparam("rtp_relay", "route_answer", "custom_rtp_answer") -... - - - - <varname>route_answer</varname> route usage - -... -route[rtp_relay_answer] { - # again, manually engaging RTPEngine - rtpengine_answer(,, $var(body), $rb); - return (1, $var(body)); -} -... - - -
- -
- <varname>route_delete</varname> (string) - - Route that is being run when media should be disconnected - (i.e. a CANCEL or BYE is received). - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route (see the return values section - below). - - - - - ctx->flags - optional, global flags that are - being specified in the variable. - - - - - delete - optional, delete flags specified in the - variable. - - - - - - - Return values are not needed. - - - Default value is rtp_relay_delete. - - - - Set <varname>route_delete</varname> parameter - -... -modparam("rtp_relay", "route_delete", "custom_rtp_delete") -... - - - - <varname>rtp_relay_delete</varname> route usage - -... -route[rtp_relay_delete] { - # manually removing RTPEngine session - rtpengine_delete(); -} -... - - -
-
- <varname>route_copy_offer</varname> (string) - - Route that is being executed when a new call's SDP is being copied. - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route (see the return values section - below). - - - - - flags - optional, flags that are being specified - by the module which is copying the SDP. - - - - - copy-ctx - optional, an copy context identifier - - this is a user populated value returned after running a - route_copy_offer route (see the return values - section below). - - - - - - - When running the route, the following values are expected to be returned: - - - - copy-ctx - optional, a copy context identifier - that can be later used to identify the current copy session. - - - - - - Default value is rtp_relay_copy_offer. - - - - Set <varname>rtp_relay_copy_offer</varname> parameter - -... -modparam("rtp_relay", "route_copy_offer", "custom_rtp_copy_offer") -... - - - - Set <varname>rtp_relay_copy_offer</varname> usage - -... -route[rtp_relay_copy_offer] { - # instruct a media engine to fork media and assign an identifier - # that shall be stored in the $var(handle) variable - return (1, $var(handle)); -} -... - - -
-
- <varname>route_copy_answer</varname> (string) - - Route that is being run when an SDP for the copied stream is received. - (i.e. a CANCEL or BYE is received). - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route (see the return values section - below). - - - - - flags - optional, flags that are being specified - by the module which is copying the SDP. - - - - - copy-ctx - optional, an copy context identifier - - this is a user populated value returned at the end of - route_copy_offer execution. - - - - - - - Default value is rtp_relay_copy_answer. - - - - Set <varname>rtp_relay_copy_answer</varname> parameter - -... -modparam("rtp_relay", "route_copy_answer", "custom_rtp_copy_answer") -... - - - - Set <varname>rtp_relay_copy_answer</varname> usage - -... -route[rtp_relay_copy_answer] { - # feed the received $param(body) to the media engine that is forking the call - # copy instance is identified by the $param(copy-ctx) variable -} -... - - -
-
- <varname>route_copy_delete</varname> (string) - - Route that is being run when media fork should be removed. - - - When the route is executed, the following parameters are - being populated: - - - - callid - the callid of the call being processed. - - - - - from_tag - the from_tag of the call being processed. - - - - - to_tag - the to_tag, if exists, of the call being processed. - - - - - branch - the branch that RTP relay is being engaed - on - if engaged in the main branch, -1 is used. - - - - - body - optional, if an explicit body is being used, - otherwise the message's body should be considered. - - - - - set - the rtp relay set being used for the call. - - - - - node - optional, an node Engine idenfifier - this - is a user populated value returned after running a - route_offer route (see the return values section - below). - - - - - flags - optional, flags that are being specified - by the module which is copying the SDP. - - - - - copy-ctx - optional, an copy context identifier - - this is a user populated value returned at the end of - route_copy_offer execution. - - - - - - Return values are not needed. - - - - Default value is rtp_relay_copy_delete. - - - - Set <varname>rtp_relay_copy_delete</varname> parameter - -... -modparam("rtp_relay", "route_copy_delete", "custom_rtp_copy_delete") -... - - - - Set <varname>rtp_relay_copy_delete</varname> usage - -... -route[rtp_relay_copy_delete] { - # remove the copy instance is identified by the $param(copy-ctx) variable -} -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">rtp_relay_engage(engine, [set])</function> - - - - Engages the RTP Relay engine for the current initial - INVITE. After calling this function, the entire RTP relay communication - will be handled by the module itself, without having to intervene for any - further in-dialog requests/replies (unless you specifically want to). - - - The function is not performing the media requests on the spot, - but rather registers the hooks to automatically handle any - further media requests. - - - The RTP session modifiers used are the ones provisioned through the - and/or - variables. - - - The function can be called from the main request route - in this case - the RTP relay will be engaged for any further branches created, or from - the branch route - in this case the RTP relay will only be engaged for - the branch where it was called, or that has an associated - rtp_relay provisioned. - - Meaning of the parameters is as follows: - - - - engine(string) - the RTP relay engine - to be used for the call (i.e. rtpproxy, - rtpengine or route) - - - - set(int, optional) - the set used for this call. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtp_relay_engage</function> usage - -... -if (is_method("INVITE") && !has_totag()) { - xlog("SCRIPT: engaging RTPProxy relay for all branches\n"); - $rtp_relay = "co"; - $rtp_relay_peer = "co"; - rtp_relay_engage("rtpproxy"); -} -... - - -
- -
- -
- Exported MI Functions -
- <function moreinfo="none">rtp_relay_list</function> - - Lists all the RTP Relay sessions engaged. - - Parameters: - - - engine - (optional) the RTP - relay engine (i.e. rtpproxy - or rtpengine). - - - set - (optional) the RTP - relay set. When used, the engine - parameter must also be specified. - - - node - (optional) the RTP - relay node. When used, the engine - parameter must also be specified. - - - - - <function moreinfo="none">rtp_relay_list</function> usage - -... -## list all sessions -$ opensips-cli -x mi rtp_relay_list - -## list all sessions going through a specific RTP node -$ opensips-cli -x mi rtp_relay_list rtpproxy udp:127.0.0.1:2222 -... - - -
-
- <function moreinfo="none">rtp_relay_update</function> - - Updates/Re-engages the RTP relays in all ongoing RTP relay sessions. - - - This function can be used to trigger dialog in-dialog - updates for certain ongoing RTP sessions. For all matched - sessions, it re-engages an RTP Relay offer/answer session, - then sends re-INVITEs to call's participants to with - the updated SDP. - - - Note:Running the command without a filter - (such as engine or set) - will cause all RTP relay sessions to be - re-engaged. - - - Note:When enforcing a new node, - it is not guaranteed to be used - if the node is not - avaialble, but a different one is, the active one will - be chosen. - - - Note:If the node is being changed, - the module tries to unforce the previous RTP relay - session, even though it might not work. - - Parameters: - - - engine - (optional) the RTP - relay engine (i.e. rtpproxy - or rtpengine) to be used - as filter. - - - set - (optional) the RTP - relay set to be used as filter. If missing, the - same set will be used as it was initially engaged - for. - - - node - (optional) the RTP - relay node to be used as filter. - - - new_set - (optional) a new RTP - Relay set to be used for the call. - - - new_node - (optional) a new RTP - node to be used for the call. If - new_set is missing, the - same set will be used. - - - - - <function moreinfo="none">rtp_relay_update</function> usage - -... -## update all sessions that are using rtpproxy -$ opensips-cli -x mi rtp_relay_update rtpproxy -... - - -
-
- <function moreinfo="none">rtp_relay_update_callid</function> - - Updates/Re-engages the RTP relays in all ongoing RTP relay sessions. - - - The function basically works in the same manner as - , but is to be - used to update a specific callid. In addition, one can - also update the engine and - flags used for the particular - session. - - Parameters: - - - callid - the callid used to - match the dialog to be updated. - - - engine - (optional) the new RTP - relay engine (i.e. rtpproxy - or rtpengine) to be used. If - missing, the same initial engine is used. - - - set - (optional) the new RTP - relay set to be used. If missing, the default - same set will be used as it was initially engaged - for. - - - node - (optional) the RTP - relay node to be used. If not specified, the first - available node is used. - - - flags - (optional) a JSON - contining the caller and/or - callee nodes, which contain - new flags that should be used for the session. Only - explicitely specified flags will be overwritten. - - - - - <function moreinfo="none">rtp_relay_update_callid</function> usage - -... -## update a call with a working RTPproxy node -$ opensips-cli -x mi rtp_relay_update_callid 1-3758963@127.0.0.1 rtpproxy - -## update a call to use RTPEngine with a SRTP SDP for caller -$ opensips-cli -x mi rtp_relay_update_callid callid=1-3758963@127.0.0.1 \ - flags='{ "caller":{"type":"SRTP", "flags":"replace-origin"}, - "callee":{"type":"RTP", "flags"="replace-origin"}}' -... - - -
-
- -
- Exported Pseudo-Variables -
- <varname>$rtp_relay</varname> - - Is used to provision the RTP back-end flags for the - current peer - if used in the initial INVITE - REQUEST route, it provisions the flags of the - caller, whereas if used in the initial INVITE BRANCH/REPLY - route, it provisions the callee's flags. - - - For a sequential request, the variable represents the - flags used for the UAC that generated the request. When - used in a reply, the other UAC's flags are provisioned. - - - In an initial INVITE scope, the variable can be - provisioned per branch, by using the variable's index. - - - For each UAC/peer, there are several flags that can be - configured: - - flags (default, when - variable is used without a name) - are the flags associated - with the current UAC - they are passed along with the offer - command - - peer - these flags are - passed along in the offer command, but they are flags associated - with the other UAC/peer - - ip - the IP that should be - advertised in the resulted SDP. - - type - the RTP type used - by the current UAC (currently only used by - rtpengine) - - iface - the interface - used for the traffic coming from this UAC. - - body - the body to be used - for the UAC. - - delete - flags to be used - when the media session is terminated/deleted. - - disabled - provisioned - as an integer, it is used to disable RTP relay for this UAC. - - - -
-
- <varname>$rtp_relay_peer</varname> - - This variable has the same meaning and parameters as the - variable, except that it - is used to provision the other UAC's flags, except the - current one. All other fields are similar. - -
-
- <varname>$rtp_relay_ctx()</varname> - - This variable can be used to provide information about the - RTP context, information that is not associated with any of - the involved peers. - - - The following settings can be used: - - callid - The callid - to be used for all communication with the rtp server. - If not specified, it is taken from the message/dialog. - - from_tag - The from-tag - to be used for all communication with the rtp server. - If not specified, it is taken from the message/dialog. - - to_tag - The to-tag - to be used for all communication with the rtp server. - If not specified, it is taken from the message/dialog. - - flags - Generic flags - to be sent to all offer/answer requests. - - delete - flags sent - when the relay session is terminated. - - - -
-
-
- diff --git a/modules/rtp_relay/rtp_relay.c b/modules/rtp_relay/rtp_relay.c index 3e061bfd518..eb21eabd808 100644 --- a/modules/rtp_relay/rtp_relay.c +++ b/modules/rtp_relay/rtp_relay.c @@ -467,7 +467,11 @@ static struct rtp_relay_leg *pv_get_rtp_relay_leg(struct sip_msg *msg, if (!peer) { if (!set) return NULL; - peer = rtp_relay_new_leg(ctx, &get_from(msg)->tag_value, RTP_RELAY_ALL_BRANCHES); + if (route_type == BRANCH_ROUTE) + tag = get_from(msg)->tag_value; + else + tag = get_to(msg)->tag_value; + peer = rtp_relay_new_leg(ctx, &tag, RTP_RELAY_ALL_BRANCHES); if (!peer) { LM_ERR("cannot create a new leg\n"); return NULL; diff --git a/modules/rtp_relay/rtp_relay_ctx.c b/modules/rtp_relay/rtp_relay_ctx.c index f318cc815a1..00373815ab6 100644 --- a/modules/rtp_relay/rtp_relay_ctx.c +++ b/modules/rtp_relay/rtp_relay_ctx.c @@ -64,7 +64,7 @@ static struct list_head *rtp_relay_contexts; static str rtp_relay_dlg_name = str_init("_rtp_relay_ctx_"); -static int rtp_relay_dlg_callbacks(struct dlg_cell *dlg, struct rtp_relay_ctx *ctx, str *to_tag); +static int rtp_relay_dlg_callbacks(struct dlg_cell *dlg, struct rtp_relay_ctx *ctx); static void rtp_relay_dlg_req_callbacks(struct dlg_cell *dlg, struct rtp_relay_ctx *ctx); static void rtp_relay_ctx_release(void *param); @@ -552,9 +552,15 @@ static inline void rtp_relay_fill_sess_leg(struct rtp_relay_ctx *ctx, struct rtp_relay_sess *sess, int type, str *tag, int index) { struct rtp_relay_leg *leg = rtp_relay_get_leg(ctx, tag, index); - if ((leg && index != RTP_RELAY_ALL_BRANCHES && sess->legs[RTP_RELAY_PEER(type)] == leg) || - (!leg && index != RTP_RELAY_ALL_BRANCHES)) + struct rtp_relay_leg *peer = sess->legs[RTP_RELAY_PEER(type)]; + + if (leg == peer) + leg = NULL; + if (!leg && index != RTP_RELAY_ALL_BRANCHES) { leg = rtp_relay_get_leg(ctx, tag, RTP_RELAY_ALL_BRANCHES); + if (leg == peer) + leg = NULL; + } rtp_relay_push_sess_leg(sess, leg, type); } @@ -985,7 +991,11 @@ static void rtp_relay_loaded_callback(struct dlg_cell *dlg, int type, DLG_VAL_TYPE_NONE); ctx->established = sess; - if (rtp_relay_dlg_callbacks(dlg, ctx, NULL) < 0) + rtp_relay_fill_dlg(ctx, &dlg->callid, dlg->h_id, dlg->h_entry, + NULL, &dlg->legs[DLG_CALLER_LEG].tag, + dlg->legs_no[DLG_LEG_200OK] ? + &dlg->legs[callee_idx(dlg)].tag : NULL); + if (rtp_relay_dlg_callbacks(dlg, ctx) < 0) goto error; rtp_relay_dlg_req_callbacks(dlg, ctx); @@ -1596,6 +1606,8 @@ static void rtp_relay_indlg(struct dlg_cell* dlg, int type, struct dlg_cb_params } body = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP); + if (!body && msg->REQ_METHOD != METHOD_INVITE && msg->REQ_METHOD != METHOD_ACK) + return; RTP_RELAY_CTX_LOCK(ctx); sess = ctx->established; ret = (sess && rtp_sess_pending(sess)); @@ -1672,17 +1684,11 @@ static void rtp_relay_dlg_req_callbacks(struct dlg_cell *dlg, struct rtp_relay_c } static int rtp_relay_dlg_callbacks(struct dlg_cell *dlg, - struct rtp_relay_ctx *ctx, str *to_tag) + struct rtp_relay_ctx *ctx) { if (rtp_relay_dlg_ctx_idx == -1) return 0; - if (!to_tag && dlg->legs_no[DLG_LEG_200OK] != 0) - to_tag = &dlg->legs[callee_idx(dlg)].tag; - - rtp_relay_fill_dlg(ctx, &dlg->callid, dlg->h_id, dlg->h_entry, - NULL, &dlg->legs[DLG_CALLER_LEG].tag, to_tag); - if (rtp_relay_dlg.register_dlgcb(dlg, DLGCB_MI_CONTEXT, rtp_relay_dlg_mi, NULL, NULL) < 0) LM_ERR("could not register MI dlg print!\n"); @@ -1717,36 +1723,36 @@ static int rtp_relay_sess_success(struct rtp_relay_ctx *ctx, rtp_sess_set_success(sess); ctx->established = sess; - if (!rtp_relay_ctx_established(ctx)) { - dlg = rtp_relay_dlg.get_dlg(); - if (!dlg) { - LM_ERR("could not find dialog!\n"); + + dlg = rtp_relay_dlg.get_dlg(); + if (!dlg) { + LM_ERR("could not find dialog!\n"); + return -1; + } + + if (dlg->legs_no[DLG_LEG_200OK]) { + to_tag = &dlg->legs[callee_idx(dlg)].tag; + } else { + if (parse_headers(msg, HDR_TO_F, 0) < 0 || !msg->to || + parse_to_header(msg) < 0) { + LM_ERR("failed to parse To header\n"); return -1; } - /* reset old pointers */ - RTP_RELAY_PUT_TM_CTX(t, NULL); - RTP_RELAY_PUT_CTX(NULL); - /* if we have a to_tag, use it from dlg, - * otherwise fetch it from tm */ - if (!dlg->legs[callee_idx(dlg)].tag.len) { - if (parse_headers(msg, HDR_TO_F, 0) == -1) { - LM_ERR("failed to parse To header\n"); - return -1; - } + to_tag = &get_to(msg)->tag_value; - if (!msg->to) { - LM_ERR("missing To header\n"); - return -1; - } - - to_tag = &get_to(msg)->tag_value; + if (to_tag->len == 0) + to_tag = NULL; + } + rtp_relay_fill_dlg(ctx, &dlg->callid, dlg->h_id, dlg->h_entry, + NULL, &dlg->legs[DLG_CALLER_LEG].tag, to_tag); - if (to_tag->len == 0) - to_tag = NULL; - } + if (!rtp_relay_ctx_established(ctx)) { + /* reset old pointers */ + RTP_RELAY_PUT_TM_CTX(t, NULL); + RTP_RELAY_PUT_CTX(NULL); - if (rtp_relay_dlg_callbacks(dlg, ctx, to_tag) < 0) { + if (rtp_relay_dlg_callbacks(dlg, ctx) < 0) { /* restore the state */ RTP_RELAY_PUT_TM_CTX(t, ctx); return -1; @@ -1785,7 +1791,7 @@ static int handle_rtp_relay_ctx_leg_reply(struct rtp_relay_ctx *ctx, /* fill in tag's tag */ if (sess->legs[type] && sess->legs[type]->tag.len) return 0; - if (parse_headers(rpl, HDR_TO_F, 0) < 0 || !rpl->to || parse_from_header(rpl) < 0) { + if (parse_headers(rpl, HDR_TO_F, 0) < 0 || !rpl->to || parse_to_header(rpl) < 0) { LM_ERR("bad request or missing To header\n"); return -1; } else { @@ -1811,6 +1817,18 @@ static int rtp_relay_ctx_leg_reply(struct rtp_relay_ctx *ctx, struct sip_msg *ms struct rtp_relay_session info; memset(&info, 0, sizeof info); info.msg = msg; + if (msg->REPLY_STATUS >= 200 && msg->REPLY_STATUS < 300) { + if (parse_headers(msg, HDR_TO_F, 0) < 0 || !msg->to || + parse_to_header(msg) < 0) { + LM_ERR("To header field missing\n"); + return -1; + } + if (get_to(msg)->tag_value.len && + shm_str_sync(&ctx->to_tag, &get_to(msg)->tag_value) < 0) { + LM_ERR("could not store tag value\n"); + return -1; + } + } info.body = get_body_part(msg, TYPE_APPLICATION, SUBTYPE_SDP); if (!info.body) { if (msg->REPLY_STATUS < 200) { @@ -1832,17 +1850,6 @@ static int rtp_relay_ctx_leg_reply(struct rtp_relay_ctx *ctx, struct sip_msg *ms } } info.branch = sess->index; - if (msg->REPLY_STATUS >= 200 && msg->REPLY_STATUS < 300 && !ctx->to_tag.s) { - if (!msg->to && ((parse_headers(msg, HDR_TO_F, 0) == -1) || (!msg->to))) { - LM_ERR("To header field missing\n"); - return -1; - } - if (get_to(msg)->tag_value.len && - shm_str_sync(&ctx->to_tag, &get_to(msg)->tag_value) < 0) { - LM_ERR("could not store tag value\n"); - return -1; - } - } if (rtp_sess_late(sess)) ret = rtp_relay_offer(&info, ctx, sess, type, NULL); @@ -1880,6 +1887,8 @@ static void rtp_relay_ctx_initial_cb(struct cell* t, int type, struct tmcb_param rtp_sess_disabled(sess), rtp_sess_pending(sess)); goto end; } + rtp_relay_fill_sess_leg(ctx, sess, RTP_RELAY_CALLEE, + NULL, rtp_relay_ctx_branch()); switch (handle_rtp_relay_ctx_leg_reply(ctx, p->rpl, p->req, sess, RTP_RELAY_CALLEE)) { case 0: rtp_relay_ctx_leg_reply(ctx, p->rpl, t, sess, RTP_RELAY_CALLEE); @@ -1910,6 +1919,8 @@ static void rtp_relay_ctx_initial_cb(struct cell* t, int type, struct tmcb_param rtp_relay_ctx_branch()); goto end; } + rtp_relay_fill_sess_leg(ctx, sess, RTP_RELAY_CALLEE, + NULL, rtp_relay_ctx_branch()); memset(&info, 0, sizeof info); info.body = get_body_part(p->req, TYPE_APPLICATION, SUBTYPE_SDP); info.msg = p->req; diff --git a/modules/rtpengine/README b/modules/rtpengine/README deleted file mode 100644 index 16ca352328b..00000000000 --- a/modules/rtpengine/README +++ /dev/null @@ -1,1527 +0,0 @@ -rtpengine Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Multiple RTP proxy usage - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. rtpengine_sock (string) - 1.4.2. rtpengine_disable_tout (integer) - 1.4.3. rtpengine_tout (integer) - 1.4.4. rtpengine_retr (integer) - 1.4.5. rtpengine_timer_interval (integer) - 1.4.6. notification_sock (string) - 1.4.7. extra_id_pv (string) - 1.4.8. setid_avp (string) - 1.4.9. error_pv (string) - 1.4.10. db_url (string) - 1.4.11. db_table (string) - 1.4.12. socket_column (string) - 1.4.13. set_column (string) - 1.4.14. ping_enabled (integer) - - 1.5. Exported Functions - - 1.5.1. rtpengine_use_set(setid) - 1.5.2. rtpengine_offer([flags[, sock_var[, - sdp_pvar[, body]]]]) - - 1.5.3. rtpengine_answer([flags[, sock_pvar[, - sdp_pvar[, body]]]]) - - 1.5.4. rtpengine_delete([flags[, sock_var]]) - 1.5.5. rtpengine_manage([flags[, sock_var[, - sdp_var[, body]]]]) - - 1.5.6. rtpengine_start_recording([flags [, - sock_var]]) - - 1.5.7. rtpengine_stop_recording([flags [, - sock_var]]) - - 1.5.8. rtpengine_pause_recording([flags [, - sock_var]]) - - 1.5.9. rtpengine_play_media(flags, [duration_spec[, - sock_var[, sockvar]]]) - - 1.5.10. rtpengine_stop_media(flags[, [sock_var[, - sockvar]], [last_frame_pos]]) - - 1.5.11. rtpengine_block_media([flags[, sockvar]]) - 1.5.12. rtpengine_unblock_media([flags[, sockvar]]) - 1.5.13. rtpengine_block_dtmf([flags[, sockvar]]) - 1.5.14. rtpengine_unblock_dtmf([flags[, sockvar]]) - 1.5.15. rtpengine_start_forwarding([flags[, - sockvar]]) - - 1.5.16. rtpengine_stop_forwarding([flags[, - sockvar]]) - - 1.5.17. rtpengine_play_dtmf(code, [flags[, - sockvar]]) - - 1.6. Exported Asyncronous Functions - - 1.6.1. rtpengine_offer([flags[, sock_pvar[, - sdp_pvar[, body]]]]) - - 1.6.2. rtpengine_answer([flags[, sock_pvar[, - sdp_pvar[, body]]]]) - - 1.6.3. rtpengine_delete([flags[, sock_var]]) - - 1.7. Exported Pseudo-Variables - - 1.7.1. $rtpstat - 1.7.2. $rtpstat(STAT)[index] - 1.7.3. $rtpquery - - 1.8. Exported MI Functions - - 1.8.1. rtpengine_enable - 1.8.2. rtpengine_show - 1.8.3. rtpengine_reload - 1.8.4. teardown - - 1.9. Exported Events - - 1.9.1. E_RTPENGINE_NOTIFICATION - 1.9.2. E_RTPENGINE_STATUS - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set rtpengine_sock parameter - 1.2. Set rtpengine_disable_tout parameter - 1.3. Set rtpengine_tout parameter - 1.4. Set rtpengine_retr parameter - 1.5. Set rtpengine_timer_interval parameter - 1.6. Set notification_sock parameter - 1.7. Set extra_id_pv parameter - 1.8. Set setid_avp parameter - 1.9. Set error_pv parameter - 1.10. Set db_url parameter - 1.11. Set db_table parameter - 1.12. Set socket_column parameter - 1.13. Set set_column parameter - 1.14. Set ping_enabled parameter - 1.15. rtpengine_use_set usage - 1.16. rtpengine_offer usage - 1.17. rtpengine_offer usage with body replace - 1.18. rtpengine_offer usage with call recording - 1.19. rtpengine_offer usage for transcoding - 1.20. Set extra_failover_error parameter - 1.21. rtpengine_answer usage - 1.22. rtpengine_delete usage - 1.23. rtpengine_manage usage - 1.24. rtpengine_start_recording usage - 1.25. rtpengine_stop_recording usage - 1.26. rtpengine_pause_recording usage - 1.27. Ringback tone using rtpengine_play_media - 1.28. Manage music on hold using rtpengine_play_media - 1.29. Ringback tone stop using rtpengine_stop_media - 1.30. Example use of the last-frame-pos parameter - rtpengine_stop_media - - 1.31. Example of rtpengine_block_media usage - 1.32. Example of rtpengine_unblock_media usage - 1.33. Example of rtpengine_block_dtmf usage - 1.34. Example of rtpengine_unblock_dtmf usage - 1.35. Example of rtpengine_start_forwarding usage - 1.36. Example of rtpengine_stop_forwarding usage - 1.37. Example of rtpengine_play_dtmf usage - 1.38. Example of async rtpengine_offer() usage - 1.39. Example of async rtpengine_answer() usage - 1.40. Example of async rtpengine_delete() usage - 1.41. $rtpstat Usage - 1.42. $rtpstat(STAT) - 1.43. $rtpquery Usage - 1.44. rtpengine_enable usage - 1.45. rtpengine_show usage - 1.46. rtpengine_reload usage - 1.47. teardown usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module that enables media streams to be proxied via - an RTP proxy. The only RTP proxy currently known to work with - this module is the Sipwise rtpengine - https://github.com/sipwise/rtpengine. The rtpengine module is a - modified version of the original rtpproxy module using a new - control protocol. The module is designed to be a drop-in - replacement for the old module from a configuration file point - of view, however due to the incompatible control protocol, it - only works with RTP proxies which specifically support it. - -1.2. Multiple RTP proxy usage - - The rtpengine module can support multiple RTP proxies for - balancing/distribution and control/selection purposes. - - The module allows definition of several sets of rtpengines. - Load-balancing will be performed over a set and the admin has - the ability to choose what set should be used. The set is - selected via its id - the id being defined with the set. Refer - to the “rtpengine_sock” module parameter definition for syntax - description. - - The balancing inside a set is done automatically by the module - based on the weight of each RTP proxy from the set. - - The selection of the set is done from script prior using - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() - functions - see the rtpengine_use_set() function. - - Another way to select the set is to define setid_avp module - parameter and assign setid to the defined avp before calling - rtpengine_offer() or rtpengine_manage() function. If forwarding - of the requests fails and there is another branch to try, - remember to unset the avp after calling rtpengine_delete() - function. - - For backward compatibility reasons, a set with no id take by - default the id 0. Also if no set is explicitly set before - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() the - 0 id set will be used. - - IMPORTANT: if you use multiple sets, take care and use the same - set for both rtpengine_offer()/rtpengine_answer() and - rtpengine_delete()!! If the set was selected using setid_avp, - the avp needs to be set only once before rtpengine_offer() or - rtpengine_manage() call. - - The module is able to failover to a new node within a set, if a - chosen one has communication issues. Moreover, it will also - failover if the node returns one of the following errors: - * Parallel session limit reached - * Ran out of ports - - You can use the extra_failover_error parameter to extend the - above list. - - Many rtpengine_* functions accept a "sock_var" parameter that - will be populated with the socket of the RTPEngine chosen for - the particular operation. The format of the data stored in - "sock_var" is: "proto:ip:port". If the "sock_var" has been - specified and it is non-NULL then it will be used to determine - the specific RTPEngine to use. Note that the socket specified - by "sock_var" must be a member of the current RTPEngine Set - context. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tm module - (optional) if you want to have - rtpengine_manage() fully functional - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. rtpengine_sock (string) - - Definition of socket(s) used to connect to (a set) RTP proxy. - It may specify a UNIX socket or an IPv4/IPv6 UDP socket. If the - protocol part (i.e. “udp:”) is missing, the socket is treated - as a UNIX socket. - - Default value is “NONE” (disabled). - - Example 1.1. Set rtpengine_sock parameter -... -# single rtproxy -modparam("rtpengine", "rtpengine_sock", "udp:localhost:12221") -# multiple rtproxies for LB -modparam("rtpengine", "rtpengine_sock", - "udp:localhost:12221 udp:localhost:12222") -# multiple sets of multiple rtproxies -modparam("rtpengine", "rtpengine_sock", - "1 == udp:localhost:12221 udp:localhost:12222") -modparam("rtpengine", "rtpengine_sock", - "2 == udp:localhost:12225") -... - -1.4.2. rtpengine_disable_tout (integer) - - Once an RTP proxy was found unreachable and marked as disabled, - the rtpengine module will not attempt to establish - communication to that RTP proxy for rtpengine_disable_tout - seconds. - - Default value is “60”. - - Example 1.2. Set rtpengine_disable_tout parameter -... -modparam("rtpengine", "rtpengine_disable_tout", 20) -... - -1.4.3. rtpengine_tout (integer) - - Timeout value in waiting for reply from RTP proxy. - - Default value is “1”. - - Example 1.3. Set rtpengine_tout parameter -... -modparam("rtpengine", "rtpengine_tout", 2) -... - -1.4.4. rtpengine_retr (integer) - - How many times the module should retry to send and receive - after timeout was generated. - - Default value is “5”. - - Example 1.4. Set rtpengine_retr parameter -... -modparam("rtpengine", "rtpengine_retr", 2) -... - -1.4.5. rtpengine_timer_interval (integer) - - Frequency to scan rtpengine sets for disabled node probing. - Probing is done outside the SIP processing context and in a - separate timer routine. Disabled nodes are probed for - re-enablement after rtpengine_disable_tout seconds. Setting - this value too high can lead to unexpectedly large disabled - interval as the max interval before probing is - (rtpengine_timer_interval + rtpengine_disable_tout) seconds. - - Default value is “5”. - - Example 1.5. Set rtpengine_timer_interval parameter -... -modparam("rtpengine", "rtpengine_timer_interval", 1) -... - -1.4.6. notification_sock (string) - - An UDP socket formatted as IP:port that indicates the listening - IP and port OpenSIPS will bind for to receive notifications - (such as DTMF events) from RTPengine. - - Every notification received from RTPengine will trigger an - E_RTPENGINE_NOTIFICATION event. - - Default value is “none” - notifications are ignored. - - Example 1.6. Set notification_sock parameter -... -modparam("rtpengine", "notification_sock", "127.0.0.1:9999") -... - -1.4.7. extra_id_pv (string) - - The parameter sets the PV definition to use when the - “via-branch=extra” option is used on the rtpengine_delete(), - rtpengine_offer(), rtpengine_answer() or rtpengine_manage() - commands. - - Default is empty, the “via-branch=extra” option may not be used - then. - - Example 1.7. Set extra_id_pv parameter -... -modparam("rtpengine", "extra_id_pv", "$avp(extra_id)") -... - -1.4.8. setid_avp (string) - - The parameter defines an AVP that, if set, determines which RTP - proxy set rtpengine_offer(), rtpengine_answer(), - rtpengine_delete(), and rtpengine_manage() functions use. - - There is no default value. - - Example 1.8. Set setid_avp parameter -... -modparam("rtpengine", "setid_avp", "$avp(setid)") -... - -1.4.9. error_pv (string) - - The parameter defines a variable that shall be populated by RTP - when one of the rtpengine_* functions fail. - - There is no default value. - - Example 1.9. Set error_pv parameter -... -modparam("rtpengine", "error_pv", "$var(rtpengine_error)") -... - -1.4.10. db_url (string) - - Database URL, used to load RTPEngines sockets from db, instead - of specifying them in the script (rtpengine_sock module - parameter). - - Default value is “NULL”, no database is used. - - Example 1.10. Set db_url parameter -... -modparam("rtpengine", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - -1.4.11. db_table (string) - - The table where the RTPEngines sockets are stored. Used when - Database URL is provisioned. - - Default value is “rtpengine”. - - Example 1.11. Set db_table parameter -... -modparam("rtpengine", "db_table", "rtpengine_new") -... - -1.4.12. socket_column (string) - - The name of the rtpengine socket column in the database table. - - Default value is “socket”. - - Example 1.12. Set socket_column parameter -... -modparam("rtpengine", "socket_column", "sock") -... - -1.4.13. set_column (string) - - The name of the rtpengine set column in the database table. - - Default value is “set_id”. - - Example 1.13. Set set_column parameter -... -modparam("rtpengine", "set_column", "set_new") -... - -1.4.14. ping_enabled (integer) - - This parameter indicates whether probing should be done for - enabled nodes as well. - - If this parameter is set, each enabled node is pinged every - rtpengine_timer_interval seconds, unless there was any - communication with the node since the previous interval. - - Default value is “0” (disabled). - - Example 1.14. Set ping_enabled parameter -... -modparam("rtpengine", "ping_enabled", yes) -... - -1.5. Exported Functions - -1.5.1. rtpengine_use_set(setid) - - Sets the ID of the RTP proxy set to be used for the next - rtpengine_delete(), rtpengine_offer(), rtpengine_answer() or - rtpengine_manage() command. The parameter is an integer. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE. - - Example 1.15. rtpengine_use_set usage -... -rtpengine_use_set(2); -rtpengine_offer(); -... - -1.5.2. rtpengine_offer([flags[, sock_var[, sdp_pvar[, body]]]]) - - Rewrites SDP body to ensure that media is passed through an RTP - proxy. To be invoked on INVITE for the cases the SDPs are in - INVITE and 200 OK and on 200 OK when SDPs are in 200 OK and - ACK. - - Meaning of the parameters is as follows: - * flags(string, optional) - flags to turn on some features. - The “flags” string is a list of space-separated items. Each - item is either an individual token, or a token in - “key=value” format. The possible tokens are described - below. - When passing an option that OpenSIPS is not aware of, it - will be blindly sent to the rtpengine daemon to be - processed. - + via-branch=... - Include the “branch” value of one of - the “Via” headers in the request to the RTP proxy. - Possible values are: “1” - use the first “Via” header; - “2” - use the second “Via” header; “auto” - use the - first “Via” header if this is a request, or the second - one if this is a reply; “extra” - don't take the value - from a header, but instead use the value of the - “extra_id_pv” variable. This can be used to create one - media session per branch on the RTP proxy. When - sending a subsequent “delete” command to the RTP - proxy, you can then stop just the session for a - specific branch when passing the flag '1' or '2' in - the “rtpengine_delete”, or stop all sessions for a - call when not passing one of those two flags there. - This is especially useful if you have serially forked - call scenarios where the RTP proxy gets an “offer” - command for a new branch, and then a “delete” command - for the previous branch, which would otherwise delete - the full call, breaking the subsequent “answer” for - the new branch. This flag is only supported by the - Sipwise rtpengine RTP proxy at the moment! - + via-branch-param=... - provide a custom value for the - via-branch param. - + call-id - provide a custom Call-ID for the session. If - missing, the Call-Id of the request/reply is used. - + from-tag - provide a custom from-tag for the session. - If missing, the from-tag request is used. - + to-tag - provide a custom to-tag of the session. If - missing, the to-tag of the request/reply is used, is - present. - + asymmetric - flags that UA from which message is - received doesn't support symmetric RTP. (automatically - sets the 'r' flag) - + force-answer - force “answer”, that is, only rewrite - SDP when corresponding session already exists in the - RTP proxy. By default is on when the session is to be - completed. - + in-iface=..., out-iface=... - these flags specify the - direction the SIP message. These flags only make sense - when the RTP proxy is running in bridge mode. - “in-iface” should indicate the proxy's inbound - interface, and “out-iface” corresponds to the RTP - proxy's outbound interface. You always have to specify - two flags to define the incoming network and the - outgoing network. For example, “in-iface=internal - out-iface=external” should be used for SIP message - received from the local interface and sent out on the - external interface. - + internal, external - these the old flags used to - specify the direction of call. They are now obsolate, - being replaced by the “in-iface=internal - out-iface=external” configuration. - + auto-bridge - this flag an alternative to the - “internal” and “external” flags in order to do - automatic bridging between IPv4 on the "internal - network" and IPv6 on the "external network". Instead - of explicitly instructing the RTP proxy to select a - particular address family, the distinction is done by - the given IP in the SDP body by the RTP proxy itself. - Not supported by Sipwise rtpengine. - + address-family=... - instructs the RTP proxy that the - recipient of this SDP body expects to see addresses of - a particular family. Possible values are “IP4” and - “IP6”. For example, if the SDP body contains IPv4 - addresses but the recipient only speaks IPv6, you - would use “address-family=IP6” to bridge between the - two address families. - Sipwise rtpengine remembers the address family - preference of each party after it has seen an SDP body - from them. This means that normally it is only - necessary to explicitly specify the address family in - the “offer”, but not in the “answer”. - Note: Please note, that this will only work properly - with non-dual-stack user-agents or with dual-stack - clients according to RFC6157 (which suggest ICE for - Dual-Stack implementations). This short-cut will not - work properly with RFC4091 (ANAT) compatible clients, - which suggests having different m-lines with different - IP-protocols grouped together. - + received-from=... - sets the address from which SIP - packet with SDP received. This flag always set - automatically, don't use it until you have a reason - for that. - + force - instructs the RTP proxy to ignore marks - inserted by another RTP proxy in transit to indicate - that the session is already goes through another - proxy. Allows creating a chain of proxies. Not - supported and ignored by Sipwise rtpengine. - + trust-address - flags that IP address in SDP should be - trusted. Without this flag, the RTP proxy ignores - address in the SDP and uses source address of the SIP - message as media address which is passed to the RTP - proxy. From rtpengine 3.8 this is the default - behaviour. - + SIP-source-address - the opposite of trust-address. - Restores the old default behaviour of ignoring - endppoint of the addresses in the SDP body. - + replace-origin - flags that IP from the origin - description (o=) should be also changed. - + replace-session-connection - flags to change the - session-level SDP connection (c=) IP if media - description also includes connection information. - + replace-zero-address - flags to replace zero address - with real address. Using a zero endpoint address is an - obsolete way to signal a muted or sendonly stream. - Streams with zero addresses are normally flagged as - sendonly and the zero address in the SDP is passed - through. - + symmetric - flags that for the UA from which message - is received, support symmetric RTP must be forced. You - do not need to explicitly specify this value, as it is - the default, and the behavior is only changed when the - asymmetric is used. - + repacketize=NN - requests the RTP proxy to perform - re-packetization of RTP traffic coming from the UA - which has sent the current message to increase or - decrease payload size per each RTP packet forwarded if - possible. The NN is the target payload size in ms, for - the most codecs its value should be in 10ms - increments, however for some codecs the increment - could differ (e.g. 30ms for GSM or 20ms for G.723). - The RTP proxy would select the closest value supported - by the codec. This feature could be used for - significantly reducing bandwith overhead for low - bitrate codecs, for example with G.729 going from 10ms - to 100ms saves two thirds of the network bandwith. Not - supported by Sipwise rtpengine. - + loop-protect - flag that instructs RTP to avoid - rewriting the SDP when looping the same message. - + ICE=... - controls the RTP proxy's behaviour regarding - ICE attributes within the SDP body. Possible values - are: “force” - discard any ICE attributes already - present in the SDP body and then generate and insert - new ICE data, leaving itself as the only ICE - candidates; “remove” instructs the RTP proxy to - discard any ICE attributes and not insert any new ones - into the SDP. The default (if no “ICE=...” is given at - all), new ICE data will only be generated if no ICE - was present in the SDP originally; otherwise the RTP - proxy will only insert itself as an additional ICE - candidate. Other SDP substitutions (c=, m=, etc) are - unaffected by this flag. - + RTP, SRTP, AVP, AVPF - These flags control the RTP - transport protocol that should be used towards the - recipient of the SDP. If none of them are specified, - the protocol given in the SDP is left untouched. - Otherwise, the “SRTP” flag indicates that SRTP should - be used, while “RTP” indicates that SRTP should not be - used. “AVPF” indicates that the advanced RTCP profile - with feedback messages should be used, and “AVP” - indicates that the regular RTCP profile should be - used. See also the next set of flags below. - + RTP/AVP, RTP/SAVP, RTP/AVPF, RTP/SAVPF - these serve - as an alternative, more explicit way to select between - the different RTP protocols and profiles supported by - the RTP proxy. For example, giving the flag - “RTP/SAVPF” has the same effect as giving the two - flags “SRTP AVPF”. - + to-tag - force inclusion of the “To” tag. Normally, - the “To” tag is always included when present, except - for “delete” messages. Including the “To” tag in a - “delete” messages allows you to be more selective - about which dialogues within a call are being torn - down. - + to-tag=... - use the specified string as “To” tag - instead of the actual “To” tag from the SIP message, - and force inclusion of the tag in the message as per - above. - + from-tag=... - use the specified string as “From” tag - instead of the actual “From” tag from the SIP message. - + call-id=... - use the specified string as “Call-ID” - instead of the actual “Call-ID” from the SIP message. - + rtcp-mux-demux - if rtcp-mux (RFC 5761) was offered, - make the RTP proxy accept the offer, but not offer it - to the recipient of this message. - + rtcp-mux-reject - if rtcp-mux was offered, make the - RTP proxy reject the offer, but still offer it to the - recipient. Can be combined with “rtcp-mux-offer” to - always offer it. - + rtcp-mux-offer - make the RTP proxy offer rtcp-mux to - the recipient of this message, regardless of whether - it was offered originally or not. - + rtcp-mux-require - Similar to offer but pretends that - the client has accepted rtcp-mux. This breaks RFC 5761 - and will not advertise seperate RTCP ports. This - option is necessary for WebRTC clients. - + rtcp-mux-accept - if rtcp-mux was offered, make the - RTP proxy accept the offer and also offer it to the - recipient of this message. Can be combined with - “rtcp-mux-offer” to always offer it. - + media-address=... - force a particular media address - to be used in the SDP body. Address family is detected - automatically. - + record-call=yes/no - indicates whether rtpengine - should record the call or not. When using this - parameter, you may pass further information in the - “metadata”. - + transcode-CODEC - used only for offer, indicates that - rtpengine should transcode the CODEC towards the - B-side. Example: transcode-PCMA will present to the - B-side the PCMA codec. - + codec-strip-CODEC - used only for offer, indicates - that the A-side of the call will not end up talking - CODEC. Example: codec-strip-PCMA will prevent the - A-side from receiving the PCMA codec. - + codec-mask-CODEC - used only for offer, indicates that - the A-side will use the CODEC, but it will not be - presented to the B-side. Example: codec-mask-PCMA will - make the A-side receive the PCMA codec, but B-side - will use something else. - * sock_var(var, optional) - variable used to store the - rtpengine socket chosen for this call. - * sdp_var(var, optional) - variable used to store the full - SDP received from rtpengine. You can perform any additional - changes on this string. Important: when providing this - variable, the message body is no longer changed, so you - have to manually replace it!. - * body(string, optional) - used to provide a specific body to - the rtpengine_* function. If this parameter is missing the - body of the current message is used. - - This function can be used from ALL_ROUTES. - - Example 1.16. rtpengine_offer usage -route { -... - if (is_method("INVITE")) { - if (has_body("application/sdp")) { - if (rtpengine_offer()) - t_on_reply("1"); - } else { - t_on_reply("2"); - } - } - if (is_method("ACK") && has_body("application/sdp")) - rtpengine_answer(); -... -} - -onreply_route[1] -{ -... - if (has_body("application/sdp")) - rtpengine_answer(); -... -} - -onreply_route[2] -{ -... - if (has_body("application/sdp")) - rtpengine_offer(); -... -} - - Example 1.17. rtpengine_offer usage with body replace -... -if (rtpengine_offer(, $var(socket), $var(body), $rb)) { - xlog("Used rtpengine $var(socket)\n"); - # make all the changes on the resulted SDP in $var(body) - ... - remove_body_part(); - add_body_part($var(body), "application/sdp"); -} -... - - Example 1.18. rtpengine_offer usage with call recording -... -$var(rtpengine_flags) = $var(rtpengine_flags) + " record-call=yes"; - -$json(recording_keys) := "{}"; -$json(recording_keys/callId) = $ci; -$json(recording_keys/fromUser) = $dlg_val(recording_from_user); -$json(recording_keys/fromDomain) = $dlg_val(recording_from_domain); -$json(recording_keys/fromTag) = $dlg_val(recording_from_tag); -$json(recording_keys/toUser) = $dlg_val(recording_to_user); -$json(recording_keys/toDomain) = $dlg_val(recording_to_domain); - -$var(rtpengine_flags) = $var(rtpengine_flags) + " metadata=" + $(json(re -cording_keys){s.encode.hexa}); -rtpengine_offer($var(rtpengine_flags)); -... - - Example 1.19. rtpengine_offer usage for transcoding -... -# Goal: make A-side talk PCMA and B-side talk opus -# * do not present PCMA to B-side: codec-mask-PCMA, but use it on A-side -# * do not use opus for A-side: codec-strip-opus -# * offer opus to B-side: transcode-opus -rtpengine_offer("... codec-mask-PCMA codec-strip-opus transcode-opus ... -"); -... - -1.5.2.1. extra_failover_error (string) - - Contains a (XDB) regular expression that can be used to match - an error received from a RTPEngine node. If matched the module - tries to use a new node to handle the affected command. - - This parameter can be used to extend the list (see Failover of - errors the module implicitely fails over. - - Note each declaration will define a single expression/matching - rule. If you want to define multiple rules, you need to define - the parameter multiple times. - - Default value is empty, no extra errors are being used. - - Example 1.20. Set extra_failover_error parameter -... -modparam("rtpengine", "extra_failover_error", "Parallel session limit re -ached") -... - -1.5.3. rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]]) - - Rewrites SDP body to ensure that media is passed through an RTP - proxy. To be invoked on 200 OK for the cases the SDPs are in - INVITE and 200 OK and on ACK when SDPs are in 200 OK and ACK. - - See rtpengine_offer() function description above for the - meaning of the parameters. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.21. rtpengine_answer usage - - See rtpengine_offer() function example above for examples. - -1.5.4. rtpengine_delete([flags[, sock_var]]) - - Tears down the RTPEngine session for the current call. - - See rtpengine_offer() function description above for the - meaning of the parameters. Note that not all flags make sense - for a “delete”. - - This function can be used from ALL_ROUTES. - - Example 1.22. rtpengine_delete usage -... -rtpengine_delete(); -... - -1.5.5. rtpengine_manage([flags[, sock_var[, sdp_var[, body]]]]) - - Manage the RTPEngine session - it combines the functionality of - rtpengine_offer(), rtpengine_answer() and rtpengine_delete(), - detecting internally based on message type and method which one - to execute. - - It can take the same parameters as rtpengine_offer(). The flags - parameter to rtpengine_manage() can be a configuration variable - containing the flags as a string. - - Functionality: - * If INVITE with SDP, then do rtpengine_offer() - * If ACK with SDP, then do rtpengine_answer() - * If BYE or CANCEL, or called within a FAILURE_ROUTE[], then - do rtpengine_delete() - * If reply to INVITE with code >= 300 do rtpengine_delete() - * If reply with SDP to INVITE having code 1xx and 2xx, then - do rtpengine_answer() if the request had SDP or tm is not - loaded, otherwise do rtpengine_offer() - - This function can be used from ALL_ROUTES. - - Example 1.23. rtpengine_manage usage -... -rtpengine_manage(); -... - -1.5.6. rtpengine_start_recording([flags [, sock_var]]) - - This function will send a signal to the RTP proxy to record the - RTP stream on the RTP proxy. - - Meaning of the parameters is as follows: - * flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different - call than the requested one. - * sock_var(var, optional) - variable used to store the - rtpengine socket chosen for this call. - - This function can be used from any route. - - Example 1.24. rtpengine_start_recording usage -... -rtpengine_start_recording(); -... - -1.5.7. rtpengine_stop_recording([flags [, sock_var]]) - - This function will send a signal to the RTP proxy to stop - recording the RTP stream on the RTP proxy. - - Meaning of the parameters is as follows: - * flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different - call than the requested one. - * sock_var(var, optional) - variable used to store the - rtpengine socket chosen for this call. - - This function can be used from any route. - - Example 1.25. rtpengine_stop_recording usage -... -rtpengine_stop_recording(); -... - -1.5.8. rtpengine_pause_recording([flags [, sock_var]]) - - This function will send a signal to the RTP proxy to pause - recording the RTP stream on the RTP proxy. Identical to stop - recording except that it instructs the recording daemon not to - close the recording file, but instead leave it open so that - recording can later be resumed via another start recording - message. - - Meaning of the parameters is as follows: - * flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different - call than the requested one. - * sock_var(var, optional) - variable used to store the - rtpengine socket chosen for this call. - - This function can be used from any route. - - Example 1.26. rtpengine_pause_recording usage -... -rtpengine_stop_recording(); -... - -1.5.9. rtpengine_play_media(flags, [duration_spec[, sock_var[, -sockvar]]]) - - This function will start playing a media file to one of the - endpoints. - - Meaning of the parameters is as follows: - * flags(string) - a list of flags similar to the other - functions. One of the file, blob or db-id parameters is - mandatory to indicate the content of the media file to be - played. file is a common choice for specifying rtpengine to - get media from a file path, blob to take the content from - an inline string and db-id to get the content from the - database. - The direction of the media stream is controlled by the - from-tag parameter, address (media address from the SDP), - or label, if the media stream contains a label. If all of - them are missing, the media file is played to the initiator - of the SIP request, and will work similar to a ringback - tone. - * duration_spec(var, optional) - a pseudo variable that will - contain the duration of the played file. It will be set to - -1 if the duration could not be determined. - * sock_var(var, optional) - variable used to store the - rtpengine socket chosen for this call. - - This function can be used from any route. - - Example 1.27. Ringback tone using rtpengine_play_media -... -if (is_method("INVITE") && !has_totag()) - rtpengine_play_media("file=/path/to/ringback_tone_file.wav"); -... - - Example 1.28. Manage music on hold using rtpengine_play_media -... -if (is_method("INVITE") && has_totag()) { - if (is_audio_on_hold()) { - $dlg_val(on_hold) = "1"; - rtpengine_play_media("from-tag=$tt file=/path/to/moh_fil -e.wav"); - } else if ($dlg_val(on_hold) == "1") { - $dlg_val(on_hold) = "0"; - rtpengine_stop_media("from-tag=$tt"); - } -} -... - -1.5.10. rtpengine_stop_media(flags[, [sock_var[, sockvar]], -[last_frame_pos]]) - - This function will stop playing a media file previously started - by a rtpengine_play_media() call. The meaning of its parameters - is similar to the previous functions. Note that this function - should be called with similar parameters as its matching - rtpengine_play_media() call, otherwise RTPEngine will not be - able to stop media playing. - - Meaning of the parameters is as follows: - * flags(string) - a list of flags similar to the other - functions. - * last_frame_pos(var, optional) - a pseudo variable that will - contain the last frame played of the file. - - This function can be used from any route. - - Example 1.29. Ringback tone stop using rtpengine_stop_media -... -if (is_method("INVITE") && $rs == 200) - rtpengine_stop_media(); -... - - Example 1.30. Example use of the last-frame-pos parameter - rtpengine_stop_media -... -if (is_method("INVITE") && has_totag()) { - if (is_audio_on_hold()) { - $dlg_val(on_hold = "1"; - rtpengine_play_media("from-tag=$tt start-pos=$avp(last_f -rame_pos) file=/path/to/moh_file.wav"); - } else if ($dlg_val(on_hold) == "1") { - rtpengine_stop_media("from-tag=$tt", , $avp(last_frame_p -os)); - $dlg_val(on_hold = "0"); - } -} - rtpengine_stop_media(); -... - -1.5.11. rtpengine_block_media([flags[, sockvar]]) - - This function will block the media sent from one of the - endpoints. The direction to be blocked is controled by the - flags parameter, the from-tag value. - - This function can be used from any route. - - Example 1.31. Example of rtpengine_block_media usage -... -rtpengine_block_media(); -... - -1.5.12. rtpengine_unblock_media([flags[, sockvar]]) - - This function will resume/unblock the media sent from one of - the endpoints. The direction to be blocked is controled by the - flags parameter, the from-tag value. - - This function can be used from any route. - - Example 1.32. Example of rtpengine_unblock_media usage -... -rtpengine_unblock_media(); -... - -1.5.13. rtpengine_block_dtmf([flags[, sockvar]]) - - This function will block the DTMF media sent from one of the - endpoints. The direction to be blocked is controled by the - flags parameter, the from-tag value. - - This function can be used from any route. - - Example 1.33. Example of rtpengine_block_dtmf usage -... -rtpengine_block_dtmf(); -... - -1.5.14. rtpengine_unblock_dtmf([flags[, sockvar]]) - - This function will resume/unblock the DTMF media sent from one - of the endpoints. The direction to be blocked is controled by - the flags parameter, the from-tag value. - - This function can be used from any route. - - Example 1.34. Example of rtpengine_unblock_dtmf usage -... -rtpengine_unblock_dtmf(); -... - -1.5.15. rtpengine_start_forwarding([flags[, sockvar]]) - - This function will start forwarding the media to a TLS - destination specified in the tls-send-to parmeter of RTPEngine. - This function allows you to select the media stream to forward, - by specifing the from-tag of the entity you want to forward the - media. If missing, all media streams are forwarded. - - This function can be used from any route. - - Example 1.35. Example of rtpengine_start_forwarding usage -... -rtpengine_start_forwarding(); -... - -1.5.16. rtpengine_stop_forwarding([flags[, sockvar]]) - - This function will stop forwarding of the media previously - started using the rtpengine_start_forwarding() function. - - This function can be used from any route. - - Example 1.36. Example of rtpengine_stop_forwarding usage -... -rtpengine_stop_forwarding(); -... - -1.5.17. rtpengine_play_dtmf(code, [flags[, sockvar]]) - - This function instructs RTP to send the DTMF code to the - participant of the call. The code can be a digit (“0-9”) or a - special character (one of “*,#,A,B,C,D”). Additional parameters - can be configured using the flags parameter. For more - information, please consult the RTP documentation. - - NOTE: if you are planning to inject DTMF in a session, you have - to specify the inject-DTMF flag when the session is created. - - This function can be used to convert SIP INFO DTMF keys to RTP - DTMF. - - This function can be used from any route. - - Example 1.37. Example of rtpengine_play_dtmf usage -... -rtpengine_play_dtmf("0"); # send the 0 code upstream -... - -1.6. Exported Asyncronous Functions - -1.6.1. rtpengine_offer([flags[, sock_pvar[, sdp_pvar[, body]]]]) - - The asynchronous flavor of the rtpengine_offer() function. It - receives the same parameters, with the same meanings. - - Example 1.38. Example of async rtpengine_offer() usage -... -if (is_method("ACK") && has_totag() && has_body_part("application/sdp")) - { - async(rtpengine_offer(), resume_invite); -} -... -route[resume_invite] { - t_relay(); -} -... - -1.6.2. rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]]) - - The asynchronous flavor of the rtpengine_answer() function. It - receives the same parameters, with the same meanings. - - Example 1.39. Example of async rtpengine_answer() usage -... -if (is_method("ACK") && has_body_part("application/sdp")) { - # late negotiation - async(rtpengine_answer(), resume_ack); -} -... -route[resume_ack] { - t_relay(); -} -... - -1.6.3. rtpengine_delete([flags[, sock_var]]) - - The asynchronous flavor of the rtpengine_delete() function. It - receives the same parameters, with the same meanings. - - Example 1.40. Example of async rtpengine_delete() usage -... -if (is_method("BYE")) { - launch(rtpengine_delete()); -} -... - -1.7. Exported Pseudo-Variables - -1.7.1. $rtpstat - - Returns the RTP statistics from the RTP proxy. The RTP - statistics from the RTP proxy are provided as a string and it - does contain several packet counters. - - Example 1.41. $rtpstat Usage -... - append_hf("X-RTP-Statistics: $rtpstat\r\n"); -... - -1.7.2. $rtpstat(STAT)[index] - - Returnes one of the pre-fined statistics listed below: - * MOS-average - without an index, it returns the average MOS - value, expressed in an integer between 0 and 50, of all the - RTP streams involved in the call, both caller and callee. - If index is specified, it has to be one of the from-tag or - to-tag involved in the call. In this case, the variable - will return the average MOS of all the streams generated by - that endpoint with the associated tag value. If you need - more granular statistics, check the $rtpquery variable. - * jitter-average - similar behavior with MOS-average, but - returnes the average jitter. - * roundtrip-average - similar behavior with MOS-average, but - returnes the average roundtrip. - * packetloss-average - similar behavior with MOS-average, but - returnes the average packet loss. - * MOS-min - without an index, it returns the minimum MOS - value (integer value between 0 and 50) of all RTP streams - involved in the call, both caller and callee. If the index - is specified, it has the same effect as for MOS-average. - * jitter-min - similar behavior with MOS-min, but returnes - the minimum jitter of a leg/call. - * roundtrip-min - similar behavior with MOS-min, but returnes - the minimum roundtrip of a leg/call. - * packetloss-min - similar behavior with MOS-min, but - returnes the minimum packet loss of a leg/call. - * MOS-max - without an index, it returns the maximum MOS - value (integer value between 0 and 50) of all RTP streams - involved in the call, both caller and callee. If the index - is specified, it has the same effect as for MOS-average. - * jitter-max - similar behavior with MOS-max, but returnes - the maximum jitter of a leg/call. - * roundtrip-max - similar behavior with MOS-max, but returnes - the maximum roundtrip of a leg/call. - * packetloss-max - similar behavior with MOS-max, but - returnes the maximum packet loss of a leg/call. - * MOS-min-at - without an index, it returns the time in - seconds elapsed from the start of the call when the MOS - value is minimum. If the index is specified, it has the - same effect as for MOS-average. - * jitter-min-at - similar behavior with MOS-min-at, but - returnes the time when the minimum jitter was detected. - * roundtrip-min-at - similar behavior with MOS-min-at, but - returnes the time when the minimum roundtrip was detected. - * packetloss-min-at - similar behavior with MOS-min-at, but - returnes the time when the minimum packet loss of a - leg/call was detected. - * MOS-max-at - without an index, it returns the time in - seconds elapsed from the start of the call when the MOS - value is maximum. If the index is specified, it has the - same effect as for MOS-average. - * jitter-max-at - similar behavior with MOS-max-at, but - returnes the time when the maximum value of jitter was - detected. - * roundtrip-max-at - similar behavior with MOS-max-at, but - returnes the time when the maximum value of roundtrip was - detected. - * packetloss-min-at - similar behavior with MOS-max-at, but - returnes the time when the maximum packet loss of a - leg/call was detected. - - NOTE: all these statistics are computed based on the statistics - generated by RTPEngine. Some of them might not be available for - all the calls (i.e. MOS cannot be computed if the call is too - short, or if the phones do not properly report RTP statistics - over RTCP). In these cases the variable returns the NULL value. - - Example 1.42. $rtpstat(STAT) -... - xlog("Average MOS of the entire call is $rtpstat(MOS-average)\r\n"); - xlog("Average MOS of caller is $(rtpstat(MOS-average)[$ft])\r\n"); - xlog("Average MOS of callee is $(rtpstat(MOS-average)[$tt])\r\n"); - xlog("Min MOS of caller is $(rtpstat(MOS-min)[$ft]) reported at $(rt -pstat(MOS-min-at)[$ft])\r\n"); -... - -1.7.3. $rtpquery - - Does a Query command to the RTP proxy and returns the answer in - a JSON format. You can use this variable to fetch arbitrary - data from the RTP proxy such as raw statistics about the call, - or other indicators. - - You can use a $json() variable to parse its output and extract - any information from the query, such as RTP statistics, or MOS - values. - - Example 1.43. $rtpquery Usage -... - $json(reply) := $rtpquery; - xlog("Total RTP Stats: $json(reply/totals)\n"); -... - -1.8. Exported MI Functions - -1.8.1. rtpengine_enable - - Enables/disables a RTP proxy. - - Parameters: - * url - the RTP proxy url (exactly as defined in the config - file). - * enable - 1 - enable, 0 - disable the RTP proxy, 2 - put the - RTP node in probing mode. - * setid (optional) the set ID of the nodes to be updated. If - provided, only nodes in the provided set will be updated. - - NOTE: if a RTP proxy is defined multiple times (in the same or - different set), all of its instances will be enabled/disabled - IF no set ID is provided. - - Example 1.44. rtpengine_enable usage -... -## disable all rtpengines by URL -$ opensips-cli -x mi rtpengine_enable udp:192.168.2.133:8081 0 -## enable rtpengine by URL and set ID (3) -$ opensips-cli -x mi rtpengine_enable url=udp:192.168.2.133:8081 enable= -1 setid=3 -... - -1.8.2. rtpengine_show - - Displays all the RTP proxies and their information: set and - status (disabled or not, weight and recheck_ticks). - - No parameter. - - Example 1.45. rtpengine_show usage -... -$ opensips-cli -x mi rtpengine_show -... - -1.8.3. rtpengine_reload - - Reloads all rtpengine sets from the database. Used only when - the “db_url” parameter is set. - - Parameters: - * type (optional) soft - when reloading nodes from the - database, reuse any existing sockets and keep existing node - disabled state. If not provided, then all nodes and sockets - will first be torndown and then nodes will be loaded from - the database. - - No parameter. - - Example 1.46. rtpengine_reload usage -... -$ opensips-cli -x mi rtpengine_reload -$ opensips-cli -x mi rtpengine_reload type=soft -... - -1.8.4. teardown - - Terminates the SIP dialog by the SIP Call-ID given as - parameter. - - Parameters: - * callid - SIP Call-ID. - - Note this is a just a wrapper function over the “dlg_end_dlg” - MI function provided by the “dialog” module. This wrapping is - done just to make rtpengine happy when trying to terminate SIP - calls based on RTP timeouts. - - Example 1.47. teardown usage -... -$ opensips-cli -x mi teardown Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY0ZD -Q -... - -1.9. Exported Events - -1.9.1. E_RTPENGINE_NOTIFICATION - - This event is raised when a notification is received from - RTPengine. - - Parameters represent the nodes within the Json request received - from RTPengine. Common values are: - * type - identifies the type of notification (i.e. DTMF) - * callid - the callid of the call this event is triggered for - * source_tag - from tag of the call this event is triggered - for - * timestamp - timestamp when the event was triggered - - For a DTMF event received, you will also get the following - nodes: - * source_ip - the IP that triggered the DTMF - * event - the event/digit pressed - * duration - how long the digit was pressed - * volume - volume of the tone - -1.9.2. E_RTPENGINE_STATUS - - This event is raised when a RTPEngine server changes it's - status to active/inactive. - - Parameters: - * socket - the socket that identifies the RTPEngine instance. - * status - active if the RTPEngine instance responds to - probing or inactive if the instance was deactivated. - * set - the numeric id of the set this RTPEngine instance is - part of. - -Chapter 2. Frequently Asked Questions - - 2.1. - - How do I migrate from “rtpproxy” or “rtpproxy-ng” to - “rtpengine”? - - For the most part, only the names of the functions have - changed, with “rtpproxy” in each name replaced with - “rtpengine”. For example, “rtpproxy_manage()” has become - “rtpengine_manage()”. A few name duplications have also been - resolved, for example there is now a single - “rtpengine_delete()” instead of “unforce_rtp_proxy()” and the - identical “rtpproxy_destroy()”. - - The largest difference to the old module is how flags are - passed to “rtpengine_offer()”, “rtpengine_answer()”, - “rtpengine_manage()” and “rtpengine_delete()”. Instead of - having a string of single-letter flags, they now take a string - of space-separated items, with each item being either a single - token (word) or a “key=value” pair. - - For example, if you had a call “rtpproxy_offer("FRWOC+PS");”, - this would then become: -rtpengine_offer("force trust-address symmetric replace-origin replace-se -ssion-connection ICE=force RTP/SAVPF"); - - Finally, if you were using the second parameter (explicit media - address) to any of these functions, this has been replaced by - the “media-address=...” option within the first string of - flags. - - 2.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.3. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.4. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 247 139 6458 3160 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 31 17 423 595 - 3. John Burke (@john08burke) 25 17 647 102 - 4. Liviu Chircu (@liviuchircu) 20 16 91 173 - 5. Richard Fuchs 20 2 640 723 - 6. Vlad Patrascu (@rvlad-patrascu) 15 7 218 330 - 7. Norman Brandinger (@NormB) 12 10 72 18 - 8. Peter Lemenkov (@lemenkov) 11 8 29 64 - 9. Vlad Paiu (@vladpaiu) 8 1 566 94 - 10. Eric Tamme (@etamme) 7 5 42 19 - - All remaining contributors: Nick Altmann (@nikbyte), Maksym - Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Eddie Fiorentine, - Zero King (@l2dy), Norm Brandinger, Rob Gagnon (@rgagnon24), - Flavio E. Goncalves, hatee, Dan Pascu (@danpascu), Oliver - Severin Mulelid-Tynes (@olivermt). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jun 2014 - Aug 2025 - 2. Norm Brandinger May 2025 - May 2025 - 3. Norman Brandinger (@NormB) Jun 2024 - Feb 2025 - 4. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2025 - 5. Vlad Paiu (@vladpaiu) Jan 2025 - Jan 2025 - 6. hatee Dec 2024 - Dec 2024 - 7. Eddie Fiorentine Nov 2024 - Nov 2024 - 8. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 9. Liviu Chircu (@liviuchircu) Jul 2014 - May 2023 - 10. John Burke (@john08burke) Jun 2019 - Apr 2022 - - All remaining contributors: Bogdan-Andrei Iancu - (@bogdan-iancu), Nick Altmann (@nikbyte), Flavio E. Goncalves, - Zero King (@l2dy), Ovidiu Sas (@ovidiusas), Vlad Patrascu - (@rvlad-patrascu), Dan Pascu (@danpascu), Oliver Severin - Mulelid-Tynes (@olivermt), Rob Gagnon (@rgagnon24), Eric Tamme - (@etamme), Richard Fuchs. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Norm Brandinger, Razvan Crainea - (@razvancrainea), Eddie Fiorentine, Norman Brandinger (@NormB), - Liviu Chircu (@liviuchircu), John Burke (@john08burke), Nick - Altmann (@nikbyte), Flavio E. Goncalves, Peter Lemenkov - (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei - Iancu (@bogdan-iancu), Richard Fuchs. - - Documentation Copyrights: - - Copyright © 2013-2014 Sipwise GmbH - - Copyright © 2010 VoIPEmbedded Inc. - - Copyright © 2009-2014 TuTPro Inc. - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2003-2008 Sippy Software, Inc. diff --git a/modules/rtpengine/README.md b/modules/rtpengine/README.md new file mode 100644 index 00000000000..f05d5873390 --- /dev/null +++ b/modules/rtpengine/README.md @@ -0,0 +1,1529 @@ +--- +title: "rtpengine Module" +description: "This is a module that enables media streams to be proxied via an RTP proxy." +--- + +## Admin Guide + + +### Overview + + +This is a module that enables media streams to be proxied +via an RTP proxy. The only RTP proxy currently known to work +with this module is the Sipwise rtpengine +[https://github.com/sipwise/rtpengine](https://github.com/sipwise/rtpengine). +The rtpengine module is a modified version of the original +rtpproxy module using a new control protocol. The module is +designed to be a drop-in replacement for the old module from +a configuration file point of view, however due to the +incompatible control protocol, it only works with RTP proxies +which specifically support it. + + +### Multiple RTP proxy usage + + +The rtpengine module can support multiple RTP proxies for +balancing/distribution and control/selection purposes. + + +The module allows definition of several sets of rtpengines. +Load-balancing will be performed over a set and the admin has the +ability to choose what set should be used. The set is selected via +its id - the id being defined with the set. Refer to the +"[rtpengine sock](#param_rtpengine_sock)" module parameter +definition for syntax description. + + +The balancing inside a set is done automatically by the module based on +the weight of each RTP proxy from the set. + + +The selection of the set is done from script prior using +rtpengine_delete(), rtpengine_offer() or rtpengine_answer() +functions - see the rtpengine_use_set() function. + + +Another way to select the set is to define setid_avp +module parameter and assign setid to the defined avp +before calling rtpengine_offer() or rtpengine_manage() +function. If forwarding of the requests fails and +there is another branch to try, remember to unset the +avp after calling rtpengine_delete() function. + + +For backward compatibility reasons, a set with no id take by default +the id 0. Also if no set is explicitly set before +rtpengine_delete(), rtpengine_offer() or rtpengine_answer() +the 0 id set will be used. + + +> [!IMPORTANT] +> If you use multiple sets, take care and use the same set for +> both rtpengine_offer()/rtpengine_answer() and rtpengine_delete()!! +> If the set was selected using setid_avp, the avp needs to be +> set only once before rtpengine_offer() or rtpengine_manage() call. + + +The module is able to failover to a new node within a set, if a chosen +one has communication issues. Moreover, it will also failover if the node +returns one of the following errors: + + +- Parallel session limit reached +- Ran out of ports + + +You can use the [extra failover error](#func_extra_failover_error) parameter +to extend the above list. + + +Many rtpengine_* functions accept a "sock_var" parameter that +will be populated with the socket of the RTPEngine chosen for +the particular operation. The format of the data stored in +"sock_var" is: "proto:ip:port". If the "sock_var" has +been specified and it is non-NULL then it will be used to +determine the specific RTPEngine to use. Note that the socket +specified by "sock_var" must be a member of the current RTPEngine +Set context. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tm module* - (optional) if you want to +have rtpengine_manage() fully functional + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### rtpengine_sock (string) + + +Definition of socket(s) used to connect to (a set) RTP proxy. It may +specify a UNIX socket or an IPv4/IPv6 UDP socket. If the protocol part +(i.e. "udp:") is missing, the socket is treated as a +UNIX socket. + + +*Default value is "NONE" (disabled).* + + +```opensips title="Set rtpengine_sock parameter" +... +# single rtproxy +modparam("rtpengine", "rtpengine_sock", "udp:localhost:12221") +# multiple rtproxies for LB +modparam("rtpengine", "rtpengine_sock", + "udp:localhost:12221 udp:localhost:12222") +# multiple sets of multiple rtproxies +modparam("rtpengine", "rtpengine_sock", + "1 == udp:localhost:12221 udp:localhost:12222") +modparam("rtpengine", "rtpengine_sock", + "2 == udp:localhost:12225") +... +``` + + +#### rtpengine_disable_tout (integer) + + +Once an RTP proxy was found unreachable and marked as disabled, the rtpengine +module will not attempt to establish communication to that RTP proxy for +rtpengine_disable_tout seconds. + + +*Default value is "60".* + + +```opensips title="Set rtpengine_disable_tout parameter" +... +modparam("rtpengine", "rtpengine_disable_tout", 20) +... +``` + + +#### rtpengine_tout (integer) + + +Timeout value in waiting for reply from RTP proxy. + + +*Default value is "1".* + + +```opensips title="Set rtpengine_tout parameter" +... +modparam("rtpengine", "rtpengine_tout", 2) +... +``` + + +#### rtpengine_retr (integer) + + +How many times the module should retry to send and receive after +timeout was generated. + + +*Default value is "5".* + + +```opensips title="Set rtpengine_retr parameter" +... +modparam("rtpengine", "rtpengine_retr", 2) +... +``` + + +#### rtpengine_timer_interval (integer) + + +Frequency to scan rtpengine sets for disabled node probing. Probing is done +outside the SIP processing context and in a separate timer routine. Disabled nodes +are probed for re-enablement after rtpengine_disable_tout seconds. Setting this value +too high can lead to unexpectedly large disabled interval as the max interval +before probing is (rtpengine_timer_interval + rtpengine_disable_tout) seconds. + + +Default value is "5". + + +```opensips title="Set rtpengine_timer_interval parameter" +... +modparam("rtpengine", "rtpengine_timer_interval", 1) +... +``` + + +#### notification_sock (string) + + +An UDP socket formatted as *IP:port* +that indicates the listening IP and port OpenSIPS will bind for to +receive notifications (such as DTMF events) from RTPengine. + + +Every notification received from RTPengine will trigger an +*E_RTPENGINE_NOTIFICATION* event. + + +*Default value is "none" - notifications are ignored.* + + +```opensips title="Set notification_sock parameter" +... +modparam("rtpengine", "notification_sock", "127.0.0.1:9999") +... +``` + + +#### extra_id_pv (string) + + +The parameter sets the PV definition to use when the "via-branch=extra" +option is used on the rtpengine_delete(), rtpengine_offer(), +rtpengine_answer() or rtpengine_manage() commands. + + +Default is empty, the "via-branch=extra" option may not be used then. + + +```opensips title="Set extra_id_pv parameter" +... +modparam("rtpengine", "extra_id_pv", "$avp(extra_id)") +... +``` + + +#### setid_avp (string) + + +The parameter defines an AVP that, if set, +determines which RTP proxy set +rtpengine_offer(), rtpengine_answer(), +rtpengine_delete(), and rtpengine_manage() +functions use. + + +There is no default value. + + +```opensips title="Set setid_avp parameter" +... +modparam("rtpengine", "setid_avp", "$avp(setid)") +... +``` + + +#### error_pv (string) + + +The parameter defines a variable that shall be populated +by RTP when one of the rtpengine_* functions fail. + + +There is no default value. + + +```opensips title="Set error_pv parameter" +... +modparam("rtpengine", "error_pv", "$var(rtpengine_error)") +... +``` + + +#### db_url (string) + + +Database URL, used to load RTPEngines sockets +from db, instead of specifying them in the +script ([rtpengine sock](#param_rtpengine_sock) +module parameter). + + +Default value is "NULL", no database +is used. + + +```opensips title="Set db_url parameter" +... +modparam("rtpengine", "db_url", + "mysql://opensips:opensipsrw@localhost/opensips") +... +``` + + +#### db_table (string) + + +The table where the RTPEngines sockets are stored. +Used when Database URL is provisioned. + + +Default value is "rtpengine". + + +```opensips title="Set db_table parameter" +... +modparam("rtpengine", "db_table", "rtpengine_new") +... +``` + + +#### socket_column (string) + + +The name of the rtpengine socket column in the database table. + + +Default value is "socket". + + +```opensips title="Set socket_column parameter" +... +modparam("rtpengine", "socket_column", "sock") +... +``` + + +#### set_column (string) + + +The name of the rtpengine set column in the database table. + + +Default value is "set_id". + + +```opensips title="Set set_column parameter" +... +modparam("rtpengine", "set_column", "set_new") +... +``` + + +#### ping_enabled (integer) + + +This parameter indicates whether probing should be done for +enabled nodes as well. + + +If this parameter is set, each enabled node is pinged +every [rtpengine timer interval](#param_rtpengine_timer_interval) seconds, unless +there was any communication with the node since the previous interval. + + +*Default value is "0" (disabled).* + + +```opensips title="Set ping_enabled parameter" +... +modparam("rtpengine", "ping_enabled", yes) +... +``` + + +### Exported Functions + + +#### rtpengine_use_set(setid) + + +Sets the ID of the RTP proxy set to be used for the next +rtpengine_delete(), rtpengine_offer(), rtpengine_answer() +or rtpengine_manage() command. The parameter is an integer. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE. + + +```opensips title="rtpengine_use_set usage" +... +rtpengine_use_set(2); +rtpengine_offer(); +... +``` + + +#### rtpengine_offer([flags[, sock_var[, sdp_pvar[, body]]]]) + + +Rewrites SDP body to ensure that media is passed through +an RTP proxy. To be invoked +on INVITE for the cases the SDPs are in INVITE and 200 OK and on 200 OK +when SDPs are in 200 OK and ACK. + + +Meaning of the parameters is as follows: + + +- *flags(string, optional)* - flags to turn on some features. +The "flags" string is a list of space-separated items. Each item +is either an individual token, or a token in "key=value" format. The +possible tokens are described below. +When passing an option that OpenSIPS is not aware of, it will be +blindly sent to the rtpengine daemon to be processed. + + - *via-branch=...* - Include the "branch" +value of one of the "Via" headers in the request to the +RTP proxy. Possible values are: +"1" - use the first "Via" header; +"2" - use the second "Via" header; +"auto" - use the first "Via" header if this is +a request, or the second one if this is a reply; +"extra" - don't take the value from a header, but instead use +the value of the "[extra id pv](#param_extra_id_pv)" variable. +This can be used to create one media session per branch +on the RTP proxy. When sending a subsequent "delete" command to +the RTP proxy, you can then stop just the session for a specific branch when +passing the flag '1' or '2' in the "rtpengine_delete", or stop +all sessions for a call when not passing one of those two flags there. This is +especially useful if you have serially forked call scenarios where the RTP proxy +gets an "offer" command for a new branch, and then a +"delete" command for the previous branch, which would otherwise +delete the full call, breaking the subsequent "answer" for the +new branch. *This flag is only supported by the Sipwise rtpengine +RTP proxy at the moment!* + - *via-branch-param=...* - provide a custom value for the +*via-branch* param. + - *call-id* - provide a custom Call-ID for the session. If +missing, the Call-Id of the request/reply is used. + - *from-tag* - provide a custom from-tag for the session. If +missing, the from-tag request is used. + - *to-tag* - provide a custom to-tag of the session. If +missing, the to-tag of the request/reply is used, is present. + - *asymmetric* - flags that UA from which message is +received doesn't support symmetric RTP. (automatically sets the 'r' flag) + - *force-answer* - force "answer", that is, +only rewrite SDP when corresponding session already exists +in the RTP proxy. By default is on when the session is to be +completed. + - *in-iface=..., out-iface=...* - these flags specify the direction +the SIP message. These flags only make sense when the RTP proxy is running +in bridge mode. "in-iface" should indicate the proxy's inbound +interface, and "out-iface" corresponds to the RTP proxy's +outbound interface. You always have to specify two flags to define +the incoming network and the outgoing network. For example, +"in-iface=internal out-iface=external" should be +used for SIP message received from the local interface and sent out on the +external interface. + - *internal, external* - these the old flags used to +specify the direction of call. They are now obsolate, being replaced by the +"in-iface=internal out-iface=external" configuration. + - *auto-bridge* - this flag an alternative to the +"internal" and "external" flags +in order to do automatic bridging between IPv4 on the +"internal network" and IPv6 on the "external network". Instead of +explicitly instructing the RTP proxy to select a particular address +family, the distinction is done by the given IP in the SDP body by +the RTP proxy itself. Not supported by Sipwise rtpengine. + - *address-family=...* - instructs the RTP proxy that the +recipient of this SDP body expects to see addresses of a particular family. +Possible values are "IP4" and "IP6". For example, +if the SDP body contains IPv4 addresses but the recipient only speaks IPv6, +you would use "address-family=IP6" to bridge between the two +address families. +Sipwise rtpengine remembers the address family preference of each party after +it has seen an SDP body from them. This means that normally it is only +necessary to explicitly specify the address family in the "offer", +but not in the "answer". +Note: Please note, that this will only work properly with non-dual-stack user-agents or with +dual-stack clients according to RFC6157 (which suggest ICE for Dual-Stack implementations). +This short-cut will not work properly with RFC4091 (ANAT) compatible clients, which suggests +having different m-lines with different IP-protocols grouped together. + - *received-from=...* - sets the address from which SIP packet with SDP received. +This flag always set automatically, don't use it until you have a reason for that. + - *force* - instructs the RTP proxy to ignore marks +inserted by another RTP proxy in transit to indicate that the +session is already goes through another proxy. Allows creating +a chain of proxies. Not supported and ignored by Sipwise rtpengine. + - *trust-address* - flags that IP address in SDP should +be trusted. Without this flag, the RTP proxy ignores address in +the SDP and uses source address of the SIP message as media +address which is passed to the RTP proxy. From rtpengine 3.8 this is the default behaviour. + - *SIP-source-address* - the opposite of trust-address. +Restores the old default behaviour of ignoring endppoint of the addresses in the SDP body. + - *replace-origin* - flags that IP from the origin +description (o=) should be also changed. + - *replace-session-connection* - flags to change the session-level +SDP connection (c=) IP if media description also includes +connection information. + - *replace-zero-address* - flags to replace zero address with real address. +Using a zero endpoint address is an obsolete way to signal a muted or sendonly stream. +Streams with zero addresses are normally flagged as sendonly and the zero address in the SDP +is passed through. + - *symmetric* - flags that for the UA from which +message is received, support symmetric RTP must be forced. You do not +need to explicitly specify this value, as it is the default, and the +behavior is only changed when the *asymmetric* is used. + - *repacketize=NN* - requests the RTP proxy to perform +re-packetization of RTP traffic coming from the UA which +has sent the current message to increase or decrease payload +size per each RTP packet forwarded if possible. The NN is the +target payload size in ms, for the most codecs its value should +be in 10ms increments, however for some codecs the increment +could differ (e.g. 30ms for GSM or 20ms for G.723). The +RTP proxy would select the closest value supported by the codec. +This feature could be used for significantly reducing bandwith +overhead for low bitrate codecs, for example with G.729 going +from 10ms to 100ms saves two thirds of the network bandwith. +Not supported by Sipwise rtpengine. + - *loop-protect* - flag that instructs RTP to +avoid rewriting the SDP when looping the same message. + - *ICE=...* - controls the RTP proxy's behaviour +regarding ICE attributes within the SDP body. Possible values +are: "force" - +discard any ICE attributes already present in the SDP body +and then generate and insert new ICE data, leaving itself +as the *only* ICE candidates; +"remove" instructs the RTP proxy to discard +any ICE attributes and not insert any new ones into the SDP. +The default (if no "ICE=..." is given at all), +new ICE data will only be generated +if no ICE was present in the SDP originally; otherwise +the RTP proxy will only insert itself as an +*additional* ICE candidate. Other +SDP substitutions (c=, m=, etc) are unaffected by this flag. + - *RTP, SRTP, AVP, AVPF* - These flags control the RTP +transport protocol that should be used towards the recipient of +the SDP. If none of them are specified, the protocol given in +the SDP is left untouched. Otherwise, the "SRTP" flag indicates that +SRTP should be used, while "RTP" indicates that SRTP should not be used. +"AVPF" indicates that the advanced RTCP profile with feedback messages +should be used, and "AVP" indicates that the regular RTCP profile +should be used. See also the next set of flags below. + - *RTP/AVP, RTP/SAVP, RTP/AVPF, RTP/SAVPF* - these serve as +an alternative, more explicit way to select between the different RTP protocols +and profiles supported by the RTP proxy. For example, giving the flag +"RTP/SAVPF" has the same effect as giving the two flags +"SRTP AVPF". + - *to-tag* - force inclusion of the "To" tag. +Normally, the "To" tag is always included when present, except +for "delete" messages. Including the "To" tag in +a "delete" messages allows you to be more selective about which +dialogues within a call are being torn down. + - *to-tag=...* - use the specified string as "To" +tag instead of the actual "To" tag from the SIP message, and +force inclusion of the tag in the message as per above. + - *from-tag=...* - use the specified string as +"From" tag instead of the actual "From" +tag from the SIP message. + - *call-id=...* - use the specified string as +"Call-ID" instead of the actual "Call-ID" +from the SIP message. + - *rtcp-mux-demux* - if rtcp-mux (RFC 5761) was +offered, make the RTP proxy accept the offer, but not offer it to the +recipient of this message. + - *rtcp-mux-reject* - if rtcp-mux was offered, make the +RTP proxy reject the offer, but still offer it to the recipient. Can be +combined with "rtcp-mux-offer" to always offer it. + - *rtcp-mux-offer* - make the RTP proxy offer rtcp-mux +to the recipient of this message, regardless of whether it was offered +originally or not. + - *rtcp-mux-require* - Similar to offer but pretends that +the client has accepted rtcp-mux. This breaks RFC 5761 and will not advertise +seperate RTCP ports. This option is necessary for WebRTC clients. + - *rtcp-mux-accept* - if rtcp-mux was offered, make the +RTP proxy accept the offer and also offer it to the recipient of this +message. Can be combined with "rtcp-mux-offer" to always offer it. + - *media-address=...* - force a particular media address to +be used in the SDP body. Address family is detected automatically. + - *record-call=yes/no* - indicates whether rtpengine should +record the call or not. When using this parameter, you may pass further +information in the "metadata". + - *transcode-CODEC* - used only for offer, indicates that +rtpengine should transcode the CODEC towards the B-side. Example: +*transcode-PCMA* will present to the B-side the PCMA codec. + - *codec-strip-CODEC* - used only for offer, indicates that +the A-side of the call will not end up talking CODEC. Example: +*codec-strip-PCMA* will prevent the A-side from receiving +the PCMA codec. + - *codec-mask-CODEC* - used only for offer, indicates that +the A-side will use the CODEC, but it will not be presented to the B-side. Example: +*codec-mask-PCMA* will make the A-side receive the PCMA codec, +but B-side will use something else. +- *sock_var(var, optional)* - variable used to store the rtpengine +socket chosen for this call. +- *sdp_var(var, optional)* - variable used to store the full SDP +received from rtpengine. You can perform any additional changes on this +string. *Important:* when providing this variable, the +message body is no longer changed, so you have to manually replace it!. +- *body(string, optional)* - used to provide a specific body +to the rtpengine_* function. If this parameter is missing the body of +the current message is used. + + +This function can be used from ALL_ROUTES. + + +```opensips title="rtpengine_offer usage" +route { +... + if (is_method("INVITE")) { + if (has_body("application/sdp")) { + if (rtpengine_offer()) + t_on_reply("1"); + } else { + t_on_reply("2"); + } + } + if (is_method("ACK") && has_body("application/sdp")) + rtpengine_answer(); +... +} + +onreply_route[1] +{ +... + if (has_body("application/sdp")) + rtpengine_answer(); +... +} + +onreply_route[2] +{ +... + if (has_body("application/sdp")) + rtpengine_offer(); +... +} +``` + + +```opensips title="rtpengine_offer usage with body replace" +... +if (rtpengine_offer(, $var(socket), $var(body), $rb)) { + xlog("Used rtpengine $var(socket)\n"); + # make all the changes on the resulted SDP in $var(body) + ... + remove_body_part(); + add_body_part($var(body), "application/sdp"); +} +... +``` + + +```opensips title="rtpengine_offer usage with call recording" +... +$var(rtpengine_flags) = $var(rtpengine_flags) + " record-call=yes"; + +$json(recording_keys) := "{}"; +$json(recording_keys/callId) = $ci; +$json(recording_keys/fromUser) = $dlg_val(recording_from_user); +$json(recording_keys/fromDomain) = $dlg_val(recording_from_domain); +$json(recording_keys/fromTag) = $dlg_val(recording_from_tag); +$json(recording_keys/toUser) = $dlg_val(recording_to_user); +$json(recording_keys/toDomain) = $dlg_val(recording_to_domain); + +$var(rtpengine_flags) = $var(rtpengine_flags) + " metadata=" + $(json(recording_keys){s.encode.hexa}); +rtpengine_offer($var(rtpengine_flags)); +... +``` + + +```opensips title="rtpengine_offer usage for transcoding" +... +# Goal: make A-side talk PCMA and B-side talk opus +# * do not present PCMA to B-side: codec-mask-PCMA, but use it on A-side +# * do not use opus for A-side: codec-strip-opus +# * offer opus to B-side: transcode-opus +rtpengine_offer("... codec-mask-PCMA codec-strip-opus transcode-opus ..."); +... +``` + + +##### extra_failover_error (string) + + +Contains a (XDB) regular expression that can be +used to match an error received from a RTPEngine node. If matched +the module tries to use a new node to handle the affected command. + + +This parameter can be used to extend the list +(see [failover](#param_failover) of errors the module +implicitely fails over. + + +> [!NOTE] +> Each declaration will define a single +> expression/matching rule. If you want to define multiple rules, you +> need to define the parameter multiple times. + + +Default value is empty, no extra errors are being used. + + +```opensips title="Set extra_failover_error parameter" +... +modparam("rtpengine", "extra_failover_error", "Parallel session limit reached") +... +``` + + +#### rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]]) + + +Rewrites SDP body to ensure that media is passed through +an RTP proxy. To be invoked +on 200 OK for the cases the SDPs are in INVITE and 200 OK and on ACK +when SDPs are in 200 OK and ACK. + + +See rtpengine_offer() function description above for the meaning of the +parameters. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +See rtpengine_offer() function example above for examples. + + +#### rtpengine_delete([flags[, sock_var]]) + + +Tears down the RTPEngine session for the current call. + + +See rtpengine_offer() function description above for the meaning of the +parameters. Note that not all flags make sense for a "delete". + + +This function can be used from ALL_ROUTES. + + +```opensips title="rtpengine_delete usage" +... +rtpengine_delete(); +... +``` + + +#### rtpengine_manage([flags[, sock_var[, sdp_var[, body]]]]) + + +Manage the RTPEngine session - it combines the functionality of +rtpengine_offer(), rtpengine_answer() and rtpengine_delete(), detecting +internally based on message type and method which one to execute. + + +It can take the same parameters as `rtpengine_offer().` +The flags parameter to rtpengine_manage() can be a configuration variable +containing the flags as a string. + + +Functionality: + + +- If INVITE with SDP, then do `rtpengine_offer()` +- If ACK with SDP, then do `rtpengine_answer()` +- If BYE or CANCEL, or called within a FAILURE_ROUTE[], then do `rtpengine_delete()` +- If reply to INVITE with code >= 300 do `rtpengine_delete()` +- If reply with SDP to INVITE having code 1xx and 2xx, then +do `rtpengine_answer()` if the request had SDP or tm is not loaded, +otherwise do `rtpengine_offer()` + + +This function can be used from ALL_ROUTES. + + +```opensips title="rtpengine_manage usage" +... +rtpengine_manage(); +... +``` + + +#### rtpengine_start_recording([flags [, sock_var]]) + + +This function will send a signal to the RTP proxy to record +the RTP stream on the RTP proxy. + + +Meaning of the parameters is as follows: + + +- *flags(string, optional)* - flags used to change the behavior +of the recorder. An importat value to set is the *call-id* +value, which can be used to start recording a different call than the requested one. +- *sock_var(var, optional)* - variable used to store the rtpengine +socket chosen for this call. + + +This function can be used from any route. + + +```opensips title="rtpengine_start_recording usage" +... +rtpengine_start_recording(); +... +``` + + +#### rtpengine_stop_recording([flags [, sock_var]]) + + +This function will send a signal to the RTP proxy to stop +recording the RTP stream on the RTP proxy. + + +Meaning of the parameters is as follows: + + +- *flags(string, optional)* - flags used to change the behavior +of the recorder. An importat value to set is the *call-id* +value, which can be used to start recording a different call than the requested one. +- *sock_var(var, optional)* - variable used to store the rtpengine +socket chosen for this call. + + +This function can be used from any route. + + +```opensips title="rtpengine_stop_recording usage" +... +rtpengine_stop_recording(); +... + +``` + + +#### rtpengine_pause_recording([flags [, sock_var]]) + + +This function will send a signal to the RTP proxy to pause +recording the RTP stream on the RTP proxy. Identical to stop recording except that it +instructs the recording daemon not to close the recording file, but instead leave it open +so that recording can later be resumed via another start recording message. + + +Meaning of the parameters is as follows: + + +- *flags(string, optional)* - flags used to change the behavior +of the recorder. An importat value to set is the *call-id* +value, which can be used to start recording a different call than the requested one. +- *sock_var(var, optional)* - variable used to store the rtpengine +socket chosen for this call. + + +This function can be used from any route. + + +```opensips title="rtpengine_pause_recording usage" +... +rtpengine_stop_recording(); +... + +``` + + +#### rtpengine_play_media(flags, [duration_spec[, sock_var[, sockvar]]]) + + +This function will start playing a media file to one of the endpoints. + + +Meaning of the parameters is as follows: + + +- *flags(string)* - a list of flags similar to +the other functions. One of the *file*, +*blob* or *db-id* parameters +is mandatory to indicate the content of the media file to be played. +*file* is a common choice for specifying rtpengine +to get media from a file path, *blob* to take +the content from an inline string and *db-id* to +get the content from the database. +The direction of the media stream is controlled by the +*from-tag* parameter, *address* +(media address from the SDP), or *label*, if the +media stream contains a label. If all of them are missing, the media +file is played to the initiator of the SIP request, and will work similar +to a ringback tone. +- *duration_spec(var, optional)* - a pseudo variable that +will contain the duration of the played file. It will be set to +*-1* if the duration could not be determined. +- *sock_var(var, optional)* - variable used to store the rtpengine +socket chosen for this call. + + +This function can be used from any route. + + +```opensips title="Ringback tone using rtpengine_play_media" +... +if (is_method("INVITE") && !has_totag()) + rtpengine_play_media("file=/path/to/ringback_tone_file.wav"); +... + +``` + + +```opensips title="Manage music on hold using rtpengine_play_media" +... +if (is_method("INVITE") && has_totag()) { + if (is_audio_on_hold()) { + $dlg_val(on_hold) = "1"; + rtpengine_play_media("from-tag=$tt file=/path/to/moh_file.wav"); + } else if ($dlg_val(on_hold) == "1") { + $dlg_val(on_hold) = "0"; + rtpengine_stop_media("from-tag=$tt"); + } +} +... + +``` + + +#### rtpengine_stop_media(flags[, [sock_var[, sockvar]], [last_frame_pos]]) + + +This function will stop playing a media file previously started +by a `rtpengine_play_media()` call. The meaning +of its parameters is similar to the previous functions. Note that this +function should be called with similar parameters as its matching +`rtpengine_play_media()` call, otherwise +RTPEngine will not be able to stop media playing. + + +Meaning of the parameters is as follows: + + +- *flags(string)* - a list of flags similar to +the other functions. +- *last_frame_pos(var, optional)* - a pseudo variable that +will contain the last frame played of the file. + + +This function can be used from any route. + + +```opensips title="Ringback tone stop using rtpengine_stop_media" +... +if (is_method("INVITE") && $rs == 200) + rtpengine_stop_media(); +... + +``` + + +```opensips title="Example use of the last-frame-pos parameter rtpengine_stop_media" +... +if (is_method("INVITE") && has_totag()) { + if (is_audio_on_hold()) { + $dlg_val(on_hold = "1"; + rtpengine_play_media("from-tag=$tt start-pos=$avp(last_frame_pos) file=/path/to/moh_file.wav"); + } else if ($dlg_val(on_hold) == "1") { + rtpengine_stop_media("from-tag=$tt", , $avp(last_frame_pos)); + $dlg_val(on_hold = "0"); + } +} + rtpengine_stop_media(); +... + +``` + + +#### rtpengine_block_media([flags[, sockvar]]) + + +This function will block the media sent from one of the endpoints. +The direction to be blocked is controled by the *flags* +parameter, the *from-tag* value. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_block_media usage" +... +rtpengine_block_media(); +... + +``` + + +#### rtpengine_unblock_media([flags[, sockvar]]) + + +This function will resume/unblock the media sent from one of the endpoints. +The direction to be blocked is controled by the *flags* +parameter, the *from-tag* value. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_unblock_media usage" +... +rtpengine_unblock_media(); +... + +``` + + +#### rtpengine_block_dtmf([flags[, sockvar]]) + + +This function will block the DTMF media sent from one of the endpoints. +The direction to be blocked is controled by the *flags* +parameter, the *from-tag* value. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_block_dtmf usage" +... +rtpengine_block_dtmf(); +... + +``` + + +#### rtpengine_unblock_dtmf([flags[, sockvar]]) + + +This function will resume/unblock the DTMF media sent from one of the endpoints. +The direction to be blocked is controled by the *flags* +parameter, the *from-tag* value. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_unblock_dtmf usage" +... +rtpengine_unblock_dtmf(); +... + +``` + + +#### rtpengine_start_forwarding([flags[, sockvar]]) + + +This function will start forwarding the media to a TLS destination specified +in the *tls-send-to* parmeter of RTPEngine. This function allows you +to select the media stream to forward, by specifing the *from-tag* +of the entity you want to forward the media. If missing, all media streams are forwarded. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_start_forwarding usage" +... +rtpengine_start_forwarding(); +... + +``` + + +#### rtpengine_stop_forwarding([flags[, sockvar]]) + + +This function will stop forwarding of the media previously started using the +*rtpengine_start_forwarding()* function. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_stop_forwarding usage" +... +rtpengine_stop_forwarding(); +... + +``` + + +#### rtpengine_play_dtmf(code, [flags[, sockvar]]) + + +This function instructs RTP to send the DTMF *code* +to the participant of the call. The *code* can be a digit +("0-9") or a special character (one of "*,#,A,B,C,D"). +Additional parameters can be configured using the *flags* +parameter. For more information, please consult the RTP documentation. + + +> [!NOTE] +> If you are planning to inject DTMF in a session, +> you have to specify the *inject-DTMF* flag when the +> session is created. + + +This function can be used to convert SIP INFO DTMF keys to RTP DTMF. + + +This function can be used from any route. + + +```opensips title="Example of rtpengine_play_dtmf usage" +... +rtpengine_play_dtmf("0"); # send the 0 code upstream +... +``` + + +### Exported Asynchronous Functions + + +#### rtpengine_offer([flags[, sock_pvar[, sdp_pvar[, body]]]]) + + +The asynchronous flavor of the [rtpengine offer](#func_rtpengine_offer) +function. It receives the same parameters, with the same meanings. + + +```opensips title="Example of async rtpengine_offer() usage" +... +if (is_method("ACK") && has_totag() && has_body_part("application/sdp")) { + async(rtpengine_offer(), resume_invite); +} +... +route[resume_invite] { + t_relay(); +} +... +``` + + +#### rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]]) + + +The asynchronous flavor of the [rtpengine answer](#func_rtpengine_answer) +function. It receives the same parameters, with the same meanings. + + +```opensips title="Example of async rtpengine_answer() usage" +... +if (is_method("ACK") && has_body_part("application/sdp")) { + # late negotiation + async(rtpengine_answer(), resume_ack); +} +... +route[resume_ack] { + t_relay(); +} +... +``` + + +#### rtpengine_delete([flags[, sock_var]]) + + +The asynchronous flavor of the [rtpengine delete](#func_rtpengine_delete) +function. It receives the same parameters, with the same meanings. + + +```opensips title="Example of async rtpengine_delete() usage" +... +if (is_method("BYE")) { + launch(rtpengine_delete()); +} +... +``` + + +### Exported Pseudo-Variables + + +#### $rtpstat + + +Returns the RTP statistics from the RTP proxy. The RTP statistics from the RTP proxy +are provided as a string and it does contain several packet counters. + + +```opensips title="$rtpstat Usage" +... + append_hf("X-RTP-Statistics: $rtpstat\r\n"); +... +``` + + +#### $rtpstat(STAT)[index] + + +Returnes one of the pre-fined statistics listed below: + + +- *MOS-average* - without an index, it returns the average +MOS value, expressed in an integer between 0 and 50, of all the RTP streams +involved in the call, both caller and callee. If index is specified, it has +to be one of the *from-tag* +or *to-tag* involved in the call. In this case, the variable +will return the average MOS of all the streams generated by that endpoint +with the associated tag value. If you need more granular statistics, check +the *$rtpquery* variable. +- *jitter-average* - similar behavior with +*MOS-average*, but returnes the average jitter. +- *roundtrip-average* - similar behavior with +*MOS-average*, but returnes the average roundtrip. +- *packetloss-average* - similar behavior with +*MOS-average*, but returnes the average packet loss. +- *MOS-min* - without an index, it returns the minimum +MOS value (integer value between 0 and 50) of all RTP streams involved in the +call, both caller and callee. +If the index is specified, it has the same effect as for +*MOS-average*. +- *jitter-min* - similar behavior with +*MOS-min*, but returnes the minimum jitter of a leg/call. +- *roundtrip-min* - similar behavior with +*MOS-min*, but returnes the minimum roundtrip of a leg/call. +- *packetloss-min* - similar behavior with +*MOS-min*, but returnes the minimum packet loss of a leg/call. +- *MOS-max* - without an index, it returns the maximum +MOS value (integer value between 0 and 50) of all RTP streams involved in the +call, both caller and callee. +If the index is specified, it has the same effect as for +*MOS-average*. +- *jitter-max* - similar behavior with +*MOS-max*, but returnes the maximum jitter of a leg/call. +- *roundtrip-max* - similar behavior with +*MOS-max*, but returnes the maximum roundtrip of a leg/call. +- *packetloss-max* - similar behavior with +*MOS-max*, but returnes the maximum packet loss of a leg/call. +- *MOS-min-at* - without an index, it returns the time in +seconds elapsed from the start of the call when the MOS value is minimum. +If the index is specified, it has the same effect as for +*MOS-average*. +- *jitter-min-at* - similar behavior with +*MOS-min-at*, but returnes the time when the minimum +jitter was detected. +- *roundtrip-min-at* - similar behavior with +*MOS-min-at*, but returnes the time when the minimum +roundtrip was detected. +- *packetloss-min-at* - similar behavior with +*MOS-min-at*, but returnes the time when the minimum +packet loss of a leg/call was detected. +- *MOS-max-at* - without an index, it returns the time in +seconds elapsed from the start of the call when the MOS value is maximum. +If the index is specified, it has the same effect as for +*MOS-average*. +- *jitter-max-at* - similar behavior with +*MOS-max-at*, but returnes the time when the maximum +value of jitter was detected. +- *roundtrip-max-at* - similar behavior with +*MOS-max-at*, but returnes the time when the maximum +value of roundtrip was detected. +- *packetloss-min-at* - similar behavior with +*MOS-max-at*, but returnes the time when the maximum +packet loss of a leg/call was detected. + + +> [!NOTE] +> All these statistics are computed based on the +> statistics generated by RTPEngine. Some of them might not be available for +> all the calls (i.e. MOS cannot be computed if the call is too short, or if +> the phones do not properly report RTP statistics over RTCP). In these cases +> the variable returns the *NULL* value. + + +```opensips title="$rtpstat(STAT)" +... + xlog("Average MOS of the entire call is $rtpstat(MOS-average)\r\n"); + xlog("Average MOS of caller is $(rtpstat(MOS-average)[$ft])\r\n"); + xlog("Average MOS of callee is $(rtpstat(MOS-average)[$tt])\r\n"); + xlog("Min MOS of caller is $(rtpstat(MOS-min)[$ft]) reported at $(rtpstat(MOS-min-at)[$ft])\r\n"); +... +``` + + +#### $rtpquery + + +Does a Query command to the RTP proxy and returns the answer in a JSON format. +You can use this variable to fetch arbitrary data from the RTP proxy such as +raw statistics about the call, or other indicators. + + +You can use a *$json()* variable to parse +its output and extract any information from the query, such as +RTP statistics, or MOS values. + + +```opensips title="$rtpquery Usage" +... + $json(reply) := $rtpquery; + xlog("Total RTP Stats: $json(reply/totals)\n"); +... +``` + + +### Exported MI Functions + + +#### rtpengine_enable + + +Enables/disables a RTP proxy. + + +Parameters: + + +- *url* - the RTP proxy url (exactly as +defined in the config file). +- *enable* - 1 - enable, 0 - disable the RTP proxy, 2 - put the RTP node in probing mode. +- *setid* (optional) the set ID of the nodes to be updated. If provided, only nodes in the provided set will be updated. + + +> [!NOTE] +> If a RTP proxy is defined multiple times (in the same or +> different set), all of its instances will be enabled/disabled IF no set ID is provided. + + +```bash title="rtpengine_enable usage" +... +## disable all rtpengines by URL +$ opensips-cli -x mi rtpengine_enable udp:192.168.2.133:8081 0 +## enable rtpengine by URL and set ID (3) +$ opensips-cli -x mi rtpengine_enable url=udp:192.168.2.133:8081 enable=1 setid=3 +... +``` + + +#### rtpengine_show + + +Displays all the RTP proxies and their information: set and +status (disabled or not, weight and recheck_ticks). + + +No parameter. + + +```bash title="rtpengine_show usage" +... +$ opensips-cli -x mi rtpengine_show +... +``` + + +#### rtpengine_reload + + +Reloads all rtpengine sets from the database. Used only when the +"[db url](#param_db_url)" parameter is set. + + +Parameters: + + +- *type* (optional) soft - when reloading nodes +from the database, reuse any existing sockets and keep existing +node disabled state. If not provided, then all nodes and sockets +will first be torndown and then nodes will be loaded from the database. + + +No parameter. + + +```bash title="rtpengine_reload usage" +... +$ opensips-cli -x mi rtpengine_reload +$ opensips-cli -x mi rtpengine_reload type=soft +... +``` + + +#### teardown + + +Terminates the SIP dialog by the SIP Call-ID given as parameter. + + +Parameters: + + +- *callid* - SIP Call-ID. + + +Note this is a just a wrapper function over the +"dlg_end_dlg" MI function provided by the +"dialog" module. This wrapping is done just to +make rtpengine happy when trying to terminate SIP calls based on +RTP timeouts. + + +```bash title="teardown usage" +... +$ opensips-cli -x mi teardown Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY0ZDQ +... +``` + + +### Exported Events + + +#### E_RTPENGINE_NOTIFICATION + + +This event is raised when a notification is received from RTPengine. + + +Parameters represent the nodes within the Json request received from RTPengine. +Common values are: + + +- *type* - identifies the type of notification (i.e. DTMF) +- *callid* - the callid of the call this event is triggered for +- *source_tag* - from tag of the call this event is triggered for +- *timestamp* - timestamp when the event was triggered + + +For a DTMF event received, you will also get the following nodes: + + +- *source_ip* - the IP that triggered the DTMF +- *event* - the event/digit pressed +- *duration* - how long the digit was pressed +- *volume* - volume of the tone + + +#### E_RTPENGINE_STATUS + + +This event is raised when a RTPEngine server changes it's status to +active/inactive. + + +Parameters: + + +- *socket* - the socket that identifies the +RTPEngine instance. +- *status* - *active* if +the RTPEngine instance responds to probing or +*inactive* if the instance was deactivated. +- *set* - the numeric id of the set +this RTPEngine instance is part of. + + +## Frequently Asked Questions + + +**Q: How do I migrate from "rtpproxy" or "rtpproxy-ng" to +"rtpengine"?** + + +For the most part, only the names of the functions have changed, with +"rtpproxy" in each name replaced with "rtpengine". +For example, "rtpproxy_manage()" has become +"rtpengine_manage()". A few name duplications have also been resolved, +for example there is now a single "rtpengine_delete()" instead of +"unforce_rtp_proxy()" and the identical "rtpproxy_destroy()". + +The largest difference to the old module is how flags are passed to +"rtpengine_offer()", "rtpengine_answer()", +"rtpengine_manage()" and "rtpengine_delete()". Instead of +having a string of single-letter flags, they now take a string of space-separated +items, with each item being either a single token (word) or a "key=value" +pair. + +For example, if you had a call "rtpproxy_offer("FRWOC+PS");", this would +then become: + +Finally, if you were using the second parameter (explicit media address) to any of +these functions, this has been replaced by the "media-address=..." +option within the first string of flags. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rtpengine/doc/contributors.xml b/modules/rtpengine/doc/contributors.xml deleted file mode 100644 index 14d6e158a88..00000000000 --- a/modules/rtpengine/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 247 - 139 - 6458 - 3160 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 31 - 17 - 423 - 595 - - - 3. - John Burke (@john08burke) - 25 - 17 - 647 - 102 - - - 4. - Liviu Chircu (@liviuchircu) - 20 - 16 - 91 - 173 - - - 5. - Richard Fuchs - 20 - 2 - 640 - 723 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 15 - 7 - 218 - 330 - - - 7. - Norman Brandinger (@NormB) - 12 - 10 - 72 - 18 - - - 8. - Peter Lemenkov (@lemenkov) - 11 - 8 - 29 - 64 - - - 9. - Vlad Paiu (@vladpaiu) - 8 - 1 - 566 - 94 - - - 10. - Eric Tamme (@etamme) - 7 - 5 - 42 - 19 - - - -
-All remaining contributors: Nick Altmann (@nikbyte), Maksym Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Eddie Fiorentine, Zero King (@l2dy), Norm Brandinger, Rob Gagnon (@rgagnon24), Flavio E. Goncalves, hatee, Dan Pascu (@danpascu), Oliver Severin Mulelid-Tynes (@olivermt). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jun 2014 - Aug 2025 - - - 2. - Norm Brandinger - May 2025 - May 2025 - - - 3. - Norman Brandinger (@NormB) - Jun 2024 - Feb 2025 - - - 4. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2025 - - - 5. - Vlad Paiu (@vladpaiu) - Jan 2025 - Jan 2025 - - - 6. - hatee - Dec 2024 - Dec 2024 - - - 7. - Eddie Fiorentine - Nov 2024 - Nov 2024 - - - 8. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 9. - Liviu Chircu (@liviuchircu) - Jul 2014 - May 2023 - - - 10. - John Burke (@john08burke) - Jun 2019 - Apr 2022 - - - -
-All remaining contributors: Bogdan-Andrei Iancu (@bogdan-iancu), Nick Altmann (@nikbyte), Flavio E. Goncalves, Zero King (@l2dy), Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Dan Pascu (@danpascu), Oliver Severin Mulelid-Tynes (@olivermt), Rob Gagnon (@rgagnon24), Eric Tamme (@etamme), Richard Fuchs. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Norm Brandinger, Razvan Crainea (@razvancrainea), Eddie Fiorentine, Norman Brandinger (@NormB), Liviu Chircu (@liviuchircu), John Burke (@john08burke), Nick Altmann (@nikbyte), Flavio E. Goncalves, Peter Lemenkov (@lemenkov), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Richard Fuchs. -
- -
diff --git a/modules/rtpengine/doc/rtpengine.xml b/modules/rtpengine/doc/rtpengine.xml deleted file mode 100644 index ed78bbe85e5..00000000000 --- a/modules/rtpengine/doc/rtpengine.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - rtpengine Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2013-2014 Sipwise GmbH - ©right; 2010 VoIPEmbedded Inc. - ©right; 2009-2014 TuTPro Inc. - ©right; 2005 &voicesystem; - ©right; 2003-2008 Sippy Software, Inc. - diff --git a/modules/rtpengine/doc/rtpengine_admin.xml b/modules/rtpengine/doc/rtpengine_admin.xml deleted file mode 100644 index 9114c109356..00000000000 --- a/modules/rtpengine/doc/rtpengine_admin.xml +++ /dev/null @@ -1,1797 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This is a module that enables media streams to be proxied - via an &rtp; proxy. The only &rtp; proxy currently known to work - with this module is the Sipwise rtpengine - . - The rtpengine module is a modified version of the original - rtpproxy module using a new control protocol. The module is - designed to be a drop-in replacement for the old module from - a configuration file point of view, however due to the - incompatible control protocol, it only works with &rtp; proxies - which specifically support it. - -
- -
- Multiple &rtp; proxy usage - - The rtpengine module can support multiple &rtp; proxies for - balancing/distribution and control/selection purposes. - - - The module allows definition of several sets of rtpengines. - Load-balancing will be performed over a set and the admin has the - ability to choose what set should be used. The set is selected via - its id - the id being defined with the set. Refer to the - module parameter - definition for syntax description. - - - The balancing inside a set is done automatically by the module based on - the weight of each &rtp; proxy from the set. - - - The selection of the set is done from script prior using - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() - functions - see the rtpengine_use_set() function. - - - Another way to select the set is to define setid_avp - module parameter and assign setid to the defined avp - before calling rtpengine_offer() or rtpengine_manage() - function. If forwarding of the requests fails and - there is another branch to try, remember to unset the - avp after calling rtpengine_delete() function. - - - For backward compatibility reasons, a set with no id take by default - the id 0. Also if no set is explicitly set before - rtpengine_delete(), rtpengine_offer() or rtpengine_answer() - the 0 id set will be used. - - - IMPORTANT: if you use multiple sets, take care and use the same set for - both rtpengine_offer()/rtpengine_answer() and rtpengine_delete()!! - If the set was selected using setid_avp, the avp needs to be - set only once before rtpengine_offer() or rtpengine_manage() call. - - - The module is able to failover to a new node within a set, if a chosen - one has communication issues. Moreover, it will also failover if the node - returns one of the following errors: - - - Parallel session limit reached - - - Ran out of ports - - - You can use the parameter - to extend the above list. - - - Many rtpengine_* functions accept a "sock_var" parameter that - will be populated with the socket of the RTPEngine chosen for - the particular operation. The format of the data stored in - "sock_var" is: "proto:ip:port". If the "sock_var" has - been specified and it is non-NULL then it will be used to - determine the specific RTPEngine to use. Note that the socket - specified by "sock_var" must be a member of the current RTPEngine - Set context. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tm module - (optional) if you want to - have rtpengine_manage() fully functional - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>rtpengine_sock</varname> (string) - - Definition of socket(s) used to connect to (a set) &rtp; proxy. It may - specify a UNIX socket or an IPv4/IPv6 UDP socket. If the protocol part - (i.e. udp:) is missing, the socket is treated as a - UNIX socket. - - - - Default value is NONE (disabled). - - - - Set <varname>rtpengine_sock</varname> parameter - -... -# single rtproxy -modparam("rtpengine", "rtpengine_sock", "udp:localhost:12221") -# multiple rtproxies for LB -modparam("rtpengine", "rtpengine_sock", - "udp:localhost:12221 udp:localhost:12222") -# multiple sets of multiple rtproxies -modparam("rtpengine", "rtpengine_sock", - "1 == udp:localhost:12221 udp:localhost:12222") -modparam("rtpengine", "rtpengine_sock", - "2 == udp:localhost:12225") -... - - -
-
- <varname>rtpengine_disable_tout</varname> (integer) - - Once an &rtp; proxy was found unreachable and marked as disabled, the rtpengine - module will not attempt to establish communication to that &rtp; proxy for - rtpengine_disable_tout seconds. - - - - Default value is 60. - - - - Set <varname>rtpengine_disable_tout</varname> parameter - -... -modparam("rtpengine", "rtpengine_disable_tout", 20) -... - - -
-
- <varname>rtpengine_tout</varname> (integer) - - Timeout value in waiting for reply from &rtp; proxy. - - - - Default value is 1. - - - - Set <varname>rtpengine_tout</varname> parameter - -... -modparam("rtpengine", "rtpengine_tout", 2) -... - - -
-
- <varname>rtpengine_retr</varname> (integer) - - How many times the module should retry to send and receive after - timeout was generated. - - - - Default value is 5. - - - - Set <varname>rtpengine_retr</varname> parameter - -... -modparam("rtpengine", "rtpengine_retr", 2) -... - - -
-
- <varname>rtpengine_timer_interval</varname> (integer) - - Frequency to scan rtpengine sets for disabled node probing. Probing is done - outside the SIP processing context and in a separate timer routine. Disabled nodes - are probed for re-enablement after rtpengine_disable_tout seconds. Setting this value - too high can lead to unexpectedly large disabled interval as the max interval - before probing is (rtpengine_timer_interval + rtpengine_disable_tout) seconds. - - Default value is 5. - - - Set <varname>rtpengine_timer_interval</varname> parameter - -... -modparam("rtpengine", "rtpengine_timer_interval", 1) -... - - -
-
- <varname>notification_sock</varname> (string) - - An UDP socket formatted as IP:port - that indicates the listening IP and port &osips; will bind for to - receive notifications (such as DTMF events) from RTPengine. - - - Every notification received from RTPengine will trigger an - E_RTPENGINE_NOTIFICATION event. - - - - Default value is none - notifications are ignored. - - - - Set <varname>notification_sock</varname> parameter - -... -modparam("rtpengine", "notification_sock", "127.0.0.1:9999") -... - - -
-
- <varname>extra_id_pv</varname> (string) - - The parameter sets the PV definition to use when the via-branch=extra - option is used on the rtpengine_delete(), rtpengine_offer(), - rtpengine_answer() or rtpengine_manage() commands. - - Default is empty, the via-branch=extra option may not be used then. - - - Set <varname>extra_id_pv</varname> parameter - -... -modparam("rtpengine", "extra_id_pv", "$avp(extra_id)") -... - - -
- -
- <varname>setid_avp</varname> (string) - - The parameter defines an AVP that, if set, - determines which &rtp; proxy set - rtpengine_offer(), rtpengine_answer(), - rtpengine_delete(), and rtpengine_manage() - functions use. - - - There is no default value. - - - Set <varname>setid_avp</varname> parameter - -... -modparam("rtpengine", "setid_avp", "$avp(setid)") -... - - -
- -
- <varname>error_pv</varname> (string) - - The parameter defines a variable that shall be populated - by &rtp; when one of the rtpengine_* functions fail. - - - There is no default value. - - - Set <varname>error_pv</varname> parameter - -... -modparam("rtpengine", "error_pv", "$var(rtpengine_error)") -... - - -
- -
- <varname>db_url</varname> (string) - - Database URL, used to load RTPEngines sockets - from db, instead of specifying them in the - script ( - module parameter). - - - Default value is NULL, no database - is used. - - - Set <varname>db_url</varname> parameter - -... -modparam("rtpengine", "db_url", - "mysql://opensips:opensipsrw@localhost/opensips") -... - - -
- -
- <varname>db_table</varname> (string) - - The table where the RTPEngines sockets are stored. - Used when Database URL is provisioned. - - - Default value is rtpengine. - - - Set <varname>db_table</varname> parameter - -... -modparam("rtpengine", "db_table", "rtpengine_new") -... - - -
- -
- <varname>socket_column</varname> (string) - - The name of the rtpengine socket column in the database table. - - - Default value is socket. - - - Set <varname>socket_column</varname> parameter - -... -modparam("rtpengine", "socket_column", "sock") -... - - -
- -
- <varname>set_column</varname> (string) - - The name of the rtpengine set column in the database table. - - - Default value is set_id. - - - Set <varname>set_column</varname> parameter - -... -modparam("rtpengine", "set_column", "set_new") -... - - -
- -
- <varname>ping_enabled</varname> (integer) - - This parameter indicates whether probing should be done for - enabled nodes as well. - - - If this parameter is set, each enabled node is pinged - every seconds, unless - there was any communication with the node since the previous interval. - - - - Default value is 0 (disabled). - - - - Set <varname>ping_enabled</varname> parameter - -... -modparam("rtpengine", "ping_enabled", yes) -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">rtpengine_use_set(setid)</function> - - - Sets the ID of the &rtp; proxy set to be used for the next - rtpengine_delete(), rtpengine_offer(), rtpengine_answer() - or rtpengine_manage() command. The parameter is an integer. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE. - - - <function>rtpengine_use_set</function> usage - -... -rtpengine_use_set(2); -rtpengine_offer(); -... - - -
-
- - <function moreinfo="none">rtpengine_offer([flags[, sock_var[, sdp_pvar[, body]]]])</function> - - - Rewrites &sdp; body to ensure that media is passed through - an &rtp; proxy. To be invoked - on INVITE for the cases the SDPs are in INVITE and 200 OK and on 200 OK - when SDPs are in 200 OK and ACK. - - Meaning of the parameters is as follows: - - - - flags(string, optional) - flags to turn on some features. - - The flags string is a list of space-separated items. Each item - is either an individual token, or a token in key=value format. The - possible tokens are described below. - When passing an option that &osips; is not aware of, it will be - blindly sent to the rtpengine daemon to be processed. - - - via-branch=... - Include the branch - value of one of the Via headers in the request to the - &rtp; proxy. Possible values are: - 1 - use the first Via header; - 2 - use the second Via header; - auto - use the first Via header if this is - a request, or the second one if this is a reply; - extra - don't take the value from a header, but instead use - the value of the variable. - This can be used to create one media session per branch - on the &rtp; proxy. When sending a subsequent delete command to - the &rtp; proxy, you can then stop just the session for a specific branch when - passing the flag '1' or '2' in the rtpengine_delete, or stop - all sessions for a call when not passing one of those two flags there. This is - especially useful if you have serially forked call scenarios where the &rtp; proxy - gets an offer command for a new branch, and then a - delete command for the previous branch, which would otherwise - delete the full call, breaking the subsequent answer for the - new branch. This flag is only supported by the Sipwise rtpengine - &rtp; proxy at the moment! - - - via-branch-param=... - provide a custom value for the - via-branch param. - - - call-id - provide a custom Call-ID for the session. If - missing, the Call-Id of the request/reply is used. - - - from-tag - provide a custom from-tag for the session. If - missing, the from-tag request is used. - - - to-tag - provide a custom to-tag of the session. If - missing, the to-tag of the request/reply is used, is present. - - - asymmetric - flags that UA from which message is - received doesn't support symmetric RTP. (automatically sets the 'r' flag) - - - force-answer - force answer, that is, - only rewrite &sdp; when corresponding session already exists - in the &rtp; proxy. By default is on when the session is to be - completed. - - - in-iface=..., out-iface=... - these flags specify the direction - the SIP message. These flags only make sense when the &rtp; proxy is running - in bridge mode. in-iface should indicate the proxy's inbound - interface, and out-iface corresponds to the &rtp; proxy's - outbound interface. You always have to specify two flags to define - the incoming network and the outgoing network. For example, - in-iface=internal out-iface=external should be - used for SIP message received from the local interface and sent out on the - external interface. - - - internal, external - these the old flags used to - specify the direction of call. They are now obsolate, being replaced by the - in-iface=internal out-iface=external configuration. - - - auto-bridge - this flag an alternative to the - internal and external flags - in order to do automatic bridging between IPv4 on the - "internal network" and IPv6 on the "external network". Instead of - explicitly instructing the &rtp; proxy to select a particular address - family, the distinction is done by the given IP in the SDP body by - the RTP proxy itself. Not supported by Sipwise rtpengine. - - - address-family=... - instructs the &rtp; proxy that the - recipient of this &sdp; body expects to see addresses of a particular family. - Possible values are IP4 and IP6. For example, - if the &sdp; body contains IPv4 addresses but the recipient only speaks IPv6, - you would use address-family=IP6 to bridge between the two - address families. - - Sipwise rtpengine remembers the address family preference of each party after - it has seen an &sdp; body from them. This means that normally it is only - necessary to explicitly specify the address family in the offer, - but not in the answer. - - Note: Please note, that this will only work properly with non-dual-stack user-agents or with - dual-stack clients according to RFC6157 (which suggest ICE for Dual-Stack implementations). - This short-cut will not work properly with RFC4091 (ANAT) compatible clients, which suggests - having different m-lines with different IP-protocols grouped together. - - - received-from=... - sets the address from which SIP packet with &sdp; received. - This flag always set automatically, don't use it until you have a reason for that. - - - force - instructs the &rtp; proxy to ignore marks - inserted by another &rtp; proxy in transit to indicate that the - session is already goes through another proxy. Allows creating - a chain of proxies. Not supported and ignored by Sipwise rtpengine. - - - trust-address - flags that IP address in SDP should - be trusted. Without this flag, the &rtp; proxy ignores address in - the SDP and uses source address of the SIP message as media - address which is passed to the RTP proxy. From rtpengine 3.8 this is the default behaviour. - - - SIP-source-address - the opposite of trust-address. - Restores the old default behaviour of ignoring endppoint of the addresses in the SDP body. - - - replace-origin - flags that IP from the origin - description (o=) should be also changed. - - - replace-session-connection - flags to change the session-level - SDP connection (c=) IP if media description also includes - connection information. - - - replace-zero-address - flags to replace zero address with real address. - Using a zero endpoint address is an obsolete way to signal a muted or sendonly stream. - Streams with zero addresses are normally flagged as sendonly and the zero address in the SDP - is passed through. - - - symmetric - flags that for the UA from which - message is received, support symmetric RTP must be forced. You do not - need to explicitly specify this value, as it is the default, and the - behavior is only changed when the asymmetric is used. - - - repacketize=NN - requests the &rtp; proxy to perform - re-packetization of RTP traffic coming from the UA which - has sent the current message to increase or decrease payload - size per each RTP packet forwarded if possible. The NN is the - target payload size in ms, for the most codecs its value should - be in 10ms increments, however for some codecs the increment - could differ (e.g. 30ms for GSM or 20ms for G.723). The - &rtp; proxy would select the closest value supported by the codec. - This feature could be used for significantly reducing bandwith - overhead for low bitrate codecs, for example with G.729 going - from 10ms to 100ms saves two thirds of the network bandwith. - Not supported by Sipwise rtpengine. - - - loop-protect - flag that instructs &rtp; to - avoid rewriting the SDP when looping the same message. - - - ICE=... - controls the &rtp; proxy's behaviour - regarding ICE attributes within the &sdp; body. Possible values - are: force - - discard any ICE attributes already present in the &sdp; body - and then generate and insert new ICE data, leaving itself - as the only ICE candidates; - remove instructs the &rtp; proxy to discard - any ICE attributes and not insert any new ones into the &sdp;. - The default (if no ICE=... is given at all), - new ICE data will only be generated - if no ICE was present in the &sdp; originally; otherwise - the &rtp; proxy will only insert itself as an - additional ICE candidate. Other - &sdp; substitutions (c=, m=, etc) are unaffected by this flag. - - - RTP, SRTP, AVP, AVPF - These flags control the &rtp; - transport protocol that should be used towards the recipient of - the &sdp;. If none of them are specified, the protocol given in - the &sdp; is left untouched. Otherwise, the SRTP flag indicates that - SRTP should be used, while RTP indicates that SRTP should not be used. - AVPF indicates that the advanced RTCP profile with feedback messages - should be used, and AVP indicates that the regular RTCP profile - should be used. See also the next set of flags below. - - - RTP/AVP, RTP/SAVP, RTP/AVPF, RTP/SAVPF - these serve as - an alternative, more explicit way to select between the different &rtp; protocols - and profiles supported by the &rtp; proxy. For example, giving the flag - RTP/SAVPF has the same effect as giving the two flags - SRTP AVPF. - - - to-tag - force inclusion of the To tag. - Normally, the To tag is always included when present, except - for delete messages. Including the To tag in - a delete messages allows you to be more selective about which - dialogues within a call are being torn down. - - - to-tag=... - use the specified string as To - tag instead of the actual To tag from the &sip; message, and - force inclusion of the tag in the message as per above. - - - from-tag=... - use the specified string as - From tag instead of the actual From - tag from the &sip; message. - - - call-id=... - use the specified string as - Call-ID instead of the actual Call-ID - from the &sip; message. - - - rtcp-mux-demux - if rtcp-mux (RFC 5761) was - offered, make the &rtp; proxy accept the offer, but not offer it to the - recipient of this message. - - - rtcp-mux-reject - if rtcp-mux was offered, make the - &rtp; proxy reject the offer, but still offer it to the recipient. Can be - combined with rtcp-mux-offer to always offer it. - - - rtcp-mux-offer - make the &rtp; proxy offer rtcp-mux - to the recipient of this message, regardless of whether it was offered - originally or not. - - - rtcp-mux-require - Similar to offer but pretends that - the client has accepted rtcp-mux. This breaks RFC 5761 and will not advertise - seperate RTCP ports. This option is necessary for WebRTC clients. - - - rtcp-mux-accept - if rtcp-mux was offered, make the - &rtp; proxy accept the offer and also offer it to the recipient of this - message. Can be combined with rtcp-mux-offer to always offer it. - - - media-address=... - force a particular media address to - be used in the &sdp; body. Address family is detected automatically. - - - record-call=yes/no - indicates whether rtpengine should - record the call or not. When using this parameter, you may pass further - information in the metadata. - - - transcode-CODEC - used only for offer, indicates that - rtpengine should transcode the CODEC towards the B-side. Example: - transcode-PCMA will present to the B-side the PCMA codec. - - - codec-strip-CODEC - used only for offer, indicates that - the A-side of the call will not end up talking CODEC. Example: - codec-strip-PCMA will prevent the A-side from receiving - the PCMA codec. - - - codec-mask-CODEC - used only for offer, indicates that - the A-side will use the CODEC, but it will not be presented to the B-side. Example: - codec-mask-PCMA will make the A-side receive the PCMA codec, - but B-side will use something else. - - - - - sock_var(var, optional) - variable used to store the rtpengine - socket chosen for this call. - - - sdp_var(var, optional) - variable used to store the full SDP - received from rtpengine. You can perform any additional changes on this - string. Important: when providing this variable, the - message body is no longer changed, so you have to manually replace it!. - - - body(string, optional) - used to provide a specific body - to the rtpengine_* function. If this parameter is missing the body of - the current message is used. - - - - This function can be used from ALL_ROUTES. - - - <function>rtpengine_offer</function> usage - -route { -... - if (is_method("INVITE")) { - if (has_body("application/sdp")) { - if (rtpengine_offer()) - t_on_reply("1"); - } else { - t_on_reply("2"); - } - } - if (is_method("ACK") && has_body("application/sdp")) - rtpengine_answer(); -... -} - -onreply_route[1] -{ -... - if (has_body("application/sdp")) - rtpengine_answer(); -... -} - -onreply_route[2] -{ -... - if (has_body("application/sdp")) - rtpengine_offer(); -... -} - - - - <function>rtpengine_offer</function> usage with body replace - -... -if (rtpengine_offer(, $var(socket), $var(body), $rb)) { - xlog("Used rtpengine $var(socket)\n"); - # make all the changes on the resulted SDP in $var(body) - ... - remove_body_part(); - add_body_part($var(body), "application/sdp"); -} -... - - - - <function>rtpengine_offer</function> usage with call recording - -... -$var(rtpengine_flags) = $var(rtpengine_flags) + " record-call=yes"; - -$json(recording_keys) := "{}"; -$json(recording_keys/callId) = $ci; -$json(recording_keys/fromUser) = $dlg_val(recording_from_user); -$json(recording_keys/fromDomain) = $dlg_val(recording_from_domain); -$json(recording_keys/fromTag) = $dlg_val(recording_from_tag); -$json(recording_keys/toUser) = $dlg_val(recording_to_user); -$json(recording_keys/toDomain) = $dlg_val(recording_to_domain); - -$var(rtpengine_flags) = $var(rtpengine_flags) + " metadata=" + $(json(recording_keys){s.encode.hexa}); -rtpengine_offer($var(rtpengine_flags)); -... - - - - <function>rtpengine_offer</function> usage for transcoding - -... -# Goal: make A-side talk PCMA and B-side talk opus -# * do not present PCMA to B-side: codec-mask-PCMA, but use it on A-side -# * do not use opus for A-side: codec-strip-opus -# * offer opus to B-side: transcode-opus -rtpengine_offer("... codec-mask-PCMA codec-strip-opus transcode-opus ..."); -... - - - -
- <varname>extra_failover_error</varname> (string) - - Contains a (XDB) regular expression that can be - used to match an error received from a RTPEngine node. If matched - the module tries to use a new node to handle the affected command. - - - This parameter can be used to extend the list - (see of errors the module - implicitely fails over. - - - Note each declaration will define a single - expression/matching rule. If you want to define multiple rules, you - need to define the parameter multiple times. - - - Default value is empty, no extra errors are being used. - - - Set <varname>extra_failover_error</varname> parameter - -... -modparam("rtpengine", "extra_failover_error", "Parallel session limit reached") -... - - -
- -
-
- - <function moreinfo="none">rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]])</function> - - - Rewrites &sdp; body to ensure that media is passed through - an &rtp; proxy. To be invoked - on 200 OK for the cases the SDPs are in INVITE and 200 OK and on ACK - when SDPs are in 200 OK and ACK. - - - See rtpengine_offer() function description above for the meaning of the - parameters. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtpengine_answer</function> usage - - See rtpengine_offer() function example above for examples. - - -
-
- - <function moreinfo="none">rtpengine_delete([flags[, sock_var]])</function> - - - Tears down the RTPEngine session for the current call. - - - See rtpengine_offer() function description above for the meaning of the - parameters. Note that not all flags make sense for a delete. - - - This function can be used from ALL_ROUTES. - - - <function>rtpengine_delete</function> usage - -... -rtpengine_delete(); -... - - -
- -
- - <function moreinfo="none">rtpengine_manage([flags[, sock_var[, sdp_var[, body]]]])</function> - - - Manage the RTPEngine session - it combines the functionality of - rtpengine_offer(), rtpengine_answer() and rtpengine_delete(), detecting - internally based on message type and method which one to execute. - - - It can take the same parameters as rtpengine_offer(). - The flags parameter to rtpengine_manage() can be a configuration variable - containing the flags as a string. - - - Functionality: - - - - - If INVITE with SDP, then do rtpengine_offer() - - - - - If ACK with SDP, then do rtpengine_answer() - - - - - If BYE or CANCEL, or called within a FAILURE_ROUTE[], then do rtpengine_delete() - - - - - If reply to INVITE with code >= 300 do rtpengine_delete() - - - - - If reply with SDP to INVITE having code 1xx and 2xx, then - do rtpengine_answer() if the request had SDP or tm is not loaded, - otherwise do rtpengine_offer() - - - - - - This function can be used from ALL_ROUTES. - - - <function>rtpengine_manage</function> usage - -... -rtpengine_manage(); -... - - -
- -
- - <function moreinfo="none">rtpengine_start_recording([flags [, sock_var]])</function> - - - This function will send a signal to the &rtp; proxy to record - the RTP stream on the &rtp; proxy. - - Meaning of the parameters is as follows: - - - flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different call than the requested one. - - - sock_var(var, optional) - variable used to store the rtpengine - socket chosen for this call. - - - - This function can be used from any route. - - - <function>rtpengine_start_recording</function> usage - -... -rtpengine_start_recording(); -... - - -
- -
- - <function moreinfo="none">rtpengine_stop_recording([flags [, sock_var]])</function> - - - This function will send a signal to the &rtp; proxy to stop - recording the RTP stream on the &rtp; proxy. - - Meaning of the parameters is as follows: - - - flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different call than the requested one. - - - sock_var(var, optional) - variable used to store the rtpengine - socket chosen for this call. - - - - This function can be used from any route. - - - <function>rtpengine_stop_recording</function> usage - -... -rtpengine_stop_recording(); -... - - -
- -
- - <function moreinfo="none">rtpengine_pause_recording([flags [, sock_var]])</function> - - - This function will send a signal to the &rtp; proxy to pause - recording the RTP stream on the &rtp; proxy. Identical to stop recording except that it - instructs the recording daemon not to close the recording file, but instead leave it open - so that recording can later be resumed via another start recording message. - - Meaning of the parameters is as follows: - - - flags(string, optional) - flags used to change the behavior - of the recorder. An importat value to set is the call-id - value, which can be used to start recording a different call than the requested one. - - - sock_var(var, optional) - variable used to store the rtpengine - socket chosen for this call. - - - - This function can be used from any route. - - - <function>rtpengine_pause_recording</function> usage - -... -rtpengine_stop_recording(); -... - - -
- -
- - <function moreinfo="none">rtpengine_play_media(flags, [duration_spec[, sock_var[, sockvar]]])</function> - - - This function will start playing a media file to one of the endpoints. - - Meaning of the parameters is as follows: - - - flags(string) - a list of flags similar to - the other functions. One of the file, - blob or db-id parameters - is mandatory to indicate the content of the media file to be played. - file is a common choice for specifying rtpengine - to get media from a file path, blob to take - the content from an inline string and db-id to - get the content from the database. - - The direction of the media stream is controlled by the - from-tag parameter, address - (media address from the SDP), or label, if the - media stream contains a label. If all of them are missing, the media - file is played to the initiator of the SIP request, and will work similar - to a ringback tone. - - - - duration_spec(var, optional) - a pseudo variable that - will contain the duration of the played file. It will be set to - -1 if the duration could not be determined. - - - sock_var(var, optional) - variable used to store the rtpengine - socket chosen for this call. - - - - This function can be used from any route. - - - Ringback tone using <function>rtpengine_play_media</function> - -... -if (is_method("INVITE") && !has_totag()) - rtpengine_play_media("file=/path/to/ringback_tone_file.wav"); -... - - - - Manage music on hold using <function>rtpengine_play_media</function> - -... -if (is_method("INVITE") && has_totag()) { - if (is_audio_on_hold()) { - $dlg_val(on_hold) = "1"; - rtpengine_play_media("from-tag=$tt file=/path/to/moh_file.wav"); - } else if ($dlg_val(on_hold) == "1") { - $dlg_val(on_hold) = "0"; - rtpengine_stop_media("from-tag=$tt"); - } -} -... - - -
- -
- - <function moreinfo="none">rtpengine_stop_media(flags[, [sock_var[, sockvar]], [last_frame_pos]])</function> - - - This function will stop playing a media file previously started - by a rtpengine_play_media() call. The meaning - of its parameters is similar to the previous functions. Note that this - function should be called with similar parameters as its matching - rtpengine_play_media() call, otherwise - RTPEngine will not be able to stop media playing. - - Meaning of the parameters is as follows: - - - flags(string) - a list of flags similar to - the other functions. - - - last_frame_pos(var, optional) - a pseudo variable that - will contain the last frame played of the file. - - - - This function can be used from any route. - - - Ringback tone stop using <function>rtpengine_stop_media</function> - -... -if (is_method("INVITE") && $rs == 200) - rtpengine_stop_media(); -... - - - - Example use of the last-frame-pos parameter <function>rtpengine_stop_media</function> - -... -if (is_method("INVITE") && has_totag()) { - if (is_audio_on_hold()) { - $dlg_val(on_hold = "1"; - rtpengine_play_media("from-tag=$tt start-pos=$avp(last_frame_pos) file=/path/to/moh_file.wav"); - } else if ($dlg_val(on_hold) == "1") { - rtpengine_stop_media("from-tag=$tt", , $avp(last_frame_pos)); - $dlg_val(on_hold = "0"); - } -} - rtpengine_stop_media(); -... - - -
- -
- - <function moreinfo="none">rtpengine_block_media([flags[, sockvar]])</function> - - - This function will block the media sent from one of the endpoints. - The direction to be blocked is controled by the flags - parameter, the from-tag value. - - - This function can be used from any route. - - - Example of <function>rtpengine_block_media</function> usage - -... -rtpengine_block_media(); -... - - -
- -
- - <function moreinfo="none">rtpengine_unblock_media([flags[, sockvar]])</function> - - - This function will resume/unblock the media sent from one of the endpoints. - The direction to be blocked is controled by the flags - parameter, the from-tag value. - - - This function can be used from any route. - - - Example of <function>rtpengine_unblock_media</function> usage - -... -rtpengine_unblock_media(); -... - - -
- -
- - <function moreinfo="none">rtpengine_block_dtmf([flags[, sockvar]])</function> - - - This function will block the DTMF media sent from one of the endpoints. - The direction to be blocked is controled by the flags - parameter, the from-tag value. - - - This function can be used from any route. - - - Example of <function>rtpengine_block_dtmf</function> usage - -... -rtpengine_block_dtmf(); -... - - -
- -
- - <function moreinfo="none">rtpengine_unblock_dtmf([flags[, sockvar]])</function> - - - This function will resume/unblock the DTMF media sent from one of the endpoints. - The direction to be blocked is controled by the flags - parameter, the from-tag value. - - - This function can be used from any route. - - - Example of <function>rtpengine_unblock_dtmf</function> usage - -... -rtpengine_unblock_dtmf(); -... - - -
- -
- - <function moreinfo="none">rtpengine_start_forwarding([flags[, sockvar]])</function> - - - This function will start forwarding the media to a TLS destination specified - in the tls-send-to parmeter of RTPEngine. This function allows you - to select the media stream to forward, by specifing the from-tag - of the entity you want to forward the media. If missing, all media streams are forwarded. - - - This function can be used from any route. - - - Example of <function>rtpengine_start_forwarding</function> usage - -... -rtpengine_start_forwarding(); -... - - -
- -
- - <function moreinfo="none">rtpengine_stop_forwarding([flags[, sockvar]])</function> - - - This function will stop forwarding of the media previously started using the - rtpengine_start_forwarding() function. - - - This function can be used from any route. - - - Example of <function>rtpengine_stop_forwarding</function> usage - -... -rtpengine_stop_forwarding(); -... - - -
- -
- - <function moreinfo="none">rtpengine_play_dtmf(code, [flags[, sockvar]])</function> - - - This function instructs &rtp; to send the DTMF code - to the participant of the call. The code can be a digit - (0-9) or a special character (one of *,#,A,B,C,D). - Additional parameters can be configured using the flags - parameter. For more information, please consult the &rtp; documentation. - - - NOTE: if you are planning to inject DTMF in a session, - you have to specify the inject-DTMF flag when the - session is created. - - - This function can be used to convert SIP INFO DTMF keys to RTP DTMF. - - - This function can be used from any route. - - - Example of <function>rtpengine_play_dtmf</function> usage - -... -rtpengine_play_dtmf("0"); # send the 0 code upstream -... - - -
- - -
- -
- Exported Asyncronous Functions -
- <function moreinfo="none">rtpengine_offer([flags[, sock_pvar[, sdp_pvar[, body]]]])</function> - - The asynchronous flavor of the - function. It receives the same parameters, with the same meanings. - - - Example of async rtpengine_offer() usage - -... -if (is_method("ACK") && has_totag() && has_body_part("application/sdp")) { - async(rtpengine_offer(), resume_invite); -} -... -route[resume_invite] { - t_relay(); -} -... - - -
-
- <function moreinfo="none">rtpengine_answer([flags[, sock_pvar[, sdp_pvar[, body]]]])</function> - - The asynchronous flavor of the - function. It receives the same parameters, with the same meanings. - - - Example of async rtpengine_answer() usage - -... -if (is_method("ACK") && has_body_part("application/sdp")) { - # late negotiation - async(rtpengine_answer(), resume_ack); -} -... -route[resume_ack] { - t_relay(); -} -... - - -
-
- - <function moreinfo="none">rtpengine_delete([flags[, sock_var]])</function> - - - The asynchronous flavor of the - function. It receives the same parameters, with the same meanings. - - - Example of async rtpengine_delete() usage - -... -if (is_method("BYE")) { - launch(rtpengine_delete()); -} -... - - -
-
- -
- Exported Pseudo-Variables -
- <function moreinfo="none">$rtpstat</function> - - Returns the &rtp; statistics from the &rtp; proxy. The &rtp; statistics from the &rtp; proxy - are provided as a string and it does contain several packet counters. - - - - $rtpstat Usage - -... - append_hf("X-RTP-Statistics: $rtpstat\r\n"); -... - - -
-
- <function moreinfo="none">$rtpstat(STAT)[index]</function> - - Returnes one of the pre-fined statistics listed below: - - - - MOS-average - without an index, it returns the average - MOS value, expressed in an integer between 0 and 50, of all the RTP streams - involved in the call, both caller and callee. If index is specified, it has - to be one of the from-tag - or to-tag involved in the call. In this case, the variable - will return the average MOS of all the streams generated by that endpoint - with the associated tag value. If you need more granular statistics, check - the $rtpquery variable. - - - jitter-average - similar behavior with - MOS-average, but returnes the average jitter. - - - roundtrip-average - similar behavior with - MOS-average, but returnes the average roundtrip. - - - packetloss-average - similar behavior with - MOS-average, but returnes the average packet loss. - - - MOS-min - without an index, it returns the minimum - MOS value (integer value between 0 and 50) of all RTP streams involved in the - call, both caller and callee. - If the index is specified, it has the same effect as for - MOS-average. - - - jitter-min - similar behavior with - MOS-min, but returnes the minimum jitter of a leg/call. - - - roundtrip-min - similar behavior with - MOS-min, but returnes the minimum roundtrip of a leg/call. - - - packetloss-min - similar behavior with - MOS-min, but returnes the minimum packet loss of a leg/call. - - - MOS-max - without an index, it returns the maximum - MOS value (integer value between 0 and 50) of all RTP streams involved in the - call, both caller and callee. - If the index is specified, it has the same effect as for - MOS-average. - - - jitter-max - similar behavior with - MOS-max, but returnes the maximum jitter of a leg/call. - - - roundtrip-max - similar behavior with - MOS-max, but returnes the maximum roundtrip of a leg/call. - - - packetloss-max - similar behavior with - MOS-max, but returnes the maximum packet loss of a leg/call. - - - MOS-min-at - without an index, it returns the time in - seconds elapsed from the start of the call when the MOS value is minimum. - If the index is specified, it has the same effect as for - MOS-average. - - - jitter-min-at - similar behavior with - MOS-min-at, but returnes the time when the minimum - jitter was detected. - - - roundtrip-min-at - similar behavior with - MOS-min-at, but returnes the time when the minimum - roundtrip was detected. - - - packetloss-min-at - similar behavior with - MOS-min-at, but returnes the time when the minimum - packet loss of a leg/call was detected. - - - MOS-max-at - without an index, it returns the time in - seconds elapsed from the start of the call when the MOS value is maximum. - If the index is specified, it has the same effect as for - MOS-average. - - - jitter-max-at - similar behavior with - MOS-max-at, but returnes the time when the maximum - value of jitter was detected. - - - roundtrip-max-at - similar behavior with - MOS-max-at, but returnes the time when the maximum - value of roundtrip was detected. - - - packetloss-min-at - similar behavior with - MOS-max-at, but returnes the time when the maximum - packet loss of a leg/call was detected. - - - - - NOTE: all these statistics are computed based on the - statistics generated by RTPEngine. Some of them might not be available for - all the calls (i.e. MOS cannot be computed if the call is too short, or if - the phones do not properly report RTP statistics over RTCP). In these cases - the variable returns the NULL value. - - - $rtpstat(STAT) - -... - xlog("Average MOS of the entire call is $rtpstat(MOS-average)\r\n"); - xlog("Average MOS of caller is $(rtpstat(MOS-average)[$ft])\r\n"); - xlog("Average MOS of callee is $(rtpstat(MOS-average)[$tt])\r\n"); - xlog("Min MOS of caller is $(rtpstat(MOS-min)[$ft]) reported at $(rtpstat(MOS-min-at)[$ft])\r\n"); -... - - -
-
- <function moreinfo="none">$rtpquery</function> - - Does a Query command to the &rtp; proxy and returns the answer in a JSON format. - You can use this variable to fetch arbitrary data from the &rtp; proxy such as - raw statistics about the call, or other indicators. - - - You can use a $json() variable to parse - its output and extract any information from the query, such as - RTP statistics, or MOS values. - - - - $rtpquery Usage - -... - $json(reply) := $rtpquery; - xlog("Total RTP Stats: $json(reply/totals)\n"); -... - - -
- -
- -
- Exported MI Functions -
- <function moreinfo="none">rtpengine_enable</function> - - Enables/disables a &rtp; proxy. - - Parameters: - - - url - the &rtp; proxy url (exactly as - defined in the config file). - - - enable - 1 - enable, 0 - disable the &rtp; proxy, 2 - put the &rtp; node in probing mode. - - - setid (optional) the set ID of the nodes to be updated. If provided, only nodes in the provided set will be updated. - - - - NOTE: if a &rtp; proxy is defined multiple times (in the same or - different set), all of its instances will be enabled/disabled IF no set ID is provided. - - - - <function moreinfo="none">rtpengine_enable</function> usage - -... -## disable all rtpengines by URL -$ opensips-cli -x mi rtpengine_enable udp:192.168.2.133:8081 0 -## enable rtpengine by URL and set ID (3) -$ opensips-cli -x mi rtpengine_enable url=udp:192.168.2.133:8081 enable=1 setid=3 -... - - -
- -
- <function moreinfo="none">rtpengine_show</function> - - Displays all the &rtp; proxies and their information: set and - status (disabled or not, weight and recheck_ticks). - - - No parameter. - - - - <function moreinfo="none">rtpengine_show</function> usage - -... -$ opensips-cli -x mi rtpengine_show -... - - -
- -
- <function moreinfo="none">rtpengine_reload</function> - - Reloads all rtpengine sets from the database. Used only when the - parameter is set. - - Parameters: - - - type (optional) soft - when reloading nodes - from the database, reuse any existing sockets and keep existing - node disabled state. If not provided, then all nodes and sockets - will first be torndown and then nodes will be loaded from the database. - - - - No parameter. - - - - <function moreinfo="none">rtpengine_reload</function> usage - -... -$ opensips-cli -x mi rtpengine_reload -$ opensips-cli -x mi rtpengine_reload type=soft -... - - -
- -
- <function moreinfo="none">teardown</function> - - Terminates the SIP dialog by the SIP Call-ID given as parameter. - - Parameters: - - - callid - SIP Call-ID. - - - - Note this is a just a wrapper function over the - dlg_end_dlg MI function provided by the - dialog module. This wrapping is done just to - make rtpengine happy when trying to terminate SIP calls based on - RTP timeouts. - - - - <function moreinfo="none">teardown</function> usage - -... -$ opensips-cli -x mi teardown Y2IwYjQ2YmE2ZDg5MWVkNDNkZGIwZjAzNGM1ZDY0ZDQ -... - - -
- - - -
- -
- Exported Events -
- - <function moreinfo="none">E_RTPENGINE_NOTIFICATION</function> - - - This event is raised when a notification is received from RTPengine. - - - Parameters represent the nodes within the Json request received from RTPengine. - Common values are: - - - - type - identifies the type of notification (i.e. DTMF) - - - callid - the callid of the call this event is triggered for - - - source_tag - from tag of the call this event is triggered for - - - timestamp - timestamp when the event was triggered - - - - For a DTMF event received, you will also get the following nodes: - - - - source_ip - the IP that triggered the DTMF - - - event - the event/digit pressed - - - duration - how long the digit was pressed - - - volume - volume of the tone - - -
- -
- - <function moreinfo="none">E_RTPENGINE_STATUS</function> - - - This event is raised when a RTPEngine server changes it's status to - active/inactive. - - Parameters: - - - socket - the socket that identifies the - RTPEngine instance. - - - status - active if - the RTPEngine instance responds to probing or - inactive if the instance was deactivated. - - - set - the numeric id of the set - this RTPEngine instance is part of. - - -
-
- - -
- diff --git a/modules/rtpengine/doc/rtpengine_faq.xml b/modules/rtpengine/doc/rtpengine_faq.xml deleted file mode 100644 index f7856cbaf5e..00000000000 --- a/modules/rtpengine/doc/rtpengine_faq.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - - &faqguide; - - - - How do I migrate from rtpproxy or rtpproxy-ng to - rtpengine? - - - - For the most part, only the names of the functions have changed, with - rtpproxy in each name replaced with rtpengine. - For example, rtpproxy_manage() has become - rtpengine_manage(). A few name duplications have also been resolved, - for example there is now a single rtpengine_delete() instead of - unforce_rtp_proxy() and the identical rtpproxy_destroy(). - - - The largest difference to the old module is how flags are passed to - rtpengine_offer(), rtpengine_answer(), - rtpengine_manage() and rtpengine_delete(). Instead of - having a string of single-letter flags, they now take a string of space-separated - items, with each item being either a single token (word) or a key=value - pair. - - - For example, if you had a call rtpproxy_offer("FRWOC+PS");, this would - then become: - - -rtpengine_offer("force trust-address symmetric replace-origin replace-session-connection ICE=force RTP/SAVPF"); - - - Finally, if you were using the second parameter (explicit media address) to any of - these functions, this has been replaced by the media-address=... - option within the first string of flags. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/rtpengine/rtpengine.c b/modules/rtpengine/rtpengine.c index c9b50844473..faeaac62951 100644 --- a/modules/rtpengine/rtpengine.c +++ b/modules/rtpengine/rtpengine.c @@ -1832,6 +1832,12 @@ static inline int rtpengine_connect_node(struct rtpe_node *pnode) } pkg_free(hostname); + if (res->ai_addrlen > sizeof(pnode->ai_addr)) { + LM_ERR("RTP proxy address is too large\n"); + freeaddrinfo(res); + return 0; + } + rtpe_socks[pnode->idx] = socket((pnode->rn_umode == 6) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0); if ( rtpe_socks[pnode->idx] == -1) { @@ -1849,7 +1855,7 @@ static inline int rtpengine_connect_node(struct rtpe_node *pnode) } pnode->ai_addrlen = res->ai_addrlen; - memcpy(&(pnode->ai_addr), res->ai_addr, res->ai_addrlen); + memcpy(&pnode->ai_addr.s, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); return 1; @@ -2635,6 +2641,8 @@ static int rtpe_check_ignore_node(str *error) return ret; } +static void pkg_free_wrapper(void *p) { pkg_free(p); } + static int rtpe_function_call_prepare(bencode_buffer_t *bencbuf, struct sip_msg *msg, enum rtpe_operation op, struct ng_flags_parse *ng_flags, str *flags_str, str *body_in, bencode_item_t *extra_dict, char **err) { @@ -2808,8 +2816,12 @@ static int rtpe_function_call_prepare(bencode_buffer_t *bencbuf, struct sip_msg goto error; } + /* flags_nt.s must remain valid until the bencode buffer is serialized + * and sent, because parse_flags() stores pointers into it (via bencode_str + * and bencode_dictionary_add_len) for key=value flags like media-address. + * Register it for cleanup when the bencode buffer is freed. */ if (flags_nt.s) - pkg_free(flags_nt.s); + bencode_buffer_destroy_add(bencbuf, pkg_free_wrapper, flags_nt.s); return 1; @@ -2828,13 +2840,12 @@ static bencode_item_t *rtpe_function_call(bencode_buffer_t *bencbuf, struct sip_ str error; struct rtpe_node *node, *failed_node; char *cp, *err = NULL; - pv_value_t val; + pv_value_t val, socket_val; struct rtpe_ignore_node *ignore_list = NULL; - int ret; + int ret, forced_socket; memset(&ng_flags, 0, sizeof(ng_flags)); error.len = 0; error.s = ""; - pv_value_t socket_val; /*** get & init basic stuff needed ***/ if (rtpe_function_call_prepare(bencbuf, msg, op, &ng_flags, flags_str, body_in, extra_dict,&err) < 0) @@ -2847,10 +2858,10 @@ static bencode_item_t *rtpe_function_call(bencode_buffer_t *bencbuf, struct sip_ } /*** If the spvar "sock_var" has been specified, parse it into a (socket_val) STR variable ***/ - if (spvar) { - memset(&socket_val, 0, sizeof(pv_value_t)); + memset(&socket_val, 0, sizeof(pv_value_t)); + if (spvar) pv_get_spec_value(msg, spvar, &socket_val); - } + forced_socket = socket_val.rs.len > 0; failed_node = NULL; @@ -2867,16 +2878,23 @@ static bencode_item_t *rtpe_function_call(bencode_buffer_t *bencbuf, struct sip_ if (spvar && (socket_val.rs.len > 0)) { LM_DBG("Sending command [%d] to RTPEngine socket: [%.*s] set id: [%d]\n", op, (int)(socket_val.rs.len), (char *)(socket_val.rs.s), set->id_set); node = lookup_rtpe_node(set, &socket_val.rs); - if (node == NULL) { - RTPE_STOP_READ(); - goto error; + socket_val.rs.s = NULL; + socket_val.rs.len = 0; + if (node && ((node->rn_disabled = rtpe_test(node, node->rn_disabled, 0)) || + rtpe_is_ignore_node(ignore_list, node))) { + LM_DBG("RTPEngine socket [%.*s] is not available\n", + node->rn_url.len, node->rn_url.s); + node = NULL; } + if (node == NULL && op == OP_OFFER) + node = select_rtpe_node(ng_flags.call_id, set, ignore_list); + } else if (forced_socket && op != OP_OFFER) { + node = NULL; } else if (snode && snode->s) { if ((node = get_rtpe_node(snode, set)) == NULL && op == OP_OFFER) node = select_rtpe_node(ng_flags.call_id, set, ignore_list); snode = NULL; - } else { node = select_rtpe_node(ng_flags.call_id, set, ignore_list); } @@ -3657,7 +3675,7 @@ static int start_async_send_rtpe_command(struct rtpe_node *node, bencode_item_t LM_ERR("can't create socket %d \n",errno); goto badproxy; } - if (connect(fd, &(node->ai_addr), node->ai_addrlen) < 0) { + if (connect(fd, &node->ai_addr.s, node->ai_addrlen) < 0) { LM_ERR("can't connect to RTP proxy %s (%d:%s)\n",node->rn_url.s,errno,strerror(errno)); close(fd); goto badproxy; @@ -4768,6 +4786,10 @@ static void rtpengine_raise_event(int sender, void *p) break; default: jstring.s = cJSON_PrintUnformatted(param); + if (!jstring.s) { + LM_ERR("cJSON_PrintUnformatted failed\n"); + break; + } jstring.len = strlen(jstring.s); err = evi_param_add_str(eparams, &name, &jstring); cJSON_PurgeString(jstring.s); @@ -5020,6 +5042,7 @@ static int rtpengine_api_offer(struct rtp_relay_session *sess, fill_rtpengine_node(server, &val.rs); else LM_ERR("could not retrieve the value of the used rtpengine!\n"); + pv_set_value(sess->msg, &media_pvar, EQ_T, NULL); } return ret; } diff --git a/modules/rtpengine/rtpengine.h b/modules/rtpengine/rtpengine.h index 17241ae2135..ba69048d6e6 100644 --- a/modules/rtpengine/rtpengine.h +++ b/modules/rtpengine/rtpengine.h @@ -27,6 +27,7 @@ #define _RTPENGINE_H #include "bencode.h" +#include "../../ip_addr.h" #include "../../str.h" /* flags for set, node, and socket management */ @@ -46,7 +47,7 @@ struct rtpe_node { unsigned int rn_last_ticks; int rn_flags; socklen_t ai_addrlen; - struct sockaddr ai_addr; + union sockaddr_union ai_addr; struct rtpe_node *rn_next; }; diff --git a/modules/rtpproxy/README b/modules/rtpproxy/README deleted file mode 100644 index d1e0f661c29..00000000000 --- a/modules/rtpproxy/README +++ /dev/null @@ -1,1051 +0,0 @@ -rtpproxy Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Multiple RTPProxy usage - 1.3. RTPProxy timeout notifications - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. rtpproxy_sock (string) - 1.5.2. rtpproxy_disable_tout (integer) - 1.5.3. rtpproxy_timeout (string) - 1.5.4. rtpproxy_autobridge (integer) - 1.5.5. rtpproxy_retr (integer) - 1.5.6. default_set (integer) - 1.5.7. nortpproxy_str (string) - 1.5.8. db_url (string) - 1.5.9. db_table (string) - 1.5.10. rtpp_socket_col (string) - 1.5.11. set_id_col (string) - 1.5.12. rtpp_notify_socket (string) - 1.5.13. generated_sdp_port_min (integer) - 1.5.14. generated_sdp_port_max (integer) - 1.5.15. generated_sdp_media_ip (string) - - 1.6. Exported Functions - - 1.6.1. rtpproxy_engage([[flags][, [ip_address][, - [set_id][, [sock_var][, ret_var]]]]]) - - 1.6.2. rtpproxy_offer([[flags][, [ip_address][, - [set_id][, [sock_var][, [ret_var][, - [body_var]]]]]]) - - 1.6.3. rtpproxy_answer([[flags][, [ip_address][, - [set_id][, [sock_var][, [ret_var][, - [body_var]]]]]]]) - - 1.6.4. rtpproxy_unforce([[set_id][, sock_var]]) - 1.6.5. rtpproxy_stream2uac(prompt_name, count[, - [set_id][, sock_var]]), - rtpproxy_stream2uas(prompt_name, count[, - [set_id][, sock_var]]) - - 1.6.6. rtpproxy_stop_stream2uac([[set_id][, - sock_var]]), - rtpproxy_stop_stream2uas([[set_id][, - sock_var]]) - - 1.6.7. rtpproxy_start_recording([[set_id][, - [sock_var][, [flags][, [destination][, - mediastream]]]]]) - - 1.6.8. rtpproxy_stats(up_pvar, down_var, sent_var, - fail_var[, [set_id][, sock_var]]) - - 1.6.9. rtpproxy_all_stats(stats_avp[, [set_id][, - sock_var]]) - - 1.7. Exported MI Functions - - 1.7.1. rtpproxy_enable - 1.7.2. rtpproxy_show - 1.7.3. rtpproxy_reload - - 1.8. Exported Events - - 1.8.1. E_RTPPROXY_STATUS - 1.8.2. E_RTPPROXY_DTMF - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set rtpproxy_sock parameter - 1.2. Set rtpproxy_disable_tout parameter - 1.3. Set rtpproxy_timeout parameter to 200ms - 1.4. Enable auto-bridging feature - 1.5. Set rtpproxy_retr parameter - 1.6. Set default_set parameter - 1.7. Set nortpproxy_str parameter - 1.8. Set db_url parameter - 1.9. Set db_table parameter - 1.10. Set rtpp_socket_col parameter - 1.11. Set set_id parameter - 1.12. Set rtpp_notify_socket parameter - 1.13. Set generated_sdp_port_min parameter - 1.14. Set generated_sdp_port_max parameter - 1.15. Set generated_sdp_media_ip parameter - 1.16. rtpproxy_engage usage - 1.17. rtpproxy_offer usage - 1.18. rtpproxy_answer usage - 1.19. rtpproxy_unforce usage - 1.20. rtpproxy_stream2xxx usage - 1.21. rtpproxy_start_recording usage - 1.22. rtpproxy_stats usage - 1.23. rtpproxy_all_stats usage - 1.24. rtpproxy_enable usage - 1.25. rtpproxy_show usage - 1.26. rtpproxy_reload usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module is used by OpenSIPS to communicate with RTPProxy, a - media relay proxy used to make the communication between user - agents behind NAT possible. - - This module is also used along with RTPProxy to record media - streams between user agents or to play media to either UAc or - UAs. - -1.2. Multiple RTPProxy usage - - Currently, the rtpproxy module can support multiple rtpproxies - for balancing/distribution and control/selection purposes. - - The module allows the definition of several sets of rtpproxies - - load-balancing will be performed over a set and the user has - the ability to choose what set should be used. The set is - selected via its id - the id being defined along with the set. - Refer to the “rtpproxy_sock” module parameter definition for - syntax description. - - The balancing inside a set is done automatically by the module - based on the weight of each rtpproxy from the set. Note that if - rtpproxy has weight 0, it will be used only when no other - rtpproxies (with a different weight value than 0) respond. - Default weight is 1. - - Starting with OpenSIPS 2.1, engage_rtp_proxy(), - unforce_rtp_proxy() and start_recording() functions have been - fully replaced by rtpproxy_engage(), rtpproxy_unforce() and - rtpproxy_start_recording(). - - IMPORTANT: if you use multiple sets, make sure you use the same - set for both rtpproxy_offer()/rtpproxy_answer() and - rtpproxy_unforce()!! - -1.3. RTPProxy timeout notifications - - Nathelper module can also receive timeout notifications from - multiple rtpproxies. RTPProxy can be configured to send - notifications when a session doesn't receive any media for a - configurable interval of time. The rtpproxy modules has - implemented a listener for such notifications and when received - it terminates the dialog at SIP level (send BYE to both ends), - with the help of dialog module. - - In our tests with RTPProxy we observed some limitations and - also provide a patch for it against git commit - “600c80493793bafd2d69427bc22fcb43faad98c5”. It contains an - addition and implements separate timeout parameters for the - phases of session establishment and ongoing sessions. In the - official code a single timeout parameter controls both session - establishment and rtp timeout and the timeout notification is - also sent in the call establishment phase. This is a problem - since we want to detect rtp timeout fast, but also allow a - longer period for call establishment. - - Note that RTPProxy version v2.0.0 has integrated this feature - upstream, therefore this patch is no longer needed. - - To enable timeout notification there are several steps that you - must follow: - - Start OpenSIPS timeout detection by setting the - “rtpp_notify_socket” module parameter in your configuration - script. This is the socket where further notification will be - received from rtpproxies. This socket must be a TCP or UNIX - socket. Also, for all the calls that require notification, the - rtpproxy_engage(), rtpproxy_offer() and rtpproxy_answer() - functions must be called with the “n” flag. - - Configure RTPProxy to use timeout notification by adding the - following command line parameters: - * “ -n timeout_socket” - specifies where the notifications - will be sent. This socket must be the same as - “rtpp_notify_socket” OpenSIPS module parameter. This - parameter is mandatory. - * “ -T ttl” - limits the rtp session timeout to “ttl”. This - parameter is optional and the default value is 60 seconds. - * “ -W ttl” - limits the session establishment timeout to - “ttl”. This parameter is optional and the default value is - 60 seconds. - - All of the previous parameters can be used with the offical - RTPProxy release, except for the last one. It has been added, - together with other modifications to RTPProxy in order to work - properly. The patch is located in the patches directory in the - module. - - To get the patched version from git you must follow theese - steps: - * Get the latest source code: “git clone - git://sippy.git.sourceforge.net/gitroot/sippy/rtpproxy” - * Make a branch from the commit: “git checkout -b branch_name - 600c80493793bafd2d69427bc22fcb43faad98c5” - * Patch RTPProxy: “patch < path_to_rtpproxy_patch” - - The patched version can also be found at: - https://opensips.org/pub/rtpproxy/ - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module - only if you want to load use a database - table from where to load the rtp proxies sets. - * dialog module - if using the rtpproxy_engage functions or - RTPProxy timeout notifications. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. rtpproxy_sock (string) - - Definition of socket(s) used to connect to (a set) RTPProxy. It - may specify a UNIX socket, an IPv4/IPv6 UDP socket or an - IPv4/IPv6 TCP socket. If the protocol part (i.e. “udp:”) is - missing, the socket is treated as a UNIX socket. - - The definition also supports to specify a different IP that - will be advertised instead of the one returned by RTPProxy. - This is useful when having multiple RTPProxy servers that are - located behind NAT, and listen only on private intefaces, but - need to advertise a public one. - - Default value is “NONE” (disabled). - - Example 1.1. Set rtpproxy_sock parameter -... -# single rtpproxy with specific weight -modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222=2") - -# single rtpproxy with advertised address + weight -modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222|8.8.8.8=2") - -# multiple rtproxies for LB -modparam("rtpproxy", "rtpproxy_sock", - "udp:localhost:22222 udp:localhost:22223 tcp:remote1:33422 tcp6: -remote2:32322") - -# multiple sets of multiple rtproxies -modparam("rtpproxy", "rtpproxy_sock", "1 == udp:localhost:22222 udp:loca -lhost:22223") -modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223") -modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223|8.8.8.8" -) -... - -1.5.2. rtpproxy_disable_tout (integer) - - Once RTPProxy was found unreachable and marked as disable, - rtpproxy will not attempt to establish communication to - RTPProxy for rtpproxy_disable_tout seconds. - - Default value is “60”. - - Example 1.2. Set rtpproxy_disable_tout parameter -... -modparam("rtpproxy", "rtpproxy_disable_tout", 20) -... - -1.5.3. rtpproxy_timeout (string) - - Timeout value in waiting for reply from RTPProxy. - - Default value is “1”. - - Example 1.3. Set rtpproxy_timeout parameter to 200ms -... -modparam("rtpproxy", "rtpproxy_timeout", "0.2") -... - -1.5.4. rtpproxy_autobridge (integer) - - Enable auto-bridging feature. Does not properly function when - doing serial/parallel forking! - - Default value is “0”. - - Example 1.4. Enable auto-bridging feature -... -modparam("rtpproxy", "rtpproxy_autobridge", 1) -... - -1.5.5. rtpproxy_retr (integer) - - How many times rtpproxy should retry to send and receive after - timeout was generated. - - Default value is “5”. - - Example 1.5. Set rtpproxy_retr parameter -... -modparam("rtpproxy", "rtpproxy_retr", 2) -... - -1.5.6. default_set (integer) - - The parameter indicates the default RTPProxy set to be used - when provisioning an engine in the config file without an - explicit set, or when calling one of the rtpproxy_*() functions - without an explicit set. - - Default value is set “0”. - - Example 1.6. Set default_set parameter -... -modparam("rtpproxy", "default_set", 1) -... - -1.5.7. nortpproxy_str (string) - - The parameter sets the SDP attribute used by rtpproxy to mark - the packet SDP informations have already been mangled. - - If empty string, no marker will be added or checked. - -Note - - The string must be a complete SDP line, including the EOH - (\r\n). - - Default value is “a=nortpproxy:yes\r\n”. - - Example 1.7. Set nortpproxy_str parameter -... -modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n") -... - -1.5.8. db_url (string) - - The database url. This parameter should be set if you want to - use a database table from where to load or reload definitions - of socket(s) used to connect to (a set) RTPProxy. The record - from the database table will be read at start up (added to the - ones defined with the rtpproxy_sock module parameter) and when - the MI command rtpproxy_reload is issued(the definitions will - be replaced with the ones from the database table). - - Default value is “NULL”. - - Example 1.8. Set db_url parameter -... -modparam("rtpproxy", "db_url", - "mysql://opensips:opensipsrw@192.168.2.132/opensips") -... - - -1.5.9. db_table (string) - - The name of the database table containing definitions of - socket(s) used to connect to (a set) RTPProxy. - - Default value is “rtpproxy_sockets”. - - Example 1.9. Set db_table parameter -... -modparam("rtpproxy", "db_table", "nh_sockets") -... - - -1.5.10. rtpp_socket_col (string) - - The name rtpp socket column in the database table. - - Default value is “rtpproxy_sock”. - - Example 1.10. Set rtpp_socket_col parameter -... -modparam("rtpproxy", "rtpp_socket_col", "rtpp_socket") -... - - -1.5.11. set_id_col (string) - - The name set id column in the database table. - - Default value is “set_id”. - - Example 1.11. Set set_id parameter -... -modparam("rtpproxy", "set_id_col", "rtpp_set_id") -... - - -1.5.12. rtpp_notify_socket (string) - - The socket OpenSIPS listens for notifications from RTPProxy. - Currently OpenSIPS can receive RTP timeout and DTMF events. - - Default value is “NULL” - no notifications are received. - - Example 1.12. Set rtpp_notify_socket parameter -... -modparam("rtpproxy", "rtpp_notify_socket", "tcp:10.10.10.10:9999") - -# use an UNIX socket -modparam("rtpproxy", "rtpp_notify_socket", "unix:/tmp/rtpproxy.unix") -# or -modparam("rtpproxy", "rtpp_notify_socket", "/tmp/rtpproxy.unix") -... - - -1.5.13. generated_sdp_port_min (integer) - - When RTPProxy module needs to generate an SDP body, use this - value as the minimum value of the port. - - Default value is “35000”. - - Example 1.13. Set generated_sdp_port_min parameter -... -modparam("rtpproxy", "generated_sdp_port_min", 10000) -... - -1.5.14. generated_sdp_port_max (integer) - - When RTPProxy module needs to generate an SDP body, use this - value as the maximum value of the port. - - Default value is “65000”. - - Example 1.14. Set generated_sdp_port_max parameter -... -modparam("rtpproxy", "generated_sdp_port_max", 30000) -... - -1.5.15. generated_sdp_media_ip (string) - - When RTPProxy module needs to generate an SDP body, use this - value as the media_ip in the c= and the o=. - - Default value is “127.0.0.1”. - - Example 1.15. Set generated_sdp_media_ip parameter -... -modparam("rtpproxy", "generated_sdp_media_ip", "10.0.0.1") -... - -1.6. Exported Functions - -1.6.1. rtpproxy_engage([[flags][, [ip_address][, [set_id][, -[sock_var][, ret_var]]]]]) - - Rewrites SDP body to ensure that media is passed through an RTP - proxy. It uses the dialog module facilities to keep track when - the rtpproxy session must be updated. Function must only be - called for the initial INVITE and internally takes care of - rewriting the body of 200 OKs and ACKs. Note that when used in - bridge mode, this function might advertise wrong interfaces in - SDP (due to the fact that OpenSIPS is not aware of the RTPProxy - configuration), so you might face an undefined behavior. - - Meaning of the parameters is as follows: - * flags(string, optional) - flags to turn on some features. - + a - flags that UA from which message is received - doesn't support symmetric RTP. - + l - force “lookup”, that is, only rewrite SDP when - corresponding session is already exists in the RTP - proxy. By default is on when the session is to be - completed (reply in non-swap or ACK in swap mode). - + k - only create RTPProxy session, but do not modify - the SDP body. This is useful when you only want to - inject some media, but do not want to engage RTPProxy - in the entire call. - + i/e - when RTPProxy is used in bridge mode, these - flags are used to indicate the direction of the media - flow for the current request/reply. 'i' refers to the - LAN (internal network) and corresponds to the first - interface of RTPProxy (as specified by the -l - parameter). 'e' refers to the WAN (external network) - and corresponds to the second interface of RTPProxy. - These flags should always be used together. For - example, an INVITE (offer) that comes from the - Internet (WAN) to goes to a local media server (LAN) - should use the 'ei' flags. The answer should use the - 'ie' flags. Depending on the scenario, the 'ii' and - 'ee' combination are also supported. Only makes sense - when RTPProxy is running in the bridge mode. - NOTE: when using RTPProxy in bridge mode, all sessions - are considered asymmetric (as oposed to symmetric if - used in normal mode). If you have symmetric clients - (this is the most common scenario), you'll have to - force the s! - + f - instructs rtpproxy to ignore marks inserted by - another rtpproxy in transit to indicate that the - session is already goes through another proxy. Allows - creating chain of proxies. - + r - flags that IP address in SDP should be trusted. - Without this flag, rtpproxy ignores address in the SDP - and uses source address of the SIP message as media - address which is passed to the RTP proxy. - + o - flags that IP from the origin description (o=) - should be also changed. - + c - flags to change the session-level SDP connection - (c=) IP if media-description also includes connection - information. - + s/w - flags that for the UA from which message is - received, support symmetric RTP must be forced. - + n[] - flags that enables the notification - timeout for the session. One can specify an optional - "advertised" socket between the < and > tags. If the - socket is not specified, the value of - rtpp_notify_socket is used. - + d[NNN] - enables DTMF notifications for this call. One - can optionally specify the payload type that DTMF will - be used for this call - it it is not specified, - RTPProxy uses the 101 pt. NOTE: this feature is - currently only available in the RTPProxy rtpp_2_1_dtmf - branch. - + tNN - can be used to specify a RTP ttl for the caller. - The NN represents the timeout in seconds for that - stream. This can be useful in music on hold scenarios - where only one client is sending RTP. - + TNN - Similar to the tNN paramaeter, but used for - tuning the calllee's ttl for RTP. - + zNN - requests the RTPproxy to perform - re-packetization of RTP traffic coming from the UA - which has sent the current message to increase or - decrease payload size per each RTP packet forwarded if - possible. The NN is the target payload size in ms, for - the most codecs its value should be in 10ms - increments, however for some codecs the increment - could differ (e.g. 30ms for GSM or 20ms for G.723). - The RTPproxy would select the closest value supported - by the codec. This feature could be used for - significantly reducing bandwith overhead for low - bitrate codecs, for example with G.729 going from 10ms - to 100ms saves two thirds of the network bandwith. - * ip_address(string, optional) - new SDP IP address. - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. Note that the - variable will only be populated in the initial request. - * ret_var(var, optional) - variable used to print the IP and - port the RTPProxy server is using for this call. This is - useful especially when using the rtp_cluster, which can - advertise multiple servers behind it. The format of the - value returned is IP:port. Note that the variable will only - be populated in the initial request. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE. - - Example 1.16. rtpproxy_engage usage -... -if (is_method("INVITE") && has_totag()) { - if ($var(setid) != 0) { - rtpproxy_engage(,,$var(setid), $var(proxy)); - xlog("SCRIPT: RTPProxy server used is $var(proxy)\n"); - } else { - rtpproxy_engage(); - xlog("SCRIPT: using default RTPProxy set\n"); - } -} -... - -1.6.2. rtpproxy_offer([[flags][, [ip_address][, [set_id][, -[sock_var][, [ret_var][, [body_var]]]]]]) - - Rewrites SDP body to ensure that media is passed through an RTP - proxy. To be invoked on INVITE for the cases the SDPs are in - INVITE and 200 OK and on 200 OK when SDPs are in 200 OK and - ACK. - - The function receives the same parameters as rtpproxy_engage(), - as well as an extra parameter named body_var - this parameter - is used as an in-out variable for the body that should be used - to challenge RTP proxy server. If the variable is specified, it - is the function uses its content as the body to challenge, and - returns the resulted body in it. If not used, the message's - body is used, and the outgoing body is changed. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.17. rtpproxy_offer usage -route { -... - if (is_method("INVITE")) { - if (has_body("application/sdp")) { - if (rtpproxy_offer()) - t_on_reply("1"); - } else { - t_on_reply("2"); - } - } - if (is_method("ACK") && has_body("application/sdp")) - rtpproxy_answer(); -... -} - -onreply_route[1] -{ -... - if (has_body("application/sdp")) - rtpproxy_answer(); -... -} - -onreply_route[2] -{ -... - if (has_body("application/sdp")) - rtpproxy_offer(); -... -} - -1.6.3. rtpproxy_answer([[flags][, [ip_address][, [set_id][, -[sock_var][, [ret_var][, [body_var]]]]]]]) - - Rewrites SDP body to ensure that media is passed through an RTP - proxy. To be invoked on 200 OK for the cases the SDPs are in - INVITE and 200 OK and on ACK when SDPs are in 200 OK and ACK. - - See rtpproxy_offer() function description above for the meaning - of the parameters. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.18. rtpproxy_answer usage - - See rtpproxy_offer() function example above for example. - -1.6.4. rtpproxy_unforce([[set_id][, sock_var]]) - - Tears down the RTPProxy session for the current call. - - Meaning of the parameters is as follows: - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.19. rtpproxy_unforce usage -... -rtpproxy_unforce(); -... - -1.6.5. rtpproxy_stream2uac(prompt_name, count[, [set_id][, -sock_var]]), rtpproxy_stream2uas(prompt_name, count[, [set_id][, -sock_var]]) - - Instruct the RTPproxy to stream prompt/announcement pre-encoded - with the makeann command from the RTPproxy distribution. The - uac/uas suffix selects who will hear the announcement - relatively to the current transaction - UAC or UAS. For example - invoking the rtpproxy_stream2uac in the request processing - block on ACK transaction will play the prompt to the UA that - has generated original INVITE and ACK while - rtpproxy_stop_stream2uas on 183 in reply processing block will - play the prompt to the UA that has generated 183. - - Apart from generating announcements, another possible - application of this function is implementing music on hold - (MOH) functionality. When count is -1, the streaming will be in - loop indefinitely until the appropriate - rtpproxy_stop_stream2xxx is issued. - - In order to work correctly, functions require that the session - in the RTPproxy already exists. Also those functions don't - alted SDP, so that they are not substitute for calling - rtpproxy_offer or rtpproxy_answer. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Meaning of the parameters is as follows: - * prompt_name (string) - name of the prompt to stream. Should - be either absolute pathname or pathname relative to the - directory where RTPproxy runs. - * count (int) - number of times the prompt should be - repeated. The value of -1 means that it will be streaming - in loop indefinitely, until appropriate - rtpproxy_stop_stream2xxx is issued. - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - - Example 1.20. rtpproxy_stream2xxx usage -... - if (is_method("INVITE")) { - rtpproxy_offer(); - if ($rb=~ "0\.0\.0\.0") { - rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", - -1); - } else { - rtpproxy_stop_stream2uas(); - }; - }; -... - -1.6.6. rtpproxy_stop_stream2uac([[set_id][, sock_var]]), -rtpproxy_stop_stream2uas([[set_id][, sock_var]]) - - Stop streaming of announcement/prompt/MOH started previously by - the respective rtpproxy_stream2xxx. The uac/uas suffix selects - whose announcement relatively to tha current transaction should - be stopped - UAC or UAS. - - Meaning of the parameters is as follows: - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - - These functions can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - -1.6.7. rtpproxy_start_recording([[set_id][, [sock_var][, [flags][, -[destination][, mediastream]]]]]) - - This command will send a signal to the RTP-Proxy to record the - RTP stream on the RTP-Proxy. - - Meaning of the parameters is as follows: - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - * flags(string, optional) - a list of flags passed to - RTPProxy for the recording. Currently only s is supported, - and it indicates that RTPProxy should record both audio - legs in a single file. Note that this feature is available - starting with RTPProxy 2.0. - * destination(string, optional) - the destination of the - recording. If it has the udp:IP:port format, RTPProxy sends - the RTP stream to that IP:port remote destination. - Otherwise, destination represents the name of the file in - the recording directory. - * mediastream(int, optional) - this parameter is only used if - the destination is specified, and represents the index of - media stream to record/copy, starting from 1. If this - parameter is missing, OpenSIPS instructs RTPProxy to copy - all the streams. - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - Example 1.21. rtpproxy_start_recording usage -... -rtpproxy_start_recording(); - -# copy RTP stream to a different listener -rtpproxy_start_recording(,,,"udp:127.0.0.1:60000"); - -# copy only first RTP stream (audio stream) -rtpproxy_start_recording(,,,"udp:127.0.0.1:60000", 1); -... - -1.6.8. rtpproxy_stats(up_pvar, down_var, sent_var, fail_var[, -[set_id][, sock_var]]) - - This command gathers call RTP statistics from RTP-Proxy. - - Meaning of the parameters is as follows: - * up_var (var) - the variable used to return the packets sent - by upstream for this call. - * down_var (var) - the variable used to return the packets - sent by downstream for this call. - * sent_var (var) - the variable used to return the total - number of packets sent for this call. - * up_var (var) - the variable used to return the number of - failed packets for this call. - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.22. rtpproxy_stats usage -... -rtpproxy_stats($var(up),$var(down),$var(sent),$var(fail)); -xlog("RTP statistics for $ci: up=$var(up) down=$var(down) sent=$var(sent -) fail=$var(fail)\n"); -... - -1.6.9. rtpproxy_all_stats(stats_avp[, [set_id][, sock_var]]) - - This command gathers all RTP statistics available from - RTP-Proxy. All the returned values stored in an AVP that can be - further read by indexing the AVP. - - This command is only available starting with RTPProxy 2.1 - realease. - - Meaning of the parameters is as follows: - * stats_avp (var) - an AVP where the statistics will be - stored. This AVP can be further indexed to get a specific - statistic. - * set_id(int, optional) - the set used for this call. - * sock_var(var, optional) - variable used to store the - RTPProxy socket chosen for this call. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Each statistic is stored at a specific index as it follows: - * ttl - $avp(ret) / $(avp(ret)[0]) - * pkts_ia - $(avp(ret)[1]) - * pkts_io - $(avp(ret)[2]) - * relayed - $(avp(ret)[3]) - * dropped - $(avp(ret)[4]) - * rtpa_set - $(avp(ret)[5]) - * rtpa_rcvd - $(avp(ret)[6]) - * rtpa_dups - $(avp(ret)[7]) - * rtpa_lost - $(avp(ret)[8]) - * rtpa_perrs - $(avp(ret)[9]) - - Example 1.23. rtpproxy_all_stats usage -... -rtpproxy_all_stats($avp(stats)); -xlog("RTP statistics for $ci: dropped=$(avp(stats)[4])\n"); -... - -1.7. Exported MI Functions - -1.7.1. rtpproxy_enable - - Enables/Disables a rtp proxy. - - Parameters: - * url - the rtp proxy url (exactly as defined in the config - file). - * enable - 1 - enable, 0 - disable the RTPproxy node, 2 - put - the RTPproxy node in probing mode. - * setid (optional) - the rtpproxy set ID (used for better - indentification of the rtpproxy instance to be enabled, for - example when a rtpproxy is used in multiple sets). - - NOTE: if a rtpproxy is defined multiple times (in the same or - different set), all its instances will be enables/disabled IF - no set ID provided (as second param). - - Example 1.24. rtpproxy_enable usage -... -## disable a RTPProxy by URL only -$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 -## disable a RTPProxy by URL and set ID (3) -$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 3 -... - -1.7.2. rtpproxy_show - - Displays all the rtp proxies and their information: set and - status (disabled or not, weight and recheck_ticks). - - No parameter. - - Example 1.25. rtpproxy_show usage -... -$ opensips-cli -x mi rtpproxy_show -... - -1.7.3. rtpproxy_reload - - Reload rtp proxies sets from database. The function will delete - all previous records and populate the list with the entries - from the database table. The db_url parameter must be set if - you want to use this command. - - No parameter. - - Example 1.26. rtpproxy_reload usage -... -$ opensips-cli -x mi rtpproxy_reload -... - -1.8. Exported Events - -1.8.1. E_RTPPROXY_STATUS - - This event is raised when a RTPProxy server changes it's status - to enabled/disabled. - - Parameters: - * socket - the socket that identifies the RTPProxy instance. - * status - active if the RTPProxy instance responds to - probing or inactive if the instance was deactivated. - -1.8.2. E_RTPPROXY_DTMF - - This event is raised when a RTPProxy server sends a DTMF - notification to OpenSIPS. In order to catch RFC 2833/4733 DTMF - events, you need to provide the d flag to rtpproxy_offer()/ - rtpproxy_answer(). - - Parameters: - * digit - the digit pressed. - * duration - the duration of the event. - * volume - the volume of the event. - * id - represents the identifier of the call for which that - event was received. - * is_callid - is 0 if the id parameter represents the Dialog - ID, or 1 if it is a callid. - * stream - indicates the stream index of the RTPProxy - session. It is normally 0 if the caller sent the DTMF, or 1 - if the callee sent it. - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with “rtpproxy_disable” parameter? - - It was removed as it became obsolete - now “rtpproxy_sock” can - take empty value to disable the rtpproxy functionality. - - 2.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.3. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.4. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 267 167 6172 2881 - 2. Maksym Sobolyev (@sobomax) 63 13 5132 308 - 3. Liviu Chircu (@liviuchircu) 30 23 229 244 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 27 23 123 116 - 5. Vlad Patrascu (@rvlad-patrascu) 25 9 409 725 - 6. Peter Lemenkov (@lemenkov) 7 5 60 59 - 7. Ovidiu Sas (@ovidiusas) 7 5 31 22 - 8. Vlad Paiu (@vladpaiu) 6 4 15 9 - 9. Ryan Bullock (@rrb3942) 4 2 68 9 - 10. John Burke (@john08burke) 4 2 8 6 - - All remaining contributors: robdyck, Dave Sidwell - (@davesidwell), Ezequiel Lovelle (@lovelle), Christophe Sollet - (@csollet), Anca Vamanu, Mikko Lehto, Dan Pascu (@danpascu), - Walter Doekes (@wdoekes), Dusan Klinec (@ph4r05), Julián Moreno - Patiño, Norman Brandinger (@NormB), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jul 2012 - Apr 2025 - 2. Razvan Crainea (@razvancrainea) Mar 2011 - Jan 2025 - 3. Norman Brandinger (@NormB) Jun 2024 - Jun 2024 - 4. Maksym Sobolyev (@sobomax) Mar 2011 - May 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 6. Peter Lemenkov (@lemenkov) Dec 2011 - Apr 2022 - 7. John Burke (@john08burke) Apr 2021 - Apr 2021 - 8. Ovidiu Sas (@ovidiusas) Mar 2011 - Jun 2020 - 9. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2011 - Apr 2020 - 10. robdyck Apr 2020 - Apr 2020 - - All remaining contributors: Zero King (@l2dy), Dan Pascu - (@danpascu), Ryan Bullock (@rrb3942), Julián Moreno Patiño, - Vlad Paiu (@vladpaiu), Dusan Klinec (@ph4r05), Dave Sidwell - (@davesidwell), Ezequiel Lovelle (@lovelle), Mikko Lehto, - Walter Doekes (@wdoekes), Christophe Sollet (@csollet), Anca - Vamanu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu - (@liviuchircu), Maksym Sobolyev (@sobomax), Zero King (@l2dy), - Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), - Julián Moreno Patiño, Bogdan-Andrei Iancu (@bogdan-iancu), - Mikko Lehto, Ryan Bullock (@rrb3942), Ovidiu Sas (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2005 Voice Sistem SRL - - Copyright © 2003-2008 Sippy Software, Inc. diff --git a/modules/rtpproxy/README.md b/modules/rtpproxy/README.md new file mode 100644 index 00000000000..ee3ba3ba859 --- /dev/null +++ b/modules/rtpproxy/README.md @@ -0,0 +1,1056 @@ +--- +title: "rtpproxy Module" +description: "This module is used by OpenSIPS to communicate with RTPProxy, a media relay proxy used to make the communication between user agents behind NAT possible." +--- + +## Admin Guide + + +### Overview + + +This module is used by OpenSIPS to communicate with RTPProxy, a media +relay proxy used to make the communication between user agents behind +NAT possible. + + +This module is also used along with RTPProxy to record media streams +between user agents or to play media to either UAc or UAs. + + +### Multiple RTPProxy usage + + +Currently, the rtpproxy module can support multiple rtpproxies for +balancing/distribution and control/selection purposes. + + +The module allows the definition of several sets of rtpproxies - +load-balancing will be performed over a set and the user has the +ability to choose what set should be used. The set is selected via +its id - the id being defined along with the set. Refer to the +"rtpproxy_sock" module parameter definition for syntax +description. + + +The balancing inside a set is done automatically by the module based on +the weight of each rtpproxy from the set. Note that if rtpproxy has weight +0, it will be used only when no other rtpproxies (with a different +weight value than 0) respond. Default weight is 1. + + +Starting with OpenSIPS 2.1, engage_rtp_proxy(), unforce_rtp_proxy() +and start_recording() functions have been fully replaced by +rtpproxy_engage(), rtpproxy_unforce() and rtpproxy_start_recording(). + + +IMPORTANT: if you use multiple sets, make sure you use the same set for +both rtpproxy_offer()/rtpproxy_answer() and rtpproxy_unforce()!! + + +### RTPProxy timeout notifications + + +Nathelper module can also receive timeout notifications from multiple +rtpproxies. RTPProxy can be configured to send notifications when +a session doesn't receive any media for a configurable interval of +time. The rtpproxy modules has implemented a listener for such +notifications and when received it terminates the dialog at SIP +level (send BYE to both ends), with the help of dialog module. + + +In our tests with RTPProxy we observed some limitations and also +provide a patch for it against git commit +"600c80493793bafd2d69427bc22fcb43faad98c5". +It contains an addition and implements separate timeout parameters +for the phases of session establishment and ongoing sessions. +In the official code a single timeout parameter controls +both session establishment and rtp timeout and the timeout +notification is also sent in the call establishment phase. +This is a problem since we want to detect rtp timeout fast, but also +allow a longer period for call establishment. + + +Note that RTPProxy version +[v2.0.0](http://www.rtpproxy.org/post/v2release/) +has integrated this feature upstream, therefore this patch is no +longer needed. + + +To enable timeout notification there are several steps that you must follow: +Start OpenSIPS timeout detection by setting the "rtpp_notify_socket" +module parameter in your configuration script. This is the socket where further +notification will be received from rtpproxies. This socket must be a TCP or +UNIX socket. Also, for all the calls that require notification, the +rtpproxy_engage(), rtpproxy_offer() and rtpproxy_answer() functions must +be called with the "n" flag. +Configure RTPProxy to use timeout notification by adding +the following command line parameters: + + +" -n timeout_socket" - specifies +where the notifications will be sent. This socket +must be the same as "rtpp_notify_socket" +OpenSIPS module parameter. This parameter is mandatory. + + +" -T ttl" - limits the rtp session +timeout to "ttl". This parameter +is optional and the default value is 60 seconds. + + +" -W ttl" - limits the session +establishment timeout to "ttl". +This parameter is optional and the default value +is 60 seconds. +All of the previous parameters can be used with the offical +RTPProxy release, except for the last one. It has been +added, together with other modifications to RTPProxy in order +to work properly. The patch is located in the +*patches* directory in the module. +To get the patched version from git you must follow theese steps: + + +Get the latest source code: "git clone git://sippy.git.sourceforge.net/gitroot/sippy/rtpproxy" + + +Make a branch from the commit: "git checkout +-b branch_name 600c80493793bafd2d69427bc22fcb43faad98c5" + + +Patch RTPProxy: "patch < +path_to_rtpproxy_patch" +The patched version can also be found at: +https://opensips.org/pub/rtpproxy/ + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database* module - only if you want +to load use a database table from where to load the rtp proxies +sets. +- *dialog* module - if using the rtpproxy_engage +functions or RTPProxy timeout notifications. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### rtpproxy_sock (string) + + +Definition of socket(s) used to connect to (a set) RTPProxy. It may +specify a UNIX socket, an IPv4/IPv6 UDP socket or an IPv4/IPv6 TCP socket. +If the protocol part (i.e. "udp:") is missing, the socket is +treated as a UNIX socket. + + +The definition also supports to specify a different IP that will +be advertised instead of the one returned by RTPProxy. This is +useful when having multiple RTPProxy servers that are located +behind NAT, and listen only on private intefaces, but need to +advertise a public one. + + +*Default value is "NONE" (disabled).* + + +```opensips title="Set rtpproxy_sock parameter" +... +# single rtpproxy with specific weight +modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222=2") + +# single rtpproxy with advertised address + weight +modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222|8.8.8.8=2") + +# multiple rtproxies for LB +modparam("rtpproxy", "rtpproxy_sock", + "udp:localhost:22222 udp:localhost:22223 tcp:remote1:33422 tcp6:remote2:32322") + +# multiple sets of multiple rtproxies +modparam("rtpproxy", "rtpproxy_sock", "1 == udp:localhost:22222 udp:localhost:22223") +modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223") +modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223|8.8.8.8") +... +``` + + +#### rtpproxy_disable_tout (integer) + + +Once RTPProxy was found unreachable and marked as disable, rtpproxy +will not attempt to establish communication to RTPProxy for +rtpproxy_disable_tout seconds. + + +*Default value is "60".* + + +```opensips title="Set rtpproxy_disable_tout parameter" +... +modparam("rtpproxy", "rtpproxy_disable_tout", 20) +... +``` + + +#### rtpproxy_timeout (string) + + +Timeout value in waiting for reply from RTPProxy. + + +*Default value is "1".* + + +```opensips title="Set rtpproxy_timeout parameter to 200ms" +... +modparam("rtpproxy", "rtpproxy_timeout", "0.2") +... +``` + + +#### rtpproxy_autobridge (integer) + + +Enable auto-bridging feature. Does not properly function when doing serial/parallel forking! + + +*Default value is "0".* + + +```opensips title="Enable auto-bridging feature" +... +modparam("rtpproxy", "rtpproxy_autobridge", 1) +... +``` + + +#### rtpproxy_retr (integer) + + +How many times rtpproxy should retry to send and receive after +timeout was generated. + + +*Default value is "5".* + + +```opensips title="Set rtpproxy_retr parameter" +... +modparam("rtpproxy", "rtpproxy_retr", 2) +... +``` + + +#### default_set (integer) + + +The parameter indicates the default RTPProxy set to be used when +provisioning an engine in the config file without an explicit set, +or when calling one of the *rtpproxy_*()* +functions without an explicit set. + + +*Default value is set "0".* + + +```opensips title="Set default_set parameter" +... +modparam("rtpproxy", "default_set", 1) +... +``` + + +#### nortpproxy_str (string) + + +The parameter sets the SDP attribute used by rtpproxy to mark +the packet SDP informations have already been mangled. + + +If empty string, no marker will be added or checked. + + +> [!NOTE] +> The string must be a complete SDP line, including the EOH (\r\n). + + +*Default value is "a=nortpproxy:yes\r\n".* + + +```opensips title="Set nortpproxy_str parameter" +... +modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n") +... +``` + + +#### db_url (string) + + +The database url. This parameter should be set if you want to +use a database table from where to load or reload definitions of +socket(s) used to connect to (a set) RTPProxy. The record from +the database table will be read at start up (added to the ones +defined with the rtpproxy_sock module parameter) and when the MI command +rtpproxy_reload is issued(the definitions will be replaced with the +ones from the database table). + + +*Default value is "NULL".* + + +```opensips title="Set db_url parameter" +... +modparam("rtpproxy", "db_url", + "mysql://opensips:opensipsrw@192.168.2.132/opensips") +... +``` + + +#### db_table (string) + + +The name of the database table containing definitions of +socket(s) used to connect to (a set) RTPProxy. + + +*Default value is "rtpproxy_sockets".* + + +```opensips title="Set db_table parameter" +... +modparam("rtpproxy", "db_table", "nh_sockets") +... +``` + + +#### rtpp_socket_col (string) + + +The name rtpp socket column in the database table. + + +*Default value is "rtpproxy_sock".* + + +```opensips title="Set rtpp_socket_col parameter" +... +modparam("rtpproxy", "rtpp_socket_col", "rtpp_socket") +... +``` + + +#### set_id_col (string) + + +The name set id column in the database table. + + +*Default value is "set_id".* + + +```opensips title="Set set_id parameter" +... +modparam("rtpproxy", "set_id_col", "rtpp_set_id") +... +``` + + +#### rtpp_notify_socket (string) + + +The socket OpenSIPS listens for notifications from RTPProxy. +Currently OpenSIPS can receive RTP timeout and DTMF events. + + +*Default value is "NULL" - no notifications are received.* + + +```opensips title="Set rtpp_notify_socket parameter" +... +modparam("rtpproxy", "rtpp_notify_socket", "tcp:10.10.10.10:9999") + +# use an UNIX socket +modparam("rtpproxy", "rtpp_notify_socket", "unix:/tmp/rtpproxy.unix") +# or +modparam("rtpproxy", "rtpp_notify_socket", "/tmp/rtpproxy.unix") +... +``` + + +#### generated_sdp_port_min (integer) + + +When RTPProxy module needs to generate an SDP body, +use this value as the minimum value of the port. + + +*Default value is "35000".* + + +```opensips title="Set generated_sdp_port_min parameter" +... +modparam("rtpproxy", "generated_sdp_port_min", 10000) +... + +``` + + +#### generated_sdp_port_max (integer) + + +When RTPProxy module needs to generate an SDP body, +use this value as the maximum value of the port. + + +*Default value is "65000".* + + +```opensips title="Set generated_sdp_port_max parameter" +... +modparam("rtpproxy", "generated_sdp_port_max", 30000) +... + +``` + + +#### generated_sdp_media_ip (string) + + +When RTPProxy module needs to generate an SDP body, +use this value as the media_ip in the *c=* +and the *o=*. + + +*Default value is "127.0.0.1".* + + +```opensips title="Set generated_sdp_media_ip parameter" +... +modparam("rtpproxy", "generated_sdp_media_ip", "10.0.0.1") +... + +``` + + +### Exported Functions + + +#### rtpproxy_engage([[flags][, [ip_address][, [set_id][, [sock_var][, ret_var]]]]]) + + +Rewrites SDP body to ensure that media is passed through +an RTP proxy. It uses the dialog module facilities to keep track +when the rtpproxy session must be updated. Function must only be +called for the initial INVITE +and internally takes care of rewriting the body of 200 OKs and ACKs. +Note that when used in bridge mode, this function might advertise wrong +interfaces in SDP (due to the fact that OpenSIPS is not aware of the RTPProxy +configuration), so you might face an undefined behavior. + + +Meaning of the parameters is as follows: + + +- *flags(string, optional)* - flags to turn on some features. + + - *a* - flags that UA from which message is +received doesn't support symmetric RTP. + - *l* - force "lookup", that is, +only rewrite SDP when corresponding session is already exists +in the RTP proxy. By default is on when the session is to be +completed (reply in non-swap or ACK in swap mode). + - *k* - only create RTPProxy session, but do +not modify the SDP body. This is useful when you only want to +inject some media, but do not want to engage RTPProxy in the +entire call. + - *i/e* - when RTPProxy is used in bridge mode, +these flags are used to indicate the direction of the media flow +for the current request/reply. 'i' refers to the LAN (internal +network) and corresponds to the first interface of RTPProxy (as +specified by the -l parameter). 'e' refers to the WAN (external +network) and corresponds to the second interface of RTPProxy. +These flags should always be used together. For example, an +INVITE (offer) that comes from the Internet (WAN) to goes to a +local media server (LAN) should use the 'ei' flags. The answer +should use the 'ie' flags. Depending on the scenario, the 'ii' +and 'ee' combination are also supported. Only makes sense when +RTPProxy is running in the bridge mode. +*NOTE:* when using RTPProxy in bridge mode, +all sessions are considered asymmetric (as oposed to symmetric +if used in normal mode). If you have symmetric clients (this +is the most common scenario), you'll have to force the +*s*! + - *f* - instructs rtpproxy to ignore marks +inserted by another rtpproxy in transit to indicate that the +session is already goes through another proxy. Allows creating +chain of proxies. + - *r* - flags that IP address in SDP should +be trusted. Without this flag, rtpproxy ignores address in +the SDP and uses source address of the SIP message as media +address which is passed to the RTP proxy. + - *o* - flags that IP from the origin +description (o=) should be also changed. + - *c* - flags to change the session-level +SDP connection (c=) IP if media-description also includes +connection information. + - *s/w* - flags that for the UA from which +message is received, support symmetric RTP must be forced. + - *n[]* - flags that enables +the notification timeout for the session. One can specify an +optional "advertised" socket between the < and > tags. +If the socket is not specified, the value of +*rtpp_notify_socket* is used. + - *d[NNN]* - enables DTMF notifications for this +call. One can optionally specify the payload type that DTMF will +be used for this call - it it is not specified, RTPProxy uses the +*101* pt. *NOTE:* this feature +is currently only available in the RTPProxy +*rtpp_2_1_dtmf* branch. + - *tNN* - can be used to specify a RTP +ttl for the caller. The NN represents the timeout in seconds +for that stream. This can be useful in music on hold scenarios +where only one client is sending RTP. + - *TNN* - Similar to the *tNN* +paramaeter, but used for tuning the calllee's ttl for RTP. + - *zNN* - requests the RTPproxy to perform +re-packetization of RTP traffic coming from the UA which +has sent the current message to increase or decrease payload +size per each RTP packet forwarded if possible. The NN is the +target payload size in ms, for the most codecs its value should +be in 10ms increments, however for some codecs the increment +could differ (e.g. 30ms for GSM or 20ms for G.723). The +RTPproxy would select the closest value supported by the codec. +This feature could be used for significantly reducing bandwith +overhead for low bitrate codecs, for example with G.729 going +from 10ms to 100ms saves two thirds of the network bandwith. +- *ip_address(string, optional)* - new SDP IP address. +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. Note that the variable will only be populated in the +initial request. +- *ret_var(var, optional)* - variable used to print the IP and port +the RTPProxy server is using for this call. This is useful especially when using +the *rtp_cluster*, which can advertise multiple servers behind it. +The format of the value returned is *IP:port*. +Note that the variable will only be populated in the initial request. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="rtpproxy_engage usage" +... +if (is_method("INVITE") && has_totag()) { + if ($var(setid) != 0) { + rtpproxy_engage(,,$var(setid), $var(proxy)); + xlog("SCRIPT: RTPProxy server used is $var(proxy)\n"); + } else { + rtpproxy_engage(); + xlog("SCRIPT: using default RTPProxy set\n"); + } +} +... + +``` + + +#### rtpproxy_offer([[flags][, [ip_address][, [set_id][, [sock_var][, [ret_var][, [body_var]]]]]]) + + +Rewrites SDP body to ensure that media is passed through +an RTP proxy. To be invoked +on INVITE for the cases the SDPs are in INVITE and 200 OK and on 200 OK +when SDPs are in 200 OK and ACK. + + +The function receives the same parameters as +`rtpproxy_engage()`, as well as an extra +parameter named *body_var* - this parameter +is used as an in-out variable for the body that should be used +to challenge RTP proxy server. If the variable is specified, +it is the function uses its content as the body to challenge, +and returns the resulted body in it. If not used, the message's +body is used, and the outgoing body is changed. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="rtpproxy_offer usage" +route { +... + if (is_method("INVITE")) { + if (has_body("application/sdp")) { + if (rtpproxy_offer()) + t_on_reply("1"); + } else { + t_on_reply("2"); + } + } + if (is_method("ACK") && has_body("application/sdp")) + rtpproxy_answer(); +... +} + +onreply_route[1] +{ +... + if (has_body("application/sdp")) + rtpproxy_answer(); +... +} + +onreply_route[2] +{ +... + if (has_body("application/sdp")) + rtpproxy_offer(); +... +} +``` + + +#### rtpproxy_answer([[flags][, [ip_address][, [set_id][, [sock_var][, [ret_var][, [body_var]]]]]]]) + + +Rewrites SDP body to ensure that media is passed through +an RTP proxy. To be invoked +on 200 OK for the cases the SDPs are in INVITE and 200 OK and on ACK +when SDPs are in 200 OK and ACK. + + +See `rtpproxy_offer()` function description +above for the meaning of the parameters. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +See rtpproxy_offer() function example above for example. + + +#### rtpproxy_unforce([[set_id][, sock_var]]) + + +Tears down the RTPProxy session for the current call. + + +Meaning of the parameters is as follows: + + +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="rtpproxy_unforce usage" +... +rtpproxy_unforce(); +... +``` + + +#### rtpproxy_stream2uac(prompt_name, count[, [set_id][, sock_var]]), rtpproxy_stream2uas(prompt_name, count[, [set_id][, sock_var]]) + + +Instruct the RTPproxy to stream prompt/announcement pre-encoded with +the makeann command from the RTPproxy distribution. The uac/uas +suffix selects who will hear the announcement relatively to the current +transaction - UAC or UAS. For example invoking the +`rtpproxy_stream2uac` in the request processing +block on ACK transaction will play the prompt to the UA that has +generated original INVITE and ACK while +`rtpproxy_stop_stream2uas` on 183 in reply +processing block will play the prompt to the UA that has generated 183. + + +Apart from generating announcements, another possible application +of this function is implementing music on hold (MOH) functionality. +When count is -1, the streaming will be in loop indefinitely until +the appropriate `rtpproxy_stop_stream2xxx` is issued. + + +In order to work correctly, functions require that the session in the +RTPproxy already exists. Also those functions don't alted SDP, so that +they are not substitute for calling `rtpproxy_offer` +or `rtpproxy_answer`. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +Meaning of the parameters is as follows: + + +- *prompt_name* (string) - name of the prompt to +stream. Should be either absolute pathname or pathname +relative to the directory where RTPproxy runs. +- *count* (int) - number of times the prompt +should be repeated. The value of -1 means that it will +be streaming in loop indefinitely, until appropriate +`rtpproxy_stop_stream2xxx` is issued. +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. + + +```opensips title="rtpproxy_stream2xxx usage" +... + if (is_method("INVITE")) { + rtpproxy_offer(); + if ($rb=~ "0\.0\.0\.0") { + rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", -1); + } else { + rtpproxy_stop_stream2uas(); + }; + }; +... + +``` + + +#### rtpproxy_stop_stream2uac([[set_id][, sock_var]]), rtpproxy_stop_stream2uas([[set_id][, sock_var]]) + + +Stop streaming of announcement/prompt/MOH started previously by the +respective `rtpproxy_stream2xxx`. The uac/uas +suffix selects whose announcement relatively to tha current +transaction should be stopped - UAC or UAS. + + +Meaning of the parameters is as follows: + + +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. + + +These functions can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +#### rtpproxy_start_recording([[set_id][, [sock_var][, [flags][, [destination][, mediastream]]]]]) + + +This command will send a signal to the RTP-Proxy to record +the RTP stream on the RTP-Proxy. + + +Meaning of the parameters is as follows: + + +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. +- *flags(string, optional)* - a list of flags passed to +RTPProxy for the recording. Currently only *s* +is supported, and it indicates that RTPProxy should record both +audio legs in a single file. Note that this feature is available +starting with RTPProxy 2.0. +- *destination(string, optional)* - the destination of +the recording. If it has the *udp:IP:port* +format, RTPProxy sends the RTP stream to that *IP:port* +remote destination. Otherwise, destination represents the name +of the file in the recording directory. +- *mediastream(int, optional)* - this parameter is only used +if the *destination* is specified, and represents +the index of media stream to record/copy, starting from 1. If this parameter +is missing, OpenSIPS instructs RTPProxy to copy all the streams. + + +This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. + + +```opensips title="rtpproxy_start_recording usage" +... +rtpproxy_start_recording(); + +# copy RTP stream to a different listener +rtpproxy_start_recording(,,,"udp:127.0.0.1:60000"); + +# copy only first RTP stream (audio stream) +rtpproxy_start_recording(,,,"udp:127.0.0.1:60000", 1); +... + +``` + + +#### rtpproxy_stats(up_pvar, down_var, sent_var, fail_var[, [set_id][, sock_var]]) + + +This command gathers call RTP statistics from RTP-Proxy. + + +Meaning of the parameters is as follows: + + +- *up_var* (var) - the variable used to return the +packets sent by *upstream* for this call. +- *down_var* (var) - the variable used to return the +packets sent by *downstream* for this call. +- *sent_var* (var) - the variable used to return the +total number of packets sent for this call. +- *up_var* (var) - the variable used to return the +number of failed packets for this call. +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="rtpproxy_stats usage" +... +rtpproxy_stats($var(up),$var(down),$var(sent),$var(fail)); +xlog("RTP statistics for $ci: up=$var(up) down=$var(down) sent=$var(sent) fail=$var(fail)\n"); +... + +``` + + +#### rtpproxy_all_stats(stats_avp[, [set_id][, sock_var]]) + + +This command gathers all RTP statistics available from RTP-Proxy. +All the returned values stored in an AVP that can be further read by +indexing the AVP. + + +This command is only available starting with RTPProxy 2.1 realease. + + +Meaning of the parameters is as follows: + + +- *stats_avp* (var) - an AVP where the +statistics will be stored. This AVP can be further +indexed to get a specific statistic. +- *set_id(int, optional)* - the set used for this call. +- *sock_var(var, optional)* - variable used to store the RTPProxy +socket chosen for this call. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +Each statistic is stored at a specific index as it follows: + + +- *ttl* - +*$avp(ret)* / +*$(avp(ret)[0])* +- *pkts_ia* - +*$(avp(ret)[1])* +- *pkts_io* - +*$(avp(ret)[2])* +- *relayed* - +*$(avp(ret)[3])* +- *dropped* - +*$(avp(ret)[4])* +- *rtpa_set* - +*$(avp(ret)[5])* +- *rtpa_rcvd* - +*$(avp(ret)[6])* +- *rtpa_dups* - +*$(avp(ret)[7])* +- *rtpa_lost* - +*$(avp(ret)[8])* +- *rtpa_perrs* - +*$(avp(ret)[9])* + + +```opensips title="rtpproxy_all_stats usage" +... +rtpproxy_all_stats($avp(stats)); +xlog("RTP statistics for $ci: dropped=$(avp(stats)[4])\n"); +... + +``` + + +### Exported MI Functions + + +#### rtpproxy_enable + + +Enables/Disables a rtp proxy. + + +Parameters: + + +- *url* - the rtp proxy url (exactly as defined in +the config file). +- *enable* - 1 - enable, 0 - disable the RTPproxy node, 2 - put the RTPproxy node in probing mode. +- *setid* (optional) - the rtpproxy set ID (used +for better indentification of the rtpproxy instance to be enabled, +for example when a rtpproxy is used in multiple sets). + + +> [!NOTE] +> If a rtpproxy is defined multiple times (in the same or +> different set), all its instances will be enables/disabled IF +> no set ID provided (as second param). + + +```bash title="rtpproxy_enable usage" +... +## disable a RTPProxy by URL only +$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 +## disable a RTPProxy by URL and set ID (3) +$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 3 +... +``` + + +#### rtpproxy_show + + +Displays all the rtp proxies and their information: set and +status (disabled or not, weight and recheck_ticks). + + +No parameter. + + +```bash title="rtpproxy_show usage" +... +$ opensips-cli -x mi rtpproxy_show +... +``` + + +#### rtpproxy_reload + + +Reload rtp proxies sets from database. The function will delete all +previous records and populate the list with the entries from the +database table. The db_url parameter must be set if you want to use +this command. + + +No parameter. + + +```bash title="rtpproxy_reload usage" +... +$ opensips-cli -x mi rtpproxy_reload +... +``` + + +### Exported Events + + +#### E_RTPPROXY_STATUS + + +This event is raised when a RTPProxy server changes it's status to +enabled/disabled. + + +Parameters: + + +- *socket* - the socket that identifies the +RTPProxy instance. +- *status* - *active* if +the RTPProxy instance responds to probing or +*inactive* if the instance was deactivated. + + +#### E_RTPPROXY_DTMF + + +This event is raised when a RTPProxy server sends a DTMF +notification to OpenSIPS. In order to catch RFC 2833/4733 +DTMF events, you need to provide the *d* +flag to *rtpproxy_offer()*/ +*rtpproxy_answer()*. + + +Parameters: + + +- *digit* - the digit pressed. +- *duration* - the duration of the event. +- *volume* - the volume of the event. +- *id* - represents the identifier of +the call for which that event was received. +- *is_callid* - is *0* +if the *id* parameter represents the +Dialog ID, or *1* if it is a callid. +- *stream* - indicates the stream index +of the RTPProxy session. It is normally 0 if the caller +sent the DTMF, or 1 if the callee sent it. + + +## Frequently Asked Questions + + +**Q: What happened with "rtpproxy_disable" parameter?** + + +It was removed as it became obsolete - now +"rtpproxy_sock" can take empty value to disable the +rtpproxy functionality. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/rtpproxy/doc/contributors.xml b/modules/rtpproxy/doc/contributors.xml deleted file mode 100644 index 2bfcfc2d436..00000000000 --- a/modules/rtpproxy/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 267 - 167 - 6172 - 2881 - - - 2. - Maksym Sobolyev (@sobomax) - 63 - 13 - 5132 - 308 - - - 3. - Liviu Chircu (@liviuchircu) - 30 - 23 - 229 - 244 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 27 - 23 - 123 - 116 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 25 - 9 - 409 - 725 - - - 6. - Peter Lemenkov (@lemenkov) - 7 - 5 - 60 - 59 - - - 7. - Ovidiu Sas (@ovidiusas) - 7 - 5 - 31 - 22 - - - 8. - Vlad Paiu (@vladpaiu) - 6 - 4 - 15 - 9 - - - 9. - Ryan Bullock (@rrb3942) - 4 - 2 - 68 - 9 - - - 10. - John Burke (@john08burke) - 4 - 2 - 8 - 6 - - - -
-All remaining contributors: robdyck, Dave Sidwell (@davesidwell), Ezequiel Lovelle (@lovelle), Christophe Sollet (@csollet), Anca Vamanu, Mikko Lehto, Dan Pascu (@danpascu), Walter Doekes (@wdoekes), Dusan Klinec (@ph4r05), Julián Moreno Patiño, Norman Brandinger (@NormB), Zero King (@l2dy). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jul 2012 - Apr 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Mar 2011 - Jan 2025 - - - 3. - Norman Brandinger (@NormB) - Jun 2024 - Jun 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Mar 2011 - May 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 6. - Peter Lemenkov (@lemenkov) - Dec 2011 - Apr 2022 - - - 7. - John Burke (@john08burke) - Apr 2021 - Apr 2021 - - - 8. - Ovidiu Sas (@ovidiusas) - Mar 2011 - Jun 2020 - - - 9. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2011 - Apr 2020 - - - 10. - robdyck - Apr 2020 - Apr 2020 - - - -
-All remaining contributors: Zero King (@l2dy), Dan Pascu (@danpascu), Ryan Bullock (@rrb3942), Julián Moreno Patiño, Vlad Paiu (@vladpaiu), Dusan Klinec (@ph4r05), Dave Sidwell (@davesidwell), Ezequiel Lovelle (@lovelle), Mikko Lehto, Walter Doekes (@wdoekes), Christophe Sollet (@csollet), Anca Vamanu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Liviu Chircu (@liviuchircu), Maksym Sobolyev (@sobomax), Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Julián Moreno Patiño, Bogdan-Andrei Iancu (@bogdan-iancu), Mikko Lehto, Ryan Bullock (@rrb3942), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/rtpproxy/doc/rtpproxy.xml b/modules/rtpproxy/doc/rtpproxy.xml deleted file mode 100644 index f9e7dae0d85..00000000000 --- a/modules/rtpproxy/doc/rtpproxy.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - rtpproxy Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005 &voicesystem; - ©right; 2003-2008 Sippy Software, Inc. - diff --git a/modules/rtpproxy/doc/rtpproxy_admin.xml b/modules/rtpproxy/doc/rtpproxy_admin.xml deleted file mode 100644 index 2ae4c9b2b04..00000000000 --- a/modules/rtpproxy/doc/rtpproxy_admin.xml +++ /dev/null @@ -1,1267 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module is used by &osips; to communicate with RTPProxy, a media - relay proxy used to make the communication between user agents behind - NAT possible. - - - This module is also used along with RTPProxy to record media streams - between user agents or to play media to either &ua;c or &ua;s. - -
- - -
- Multiple RTPProxy usage - - Currently, the rtpproxy module can support multiple rtpproxies for - balancing/distribution and control/selection purposes. - - - The module allows the definition of several sets of rtpproxies - - load-balancing will be performed over a set and the user has the - ability to choose what set should be used. The set is selected via - its id - the id being defined along with the set. Refer to the - rtpproxy_sock module parameter definition for syntax - description. - - - The balancing inside a set is done automatically by the module based on - the weight of each rtpproxy from the set. Note that if rtpproxy has weight - 0, it will be used only when no other rtpproxies (with a different - weight value than 0) respond. Default weight is 1. - - - Starting with &osips; 2.1, engage_rtp_proxy(), unforce_rtp_proxy() - and start_recording() functions have been fully replaced by - rtpproxy_engage(), rtpproxy_unforce() and rtpproxy_start_recording(). - - - IMPORTANT: if you use multiple sets, make sure you use the same set for - both rtpproxy_offer()/rtpproxy_answer() and rtpproxy_unforce()!! - -
- -
- RTPProxy timeout notifications - - Nathelper module can also receive timeout notifications from multiple - rtpproxies. RTPProxy can be configured to send notifications when - a session doesn't receive any media for a configurable interval of - time. The rtpproxy modules has implemented a listener for such - notifications and when received it terminates the dialog at SIP - level (send BYE to both ends), with the help of dialog module. - - - In our tests with RTPProxy we observed some limitations and also - provide a patch for it against git commit - 600c80493793bafd2d69427bc22fcb43faad98c5. - It contains an addition and implements separate timeout parameters - for the phases of session establishment and ongoing sessions. - In the official code a single timeout parameter controls - both session establishment and rtp timeout and the timeout - notification is also sent in the call establishment phase. - This is a problem since we want to detect rtp timeout fast, but also - allow a longer period for call establishment. - - - Note that RTPProxy version - v2.0.0 - has integrated this feature upstream, therefore this patch is no - longer needed. - - - To enable timeout notification there are several steps that you must follow: - - Start &osips; timeout detection by setting the rtpp_notify_socket - module parameter in your configuration script. This is the socket where further - notification will be received from rtpproxies. This socket must be a TCP or - UNIX socket. Also, for all the calls that require notification, the - rtpproxy_engage(), rtpproxy_offer() and rtpproxy_answer() functions must - be called with the n flag. - - - Configure RTPProxy to use timeout notification by adding - the following command line parameters: - - - -n timeout_socket - specifies - where the notifications will be sent. This socket - must be the same as rtpp_notify_socket - &osips; module parameter. This parameter is mandatory. - - - - -T ttl - limits the rtp session - timeout to ttl. This parameter - is optional and the default value is 60 seconds. - - - - -W ttl - limits the session - establishment timeout to ttl. - This parameter is optional and the default value - is 60 seconds. - - - - - - All of the previous parameters can be used with the offical - RTPProxy release, except for the last one. It has been - added, together with other modifications to RTPProxy in order - to work properly. The patch is located in the - patches directory in the module. - - - To get the patched version from git you must follow theese steps: - - - - Get the latest source code: git clone git://sippy.git.sourceforge.net/gitroot/sippy/rtpproxy - - - - - Make a branch from the commit: git checkout - -b branch_name 600c80493793bafd2d69427bc22fcb43faad98c5 - - - - - Patch RTPProxy: patch < - path_to_rtpproxy_patch - - - - - - The patched version can also be found at: - https://opensips.org/pub/rtpproxy/ - - -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module - only if you want - to load use a database table from where to load the rtp proxies - sets. - - - - - - dialog module - if using the rtpproxy_engage - functions or RTPProxy timeout notifications. - - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>rtpproxy_sock</varname> (string) - - Definition of socket(s) used to connect to (a set) RTPProxy. It may - specify a UNIX socket, an IPv4/IPv6 UDP socket or an IPv4/IPv6 TCP socket. - If the protocol part (i.e. udp:) is missing, the socket is - treated as a UNIX socket. - - - The definition also supports to specify a different IP that will - be advertised instead of the one returned by RTPProxy. This is - useful when having multiple RTPProxy servers that are located - behind NAT, and listen only on private intefaces, but need to - advertise a public one. - - - - Default value is NONE (disabled). - - - - Set <varname>rtpproxy_sock</varname> parameter - -... -# single rtpproxy with specific weight -modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222=2") - -# single rtpproxy with advertised address + weight -modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:22222|8.8.8.8=2") - -# multiple rtproxies for LB -modparam("rtpproxy", "rtpproxy_sock", - "udp:localhost:22222 udp:localhost:22223 tcp:remote1:33422 tcp6:remote2:32322") - -# multiple sets of multiple rtproxies -modparam("rtpproxy", "rtpproxy_sock", "1 == udp:localhost:22222 udp:localhost:22223") -modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223") -modparam("rtpproxy", "rtpproxy_sock", "2 == udp:localhost:22223|8.8.8.8") -... - - -
-
- <varname>rtpproxy_disable_tout</varname> (integer) - - Once RTPProxy was found unreachable and marked as disable, rtpproxy - will not attempt to establish communication to RTPProxy for - rtpproxy_disable_tout seconds. - - - - Default value is 60. - - - - Set <varname>rtpproxy_disable_tout</varname> parameter - -... -modparam("rtpproxy", "rtpproxy_disable_tout", 20) -... - - -
-
- <varname>rtpproxy_timeout</varname> (string) - - Timeout value in waiting for reply from RTPProxy. - - - - Default value is 1. - - - - Set <varname>rtpproxy_timeout</varname> parameter to 200ms - -... -modparam("rtpproxy", "rtpproxy_timeout", "0.2") -... - - -
-
- <varname>rtpproxy_autobridge</varname> (integer) - - Enable auto-bridging feature. Does not properly function when doing serial/parallel forking! - - - - Default value is 0. - - - - Enable auto-bridging feature - -... -modparam("rtpproxy", "rtpproxy_autobridge", 1) -... - - -
-
- <varname>rtpproxy_retr</varname> (integer) - - How many times rtpproxy should retry to send and receive after - timeout was generated. - - - - Default value is 5. - - - - Set <varname>rtpproxy_retr</varname> parameter - -... -modparam("rtpproxy", "rtpproxy_retr", 2) -... - - -
- -
- <varname>default_set</varname> (integer) - - The parameter indicates the default RTPProxy set to be used when - provisioning an engine in the config file without an explicit set, - or when calling one of the rtpproxy_*() - functions without an explicit set. - - - - Default value is set 0. - - - - Set <varname>default_set</varname> parameter - -... -modparam("rtpproxy", "default_set", 1) -... - - -
-
- <varname>nortpproxy_str</varname> (string) - - The parameter sets the SDP attribute used by rtpproxy to mark - the packet SDP informations have already been mangled. - - - If empty string, no marker will be added or checked. - - - The string must be a complete SDP line, including the EOH (\r\n). - - - - Default value is a=nortpproxy:yes\r\n. - - - - Set <varname>nortpproxy_str</varname> parameter - -... -modparam("rtpproxy", "nortpproxy_str", "a=sdpmangled:yes\r\n") -... - - -
- -
- <varname>db_url</varname> (string) - - The database url. This parameter should be set if you want to - use a database table from where to load or reload definitions of - socket(s) used to connect to (a set) RTPProxy. The record from - the database table will be read at start up (added to the ones - defined with the rtpproxy_sock module parameter) and when the MI command - rtpproxy_reload is issued(the definitions will be replaced with the - ones from the database table). - - - - Default value is NULL. - - - - - Set <varname>db_url</varname> parameter - -... -modparam("rtpproxy", "db_url", - "mysql://opensips:opensipsrw@192.168.2.132/opensips") -... - - - -
- -
- <varname>db_table</varname> (string) - - The name of the database table containing definitions of - socket(s) used to connect to (a set) RTPProxy. - - - - Default value is rtpproxy_sockets. - - - - - Set <varname>db_table</varname> parameter - -... -modparam("rtpproxy", "db_table", "nh_sockets") -... - - - -
- -
- <varname>rtpp_socket_col</varname> (string) - - The name rtpp socket column in the database table. - - - - Default value is rtpproxy_sock. - - - - - Set <varname>rtpp_socket_col</varname> parameter - -... -modparam("rtpproxy", "rtpp_socket_col", "rtpp_socket") -... - - - -
- -
- <varname>set_id_col</varname> (string) - - The name set id column in the database table. - - - - Default value is set_id. - - - - - Set <varname>set_id</varname> parameter - -... -modparam("rtpproxy", "set_id_col", "rtpp_set_id") -... - - - -
- -
- <varname>rtpp_notify_socket</varname> (string) - - The socket &osips; listens for notifications from RTPProxy. - Currently &osips; can receive RTP timeout and DTMF events. - - - - Default value is NULL - no notifications are received. - - - - - Set <varname>rtpp_notify_socket</varname> parameter - -... -modparam("rtpproxy", "rtpp_notify_socket", "tcp:10.10.10.10:9999") - -# use an UNIX socket -modparam("rtpproxy", "rtpp_notify_socket", "unix:/tmp/rtpproxy.unix") -# or -modparam("rtpproxy", "rtpp_notify_socket", "/tmp/rtpproxy.unix") -... - - - -
- -
- <varname>generated_sdp_port_min</varname> (integer) - - When RTPProxy module needs to generate an SDP body, - use this value as the minimum value of the port. - - - - Default value is 35000. - - - Set <varname>generated_sdp_port_min</varname> parameter - -... -modparam("rtpproxy", "generated_sdp_port_min", 10000) -... - - -
- -
- <varname>generated_sdp_port_max</varname> (integer) - - When RTPProxy module needs to generate an SDP body, - use this value as the maximum value of the port. - - - - Default value is 65000. - - - Set <varname>generated_sdp_port_max</varname> parameter - -... -modparam("rtpproxy", "generated_sdp_port_max", 30000) -... - - -
- -
- <varname>generated_sdp_media_ip</varname> (string) - - When RTPProxy module needs to generate an SDP body, - use this value as the media_ip in the c= - and the o=. - - - - Default value is 127.0.0.1. - - - Set <varname>generated_sdp_media_ip</varname> parameter - -... -modparam("rtpproxy", "generated_sdp_media_ip", "10.0.0.1") -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">rtpproxy_engage([[flags][, [ip_address][, [set_id][, [sock_var][, ret_var]]]]])</function> - - - - Rewrites &sdp; body to ensure that media is passed through - an &rtp; proxy. It uses the dialog module facilities to keep track - when the rtpproxy session must be updated. Function must only be - called for the initial INVITE - and internally takes care of rewriting the body of 200 OKs and ACKs. - Note that when used in bridge mode, this function might advertise wrong - interfaces in &sdp; (due to the fact that &osips; is not aware of the RTPProxy - configuration), so you might face an undefined behavior. - - Meaning of the parameters is as follows: - - - - flags(string, optional) - flags to turn on some features. - - - - a - flags that UA from which message is - received doesn't support symmetric RTP. - - - l - force lookup, that is, - only rewrite SDP when corresponding session is already exists - in the RTP proxy. By default is on when the session is to be - completed (reply in non-swap or ACK in swap mode). - - - k - only create RTPProxy session, but do - not modify the SDP body. This is useful when you only want to - inject some media, but do not want to engage RTPProxy in the - entire call. - - - i/e - when RTPProxy is used in bridge mode, - these flags are used to indicate the direction of the media flow - for the current request/reply. 'i' refers to the LAN (internal - network) and corresponds to the first interface of RTPProxy (as - specified by the -l parameter). 'e' refers to the WAN (external - network) and corresponds to the second interface of RTPProxy. - These flags should always be used together. For example, an - INVITE (offer) that comes from the Internet (WAN) to goes to a - local media server (LAN) should use the 'ei' flags. The answer - should use the 'ie' flags. Depending on the scenario, the 'ii' - and 'ee' combination are also supported. Only makes sense when - RTPProxy is running in the bridge mode. - - NOTE: when using RTPProxy in bridge mode, - all sessions are considered asymmetric (as oposed to symmetric - if used in normal mode). If you have symmetric clients (this - is the most common scenario), you'll have to force the - s! - - - f - instructs rtpproxy to ignore marks - inserted by another rtpproxy in transit to indicate that the - session is already goes through another proxy. Allows creating - chain of proxies. - - - r - flags that IP address in SDP should - be trusted. Without this flag, rtpproxy ignores address in - the SDP and uses source address of the SIP message as media - address which is passed to the RTP proxy. - - - o - flags that IP from the origin - description (o=) should be also changed. - - - c - flags to change the session-level - SDP connection (c=) IP if media-description also includes - connection information. - - - s/w - flags that for the UA from which - message is received, support symmetric RTP must be forced. - - - n[<SOCKET>] - flags that enables - the notification timeout for the session. One can specify an - optional "advertised" socket between the < and > tags. - If the socket is not specified, the value of - rtpp_notify_socket is used. - - - d[NNN] - enables DTMF notifications for this - call. One can optionally specify the payload type that DTMF will - be used for this call - it it is not specified, RTPProxy uses the - 101 pt. NOTE: this feature - is currently only available in the RTPProxy - rtpp_2_1_dtmf branch. - - - tNN - can be used to specify a RTP - ttl for the caller. The NN represents the timeout in seconds - for that stream. This can be useful in music on hold scenarios - where only one client is sending RTP. - - - TNN - Similar to the tNN - paramaeter, but used for tuning the calllee's ttl for RTP. - - - zNN - requests the RTPproxy to perform - re-packetization of RTP traffic coming from the UA which - has sent the current message to increase or decrease payload - size per each RTP packet forwarded if possible. The NN is the - target payload size in ms, for the most codecs its value should - be in 10ms increments, however for some codecs the increment - could differ (e.g. 30ms for GSM or 20ms for G.723). The - RTPproxy would select the closest value supported by the codec. - This feature could be used for significantly reducing bandwith - overhead for low bitrate codecs, for example with G.729 going - from 10ms to 100ms saves two thirds of the network bandwith. - - - - - ip_address(string, optional) - new SDP IP address. - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. Note that the variable will only be populated in the - initial request. - - - ret_var(var, optional) - variable used to print the IP and port - the RTPProxy server is using for this call. This is useful especially when using - the rtp_cluster, which can advertise multiple servers behind it. - The format of the value returned is IP:port. - Note that the variable will only be populated in the initial request. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtpproxy_engage</function> usage - -... -if (is_method("INVITE") && has_totag()) { - if ($var(setid) != 0) { - rtpproxy_engage(,,$var(setid), $var(proxy)); - xlog("SCRIPT: RTPProxy server used is $var(proxy)\n"); - } else { - rtpproxy_engage(); - xlog("SCRIPT: using default RTPProxy set\n"); - } -} -... - - -
- -
- - <function moreinfo="none">rtpproxy_offer([[flags][, [ip_address][, [set_id][, [sock_var][, [ret_var][, [body_var]]]]]])</function> - - - Rewrites &sdp; body to ensure that media is passed through - an &rtp; proxy. To be invoked - on INVITE for the cases the SDPs are in INVITE and 200 OK and on 200 OK - when SDPs are in 200 OK and ACK. - - - The function receives the same parameters as - rtpproxy_engage(), as well as an extra - parameter named body_var - this parameter - is used as an in-out variable for the body that should be used - to challenge &rtp; proxy server. If the variable is specified, - it is the function uses its content as the body to challenge, - and returns the resulted body in it. If not used, the message's - body is used, and the outgoing body is changed. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtpproxy_offer</function> usage - -route { -... - if (is_method("INVITE")) { - if (has_body("application/sdp")) { - if (rtpproxy_offer()) - t_on_reply("1"); - } else { - t_on_reply("2"); - } - } - if (is_method("ACK") && has_body("application/sdp")) - rtpproxy_answer(); -... -} - -onreply_route[1] -{ -... - if (has_body("application/sdp")) - rtpproxy_answer(); -... -} - -onreply_route[2] -{ -... - if (has_body("application/sdp")) - rtpproxy_offer(); -... -} - - -
-
- - <function moreinfo="none">rtpproxy_answer([[flags][, [ip_address][, [set_id][, [sock_var][, [ret_var][, [body_var]]]]]]])</function> - - - Rewrites &sdp; body to ensure that media is passed through - an &rtp; proxy. To be invoked - on 200 OK for the cases the SDPs are in INVITE and 200 OK and on ACK - when SDPs are in 200 OK and ACK. - - - See rtpproxy_offer() function description - above for the meaning of the parameters. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtpproxy_answer</function> usage - - See rtpproxy_offer() function example above for example. - - -
-
- - <function moreinfo="none">rtpproxy_unforce([[set_id][, sock_var]])</function> - - - Tears down the RTPProxy session for the current call. - - Meaning of the parameters is as follows: - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>rtpproxy_unforce</function> usage - -... -rtpproxy_unforce(); -... - - -
-
- - <function>rtpproxy_stream2uac(prompt_name, count[, [set_id][, sock_var]])</function>, - <function>rtpproxy_stream2uas(prompt_name, count[, [set_id][, sock_var]])</function> - - - Instruct the RTPproxy to stream prompt/announcement pre-encoded with - the makeann command from the RTPproxy distribution. The uac/uas - suffix selects who will hear the announcement relatively to the current - transaction - UAC or UAS. For example invoking the - rtpproxy_stream2uac in the request processing - block on ACK transaction will play the prompt to the UA that has - generated original INVITE and ACK while - rtpproxy_stop_stream2uas on 183 in reply - processing block will play the prompt to the UA that has generated 183. - - - Apart from generating announcements, another possible application - of this function is implementing music on hold (MOH) functionality. - When count is -1, the streaming will be in loop indefinitely until - the appropriate rtpproxy_stop_stream2xxx is issued. - - - In order to work correctly, functions require that the session in the - RTPproxy already exists. Also those functions don't alted SDP, so that - they are not substitute for calling rtpproxy_offer - or rtpproxy_answer. - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Meaning of the parameters is as follows: - - - - prompt_name (string) - name of the prompt to - stream. Should be either absolute pathname or pathname - relative to the directory where RTPproxy runs. - - - - - count (int) - number of times the prompt - should be repeated. The value of -1 means that it will - be streaming in loop indefinitely, until appropriate - rtpproxy_stop_stream2xxx is issued. - - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - - <function>rtpproxy_stream2xxx</function> usage - -... - if (is_method("INVITE")) { - rtpproxy_offer(); - if ($rb=~ "0\.0\.0\.0") { - rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", -1); - } else { - rtpproxy_stop_stream2uas(); - }; - }; -... - - -
-
- - <function>rtpproxy_stop_stream2uac([[set_id][, sock_var]])</function>, - <function>rtpproxy_stop_stream2uas([[set_id][, sock_var]])</function> - - - Stop streaming of announcement/prompt/MOH started previously by the - respective rtpproxy_stream2xxx. The uac/uas - suffix selects whose announcement relatively to tha current - transaction should be stopped - UAC or UAS. - - Meaning of the parameters is as follows: - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - - These functions can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - -
-
- - <function moreinfo="none">rtpproxy_start_recording([[set_id][, [sock_var][, [flags][, [destination][, mediastream]]]]])</function> - - - This command will send a signal to the RTP-Proxy to record - the RTP stream on the RTP-Proxy. - - Meaning of the parameters is as follows: - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - flags(string, optional) - a list of flags passed to - RTPProxy for the recording. Currently only s - is supported, and it indicates that RTPProxy should record both - audio legs in a single file. Note that this feature is available - starting with RTPProxy 2.0. - - - destination(string, optional) - the destination of - the recording. If it has the udp:IP:port - format, RTPProxy sends the RTP stream to that IP:port - remote destination. Otherwise, destination represents the name - of the file in the recording directory. - - - mediastream(int, optional) - this parameter is only used - if the destination is specified, and represents - the index of media stream to record/copy, starting from 1. If this parameter - is missing, &osips; instructs RTPProxy to copy all the streams. - - - - This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE. - - - <function>rtpproxy_start_recording</function> usage - -... -rtpproxy_start_recording(); - -# copy RTP stream to a different listener -rtpproxy_start_recording(,,,"udp:127.0.0.1:60000"); - -# copy only first RTP stream (audio stream) -rtpproxy_start_recording(,,,"udp:127.0.0.1:60000", 1); -... - - -
-
- - <function moreinfo="none">rtpproxy_stats(up_pvar, down_var, sent_var, fail_var[, [set_id][, sock_var]])</function> - - - This command gathers call RTP statistics from RTP-Proxy. - - Meaning of the parameters is as follows: - - - up_var (var) - the variable used to return the - packets sent by upstream for this call. - - - down_var (var) - the variable used to return the - packets sent by downstream for this call. - - - sent_var (var) - the variable used to return the - total number of packets sent for this call. - - - up_var (var) - the variable used to return the - number of failed packets for this call. - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - <function>rtpproxy_stats</function> usage - -... -rtpproxy_stats($var(up),$var(down),$var(sent),$var(fail)); -xlog("RTP statistics for $ci: up=$var(up) down=$var(down) sent=$var(sent) fail=$var(fail)\n"); -... - - -
-
- - <function moreinfo="none">rtpproxy_all_stats(stats_avp[, [set_id][, sock_var]])</function> - - - This command gathers all RTP statistics available from RTP-Proxy. - All the returned values stored in an AVP that can be further read by - indexing the AVP. - - - This command is only available starting with RTPProxy 2.1 realease. - - Meaning of the parameters is as follows: - - - stats_avp (var) - an AVP where the - statistics will be stored. This AVP can be further - indexed to get a specific statistic. - - - set_id(int, optional) - the set used for this call. - - - sock_var(var, optional) - variable used to store the RTPProxy - socket chosen for this call. - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - - Each statistic is stored at a specific index as it follows: - - ttl - - $avp(ret) / - $(avp(ret)[0]) - - pkts_ia - - $(avp(ret)[1]) - - pkts_io - - $(avp(ret)[2]) - - relayed - - $(avp(ret)[3]) - - dropped - - $(avp(ret)[4]) - - rtpa_set - - $(avp(ret)[5]) - - rtpa_rcvd - - $(avp(ret)[6]) - - rtpa_dups - - $(avp(ret)[7]) - - rtpa_lost - - $(avp(ret)[8]) - - rtpa_perrs - - $(avp(ret)[9]) - - - - - <function>rtpproxy_all_stats</function> usage - -... -rtpproxy_all_stats($avp(stats)); -xlog("RTP statistics for $ci: dropped=$(avp(stats)[4])\n"); -... - - -
-
- - -
- Exported MI Functions -
- <function moreinfo="none">rtpproxy_enable</function> - - Enables/Disables a rtp proxy. - - Parameters: - - - url - the rtp proxy url (exactly as defined in - the config file). - - - enable - 1 - enable, 0 - disable the RTPproxy node, 2 - put the RTPproxy node in probing mode. - - - setid (optional) - the rtpproxy set ID (used - for better indentification of the rtpproxy instance to be enabled, - for example when a rtpproxy is used in multiple sets). - - - - NOTE: if a rtpproxy is defined multiple times (in the same or - different set), all its instances will be enables/disabled IF - no set ID provided (as second param). - - - - <function moreinfo="none">rtpproxy_enable</function> usage - -... -## disable a RTPProxy by URL only -$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 -## disable a RTPProxy by URL and set ID (3) -$ opensips-cli -x mi rtpproxy_enable udp:192.168.2.133:8081 0 3 -... - - -
- -
- <function moreinfo="none">rtpproxy_show</function> - - Displays all the rtp proxies and their information: set and - status (disabled or not, weight and recheck_ticks). - - - No parameter. - - - - <function moreinfo="none">rtpproxy_show</function> usage - -... -$ opensips-cli -x mi rtpproxy_show -... - - -
- -
- <function moreinfo="none">rtpproxy_reload</function> - - Reload rtp proxies sets from database. The function will delete all - previous records and populate the list with the entries from the - database table. The db_url parameter must be set if you want to use - this command. - - - No parameter. - - - - <function moreinfo="none">rtpproxy_reload</function> usage - -... -$ opensips-cli -x mi rtpproxy_reload -... - - -
- - -
- -
- Exported Events -
- - <function moreinfo="none">E_RTPPROXY_STATUS</function> - - - This event is raised when a RTPProxy server changes it's status to - enabled/disabled. - - Parameters: - - - socket - the socket that identifies the - RTPProxy instance. - - - status - active if - the RTPProxy instance responds to probing or - inactive if the instance was deactivated. - - -
-
- - <function moreinfo="none">E_RTPPROXY_DTMF</function> - - - This event is raised when a RTPProxy server sends a DTMF - notification to OpenSIPS. In order to catch RFC 2833/4733 - DTMF events, you need to provide the d - flag to rtpproxy_offer()/ - rtpproxy_answer(). - - Parameters: - - - digit - the digit pressed. - - - duration - the duration of the event. - - - volume - the volume of the event. - - - id - represents the identifier of - the call for which that event was received. - - - is_callid - is 0 - if the id parameter represents the - Dialog ID, or 1 if it is a callid. - - - stream - indicates the stream index - of the RTPProxy session. It is normally 0 if the caller - sent the DTMF, or 1 if the callee sent it. - - -
-
- -
- diff --git a/modules/rtpproxy/doc/rtpproxy_faq.xml b/modules/rtpproxy/doc/rtpproxy_faq.xml deleted file mode 100644 index fedadcbb103..00000000000 --- a/modules/rtpproxy/doc/rtpproxy_faq.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - &faqguide; - - - - What happened with rtpproxy_disable parameter? - - - - It was removed as it became obsolete - now - rtpproxy_sock can take empty value to disable the - rtpproxy functionality. - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/rtpproxy/notification_process.c b/modules/rtpproxy/notification_process.c index 8376e201f4a..14ec2c4d46d 100644 --- a/modules/rtpproxy/notification_process.c +++ b/modules/rtpproxy/notification_process.c @@ -54,11 +54,44 @@ struct rtpp_notify { int fd; char *remaining; int remaining_len; + int linked; union sockaddr_union addr; struct list_head list; }; OSIPS_LIST_HEAD(rtpp_notify_fds); +static void free_rtpp_notify(int fd, struct rtpp_notify *notify) +{ + reactor_proc_del_fd(fd, -1, IO_FD_CLOSING); + if (notify) { + if (notify->linked) + list_del(¬ify->list); + if (notify->remaining) + pkg_free(notify->remaining); + pkg_free(notify); + } + shutdown(fd, SHUT_RDWR); + close(fd); +} + +static int set_nonblocking(int fd) +{ + int flags; + + flags = fcntl(fd, F_GETFL); + if (flags == -1) { + LM_ERR("fcntl(%d, F_GETFL) failed: %s\n", fd, strerror(errno)); + return -1; + } + + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { + LM_ERR("fcntl(%d, F_SETFL) failed: %s\n", fd, strerror(errno)); + return -1; + } + + return 0; +} + static int notification_handler(str *command) { char cmd, *p; @@ -200,7 +233,7 @@ static int rtpproxy_io_callback(int fd, void *fs, int was_timeout) { struct rtpp_notify *notify = (struct rtpp_notify *)fs; char buffer[BUF_LEN]; - int len, left, offset; + int len, left, offset, total; str command; char *p, *start, *sp, *end; @@ -214,59 +247,79 @@ static int rtpproxy_io_callback(int fd, void *fs, int was_timeout) offset = 0; } - do - len = read(fd, buffer + offset, BUF_LEN - offset); - while (len == -1 && errno == EINTR); - - if (len < 0) { - LM_ERR("reading from socket failed: %s\n",strerror(errno)); - return -1; - } - if (len == 0) { - LM_DBG("closing rtpproxy notify socket\n"); - reactor_del_reader(fd, -1, IO_FD_CLOSING); - if (notify) { - list_del(¬ify->list); - pkg_free(notify); + for (;;) { + if (offset == BUF_LEN) { + LM_ERR("RTPProxy notification command too large [%.*s]\n", + offset, buffer); + free_rtpp_notify(fd, notify); + return -1; } - shutdown(fd, SHUT_RDWR); - close(fd); - return 0; - } - LM_DBG("Notification(s) received: [%.*s]\n", len, buffer); - p = buffer; - left = len + offset; - end = buffer + left; + do + len = read(fd, buffer + offset, BUF_LEN - offset); + while (len == -1 && errno == EINTR); - do { - start = p; + if (len < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; - sp = q_memchr(p, '\n', left); - if (sp == NULL) - break; - command.s = p; - command.len = sp - p; - /* skip the command */ - p = sp + 1; - left -= (sp - start) + 1; - - if (notification_handler(&command) < 0) + LM_ERR("reading from socket failed: %s\n",strerror(errno)); + free_rtpp_notify(fd, notify); return -1; + } + if (len == 0) { + if (offset) + LM_WARN("dropping partial RTPProxy notification [%.*s]\n", + offset, buffer); + LM_DBG("closing rtpproxy notify socket\n"); + free_rtpp_notify(fd, notify); + return 0; + } + + total = len + offset; + LM_DBG("Notification(s) received: [%.*s]\n", total, buffer); + p = buffer; + left = total; + end = buffer + total; + + do { + start = p; + + sp = q_memchr(p, '\n', left); + if (sp == NULL) + break; + command.s = p; + command.len = sp - p; + /* skip the command */ + p = sp + 1; + left -= (sp - start) + 1; + + if (notification_handler(&command) < 0) { + LM_ERR("notification_handler failed\n"); + free_rtpp_notify(fd, notify); + return -1; + } - LM_DBG("Left to process: %d\n[%.*s]\n", left, left, p); + LM_DBG("Left to process: %d\n[%.*s]\n", left, left, p); - } while (p < end); + } while (p < end); + + offset = end - p; + if (offset) { + LM_DBG("%d remaining data in buffer!\n", offset); + memmove(buffer, p, offset); + } + } - if (end - p) { - LM_DBG("%d remaining data in buffer!\n", (int)(end - start)); - if (notify && (notify->remaining = pkg_malloc(end - start)) != NULL) { - notify->remaining_len = (int)(end - start); - memcpy(notify->remaining, p, notify->remaining_len); + if (offset) { + if (notify && (notify->remaining = pkg_malloc(offset)) != NULL) { + notify->remaining_len = offset; + memcpy(notify->remaining, buffer, offset); } else { - LM_WARN("dropping remaining data [%.*s]\n", (int)(end - start), start); + LM_WARN("dropping remaining data [%.*s]\n", offset, buffer); } } + return 0; } @@ -285,35 +338,43 @@ static int rtpproxy_io_new_callback(int fd, void *fs, int was_timeout) return -1; } - if (rtpp_notify_socket_un) { - LM_DBG("trusting unix socket connection\n"); - if (reactor_proc_add_fd(fd, rtpproxy_io_callback, NULL)<0) { - LM_CRIT("failed to add RTPProxy new connection to reactor\n"); - return -1; - } - return 0; - } - node = rtpproxy_get_node((union sockaddr_union *)&rtpp_info); - if (!node) { - LM_WARN("connection from unknown RTPProxy node"); - return -1; - } + if (set_nonblocking(fd) < 0) + goto err; notify = pkg_malloc(sizeof *notify); if (!notify) { LM_ERR("could not allocate notify node\n"); - return -1; + goto err; } memset(notify, 0, sizeof *notify); notify->fd = fd; - memcpy(¬ify->addr, &node->addr, sizeof(union sockaddr_union)); + + if (rtpp_notify_socket_un) { + LM_DBG("trusting unix socket connection\n"); + } else { + node = rtpproxy_get_node((union sockaddr_union *)&rtpp_info); + if (!node) { + LM_WARN("connection from unknown RTPProxy node"); + pkg_free(notify); + goto err; + } + memcpy(¬ify->addr, &node->addr, sizeof(union sockaddr_union)); + list_add(¬ify->list, &rtpp_notify_fds); + notify->linked = 1; + } + if (reactor_proc_add_fd(fd, rtpproxy_io_callback, notify) < 0) { LM_CRIT("failed to add RTPProxy listen socket to reactor\n"); + if (notify->linked) + list_del(¬ify->list); pkg_free(notify); - return -1; + goto err; } - list_add(¬ify->list, &rtpp_notify_fds); return 0; +err: + shutdown(fd, SHUT_RDWR); + close(fd); + return -1; } int init_rtpp_notify(void) @@ -411,6 +472,8 @@ void notification_listener_process(int rank) return; } + if (set_nonblocking(socket_fd) < 0) + return; if (reactor_proc_add_fd( socket_fd, rtpproxy_io_new_callback, NULL) < 0) { LM_CRIT("failed to add RTPProxy listen socket to reactor\n"); return; @@ -443,7 +506,7 @@ static void ipc_update_rtpp_notify(int sender, void *param) void update_rtpp_notify(void) { if (!rtpp_notify_process_no) { - LM_WARN("RTPProxy process not initialized\n"); + LM_DBG("RTPProxy process not initialized\n"); return; } if (ipc_send_rpc(*rtpp_notify_process_no, ipc_update_rtpp_notify, NULL) != 0) diff --git a/modules/rtpproxy/rtpproxy.c b/modules/rtpproxy/rtpproxy.c index 8f1682207f5..d6e665e38c0 100644 --- a/modules/rtpproxy/rtpproxy.c +++ b/modules/rtpproxy/rtpproxy.c @@ -5069,13 +5069,16 @@ int rtpproxy_raise_dtmf_event(struct rtpp_dtmf_event *dtmf) static int rtpproxy_fill_call_args(struct rtp_relay_session *sess, struct rtpp_args *args, str *ip, str *type, str *in_iface, str *out_iface, - str *global_flags, str *flags, str *extra_flags) + str *global_flags, str *flags, str *extra_flags, int require_from_tag) { char *p; str b; if (!sess->from_tag) { - if (get_from_tag(sess->msg, &args->from_tag) == -1 || args->from_tag.len == 0) { + if (require_from_tag && + (!sess->msg || + get_from_tag(sess->msg, &args->from_tag) == -1 || + args->from_tag.len == 0)) { LM_ERR("can't get From tag\n"); return 0; } @@ -5091,7 +5094,9 @@ static int rtpproxy_fill_call_args(struct rtp_relay_session *sess, struct rtpp_a args->to_tag = *sess->to_tag; } if (!sess->callid) { - if (get_callid(sess->msg, &args->callid) == -1 || args->callid.len == 0) { + if (!sess->msg || + get_callid(sess->msg, &args->callid) == -1 || + args->callid.len == 0) { LM_ERR("can't get Call-Id field\n"); return 0; } @@ -5188,7 +5193,7 @@ static int rtpproxy_api_offer(struct rtp_relay_session *sess, memset(&args, '\0', sizeof(args)); if (!rtpproxy_fill_call_args(sess, &args, ip, type, - in_iface, out_iface, global_flags, flags, extra_flags)) + in_iface, out_iface, global_flags, flags, extra_flags, 1)) return -1; if (!server->node.s) { @@ -5255,7 +5260,7 @@ static int rtpproxy_api_answer(struct rtp_relay_session *sess, memset(&args, '\0', sizeof(args)); if (!rtpproxy_fill_call_args(sess, &args, ip, type, - in_iface, out_iface, global_flags, flags, extra_flags)) + in_iface, out_iface, global_flags, flags, extra_flags, 1)) return -1; if (nh_lock) @@ -5297,7 +5302,7 @@ static int rtpproxy_api_delete(struct rtp_relay_session *sess, struct rtp_relay_ memset(&args, '\0', sizeof(args)); if (!rtpproxy_fill_call_args(sess, &args, NULL, NULL, - NULL, NULL, NULL, flags, extra)) + NULL, NULL, NULL, flags, extra, 0)) return -1; if (nh_lock) { @@ -5900,7 +5905,7 @@ static int rtpproxy_api_copy_answer(struct rtp_relay_session *sess, memset(&args, '\0', sizeof(args)); if (!rtpproxy_fill_call_args(sess, &args, NULL, NULL, - NULL, NULL, NULL, flags, NULL)) + NULL, NULL, NULL, flags, NULL, 1)) return -1; if (!server->node.s) { @@ -5967,7 +5972,7 @@ static int rtpproxy_api_copy_delete(struct rtp_relay_session *sess, memset(&args, '\0', sizeof(args)); if (!rtpproxy_fill_call_args(sess, &args, NULL, NULL, - NULL, NULL, NULL, flags, NULL)) + NULL, NULL, NULL, flags, NULL, 1)) return -1; if (!server->node.s) { diff --git a/modules/script_helper/README b/modules/script_helper/README deleted file mode 100644 index b48b32d6ae0..00000000000 --- a/modules/script_helper/README +++ /dev/null @@ -1,188 +0,0 @@ -Script Helper Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. use_dialog (integer) - 1.4.2. create_dialog_flags (string) - 1.4.3. sequential_route (string) - - 1.5. Known Issues - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting use_dialog - 1.2. Setting create_dialog_flags - 1.3. Setting sequential_route - -Chapter 1. Admin Guide - -1.1. Overview - - The purpose of the Script Helper module is to simplify the - scripting process in OpenSIPS when doing basic scenarios. At - the same time, it is useful to script writers as it contains - basic SIP routing logic, and thus it allows them to focus more - on the particular aspects of their OpenSIPS routing code. - -1.2. How it works - - By simply loading the module, the following default logic will - be embedded: - * for initial SIP requests, the module will perform record - routing before running the main request route - * sequential SIP requests will be transparently handled - the - module will perform loose routing, and the request route - will not be run at all - - Currently, the module may be further configured to embed the - following optional logic: - * dialog support (dialog module dependency - must be loaded - before this module) - * an additional route to be run before relaying sequential - requests - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog (only if use_dialog is enabled). - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. use_dialog (integer) - - Enables dialog support. Note that the dialog module must be - loaded before this module when setting this parameter. - - Default value is 0 (disabled) - - Example 1.1. Setting use_dialog -... -modparam("script_helper", "use_dialog", 1) -... - -1.4.2. create_dialog_flags (string) - - Flags used when creating dialogs. For details on these flags, - please refer to the create_dialog() function of the dialog - module. - - Default value is "" (no flags are set) - - Example 1.2. Setting create_dialog_flags -... -modparam("script_helper", "create_dialog_flags", "PpB") -... - -1.4.3. sequential_route (string) - - Optional route to be run just before sequential requests are - relayed. If the exit script statement is used inside this - route, the module assumes that the relaying logic has been - handled. - - By default, this parameter is not set - - Example 1.3. Setting sequential_route -... -modparam("script_helper", "sequential_route", "sequential_handling") -... -route [sequential_handling] -{ -... -} -... - -1.5. Known Issues - - The Max-Forwards header is currently not handled at all. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 19 13 499 46 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 7 5 13 10 - 3. Razvan Crainea (@razvancrainea) 7 5 10 8 - 4. Vlad Patrascu (@rvlad-patrascu) 6 4 9 13 - 5. Maksym Sobolyev (@sobomax) 5 3 3 4 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - May 2023 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2014 www.opensips-solutions.com diff --git a/modules/script_helper/README.md b/modules/script_helper/README.md new file mode 100644 index 00000000000..a9fc0c73793 --- /dev/null +++ b/modules/script_helper/README.md @@ -0,0 +1,130 @@ +--- +title: "Script Helper Module" +description: "The purpose of the **Script Helper module** is to simplify the scripting process in OpenSIPS when doing basic scenarios." +--- + +## Admin Guide + + +### Overview + + +The purpose of the **Script Helper module** +is to simplify the scripting process in OpenSIPS when doing basic scenarios. +At the same time, it is useful to script writers as it contains basic SIP +routing logic, and thus it allows them to focus more on the particular aspects +of their OpenSIPS routing code. + + +### How it works + + +By simply loading the module, the following +**default logic** will be embedded: + + +- for initial SIP requests, the module will perform *record routing* +before running the main *request* route +- sequential SIP requests will be transparently handled - the module will perform +*loose routing*, and the request route will not be run at all + + +Currently, the module may be further configured to embed the following +**optional logic**: + + +- *dialog* support (dialog module dependency - must be loaded before this module) +- an additional route to be run before relaying sequential requests + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog* (only if **[use dialog](#param_use_dialog)** is enabled). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### use_dialog (integer) + + +Enables dialog support. Note that the dialog module must be loaded before +this module when setting this parameter. + + +Default value is 0 (disabled) + + +```opensips title="Setting use_dialog" +... +modparam("script_helper", "use_dialog", 1) +... +``` + + +#### create_dialog_flags (string) + + +Flags used when creating dialogs. For details on these flags, please refer +to the *create_dialog()* function of the dialog module. + + +Default value is "" (no flags are set) + + +```opensips title="Setting create_dialog_flags" +... +modparam("script_helper", "create_dialog_flags", "PpB") +... +``` + + +#### sequential_route (string) + + +Optional route to be run just before sequential requests are relayed. +If the *exit* script statement is used inside this route, +the module assumes that the relaying logic has been handled. + + +By default, this parameter is not set + + +```opensips title="Setting sequential_route" +... +modparam("script_helper", "sequential_route", "sequential_handling") +... +route [sequential_handling] +{ +... +} +... +``` + + +### Known Issues + + +The Max-Forwards header is currently not handled at all. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/script_helper/doc/contributors.xml b/modules/script_helper/doc/contributors.xml deleted file mode 100644 index 9d868c099d2..00000000000 --- a/modules/script_helper/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 19 - 13 - 499 - 46 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 5 - 13 - 10 - - - 3. - Razvan Crainea (@razvancrainea) - 7 - 5 - 10 - 8 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 9 - 13 - - - 5. - Maksym Sobolyev (@sobomax) - 5 - 3 - 3 - 4 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - May 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/script_helper/doc/script_helper.xml b/modules/script_helper/doc/script_helper.xml deleted file mode 100644 index 9d862d68f5f..00000000000 --- a/modules/script_helper/doc/script_helper.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Script Helper Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2014 &osipssol; - - diff --git a/modules/script_helper/doc/script_helper_admin.xml b/modules/script_helper/doc/script_helper_admin.xml deleted file mode 100644 index 219759ec732..00000000000 --- a/modules/script_helper/doc/script_helper_admin.xml +++ /dev/null @@ -1,167 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The purpose of the Script Helper module - is to simplify the scripting process in OpenSIPS when doing basic scenarios. - At the same time, it is useful to script writers as it contains basic SIP - routing logic, and thus it allows them to focus more on the particular aspects - of their OpenSIPS routing code. - -
- -
- How it works - - By simply loading the module, the following - default logic will be embedded: - - - - - for initial SIP requests, the module will perform record routing - before running the main request route - - - - - sequential SIP requests will be transparently handled - the module will perform - loose routing, and the request route will not be run at all - - - - - - Currently, the module may be further configured to embed the following - optional logic: - - - - - dialog support (dialog module dependency - must be loaded before this module) - - - - - an additional route to be run before relaying sequential requests - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog (only if is enabled). - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - -
- <varname>use_dialog</varname> (integer) - - Enables dialog support. Note that the dialog module must be loaded before - this module when setting this parameter. - - - Default value is 0 (disabled) - - - Setting <varname>use_dialog</varname> - -... -modparam("script_helper", "use_dialog", 1) -... - - -
- -
- <varname>create_dialog_flags</varname> (string) - - Flags used when creating dialogs. For details on these flags, please refer - to the create_dialog() function of the dialog module. - - - Default value is "" (no flags are set) - - - Setting <varname>create_dialog_flags</varname> - -... -modparam("script_helper", "create_dialog_flags", "PpB") -... - - -
- -
- <varname>sequential_route</varname> (string) - - Optional route to be run just before sequential requests are relayed. - If the exit script statement is used inside this route, - the module assumes that the relaying logic has been handled. - - - By default, this parameter is not set - - - Setting <varname>sequential_route</varname> - -... -modparam("script_helper", "sequential_route", "sequential_handling") -... -route [sequential_handling] -{ -... -} -... - - -
- -
- -
- Known Issues - - - The Max-Forwards header is currently not handled at all. - - -
-
- diff --git a/modules/signaling/README b/modules/signaling/README deleted file mode 100644 index 94934c0bcca..00000000000 --- a/modules/signaling/README +++ /dev/null @@ -1,210 +0,0 @@ -signaling Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Functions - - 1.4.1. send_reply(code, reason) - - 1.5. Exported Variables - - 1.5.1. $sig_local_totag - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. sl_send_reply usage - 1.2. Usage of $sig_local_totag variable - -Chapter 1. Admin Guide - -1.1. Overview - - The SIGNALING module comes as a wrapper over tm and sl modules - and offers one function to be called by the modules that want - to send a reply. - - The logic behind the module is to first search if a transaction - is created and if so, send a state full reply, using tm module, - otherwise send a stateless reply with the function exported by - sl. In this way, the script writer still has the call on how - the transaction should be handled, state full or stateless and - the reply is send accordingly to his choice. - - For example, if you do a t_newtran() in the script before doing - save() (for registration), the function will automatically send - the reply in stateful mode as a transaction is available. If no - transaction is done, the reply will be sent in stateless way - (as now). - - By doing this, we have the possibility to have same module - sending either stateful either stateless replies, by just - controlling this from the script (if we create or not a - transaction). So, the signalling will be more coherent as the - replies will be sent according to the transaction presence (or - not). - - Moreover, this module offers the possibility of loading only - one of the module, sl or tm, and send reply using only the - module that is loaded. This is useful as not in all cases a - user desires to send stateful or stateless replies and he - should not be forced to load the module only because the send - reply interface requires it. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - At least one of the following modules must be loaded before - this module: - * sl. - * tm. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - - * None. - -1.4. Exported Functions - -1.4.1. send_reply(code, reason) - - For the current request, a reply is sent back having the given - code and text reason. The reply is sent stateless or statefull - depending on which module is loaded and if a transaction was - created, as explained above. - - Meaning of the parameters is as follows: - * code (int) - Return code. - * reason (string) - Reason phrase. - - This function can be used from REQUEST_ROUTE, ERROR_ROUTE. - - Example 1.1. sl_send_reply usage -... -send_reply(404, "Not found"); -... -send_reply($err.rcode, $err.rreason); -... - -1.5. Exported Variables - -1.5.1. $sig_local_totag - - This variable returns the local To-tag that will be used by - OpenSIPS for locally sending replies to the current SIP - request. Yes, this variable should be used only in the context - of a SIP request and it should be used only in conjunction with - the using send_reply(). - - Whenever you use it, be sure that the function is used in the - same stateful / stateless SIP mode as the following replying - function. Otherwise you may get different values for the - To-tag!! - - NOTE: the variable returns the To-Tag that will be used by - OpenSIPS in the locally generated reply. This may be completly - different from the To-tag in the replies received and forwarded - by OpenSIPS. - - Example 1.2. Usage of $sig_local_totag variable -... -# stateful handling -t_newtran(); -xlog("the To-tag to be used is $sig_local_totag \n"); -send_reply(); # or t_reply(); -... -# stateless handling -xlog("the To-tag to be used is $sig_local_totag \n"); -send_reply(); # or sl_send_reply(); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 12 10 28 37 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 12 9 131 23 - 3. Anca Vamanu 9 3 524 2 - 4. Razvan Crainea (@razvancrainea) 7 5 6 4 - 5. Maksym Sobolyev (@sobomax) 6 4 11 10 - 6. Vlad Patrascu (@rvlad-patrascu) 6 3 23 76 - 7. Peter Lemenkov (@lemenkov) 3 1 1 1 - 8. zhangst 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Oct 2020 - Nov 2023 - 3. Razvan Crainea (@razvancrainea) Aug 2015 - Dec 2020 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Nov 2008 - May 2020 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. zhangst Jul 2014 - Jul 2014 - 8. Anca Vamanu Nov 2008 - Mar 2010 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu), zhangst, Anca Vamanu. - - Documentation Copyrights: - - Copyright © 2008 FhG FOKUS diff --git a/modules/signaling/README.md b/modules/signaling/README.md new file mode 100644 index 00000000000..b4c0a155e1f --- /dev/null +++ b/modules/signaling/README.md @@ -0,0 +1,146 @@ +--- +title: "signaling Module" +description: "The SIGNALING module comes as a wrapper over tm and sl modules and offers one function to be called by the modules that want to send a reply." +--- + +## Admin Guide + + +### Overview + + +The SIGNALING module comes as a wrapper over +tm and sl modules and offers one function to be called by the modules +that want to send a reply. + + +The logic behind the module is to first search if a transaction is +created and if so, send a state full reply, using tm module, otherwise +send a stateless reply with the function exported by sl. +In this way, the script writer still has the call on how the transaction +should be handled, state full or stateless and the reply is send +accordingly to his choice. + + +For example, if you do a t_newtran() in the script before doing save() +(for registration), the function will automatically send the reply in +stateful mode as a transaction is available. If no transaction is done, +the reply will be sent in stateless way (as now). + + +By doing this, we have the possibility to have same module sending +either stateful either stateless replies, by just controlling this from +the script (if we create or not a transaction). +So, the signalling will be more coherent as the replies will be sent +according to the transaction presence (or not). + + +Moreover, this module offers the possibility of loading only one +of the module, sl or tm, and send reply using only the module that is +loaded. This is useful as not in all cases a user desires to send +stateful or stateless replies and he should not be forced to load the +module only because the send reply interface requires it. + + +### Dependencies + + +#### OpenSIPS Modules + + +At least one of the following modules must be loaded before this module: + + +- *sl*. +- *tm*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +- *None*. + + +### Exported Functions + + +#### send_reply(code, reason) + + +For the current request, a reply is sent back having the given code +and text reason. The reply is sent stateless or statefull depending +on which module is loaded and if a transaction was created, as +explained above. + + +Meaning of the parameters is as follows: + + +- *code (int)* - Return code. +- *reason (string)* - Reason phrase. + + +This function can be used from REQUEST_ROUTE, ERROR_ROUTE. + + +```opensips title="sl_send_reply usage" +... +send_reply(404, "Not found"); +... +send_reply($err.rcode, $err.rreason); +... + +``` + + +### Exported Variables + + +#### $sig_local_totag + + +This variable returns the local To-tag that will be used +by OpenSIPS for locally sending replies to the current SIP request. +Yes, this variable should be used only in the context of a SIP +request and it should be used only in conjunction with the +using [send reply](#func_send_reply). + + +Whenever you use it, be sure that the function is used in the same +stateful / stateless SIP mode as the following replying function. +Otherwise you may get different values for the To-tag!! + + +> [!NOTE] +> The variable returns the To-Tag that will be used by OpenSIPS +> in the locally generated reply. This may be completly different from +> the To-tag in the replies received and forwarded by OpenSIPS. + + +```opensips title="Usage of $sig_local_totag variable" +... +# stateful handling +t_newtran(); +xlog("the To-tag to be used is $sig_local_totag \n"); +send_reply(); # or t_reply(); +... +# stateless handling +xlog("the To-tag to be used is $sig_local_totag \n"); +send_reply(); # or sl_send_reply(); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/signaling/doc/contributors.xml b/modules/signaling/doc/contributors.xml deleted file mode 100644 index 95e2ea5d87c..00000000000 --- a/modules/signaling/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 12 - 10 - 28 - 37 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 12 - 9 - 131 - 23 - - - 3. - Anca Vamanu - 9 - 3 - 524 - 2 - - - 4. - Razvan Crainea (@razvancrainea) - 7 - 5 - 6 - 4 - - - 5. - Maksym Sobolyev (@sobomax) - 6 - 4 - 11 - 10 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 3 - 23 - 76 - - - 7. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 8. - zhangst - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Oct 2020 - Nov 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Aug 2015 - Dec 2020 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Nov 2008 - May 2020 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - zhangst - Jul 2014 - Jul 2014 - - - 8. - Anca Vamanu - Nov 2008 - Mar 2010 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), zhangst, Anca Vamanu. -
- -
diff --git a/modules/signaling/doc/signaling.xml b/modules/signaling/doc/signaling.xml deleted file mode 100644 index 9a2464825b5..00000000000 --- a/modules/signaling/doc/signaling.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - signaling Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 &fhg; - diff --git a/modules/signaling/doc/signaling_admin.xml b/modules/signaling/doc/signaling_admin.xml deleted file mode 100644 index de09141cdc3..00000000000 --- a/modules/signaling/doc/signaling_admin.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The SIGNALING module comes as a wrapper over - tm and sl modules and offers one function to be called by the modules - that want to send a reply. - - - The logic behind the module is to first search if a transaction is - created and if so, send a state full reply, using tm module, otherwise - send a stateless reply with the function exported by sl. - In this way, the script writer still has the call on how the transaction - should be handled, state full or stateless and the reply is send - accordingly to his choice. - - - For example, if you do a t_newtran() in the script before doing save() - (for registration), the function will automatically send the reply in - stateful mode as a transaction is available. If no transaction is done, - the reply will be sent in stateless way (as now). - - - By doing this, we have the possibility to have same module sending - either stateful either stateless replies, by just controlling this from - the script (if we create or not a transaction). - So, the signalling will be more coherent as the replies will be sent - according to the transaction presence (or not). - - - Moreover, this module offers the possibility of loading only one - of the module, sl or tm, and send reply using only the module that is - loaded. This is useful as not in all cases a user desires to send - stateful or stateless replies and he should not be forced to load the - module only because the send reply interface requires it. - -
-
- Dependencies -
- &osips; Modules - - At least one of the following modules must be loaded before this module: - - - - sl. - - - - - tm. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - - - - - None. - - - - -
- -
- Exported Functions -
- - <function moreinfo="none">send_reply(code, reason)</function> - - - For the current request, a reply is sent back having the given code - and text reason. The reply is sent stateless or statefull depending - on which module is loaded and if a transaction was created, as - explained above. - - Meaning of the parameters is as follows: - - - code (int) - Return code. - - - - reason (string) - Reason phrase. - - - - - This function can be used from REQUEST_ROUTE, ERROR_ROUTE. - - - <function>sl_send_reply</function> usage - -... -send_reply(404, "Not found"); -... -send_reply($err.rcode, $err.rreason); -... - - -
-
- -
- Exported Variables -
- $sig_local_totag - This variable returns the local To-tag that will be used - by OpenSIPS for locally sending replies to the current SIP request. - Yes, this variable should be used only in the context of a SIP - request and it should be used only in conjunction with the - using . - - - Whenever you use it, be sure that the function is used in the same - stateful / stateless SIP mode as the following replying function. - Otherwise you may get different values for the To-tag!! - - - NOTE: the variable returns the To-Tag that will be used by OpenSIPS - in the locally generated reply. This may be completly different from - the To-tag in the replies received and forwarded by OpenSIPS. - - - Usage of <varname>$sig_local_totag</varname> variable - -... -# stateful handling -t_newtran(); -xlog("the To-tag to be used is $sig_local_totag \n"); -send_reply(); # or t_reply(); -... -# stateless handling -xlog("the To-tag to be used is $sig_local_totag \n"); -send_reply(); # or sl_send_reply(); -... - - -
-
- -
- diff --git a/modules/sip_i/README b/modules/sip_i/README deleted file mode 100644 index 7fccaf8949d..00000000000 --- a/modules/sip_i/README +++ /dev/null @@ -1,812 +0,0 @@ -SIP-I Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Parameters - - 1.3.1. param_subfield_separator (str) - 1.3.2. isup_mime_str (str) - 1.3.3. default_part_headers (str) - 1.3.4. country_code (str) - - 1.4. Exported Functions - - 1.4.1. - add_isup_part([isup_msg_type][,extra_headers]) - - 1.5. Exported Pseudo-Variables - - 1.5.1. - $(isup_param(param_name{sep}subfield_name)[byt - e_index]) - - 1.5.2. $isup_param_str(param_name{sep}subfield_name) - - 1.5.3. $isup_msg_type - - 1.6. Exported script transformations - - 1.6.1. {isup.param,param_name,[subfield_name]} - 1.6.2. {isup.param.str,param_name,[subfield_name]} - - 1.7. ISUP parameter subfields and string aliases - 1.8. Mandatory ISUP parameters - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set param_subfield_separator parameter - 1.2. Set isup_mime_str parameter - 1.3. Set default_part_headers parameter - 1.4. Set country_code parameter - 1.5. add_isup_part usage - 1.6. isup_param usage - 1.7. isup_param_str usage - 1.8. isup_msg_type usage - 1.9. isup.param usage - 1.10. isup.param.str usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module offers the possibility of processing ISDN User - Part(ISUP) messages encapsulated in SIP. The available - operations are: reading and modifying parameters from an ISUP - message, removing or adding new optional parameters, adding an - ISUP part to a SIP message body. This is done explicitly via - script pseudovariables and functions. - - The supported ISUP message types are only the ones that can be - included in a SIP message according to the SIP-I(SIP with - encapsulated ISUP) protocol defined by ITU-T. - - The format and specification of the ISUP messages and - parameters follow the recomandations from ITU-T Rec. Q.763. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Parameters - -1.3.1. param_subfield_separator (str) - - The character to be used as separator in the subname of the - $isup_param and $isup_param_str pseudovariables between the - ISUP parameter name and subfield name. - - Default value is "|". - - Example 1.1. Set param_subfield_separator parameter -... -modparam("sip_i", "param_subfield_separator", ":") -... - -1.3.2. isup_mime_str (str) - - The string to be used for the Content-Type header field of the - ISUP MIME body when creating a new ISUP part. - - Default value is "application/ISUP;version=itu-t92+". - - Example 1.2. Set isup_mime_str parameter -... -modparam("sip_i", "isup_mime_str", "application/ISUP;base=itu-t92+;versi -on=itu-t") -... - - -1.3.3. default_part_headers (str) - - The default set of headers (fully defined, including the header - termination) to be pushed into the ISUP part together with the - Content-Type header. - - Default value is - "Content-Disposition:signal;handling=optional\r\n". - - Example 1.3. Set default_part_headers parameter -... -modparam("sip_i", "default_part_headers", "Content-Disposition:signal;ha -ndling=required\r\n") -... - - -1.3.4. country_code (str) - - Country Code that the first part of the number from - P-Asserted-Identity is tested against when trying to map the - Calling Party Number ISUP parameter from SIP by default. If - there is a match, the value assigned to the Nature of Address - Indicator subfield is 3(national), otherwise it is - 4(international). - - Default value is "+1". - - Example 1.4. Set country_code parameter -... -modparam("sip_i", "country_code", "+4") -... - - -1.4. Exported Functions - -1.4.1. add_isup_part([isup_msg_type][,extra_headers]) - - Adds a new ISUP part to the SIP message body. - - With the exception of some ISUP message types(IAM, REL, ACM, - CPG, ANM, CON), the newly added part contains a blank ISUP - message(i.e. all mandatory parameters zeroed and no optional - ones) and all the required parameters should be set through - $isup_param. For the previously mentioned message types, the - mandatory parameters and some optional ones are automaticaly - set to default values according to basic SIP-ISUP interworking - rules from ITU-T Rec. Q.1912.5. This only provides a general - and simplified mapping from SIP headers and message type - (request method, reply code etc.) to ISUP parameters and you - should not base your SIP-ISUP interworking only on this. - - Meaning of the parameters is as follows: - * isup_msg_type (string, optional) - name of the ISUP message - to be added, exactly as it appears in ITU-T Rec. Q.763 or - an abbreviation(eg. IAM for "Initial address"). - * extra_headers (string, string, optional) - a chunk of fully - defined SIP headers (including header terminatior) to be - inserted into the ISUP part next to the Content-Type - header. It overrides the global module parameter - default_part_headers. If not specified, the - default_part_headers value will be used. - - If isup_msg_type is not explicitly provided, it is - automatically deduced from the SIP message as follows: - * INVITE - IAM - * BYE - REL - * 180, 183 - ACM - * 4xx, 5xx - REL - * 200 OK INVITE - ANM - * 200 OK BYE - RLC - - The abbreviations that can be given as isup_msg_type for each - ISUP message type are the following: - * Initial address - IAM - * Address complete - ACM - * Answer - ANM - * Connect - CON - * Release - REL - * Release complete - RLC - * Call progress - CPG - * Facility reject - FRJ - * Facility accepted - FAA - * Facility request - FAR - * Confusion - CFN - * Suspend - SUS - * Resume - RES - * Subsequent address - SAM - * Forward transfer - FOT - * User-to-user information - USR - * Network resource management - NRM - * Facility - FAC - * Identification request - IRQ - * Identification response - IRS - * Loop prevention - LPR - * Application transport - APT - * Pre-release information - PRI - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,LOCAL_ROUTE. - - Example 1.5. add_isup_part usage -... -if ($rs == "183") { - # Encapsulate a CPG - add_isup_part("Call progress"); - # set desired parameters - ... -} -... - -1.5. Exported Pseudo-Variables - -1.5.1. $(isup_param(param_name{sep}subfield_name)[byte_index]) - - The ISUP parameter named param_name of a received or newly - added ISUP message can be accessed through this read-write - variable. For optional parameters, writing to a param_name that - does not exist in this ISUP message will insert it. Assigning - null to this variable will remove the optional parameter from - the message or zeroize the parameter in case of a mandatory - one. - - The format of the subname for $isup_param is the following: - * param_name - name of the ISUP parameter as it appears in - ITU-T Rec. Q.763 - * sep - separator, whitespaces allowed before/after - * subfield_name - name of the subfield of the ISUP parameter - as it appears in ITU-T Rec. Q.763 - - The ISUP parameter can be addressed in different ways: - * entire parameter - by providing as subname for the - varaiable only the ISUP parameter name, allowing access to - the contents of the entire parameter as: a hex - string(similar to a hex "dump") for read/write, a string - alias for writing, or an integer value for read/write; when - assigning a hex string, the hex value must be preceded by - "0x"; when reading, if string aliases are supported for - this parameter, an associated integer value will be - returned, otherwise a hex string is returned - * at subfield level - by providing as subname for the - varaiable the ISUP parameter name and the subfield name, - allowing access to the specific subfield as an integer - value or string value(eg. telephone number for parameters - such as Called Party Number) for read/write or as a string - alias for writing - * at byte level - by providing as subname for the variable - the ISUP parameter name and an index, allowing access to - the byte with the specified index as an integer value - - Addressing at entire parameter level as a hex string and at - byte level are supported for all the ISUP parameters defined in - the ITU-T Rec. Q.763. Addressing at subfield level is supported - only for some ISUP parameters and not all of the subfields of a - parameter defined in the ITU Recommandation are supported. - - String aliases are not available for all parameters or - parameter subfields. Also, not all the possible values of a - parameter or parameter subfield have a string alias defined. - - For more information on supported subfields and aliases check - Section 1.7, “ISUP parameter subfields and string aliases”. - - Example 1.6. isup_param usage -... - $isup_param(Called Party Number | Nature of address indicator) = - 3; - ... - # use a string alias - $isup_param(Called Party Number | Numbering plan indicator) = "I -SDN"; - ... - $isup_param(Called Party Number | Address signal) = "99991234"; - $isup_param(Nature of connection indicators) = "0x01" - $isup_param(Calling party's category) = 10; - ... - # use a string alias - $isup_param(Transmission Medium Requirement) = "speech"; - ... - # access at byte level - $(isup_param(Forward Call Indicators)[0]) = 96; - $(isup_param(Forward Call Indicators)[1]) = 1; -... - -1.5.2. $isup_param_str(param_name{sep}subfield_name) - - The ISUP parameter named param_name of a received or newly - added ISUP message can also be accessed through this read-only - variable. This variable is similar in usage with $isup_param - except it will return the string alias for the value when - possible. - - The format of the subname for $isup_param_str is the following: - * param_name - name of the ISUP parameter as it appears in - ITU-T Rec. Q.763 - * sep - separator, whitespaces allowed before/after - * subfield_name - name of the subfield of the ISUP parameter - as it appears in ITU-T Rec. Q.763 - - Example 1.7. isup_param_str usage -... - # may print: "NOA is: national" - xlog("NOA is: $isup_param_str(Called Party Number|Nature of addr -ess indicator)"); - # may print: "CpN is: 99991234" - xlog("CpN is: $isup_param_str(Called Party Number|Address signal -)"); - # may print: "nature of conn: 0x01" - xlog("nature of conn: $isup_param_str(Nature of connection indic -ators)"); - # may print: "Cg cat is: ordinary" - xlog("$isup_param_str(Calling party's category)"); -... - -1.5.3. $isup_msg_type - - Read-only variable, returns the ISUP message type as string. - - Example 1.8. isup_msg_type usage -... - # may print: "ISUP msg is: IAM" - xlog("ISUP msg is: $isup_msg_type"); -... - -1.6. Exported script transformations - - The module also provides a way for accessing the value of ISUP - parameters and their subfields from an ISUP message contained - in a arbitrary script variable as opposed to directly from the - processed SIP (with encapsulated ISUP) message. This is done by - aplying a transformation to a script variable containing the - ISUP message body. The value of the original variable is not - altered and a corresponding integer or string value - (representing an ISUP parameter or subfield as the exact value - or string alias) is returned. - -1.6.1. {isup.param,param_name,[subfield_name]} - - The result of this transformation is similar to a read access - of the $isup_param pseudovariable with the exception that byte - level access is not provided. - - The parameters for the transformation are: - * param_name - name of the ISUP parameter as it appears in - ITU-T Rec. Q.763 - * subfield_name - optional, name of the subfield of the ISUP - parameter as it appears in ITU-T Rec. Q.763 - - Example 1.9. isup.param usage -... - # for this example, we take the ISUP body from the received SIP- -I message - $var(isup_body) = $(rb[1]); - - # may print: "NOA is: 3" - xlog("NOA is: $(var(isup_body){isup.param, Called Party Number, -Nature of address indicator})\n"); - - # may print: "CpN is: 99991234" - xlog("CpN is: $(var(isup_body){isup.param, Called Party Number, -Address signal})\n"); - - # may print: "Cg cat is: 10" - xlog("Cg cat is: $(var(isup_body){isup.param, Calling party's ca -tegory})\n"); - - # may print: "nature of conn: 0x01" - xlog("nature of conn: $(var(isup_body){isup.param, Nature of con -nection indicators})\n"); -... - -1.6.2. {isup.param.str,param_name,[subfield_name]} - - The result of this transformation is similar to a read access - of the $isup_param_str pseudovariable with the exception that - byte level access is not provided. - - The parameters for the transformation are: - * param_name - name of the ISUP parameter as it appears in - ITU-T Rec. Q.763 - * subfield_name - optional, name of the subfield of the ISUP - parameter as it appears in ITU-T Rec. Q.763 - - Example 1.10. isup.param.str usage -... - # for this example, we take the ISUP body from the received SIP- -I message - $var(isup_body) = $(rb[1]); - - # may print: "NOA is: national" - xlog("NOA is: $(var(isup_body){isup.param.str, Called Party Numb -er, Nature of address indicator})\n"); - - # may print: "CpN is: 99991234" - xlog("CpN is: $(var(isup_body){isup.param.str, Called Party Numb -er, Address signal})\n"); - - # may print: "Cg cat is: ordinary" - xlog("Cg cat is: $(var(isup_body){isup.param.str, Calling party' -s category})\n"); - - # may print: "nature of conn: 0x01" - xlog("nature of conn: $(var(isup_body){isup.param.str, Nature of - connection indicators})\n"); -... - -1.7. ISUP parameter subfields and string aliases - - The supported subfields for each ISUP parameter and the string - aliases for their values are the following: - * Nature of Connection Indicators - + Satellite indicator - o no satellite - 0 - o one satellite - 1 - o two satellite - 2 - + Continuity check indicator - o not required - 0 - o required - 1 - o performed - 2 - + Echo control device indicator - o not included - 0 - o included - 1 - * Forward Call Indicators - + National/international call indicator - o national - 0 - o international - 1 - + End-to-end method indicator - o no method - 0 - o pass-along - 1 - o SCCP - 2 - o pass-along and SCCP - 3 - + Interworking indicator - o no interworking - 0 - o interworking - 1 - + End-to-end information indicator - o no end-to-end - 0 - o end-to-end - 1 - + ISDN user part indicator - o not all the way - 0 - o all the way - 1 - + ISDN user part preference indicator - o preferred - 0 - o not required - 1 - o required - 2 - + ISDN access indicator - o non-ISDN - 0 - o ISDN - 1 - + SCCP method indicator - o no indication - 0 - o connectionless - 1 - o connection - 2 - o connectionless and connection - 3 - * Optional forward call indicators - + Closed user group call indicator - o non-CUG - 0 - o outgoing allowed - 2 - o outgoing not allowed - 3 - + Simple segmentation indicator - o no additional information - 0 - o additional information - 1 - + Connected line identity request indicator - o not requested - 0 - o requested - 1 - * Called Party Number - + Odd/even indicator - o even - 0 - o odd - 1 - + Nature of address indicator - o subscriber - 1 - o unknown - 2 - o national - 3 - o international - 4 - o network-specific - 5 - o network routing national - 6 - o network routing network-specific - 7 - o network routing with CDN - 8 - + Internal Network Number indicator - o allowed - 0 - o not allowed - 1 - + Numbering plan indicator - o ISDN - 1 - o Data - 3 - o Telex - 4 - + Address signal - * Calling Party Number - + Odd/even indicator - o even - 0 - o odd - 1 - + Nature of address indicator - o subscriber - 1 - o unknown - 2 - o national - 3 - o international - 4 - + Number Incomplete indicator - o complete - 0 - o incomplete - 1 - + Numbering plan indicator - o ISDN - 1 - o Data - 3 - o Telex - 4 - + Address presentation restricted indicator - o allowed - 0 - o restricted - 1 - o not available - 2 - o reserved - 3 - + Screening indicator - o user - 0 - o network - 1 - + Address signal - * Backward Call Indicators - + Charge indicator - o no indication - 0 - o no charge - 1 - + Called party's status indicator - o no indication - 0 - o subscriber free - 1 - o connect - 2 - + Called party's category indicator - o no indication - 0 - o ordinary subscriber - 1 - o payphone - 2 - + End to End method indicator - o no end-to-end - 0 - o pass-along - 1 - o SCCP - 2 - o pass-along and SCCP - 3 - + Interworking indicator - o no interworking - 0 - o interworking - 1 - + End to End information indicator - o no end-to-end - 0 - o end-to-end - 1 - + ISDN user part indicator - o not all the way - 0 - o all the way - 1 - + Holding indicator - o not requested - 0 - o requested - 1 - + ISDN access indicator - o non-ISDN - 0 - o ISDN - 1 - + Echo control device indicator - o not included - 0 - o included - 1 - + SCCP method indicator - o no indication - 0 - o connectionless - 1 - o connection - 2 - o connectionless and connection - 3 - * Optional Backward Call Indicators - + In-band information indicator - o no indication- 0 - o available - 1 - + Call diversion may occur indicator - o no indication - 0 - o call diversion - 1 - + Simple segmentation indicator - o no additional information - 0 - o additional information - 1 - + MLPP user indicator - o no indication - 0 - o MLPP user - 1 - * Connected Number - + Odd/even indicator - o even - 0 - o odd - 1 - + Nature of address indicator - o subscriber - 1 - o unknown - 2 - o national - 3 - o international - 4 - + Numbering plan indicator - o ISDN - 1 - o Data - 3 - o Telex - 4 - + Address presentation restricted indicator - o allowed - 0 - o restricted - 1 - o not available - 2 - + Screening indicator - o user - 0 - o network - 1 - + Address signal - * Original Called Number - + Odd/even indicator - o even - 0 - o odd - 1 - + Nature of address indicator - o subscriber - 1 - o unknown - 2 - o national - 3 - o international - 4 - + Numbering plan indicator - o ISDN - 1 - o Data - 3 - o Telex - 4 - + Address presentation restricted indicator - o allowed - 0 - o restricted - 1 - o not available - 2 - o reserved - 3 - * Redirecting Number - same as Original Called Number - * Redirection Number - same as Called Party Number - * Redirection information - + Redirecting indicator - o no redirection - 0 - o call rerouted - 1 - o call rerouted, all information restricted - 2 - o call diverted - 3 - o Call diverted, all information restricted - 4 - o call rerouted, redirection number restricted - 5 - o call diversion, redirection number restricted - 6 - + Original redirection reason - o unknown/not available - 0 - o user busy - 1 - o no reply - 2 - o unconditional - 3 - + Redirection counter - o 1 - o 2 - o 3 - o 4 - o 5 - + Redirecting reason - o unknown/not available - 0 - o user busy - 1 - o no reply - 2 - o unconditional - 3 - o deflection alerting - 4 - o deflection response - 5 - o mobile not reachable - 6 - * Cause Indicators - + Location - o user - 0 - o LPN - 1 - o LN - 2 - o TN - 3 - o RLN - 4 - o RPN - 5 - o INTL - 7 - o BI - 10 - + Coding standard - o ITU-T - 0 - o ISO/IEC - 1 - o national - 2 - o location - 3 - + Cause value - * Subsequent Number - + Odd/even indicator - o even - 0 - o odd - 1 - + Address signal - * Event Information - + Event indicator - o alerting - 1 - o progress - 2 - o in-band or pattern - 3 - o busy - 4 - o no reply - 5 - o unconditional - 6 - + Event presentation restricted indicator - o no indication - 0 - o restricted - 1 - * Calling Party's Category - + unknown - 0 - + french - 1 - + english - 2 - + german - 3 - + russian - 4 - + spanish - 5 - + ordinary - 10 - + priority - 11 - + data - 12 - + test - 13 - + payphone - 15 - * Transmission Medium Requirement - + speech - 0 - + 64 kbit/s unrestricted - 2 - + 3.1 kHz audio - 3 - + 64 kbit/s preferred - 6 - + 2 x 64 kbit/s - 7 - + 384 kbit/s - 8 - + 1536 kbit/s - 9 - + 1920 kbit/s - 10 - -1.8. Mandatory ISUP parameters - - The mandatory parameters(According to ITU-T Rec. Q.763) for - each supported ISUP message that requires this are the - following: - * Initial address - + Nature of connection indicators - + Forward call indicators - + Calling party's category - + Transmission medium requirement - + Called party number - * Address complete - + Backward call indicators - * Connect - + Backward call indicators - * Release - + Cause indicators - * Call progress - + Event information - * Facility reject - + Facility indicator - + Cause indicators - * Facility accepted - + Facility indicator - * Facility request - + Facility indicator - * Confusion - + Cause indicators - * Suspend - + Suspend/resume indicators - * Resume - + Suspend/resume indicators - * Subsequent address - + Subsequent number - * User-to-user information - + User-to-user information - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 129 44 6684 1643 - 2. Razvan Crainea (@razvancrainea) 11 9 21 20 - 3. Liviu Chircu (@liviuchircu) 8 6 24 31 - 4. Maksym Sobolyev (@sobomax) 7 5 14 15 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 6 4 83 11 - 6. Rustam Safargalin 3 1 80 1 - 7. Walter Doekes (@wdoekes) 3 1 16 20 - 8. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2018 - Jan 2025 - 2. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 3. Razvan Crainea (@razvancrainea) Feb 2017 - Jul 2021 - 4. Vlad Patrascu (@rvlad-patrascu) Oct 2016 - Dec 2020 - 5. Rustam Safargalin Apr 2020 - Apr 2020 - 6. Walter Doekes (@wdoekes) Apr 2019 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Liviu Chircu (@liviuchircu) Apr 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2016 www.opensips-solutions.com diff --git a/modules/sip_i/README.md b/modules/sip_i/README.md new file mode 100644 index 00000000000..e5978793179 --- /dev/null +++ b/modules/sip_i/README.md @@ -0,0 +1,774 @@ +--- +title: "SIP-I Module" +description: "This module offers the possibility of processing ISDN User Part(ISUP) messages encapsulated in SIP." +--- + +## Admin Guide + + +### Overview + + +This module offers the possibility of processing ISDN User Part(ISUP) messages encapsulated in SIP. The available operations are: reading and modifying parameters from an ISUP message, removing or adding new optional parameters, adding an ISUP part to a SIP message body. This is done explicitly via script pseudovariables and functions. + + +The supported ISUP message types are only the ones that can be included in a SIP message according to the SIP-I(SIP with encapsulated ISUP) protocol defined by ITU-T. + + +The format and specification of the ISUP messages and parameters follow the recomandations from ITU-T Rec. Q.763. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### param_subfield_separator (str) + + +The character to be used as separator in the subname of the *$isup_param* and *$isup_param_str* pseudovariables between the ISUP parameter name and subfield name. + + +*Default value is "|".* + + +```opensips title="Set param_subfield_separator parameter" +... +modparam("sip_i", "param_subfield_separator", ":") +... +``` + + +#### isup_mime_str (str) + + +The string to be used for the Content-Type header field of the ISUP MIME body when creating a new ISUP part. + + +*Default value is "application/ISUP;version=itu-t92+".* + + +```opensips title="Set isup_mime_str parameter" +... +modparam("sip_i", "isup_mime_str", "application/ISUP;base=itu-t92+;version=itu-t") +... +``` + + +#### default_part_headers (str) + + +The default set of headers (fully defined, including the header +termination) to be pushed into the ISUP part together +with the *Content-Type* header. + + +*Default value is "Content-Disposition:signal;handling=optional\r\n".* + + +```opensips title="Set default_part_headers parameter" +... +modparam("sip_i", "default_part_headers", "Content-Disposition:signal;handling=required\r\n") +... +``` + + +#### country_code (str) + + +Country Code that the first part of the number from +P-Asserted-Identity is tested against when trying to map the +Calling Party Number ISUP parameter from SIP by default. If there +is a match, the value assigned to the Nature of Address Indicator +subfield is *3*(national), otherwise it is +*4*(international). + + +*Default value is "+1".* + + +```opensips title="Set country_code parameter" +... +modparam("sip_i", "country_code", "+4") +... +``` + + +### Exported Functions + + +#### add_isup_part([isup_msg_type][,extra_headers]) + + +Adds a new ISUP part to the SIP message body. + + +With the exception of some ISUP message types(IAM, REL, ACM, CPG, ANM, CON), the newly added part contains a blank ISUP message(i.e. all mandatory parameters zeroed and no optional ones) and all the required parameters should be set through $isup_param. For the previously mentioned message types, the mandatory parameters and some optional ones are automaticaly set to default values according to basic SIP-ISUP interworking rules from ITU-T Rec. Q.1912.5. This only provides a general and simplified mapping from SIP headers and message type (request method, reply code etc.) to ISUP parameters and you should not base your SIP-ISUP interworking only on this. + + +Meaning of the parameters is as follows: + + +- *isup_msg_type (string, optional)* - name of the ISUP message to be added, exactly as it appears in ITU-T Rec. Q.763 or an abbreviation(eg. *IAM* for "Initial address"). +- *extra_headers (string, string, optional)* - a chunk of fully defined SIP headers (including header terminatior) to be inserted into the ISUP part next to the *Content-Type* header. It overrides the global module parameter *default_part_headers*. If not specified, the *default_part_headers* value will be used. + + +If *isup_msg_type* is not explicitly provided, it is automatically deduced from the SIP message as follows: + + +- INVITE - IAM +- BYE - REL +- 180, 183 - ACM +- 4xx, 5xx - REL +- 200 OK INVITE - ANM +- 200 OK BYE - RLC + + +The abbreviations that can be given as *isup_msg_type* for each ISUP message type are the following: + + +- Initial address - *IAM* +- Address complete - *ACM* +- Answer - *ANM* +- Connect - *CON* +- Release - *REL* +- Release complete - *RLC* +- Call progress - *CPG* +- Facility reject - *FRJ* +- Facility accepted - *FAA* +- Facility request - *FAR* +- Confusion - *CFN* +- Suspend - *SUS* +- Resume - *RES* +- Subsequent address - *SAM* +- Forward transfer - *FOT* +- User-to-user information - *USR* +- Network resource management - *NRM* +- Facility - *FAC* +- Identification request - *IRQ* +- Identification response - *IRS* +- Loop prevention - *LPR* +- Application transport - *APT* +- Pre-release information - *PRI* + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,LOCAL_ROUTE. + + +```opensips title="add_isup_part usage" +... +if ($rs == "183") { + # Encapsulate a CPG + add_isup_part("Call progress"); + # set desired parameters + ... +} +... + +``` + + +### Exported Pseudo-Variables + + +#### $(isup_param(param_name{sep}subfield_name)[byte_index]) + + +The ISUP parameter named *param_name* of a received or newly added ISUP message can be accessed through this read-write variable. For optional parameters, writing to a *param_name* that does not exist in this ISUP message will insert it. Assigning null to this variable will remove the optional parameter from the message or zeroize the parameter in case of a mandatory one. + + +The format of the subname for `$isup_param` is the following: + + +- *param_name* - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 +- *sep* - separator, whitespaces allowed before/after +- *subfield_name* - name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 + + +The ISUP parameter can be addressed in different ways: + + +- entire parameter - by providing as subname for the varaiable only the ISUP parameter name, allowing access to the contents of the entire parameter as: a hex string(similar to a hex "dump") for read/write, a string alias for writing, or an integer value for read/write; when assigning a hex string, the hex value must be preceded by "0x"; when reading, if string aliases are supported for this parameter, an associated integer value will be returned, otherwise a hex string is returned +- at subfield level - by providing as subname for the varaiable the ISUP parameter name and the subfield name, allowing access to the specific subfield as an integer value or string value(eg. telephone number for parameters such as Called Party Number) for read/write or as a string alias for writing +- at byte level - by providing as subname for the variable the ISUP parameter name and an index, allowing access to the byte with the specified index as an integer value + + +Addressing at entire parameter level as a hex string and at byte level are supported for all the ISUP parameters defined in the ITU-T Rec. Q.763. Addressing at subfield level is supported only for some ISUP parameters and not all of the subfields of a parameter defined in the ITU Recommandation are supported. + + +String aliases are not available for all parameters or parameter subfields. Also, not all the possible values of a parameter or parameter subfield have a string alias defined. + + +For more information on supported subfields and aliases check [subfields aliases](#isup_parameter_subfields_and_string_aliases). + + +```opensips title="isup_param usage" +... + $isup_param(Called Party Number | Nature of address indicator) = 3; + ... + # use a string alias + $isup_param(Called Party Number | Numbering plan indicator) = "ISDN"; + ... + $isup_param(Called Party Number | Address signal) = "99991234"; + $isup_param(Nature of connection indicators) = "0x01" + $isup_param(Calling party's category) = 10; + ... + # use a string alias + $isup_param(Transmission Medium Requirement) = "speech"; + ... + # access at byte level + $(isup_param(Forward Call Indicators)[0]) = 96; + $(isup_param(Forward Call Indicators)[1]) = 1; +... + +``` + + +#### $isup_param_str(param_name{sep}subfield_name) + + +The ISUP parameter named *param_name* of a received or newly added ISUP message can also be accessed through this read-only variable. This variable is similar in usage with *$isup_param* except it will return the string alias for the value when possible. + + +The format of the subname for `$isup_param_str` is the following: + + +- *param_name* - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 +- *sep* - separator, whitespaces allowed before/after +- *subfield_name* - name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 + + +```opensips title="isup_param_str usage" +... + # may print: "NOA is: national" + xlog("NOA is: $isup_param_str(Called Party Number|Nature of address indicator)"); + # may print: "CpN is: 99991234" + xlog("CpN is: $isup_param_str(Called Party Number|Address signal)"); + # may print: "nature of conn: 0x01" + xlog("nature of conn: $isup_param_str(Nature of connection indicators)"); + # may print: "Cg cat is: ordinary" + xlog("$isup_param_str(Calling party's category)"); +... + +``` + + +#### $isup_msg_type + + +Read-only variable, returns the ISUP message type as string. + + +```opensips title="isup_msg_type usage" +... + # may print: "ISUP msg is: IAM" + xlog("ISUP msg is: $isup_msg_type"); +... + +``` + + +### Exported script transformations + + +The module also provides a way for accessing the value of ISUP parameters and their subfields from an ISUP message contained in a arbitrary script variable as opposed to directly from the processed SIP (with encapsulated ISUP) message. This is done by aplying a transformation to a script variable containing the ISUP message body. The value of the original variable is not altered and a corresponding integer or string value (representing an ISUP parameter or subfield as the exact value or string alias) is returned. + + +#### {isup.param,param_name,[subfield_name]} + + +The result of this transformation is similar to a read access of the `$isup_param` pseudovariable with the exception that byte level access is not provided. + + +The parameters for the transformation are: + + +- *param_name* - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 +- *subfield_name* - optional, name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 + + +```opensips title="isup.param usage" +... + # for this example, we take the ISUP body from the received SIP-I message + $var(isup_body) = $(rb[1]); + + # may print: "NOA is: 3" + xlog("NOA is: $(var(isup_body){isup.param, Called Party Number, Nature of address indicator})\n"); + + # may print: "CpN is: 99991234" + xlog("CpN is: $(var(isup_body){isup.param, Called Party Number, Address signal})\n"); + + # may print: "Cg cat is: 10" + xlog("Cg cat is: $(var(isup_body){isup.param, Calling party's category})\n"); + + # may print: "nature of conn: 0x01" + xlog("nature of conn: $(var(isup_body){isup.param, Nature of connection indicators})\n"); +... + +``` + + +#### {isup.param.str,param_name,[subfield_name]} + + +The result of this transformation is similar to a read access of the `$isup_param_str` pseudovariable with the exception that byte level access is not provided. + + +The parameters for the transformation are: + + +- *param_name* - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 +- *subfield_name* - optional, name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 + + +```opensips title="isup.param.str usage" +... + # for this example, we take the ISUP body from the received SIP-I message + $var(isup_body) = $(rb[1]); + + # may print: "NOA is: national" + xlog("NOA is: $(var(isup_body){isup.param.str, Called Party Number, Nature of address indicator})\n"); + + # may print: "CpN is: 99991234" + xlog("CpN is: $(var(isup_body){isup.param.str, Called Party Number, Address signal})\n"); + + # may print: "Cg cat is: ordinary" + xlog("Cg cat is: $(var(isup_body){isup.param.str, Calling party's category})\n"); + + # may print: "nature of conn: 0x01" + xlog("nature of conn: $(var(isup_body){isup.param.str, Nature of connection indicators})\n"); +... + +``` + + +### ISUP parameter subfields and string aliases + + +The supported subfields for each ISUP parameter and the string aliases for their values are the following: + + +- Nature of Connection Indicators + + - Satellite indicator + + - *no satellite* - 0 + - *one satellite* - 1 + - *two satellite* - 2 + - Continuity check indicator + + - *not required* - 0 + - *required* - 1 + - *performed* - 2 + - Echo control device indicator + + - *not included* - 0 + - *included* - 1 +- Forward Call Indicators + + - National/international call indicator + + - *national* - 0 + - *international* - 1 + - End-to-end method indicator + + - *no method* - 0 + - *pass-along* - 1 + - *SCCP* - 2 + - *pass-along and SCCP* - 3 + - Interworking indicator + + - *no interworking* - 0 + - *interworking* - 1 + - End-to-end information indicator + + - *no end-to-end* - 0 + - *end-to-end* - 1 + - ISDN user part indicator + + - *not all the way* - 0 + - *all the way* - 1 + - ISDN user part preference indicator + + - *preferred* - 0 + - *not required* - 1 + - *required* - 2 + - ISDN access indicator + + - *non-ISDN* - 0 + - *ISDN* - 1 + - SCCP method indicator + + - *no indication* - 0 + - *connectionless* - 1 + - *connection* - 2 + - *connectionless and connection* - 3 +- Optional forward call indicators + + - Closed user group call indicator + + - *non-CUG* - 0 + - *outgoing allowed* - 2 + - *outgoing not allowed* - 3 + - Simple segmentation indicator + + - *no additional information* - 0 + - *additional information* - 1 + - Connected line identity request indicator + + - *not requested* - 0 + - *requested* - 1 +- Called Party Number + + - Odd/even indicator + + - *even* - 0 + - *odd* - 1 + - Nature of address indicator + + - *subscriber* - 1 + - *unknown* - 2 + - *national* - 3 + - *international* - 4 + - *network-specific* - 5 + - *network routing national* - 6 + - *network routing network-specific* - 7 + - *network routing with CDN* - 8 + - Internal Network Number indicator + + - *allowed* - 0 + - *not allowed* - 1 + - Numbering plan indicator + + - *ISDN* - 1 + - *Data* - 3 + - *Telex* - 4 + - Address signal +- Calling Party Number + + - Odd/even indicator + + - *even* - 0 + - *odd* - 1 + - Nature of address indicator + + - *subscriber* - 1 + - *unknown* - 2 + - *national* - 3 + - *international* - 4 + - Number Incomplete indicator + + - *complete* - 0 + - *incomplete* - 1 + - Numbering plan indicator + + - *ISDN* - 1 + - *Data* - 3 + - *Telex* - 4 + - Address presentation restricted indicator + + - *allowed* - 0 + - *restricted* - 1 + - *not available* - 2 + - *reserved* - 3 + - Screening indicator + + - *user* - 0 + - *network* - 1 + - Address signal +- Backward Call Indicators + + - Charge indicator + + - *no indication* - 0 + - *no charge* - 1 + - Called party's status indicator + + - *no indication* - 0 + - *subscriber free* - 1 + - *connect* - 2 + - Called party's category indicator + + - *no indication* - 0 + - *ordinary subscriber* - 1 + - *payphone* - 2 + - End to End method indicator + + - *no end-to-end* - 0 + - *pass-along* - 1 + - *SCCP* - 2 + - *pass-along and SCCP* - 3 + - Interworking indicator + + - *no interworking* - 0 + - *interworking* - 1 + - End to End information indicator + + - *no end-to-end* - 0 + - *end-to-end* - 1 + - ISDN user part indicator + + - *not all the way* - 0 + - *all the way* - 1 + - Holding indicator + + - *not requested* - 0 + - *requested* - 1 + - ISDN access indicator + + - *non-ISDN* - 0 + - *ISDN* - 1 + - Echo control device indicator + + - *not included* - 0 + - *included* - 1 + - SCCP method indicator + + - *no indication* - 0 + - *connectionless* - 1 + - *connection* - 2 + - *connectionless and connection* - 3 +- Optional Backward Call Indicators + + - In-band information indicator + + - *no indication*- 0 + - *available* - 1 + - Call diversion may occur indicator + + - *no indication* - 0 + - *call diversion* - 1 + - Simple segmentation indicator + + - *no additional information* - 0 + - *additional information* - 1 + - MLPP user indicator + + - *no indication* - 0 + - *MLPP user* - 1 +- Connected Number + + - Odd/even indicator + + - *even* - 0 + - *odd* - 1 + - Nature of address indicator + + - *subscriber* - 1 + - *unknown* - 2 + - *national* - 3 + - *international* - 4 + - Numbering plan indicator + + - *ISDN* - 1 + - *Data* - 3 + - *Telex* - 4 + - Address presentation restricted indicator + + - *allowed* - 0 + - *restricted* - 1 + - *not available* - 2 + - Screening indicator + + - *user* - 0 + - *network* - 1 + - Address signal +- Original Called Number + + - Odd/even indicator + + - *even* - 0 + - *odd* - 1 + - Nature of address indicator + + - *subscriber* - 1 + - *unknown* - 2 + - *national* - 3 + - *international* - 4 + - Numbering plan indicator + + - *ISDN* - 1 + - *Data* - 3 + - *Telex* - 4 + - Address presentation restricted indicator + + - *allowed* - 0 + - *restricted* - 1 + - *not available* - 2 + - *reserved* - 3 +- Redirecting Number - same as *Original Called Number* +- Redirection Number - same as *Called Party Number* +- Redirection information + + - Redirecting indicator + + - *no redirection* - 0 + - *call rerouted* - 1 + - *call rerouted, all information restricted* - 2 + - *call diverted* - 3 + - *Call diverted, all information restricted* - 4 + - *call rerouted, redirection number restricted* - 5 + - *call diversion, redirection number restricted* - 6 + - Original redirection reason + + - *unknown/not available* - 0 + - *user busy* - 1 + - *no reply* - 2 + - *unconditional* - 3 + - Redirection counter + + - 1 + - 2 + - 3 + - 4 + - 5 + - Redirecting reason + + - *unknown/not available* - 0 + - *user busy* - 1 + - *no reply* - 2 + - *unconditional* - 3 + - *deflection alerting* - 4 + - *deflection response* - 5 + - *mobile not reachable* - 6 +- Cause Indicators + + - Location + + - *user* - 0 + - *LPN* - 1 + - *LN* - 2 + - *TN* - 3 + - *RLN* - 4 + - *RPN* - 5 + - *INTL* - 7 + - *BI* - 10 + - Coding standard + + - *ITU-T* - 0 + - *ISO/IEC* - 1 + - *national* - 2 + - *location* - 3 + - Cause value +- Subsequent Number + + - Odd/even indicator + + - *even* - 0 + - *odd* - 1 + - Address signal +- Event Information + + - Event indicator + + - *alerting* - 1 + - *progress* - 2 + - *in-band or pattern* - 3 + - *busy* - 4 + - *no reply* - 5 + - *unconditional* - 6 + - Event presentation restricted indicator + + - *no indication* - 0 + - *restricted* - 1 +- Calling Party's Category + + - *unknown* - 0 + - *french* - 1 + - *english* - 2 + - *german* - 3 + - *russian* - 4 + - *spanish* - 5 + - *ordinary* - 10 + - *priority* - 11 + - *data* - 12 + - *test* - 13 + - *payphone* - 15 +- Transmission Medium Requirement + + - *speech* - 0 + - *64 kbit/s unrestricted* - 2 + - *3.1 kHz audio* - 3 + - *64 kbit/s preferred* - 6 + - *2 x 64 kbit/s* - 7 + - *384 kbit/s* - 8 + - *1536 kbit/s* - 9 + - *1920 kbit/s* - 10 + + +### Mandatory ISUP parameters + + +The mandatory parameters(According to ITU-T Rec. Q.763) for each supported ISUP message that requires this are the following: + + +- Initial address + + - Nature of connection indicators + - Forward call indicators + - Calling party's category + - Transmission medium requirement + - Called party number +- Address complete + + - Backward call indicators +- Connect + + - Backward call indicators +- Release + + - Cause indicators +- Call progress + + - Event information +- Facility reject + + - Facility indicator + + - Cause indicators +- Facility accepted + + - Facility indicator +- Facility request + + - Facility indicator +- Confusion + + - Cause indicators +- Suspend + + - Suspend/resume indicators +- Resume + + - Suspend/resume indicators +- Subsequent address + + - Subsequent number +- User-to-user information + + - User-to-user information + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sip_i/doc/contributors.xml b/modules/sip_i/doc/contributors.xml deleted file mode 100644 index fe7e65a69d7..00000000000 --- a/modules/sip_i/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 129 - 44 - 6684 - 1643 - - - 2. - Razvan Crainea (@razvancrainea) - 11 - 9 - 21 - 20 - - - 3. - Liviu Chircu (@liviuchircu) - 8 - 6 - 24 - 31 - - - 4. - Maksym Sobolyev (@sobomax) - 7 - 5 - 14 - 15 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 4 - 83 - 11 - - - 6. - Rustam Safargalin - 3 - 1 - 80 - 1 - - - 7. - Walter Doekes (@wdoekes) - 3 - 1 - 16 - 20 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2018 - Jan 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Feb 2017 - Jul 2021 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Oct 2016 - Dec 2020 - - - 5. - Rustam Safargalin - Apr 2020 - Apr 2020 - - - 6. - Walter Doekes (@wdoekes) - Apr 2019 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Liviu Chircu (@liviuchircu) - Apr 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/sip_i/doc/sip_i.xml b/modules/sip_i/doc/sip_i.xml deleted file mode 100644 index 324ea364fe3..00000000000 --- a/modules/sip_i/doc/sip_i.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - SIP-I Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2016 &osipssol; - diff --git a/modules/sip_i/doc/sip_i_admin.xml b/modules/sip_i/doc/sip_i_admin.xml deleted file mode 100644 index d3ae5acdd5e..00000000000 --- a/modules/sip_i/doc/sip_i_admin.xml +++ /dev/null @@ -1,1618 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module offers the possibility of processing ISDN User Part(ISUP) messages encapsulated in SIP. The available operations are: reading and modifying parameters from an ISUP message, removing or adding new optional parameters, adding an ISUP part to a SIP message body. This is done explicitly via script pseudovariables and functions. - - - The supported ISUP message types are only the ones that can be included in a SIP message according to the SIP-I(SIP with encapsulated ISUP) protocol defined by ITU-T. - - - The format and specification of the ISUP messages and parameters follow the recomandations from ITU-T Rec. Q.763. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Parameters -
- <varname>param_subfield_separator</varname> (str) - - The character to be used as separator in the subname of the $isup_param and $isup_param_str pseudovariables between the ISUP parameter name and subfield name. - - - - Default value is "|". - - - - Set <varname>param_subfield_separator</varname> parameter - -... -modparam("sip_i", "param_subfield_separator", ":") -... - - -
-
- <varname>isup_mime_str</varname> (str) - - The string to be used for the Content-Type header field of the ISUP MIME body when creating a new ISUP part. - - - - Default value is "application/ISUP;version=itu-t92+". - - - - Set <varname>isup_mime_str</varname> parameter - -... -modparam("sip_i", "isup_mime_str", "application/ISUP;base=itu-t92+;version=itu-t") -... - - - -
-
- <varname>default_part_headers</varname> (str) - - The default set of headers (fully defined, including the header - termination) to be pushed into the ISUP part together - with the Content-Type header. - - - - Default value is "Content-Disposition:signal;handling=optional\r\n". - - - - Set <varname>default_part_headers</varname> parameter - -... -modparam("sip_i", "default_part_headers", "Content-Disposition:signal;handling=required\r\n") -... - - - -
-
- <varname>country_code</varname> (str) - - Country Code that the first part of the number from - P-Asserted-Identity is tested against when trying to map the - Calling Party Number ISUP parameter from SIP by default. If there - is a match, the value assigned to the Nature of Address Indicator - subfield is 3(national), otherwise it is - 4(international). - - - - Default value is "+1". - - - - Set <varname>country_code</varname> parameter - -... -modparam("sip_i", "country_code", "+4") -... - - - -
- - -
- -
- Exported Functions - -
- - <function moreinfo="none">add_isup_part([isup_msg_type][,extra_headers])</function> - - - Adds a new ISUP part to the SIP message body. - - - With the exception of some ISUP message types(IAM, REL, ACM, CPG, ANM, CON), the newly added part contains a blank ISUP message(i.e. all mandatory parameters zeroed and no optional ones) and all the required parameters should be set through $isup_param. For the previously mentioned message types, the mandatory parameters and some optional ones are automaticaly set to default values according to basic SIP-ISUP interworking rules from ITU-T Rec. Q.1912.5. This only provides a general and simplified mapping from SIP headers and message type (request method, reply code etc.) to ISUP parameters and you should not base your SIP-ISUP interworking only on this. - - Meaning of the parameters is as follows: - - - isup_msg_type (string, optional) - name of the ISUP message to be added, exactly as it appears in ITU-T Rec. Q.763 or an abbreviation(eg. IAM for "Initial address"). - - - - extra_headers (string, string, optional) - a chunk of fully defined SIP headers (including header terminatior) to be inserted into the ISUP part next to the Content-Type header. It overrides the global module parameter default_part_headers. If not specified, the default_part_headers value will be used. - - - - - If isup_msg_type is not explicitly provided, it is automatically deduced from the SIP message as follows: - - - - INVITE - IAM - - - - - BYE - REL - - - - - 180, 183 - ACM - - - - - 4xx, 5xx - REL - - - - - 200 OK INVITE - ANM - - - - - 200 OK BYE - RLC - - - - - - The abbreviations that can be given as isup_msg_type for each ISUP message type are the following: - - - - Initial address - IAM - - - - - Address complete - ACM - - - - - Answer - ANM - - - - - Connect - CON - - - - - Release - REL - - - - - Release complete - RLC - - - - - Call progress - CPG - - - - - Facility reject - FRJ - - - - - Facility accepted - FAA - - - - - Facility request - FAR - - - - - Confusion - CFN - - - - - Suspend - SUS - - - - - Resume - RES - - - - - Subsequent address - SAM - - - - - Forward transfer - FOT - - - - - User-to-user information - USR - - - - - Network resource management - NRM - - - - - Facility - FAC - - - - - Identification request - IRQ - - - - - Identification response - IRS - - - - - Loop prevention - LPR - - - - - Application transport - APT - - - - - Pre-release information - PRI - - - - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,LOCAL_ROUTE. - - - <function>add_isup_part</function> usage - -... -if ($rs == "183") { - # Encapsulate a CPG - add_isup_part("Call progress"); - # set desired parameters - ... -} -... - - - -
- -
- -
- Exported Pseudo-Variables - -
- - <varname>$(isup_param(param_name{sep}subfield_name)[byte_index])</varname> - - The ISUP parameter named param_name of a received or newly added ISUP message can be accessed through this read-write variable. For optional parameters, writing to a param_name that does not exist in this ISUP message will insert it. Assigning null to this variable will remove the optional parameter from the message or zeroize the parameter in case of a mandatory one. - - The format of the subname for $isup_param is the following: - - - param_name - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - sep - separator, whitespaces allowed before/after - - - subfield_name - name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - The ISUP parameter can be addressed in different ways: - - - - entire parameter - by providing as subname for the varaiable only the ISUP parameter name, allowing access to the contents of the entire parameter as: a hex string(similar to a hex "dump") for read/write, a string alias for writing, or an integer value for read/write; when assigning a hex string, the hex value must be preceded by "0x"; when reading, if string aliases are supported for this parameter, an associated integer value will be returned, otherwise a hex string is returned - - - - - at subfield level - by providing as subname for the varaiable the ISUP parameter name and the subfield name, allowing access to the specific subfield as an integer value or string value(eg. telephone number for parameters such as Called Party Number) for read/write or as a string alias for writing - - - - - at byte level - by providing as subname for the variable the ISUP parameter name and an index, allowing access to the byte with the specified index as an integer value - - - - Addressing at entire parameter level as a hex string and at byte level are supported for all the ISUP parameters defined in the ITU-T Rec. Q.763. Addressing at subfield level is supported only for some ISUP parameters and not all of the subfields of a parameter defined in the ITU Recommandation are supported. - String aliases are not available for all parameters or parameter subfields. Also, not all the possible values of a parameter or parameter subfield have a string alias defined. - For more information on supported subfields and aliases check . - - <varname>isup_param</varname> usage - -... - $isup_param(Called Party Number | Nature of address indicator) = 3; - ... - # use a string alias - $isup_param(Called Party Number | Numbering plan indicator) = "ISDN"; - ... - $isup_param(Called Party Number | Address signal) = "99991234"; - $isup_param(Nature of connection indicators) = "0x01" - $isup_param(Calling party's category) = 10; - ... - # use a string alias - $isup_param(Transmission Medium Requirement) = "speech"; - ... - # access at byte level - $(isup_param(Forward Call Indicators)[0]) = 96; - $(isup_param(Forward Call Indicators)[1]) = 1; -... - - -
- -
- - <varname>$isup_param_str(param_name{sep}subfield_name)</varname> - - The ISUP parameter named param_name of a received or newly added ISUP message can also be accessed through this read-only variable. This variable is similar in usage with $isup_param except it will return the string alias for the value when possible. - - The format of the subname for $isup_param_str is the following: - - - param_name - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - sep - separator, whitespaces allowed before/after - - - subfield_name - name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - - <varname>isup_param_str</varname> usage - -... - # may print: "NOA is: national" - xlog("NOA is: $isup_param_str(Called Party Number|Nature of address indicator)"); - # may print: "CpN is: 99991234" - xlog("CpN is: $isup_param_str(Called Party Number|Address signal)"); - # may print: "nature of conn: 0x01" - xlog("nature of conn: $isup_param_str(Nature of connection indicators)"); - # may print: "Cg cat is: ordinary" - xlog("$isup_param_str(Calling party's category)"); -... - - -
- -
- - <varname>$isup_msg_type</varname> - - - Read-only variable, returns the ISUP message type as string. - - - <varname>isup_msg_type</varname> usage - -... - # may print: "ISUP msg is: IAM" - xlog("ISUP msg is: $isup_msg_type"); -... - - -
- -
- -
- Exported script transformations - - The module also provides a way for accessing the value of ISUP parameters and their subfields from an ISUP message contained in a arbitrary script variable as opposed to directly from the processed SIP (with encapsulated ISUP) message. This is done by aplying a transformation to a script variable containing the ISUP message body. The value of the original variable is not altered and a corresponding integer or string value (representing an ISUP parameter or subfield as the exact value or string alias) is returned. - - -
- - <varname>{isup.param,param_name,[subfield_name]}</varname> - - - The result of this transformation is similar to a read access of the $isup_param pseudovariable with the exception that byte level access is not provided. - - - The parameters for the transformation are: - - - param_name - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - subfield_name - optional, name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - - - <varname>isup.param</varname> usage - -... - # for this example, we take the ISUP body from the received SIP-I message - $var(isup_body) = $(rb[1]); - - # may print: "NOA is: 3" - xlog("NOA is: $(var(isup_body){isup.param, Called Party Number, Nature of address indicator})\n"); - - # may print: "CpN is: 99991234" - xlog("CpN is: $(var(isup_body){isup.param, Called Party Number, Address signal})\n"); - - # may print: "Cg cat is: 10" - xlog("Cg cat is: $(var(isup_body){isup.param, Calling party's category})\n"); - - # may print: "nature of conn: 0x01" - xlog("nature of conn: $(var(isup_body){isup.param, Nature of connection indicators})\n"); -... - - - -
- -
- - <varname>{isup.param.str,param_name,[subfield_name]}</varname> - - - The result of this transformation is similar to a read access of the $isup_param_str pseudovariable with the exception that byte level access is not provided. - - - The parameters for the transformation are: - - - param_name - name of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - subfield_name - optional, name of the subfield of the ISUP parameter as it appears in ITU-T Rec. Q.763 - - - - - <varname>isup.param.str</varname> usage - -... - # for this example, we take the ISUP body from the received SIP-I message - $var(isup_body) = $(rb[1]); - - # may print: "NOA is: national" - xlog("NOA is: $(var(isup_body){isup.param.str, Called Party Number, Nature of address indicator})\n"); - - # may print: "CpN is: 99991234" - xlog("CpN is: $(var(isup_body){isup.param.str, Called Party Number, Address signal})\n"); - - # may print: "Cg cat is: ordinary" - xlog("Cg cat is: $(var(isup_body){isup.param.str, Calling party's category})\n"); - - # may print: "nature of conn: 0x01" - xlog("nature of conn: $(var(isup_body){isup.param.str, Nature of connection indicators})\n"); -... - - - -
-
- -
- ISUP parameter subfields and string aliases - The supported subfields for each ISUP parameter and the string aliases for their values are the following: - - - Nature of Connection Indicators - - - Satellite indicator - - - no satellite - 0 - - - one satellite - 1 - - - two satellite - 2 - - - - - Continuity check indicator - - - not required - 0 - - - required - 1 - - - performed - 2 - - - - - Echo control device indicator - - - not included - 0 - - - included - 1 - - - - - - - Forward Call Indicators - - - National/international call indicator - - - national - 0 - - - international - 1 - - - - - End-to-end method indicator - - - no method - 0 - - - pass-along - 1 - - - SCCP - 2 - - - pass-along and SCCP - 3 - - - - - Interworking indicator - - - no interworking - 0 - - - interworking - 1 - - - - - End-to-end information indicator - - - no end-to-end - 0 - - - end-to-end - 1 - - - - - ISDN user part indicator - - - not all the way - 0 - - - all the way - 1 - - - - - ISDN user part preference indicator - - - preferred - 0 - - - not required - 1 - - - required - 2 - - - - - ISDN access indicator - - - non-ISDN - 0 - - - ISDN - 1 - - - - - SCCP method indicator - - - no indication - 0 - - - connectionless - 1 - - - connection - 2 - - - connectionless and connection - 3 - - - - - - - Optional forward call indicators - - - Closed user group call indicator - - - non-CUG - 0 - - - outgoing allowed - 2 - - - outgoing not allowed - 3 - - - - - Simple segmentation indicator - - - no additional information - 0 - - - additional information - 1 - - - - - Connected line identity request indicator - - - not requested - 0 - - - requested - 1 - - - - - - - Called Party Number - - - Odd/even indicator - - - even - 0 - - - odd - 1 - - - - - Nature of address indicator - - - subscriber - 1 - - - unknown - 2 - - - national - 3 - - - international - 4 - - - network-specific - 5 - - - network routing national - 6 - - - network routing network-specific - 7 - - - network routing with CDN - 8 - - - - - Internal Network Number indicator - - - allowed - 0 - - - not allowed - 1 - - - - - Numbering plan indicator - - - ISDN - 1 - - - Data - 3 - - - Telex - 4 - - - - - Address signal - - - - - Calling Party Number - - - Odd/even indicator - - - even - 0 - - - odd - 1 - - - - - Nature of address indicator - - - subscriber - 1 - - - unknown - 2 - - - national - 3 - - - international - 4 - - - - - Number Incomplete indicator - - - complete - 0 - - - incomplete - 1 - - - - - Numbering plan indicator - - - ISDN - 1 - - - Data - 3 - - - Telex - 4 - - - - - Address presentation restricted indicator - - - allowed - 0 - - - restricted - 1 - - - not available - 2 - - - reserved - 3 - - - - - Screening indicator - - - user - 0 - - - network - 1 - - - - - Address signal - - - - - Backward Call Indicators - - - Charge indicator - - - no indication - 0 - - - no charge - 1 - - - - - Called party's status indicator - - - no indication - 0 - - - subscriber free - 1 - - - connect - 2 - - - - - Called party's category indicator - - - no indication - 0 - - - ordinary subscriber - 1 - - - payphone - 2 - - - - - End to End method indicator - - - no end-to-end - 0 - - - pass-along - 1 - - - SCCP - 2 - - - pass-along and SCCP - 3 - - - - - Interworking indicator - - - no interworking - 0 - - - interworking - 1 - - - - - End to End information indicator - - - no end-to-end - 0 - - - end-to-end - 1 - - - - - ISDN user part indicator - - - not all the way - 0 - - - all the way - 1 - - - - - Holding indicator - - - not requested - 0 - - - requested - 1 - - - - - ISDN access indicator - - - non-ISDN - 0 - - - ISDN - 1 - - - - - Echo control device indicator - - - not included - 0 - - - included - 1 - - - - - SCCP method indicator - - - no indication - 0 - - - connectionless - 1 - - - connection - 2 - - - connectionless and connection - 3 - - - - - - - Optional Backward Call Indicators - - - In-band information indicator - - - no indication- 0 - - - available - 1 - - - - - Call diversion may occur indicator - - - no indication - 0 - - - call diversion - 1 - - - - - Simple segmentation indicator - - - no additional information - 0 - - - additional information - 1 - - - - - MLPP user indicator - - - no indication - 0 - - - MLPP user - 1 - - - - - - - Connected Number - - - Odd/even indicator - - - even - 0 - - - odd - 1 - - - - - Nature of address indicator - - - subscriber - 1 - - - unknown - 2 - - - national - 3 - - - international - 4 - - - - - Numbering plan indicator - - - ISDN - 1 - - - Data - 3 - - - Telex - 4 - - - - - Address presentation restricted indicator - - - allowed - 0 - - - restricted - 1 - - - not available - 2 - - - - - Screening indicator - - - user - 0 - - - network - 1 - - - - - Address signal - - - - - Original Called Number - - - Odd/even indicator - - - even - 0 - - - odd - 1 - - - - - Nature of address indicator - - - subscriber - 1 - - - unknown - 2 - - - national - 3 - - - international - 4 - - - - - Numbering plan indicator - - - ISDN - 1 - - - Data - 3 - - - Telex - 4 - - - - - Address presentation restricted indicator - - - allowed - 0 - - - restricted - 1 - - - not available - 2 - - - reserved - 3 - - - - - - - Redirecting Number - same as Original Called Number - - - Redirection Number - same as Called Party Number - - - Redirection information - - - Redirecting indicator - - - no redirection - 0 - - - call rerouted - 1 - - - call rerouted, all information restricted - 2 - - - call diverted - 3 - - - Call diverted, all information restricted - 4 - - - call rerouted, redirection number restricted - 5 - - - call diversion, redirection number restricted - 6 - - - - - Original redirection reason - - - unknown/not available - 0 - - - user busy - 1 - - - no reply - 2 - - - unconditional - 3 - - - - - Redirection counter - - - 1 - - - 2 - - - 3 - - - 4 - - - 5 - - - - - Redirecting reason - - - unknown/not available - 0 - - - user busy - 1 - - - no reply - 2 - - - unconditional - 3 - - - deflection alerting - 4 - - - deflection response - 5 - - - mobile not reachable - 6 - - - - - - - Cause Indicators - - - Location - - - user - 0 - - - LPN - 1 - - - LN - 2 - - - TN - 3 - - - RLN - 4 - - - RPN - 5 - - - INTL - 7 - - - BI - 10 - - - - - Coding standard - - - ITU-T - 0 - - - ISO/IEC - 1 - - - national - 2 - - - location - 3 - - - - - Cause value - - - - - Subsequent Number - - - Odd/even indicator - - - even - 0 - - - odd - 1 - - - - - Address signal - - - - - Event Information - - - Event indicator - - - alerting - 1 - - - progress - 2 - - - in-band or pattern - 3 - - - busy - 4 - - - no reply - 5 - - - unconditional - 6 - - - - - Event presentation restricted indicator - - - no indication - 0 - - - restricted - 1 - - - - - - - Calling Party's Category - - - unknown - 0 - - - french - 1 - - - english - 2 - - - german - 3 - - - russian - 4 - - - spanish - 5 - - - ordinary - 10 - - - priority - 11 - - - data - 12 - - - test - 13 - - - payphone - 15 - - - - - Transmission Medium Requirement - - - speech - 0 - - - 64 kbit/s unrestricted - 2 - - - 3.1 kHz audio - 3 - - - 64 kbit/s preferred - 6 - - - 2 x 64 kbit/s - 7 - - - 384 kbit/s - 8 - - - 1536 kbit/s - 9 - - - 1920 kbit/s - 10 - - - - -
- -
- Mandatory ISUP parameters - The mandatory parameters(According to ITU-T Rec. Q.763) for each supported ISUP message that requires this are the following: - - - Initial address - - Nature of connection indicators - Forward call indicators - Calling party's category - Transmission medium requirement - Called party number - - - - Address complete - - Backward call indicators - - - - Connect - - Backward call indicators - - - - Release - - Cause indicators - - - - Call progress - - Event information - - - - Facility reject - - Facility indicator - - - Cause indicators - - - - Facility accepted - - Facility indicator - - - - Facility request - - Facility indicator - - - - Confusion - - Cause indicators - - - - Suspend - - Suspend/resume indicators - - - - Resume - - Suspend/resume indicators - - - - Subsequent address - - Subsequent number - - - - User-to-user information - - User-to-user information - - - -
- -
diff --git a/modules/sip_i/sip_i.c b/modules/sip_i/sip_i.c index 481a383df43..ead18fd8a76 100644 --- a/modules/sip_i/sip_i.c +++ b/modules/sip_i/sip_i.c @@ -1661,7 +1661,7 @@ static int add_isup_part_cmd(struct sip_msg *msg, str *msg_type, str *hdrs) else if (msg->REPLY_STATUS == 200) { if (get_cseq(msg)->method_id == METHOD_INVITE) /* 200 OK INVITE -> ANM */ - isup_msg_idx = get_msg_idx_by_type(ISUP_REL); + isup_msg_idx = get_msg_idx_by_type(ISUP_ANM); else if (get_cseq(msg)->method_id == METHOD_BYE) /* 200 OK INVITE -> RLC */ isup_msg_idx = get_msg_idx_by_type(ISUP_RLC); diff --git a/modules/sipcapture/README b/modules/sipcapture/README deleted file mode 100644 index f2d7a0bd615..00000000000 --- a/modules/sipcapture/README +++ /dev/null @@ -1,818 +0,0 @@ -SipCapture Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Parameters - - 1.3.1. db_url (str) - 1.3.2. table_name (str) - 1.3.3. rtcp_table_name (str) - 1.3.4. capture_on (integer) - 1.3.5. hep_capture_on (integer) - 1.3.6. max_async_queries (integer) - 1.3.7. raw_ipip_capture_on (integer) - 1.3.8. raw_moni_capture_on (integer) - 1.3.9. raw_socket_listen (string) - 1.3.10. raw_interface (string) - 1.3.11. raw_sock_children (integer) - 1.3.12. promiscuous_on (integer) - 1.3.13. raw_moni_bpf_on (integer) - 1.3.14. capture_node (str) - 1.3.15. hep_route (string) - - 1.4. Exported Functions - - 1.4.1. sip_capture([table_name], [custom_field1], - [custom_field2], [custom_field3]) - - 1.4.2. report_capture(correlation_id, [table_name], - [proto_type]) - - 1.4.3. hep_set(chunk_id, chunk_data, [data_type], - [vendor_id]) - - 1.4.4. hep_get(chunk_id, data_type, [chunk_data_pv], - [vendor_id_pv]) - - 1.4.5. hep_del(chunk_id) - 1.4.6. hep_relay() - 1.4.7. hep_resume_sip() - - 1.5. Exported Async Functions - - 1.5.1. sip_capture() - - 1.6. Exported Pseudo-Variables - - 1.6.1. $hep_net - 1.6.2. HEPVERSION (string, int) - - 1.7. MI Commands - - 1.7.1. sip_capture - - 1.8. Database setup - 1.9. Limitation - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set table_name parameter - 1.3. Set rtcp_capture parameter - 1.4. Set capture_on parameter - 1.5. Set hep_capture_on parameter - 1.6. Set max_async_queries parameter - 1.7. Set raw_ipip_capture_on parameter - 1.8. Set raw_moni_capture_on parameter - 1.9. Set raw_socket_listen parameter - 1.10. Set raw_socket_listen parameter - 1.11. Set raw_socket_listen parameter - 1.12. Set promiscuous_on parameter - 1.13. Set raw_moni_bpf_on parameter - 1.14. Set capture_node parameter - 1.15. Set hep_route parameter - 1.16. sip_capture usage - 1.17. sip_capture usage - 1.18. hep_set usage - 1.19. hep_set usage - 1.20. hep_set usage - 1.21. hep_relay usage - 1.22. hep_resume_sip usage - 1.23. sip_capture usage - 1.24. hep_net usage - 1.25. HEPVERSION usage - -Chapter 1. Admin Guide - -1.1. Overview - - Offer a possibility to store incoming/outgoing SIP messages in - database. - - OpenSIPs can capture SIP messages in three mode - * IPIP encapsulation. (ETHHDR+IPHDR+IPHDR+UDPHDR). - * Monitoring/mirroring port. - * Homer encapsulation protocl mode (HEP v1/2/3). With version - 2.2 comes the new HEPv3 support using the proto _hep - module. Also header manipulation support for HEPv3 has been - added. See hep_set() for more details. If you want more - information about hep protocol check this link. - - The capturing can be turned on/off using fifo commad. - - opensips-cli -x mi sip_capture on - - opensips-cli -x mi sip_capture off - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * database module - mysql, postrgress, dbtext, unixodbc... - * proto_hep module - if hep capturing used - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Parameters - -1.3.1. db_url (str) - - Database URL. - - Default value is "". - - Example 1.1. Set db_url parameter -... -modparam("sipcapture", "db_url", "mysql://user:passwd@host/dbname") -... - -1.3.2. table_name (str) - - Name of the table's name where to store the SIP messages. Since - version 2.2 it allows strftime-like suffix for having time - formatted table names. - - Default value is "sip_capture". - - Example 1.2. Set table_name parameter -... -modparam("sipcapture", "table_name", "homer_capture") - -/* change table name every day */ -modparam("sipcapture", "table_name", "homer_%m_%d") -/* if today is 13-04-2014 it will exetend to homer_04_13 */ -... - - -1.3.3. rtcp_table_name (str) - - Name of the table's name where to store packets captured with - report_capture function. Since version 2.2 it allows - strftime-like suffix for having time formatted table names. - - Default value is "rtcp_capture". - - Example 1.3. Set rtcp_capture parameter -... -modparam("sipcapture", "rtcp_table_name", "homer_capture") - -/* change table name every hour */ -modparam("sipcapture", "rtcp_table_name", "homer_%m_%d_%H") -/* if today is 13-04-2014 13:05 pm it will exetend to homer_04_13_13 */ -... - -1.3.4. capture_on (integer) - - Parameter to enable/disable capture globaly (on(1)/off(0)) - - Default value is "0". - - Example 1.4. Set capture_on parameter -... -modparam("sipcapture", "capture_on", 1) -... - -1.3.5. hep_capture_on (integer) - - Parameter to enable/disable capture of HEP (on(1)/off(0)) - - Default value is "0". - - Example 1.5. Set hep_capture_on parameter -... -modparam("sipcapture", "hep_capture_on", 1) -... - -1.3.6. max_async_queries (integer) - - Parameter to set the maximum number of 'INSERT' queries of - captured packets to be done in the same time, only if the DB - supports async operations. If OpenSIPS is shut down, the - remaining queries shall be executed. The query buffer is - limited 65535 chars, so probably no more than 30-40 queries can - be done in the same time, depending mostly on the size of the - inserted sip message, since it's the biggest part of the query. - - Default value is "5". - - Example 1.6. Set max_async_queries parameter -... -modparam("sipcapture", "max_async_queries", 3) -... - -1.3.7. raw_ipip_capture_on (integer) - - Parameter to enable/disable IPIP capturing (on(1)/off(0)) - - Default value is "0". - - Example 1.7. Set raw_ipip_capture_on parameter -... -modparam("sipcapture", "raw_ipip_capture_on", 1) -... - -1.3.8. raw_moni_capture_on (integer) - - Parameter to enable/disable monitoring/mirroring port capturing - (on(1)/off(0)) Only one mode on raw socket can be enabled! - Monitoring port capturing currently supported only on Linux. - - Default value is "0". - - Example 1.8. Set raw_moni_capture_on parameter -... -modparam("sipcapture", "raw_moni_capture_on", 1) -... - -1.3.9. raw_socket_listen (string) - - Parameter indicate an listen IP address of RAW socket for IPIP - capturing. You can also define a port/portrange for - IPIP/Mirroring mode, to capture SIP messages in specific ports: - - "10.0.0.1:5060" - the source/destination port of the SIP - message must be equal 5060 - - "10.0.0.1:5060-5090" - the source/destination port of the SIP - message must be equal or be between 5060 and 5090. - - The port/portrange must be defined if you are planning to use - mirroring capture! In this case, the part with IP address will - be ignored, but to make parser happy, use i.e. 10.0.0.0 - - Default value is "". - - Example 1.9. Set raw_socket_listen parameter -... -modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060-5090") -... -modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060") -... - -1.3.10. raw_interface (string) - - Name of the interface to bind on the raw socket. - - Default value is "". - - Example 1.10. Set raw_socket_listen parameter -... -modparam("sipcapture", "raw_interface", "eth0") -... - -1.3.11. raw_sock_children (integer) - - Parameter define how much children must be created to listen - the raw socket. - - Default value is "1". - - Example 1.11. Set raw_socket_listen parameter -... -modparam("sipcapture", "raw_sock_children", 6) -... - -1.3.12. promiscuous_on (integer) - - Parameter to enable/disable promiscuous mode on the raw socket. - Linux only. - - Default value is "0". - - Example 1.12. Set promiscuous_on parameter -... -modparam("sipcapture", "promiscuous_on", 1) -... - -1.3.13. raw_moni_bpf_on (integer) - - Activate Linux Socket Filter (LSF based on BPF) on the - mirroring interface. The structure is defined in - linux/filter.h. The default LSF accept a port/portrange from - the raw_socket_listen param. Currently LSF supported only on - Linux. - - Default value is "0". - - Example 1.13. Set raw_moni_bpf_on parameter -... -modparam("sipcapture", "raw_moni_bpf_on", 1) -... - -1.3.14. capture_node (str) - - Name of the capture node. - - Default value is "homer01". - - Example 1.14. Set capture_node parameter -... -modparam("sipcapture", "capture_node", "homer03") -... - -1.3.15. hep_route (string) - - Specifies what path your hep messages should take. Possible - values are the following: - * none - don't go through the script; do directly - sip_capture(); - * sip(default) - go through the main request route; here the - message is parsed and you can do anything you want with it; - * any other string value - define a route name through which - your hep messages should go; the message is not parsed - because of efficiency reasons; from here you can modify the - hep chunks(if hep version 3 is used) and relay the hep - messages to other hep capture nodes; - - Default value is sip(going thorugh the main request route). - - Example 1.15. Set hep_route parameter -... -modparam("sipcapture", "hep_route", "my_hep_route") -... - -route[my_hep_route] { - /* do hep stuff in here */ - ... -} -... - -1.4. Exported Functions - -1.4.1. sip_capture([table_name], [custom_field1], [custom_field2], -[custom_field3]) - - Save the message into the database. - - Meaning of the parameters is as follows: - * table_name (string, optional) - the name of the table to - store the packet; it can have a strftime-like formatted - suffix in order to change it's name based on time; if not - set, modparam defined table will be used; - custom_field1 (string, optional) - custom data to store - inside the "custom_field1" column - custom_field2 (string, optional) - custom data to store - inside the "custom_field2" column - custom_field3 (string, optional) - custom data to store - inside the "custom_field3" column - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Example 1.16. sip_capture usage -... -if (is_method("REGISTER")) - sip_capture(); - ... - /* table name will change every day */ - sip_capture("homer_%m_%d"); - sip_capture("homer_%m_%d", , $hdr(P-Asserted-Identity)); -... - -1.4.2. report_capture(correlation_id, [table_name], [proto_type]) - - Save the message into the database. If you want set the - protocol type you have to define the table name, even if you - pass over it(report_capture($var(cor_id),,$var(proto_type))). - - Meaning of the parameters is as follows: - * correlation_id (string) - * table_name (string, optional) - the name of the table to - store the packet; it can have a strftime-like formatted - suffix in order to change it's name based on time; - * proto_type (int, optional) - protocol type number as - defined in hep protocol specification. - - VERY IMPORTANT: Since version 2.3 report_capture function - behaviour will change depending on homer5_on parameter from - proto_hep. Check sql folder from the module to check the fields - of the tables for each version. - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Example 1.17. sip_capture usage -... - hep_get("0x0011", "utf8-string", , $var(correlation_id)); - if ($var(correlation_id) == null) { - xlog("NO CORRELATION ID! SET SOMETHING OR DROP"); - $var(correlation_id) = "absdcef"; - } - - $var(proto_type) = "3"; /* 0x03 - SDP protocol */ - - report_capture($var(correlation_id), "rtcp_log"); - /* setting the 2nd parameter, even if setting it to null, is man -datory in order to be able to set proto type */ - report_capture($var(correlation_id), , $var(proto_type)); - report_capture($var(correlation_id), "rtcp_log", $var(proto_type -)); -... - -1.4.3. hep_set(chunk_id, chunk_data, [data_type], [vendor_id]) - - Set a hep chunk. If not exists, it shall be added. - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Meaning of the parameters is as follows: - * chunk_id(string value with hex/int or string identifier of - chunk) - id of the chunk to be added; most of the generic - chunks are in the internal hep structure. For these you can - skip the data_type and vendor_id since they are already - known. Generic chunks that don't have built in support are - the followinig: 0x000d(keep alive timer), - 0x000e(authenticate key), 0x0011(internal correltion id), - 0x0012(vlan ID). You can set these chunks, but only with - vendor id 0x0000, other values shall result in an error. - Timestamp(0x0009) and timestamp_us(0x000A) chunks can't be - set. For chunks that have built-in support you can also use - strings instead of chunk ids as follows: - + 0x0001 - proto_family(CAN'T BE SET; it shall be - automatically updated if you change the type of the - source/destination address from IPv4 to IPv6 or else) - + 0x0002 - proto_id; since it's quite hard to know the - int values for the protocol one can change this value - using the following string values: - o UDP - o TCP - o TLS - o SCTP - o WS - o WSS - o BIN - o HEP - + 0x0003 - src_ip - + 0x0004 - dst_ip - + 0x0005 - src_ip - + 0x0006 - dst_ip - + 0x0007 - src_port - + 0x0008 - dst_port - + 0x0009 - timestamp(CAN'T BE SET) - + 0x000A - timestamp_us(CAN'T BE SET) - + 0x000B - proto_type; for this variable there are - predefined strings which can be set: - o SIP - o XMPP - o SDP - o RTP - o RTCP - o MGCP - o MEGACO - o M2UA - o M3UA - o IAX - o H322 - o H321 - + 0x000C - captagent_id - + 0x000f - payload - + 0x0010 - payload - * chunk_data(string) - data that the chunk shall contain; - internally it shall be converted to the requested data type - * data_type (string, optional, default: "utf8-string") - data - type of the data in the chunk. It can have the following - values: - + uint8 - byte unsigned integer - + uint16 - word unsigned integer - + uint32 - 4 byte unsigned integer - + inet4-addr - IPv4 address in human readable format - + inet6-addr - IPv6 address in human readable format - + utf8-string - UTF8 encoded character sequence - + octet-string - byte array - * vendor id(string value with hex or int, optional, default: - "3") - there are some vendor ids already defined; check hep - proto docs for more details. - - Example 1.18. hep_set usage -... -/* modify/add a generic chunk */ -hep_set("proto_type", "H321"); - -/* add a custom chunk - int */ -hep_set("31", "132", "uint32", "3") - -/* add a custom chunk - IPv4 address */ -hep_set("32", "192.168.5.14", "inet4-addr", "3") -... - -1.4.4. hep_get(chunk_id, data_type, [chunk_data_pv], [vendor_id_pv]) - - Set a hep chunk. If not exists, it shall be added. - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Meaning of the parameters is as follows: - * chunk_id (string) - same meaning as in hep_set() - * data_type (string) - same meaning as in hep_set(); can miss - if it's a generic chunk - * chunk_data_pv (writable var, optional) - will hold the data - inside the chunk; some of the generic chunk data come in - specific format, as following: - + 0x0001 - proto_family(string) - AF_INET/AF_INET6 - + 0x0002 proto_id(string) - see hep_set() for possible - values - + 0x0003/0x0004/0x0005/0x0006 src/dst_ip(string) - ip - addresses in human readable format - + 0x0009 timestamp(string) - time and date in human - readable format - + 0x000B proto_type(string) - see hep_set() for possible - values - * vendor_id_pv (writable var, optional) - will hold the - vendor id(int value) of the chunk - - Example 1.19. hep_set usage -... -/* get a generic chunk */ -hep_get("proto_type", , $var(data), $var(vid)); - -/* get custom chunk - you must know what kind of data is there */ -hep_set("31", "uint32", $var(data), $var(vid)) -... - -1.4.5. hep_del(chunk_id) - - Removes a hep chunk. - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Meaning of the parameters is as follows: - * chunk_id (string) - same meaning as the chunk_id in - hep_set(). - - Example 1.20. hep_set usage -... -/* get a generic chunk */ -hep_del("25"); /* removes chunk with chunk id 25 */ -... - -1.4.6. hep_relay() - - Relay a message statefully to destination indicated in current - URI. (If the original URI was rewritten by UsrLoc, RR, - strip/prefix, etc., the new URI will be taken). The message has - to have been a HEP message, version 1, 2 or 3. For version 1 - and 2 you can relay only using UDP, for version 3 TCP and UDP - can be used. - - This function can be used from - REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_RO - UTE. - - Example 1.21. hep_relay usage -... -$du="sip:192.168.153.157"; -if (!hep_relay()) { - xlog("Hep proxying failed!\n"); - exit; -} - -... - -1.4.7. hep_resume_sip() - - Break hep route execution and resume into the main request - route. - - WARNING: USE THIS FUNCTION ONLY FROM A ROUTE DEFINED USING - hep_route PARAMETER. - - Example 1.22. hep_resume_sip usage -... -modparam("sipcapture", "hep_route", "my_hep_route") - -route[my_hep_route] { - ... - - /* resume execution in the main request route */ - hep_resume_sip(); -} - - -... - -1.5. Exported Async Functions - -1.5.1. sip_capture() - - Save the message inside the database. The query is being done - asnychronously only if the database supports async operations. - The query might not be executed exactly at this moment, it - depends on the max_async_queries parameter. - - Example 1.23. sip_capture usage -... -{ - async(sip_capture(), capture_resume); -} - -route[capture_resume] { - xlog("insert executed\n"); - /*continuing logic here */ -} -... - -1.6. Exported Pseudo-Variables - -1.6.1. $hep_net - - Holds layer 3 and 4 information(IP addresses and ports) about - the node from where the hep message was received. The variable - is read-only and can be used only if it's referenced by it's - name. - - Possible values for it's name are the following: - * proto_family - can be AF_INET/AF_INET6 - * proto_id - it's PROTO_HEP since you receive the message as - hep. - * src_ip - IPv4/IPv6 address, depending on the proto_family, - of the sending node. - * dst_ip - IPv4/IPv6 address, depending on the proto_family, - of the receiving node(OpenSIPS hep interface ip on which - the message was received). - * src_port - Sending node port. - * dst_port - Receiving port(OpenSIPS hep interace port on - which the message was received). - - Example 1.24. hep_net usage -... - /* received this hep packet on interface 192.168.2.5*/ - if ($hep_net(dst_ip) == "192.168.2.5") { - /* received this on 192.168.2.5:6060 interface */ - if ($hep_net(dst_port) == 6060) { - ... - /* received this on 192.168.2.5:6061 interface */ - } else if ($hep_net(dst_port) == 6061) { - ... - } - } -... - -1.6.2. HEPVERSION (string, int) - - Holds the version of the hep packet received on the interface. - - Example 1.25. HEPVERSION usage -... - if ($HEPVERSION == 3) { - /* It's a HEPv3 packet*/ - ... - } else if ($HEPVERSION == 2) { - /* It's a HEPv2 packet */ - ... - } else if ($HEPVERSION == 1) { - /* It's a HEPv1 packet */ - ... - } -... - -1.7. MI Commands - -1.7.1. sip_capture - - Name: sip_capture - - Parameters: - * capture_mode (optional) - turns on/off SIP message - capturing. Possible values are: - + on - + off - if the parameter is missing, the command will return the - status of the SIP message capturing (as string “on” or - “off” ) without changing anything. - - MI FIFO Command Format: - opensips-cli -x mi sip_capture off - -1.8. Database setup - - Before running OpenSIPS with sipcapture, you have to setup the - database tables where the module will store the data. For that, - if the table were not created by the installation script or you - choose to install everything by yourself you can use the - sipcapture-create.sql and reportcapture-create.sql or the - sipcapture-st-create.sql SQL script in the database directories - in the opensips/scripts folder as template. You can also find - the complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -1.9. Limitation - - 1. Only one capturing mode on RAW socket is supported: IPIP or - monitoring/mirroring port. Don't activate both at the same - time. 2. By default MySQL doesn't support INSERT DELAYED for - partitioning table. You can patch MySQL - (http://bugs.mysql.com/bug.php?id=50393) or use separate tables - (pseudo partitioning) 3. Mirroring port capturing works only on - Linux. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ionut Ionita (@ionutrazvanionita) 203 45 5927 6525 - 2. Liviu Chircu (@liviuchircu) 45 24 477 933 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 29 24 202 180 - 4. Razvan Crainea (@razvancrainea) 24 21 86 64 - 5. Alexandr Dubovikov (@adubovikov) 22 2 2360 0 - 6. Vlad Patrascu (@rvlad-patrascu) 9 7 73 54 - 7. Maksym Sobolyev (@sobomax) 8 6 19 16 - 8. Walter Doekes (@wdoekes) 5 3 7 5 - 9. Bence Szigeti 4 2 10 4 - 10. Zero King (@l2dy) 4 2 2 3 - - All remaining contributors: Vlad Paiu (@vladpaiu), Dusan Klinec - (@ph4r05), Ezequiel Lovelle (@lovelle), Julián Moreno Patiño, - Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 3. Bence Szigeti Jul 2023 - Aug 2023 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Aug 2012 - May 2023 - 6. Razvan Crainea (@razvancrainea) Aug 2015 - Apr 2021 - 7. Walter Doekes (@wdoekes) May 2014 - Apr 2021 - 8. Zero King (@l2dy) Mar 2020 - Mar 2020 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 10. Ionut Ionita (@ionutrazvanionita) Oct 2015 - Apr 2017 - - All remaining contributors: Julián Moreno Patiño, Dusan Klinec - (@ph4r05), Ezequiel Lovelle (@lovelle), Vlad Paiu (@vladpaiu), - Alexandr Dubovikov (@adubovikov). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Zero King (@l2dy), Vlad Patrascu - (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Ionut Ionita - (@ionutrazvanionita), Vlad Paiu (@vladpaiu), Alexandr Dubovikov - (@adubovikov). - - Documentation Copyrights: - - Copyright © 2011 QSC AG diff --git a/modules/sipcapture/README.md b/modules/sipcapture/README.md new file mode 100644 index 00000000000..308c47a2848 --- /dev/null +++ b/modules/sipcapture/README.md @@ -0,0 +1,803 @@ +--- +title: "SipCapture Module" +description: "Offer a possibility to store incoming/outgoing SIP messages in database." +--- + +## Admin Guide + + +### Overview + + +Offer a possibility to store incoming/outgoing SIP messages in database. + + +OpenSIPs can capture SIP messages in three mode + + +- IPIP encapsulation. (ETHHDR+IPHDR+IPHDR+UDPHDR). +- Monitoring/mirroring port. +- Homer encapsulation protocl mode (HEP v1/2/3). With version 2.2 +comes the new HEPv3 support using the proto _hep module. Also +header manipulation support for HEPv3 has been added. See +[hep set](#func_hep_set) for more details. If you want more +information about hep protocol check this +[link](https://github.com/sipcapture/HEP/blob/master/docs/HEP3_rev11.pdf). + + +The capturing can be turned on/off using fifo commad. + + +opensips-cli -x mi sip_capture on + + +opensips-cli -x mi sip_capture off + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *database module* - mysql, postrgress, +dbtext, unixodbc... +- *proto_hep module* - if hep capturing used + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (str) + + +Database URL. + + +*Default value is "".* + + +```opensips title="Set db_url parameter" +... +modparam("sipcapture", "db_url", "mysql://user:passwd@host/dbname") +... +``` + + +#### table_name (str) + + +Name of the table's name where to store the SIP messages. Since +version 2.2 it allows strftime-like suffix for having time formatted +table names. + + +*Default value is "sip_capture".* + + +```opensips title="Set table_name parameter" +... +modparam("sipcapture", "table_name", "homer_capture") + +/* change table name every day */ +modparam("sipcapture", "table_name", "homer_%m_%d") +/* if today is 13-04-2014 it will exetend to homer_04_13 */ +... +``` + + +#### rtcp_table_name (str) + + +Name of the table's name where to store packets captured +with report_capture function. Since version 2.2 it allows +strftime-like suffix for having time formatted +table names. + + +*Default value is "rtcp_capture".* + + +```opensips title="Set rtcp_capture parameter" +... +modparam("sipcapture", "rtcp_table_name", "homer_capture") + +/* change table name every hour */ +modparam("sipcapture", "rtcp_table_name", "homer_%m_%d_%H") +/* if today is 13-04-2014 13:05 pm it will exetend to homer_04_13_13 */ +... +``` + + +#### capture_on (integer) + + +Parameter to enable/disable capture globaly (on(1)/off(0)) + + +*Default value is "0".* + + +```opensips title="Set capture_on parameter" +... +modparam("sipcapture", "capture_on", 1) +... +``` + + +#### hep_capture_on (integer) + + +Parameter to enable/disable capture of HEP (on(1)/off(0)) + + +*Default value is "0".* + + +```opensips title="Set hep_capture_on parameter" +... +modparam("sipcapture", "hep_capture_on", 1) +... +``` + + +#### max_async_queries (integer) + + +Parameter to set the maximum number of 'INSERT' queries of captured +packets to be done in the same time, only if the DB supports async +operations. If OpenSIPS is shut down, the remaining queries shall be +executed. The query buffer is limited 65535 chars, so probably no more +than 30-40 queries can be done in the same time, depending mostly on the size +of the inserted sip message, since it's the biggest part of the query. + + +*Default value is "5".* + + +```opensips title="Set max_async_queries parameter" +... +modparam("sipcapture", "max_async_queries", 3) +... +``` + + +#### raw_ipip_capture_on (integer) + + +Parameter to enable/disable IPIP capturing (on(1)/off(0)) + + +*Default value is "0".* + + +```opensips title="Set raw_ipip_capture_on parameter" +... +modparam("sipcapture", "raw_ipip_capture_on", 1) +... +``` + + +#### raw_moni_capture_on (integer) + + +Parameter to enable/disable monitoring/mirroring port capturing (on(1)/off(0)) +Only one mode on raw socket can be enabled! Monitoring port capturing currently +supported only on Linux. + + +*Default value is "0".* + + +```opensips title="Set raw_moni_capture_on parameter" +... +modparam("sipcapture", "raw_moni_capture_on", 1) +... + +``` + + +#### raw_socket_listen (string) + + +Parameter indicate an listen IP address of RAW socket for IPIP capturing. +You can also define a port/portrange for IPIP/Mirroring mode, to capture +SIP messages in specific ports: +"10.0.0.1:5060" - the source/destination port of the SIP message must be equal 5060 +"10.0.0.1:5060-5090" - the source/destination port of the SIP message must be +equal or be between 5060 and 5090. +The port/portrange must be defined if you are planning to +use mirroring capture! In this case, the part with IP address will be +ignored, but to make parser happy, use i.e. 10.0.0.0 + + +*Default value is "".* + + +```opensips title="Set raw_socket_listen parameter" +... +modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060-5090") +... +modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060") +... +``` + + +#### raw_interface (string) + + +Name of the interface to bind on the raw socket. + + +*Default value is "".* + + +```opensips title="Set raw_socket_listen parameter" +... +modparam("sipcapture", "raw_interface", "eth0") +... +``` + + +#### raw_sock_children (integer) + + +Parameter define how much children must be created to listen the raw socket. + + +*Default value is "1".* + + +```opensips title="Set raw_socket_listen parameter" +... +modparam("sipcapture", "raw_sock_children", 6) +... +``` + + +#### promiscuous_on (integer) + + +Parameter to enable/disable promiscuous mode on the raw socket. +Linux only. + + +*Default value is "0".* + + +```opensips title="Set promiscuous_on parameter" +... +modparam("sipcapture", "promiscuous_on", 1) +... +``` + + +#### raw_moni_bpf_on (integer) + + +Activate Linux Socket Filter (LSF based on BPF) on the mirroring interface. +The structure is defined in linux/filter.h. The default LSF accept a port/portrange +from the raw_socket_listen param. Currently LSF supported only on Linux. + + +*Default value is "0".* + + +```opensips title="Set raw_moni_bpf_on parameter" +... +modparam("sipcapture", "raw_moni_bpf_on", 1) +... +``` + + +#### capture_node (str) + + +Name of the capture node. + + +*Default value is "homer01".* + + +```opensips title="Set capture_node parameter" +... +modparam("sipcapture", "capture_node", "homer03") +... +``` + + +#### hep_route (string) + + +Specifies what path your hep messages should take. Possible +values are the following: + + +- *none* - don't go through the script; +do directly sip_capture(); +- *sip(default)* - go through the main +request route; here the message is parsed and you can do anything you +want with it; +- *any other string value* - define a route name +through which your hep messages should go; the message is not parsed because +of efficiency reasons; from here you can modify the hep chunks(if hep version +3 is used) and relay the hep messages to other hep capture nodes; + + +*Default value is sip(going thorugh the main request route).* + + +```opensips title="Set hep_route parameter" +... +modparam("sipcapture", "hep_route", "my_hep_route") +... + +route[my_hep_route] { + /* do hep stuff in here */ + ... +} +... +``` + + +### Exported Functions + + +#### sip_capture([table_name], [custom_field1], [custom_field2], [custom_field3]) + + +Save the message into the database. + + +Meaning of the parameters is as follows: + + +- *table_name (string, optional)* - the name of the table to store +the packet; it can have a strftime-like formatted suffix in order to change it's name +based on time; if not set, modparam defined table will be used; +*custom_field1 (string, optional)* - custom data to store inside the +"custom_field1" column +*custom_field2 (string, optional)* - custom data to store inside the +"custom_field2" column +*custom_field3 (string, optional)* - custom data to store inside the +"custom_field3" column + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +```opensips title="sip_capture usage" +... +if (is_method("REGISTER")) + sip_capture(); + ... + /* table name will change every day */ + sip_capture("homer_%m_%d"); + sip_capture("homer_%m_%d", , $hdr(P-Asserted-Identity)); +... + +``` + + +#### report_capture(correlation_id, [table_name], [proto_type]) + + +Save the message into the database. If you want set the protocol type you have to define +the table name, even if you pass over it(report_capture($var(cor_id),,$var(proto_type))). + + +Meaning of the parameters is as follows: + + +- *correlation_id (string)* +- *table_name (string, optional)* - the name of the table to store +the packet; it can have a strftime-like formatted suffix in order to change it's name +based on time; +- *proto_type (int, optional)* - protocol type number as defined in hep protocol +specification. + + +> [!IMPORTANT] +> Since version 2.3 report_capture function +> behaviour will change depending on +> [homer5_on](../proto_hep#idp154080) +> parameter from +> [proto_hep](../proto_hep). Check +> [sql](https://github.com/OpenSIPS/opensips/tree/master/modules/sipcapture/sql) +> folder from the module to check the fields of the tables for each version. + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +```opensips title="sip_capture usage" +... + hep_get("0x0011", "utf8-string", , $var(correlation_id)); + if ($var(correlation_id) == null) { + xlog("NO CORRELATION ID! SET SOMETHING OR DROP"); + $var(correlation_id) = "absdcef"; + } + + $var(proto_type) = "3"; /* 0x03 - SDP protocol */ + + report_capture($var(correlation_id), "rtcp_log"); + /* setting the 2nd parameter, even if setting it to null, is mandatory in order to be able to set proto type */ + report_capture($var(correlation_id), , $var(proto_type)); + report_capture($var(correlation_id), "rtcp_log", $var(proto_type)); +... + +``` + + +#### hep_set(chunk_id, chunk_data, [data_type], [vendor_id]) + + +Set a hep chunk. If not exists, it shall be added. + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +Meaning of the parameters is as follows: + + +- *chunk_id(string value with hex/int or string identifier of chunk)* + - id of the chunk to be added; most of the generic +chunks are in the internal hep structure. For these you can skip the data_type +and vendor_id since they are already known. Generic chunks that don't have built +in support are the followinig: 0x000d(keep alive timer), 0x000e(authenticate key), +0x0011(internal correltion id), 0x0012(vlan ID). You can set these chunks, but +only with vendor id 0x0000, other values shall result in an error. Timestamp(0x0009) +and timestamp_us(0x000A) chunks can't be set. For chunks +that have built-in support you can also use strings instead of chunk ids as +follows: + - 0x0001 - proto_family (CAN'T BE SET; it shall be automatically updated if you change the type of the source/destination address from IPv4 to IPv6 or else) + - 0x0002 - proto_id; since it's quite hard to know the int values for the protocol one can change this value using the following string values: + - UDP + - TCP + - TLS + - SCTP + - WS + - WSS + - BIN + - HEP + - 0x0003 - src_ip + - 0x0004 - dst_ip + - 0x0005 - src_ip + - 0x0006 - dst_ip + - 0x0007 - src_port + - 0x0008 - dst_port + - 0x0009 - timestamp(CAN'T BE SET) + - 0x000A - timestamp_us(CAN'T BE SET) + - 0x000B - proto_type; for this variable there are predefined strings which can be set: + - SIP + - XMPP + - SDP + - RTP + - RTCP + - MGCP + - MEGACO + - M2UA + - M3UA + - IAX + - H322 + - H321 + - 0x000C - captagent_id + - 0x000f - payload + - 0x0010 - payload +- *chunk_data(string)* - data that the chunk shall contain; +internally it shall be converted to the requested data type +- *data_type (string, optional, default: "utf8-string")* - data type of the data in the chunk. It can have +the following values: + + - uint8 - byte unsigned integer + - uint16 - word unsigned integer + - uint32 - 4 byte unsigned integer + - inet4-addr - IPv4 address in human readable format + - inet6-addr - IPv6 address in human readable format + - utf8-string - UTF8 encoded character sequence + - octet-string - byte array +- *vendor id(string value with hex or int, optional, default: "3")* - there are +some vendor ids already defined; check +[hep proto docs](http://hep.sipcapture.org/hepfiles/HEP3_rev11.pdf) +for more details. + + +```opensips title="hep_set usage" +... +/* modify/add a generic chunk */ +hep_set("proto_type", "H321"); + +/* add a custom chunk - int */ +hep_set("31", "132", "uint32", "3") + +/* add a custom chunk - IPv4 address */ +hep_set("32", "192.168.5.14", "inet4-addr", "3") +... + +``` + + +#### hep_get(chunk_id, data_type, [chunk_data_pv], [vendor_id_pv]) + + +Set a hep chunk. If not exists, it shall be added. + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +Meaning of the parameters is as follows: + + +- *chunk_id (string)* - same meaning as in +[hep set](#func_hep_set) +- *data_type (string)* - same meaning as in +[hep set](#func_hep_set); can miss if it's a generic chunk +- *chunk_data_pv (writable var, optional)* - will hold the data inside the +chunk; some of the generic chunk data come in specific format, as following: + + - 0x0001 - proto_family(string) - AF_INET/AF_INET6 + - 0x0002 proto_id(string) - see [hep set](#func_hep_set) for possible values + - 0x0003/0x0004/0x0005/0x0006 src/dst_ip(string) - ip addresses in human readable format + - 0x0009 timestamp(string) - time and date in human readable format + - 0x000B proto_type(string) - see [hep set](#func_hep_set) for possible values +- *vendor_id_pv (writable var, optional)* - will hold the vendor id(int value) +of the chunk + + +```opensips title="hep_set usage" +... +/* get a generic chunk */ +hep_get("proto_type", , $var(data), $var(vid)); + +/* get custom chunk - you must know what kind of data is there */ +hep_set("31", "uint32", $var(data), $var(vid)) +... + +``` + + +#### hep_del(chunk_id) + + +Removes a hep chunk. + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +Meaning of the parameters is as follows: + + +- *chunk_id (string)* - same meaning as the *chunk_id* in +[hep set](#func_hep_set). + + +```opensips title="hep_set usage" +... +/* get a generic chunk */ +hep_del("25"); /* removes chunk with chunk id 25 */ +... + +``` + + +#### hep_relay() + + +Relay a message statefully to destination indicated in current URI. +(If the original URI was rewritten by UsrLoc, RR, strip/prefix, etc., +the new URI will be taken). The message has to have been a HEP message, +version 1, 2 or 3. For version 1 and 2 you can relay only using UDP, +for version 3 TCP and UDP can be used. + + +This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. + + +```opensips title="hep_relay usage" +... +$du="sip:192.168.153.157"; +if (!hep_relay()) { + xlog("Hep proxying failed!\n"); + exit; +} + +... + +``` + + +#### hep_resume_sip() + + +Break hep route execution and resume into the main request route. + + +> [!WARNING] +> USE THIS FUNCTION ONLY FROM A ROUTE DEFINED USING *hep_route* PARAMETER. + + +```opensips title="hep_resume_sip usage" +... +modparam("sipcapture", "hep_route", "my_hep_route") + +route[my_hep_route] { + ... + + /* resume execution in the main request route */ + hep_resume_sip(); +} + + +... + +``` + + +### Exported Asynchronous Functions + + +#### sip_capture() + + +Save the message inside the database. The query is being done +asnychronously only if the database supports async operations. +The query might not be executed exactly at this moment, it depends +on the *max_async_queries* parameter. + + +```opensips title="sip_capture usage" +... +{ + async(sip_capture(), capture_resume); +} + +route[capture_resume] { + xlog("insert executed\n"); + /*continuing logic here */ +} +... + +``` + + +### Exported Pseudo-Variables + + +#### $hep_net + + +Holds layer 3 and 4 information(IP addresses and ports) about +the node from where the hep message was received. The variable is +read-only and can be used only if it's referenced by it's name. + + +Possible values for it's name are the following: + + +- *proto_family* - can be AF_INET/AF_INET6 +- *proto_id* - it's PROTO_HEP since you receive +the message as hep. +- *src_ip* - IPv4/IPv6 address, depending on the +proto_family, of the sending node. +- *dst_ip* - IPv4/IPv6 address, depending on the +proto_family, of the receiving node(OpenSIPS hep interface ip on which +the message was received). +- *src_port* - Sending node port. +- *dst_port* - Receiving port(OpenSIPS hep interace +port on which the message was received). + + +```opensips title="hep_net usage" +... + /* received this hep packet on interface 192.168.2.5*/ + if ($hep_net(dst_ip) == "192.168.2.5") { + /* received this on 192.168.2.5:6060 interface */ + if ($hep_net(dst_port) == 6060) { + ... + /* received this on 192.168.2.5:6061 interface */ + } else if ($hep_net(dst_port) == 6061) { + ... + } + } +... + +``` + + +#### HEPVERSION (string, int) + + +Holds the version of the hep packet received on the interface. + + +```opensips title="HEPVERSION usage" +... + if ($HEPVERSION == 3) { + /* It's a HEPv3 packet*/ + ... + } else if ($HEPVERSION == 2) { + /* It's a HEPv2 packet */ + ... + } else if ($HEPVERSION == 1) { + /* It's a HEPv1 packet */ + ... + } +... + +``` + + +### Exported MI Functions + + +#### sip_capture + + +Name: *sip_capture* + + +Parameters: + + +- *capture_mode* (optional) - +turns on/off SIP message capturing. Possible values are: + - on + - off + +If the parameter is missing, the command will +return the status of the SIP message capturing (as string +"on" or "off" ) without changing +anything. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi sip_capture off +``` + + +### Database setup + + +Before running OpenSIPS with sipcapture, you have to setup the database +tables where the module will store the data. For that, if the +table were not created by the installation script or you choose +to install everything by yourself you can use the sipcapture-create.sql and +reportcapture-create.sql or +the sipcapture-st-create.sql SQL script in the database +directories in the opensips/scripts folder as template. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +### Limitation + + +1. Only one capturing mode on RAW socket is supported: IPIP or monitoring/mirroring port. +Don't activate both at the same time. + 2. By default MySQL doesn't support INSERT DELAYED for partitioning table. You can patch MySQL +(http://bugs.mysql.com/bug.php?id=50393) or use separate tables (pseudo partitioning) + 3. Mirroring port capturing works only on Linux. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sipcapture/doc/contributors.xml b/modules/sipcapture/doc/contributors.xml deleted file mode 100644 index 5c86547894a..00000000000 --- a/modules/sipcapture/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ionut Ionita (@ionutrazvanionita) - 203 - 45 - 5927 - 6525 - - - 2. - Liviu Chircu (@liviuchircu) - 45 - 24 - 477 - 933 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 29 - 24 - 202 - 180 - - - 4. - Razvan Crainea (@razvancrainea) - 24 - 21 - 86 - 64 - - - 5. - Alexandr Dubovikov (@adubovikov) - 22 - 2 - 2360 - 0 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 9 - 7 - 73 - 54 - - - 7. - Maksym Sobolyev (@sobomax) - 8 - 6 - 19 - 16 - - - 8. - Walter Doekes (@wdoekes) - 5 - 3 - 7 - 5 - - - 9. - Bence Szigeti - 4 - 2 - 10 - 4 - - - 10. - Zero King (@l2dy) - 4 - 2 - 2 - 3 - - - -
-All remaining contributors: Vlad Paiu (@vladpaiu), Dusan Klinec (@ph4r05), Ezequiel Lovelle (@lovelle), Julián Moreno Patiño, Peter Lemenkov (@lemenkov). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 3. - Bence Szigeti - Jul 2023 - Aug 2023 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Aug 2012 - May 2023 - - - 6. - Razvan Crainea (@razvancrainea) - Aug 2015 - Apr 2021 - - - 7. - Walter Doekes (@wdoekes) - May 2014 - Apr 2021 - - - 8. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 10. - Ionut Ionita (@ionutrazvanionita) - Oct 2015 - Apr 2017 - - - -
-All remaining contributors: Julián Moreno Patiño, Dusan Klinec (@ph4r05), Ezequiel Lovelle (@lovelle), Vlad Paiu (@vladpaiu), Alexandr Dubovikov (@adubovikov). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Zero King (@l2dy), Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Vlad Paiu (@vladpaiu), Alexandr Dubovikov (@adubovikov). -
- -
diff --git a/modules/sipcapture/doc/sipcapture.xml b/modules/sipcapture/doc/sipcapture.xml deleted file mode 100644 index bafbfb3f2b8..00000000000 --- a/modules/sipcapture/doc/sipcapture.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - - SipCapture Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011 QSC AG - diff --git a/modules/sipcapture/doc/sipcapture_admin.xml b/modules/sipcapture/doc/sipcapture_admin.xml deleted file mode 100644 index a280df190a1..00000000000 --- a/modules/sipcapture/doc/sipcapture_admin.xml +++ /dev/null @@ -1,1095 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Offer a possibility to store incoming/outgoing SIP messages in database. - - - OpenSIPs can capture SIP messages in three mode - - - - IPIP encapsulation. (ETHHDR+IPHDR+IPHDR+UDPHDR). - - - - - Monitoring/mirroring port. - - - - - Homer encapsulation protocl mode (HEP v1/2/3). With version 2.2 - comes the new HEPv3 support using the proto _hep module. Also - header manipulation support for HEPv3 has been added. See - for more details. If you want more - information about hep protocol check this - - link. - - - - - - - The capturing can be turned on/off using fifo commad. - - - opensips-cli -x mi sip_capture on - - - opensips-cli -x mi sip_capture off - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - database module - mysql, postrgress, - dbtext, unixodbc... - - - - - proto_hep module - if hep capturing used - - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Parameters -
- <varname>db_url</varname> (str) - - Database URL. - - - - Default value is "". - - - - Set <varname>db_url</varname> parameter - -... -modparam("sipcapture", "db_url", "mysql://user:passwd@host/dbname") -... - - -
-
- <varname>table_name</varname> (str) - - Name of the table's name where to store the SIP messages. Since - version 2.2 it allows strftime-like suffix for having time formatted - table names. - - - - Default value is "sip_capture". - - - - Set <varname>table_name</varname> parameter - -... -modparam("sipcapture", "table_name", "homer_capture") - -/* change table name every day */ -modparam("sipcapture", "table_name", "homer_%m_%d") -/* if today is 13-04-2014 it will exetend to homer_04_13 */ -... - - - -
-
- <varname>rtcp_table_name</varname> (str) - - Name of the table's name where to store packets captured - with report_capture function. Since version 2.2 it allows - strftime-like suffix for having time formatted - table names. - - - - - Default value is "rtcp_capture". - - - - Set <varname>rtcp_capture</varname> parameter - -... -modparam("sipcapture", "rtcp_table_name", "homer_capture") - -/* change table name every hour */ -modparam("sipcapture", "rtcp_table_name", "homer_%m_%d_%H") -/* if today is 13-04-2014 13:05 pm it will exetend to homer_04_13_13 */ -... - - -
- -
- <varname>capture_on</varname> (integer) - - Parameter to enable/disable capture globaly (on(1)/off(0)) - - - - Default value is "0". - - - - Set <varname>capture_on</varname> parameter - -... -modparam("sipcapture", "capture_on", 1) -... - - -
-
- <varname>hep_capture_on</varname> (integer) - - Parameter to enable/disable capture of HEP (on(1)/off(0)) - - - - Default value is "0". - - - - Set <varname>hep_capture_on</varname> parameter - -... -modparam("sipcapture", "hep_capture_on", 1) -... - - -
-
- <varname>max_async_queries</varname> (integer) - - Parameter to set the maximum number of 'INSERT' queries of captured - packets to be done in the same time, only if the DB supports async - operations. If OpenSIPS is shut down, the remaining queries shall be - executed. The query buffer is limited 65535 chars, so probably no more - than 30-40 queries can be done in the same time, depending mostly on the size - of the inserted sip message, since it's the biggest part of the query. - - - - Default value is "5". - - - - Set <varname>max_async_queries</varname> parameter - -... -modparam("sipcapture", "max_async_queries", 3) -... - - -
- -
- <varname>raw_ipip_capture_on</varname> (integer) - - Parameter to enable/disable IPIP capturing (on(1)/off(0)) - - - - Default value is "0". - - - - Set <varname>raw_ipip_capture_on</varname> parameter - -... -modparam("sipcapture", "raw_ipip_capture_on", 1) -... - - -
-
- <varname>raw_moni_capture_on</varname> (integer) - - Parameter to enable/disable monitoring/mirroring port capturing (on(1)/off(0)) - Only one mode on raw socket can be enabled! Monitoring port capturing currently - supported only on Linux. - - - - Default value is "0". - - - - Set <varname>raw_moni_capture_on</varname> parameter - -... -modparam("sipcapture", "raw_moni_capture_on", 1) -... - - -
-
- <varname>raw_socket_listen</varname> (string) - - Parameter indicate an listen IP address of RAW socket for IPIP capturing. - You can also define a port/portrange for IPIP/Mirroring mode, to capture - SIP messages in specific ports: - - "10.0.0.1:5060" - the source/destination port of the SIP message must be equal 5060 - - - "10.0.0.1:5060-5090" - the source/destination port of the SIP message must be - equal or be between 5060 and 5090. - - - The port/portrange must be defined if you are planning to - use mirroring capture! In this case, the part with IP address will be - ignored, but to make parser happy, use i.e. 10.0.0.0 - - - - - Default value is "". - - - - Set <varname>raw_socket_listen</varname> parameter - -... -modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060-5090") -... -modparam("sipcapture", "raw_socket_listen", "10.0.0.1:5060") -... - - -
-
- <varname>raw_interface</varname> (string) - - Name of the interface to bind on the raw socket. - - - - Default value is "". - - - - Set <varname>raw_socket_listen</varname> parameter - -... -modparam("sipcapture", "raw_interface", "eth0") -... - - -
-
- <varname>raw_sock_children</varname> (integer) - - Parameter define how much children must be created to listen the raw socket. - - - - Default value is "1". - - - - Set <varname>raw_socket_listen</varname> parameter - -... -modparam("sipcapture", "raw_sock_children", 6) -... - - -
-
- <varname>promiscuous_on</varname> (integer) - - Parameter to enable/disable promiscuous mode on the raw socket. - Linux only. - - - - Default value is "0". - - - - Set <varname>promiscuous_on</varname> parameter - -... -modparam("sipcapture", "promiscuous_on", 1) -... - - -
-
- <varname>raw_moni_bpf_on</varname> (integer) - - Activate Linux Socket Filter (LSF based on BPF) on the mirroring interface. - The structure is defined in linux/filter.h. The default LSF accept a port/portrange - from the raw_socket_listen param. Currently LSF supported only on Linux. - - - - Default value is "0". - - - - Set <varname>raw_moni_bpf_on</varname> parameter - -... -modparam("sipcapture", "raw_moni_bpf_on", 1) -... - - -
-
- <varname>capture_node</varname> (str) - - Name of the capture node. - - - - Default value is "homer01". - - - - Set <varname>capture_node</varname> parameter - -... -modparam("sipcapture", "capture_node", "homer03") -... - - -
-
- <varname>hep_route</varname> (string) - - Specifies what path your hep messages should take. Possible - values are the following: - - - none - don't go through the script; - do directly sip_capture(); - - sip(default) - go through the main - request route; here the message is parsed and you can do anything you - want with it; - - - any other string value - define a route name - through which your hep messages should go; the message is not parsed because - of efficiency reasons; from here you can modify the hep chunks(if hep version - 3 is used) and relay the hep messages to other hep capture nodes; - - - - - Default value is sip(going thorugh the main request route). - - - - Set <varname>hep_route</varname> parameter - -... -modparam("sipcapture", "hep_route", "my_hep_route") -... - -route[my_hep_route] { - /* do hep stuff in here */ - ... -} -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">sip_capture([table_name], [custom_field1], [custom_field2], [custom_field3])</function> - - - Save the message into the database. - - Meaning of the parameters is as follows: - - - table_name (string, optional) - the name of the table to store - the packet; it can have a strftime-like formatted suffix in order to change it's name - based on time; if not set, modparam defined table will be used; - - custom_field1 (string, optional) - custom data to store inside the - "custom_field1" column - - custom_field2 (string, optional) - custom data to store inside the - "custom_field2" column - - custom_field3 (string, optional) - custom data to store inside the - "custom_field3" column - - - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - - <function>sip_capture</function> usage - -... -if (is_method("REGISTER")) - sip_capture(); - ... - /* table name will change every day */ - sip_capture("homer_%m_%d"); - sip_capture("homer_%m_%d", , $hdr(P-Asserted-Identity)); -... - - - -
- -
- - <function moreinfo="none">report_capture(correlation_id, [table_name], [proto_type])</function> - - - Save the message into the database. If you want set the protocol type you have to define - the table name, even if you pass over it(report_capture($var(cor_id),,$var(proto_type))). - - Meaning of the parameters is as follows: - - - correlation_id (string) - - - - table_name (string, optional) - the name of the table to store - the packet; it can have a strftime-like formatted suffix in order to change it's name - based on time; - - - - proto_type (int, optional) - protocol type number as defined in hep protocol - specification. - - - - VERY IMPORTANT: Since version 2.3 report_capture function - behaviour will change depending on - homer5_on - parameter from - proto_hep. Check - sql - folder from the module to check the fields of the tables for each version. - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - - <function>sip_capture</function> usage - -... - hep_get("0x0011", "utf8-string", , $var(correlation_id)); - if ($var(correlation_id) == null) { - xlog("NO CORRELATION ID! SET SOMETHING OR DROP"); - $var(correlation_id) = "absdcef"; - } - - $var(proto_type) = "3"; /* 0x03 - SDP protocol */ - - report_capture($var(correlation_id), "rtcp_log"); - /* setting the 2nd parameter, even if setting it to null, is mandatory in order to be able to set proto type */ - report_capture($var(correlation_id), , $var(proto_type)); - report_capture($var(correlation_id), "rtcp_log", $var(proto_type)); -... - - - -
- - - -
- - <function moreinfo="none">hep_set(chunk_id, chunk_data, [data_type], [vendor_id])</function> - - - Set a hep chunk. If not exists, it shall be added. - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - Meaning of the parameters is as follows: - - - - chunk_id(string value with hex/int or string identifier of chunk) - - id of the chunk to be added; most of the generic - chunks are in the internal hep structure. For these you can skip the data_type - and vendor_id since they are already known. Generic chunks that don't have built - in support are the followinig: 0x000d(keep alive timer), 0x000e(authenticate key), - 0x0011(internal correltion id), 0x0012(vlan ID). You can set these chunks, but - only with vendor id 0x0000, other values shall result in an error. Timestamp(0x0009) - and timestamp_us(0x000A) chunks can't be set. For chunks - that have built-in support you can also use strings instead of chunk ids as - follows: - - - 0x0001 - proto_family(CAN'T BE SET; it shall be automatically updated - if you change the type of the source/destination address from IPv4 to IPv6 - or else) - - - - 0x0002 - proto_id; since it's quite hard to know the int values for the protocol - one can change this value using the following string values: - - - UDP - - - TCP - - - TLS - - - SCTP - - - WS - - - WSS - - - BIN - - - HEP - - - - - 0x0003 - src_ip - - - 0x0004 - dst_ip - - - 0x0005 - src_ip - - - 0x0006 - dst_ip - - - 0x0007 - src_port - - - 0x0008 - dst_port - - - 0x0009 - timestamp(CAN'T BE SET) - - - 0x000A - timestamp_us(CAN'T BE SET) - - - 0x000B - proto_type; for this variable there are predefined - strings which can be set: - - - SIP - - - XMPP - - - SDP - - - RTP - - - RTCP - - - MGCP - - - MEGACO - - - M2UA - - - M3UA - - - IAX - - - H322 - - - H321 - - - - - 0x000C - captagent_id - - - 0x000f - payload - - - 0x0010 - payload - - - - - - chunk_data(string) - data that the chunk shall contain; - internally it shall be converted to the requested data type - - - - data_type (string, optional, default: "utf8-string") - data type of the data in the chunk. It can have - the following values: - - - - uint8 - byte unsigned integer - - - uint16 - word unsigned integer - - - uint32 - 4 byte unsigned integer - - - inet4-addr - IPv4 address in human readable format - - - inet6-addr - IPv6 address in human readable format - - - utf8-string - UTF8 encoded character sequence - - - octet-string - byte array - - - - - vendor id(string value with hex or int, optional, default: "3") - there are - some vendor ids already defined; check - - hep proto docs - for more details. - - - - - <function>hep_set</function> usage - -... -/* modify/add a generic chunk */ -hep_set("proto_type", "H321"); - -/* add a custom chunk - int */ -hep_set("31", "132", "uint32", "3") - -/* add a custom chunk - IPv4 address */ -hep_set("32", "192.168.5.14", "inet4-addr", "3") -... - - - -
- -
- - <function moreinfo="none">hep_get(chunk_id, data_type, [chunk_data_pv], [vendor_id_pv])</function> - - - Set a hep chunk. If not exists, it shall be added. - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - Meaning of the parameters is as follows: - - - chunk_id (string) - same meaning as in - - - - data_type (string) - same meaning as in - ; can miss if it's a generic chunk - - - chunk_data_pv (writable var, optional) - will hold the data inside the - chunk; some of the generic chunk data come in specific format, as following: - - - 0x0001 - proto_family(string) - AF_INET/AF_INET6 - - - 0x0002 proto_id(string) - see for possible values - - - 0x0003/0x0004/0x0005/0x0006 src/dst_ip(string) - ip addresses in human readable format - - - 0x0009 timestamp(string) - time and date in human readable format - - - 0x000B proto_type(string) - see for possible values - - - - - vendor_id_pv (writable var, optional) - will hold the vendor id(int value) - of the chunk - - - - -<function>hep_set</function> usage - -... -/* get a generic chunk */ -hep_get("proto_type", , $var(data), $var(vid)); - -/* get custom chunk - you must know what kind of data is there */ -hep_set("31", "uint32", $var(data), $var(vid)) -... - - - -
- -
- - <function moreinfo="none">hep_del(chunk_id)</function> - - - Removes a hep chunk. - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - Meaning of the parameters is as follows: - - - chunk_id (string) - same meaning as the chunk_id in - . - - - - -<function>hep_set</function> usage - -... -/* get a generic chunk */ -hep_del("25"); /* removes chunk with chunk id 25 */ -... - - - -
- - -
- - <function moreinfo="none">hep_relay()</function> - - - Relay a message statefully to destination indicated in current URI. - (If the original URI was rewritten by UsrLoc, RR, strip/prefix, etc., - the new URI will be taken). The message has to have been a HEP message, - version 1, 2 or 3. For version 1 and 2 you can relay only using UDP, - for version 3 TCP and UDP can be used. - - - This function can be used from REQUEST_ROUTE,FAILURE_ROUTE,ONREPLY_ROUTE,BRANCH_ROUTE,LOCAL_ROUTE. - - -<function>hep_relay</function> usage - -... -$du="sip:192.168.153.157"; -if (!hep_relay()) { - xlog("Hep proxying failed!\n"); - exit; -} - -... - - - -
- -
- - <function moreinfo="none">hep_resume_sip()</function> - - - Break hep route execution and resume into the main request route. - - - WARNING: USE THIS FUNCTION ONLY FROM A ROUTE DEFINED USING hep_route PARAMETER. - - -<function>hep_resume_sip</function> usage - -... -modparam("sipcapture", "hep_route", "my_hep_route") - -route[my_hep_route] { - ... - - /* resume execution in the main request route */ - hep_resume_sip(); -} - - -... - - - -
- - - - - -
- -
- Exported Async Functions - -
- - <function moreinfo="none">sip_capture()</function> - - - Save the message inside the database. The query is being done - asnychronously only if the database supports async operations. - The query might not be executed exactly at this moment, it depends - on the max_async_queries parameter. - - - <function>sip_capture</function> usage - -... -{ - async(sip_capture(), capture_resume); -} - -route[capture_resume] { - xlog("insert executed\n"); - /*continuing logic here */ -} -... - - -
- -
- - -
- Exported Pseudo-Variables - -
- - <function moreinfo="none">$hep_net</function> - - Holds layer 3 and 4 information(IP addresses and ports) about - the node from where the hep message was received. The variable is - read-only and can be used only if it's referenced by it's name. - Possible values for it's name are the following: - - - proto_family - can be AF_INET/AF_INET6 - - - proto_id - it's PROTO_HEP since you receive - the message as hep. - - - - src_ip - IPv4/IPv6 address, depending on the - proto_family, of the sending node. - - - dst_ip - IPv4/IPv6 address, depending on the - proto_family, of the receiving node(&osips; hep interface ip on which - the message was received). - - - src_port - Sending node port. - - - dst_port - Receiving port(&osips; hep interace - port on which the message was received). - - - - <function>hep_net</function> usage - -... - /* received this hep packet on interface 192.168.2.5*/ - if ($hep_net(dst_ip) == "192.168.2.5") { - /* received this on 192.168.2.5:6060 interface */ - if ($hep_net(dst_port) == 6060) { - ... - /* received this on 192.168.2.5:6061 interface */ - } else if ($hep_net(dst_port) == 6061) { - ... - } - } -... - - -
- -
- - <function moreinfo="none">HEPVERSION (string, int)</function> - - - Holds the version of the hep packet received on the interface. - - - <function>HEPVERSION</function> usage - -... - if ($HEPVERSION == 3) { - /* It's a HEPv3 packet*/ - ... - } else if ($HEPVERSION == 2) { - /* It's a HEPv2 packet */ - ... - } else if ($HEPVERSION == 1) { - /* It's a HEPv1 packet */ - ... - } -... - - -
- - - - - - - - -
- - -
- MI Commands -
- - <function moreinfo="none">sip_capture</function> - - - - - - Name: sip_capture - - Parameters: - - capture_mode (optional) - - turns on/off SIP message capturing. Possible values are: - - on - off - - if the parameter is missing, the command will - return the status of the SIP message capturing (as string - on or off ) without changing - anything. - - - - - MI FIFO Command Format: - - - opensips-cli -x mi sip_capture off - -
-
- -
- Database setup - - Before running &osips; with sipcapture, you have to setup the database - tables where the module will store the data. For that, if the - table were not created by the installation script or you choose - to install everything by yourself you can use the sipcapture-create.sql and - reportcapture-create.sql or - the sipcapture-st-create.sql SQL script in the database - directories in the opensips/scripts folder as template. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
-
- Limitation - - - 1. Only one capturing mode on RAW socket is supported: IPIP or monitoring/mirroring port. - Don't activate both at the same time. - 2. By default MySQL doesn't support INSERT DELAYED for partitioning table. You can patch MySQL - (http://bugs.mysql.com/bug.php?id=50393) or use separate tables (pseudo partitioning) - 3. Mirroring port capturing works only on Linux. - - -
-
- diff --git a/modules/sipmsgops/README b/modules/sipmsgops/README deleted file mode 100644 index 4201c72b296..00000000000 --- a/modules/sipmsgops/README +++ /dev/null @@ -1,1238 +0,0 @@ -sipmsgops Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Functions - - 1.3.1. append_to_reply(txt) - 1.3.2. append_body_to_reply(txt) - 1.3.3. append_hf(txt[, hdr_anchor]) - 1.3.4. insert_hf(txt) - 1.3.5. insert_hf(txt, hdr) - 1.3.6. append_urihf(prefix, suffix) - 1.3.7. is_present_hf(hf_name) - 1.3.8. append_time() - 1.3.9. is_method(name) - 1.3.10. remove_hf(hname) - 1.3.11. remove_hf_re(hname_expr) - 1.3.12. remove_hf_glob(hname_pattern) - 1.3.13. has_totag() - 1.3.14. ruri_has_param(param[,value]) - 1.3.15. ruri_add_param(param) - 1.3.16. ruri_del_param(param) - 1.3.17. ruri_tel2sip() - 1.3.18. is_uri_user_e164(uri) - 1.3.19. has_body_part([mime]) - 1.3.20. is_audio_on_hold() - 1.3.21. is_privacy(privacy_type) - 1.3.22. remove_body_part([mime[, revert]]) - 1.3.23. add_body_part(body, mime[, headers]) - 1.3.24. get_updated_body_part( [mime], variable) - 1.3.25. sipmsg_validate([flags[, result_pvar]]) - 1.3.26. codec_exists (name[, clock]) - 1.3.27. codec_delete(name[, clock]) - 1.3.28. codec_move_up(name[, clock]) - 1.3.29. codec_move_down(name[, clock]) - 1.3.30. codec_exists_re ( regexp ) - 1.3.31. codec_delete_re ( regexp ) - 1.3.32. codec_delete_except_re ( regexp ) - 1.3.33. codec_move_up_re ( regexp ) - 1.3.34. codec_move_down_re ( regexp ) - 1.3.35. change_reply_status(code, reason) - 1.3.36. stream_exists(regexp[,regexp2]) - 1.3.37. stream_delete(regexp[,regexp2]) - 1.3.38. list_hdr_has_option(hdr_name, option) - 1.3.39. list_hdr_add_option(hdr_name, option) - 1.3.40. list_hdr_remove_option(hdr_name, option) - 1.3.41. get_glob_headers_values(hdr_name_glob, - hdr_names_avp,hdr_vals_avp) - - 1.3.42. sip_to_json(out_var) - - 1.4. Known Limitations - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. append_to_reply usage - 1.2. append_to_reply usage - 1.3. append_hf usage - 1.4. insert_hf usage - 1.5. insert_hf usage - 1.6. append_urihf usage - 1.7. is_present_hf usage - 1.8. append_time usage - 1.9. is_method usage - 1.10. remove_hf usage - 1.11. remove_hf_re usage - 1.12. remove_hf_glob usage - 1.13. has_totag usage - 1.14. ruri_has_param usage - 1.15. ruri_add_param usage - 1.16. ruri_del_param usage - 1.17. ruri_tel2sip usage - 1.18. is_uri_user_e164 usage - 1.19. has_body_part usage - 1.20. is_audio_on_hold usage - 1.21. is_privacy usage - 1.22. remove_body_part() usage - 1.23. add_body_part usage - 1.24. get_updated_body_part usage - 1.25. sipmsg_validate usage - 1.26. codec_exists usage - 1.27. codec_delete usage - 1.28. codec_move_up usage - 1.29. codec_move_down usage - 1.30. codec_move_down usage - 1.31. codec_exists_re usage - 1.32. codec_delete_re usage - 1.33. codec_delete_except_re usage - 1.34. codec_move_up_re usage - 1.35. codec_move_down_re usage - 1.36. codec_move_down usage - 1.37. change_reply_status usage - 1.38. stream_exists usage - 1.39. stream_delete usage - 1.40. list_hdr_has_option usage - 1.41. list_hdr_add_option usage - 1.42. list_hdr_remove_option usage - 1.43. get_glob_headers_values usage - 1.44. sip_to_json usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements SIP based operations over the messages - processed by OpenSIPS. SIP is a text based protocol and the - module provides a large set of very useful functions to - manipulate the message at SIP level, e.g., inserting new - headers or deleting them, check for method type, etc. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Functions - -1.3.1. append_to_reply(txt) - - Append 'txt' as header to all replies that will be generated by - OpenSIPS for this request. - - Meaning of the parameters is as follows: - * txt (string) - SIP header field, value and CRLF marker. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ERROR_ROUTE. - - Example 1.1. append_to_reply usage -... -append_to_reply("Foo: bar\r\n"); -append_to_reply("Foo: $rm at $Ts\r\n"); -... - -1.3.2. append_body_to_reply(txt) - - Append 'txt' as body to all replies that will be generated by - OpenSIPS for this request. - - Multiple calls will override the already set body. - - NOTE: the function does not add any Content-Type hdr to match - the body, so you should use "append_to_reply()" to do that. - - Meaning of the parameters is as follows: - * txt (string) - body of the SIP reply - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and ERROR_ROUTE. - - Example 1.2. append_to_reply usage -... -append_body_to_reply( $var(sdp_body) ); -... - -1.3.3. append_hf(txt[, hdr_anchor]) - - Appends 'txt' as header after the last header field. If - 'hdr_anchor' is given, 'txt' will be appended after the first - occurrence of 'hdr_anchor' instead. - - Meaning of the parameters is as follows: - * txt (string) - Header field to be appended. - * hdr_anchor (string, optional) - Header name after which the - 'txt' is appended. - - Note: Headers which are added in main route cannot be removed - in further routes (e.g. failure routes). So, the idea is not to - add there any headers that you might want to remove later. To - add headers temporarily, use the branch route because the - changes you do there are per-branch. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.3. append_hf usage -... -append_hf("P-hint: VOICEMAIL\r\n"); -append_hf("From-username: $fU\r\n"); -append_hf("From-username: $fU\r\n", "Call-ID"); -... - -1.3.4. insert_hf(txt) - - Inserts 'txt' as header before the first header field. - - Meaning of the parameters is as follows: - * txt (string) - Header field to be inserted. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.4. insert_hf usage -... -insert_hf("P-hint: VOICEMAIL\r\n"); -insert_hf("To-username: $tU\r\n"); -... - -1.3.5. insert_hf(txt, hdr) - - Inserts 'txt' as header before first 'hdr' header field. - - Meaning of the parameters is as follows: - * txt (string) - Header field to be inserted. - * hdr (string, optional) - Header name before which the 'txt' - is inserted. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.5. insert_hf usage -... -insert_hf("P-hint: VOICEMAIL\r\n", "Call-ID"); -insert_hf("To-username: $tU\r\n", "Call-ID"); -... - -1.3.6. append_urihf(prefix, suffix) - - Append header field name with original Request-URI in middle. - - Meaning of the parameters is as follows: - * prefix - string (usually at least header field name). - * suffix - string (usually at least line terminator). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE and - BRANCH_ROUTE. - - Example 1.6. append_urihf usage -... -append_urihf("CC-Diversion: ", "\r\n"); -... - -1.3.7. is_present_hf(hf_name) - - Return true if a header field is present in message. - -Note - - The function is also able to distinguish the compact names. For - exmaple “From” will match with “f” - - Meaning of the parameters is as follows: - * hf_name (string) - Header field name (long or compact - form). - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.7. is_present_hf usage -... -if (is_present_hf("From")) log(1, "From HF Present"); -... - -1.3.8. append_time() - - Adds a time header to the reply of the request. You must use it - before functions that are likely to send a reply, e.g., save() - from 'registrar' module. Header format is: “Date: %a, %d %b %Y - %H:%M:%S GMT”, with the legend: - * %a abbreviated week of day name (locale) - * %d day of month as decimal number - * %b abbreviated month name (locale) - * %Y year with century - * %H hour - * %M minutes - * %S seconds - - Return true if a header was successfully appended. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.8. append_time usage -... -append_time(); -... - -1.3.9. is_method(name) - - Check if the method of the message matches the name. If name is - a known method (invite, cancel, ack, bye, options, info, - update, register, message, subscribe, notify, refer, prack), - the function performs method ID testing (integer comparison) - instead of ignore case string comparison. - - The 'name' can be a list of methods in the form of - 'method1|method2|...'. In this case, the function returns true - if the SIP message's method is one from the list. IMPORTANT - NOTE: in the list must be only methods defined in OpenSIPS with - ID (invite, cancel, ack, bye, options, info, update, register, - message, subscribe, notify, refer, prack, publish; for more - see: https://www.iana.org/assignments/sip-parameters). - - If used for replies, the function tests the value of method - field from CSeq header. - - Meaning of the parameters is as follows: - * name (string) - SIP method name - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.9. is_method usage -... -if(is_method("INVITE")) -{ - # process INVITEs here -} -if(is_method("OPTION|UPDATE")) -{ - # process OPTIONs and UPDATEs here -} -... - -1.3.10. remove_hf(hname) - - Remove from message all headers with name “hname” - - Returns true if at least one header is found and removed. - - Meaning of the parameters is as follows: - * hname (string) - header name to be removed. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.10. remove_hf usage -... -if(remove_hf("User-Agent")) -{ - # User Agent header removed -} -... - -1.3.11. remove_hf_re(hname_expr) - - Remove from message all headers matching the “hname_expr” POSIX - regular expression. - - Returns true if at least one header is found and removed. - - Meaning of the parameters is as follows: - * hname_expr (string) - regular expression. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.11. remove_hf_re usage -... -remove_hf_re("^X-g.+[0-9]"); -... - -1.3.12. remove_hf_glob(hname_pattern) - - Remove from message all headers matching the “hname_pattern” - glob pattern. - - Returns true if at least one header is found and removed. - - Meaning of the parameters is as follows: - * hname_pattern (string) - glob pattern - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.12. remove_hf_glob usage -... -# removes X-Billing-Account, X-Billing-Price, X-Billing-rateplan, etc -remove_hf_glob("X-Billing*"); -... - -1.3.13. has_totag() - - Check if To header field uri contains tag parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.13. has_totag usage -... -if (has_totag()) { - ... -}; -... - -1.3.14. ruri_has_param(param[,value]) - - Find if Request URI has a given parameter. If no value is - given, the function will look for the paramter with no value, - oherwise it will search for the parameter with the matching - value. - - Meaning of the parameters is as follows: - * param (string) - parameter name to look for. - * value (string, optional) - parameter value to match. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.14. ruri_has_param usage -... -if (ruri_has_param("user","phone")) { - ... -}; -... - -1.3.15. ruri_add_param(param) - - Add to RURI an URI parameter formated as "name=value". - - Meaning of the parameters is as follows: - * param (string) - parameter to be appended in “name=value” - format. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.15. ruri_add_param usage -... -ruri_add_param("nat=yes"); -... - -1.3.16. ruri_del_param(param) - - Delete a parameter, its value and any leading ";" from the - Request-URI of the current SIP message. - - Meaning of the parameters is as follows: - * param (string) - the parameter to be removed - - Returns 1 on a successful deletion or -1 otherwise. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.16. ruri_del_param usage -... -ruri_del_param("user"); -... - -1.3.17. ruri_tel2sip() - - Converts RURI, if it is tel URI, to SIP URI. Returns true, only - if conversion succeeded or if no conversion was needed (like - RURI was not tel URI. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.17. ruri_tel2sip usage -... -ruri_tel2sip(); -... - -1.3.18. is_uri_user_e164(uri) - - Checks if the username part of the given URI is an E164 number. - - Meaning of the parameters is as follows: - * uri (string) - a SIP URI - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE and - LOCAL_ROUTE. - - Example 1.18. is_uri_user_e164 usage -... -if (is_uri_user_e164($fu)) { # Check From header URI user part - ... -} -if (is_uri_user_e164($avp(uri)) { - # Check user part of URI stored in avp uri - ... -}; -... - -1.3.19. has_body_part([mime]) - - The function returns true if the SIP message has any body part - with the given MIME. If there is no MIME given, it will return - true if at least one body part is found (with any MIME). - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.19. has_body_part usage -... -if(has_body_part("application/sdp")) -{ - # do interesting stuff here -} -... - -1.3.20. is_audio_on_hold() - - The function returns true if the SIP message has an SDP body - attached and at least one audio stream in on hold. The return - code of the function indicates the detected hold type: - * 1 - RFC2543 hold type: null connection IP detected - * 2 - RFC3264 hold type: inactive or sendonly attributes - detected - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.20. is_audio_on_hold usage -... -if(is_audio_on_hold()) -{ - switch ($rc) { - case 1: - # RFC2543 hold type - # do interesting stuff here - break; - case 2: - # RFC3264 hold type - # do interesting stuff here - break; -} -... - -1.3.21. is_privacy(privacy_type) - - The function returns true if the SIP message has a Privacy - header field that includes the given privacy_type among its - privacy values. See - https://www.iana.org/assignments/sip-parameters/sip-parameters. - xhtml#sip-parameters-8 for possible privacy type values. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.21. is_privacy usage -... -if(is_privacy("id")) -{ - # do interesting stuff here -} -... - -1.3.22. remove_body_part([mime[, revert]]) - - Removes from the message body all the body parts with the given - mime. The necessary corrections over the Content-Type and - Content-Length headers are automatically done. - - If a MIME type is given, it will delete only the body parts - with that mime. If no MIME given, all the parts (entire body) - will be removed. - - Meaning of the parameters is as follows: - * mime (string, optional) - MIME type to be checked against - the body parts; If not given, all parts are to remvoed; - * revert (string, optional) - useful only if a MIME was - specified. If "revert" string is given here, the function - will delete all body parts but the ones with the given - MIME. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.22. remove_body_part() usage -... -# delete entire body message (all parts) -remove_body_part(); -# delete all body parts with mime "application/isup" -remove_body_part("application/isup"); -# delete all body parts but keep the the ones with "application/sdp" -remove_body_part("application/sdp","revert") -... - -1.3.23. add_body_part(body, mime[, headers]) - - This function can be used to add a new body part to the message - body. If another part already exist, body of the message will - be converted to a multi-part body automatically. - - Meaning of the parameters is as follows: - * body (string) - the content of the body part to be added - * mime (string) - the mime string for the body part to be - added - * headers (string, optional) - optional list of SIP headers - (fully defined, including the header separator) to be - pushed into this part next to the Content-Type header. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.23. add_body_part usage -... -add_body_part("Hello World!", "text/plain"); -... - -1.3.24. get_updated_body_part( [mime], variable) - - This function returns into a variable the regenerated body - part, meaning the body part updated with all the changes done - so far by OpenSIPS. This is helpful if you want to do a - sequance of operations over the body parts and some operations - require to have all the previous changes applied (like first - doing some codec related changes and later to rtpengine - insertion). - - NOTE: the actual SIP message will not be affected by this - operation! - - Meaning of the parameters is as follows: - * mime (string) - the mime string for the body to be - regenerated and returned. If missing, the whole body (with - all its parts) will be regenerated. - * variable - a variable to be used to return the regenerated - body part (as text). - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.24. get_updated_body_part usage -... - codec_delete_re("PCMA|PCMU"); - - get_updated_body_part( "application/sdp", $var(new_sdp)); - - xlog("------updated SDP is ----\n$var(new_sdp)\n-----------\n"); - exit; -... - -1.3.25. sipmsg_validate([flags[, result_pvar]]) - - The function returns true if the SIP message is properly built - according to SIP RFC3261. It verifies if the mandatory headers - for each request/reply and can also check the format of the - headers body. - - The flags parameter received is optional and can be composed - with the following values: - * 's' - checks the integrity of the SDP body, if it exists - * 'h' - checks the format and integrity of each header body. - * 'm' - don't check the Max-Forwards header. - * 'r' - checks the R-URI and whether the domain contains - valid characters. - * 'f' - checks the URI of the 'From' field and whether the - domain contains valid characters. - * 't' - checks the URI of the 'To' field and whether the - domain contains valid characters. - * 'c' - checks the URI of the 'Contact' field. - - The result_pvar parameter sets resulting pvar with text error - reason in case of negative result ( easy for logging or - propagating the rejection reason back to the bogus UA ) - - This function can return the following codes: - * 1 - the message is RFC3261 compliant and has been - successfully validated. - * -1 - No SIP message - * -2 - Header Parsing error - * -3 - No Call-ID header - * -4 - No Content-Length header for transports that require - it ( eg. TCP ) - * -5 - Invalid Content-Length, other from the size of the - actual body - * -6 - SDP body parsing error. - * -7 - No Cseq header. - * -8 - No From header. - * -9 - No To header. - * -10 - No Via header. - * -11 - Request URI parse error. - * -12 - Bad hostname in R-URI. - * -13 - No Max-Forwards header. - * -14 - No Contact header. - * -15 - Path user for non-Register request. - * -16 - No allow header in 405 reply. - * -17 - No Min-Expire header in 423 reply. - * -18 - No Proxy-Authorize header in 407 reply. - * -19 - No Unsupported header in 420 reply. - * -20 - No WWW-Authorize header in 401 reply. - * -21 - No Content-Type header - * -22 - To header parse error - * -23 - Bad hostname in To header - * -24 - From header parse error - * -25 - Bad hostname in From header - * -26 - Contact header parse error - * -27 - Bad URI username - * -28 - Bad From URI username - * -29 - Bad To URI username - * -255 - undefined errors. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE. - - Example 1.25. sipmsg_validate usage -... -if(!sipmsg_validate()) -{ - send_reply(400, "Bad Request"); - exit; -} -... - -... -# checks also the SDP and headers body -if(!sipmsg_validate("sh", $var(err_reason))) -{ - send_reply(400, "Bad Request/Body"); - exit; -} -... - -1.3.26. codec_exists (name[, clock]) - - This function can be used to verify if a codec exists inside an - sdp payload. It will search for the codec inside all streams - from all sdp sessions. If it is found anywhere it will return - TRUE otherwise it will return FALSE. - - Parameters: - * name (string) - Parameter is CASE INSENSITIVE. - * clock (string, optional) - if not supplied any clockrate - will match. Parameter is CASE INSENSITIVE. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.26. codec_exists usage -... -codec_exists("speex"); -or -codec_exists("GSM", "8000"); -... - -1.3.27. codec_delete(name[, clock]) - - This function can be used to delete a codec from inside an sdp - payload. It will search for the codec inside all streams from - all sdp sessions. If it is found anywhere it will be deleted - from the mapping ("a=...") and from the list of indexes - ("m=..."). Returns TRUE if any deletion occurred otherwise it - will return FALSE. - * name (string) - Parameter is CASE INSENSITIVE. - * clock (string, optional) - if not supplied any clockrate - will match and all will be deleted. Parameter is CASE - INSENSITIVE. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.27. codec_delete usage -... -codec_delete("speex"); -or -codec_delete("GSM", "8000"); -... - -1.3.28. codec_move_up(name[, clock]) - - This function can be used to move a codec up in the list of - indexes ("m=..."). It will search for the codec inside all - streams from all sdp sessions. If it is found anywhere it will - be moved to the top of the index list. Returns TRUE if any - moves occurred otherwise it will return FALSE. - * name (string) - parameter is CASE INSENSITIVE. - * clock (string, optional) - if not supplied any clockrate - will match and all codecs will be moved to the front while - preserving their original ordering. Parameter is CASE - INSENSITIVE. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.28. codec_move_up usage -... -codec_move_up("speex"); -or -codec_move_up("GSM", "8000"); -... - -1.3.29. codec_move_down(name[, clock]) - - This function can be used to move a codec down in the list of - indexes ("m=..."). It will search for the codec inside all - streams from all sdp sessions. If it is found anywhere it will - be moved to the back of the index list. Returns TRUE if any - moves occurred otherwise it will return FALSE. The second - parameter is optional, if it is not supplied any clockrate will - match and all codecs will be moved to the back while preserving - their original ordering. Parameters are CASE INSENSITIVE. - * name (string) - parameter is CASE INSENSITIVE. - * clock (string, optional) - if not supplied any clockrate - will match and all codecs will be moved to the back while - preserving their original ordering. Parameter is CASE - INSENSITIVE. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.29. codec_move_down usage -... -codec_move_down("speex"); -or -codec_move_down("GSM", "8000"); -... - - Example 1.30. codec_move_down usage -... -/* - This example will move speex with 8000 codec to the back of the list, - then it will erase GSM with 8000 clock, and then it will bring all - speex codecs to the front of the list. Speex/8000 will be behind any - other speex. -*/ -codec_move_down("speex", "8000"); -codec_delete("GSM", "8000"); -codec_move_up("speex"); -... - -1.3.30. codec_exists_re ( regexp ) - - This function has the same effect as codec_exists ( without the - clock parameter ) the only difference is that it takes a POSIX - regular expression as a parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.31. codec_exists_re usage -... -codec_exists_re("sp[a-z]*"); -... - -1.3.31. codec_delete_re ( regexp ) - - This function has the same effect as codec_delete ( without the - clock parameter ) the only difference is that it takes a POSIX - regular expression as a parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.32. codec_delete_re usage -... -codec_delete_re("PCMA|PCMU"); -... - - -1.3.32. codec_delete_except_re ( regexp ) - - This function deletes all the codecs except those specified by - the regular expression. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.33. codec_delete_except_re usage -... -codec_delete_except_re("PCMA|PCMU");#will delete all codecs except PCMA -and PCMU -... - - -1.3.33. codec_move_up_re ( regexp ) - - This function has the same effect as codec_move_up ( without - the clock parameter ) the only difference is that it takes a - POSIX regular expression as a parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.34. codec_move_up_re usage -... -codec_move_up_re("sp[a-z]*"); -... - -1.3.34. codec_move_down_re ( regexp ) - - This function has the same effect as codec_move_down ( without - the clock parameter ) the only difference is that it takes a - POSIX regular expression as a parameter. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.35. codec_move_down_re usage -... -codec_move_down_re("sp[a-z]*"); -... - - Example 1.36. codec_move_down usage -... -/* - This example will move speex with 8000 codec to the back of the list, - then it will erase GSM with 8000 clock, and then it will bring all - speex codecs to the front of the list. Speex/8000 will be behind any - other speex. -*/ -codec_move_down("speex","8000"); -codec_delete("GSM","8000"); -codec_move_up("speex"); -... - -1.3.35. change_reply_status(code, reason) - - Intercept a SIP reply (in any onreply_route) and change its - status code and reason phrase prior to propogating it. - - Meaning of the parameters is as follows: - * code (int) - Status code. - * reason (string) - Reason phrase. - - This function can be used from ONREPLY_ROUTE. - - Example 1.37. change_reply_status usage -... -onreply_route { - if ($rs == "603") { - change_reply_status(404, "Not Found"); - exit; - } -} -... - -1.3.36. stream_exists(regexp[,regexp2]) - - This function can be used to verify if a stream exists inside - an sdp payload. It will search for the stream inside all sdp - sessions. If it is found anywhere it will return TRUE otherwise - it will return FALSE. - - Meaning of the parameters is as follows: - * regexp - a POSIX regular expression to match the stream - media name. - * regexp2 - an optional POSIX regular expression to match the - stream transport name. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.38. stream_exists usage -... -# check for FAX -stream_exists("image"); -... -stream_exists("audio","SAVP"); -... - -1.3.37. stream_delete(regexp[,regexp2]) - - This function can be used to delete a whole stream from inside - an sdp payload. It will search for the stream inside all sdp - sessions. If it is found anywhere it will be deleted along with - all attributes Returns TRUE if any deletion occurred otherwise - it will return FALSE. - - Meaning of the parameters is as follows: - * regexp - a POSIX regular expression to match the stream - media name. - * regexp2 - an optional POSIX regular expression to match the - stream transport name. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.39. stream_delete usage -... -# prevent usage of video -stream_delete("video"); -... - -1.3.38. list_hdr_has_option(hdr_name, option) - - Checks and returns true if the given option/token is listed in - the body of the given header. The header must have its body - formated as a CSV list of tokens/option (like the Supported, - Require, Content-Dispsition headers) body format - - Meaning of the parameters is as follows: - * hdr_name (string) - the name of the header to be checked. - Note that all instances of that header will be checked (if - the header has multiple instances in the SIP message). Any - kind of header name is supported - RFC3261 standard, RFC - extensions or custom names. - * opt (string) - the option/tolen to be searched for. - - The function returns true if the options was found listed in - one of the header instances. If no header was found, if the - option was not found or if there was a parsing or runtime - error, false will be returned. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.40. list_hdr_has_option usage -... -# check if 100rel is advertised -if (list_hdr_has_option("Supported", "100rel")) - xlog("100rel option found\n"); -... - -1.3.39. list_hdr_add_option(hdr_name, option) - - Add a new option/token at the end of the list in the body of - the given header. The header must have its body formated as a - CSV list of tokens/option (like the Supported, Require, - Content-Disposition headers) body format - - Multiple add / remove operations can be performed over the same - header. - - Meaning of the parameters is as follows: - * hdr_name (string) - the name of the header where the option - has to be added. If multiple instances of that header are - present in the SIP message, the add will be performed on - the first instance. Any kind of header name is supported - - RFC3261 standard, RFC extensions or custom names. - * opt (string) - the option/token to be added to the CSV - list. Note there is not verification for duplicated (if the - newly added option is not already present in the header). - - The function returns true if the options was successfully added - to the listed of the given header. If no header was found or if - there was a parsing or runtime error, false will be returned. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.41. list_hdr_add_option usage -... -# add 100rel for advertising -if (!list_hdr_has_option("Supported", "100rel")) - list_hdr_add_option("Supported", "100rel"); - -1.3.40. list_hdr_remove_option(hdr_name, option) - - Removes an option/token from the list inside the body of the - given header. The header must have its body formated as a CSV - list of tokens/option (like the Supported, Require, - Content-Dispsition headers) body format - - Multiple add / remove operations can be performed over the same - header. - - Meaning of the parameters is as follows: - * hdr_name (string) - the name of the header where the option - has to be removed from. If the option is duplicated in the - same header, only the last one will be removed. If multiple - instances of that header are present in the SIP message, - the remove will be performed on all instance instance. Any - kind of header name is supported - RFC3261 standard, RFC - extensions or custom names. - * opt (string) - the option/token to be removed from the CSV - list. Note that if this the only option in the header, the - whole header will be removed. - - The function returns true if the options was successfully - removed from at least one heaer instance. If no header was - found or if the token was not found or if there was a parsing - or runtime error, false will be returned. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.42. list_hdr_remove_option usage -... -# add 100rel for advertising -if (list_hdr_has_option("Supported", "100rel")) - list_hdr_remove_option("Supported", "100rel"); -list_hdr_add_option("Supported", "optionX"); - -1.3.41. get_glob_headers_values(hdr_name_glob, -hdr_names_avp,hdr_vals_avp) - - Populates the hdr_names_avp and hdr_vals_avp AVPs with all the - header names and values that match the hdr_name_glob pattern. - - Meaning of the parameters is as follows: - * hdr_name_glob (string) - the glob pattern for matching the - header names - * hdr_names_avp (var) - the AVP which will get populated with - all the header names that match the glob pattern - * hdr_vals_avp (var) - the AVP which will get populated with - all the header values corresponding to the header names - that match the glob pattern - - The function returns true if at least 1 header was found that - matches the glob pattern and false if no match is found. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.43. get_glob_headers_values usage -... - if (get_glob_headers_values("X-*",$avp(names),$avp(values))) { - xlog("All X- names are $(avp(names)[*]) and X- vals are $(avp -(values)[*])\n"); - } -... - -1.3.42. sip_to_json(out_var) - - Returns a JSON formatted representation of the current SIP - message, containing first_line , headers and body json members - Useful in cases when you want to pass a generic SIP message to - a SIP agnostic entity, but still want to provide some layer of - SIP parsing before sending the full message further. - - Meaning of the parameters is as follows: - * out_var (string) - the output JSON formatted SIP message - variable - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. - - Example 1.44. sip_to_json usage -... - if (sip_to_json($var(out_sip_json))) { - xlog("The JSON format for the current SIP message is $var(out -_sip_json) \n"); - } -... - -1.4. Known Limitations - - Search functions are applied to the current message so - modifications made to the sdp will be visible to the - codec_exists functions( e.g. after calling - codec_delete("speex") , codec_exists("speex") will return false - ). - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 74 43 2199 725 - 2. Liviu Chircu (@liviuchircu) 59 27 809 1510 - 3. Razvan Crainea (@razvancrainea) 48 21 2956 120 - 4. Vlad Paiu (@vladpaiu) 17 8 663 123 - 5. Mihai Tiganus (@tallicamike) 6 3 155 28 - 6. Maksym Sobolyev (@sobomax) 5 3 2 3 - 7. Vlad Patrascu (@rvlad-patrascu) 4 2 49 13 - 8. Ovidiu Sas (@ovidiusas) 4 2 22 1 - 9. Peter Lemenkov (@lemenkov) 4 2 2 2 - 10. Boris Ratner 4 1 129 46 - - All remaining contributors: Bence Szigeti, Julián Moreno - Patiño, Fabian Gast (@fgast), Alexey Vasilyev (@vasilevalex), - Jarrod Baumann (@jarrodb), Ubuntu, Ezequiel Lovelle (@lovelle), - Walter Doekes (@wdoekes), Nick Altmann (@nikbyte), Ionut Ionita - (@ionutrazvanionita), Dan Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ubuntu Mar 2025 - Mar 2025 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2012 - Jan 2025 - 3. Razvan Crainea (@razvancrainea) Feb 2012 - Jul 2024 - 4. Vlad Paiu (@vladpaiu) Feb 2012 - May 2024 - 5. Bence Szigeti May 2023 - May 2023 - 6. Maksym Sobolyev (@sobomax) Mar 2021 - Feb 2023 - 7. Liviu Chircu (@liviuchircu) Nov 2012 - Oct 2022 - 8. Dan Pascu (@danpascu) May 2019 - May 2019 - 9. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 10. Alexey Vasilyev (@vasilevalex) Jan 2019 - Jan 2019 - - All remaining contributors: Fabian Gast (@fgast), Peter - Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Jarrod Baumann - (@jarrodb), Julián Moreno Patiño, Ionut Ionita - (@ionutrazvanionita), Ezequiel Lovelle (@lovelle), Mihai - Tiganus (@tallicamike), Boris Ratner, Nick Altmann (@nikbyte), - Walter Doekes (@wdoekes). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu - (@vladpaiu), Bence Szigeti, Liviu Chircu (@liviuchircu), Vlad - Patrascu (@rvlad-patrascu), Fabian Gast (@fgast), Peter - Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Julián Moreno - Patiño, Razvan Crainea (@razvancrainea), Mihai Tiganus - (@tallicamike), Boris Ratner, Nick Altmann (@nikbyte). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/sipmsgops/README.md b/modules/sipmsgops/README.md new file mode 100644 index 00000000000..0ae81c34cf0 --- /dev/null +++ b/modules/sipmsgops/README.md @@ -0,0 +1,1379 @@ +--- +title: "sipmsgops Module" +description: "The module implements SIP based operations over the messages processed by OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +The module implements SIP based operations over the messages +processed by OpenSIPS. SIP is a text based protocol and the module +provides a large set of very useful functions to manipulate the +message at SIP level, e.g., inserting new headers or deleting them, +check for method type, etc. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Functions + + +#### append_to_reply(txt) + + +Append 'txt' as header to all replies that will be generated by +OpenSIPS for this request. + + +Meaning of the parameters is as follows: + + +- *txt (string)* - SIP header field, +value and CRLF marker. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and ERROR_ROUTE. + + +```opensips title="append_to_reply usage" +... +append_to_reply("Foo: bar\r\n"); +append_to_reply("Foo: $rm at $Ts\r\n"); +... +``` + + +#### append_body_to_reply(txt) + + +Append 'txt' as body to all replies that will be generated by +OpenSIPS for this request. + + +Multiple calls will override the already set body. + + +> [!NOTE] +> The function does not add any Content-Type hdr to match the body, +> so you should use "append_to_reply()" to do that. + + +Meaning of the parameters is as follows: + + +- *txt (string)* - body of the SIP reply + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and ERROR_ROUTE. + + +```opensips title="append_to_reply usage" +... +append_body_to_reply( $var(sdp_body) ); +... +``` + + +#### append_hf(txt[, hdr_anchor]) + + +Appends 'txt' as header after the last header field. If +'hdr_anchor' is given, 'txt' will be appended after the first +occurrence of 'hdr_anchor' instead. + + +Meaning of the parameters is as follows: + + +- *txt (string)* - Header field to be appended. +- *hdr_anchor (string, optional)* - Header name +after which the 'txt' is appended. + +> [!NOTE] +> Headers which are added in main route cannot be removed in further routes +> (e.g. failure routes). So, the idea is not to add there any headers that you +> might want to remove later. To add headers temporarily, use the branch route +> because the changes you do there are per-branch. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="append_hf usage" +... +append_hf("P-hint: VOICEMAIL\r\n"); +append_hf("From-username: $fU\r\n"); +append_hf("From-username: $fU\r\n", "Call-ID"); +... +``` + + +#### insert_hf(txt) + + +Inserts 'txt' as header before the first header field. + + +Meaning of the parameters is as follows: + + +- *txt (string)* - Header field to be inserted. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="insert_hf usage" +... +insert_hf("P-hint: VOICEMAIL\r\n"); +insert_hf("To-username: $tU\r\n"); +... +``` + + +#### insert_hf(txt, hdr) + + +Inserts 'txt' as header before first 'hdr' header field. + + +Meaning of the parameters is as follows: + + +- *txt (string)* - Header field to be inserted. +- *hdr (string, optional)* - Header name +before which the 'txt' is inserted. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="insert_hf usage" +... +insert_hf("P-hint: VOICEMAIL\r\n", "Call-ID"); +insert_hf("To-username: $tU\r\n", "Call-ID"); +... +``` + + +#### append_urihf(prefix, suffix) + + +Append header field name with original Request-URI +in middle. + + +Meaning of the parameters is as follows: + + +- *prefix* - string (usually at least +header field name). +- *suffix* - string (usually at least +line terminator). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE +and BRANCH_ROUTE. + + +```opensips title="append_urihf usage" +... +append_urihf("CC-Diversion: ", "\r\n"); +... +``` + + +#### is_present_hf(hf_name) + + +Return true if a header field is present in message. + + +> [!NOTE] +> The function is also able to distinguish the compact names. For +exmaple "From" will match with "f" + + +Meaning of the parameters is as follows: + + +- *hf_name (string)* - Header field name (long or +compact form). + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="is_present_hf usage" +... +if (is_present_hf("From")) log(1, "From HF Present"); +... +``` + + +#### append_time() + + +Adds a time header to the reply of the request. You must use it +before functions that are likely to send a reply, e.g., save() +from 'registrar' module. Header format is: +"Date: %a, %d %b %Y %H:%M:%S GMT", with the legend: + + +- *%a* abbreviated week of day name (locale) +- *%d* day of month as decimal number +- *%b* abbreviated month name (locale) +- *%Y* year with century +- *%H* hour +- *%M* minutes +- *%S* seconds + + +Return true if a header was successfully appended. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="append_time usage" +... +append_time(); +... +``` + + +#### is_method(name) + + +Check if the method of the message matches the name. If name is a +known method (invite, cancel, ack, bye, options, info, update, register, +message, subscribe, notify, refer, prack), the function performs method +ID testing (integer comparison) instead of ignore case string +comparison. + + +The 'name' can be a list of methods in the form of +'method1|method2|...'. In this case, the function returns true if the +SIP message's method is one from the list. IMPORTANT NOTE: in the list +must be only methods defined in OpenSIPS with ID (invite, cancel, ack, +bye, options, info, update, register, message, subscribe, notify, +refer, prack, publish; for more see: +[https://www.iana.org/assignments/sip-parameters](https://www.iana.org/assignments/sip-parameters)). + + +If used for replies, the function tests the value of method field from +CSeq header. + + +Meaning of the parameters is as follows: + + +- *name (string)* - SIP method name + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="is_method usage" +... +if(is_method("INVITE")) +{ + # process INVITEs here +} +if(is_method("OPTION|UPDATE")) +{ + # process OPTIONs and UPDATEs here +} +... +``` + + +#### remove_hf(hname) + + +Remove from message all headers with name "hname" + + +Returns true if at least one header is found and removed. + + +Meaning of the parameters is as follows: + + +- *hname (string)* - header name to be removed. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="remove_hf usage" +... +if(remove_hf("User-Agent")) +{ + # User Agent header removed +} +... +``` + + +#### remove_hf_re(hname_expr) + + +Remove from message all headers matching the +"hname_expr" POSIX regular expression. + + +Returns true if at least one header is found and removed. + + +Meaning of the parameters is as follows: + + +- *hname_expr (string)* - regular expression. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="remove_hf_re usage" +... +remove_hf_re("^X-g.+[0-9]"); +... +``` + + +#### remove_hf_glob(hname_pattern) + + +Remove from message all headers matching the +"hname_pattern" glob pattern. + + +Returns true if at least one header is found and removed. + + +Meaning of the parameters is as follows: + + +- *hname_pattern (string)* - glob pattern + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="remove_hf_glob usage" +... +# removes X-Billing-Account, X-Billing-Price, X-Billing-rateplan, etc +remove_hf_glob("X-Billing*"); +... +``` + + +#### has_totag() + + +Check if To header field uri contains tag parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="has_totag usage" +... +if (has_totag()) { + ... +}; +... +``` + + +#### ruri_has_param(param[,value]) + + +Find if Request URI has a given parameter. If no value is given, +the function will look for the paramter with no value, oherwise it +will search for the parameter with the matching value. + + +Meaning of the parameters is as follows: + + +- *param (string)* - parameter name to look for. +- *value (string, optional)* - parameter value to match. + + +This function can be used from REQUEST_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="ruri_has_param usage" +... +if (ruri_has_param("user","phone")) { + ... +}; +... +``` + + +#### ruri_add_param(param) + + +Add to RURI an URI parameter formated as "name=value". + + +Meaning of the parameters is as follows: + + +- *param (string)* - parameter to be appended in +"name=value" format. + + +This function can be used from REQUEST_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="ruri_add_param usage" +... +ruri_add_param("nat=yes"); +... +``` + + +#### ruri_del_param(param) + + +Delete a parameter, its value and any leading ";" from the Request-URI of the current SIP message. + + +Meaning of the parameters is as follows: + + +- *param (string)* - the parameter to be removed + + +Returns **1** on a successful deletion or **-1** otherwise. + + +This function can be used from REQUEST_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="ruri_del_param usage" +... +ruri_del_param("user"); +... +``` + + +#### ruri_tel2sip() + + +Converts RURI, if it is tel URI, to SIP URI. Returns true, only if +conversion succeeded or if no conversion was needed (like RURI +was not tel URI. + + +This function can be used from REQUEST_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="ruri_tel2sip usage" +... +ruri_tel2sip(); +... +``` + + +#### is_uri_user_e164(uri) + + +Checks if the username part of the given URI is an E164 number. + + +Meaning of the parameters is as follows: + + +- *uri (string)* - a SIP URI + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE +and LOCAL_ROUTE. + + +```opensips title="is_uri_user_e164 usage" +... +if (is_uri_user_e164($fu)) { # Check From header URI user part + ... +} +if (is_uri_user_e164($avp(uri)) { + # Check user part of URI stored in avp uri + ... +}; +... +``` + + +#### has_body_part([mime]) + + +The function returns *true* if the SIP message +has any body part with the given MIME. If there is no MIME given, +it will return true if at least one body part is found (with any MIME). + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="has_body_part usage" +... +if(has_body_part("application/sdp")) +{ + # do interesting stuff here +} +... +``` + + +#### is_audio_on_hold() + + +The function returns *true* if the SIP message +has an SDP body attached and at least one audio stream in on hold. +The return code of the function indicates the detected hold type: + + +- *1* - RFC2543 hold type: +null connection IP detected +- *2* - RFC3264 hold type: +inactive or sendonly attributes detected + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="is_audio_on_hold usage" +... +if(is_audio_on_hold()) +{ + switch ($rc) { + case 1: + # RFC2543 hold type + # do interesting stuff here + break; + case 2: + # RFC3264 hold type + # do interesting stuff here + break; +} +... +``` + + +#### is_privacy(privacy_type) + + +The function returns *true* if +the SIP message has a Privacy header field that includes +the given privacy_type among its privacy values. See +[https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-8](https://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml#sip-parameters-8) +for possible privacy type values. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="is_privacy usage" +... +if(is_privacy("id")) +{ + # do interesting stuff here +} +... +``` + + +#### remove_body_part([mime[, revert]]) + + +Removes from the message body all the body parts with the given mime. +The necessary corrections over the Content-Type and Content-Length +headers are automatically done. + + +If a MIME type is given, it will delete only the body parts with +that mime. If no MIME given, all the parts (entire body) will be +removed. + + +Meaning of the parameters is as follows: + + +- *mime (string, optional)* - MIME type to +be checked against the body parts; If not given, all parts +are to remvoed; +- *revert (string, optional)* - useful only +if a MIME was specified. If "revert" string is given here, the +function will delete all body parts but the ones with the given MIME. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="remove_body_part() usage" +... +# delete entire body message (all parts) +remove_body_part(); +# delete all body parts with mime "application/isup" +remove_body_part("application/isup"); +# delete all body parts but keep the the ones with "application/sdp" +remove_body_part("application/sdp","revert") +... +``` + + +#### add_body_part(body, mime[, headers]) + + +This function can be used to add a new body part to the message body. +If another part already exist, body of the message will be converted +to a multi-part body automatically. + + +Meaning of the parameters is as follows: + + +- *body (string)* - the content of the body part +to be added +- *mime (string)* - the mime string for the body +part to be added +- *headers (string, optional)* - optional list of SIP headers +(fully defined, including the header separator) to be pushed into +this part next to the *Content-Type* header. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="add_body_part usage" +... +add_body_part("Hello World!", "text/plain"); +... +``` + + +#### get_updated_body_part( [mime], variable) + + +This function returns into a variable the regenerated body part, +meaning the body part updated with all the changes done so far by +OpenSIPS. This is helpful if you want to do a sequance of operations +over the body parts and some operations require to have all the +previous changes applied (like first doing some codec related changes +and later to rtpengine insertion). + + +> [!NOTE] +> The actual SIP message will not be affected by this operation! + + +Meaning of the parameters is as follows: + + +- *mime (string)* - the mime string for +the body to be regenerated and returned. If missing, the whole +body (with all its parts) will be regenerated. +- *variable* - a variable to be used to +return the regenerated body part (as text). + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="get_updated_body_part usage" +... + codec_delete_re("PCMA|PCMU"); + + get_updated_body_part( "application/sdp", $var(new_sdp)); + + xlog("------updated SDP is ----\n$var(new_sdp)\n-----------\n"); + exit; +... +``` + + +#### sipmsg_validate([flags[, result_pvar]]) + + +The function returns *true* if the SIP message +is properly built according to SIP RFC3261. It verifies if the +mandatory headers for each request/reply and can also check the format +of the headers body. + + +The flags parameter received is optional and can be composed +with the following values: + + +- *'s'* - checks the +integrity of the SDP body, if it exists +- *'h'* - checks the format +and integrity of each header body. +- *'m'* - don't check the +Max-Forwards header. +- *'r'* - checks the R-URI +and whether the domain contains valid characters. +- *'f'* - checks the URI of the 'From' field +and whether the domain contains valid characters. +- *'t'* - checks the URI of the 'To' field +and whether the domain contains valid characters. +- *'c'* - checks the value of the 'Contact' field +and whether it is a Uri, Star - for REGISTER requests with Expires header set to 0. + + +The result_pvar parameter sets resulting pvar with text error reason in case of +negative result ( easy for logging or propagating the rejection reason back to the +bogus UA ) + + +This function can return the following codes: + + +- *1* - the message is +RFC3261 compliant and has been successfully validated. +- *-1* - No SIP message +- *-2* - Header Parsing error +- *-3* - No Call-ID header +- *-4* - No Content-Length header for transports that require it ( eg. TCP ) +- *-5* - Invalid Content-Length, other from the size of the actual body +- *-6* - SDP body parsing error. +- *-7* - No Cseq header. +- *-8* - No From header. +- *-9* - No To header. +- *-10* - No Via header. +- *-11* - Request URI parse error. +- *-12* - Bad hostname in R-URI. +- *-13* - No Max-Forwards header. +- *-14* - No Contact header. +- *-15* - Path user for non-Register request. +- *-16* - No allow header in 405 reply. +- *-17* - No Min-Expire header in 423 reply. +- *-18* - No Proxy-Authorize header in 407 reply. +- *-19* - No Unsupported header in 420 reply. +- *-20* - No WWW-Authorize header in 401 reply. +- *-21* - No Content-Type header +- *-22* - To header parse error +- *-23* - Bad hostname in To header +- *-24* - From header parse error +- *-25* - Bad hostname in From header +- *-26* - Contact header parse error +- *-27* - Bad URI username +- *-28* - Bad From URI username +- *-29* - Bad To URI username +- *-30* - Contact header contains * for non-Register request +- *-255* - undefined errors. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE and BRANCH_ROUTE. + + +```opensips title="sipmsg_validate usage" +... +if(!sipmsg_validate()) +{ + send_reply(400, "Bad Request"); + exit; +} +... + +... +# checks also the SDP and headers body +if(!sipmsg_validate("sh", $var(err_reason))) +{ + send_reply(400, "Bad Request/Body"); + exit; +} +... + +... +# checks Contact header for a 200 Ok reply and logs when it's * +if(!sipmsg_validate("c")) +{ + if ($rc == -30) + xlog("Invalid * Contact header found\n"); +} +... +``` + + +#### codec_exists (name[, clock]) + + +This function can be used to verify if a codec exists inside an +sdp payload. It will search for the codec inside all streams from all +sdp sessions. If it is found anywhere it will return TRUE otherwise +it will return FALSE. + + +Parameters: + + +- *name* (string) - Parameter is CASE INSENSITIVE. +- *clock* (string, optional) - if not supplied +any clockrate will match. Parameter is CASE INSENSITIVE. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_exists usage" +... +codec_exists("speex"); +or +codec_exists("GSM", "8000"); +... +``` + + +#### codec_delete(name[, clock]) + + +This function can be used to delete a codec from inside an +sdp payload. It will search for the codec inside all streams from all +sdp sessions. If it is found anywhere it will be deleted from the +mapping ("a=...") and from the list of indexes ("m=..."). +Returns TRUE if any deletion occurred otherwise +it will return FALSE. + + +- *name* (string) - Parameter is CASE INSENSITIVE. +- *clock* (string, optional) - if not supplied +any clockrate will match and all will be deleted. Parameter is CASE INSENSITIVE. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_delete usage" +... +codec_delete("speex"); +or +codec_delete("GSM", "8000"); +... +``` + + +#### codec_move_up(name[, clock]) + + +This function can be used to move a codec up in the list +of indexes ("m=..."). It will search for the codec inside all streams from all +sdp sessions. If it is found anywhere it will be moved to the top +of the index list. Returns TRUE if any moves occurred otherwise +it will return FALSE. + + +- *name* (string) - parameter is CASE INSENSITIVE. +- *clock* (string, optional) - if not supplied +any clockrate will match and all codecs +will be moved to the front while preserving their original ordering. +Parameter is CASE INSENSITIVE. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_move_up usage" +... +codec_move_up("speex"); +or +codec_move_up("GSM", "8000"); +... +``` + + +#### codec_move_down(name[, clock]) + + +This function can be used to move a codec down in the list +of indexes ("m=..."). It will search for the codec inside all streams from all +sdp sessions. If it is found anywhere it will be moved to the back +of the index list. Returns TRUE if any moves occurred otherwise +it will return FALSE. The second parameter is optional, +if it is not supplied any clockrate will match and all codecs +will be moved to the back while preserving their original ordering. +Parameters are CASE INSENSITIVE. + + +- *name* (string) - parameter is CASE INSENSITIVE. +- *clock* (string, optional) - if not supplied +any clockrate will match and all codecs +will be moved to the back while preserving their original ordering. +Parameter is CASE INSENSITIVE. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_move_down usage" +... +codec_move_down("speex"); +or +codec_move_down("GSM", "8000"); +... +``` + + +```opensips title="codec_move_down usage" +... +/* + This example will move speex with 8000 codec to the back of the list, + then it will erase GSM with 8000 clock, and then it will bring all + speex codecs to the front of the list. Speex/8000 will be behind any + other speex. +*/ +codec_move_down("speex", "8000"); +codec_delete("GSM", "8000"); +codec_move_up("speex"); +... +``` + + +#### codec_exists_re ( regexp ) + + +This function has the same effect as codec_exists ( without +the clock parameter ) the only +difference is that it takes a POSIX regular expression +as a parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_exists_re usage" +... +codec_exists_re("sp[a-z]*"); +... +``` + + +#### codec_delete_re ( regexp ) + + +This function has the same effect as codec_delete ( without +the clock parameter ) the only +difference is that it takes a POSIX regular expression +as a parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_delete_re usage" +... +codec_delete_re("PCMA|PCMU"); +... +``` + + +#### codec_delete_except_re ( regexp ) + + +This function deletes all the codecs except those specified +by the regular expression. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_delete_except_re usage" +... +codec_delete_except_re("PCMA|PCMU");#will delete all codecs except PCMA and PCMU +... +``` + + +#### codec_move_up_re ( regexp ) + + +This function has the same effect as codec_move_up ( without +the clock parameter ) the only +difference is that it takes a POSIX regular expression +as a parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_move_up_re usage" +... +codec_move_up_re("sp[a-z]*"); +... +``` + + +#### codec_move_down_re ( regexp ) + + +This function has the same effect as codec_move_down ( without +the clock parameter ) the only +difference is that it takes a POSIX regular expression +as a parameter. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="codec_move_down_re usage" +... +codec_move_down_re("sp[a-z]*"); +... +``` + + +```opensips title="codec_move_down usage" +... +/* + This example will move speex with 8000 codec to the back of the list, + then it will erase GSM with 8000 clock, and then it will bring all + speex codecs to the front of the list. Speex/8000 will be behind any + other speex. +*/ +codec_move_down("speex","8000"); +codec_delete("GSM","8000"); +codec_move_up("speex"); +... +``` + + +#### change_reply_status(code, reason) + + +Intercept a SIP reply (in any onreply_route) and change its status code +and reason phrase prior to propogating it. + + +Meaning of the parameters is as follows: + + +- *code (int)* - Status code. +- *reason (string)* - Reason phrase. + + +This function can be used from ONREPLY_ROUTE. + + +```opensips title="change_reply_status usage" +... +onreply_route { + if ($rs == "603") { + change_reply_status(404, "Not Found"); + exit; + } +} +... + +``` + + +#### stream_exists(regexp[,regexp2]) + + +This function can be used to verify if a stream exists inside an +sdp payload. It will search for the stream inside all sdp sessions. +If it is found anywhere it will return TRUE otherwise +it will return FALSE. + + +Meaning of the parameters is as follows: + + +- *regexp* - a POSIX regular expression +to match the stream media name. +- *regexp2* - an optional POSIX regular +expression to match the stream transport name. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="stream_exists usage" +... +# check for FAX +stream_exists("image"); +... +stream_exists("audio","SAVP"); +... +``` + + +#### stream_delete(regexp[,regexp2]) + + +This function can be used to delete a whole stream from inside an +sdp payload. It will search for the stream inside all sdp sessions. +If it is found anywhere it will be deleted along with all attributes +Returns TRUE if any deletion occurred otherwise +it will return FALSE. + + +Meaning of the parameters is as follows: + + +- *regexp* - a POSIX regular expression +to match the stream media name. +- *regexp2* - an optional POSIX regular +expression to match the stream transport name. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="stream_delete usage" +... +# prevent usage of video +stream_delete("video"); +... +``` + + +#### list_hdr_has_option(hdr_name, option) + + +Checks and returns true if the given option/token is listed in the +body of the given header. The header must have its body formated as a +CSV list of tokens/option (like the Supported, Require, +Content-Dispsition headers) +body format + + +Meaning of the parameters is as follows: + + +- *hdr_name (string)* - the name of the header to be +checked. Note that all instances of that header will be checked (if the +header has multiple instances in the SIP message). Any kind of header +name is supported - RFC3261 standard, RFC extensions or custom names. +- *opt (string)* - the option/tolen to be searched for. + + +The function returns true if the options was found listed in one of the +header instances. If no header was found, if the option was not found +or if there was a parsing or runtime error, false will be returned. +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="list_hdr_has_option usage" +... +# check if 100rel is advertised +if (list_hdr_has_option("Supported", "100rel")) + xlog("100rel option found\n"); +... +``` + + +#### list_hdr_add_option(hdr_name, option) + + +Add a new option/token at the end of the list in the body of the given +header. The header must have its body formated as a +CSV list of tokens/option (like the Supported, Require, +Content-Disposition headers) body format + + +Multiple add / remove operations can be performed over the same header. + + +Meaning of the parameters is as follows: + + +- *hdr_name (string)* - the name of the header where the +option has to be added. If multiple instances of that header are +present in the SIP message, the add will be performed on the first +instance. Any kind of header name is supported - RFC3261 standard, +RFC extensions or custom names. +- *opt (string)* - the option/token to be added to the +CSV list. Note there is not verification for duplicated (if the newly +added option is not already present in the header). + + +The function returns true if the options was successfully added to +the listed of the given header. If no header was found or if there was +a parsing or runtime error, false will be returned. +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="list_hdr_add_option usage" +... +# add 100rel for advertising +if (!list_hdr_has_option("Supported", "100rel")) + list_hdr_add_option("Supported", "100rel"); +``` + + +#### list_hdr_remove_option(hdr_name, option) + + +Removes an option/token from the list inside the body of the given +header. The header must have its body formated as a +CSV list of tokens/option (like the Supported, Require, +Content-Dispsition headers) +body format + + +Multiple add / remove operations can be performed over the same header. + + +Meaning of the parameters is as follows: + + +- *hdr_name (string)* - the name of the header where the +option has to be removed from. If the option is duplicated in the same +header, only the last one will be removed. If multiple instances of +that header are present in the SIP message, the remove will be +performed on all instance instance. Any kind of header name is +supported - RFC3261 standard, RFC extensions or custom names. +- *opt (string)* - the option/token to be removed from +the CSV list. Note that if this the only option in the header, the +whole header will be removed. + + +The function returns true if the options was successfully removed from +at least one heaer instance. If no header was found or if the +token was not found or if there was a parsing or runtime error, false +will be returned. +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="list_hdr_remove_option usage" +... +# add 100rel for advertising +if (list_hdr_has_option("Supported", "100rel")) + list_hdr_remove_option("Supported", "100rel"); +list_hdr_add_option("Supported", "optionX"); +``` + + +#### get_glob_headers_values(hdr_name_glob, hdr_names_avp,hdr_vals_avp) + + +Populates the hdr_names_avp and hdr_vals_avp AVPs with all the header names and values that match the hdr_name_glob pattern. + + +Meaning of the parameters is as follows: + + +- *hdr_name_glob (string)* - the glob pattern for matching the header names +- *hdr_names_avp (var)* - the AVP which will get populated with all the header names that match the glob pattern +- *hdr_vals_avp (var)* - the AVP which will get populated with all the header values corresponding to the header names that match the glob pattern + + +The function returns true if at least 1 header was found that matches the glob pattern and false if no match is found. +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="get_glob_headers_values usage" +... + if (get_glob_headers_values("X-*",$avp(names),$avp(values))) { + xlog("All X- names are $(avp(names)[*]) and X- vals are $(avp(values)[*])\n"); + } +... +``` + + +#### sip_to_json(out_var) + + +Returns a JSON formatted representation of the current SIP message, containing first_line , headers and body json members +Useful in cases when you want to pass a generic SIP message to a SIP agnostic entity, but still want to provide some layer of SIP parsing before sending the full message further. + + +Meaning of the parameters is as follows: + + +- *out_var (string)* - the output JSON formatted SIP message variable + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE and LOCAL_ROUTE. + + +```opensips title="sip_to_json usage" +... + if (sip_to_json($var(out_sip_json))) { + xlog("The JSON format for the current SIP message is $var(out_sip_json) \n"); + } +... +``` + + +### Known Limitations + + +Search functions are applied to the current message so +modifications made to the sdp will be visible +to the codec_exists functions( e.g. after +calling codec_delete("speex") , codec_exists("speex") +will return false ). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sipmsgops/doc/contributors.xml b/modules/sipmsgops/doc/contributors.xml deleted file mode 100644 index 7fdfa591312..00000000000 --- a/modules/sipmsgops/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 74 - 43 - 2199 - 725 - - - 2. - Liviu Chircu (@liviuchircu) - 59 - 27 - 809 - 1510 - - - 3. - Razvan Crainea (@razvancrainea) - 48 - 21 - 2956 - 120 - - - 4. - Vlad Paiu (@vladpaiu) - 17 - 8 - 663 - 123 - - - 5. - Mihai Tiganus (@tallicamike) - 6 - 3 - 155 - 28 - - - 6. - Maksym Sobolyev (@sobomax) - 5 - 3 - 2 - 3 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 4 - 2 - 49 - 13 - - - 8. - Ovidiu Sas (@ovidiusas) - 4 - 2 - 22 - 1 - - - 9. - Peter Lemenkov (@lemenkov) - 4 - 2 - 2 - 2 - - - 10. - Boris Ratner - 4 - 1 - 129 - 46 - - - -
-All remaining contributors: Bence Szigeti, Julián Moreno Patiño, Fabian Gast (@fgast), Alexey Vasilyev (@vasilevalex), Jarrod Baumann (@jarrodb), Ubuntu, Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Nick Altmann (@nikbyte), Ionut Ionita (@ionutrazvanionita), Dan Pascu (@danpascu). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ubuntu - Mar 2025 - Mar 2025 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2012 - Jan 2025 - - - 3. - Razvan Crainea (@razvancrainea) - Feb 2012 - Jul 2024 - - - 4. - Vlad Paiu (@vladpaiu) - Feb 2012 - May 2024 - - - 5. - Bence Szigeti - May 2023 - May 2023 - - - 6. - Maksym Sobolyev (@sobomax) - Mar 2021 - Feb 2023 - - - 7. - Liviu Chircu (@liviuchircu) - Nov 2012 - Oct 2022 - - - 8. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 10. - Alexey Vasilyev (@vasilevalex) - Jan 2019 - Jan 2019 - - - -
-All remaining contributors: Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Jarrod Baumann (@jarrodb), Julián Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Ezequiel Lovelle (@lovelle), Mihai Tiganus (@tallicamike), Boris Ratner, Nick Altmann (@nikbyte), Walter Doekes (@wdoekes). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Bence Szigeti, Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Fabian Gast (@fgast), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Julián Moreno Patiño, Razvan Crainea (@razvancrainea), Mihai Tiganus (@tallicamike), Boris Ratner, Nick Altmann (@nikbyte). -
- -
diff --git a/modules/sipmsgops/doc/sipmsgops.xml b/modules/sipmsgops/doc/sipmsgops.xml deleted file mode 100644 index 257128cd8cc..00000000000 --- a/modules/sipmsgops/doc/sipmsgops.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - sipmsgops Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/sipmsgops/sipmsgops.c b/modules/sipmsgops/sipmsgops.c index e74de47e3e8..b9564c014f3 100644 --- a/modules/sipmsgops/sipmsgops.c +++ b/modules/sipmsgops/sipmsgops.c @@ -2149,6 +2149,10 @@ static int w_sip_to_json(struct sip_msg *msg, pv_spec_t* out_json) } for (it=msg->headers;it;it=it->next) { + if (it->name.len >= sizeof(hdr_name_buf)) { + LM_WARN("header name too long (%d), skipping\n", it->name.len); + continue; + } memcpy(hdr_name_buf,it->name.s,it->name.len); hdr_name_buf[it->name.len] = 0; diff --git a/modules/siprec/README b/modules/siprec/README deleted file mode 100644 index f91d9d289e5..00000000000 --- a/modules/siprec/README +++ /dev/null @@ -1,507 +0,0 @@ -SIPREC Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Media Handling - 1.4. SRS Failover - 1.5. Limitations - 1.6. Dependencies - - 1.6.1. OpenSIPS Modules - 1.6.2. External Libraries or Applications - - 1.7. Exported Parameters - - 1.7.1. skip_failover_codes (string) - - 1.8. Exported Events - - 1.8.1. E_SIPREC_START - 1.8.2. E_SIPREC_STOP - - 1.9. Exported Functions - - 1.9.1. siprec_start_recording(srs[, instance]) - 1.9.2. siprec_pause_recording([instance]) - 1.9.3. siprec_resume_recording([instance]) - 1.9.4. siprec_stop_recording([instance]) - 1.9.5. siprec_send_indialog([hdrs[, body]]) - - 1.10. Exported Pseudo-Variables - - 1.10.1. $siprec - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set skip_failover_codes parameter - 1.2. Use siprec_start_recording() function with a single SRS - 1.3. Use siprec_start_recording() function with multiple SRS - servers - - 1.4. Use siprec_start_recording() function with custom XML - values for participants - - 1.5. Use siprec_start_recording() function with custom headers - 1.6. Use siprec_start_recording() function with custom group - and session extensions - - 1.7. Use siprec_pause_recording() - 1.8. Use siprec_resume_recording() - 1.9. Use siprec_stop_recording() - 1.10. Use siprec_send_indialog() - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides the means to do calls recording using an - external recorder - the entity that records the call is not in - the media path between the caller and callee, but it is - completely separate, thus it can not affect by any means the - quality of the conversation. This is done in a standardized - manner, using the SIPREC Protocol, thus it can be used by any - recorder that implements this protocol. - - Since an external server is used to record calls, there are no - constraints regarding the location of the recorder, thus it can - be placed arbitrary. This offers huge flexibility to your - architecture configuration and various means for scaling. - - The work for this module has been sponsored by the OrecX - Company. This module is fully integrated with the OrecX Call - Recording products. - -1.2. How it works - - The full architecture of a SIP Media Recording platform is - documented in RFC 7245. According to this architecture, this - OpenSIPS module implements a SRC (Session Recording Client) - that instructs a SRS (Session Recording Server) when new calls - are started, the participants of the calls and their profiles. - Based on this data, the SRS can decide whether the call should - be recorded or not. - - From SIP signalling perspective, the module does not change the - call flow between the caller and callee. The call is - established just as any other calls that are not recorded. But - for each call that has SIPREC engaged, a completely separate - SIP session is started by the SRC (OpenSIPS) towards the SRS, - using the OpenSIPS Back-2-Back module. The INVITE message sent - to the SRS contains a multi-part body consisting of two parts: - * Recording SDP - the SDP of the Media Server that will fork - the RTP to the recorder. - * Participants Metadata - an XML-formatted document that - contains information about the participants. The structure - of the document is detailed in RFC 7865. - - The SRS can respond with negative reply, indicating that the - session does not need to be recorded, or with a positive reply - (200 OK), indicating in the SDP body where the media RTP should - be sent/forked. When the call ends, the SRC must send a BYE - message to the SRS, indicating that the recording should be - completed. - - Full examples of call flows can be found in RFC 8068. - -1.3. Media Handling - - Since OpenSIPS is a SIP Proxy, it does not have any Media - Capabilities by itself. Thus we need to rely on a different - Media Server to capture the RTP traffic and fork it to the SRS. - The current implementation supports both the RTPProxy (through - the RTPProxy module) and RTPEngine (through the RTEngine - module) Media Servers. - -1.4. SRS Failover - - The siprec module supports failover between multiple SRS - servers - when calling the siprec_start_recording() function, - one can provision multiple SRS URIs, separated by comma. In - this case, OpenSIPS will try to use them in the same order - specified, one by one, until either one of them responds with a - positive reply (200 OK), or the response code is one of the - codes matched by the skip_failover_codes regular expression. In - the latter case the call is not recorded at all. - -1.5. Limitations - - This module only implements the SRC specifications of the - SIPREC RFC. In order to have a full recording solution, you - will also need a SRS solution such as Oreka - an open-source - project provided by OrecX. - - Although this module provides all the necessary tools to do - calls recording, it does not fully implement the entire SIPREC - SRC specifications. This list contains some of the module's - limitations: - * There is no Recording Indicator played to the callee - - since OpenSIPS continues to act as a proxy, there is no way - for us to postpone the media between the caller and callee - to play a Recording Indicator message. - * Cannot handle Recording Sessions initiated by SRS - we do - not support the scenario when an SRS suddenly decides to - record a call in the middle of the dialog. - * OpenSIPS cannot be “queried” for ongoing recording sessions - - this is scheduled to be implemented in further releases. - -1.6. Dependencies - -1.6.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction module. - * Dialog - Dialog module for keeping track of the call. - * RTP_Relay - RTP Relay module used for controlling the Media - Servers that will fork the media. - * B2B_ENTITIES - Back-2-Back module used for communicating - with the SRS. - -1.6.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.7. Exported Parameters - -1.7.1. skip_failover_codes (string) - - A regular expression used to specify the codes that should - prevent the module from failing over to a new SRS server. - - By default any negative reply generates a failover. - - Example 1.1. Set skip_failover_codes parameter -... -# do not failover on 408 reply codes -modparam("siprec", "skip_failover_codes", "408") - -# do not failover on 408 or 487 reply codes -modparam("siprec", "skip_failover_codes", "408|487") - -# do not failover on any 3xx or 4xx reply code -modparam("siprec", "skip_failover_codes", "[34][0-9][0-9]") -... - -1.8. Exported Events - -1.8.1. E_SIPREC_START - - This event is raised when a SIPREC call is established and a - call starts to be recorded. - - Parameters: - * dlg_id - dialog id (“did”) of the call being recorded; - * dlg_callid - Call-Id of the call being recorded; - * callid - Call-Id (B2B id) of the SIPREC call; - * session_id - SIPREC UUID of the recording call; - * server - the SIPREC server handing this call; - * instance - the SIPREC instance this event is triggered for; - -1.8.2. E_SIPREC_STOP - - This event is raised when a SIPREC call is terminated. - - This event exposes the same parameters as the E_SIPREC_START - event. - -1.9. Exported Functions - -1.9.1. siprec_start_recording(srs[, instance]) - - Calling this function on an initial INVITE engages call - recording to SRS(s) for that call. Note that it does not - necessary mean that the call will be recorded - it just means - that OpenSIPS will query instruct the SRS that a new call has - started, but the SRS might decide that the recording is - disabled for those participants. - - Note that the call recording is not started right away, but - only when the callee provides an SDP as well (usually in a 200 - OK, or possibly a 183 Ringing). - - Note if you only want to start recording when the call is - established (200 OK is received), then you should call this - function in the onreply route processing that 200 OK. - - Parameters: - * srs (string) - a comma-separated list of SRS URIs. These - URIs are used in the order specified. See - siprec_srs_failover for more information. - * instance (string, optional) - used to start a particular - SIPREC instance. When missing, the default instance is - started. - - The function returns false when an internal error is triggered - and the call recording setup fails. Otherwise, if all the - internal mechanisms are activated, it returns true. - - This function can be used from REQUEST_ROUTE. - - Example 1.2. Use siprec_start_recording() function with a - single SRS - ... - if (!has_totag() && is_method("INVITE")) { - $var(srs) = "sip:127.0.0.1"; - xlog("Engage SIPREC call recording to $var(srs) for $ci\ -n"); - siprec_start_recording($var(srs)); - } - ... - - Example 1.3. Use siprec_start_recording() function with - multiple SRS servers - ... - if (!has_totag() && is_method("INVITE")) { - $var(srs) = "sip:127.0.0.1, sip:127.0.0.1;transport=TCP" -; - xlog("Engage SIPREC call recording to servers $var(srs) -for $ci in inbound group\n"); - siprec_start_recording($var(srs), "inbound"); - } - ... - - Example 1.4. Use siprec_start_recording() function with custom - XML values for participants - ... - $xml(caller_xml) = ""; - $xml(caller_xml/nameID.attr/aor) = "sip:6024151234@10.0.0.11:509 -0"; - $xml(caller_xml/nameID) = "test"; - $siprec(caller) = $xml(caller_xml/nameID); - siprec_start_recording($var(srs)); - ... - - Example 1.5. Use siprec_start_recording() function with custom - headers - ... - $siprec(headers) = "X-MY-CUSTOM_HDR: 1\r\n"; - siprec_start_recording($var(srs)); - ... - - Example 1.6. Use siprec_start_recording() function with custom - group and session extensions - ... - $var(temp) = " 17"; - $siprec(group_custom_extension) = $var(temp); - $siprec(session_custom_extension) = "dfgh3q45gsd -fty5"; - - siprec_start_recording($var(srs)); - ... - -1.9.2. siprec_pause_recording([instance]) - - Pauses the recording for the ongoing call. Should be called - after the dialog has matched. - - Parameters: - * instance (string, optional) - used to pause a particular - SIPREC instance. When missing, the default instance is - paused. - - This function can be used from any route. - - Example 1.7. Use siprec_pause_recording() - ... - if (has_totag() && is_method("INVITE")) { - if (is_audio_on_hold()) - siprec_pause_recording(); - } - ... - -1.9.3. siprec_resume_recording([instance]) - - Resumes the recording for the ongoing call. Should be called - after the dialog has matched. - - Parameters: - * instance (string, optional) - used to resume a particular - SIPREC instance. When missing, the default instance is - resumed. - - This function can be used from any route. - - Example 1.8. Use siprec_resume_recording() - ... - if (has_totag() && is_method("INVITE")) { - if (!is_audio_on_hold()) - siprec_resume_recording(); - } - ... - -1.9.4. siprec_stop_recording([instance]) - - Stops the recording for the ongoing call. Should be called for - SIPREC sessions that have been previously started. - - Parameters: - * instance (string, optional) - used to stop a particular - SIPREC instance. When missing, the default instance is - stopped. - - This function can be used from any route. - - Example 1.9. Use siprec_stop_recording() - ... - if (has_totag() && is_method("INVITE")) { - if (is_audio_on_hold()) - siprec_stop_recording(); - } - ... - -1.9.5. siprec_send_indialog([hdrs[, body]]) - - Sends an arbitrary in-dialog request to the SRS. - - This function can be used from any route. - - Parameters: - * headers (string, optional) - a set of headers that will be - added to the generated request. - * body (string, optional) - the body that will be added to - the generated request. - * instance (string, optional) - used to send a request within - a particular SIPREC instance. When missing, the request is - sent in to the default instance. - - Example 1.10. Use siprec_send_indialog() - ... - if (has_totag() && is_method("INFO")) { - siprec_send_indialog("Content-Type: $hdr(Content-Type)\r -\n", $rb); - } - ... - -1.10. Exported Pseudo-Variables - -1.10.1. $siprec - - Used to modify/describe different siprec sessions parameters - that should be taken into account by the - siprec_start_recording() function. - - The variable can be indexed with the instance the user wants to - tune the variable for. If missing, the the default instance is - being altered. - - The context of this variable is only limited to the current - message processed - it is not available at the transaction or - dialog level. - - Any of this setting is optional. - - Settings that can be provisioned: - * group - an opaque value that will be inserted in the SIPREC - body and represents the name of the group that can be used - to classify calls in certain profiles. If missing, no group - is added. - * caller - an XML block containing information about the - caller. If absent, the From header of the initial dialog is - used to build the value. - * callee - an XML block containing information about the - callee. If absent, the To header of the initial dialog is - used to build the value. - * media - the IP that RTPProxy will be streaming media from. - If absent 127.0.0.1 will be used. NOTE:media_ip has been - dropped. - * headers - extra headers that are to be added in the initial - request towards the SRS. NOTE: headers must be separated by - \r\n and must end with \r\n. - * socket - listening socket that the outgoing request towards - SRS should be used. - * from_uri - the URI to appear in the From header of the - dialog. Default value is the request URI. Note that this - does not influence the caller information in the XML block, - which is taken from the initial dialog. - * to_uri - the URI to appear in the To header of the dialog. - Default value is the request URI. Note that this does not - influence the callee information in the XML block, which is - taken from the initial dialog. - * group_custom_extension - an optional XML block containing - custom information to be added under the group tag. NOTE: - if the group is absent this value will be ignored and not - used anywhere. - * session_custom_extension - an optional XML block containing - custom information to be added under the session tag. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 193 101 6419 2268 - 2. Vlad Patrascu (@rvlad-patrascu) 16 11 166 149 - 3. Liviu Chircu (@liviuchircu) 9 7 35 53 - 4. Maksym Sobolyev (@sobomax) 6 4 12 11 - 5. Jupiter Tang 5 3 13 3 - 6. Seyed Mehran Siadati 5 2 124 15 - 7. Bogdan-Andrei Iancu (@bogdan-iancu) 4 2 3 2 - 8. Norman Brandinger (@NormB) 3 1 4 4 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Jupiter Tang Oct 2025 - Dec 2025 - 2. Razvan Crainea (@razvancrainea) Jun 2017 - Oct 2025 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 4. Seyed Mehran Siadati Nov 2023 - Nov 2023 - 5. Liviu Chircu (@liviuchircu) Apr 2018 - Aug 2023 - 6. Vlad Patrascu (@rvlad-patrascu) Feb 2018 - Mar 2023 - 7. Norman Brandinger (@NormB) Aug 2021 - Aug 2021 - 8. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2021 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Seyed Mehran - Siadati, Norman Brandinger (@NormB), Vlad Patrascu - (@rvlad-patrascu), Liviu Chircu (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2017 www.opensips-solutions.com diff --git a/modules/siprec/README.md b/modules/siprec/README.md new file mode 100644 index 00000000000..554766c2633 --- /dev/null +++ b/modules/siprec/README.md @@ -0,0 +1,498 @@ +--- +title: "SIPREC Module" +description: "This module provides the means to do calls recording using an external recorder - the entity that records the call is not in the media path between the caller and callee, but it is completely separate, thus it can not affect by any means the quality of the conversation." +--- + +## Admin Guide + + +### Overview + + +This module provides the means to do calls recording using an +external recorder - the entity that records the call is not in +the media path between the caller and callee, but it is completely +separate, thus it can not affect by any means the quality of the +conversation. This is done in a standardized manner, using +the [SIPREC +Protocol](https://tools.ietf.org/html/rfc7866), thus it can be used by any recorder that +implements this protocol. + + +Since an external server is used to record calls, there are no +constraints regarding the location of the recorder, thus it can be +placed arbitrary. This offers huge flexibility to your architecture +configuration and various means for scaling. + + +The work for this module has been sponsored by the [OrecX Company](http://www.orecx.com/). This module is +fully integrated with the OrecX Call Recording products. + + +### How it works + + +The full architecture of a SIP Media Recording platform is +documented in [RFC 7245](https://tools.ietf.org/html/rfc7245). According to this architecture, this OpenSIPS +module implements a SRC (Session Recording Client) that instructs a SRS +(Session Recording Server) when new calls are started, the +participants of the calls and their profiles. Based on this data, the +SRS can decide whether the call should be recorded or not. + + +From SIP signalling perspective, the module does not change the call +flow between the caller and callee. The call is established just as +any other calls that are not recorded. But for each call that has +*SIPREC* engaged, a completely separate SIP session +is started by the SRC (OpenSIPS) towards the SRS, using the [OpenSIPS Back-2-Back module](../b2b_entities). The +*INVITE* message sent to the SRS contains a +multi-part body consisting of two parts: + + +- *Recording SDP* - the SDP of the Media Server +that will *fork* the RTP to the recorder. +- *Participants Metadata* - an XML-formatted +document that contains information about the participants. The +structure of the document is detailed in [RFC 7865](https://tools.ietf.org/html/rfc7865). + + +The SRS can respond with negative reply, indicating that the session +does not need to be recorded, or with a positive reply (200 OK), +indicating in the SDP body where the media RTP should be +*sent/forked*. When the call ends, the SRC must +send a *BYE* message to the SRS, indicating that +the recording should be completed. + + +Full examples of call flows can be found in [RFC 8068](https://tools.ietf.org/html/rfc8068). + + +### Media Handling + + +Since OpenSIPS is a SIP Proxy, it does not have any Media Capabilities +by itself. Thus we need to rely on a different Media Server to capture +the RTP traffic and fork it to the SRS. The current implementation +supports both the [RTPProxy](http://www.rtpproxy.org/) +(through the [RTPProxy module](../rtpproxy)) and +[RTPEngine](https://github.com/sipwise/rtpengine) +(through the [RTEngine module](../rtpengine)) Media +Servers. + + +### SRS Failover + + +The *siprec* module supports failover between +multiple SRS servers - when calling the *[siprec start recording](#func_siprec_start_recording)* function, one +can provision multiple SRS URIs, separated by comma. In this case, OpenSIPS +will try to use them in the same order specified, one by one, until +either one of them responds with a positive reply (200 OK), or the +response code is one of the codes matched by the *[skip failover codes](#param_skip_failover_codes)* regular expression. +In the latter case the call is not recorded at all. + + +### Limitations + + +This module only implements the SRC +specifications of the [SIPREC RFC](https://tools.ietf.org/html/rfc7866). In +order to have a full recording solution, you will also need a SRS solution +such as [Oreka](http://oreka.sourceforge.net/) - an +open-source project provided by [OrecX](http://www.orecx.com/). + + +Although this module provides all the necessary tools to do calls +recording, it does not fully implement the entire +*SIPREC* SRC specifications. This list contains +some of the module's limitations: + + +- *There is no Recording Indicator played to the +callee* - since OpenSIPS continues to act as a proxy, +there is no way for us to postpone the media between the caller +and callee to play a Recording Indicator message. +- *Cannot handle Recording Sessions initiated by +SRS* - we do not support the scenario when an SRS +suddenly decides to record a call in the middle of the dialog. +- *OpenSIPS cannot be "queried" for ongoing +recording sessions* - this is scheduled to be +implemented in further releases. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM* - Transaction module. +- *Dialog* - Dialog module for keeping track of the call. +- *RTP_Relay* - RTP Relay module used for controlling the +Media Servers that will fork the media. +- *B2B_ENTITIES* - Back-2-Back module used for communicating with the SRS. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### skip_failover_codes (string) + + +A regular expression used to specify the codes that should prevent +the module from failing over to a new SRS server. + + +*By default any negative reply generates a failover.* + + +```opensips title="Set skip_failover_codes parameter" +... +# do not failover on 408 reply codes +modparam("siprec", "skip_failover_codes", "408") + +# do not failover on 408 or 487 reply codes +modparam("siprec", "skip_failover_codes", "408|487") + +# do not failover on any 3xx or 4xx reply code +modparam("siprec", "skip_failover_codes", "[34][0-9][0-9]") +... + +``` + + +### Exported Events + + +#### E_SIPREC_START + + +This event is raised when a SIPREC call is established and a call +starts to be recorded. + + +Parameters: + + +- *dlg_id* - dialog id ("did") +of the call being recorded; +- *dlg_callid* - Call-Id of the call being +recorded; +- *callid* - Call-Id (B2B id) of the +SIPREC call; +- *session_id* - SIPREC UUID of the recording call; +- *server* - the SIPREC server handing this call; +- *instance* - the SIPREC instance this event is triggered for; + + +#### E_SIPREC_STOP + + +This event is raised when a SIPREC call is terminated. + + +This event exposes the same parameters as the +[E SIPREC START](#event_e_siprec_start) event. + + +### Exported Functions + + +#### siprec_start_recording(srs[, instance]) + + +Calling this function on an initial +*INVITE* engages call recording to SRS(s) for +that call. Note that it does not necessary mean that the call +will be recorded - it just means that OpenSIPS will query +instruct the SRS that a new call has started, but the SRS +might decide that the recording is disabled for those +participants. + + +> [!NOTE] +> The call recording is not +> started right away, but only when the callee provides an +> SDP as well (usually in a 200 OK, or possibly a 183 Ringing). + + +> [!Note] +> If you only want to start recording +> when the call is established (200 OK is received), then you +> should call this function in the onreply route processing that +> 200 OK. + + +Parameters: + + +- *srs* (string) - a comma-separated list of SRS +URIs. These URIs are used in the order specified. See +[siprec srs failover](#srs_failover) for more +information. +- *instance* (string, optional) - used to +start a particular SIPREC *instance*. +When missing, the *default* instance +is started. + + +The function returns false when an internal error is triggered +and the call recording setup fails. Otherwise, if all the +internal mechanisms are activated, it returns true. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="Use siprec_start_recording() function with a single SRS" + ... + if (!has_totag() && is_method("INVITE")) { + $var(srs) = "sip:127.0.0.1"; + xlog("Engage SIPREC call recording to $var(srs) for $ci\n"); + siprec_start_recording($var(srs)); + } + ... +``` + + +```opensips title="Use siprec_start_recording() function with multiple SRS servers" + ... + if (!has_totag() && is_method("INVITE")) { + $var(srs) = "sip:127.0.0.1, sip:127.0.0.1;transport=TCP"; + xlog("Engage SIPREC call recording to servers $var(srs) for $ci in inbound group\n"); + siprec_start_recording($var(srs), "inbound"); + } + ... +``` + + +```opensips title="Use siprec_start_recording() function with custom XML values for participants" + ... + $xml(caller_xml) = ""; + $xml(caller_xml/nameID.attr/aor) = "sip:6024151234@10.0.0.11:5090"; + $xml(caller_xml/nameID) = "test"; + $siprec(caller) = $xml(caller_xml/nameID); + siprec_start_recording($var(srs)); + ... +``` + + +```opensips title="Use siprec_start_recording() function with custom headers" + ... + $siprec(headers) = "X-MY-CUSTOM_HDR: 1\r\n"; + siprec_start_recording($var(srs)); + ... +``` + + +```opensips title="Use siprec_start_recording() function with custom group and session extensions" + ... + $var(temp) = " +``` + + +#### siprec_pause_recording([instance]) + + +Pauses the recording for the ongoing call. Should be called after +the dialog has matched. + + +Parameters: + + +- *instance* (string, optional) - used to +pause a particular SIPREC *instance*. +When missing, the *default* instance +is paused. + + +This function can be used from any route. + + +```opensips title="Use siprec_pause_recording()" + ... + if (has_totag() && is_method("INVITE")) { + if (is_audio_on_hold()) + siprec_pause_recording(); + } + ... +``` + + +#### siprec_resume_recording([instance]) + + +Resumes the recording for the ongoing call. Should be called after +the dialog has matched. + + +Parameters: + + +- *instance* (string, optional) - used to +resume a particular SIPREC *instance*. +When missing, the *default* instance +is resumed. + + +This function can be used from any route. + + +```opensips title="Use siprec_resume_recording()" + ... + if (has_totag() && is_method("INVITE")) { + if (!is_audio_on_hold()) + siprec_resume_recording(); + } + ... +``` + + +#### siprec_stop_recording([instance]) + + +Stops the recording for the ongoing call. Should be called for SIPREC +sessions that have been previously started. + + +Parameters: + + +- *instance* (string, optional) - used to +stop a particular SIPREC *instance*. +When missing, the *default* instance +is stopped. + + +This function can be used from any route. + + +```opensips title="Use siprec_stop_recording()" + ... + if (has_totag() && is_method("INVITE")) { + if (is_audio_on_hold()) + siprec_stop_recording(); + } + ... +``` + + +#### siprec_send_indialog([hdrs[, body]]) + + +Sends an arbitrary in-dialog request to the SRS. + + +This function can be used from any route. + + +Parameters: + + +- *headers* (string, optional) - a set of headers +that will be added to the generated request. +- *body* (string, optional) - the body that +will be added to the generated request. +- *instance* (string, optional) - used to +send a request within a particular SIPREC *instance*. +When missing, the request is sent in to the *default* +instance. + + +```opensips title="Use siprec_send_indialog()" + ... + if (has_totag() && is_method("INFO")) { + siprec_send_indialog("Content-Type: $hdr(Content-Type)\r\n", $rb); + } + ... +``` + + +### Exported Pseudo-Variables + + +#### $siprec + + +Used to modify/describe different siprec sessions +parameters that should be taken into account by the +[siprec start recording](#func_siprec_start_recording) function. + + +The variable can be indexed with the *instance* +the user wants to tune the variable for. If missing, the +the *default* instance is being altered. + + +The context of this variable is only limited to the current +message processed - it is not available at the transaction +or dialog level. + + +Any of this setting is optional. + + +Settings that can be provisioned: + + +- *group* - an opaque value that will be inserted +in the SIPREC body and represents the name of the group that can be +used to classify calls in certain profiles. If missing, no group is added. +- *caller* - an XML block containing information +about the caller. If absent, the *From* header +of the initial dialog is used to build the value. +- *callee* - an XML block containing information +about the callee. If absent, the *To* header +of the initial dialog is used to build the value. +- *media* - the IP that +RTPProxy will be streaming media from. If absent +*127.0.0.1* will be used. + > [!NOTE] + > *media_ip* has been dropped. +- *headers* - extra headers +that are to be added in the initial request towards the SRS. + > [!NOTE] + > Headers must be separated by + > *\r\n* and must end with *\r\n*. +- *socket* - listening socket that the outgoing +request towards SRS should be used. +- *from_uri* - the URI to appear in the +*From* header of the dialog. Default value is the +request URI. + > [!NOTE] + > This does not influence the + > *caller* information in the XML block, + > which is taken from the initial dialog. +- *to_uri* - the URI to appear in the +*To* header of the dialog. Default value is the +request URI. Note that this does not influence the +*callee* information in the XML block, +which is taken from the initial dialog. +- *group_custom_extension* - an optional XML block +containing custom information to be added under the +*group* tag. + > [!NOTE] + > If the *group* is absent this + > value will be ignored and not used anywhere. +- *session_custom_extension* - an optional XML block +containing custom information to be added under the +*session* tag. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/siprec/doc/contributors.xml b/modules/siprec/doc/contributors.xml deleted file mode 100644 index b9e377a6af0..00000000000 --- a/modules/siprec/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 193 - 101 - 6419 - 2268 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - 16 - 11 - 166 - 149 - - - 3. - Liviu Chircu (@liviuchircu) - 9 - 7 - 35 - 53 - - - 4. - Maksym Sobolyev (@sobomax) - 6 - 4 - 12 - 11 - - - 5. - Jupiter Tang - 5 - 3 - 13 - 3 - - - 6. - Seyed Mehran Siadati - 5 - 2 - 124 - 15 - - - 7. - Bogdan-Andrei Iancu (@bogdan-iancu) - 4 - 2 - 3 - 2 - - - 8. - Norman Brandinger (@NormB) - 3 - 1 - 4 - 4 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Jupiter Tang - Oct 2025 - Dec 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jun 2017 - Oct 2025 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 4. - Seyed Mehran Siadati - Nov 2023 - Nov 2023 - - - 5. - Liviu Chircu (@liviuchircu) - Apr 2018 - Aug 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - Feb 2018 - Mar 2023 - - - 7. - Norman Brandinger (@NormB) - Aug 2021 - Aug 2021 - - - 8. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2021 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Seyed Mehran Siadati, Norman Brandinger (@NormB), Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/siprec/doc/siprec.xml b/modules/siprec/doc/siprec.xml deleted file mode 100644 index 7369b47cda5..00000000000 --- a/modules/siprec/doc/siprec.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - SIPREC Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2017 &osipssol; - diff --git a/modules/siprec/doc/siprec_admin.xml b/modules/siprec/doc/siprec_admin.xml deleted file mode 100644 index f78f5d5c352..00000000000 --- a/modules/siprec/doc/siprec_admin.xml +++ /dev/null @@ -1,628 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides the means to do calls recording using an - external recorder - the entity that records the call is not in - the media path between the caller and callee, but it is completely - separate, thus it can not affect by any means the quality of the - conversation. This is done in a standardized manner, using - the SIPREC - Protocol, thus it can be used by any recorder that - implements this protocol. - - - Since an external server is used to record calls, there are no - constraints regarding the location of the recorder, thus it can be - placed arbitrary. This offers huge flexibility to your architecture - configuration and various means for scaling. - - - The work for this module has been sponsored by the OrecX Company. This module is - fully integrated with the OrecX Call Recording products. - -
- -
- How it works - - The full architecture of a SIP Media Recording platform is - documented in - RFC 7245. According to this architecture, this &osips; - module implements a SRC (Session Recording Client) that instructs a SRS - (Session Recording Server) when new calls are started, the - participants of the calls and their profiles. Based on this data, the - SRS can decide whether the call should be recorded or not. - - - From SIP signalling perspective, the module does not change the call - flow between the caller and callee. The call is established just as - any other calls that are not recorded. But for each call that has - SIPREC engaged, a completely separate SIP session - is started by the SRC (&osips;) towards the SRS, using the &osips; Back-2-Back module. The - INVITE message sent to the SRS contains a - multi-part body consisting of two parts: - - - - Recording SDP - the SDP of the Media Server - that will fork the RTP to the recorder. - - - - - Participants Metadata - an XML-formatted - document that contains information about the participants. The - structure of the document is detailed in RFC 7865. - - - - - - The SRS can respond with negative reply, indicating that the session - does not need to be recorded, or with a positive reply (200 OK), - indicating in the SDP body where the media RTP should be - sent/forked. When the call ends, the SRC must - send a BYE message to the SRS, indicating that - the recording should be completed. - - - Full examples of call flows can be found in RFC 8068. - -
- -
- Media Handling - - Since &osips; is a SIP Proxy, it does not have any Media Capabilities - by itself. Thus we need to rely on a different Media Server to capture - the RTP traffic and fork it to the SRS. The current implementation - supports both the RTPProxy - (through the RTPProxy module) and - RTPEngine - (through the RTEngine module) Media - Servers. - -
- -
- SRS Failover - - The siprec module supports failover between - multiple SRS servers - when calling the function, one - can provision multiple SRS URIs, separated by comma. In this case, &osips; - will try to use them in the same order specified, one by one, until - either one of them responds with a positive reply (200 OK), or the - response code is one of the codes matched by the regular expression. - In the latter case the call is not recorded at all. - -
- -
- Limitations - - This module only implements the SRC - specifications of the SIPREC RFC. In - order to have a full recording solution, you will also need a SRS solution - such as Oreka - an - open-source project provided by OrecX. - - - Although this module provides all the necessary tools to do calls - recording, it does not fully implement the entire - SIPREC SRC specifications. This list contains - some of the module's limitations: - - - - There is no Recording Indicator played to the - callee - since &osips; continues to act as a proxy, - there is no way for us to postpone the media between the caller - and callee to play a Recording Indicator message. - - - - - Cannot handle Recording Sessions initiated by - SRS - we do not support the scenario when an SRS - suddenly decides to record a call in the middle of the dialog. - - - - - &osips; cannot be queried for ongoing - recording sessions - this is scheduled to be - implemented in further releases. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction module. - - - - - Dialog - Dialog module for keeping track of the call. - - - - - RTP_Relay - RTP Relay module used for controlling the - Media Servers that will fork the media. - - - - - B2B_ENTITIES - Back-2-Back module used for communicating with the SRS. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters - -
- <varname>skip_failover_codes</varname> (string) - - A regular expression used to specify the codes that should prevent - the module from failing over to a new SRS server. - - - By default any negative reply generates a failover. - - - - Set <varname>skip_failover_codes</varname> parameter - -... -# do not failover on 408 reply codes -modparam("siprec", "skip_failover_codes", "408") - -# do not failover on 408 or 487 reply codes -modparam("siprec", "skip_failover_codes", "408|487") - -# do not failover on any 3xx or 4xx reply code -modparam("siprec", "skip_failover_codes", "[34][0-9][0-9]") -... - - - -
-
- -
- Exported Events -
- - <function moreinfo="none">E_SIPREC_START</function> - - - This event is raised when a SIPREC call is established and a call - starts to be recorded. - - Parameters: - - - dlg_id - dialog id (did) - of the call being recorded; - - - dlg_callid - Call-Id of the call being - recorded; - - - callid - Call-Id (B2B id) of the - SIPREC call; - - - session_id - SIPREC UUID of the recording call; - - - server - the SIPREC server handing this call; - - - instance - the SIPREC instance this event is triggered for; - - -
- -
- - <function moreinfo="none">E_SIPREC_STOP</function> - - - This event is raised when a SIPREC call is terminated. - - This event exposes the same parameters as the - event. - -
-
- -
- Exported Functions -
- - <function moreinfo="none">siprec_start_recording(srs[, instance])</function> - - - Calling this function on an initial - INVITE engages call recording to SRS(s) for - that call. Note that it does not necessary mean that the call - will be recorded - it just means that &osips; will query - instruct the SRS that a new call has started, but the SRS - might decide that the recording is disabled for those - participants. - - - Note that the call recording is not - started right away, but only when the callee provides an - SDP as well (usually in a 200 OK, or possibly a 183 Ringing). - - - Note if you only want to start recording - when the call is established (200 OK is received), then you - should call this function in the onreply route processing that - 200 OK. - - - Parameters: - - - srs (string) - a comma-separated list of SRS - URIs. These URIs are used in the order specified. See - for more - information. - - - instance (string, optional) - used to - start a particular SIPREC instance. - When missing, the default instance - is started. - - - - - The function returns false when an internal error is triggered - and the call recording setup fails. Otherwise, if all the - internal mechanisms are activated, it returns true. - - - This function can be used from REQUEST_ROUTE. - - - Use <function>siprec_start_recording()</function> function with a single SRS - - ... - if (!has_totag() && is_method("INVITE")) { - $var(srs) = "sip:127.0.0.1"; - xlog("Engage SIPREC call recording to $var(srs) for $ci\n"); - siprec_start_recording($var(srs)); - } - ... - - - - - Use <function>siprec_start_recording()</function> function with multiple SRS servers - - ... - if (!has_totag() && is_method("INVITE")) { - $var(srs) = "sip:127.0.0.1, sip:127.0.0.1;transport=TCP"; - xlog("Engage SIPREC call recording to servers $var(srs) for $ci in inbound group\n"); - siprec_start_recording($var(srs), "inbound"); - } - ... - - - - - Use <function>siprec_start_recording()</function> function with custom XML values for participants - - ... - $xml(caller_xml) = "<nameID></nameID>"; - $xml(caller_xml/nameID.attr/aor) = "sip:6024151234@10.0.0.11:5090"; - $xml(caller_xml/nameID) = "<name>test</name>"; - $siprec(caller) = $xml(caller_xml/nameID); - siprec_start_recording($var(srs)); - ... - - - - - Use <function>siprec_start_recording()</function> function with custom headers - - ... - $siprec(headers) = "X-MY-CUSTOM_HDR: 1\r\n"; - siprec_start_recording($var(srs)); - ... - - - - - Use <function>siprec_start_recording()</function> function with custom group and session extensions - - ... - $var(temp) = " 17"; - $siprec(group_custom_extension) = $var(temp); - $siprec(session_custom_extension) = "dfgh3q45gsdfty5"; - - siprec_start_recording($var(srs)); - ... - - -
-
- - <function moreinfo="none">siprec_pause_recording([instance])</function> - - - Pauses the recording for the ongoing call. Should be called after - the dialog has matched. - - - Parameters: - - - instance (string, optional) - used to - pause a particular SIPREC instance. - When missing, the default instance - is paused. - - - - - This function can be used from any route. - - - Use <function>siprec_pause_recording()</function> - - ... - if (has_totag() && is_method("INVITE")) { - if (is_audio_on_hold()) - siprec_pause_recording(); - } - ... - - -
-
- - <function moreinfo="none">siprec_resume_recording([instance])</function> - - - Resumes the recording for the ongoing call. Should be called after - the dialog has matched. - - - Parameters: - - - instance (string, optional) - used to - resume a particular SIPREC instance. - When missing, the default instance - is resumed. - - - - - This function can be used from any route. - - - Use <function>siprec_resume_recording()</function> - - ... - if (has_totag() && is_method("INVITE")) { - if (!is_audio_on_hold()) - siprec_resume_recording(); - } - ... - - -
-
- - <function moreinfo="none">siprec_stop_recording([instance])</function> - - - Stops the recording for the ongoing call. Should be called for SIPREC - sessions that have been previously started. - - - Parameters: - - - instance (string, optional) - used to - stop a particular SIPREC instance. - When missing, the default instance - is stopped. - - - - - This function can be used from any route. - - - Use <function>siprec_stop_recording()</function> - - ... - if (has_totag() && is_method("INVITE")) { - if (is_audio_on_hold()) - siprec_stop_recording(); - } - ... - - -
-
- - <function moreinfo="none">siprec_send_indialog([hdrs[, body]])</function> - - - Sends an arbitrary in-dialog request to the SRS. - - - This function can be used from any route. - - - Parameters: - - - headers (string, optional) - a set of headers - that will be added to the generated request. - - - body (string, optional) - the body that - will be added to the generated request. - - - instance (string, optional) - used to - send a request within a particular SIPREC instance. - When missing, the request is sent in to the default - instance. - - - - - Use <function>siprec_send_indialog()</function> - - ... - if (has_totag() && is_method("INFO")) { - siprec_send_indialog("Content-Type: $hdr(Content-Type)\r\n", $rb); - } - ... - - -
-
- -
- Exported Pseudo-Variables -
- <varname>$siprec</varname> - - Used to modify/describe different siprec sessions - parameters that should be taken into account by the - function. - - - The variable can be indexed with the instance - the user wants to tune the variable for. If missing, the - the default instance is being altered. - - - The context of this variable is only limited to the current - message processed - it is not available at the transaction - or dialog level. - - - Any of this setting is optional. - - - Settings that can be provisioned: - - - - group - an opaque value that will be inserted - in the SIPREC body and represents the name of the group that can be - used to classify calls in certain profiles. If missing, no group is added. - - - caller - an XML block containing information - about the caller. If absent, the From header - of the initial dialog is used to build the value. - - - callee - an XML block containing information - about the callee. If absent, the To header - of the initial dialog is used to build the value. - - - media - the IP that - RTPProxy will be streaming media from. If absent - 127.0.0.1 will be used. - NOTE:media_ip has been dropped. - - - headers - extra headers - that are to be added in the initial request towards the SRS. - NOTE: headers must be separated by - \r\n and must end with \r\n. - - - socket - listening socket that the outgoing - request towards SRS should be used. - - - from_uri - the URI to appear in the - From header of the dialog. Default value is the - request URI. Note that this does not influence the - caller information in the XML block, - which is taken from the initial dialog. - - - to_uri - the URI to appear in the - To header of the dialog. Default value is the - request URI. Note that this does not influence the - callee information in the XML block, - which is taken from the initial dialog. - - - group_custom_extension - an optional XML block - containing custom information to be added under the - group tag. - NOTE: if the group is absent this - value will be ignored and not used anywhere. - - - session_custom_extension - an optional XML block - containing custom information to be added under the - session tag. - - -
- -
- -
diff --git a/modules/siprec/siprec_logic.c b/modules/siprec/siprec_logic.c index 80c104c0689..b53fe8384ea 100644 --- a/modules/siprec/siprec_logic.c +++ b/modules/siprec/siprec_logic.c @@ -201,7 +201,7 @@ static void dlg_src_unref_session(void *p) { struct src_sess *ss = (struct src_sess *)p; /* if the dialog is not in termination state, we should not delete it */ - if (ss->ctx->dlg->state < DLG_STATE_DELETED) + if (ss->ctx->dlg && ss->ctx->dlg->state < DLG_STATE_DELETED) return; srec_hlog(ss, SREC_UNREF, "dlg recording unref"); SIPREC_UNREF(ss); @@ -370,6 +370,8 @@ static int srec_b2b_notify(struct sip_msg *msg, str *key, int type, * ongoing media sessions */ if (ss->flags & SIPREC_ONGOING) return 0; + if (!ss->ctx->dlg || ss->ctx->dlg->state >= DLG_STATE_DELETED) + return 0; if (srs_skip_failover(msg->first_line.u.reply.status) || srs_do_failover(ss) < 0) { LM_DBG("no more to failover!\n"); @@ -398,7 +400,7 @@ static int srec_b2b_notify(struct sip_msg *msg, str *key, int type, goto no_recording; } - if (ss->ctx->dlg->state >= DLG_STATE_DELETED) { + if (!ss->ctx->dlg || ss->ctx->dlg->state >= DLG_STATE_DELETED) { LM_ERR("dialog already in deleted state!\n"); goto no_recording; } @@ -429,16 +431,18 @@ static int srec_b2b_notify(struct sip_msg *msg, str *key, int type, LM_ERR("Cannot send bye for recording session with key %.*s\n", req.b2b_key->len, req.b2b_key->s); } - if (ss->ctx->dlg->state >= DLG_STATE_DELETED) - LM_DBG("rtp context already destroyed!\n"); - else - srec_rtp.copy_delete(ss->ctx->rtp, &ss->instance, &ss->media); + if (ss->ctx->dlg) { + if (ss->ctx->dlg->state >= DLG_STATE_DELETED) + LM_DBG("rtp context=%p already destroyed dlg=%p!\n", ss->ctx, ss->ctx->dlg); + else + srec_rtp.copy_delete(ss->ctx->rtp, &ss->instance, &ss->media); + } if (ss->flags & SIPREC_STARTED) raise_siprec_stop_event(ss); srec_logic_destroy(ss, 0); - if (!(ss->flags & SIPREC_DLG_CBS)) { + if (ss->ctx->dlg && !(ss->flags & SIPREC_DLG_CBS)) { /* if the dialog has already been engaged, then we need to keep the * reference until the end of the dialog, where it will be cleaned up */ srec_dlg.dlg_ctx_put_ptr(ss->ctx->dlg, srec_dlg_idx, NULL); @@ -497,6 +501,9 @@ static int srs_send_invite(struct src_sess *sess) "Content-Type: multipart/mixed;boundary=" OSS_BOUNDARY CRLF ); + if (!sess->initial_sdp.s) + return 0; + memset(&ci, 0, sizeof ci); ci.method.s = INVITE; ci.method.len = INVITE_LEN; diff --git a/modules/siprec/siprec_sess.c b/modules/siprec/siprec_sess.c index 1235f01620a..822414aa7af 100644 --- a/modules/siprec/siprec_sess.c +++ b/modules/siprec/siprec_sess.c @@ -809,6 +809,21 @@ struct src_ctx *src_get_ctx(struct dlg_cell *dlg) return (struct src_ctx *)srec_dlg.dlg_ctx_get_ptr(dlg, srec_dlg_idx); } +static void srec_dlg_destroy(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) +{ + struct src_ctx *ctx; + + if (!_params) { + LM_ERR("no parameter specified to dlg callback!\n"); + return; + } + ctx = *_params->param; + /* dialog is going to be removed, so we drop it from the structure */ + LM_DBG("resetting ctx=%p dlg=%p\n", ctx, ctx->dlg); + ctx->dlg = NULL; +} + + struct src_ctx *src_new_ctx(struct dlg_cell *dlg) { rtp_ctx *rtp; @@ -840,6 +855,13 @@ struct src_ctx *src_new_ctx(struct dlg_cell *dlg) ctx->dlg = dlg; ctx->rtp = rtp; + if (srec_dlg.register_dlgcb(ctx->dlg, DLGCB_DESTROY, + srec_dlg_destroy, ctx, NULL)){ + LM_ERR("cannot register callback for dialog destruction\n"); + shm_free(ctx); + return NULL; + } + srec_dlg.dlg_ctx_put_ptr(dlg, srec_dlg_idx, ctx); return ctx; diff --git a/modules/sl/README b/modules/sl/README deleted file mode 100644 index 2541cf92467..00000000000 --- a/modules/sl/README +++ /dev/null @@ -1,266 +0,0 @@ -sl Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. enable_stats (integer) - - 1.4. Exported Functions - - 1.4.1. sl_send_reply(code, reason) - 1.4.2. sl_reply_error() - - 1.5. Exported Statistics - - 1.5.1. 1xx_replies - 1.5.2. 2xx_replies - 1.5.3. 3xx_replies - 1.5.4. 4xx_replies - 1.5.5. 5xx_replies - 1.5.6. 6xx_replies - 1.5.7. sent_replies - 1.5.8. sent_err_replies - 1.5.9. received_ACKs - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. enable_stats example - 1.2. sl_send_reply usage - 1.3. sl_reply_error usage - -Chapter 1. Admin Guide - -1.1. Overview - - The SL module allows OpenSIPS to act as a stateless UA server - and generate replies to SIP requests without keeping state. - That is beneficial in many scenarios, in which you wish not to - burden server's memory and scale well. - - The SL module needs to filter ACKs sent after a local stateless - reply to an INVITE was generated. To recognize such ACKs, - OpenSIPS adds a special "signature" in to-tags. This signature - is sought for in incoming ACKs, and if included, the ACKs are - absorbed. - - To speed up the filtering process, the module uses a timeout - mechanism. When a reply is sent, a timer is set. As time as the - timeout didn't hit, the incoming ACK requests will be checked - using TO tag value. Once the timer expires, all the ACK are let - through - a long time passed till it sent a reply, so it does - not expect any ACK that have to be blocked. - - The ACK filtering may fail in some rare cases. If you think - these matter to you, better use stateful processing (tm module) - for INVITE processing. Particularly, the problem happens when a - UA sends an INVITE which already has a to-tag in it (e.g., a - re-INVITE) and OpenSIPS want to reply to it. Than, it will keep - the current to-tag, which will be mirrored in ACK. OpenSIPS - will not see its signature and forward the ACK downstream. - Caused harm is not bad--just a useless ACK is forwarded. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. enable_stats (integer) - - If the module should generate and export statistics to the core - manager. A zero value means disabled. - - SL module provides statistics about how many replies were sent - ( splitted per code classes) and how many local ACKs were - filtered out. - - Default value is 1 (enabled). - - Example 1.1. enable_stats example -modparam("sl", "enable_stats", 0) - -1.4. Exported Functions - -1.4.1. sl_send_reply(code, reason) - - For the current request, a reply is sent back having the given - code and text reason. The reply is sent stateless, totally - independent of the Transaction module and with no - retransmission for the INVITE's replies. 'code' and 'reason' - can contain pseudo-variables that are replaced at runtime. - - Meaning of the parameters is as follows: - * code (int) - Return code. - * reason (string) - Reason phrase. - - This function can be used from REQUEST_ROUTE, ERROR_ROUTE. - - Example 1.2. sl_send_reply usage -... -sl_send_reply(404, "Not found"); -... -sl_send_reply($err.rcode, $err.rreason); -... - -1.4.2. sl_reply_error() - - Sends back an error reply describing the nature of the last - internal error. Usually this function should be used after a - script function that returned an error code. - - This function can be used from REQUEST_ROUTE. - - Example 1.3. sl_reply_error usage -... -sl_reply_error(); -... - -1.5. Exported Statistics - -1.5.1. 1xx_replies - - The number of 1xx_replies. - -1.5.2. 2xx_replies - - The number of 2xx_replies. - -1.5.3. 3xx_replies - - The number of 3xx_replies. - -1.5.4. 4xx_replies - - The number of 4xx_replies. - -1.5.5. 5xx_replies - - The number of 5xx_replies. - -1.5.6. 6xx_replies - - The number of 6xx_replies. - -1.5.7. sent_replies - - The number of sent_replies. - -1.5.8. sent_err_replies - - The number of sent_err_replies. - -1.5.9. received_ACKs - - The number of received_ACKs. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 75 55 884 711 - 2. Jiri Kuthan (@jiriatipteldotorg) 42 32 665 232 - 3. Daniel-Constantin Mierla (@miconda) 22 16 295 172 - 4. Andrei Pelinescu-Onciul 16 14 50 50 - 5. Liviu Chircu (@liviuchircu) 13 10 28 62 - 6. Jan Janak (@janakj) 12 8 355 21 - 7. Henning Westerholt (@henningw) 7 5 12 12 - 8. Razvan Crainea (@razvancrainea) 7 5 12 11 - 9. Vlad Patrascu (@rvlad-patrascu) 7 4 30 83 - 10. Maksym Sobolyev (@sobomax) 5 3 8 9 - - All remaining contributors: Elena-Ramona Modroiu, Jeffrey - Magder, Andreas Heise, Konstantin Bokarius, Anca Vamanu, Ionut - Ionita (@ionutrazvanionita), Peter Lemenkov (@lemenkov), Edson - Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2002 - Apr 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2020 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Ionut Ionita (@ionutrazvanionita) Nov 2014 - Nov 2014 - 8. Anca Vamanu Nov 2010 - Nov 2010 - 9. Henning Westerholt (@henningw) Aug 2007 - Jun 2008 - 10. Daniel-Constantin Mierla (@miconda) Apr 2006 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Andreas Heise, Elena-Ramona Modroiu, Jeffrey Magder, - Jiri Kuthan (@jiriatipteldotorg), Jan Janak (@janakj), Andrei - Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu - (@bogdan-iancu), Razvan Crainea (@razvancrainea), Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona - Modroiu, Jan Janak (@janakj). - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/sl/README.md b/modules/sl/README.md new file mode 100644 index 00000000000..eb7193f93fb --- /dev/null +++ b/modules/sl/README.md @@ -0,0 +1,195 @@ +--- +title: "sl Module" +description: "The SL module allows OpenSIPS to act as a stateless UA server and generate replies to SIP requests without keeping state." +--- + +## Admin Guide + + +### Overview + + +The SL module allows OpenSIPS to act as a stateless +UA server and generate replies to SIP requests without keeping +state. That is beneficial in many scenarios, in which you wish not to +burden server's memory and scale well. + + +The SL module needs to filter ACKs sent after a +local stateless reply to an INVITE was generated. To recognize such +ACKs, OpenSIPS adds a special "signature" in to-tags. This signature is +sought for in incoming ACKs, and if included, the ACKs are absorbed. + + +To speed up the filtering process, the module uses a timeout +mechanism. When a reply is sent, a timer is set. As time as the timeout +didn't hit, the incoming ACK requests will be checked using TO tag +value. Once the timer expires, all the ACK are let through - a long +time passed till it sent a reply, so it does not expect any ACK that +have to be blocked. + + +The ACK filtering may fail in some rare cases. If you think these +matter to you, better use stateful processing (tm module) for INVITE +processing. Particularly, the problem happens when a UA sends an +INVITE which already has a to-tag in it (e.g., a re-INVITE) +and OpenSIPS want to reply to it. Than, it will keep the current to-tag, +which will be mirrored in ACK. OpenSIPS will not see its signature and +forward the ACK downstream. Caused harm is not bad--just a useless +ACK is forwarded. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### enable_stats (integer) + + +If the module should generate and export statistics to the core +manager. A zero value means disabled. + + +SL module provides statistics about how many replies were sent ( +splitted per code classes) and how many local ACKs were filtered out. + + +Default value is 1 (enabled). + + +```opensips title="enable_stats example" +modparam("sl", "enable_stats", 0) +``` + + +### Exported Functions + + +#### sl_send_reply(code, reason) + + +For the current request, a reply is sent back having the given code +and text reason. The reply is sent stateless, totally independent of +the Transaction module and with no retransmission for the INVITE's +replies. 'code' and 'reason' can contain pseudo-variables that are +replaced at runtime. + + +Meaning of the parameters is as follows: + + +- *code (int)* - Return code. +- *reason (string)* - Reason phrase. + + +This function can be used from REQUEST_ROUTE, ERROR_ROUTE. + + +```opensips title="sl_send_reply usage" +... +sl_send_reply(404, "Not found"); +... +sl_send_reply($err.rcode, $err.rreason); +... +``` + + +#### sl_reply_error() + + +Sends back an error reply describing the nature of the last internal +error. Usually this function should be used after a script function +that returned an error code. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="sl_reply_error usage" +... +sl_reply_error(); +... +``` + + +### Exported Statistics + + +#### 1xx_replies + + +The number of 1xx_replies. + + +#### 2xx_replies + + +The number of 2xx_replies. + + +#### 3xx_replies + + +The number of 3xx_replies. + + +#### 4xx_replies + + +The number of 4xx_replies. + + +#### 5xx_replies + + +The number of 5xx_replies. + + +#### 6xx_replies + + +The number of 6xx_replies. + + +#### sent_replies + + +The number of sent_replies. + + +#### sent_err_replies + + +The number of sent_err_replies. + + +#### received_ACKs + + +The number of received_ACKs. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sl/doc/contributors.xml b/modules/sl/doc/contributors.xml deleted file mode 100644 index c2c538903ab..00000000000 --- a/modules/sl/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 75 - 55 - 884 - 711 - - - 2. - Jiri Kuthan (@jiriatipteldotorg) - 42 - 32 - 665 - 232 - - - 3. - Daniel-Constantin Mierla (@miconda) - 22 - 16 - 295 - 172 - - - 4. - Andrei Pelinescu-Onciul - 16 - 14 - 50 - 50 - - - 5. - Liviu Chircu (@liviuchircu) - 13 - 10 - 28 - 62 - - - 6. - Jan Janak (@janakj) - 12 - 8 - 355 - 21 - - - 7. - Henning Westerholt (@henningw) - 7 - 5 - 12 - 12 - - - 8. - Razvan Crainea (@razvancrainea) - 7 - 5 - 12 - 11 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 7 - 4 - 30 - 83 - - - 10. - Maksym Sobolyev (@sobomax) - 5 - 3 - 8 - 9 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Jeffrey Magder, Andreas Heise, Konstantin Bokarius, Anca Vamanu, Ionut Ionita (@ionutrazvanionita), Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2002 - Apr 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2020 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Ionut Ionita (@ionutrazvanionita) - Nov 2014 - Nov 2014 - - - 8. - Anca Vamanu - Nov 2010 - Nov 2010 - - - 9. - Henning Westerholt (@henningw) - Aug 2007 - Jun 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - Apr 2006 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Andreas Heise, Elena-Ramona Modroiu, Jeffrey Magder, Jiri Kuthan (@jiriatipteldotorg), Jan Janak (@janakj), Andrei Pelinescu-Onciul. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Jan Janak (@janakj). -
- -
diff --git a/modules/sl/doc/sl.xml b/modules/sl/doc/sl.xml deleted file mode 100644 index 8bc325b61ed..00000000000 --- a/modules/sl/doc/sl.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - sl Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - diff --git a/modules/sl/doc/sl_admin.xml b/modules/sl/doc/sl_admin.xml deleted file mode 100644 index ebb6b508a99..00000000000 --- a/modules/sl/doc/sl_admin.xml +++ /dev/null @@ -1,216 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The SL module allows &osips; to act as a stateless - &ua; server and generate replies to &sip; requests without keeping - state. That is beneficial in many scenarios, in which you wish not to - burden server's memory and scale well. - - - The SL module needs to filter ACKs sent after a - local stateless reply to an INVITE was generated. To recognize such - ACKs, &osips; adds a special "signature" in to-tags. This signature is - sought for in incoming ACKs, and if included, the ACKs are absorbed. - - - To speed up the filtering process, the module uses a timeout - mechanism. When a reply is sent, a timer is set. As time as the timeout - didn't hit, the incoming ACK requests will be checked using TO tag - value. Once the timer expires, all the ACK are let through - a long - time passed till it sent a reply, so it does not expect any ACK that - have to be blocked. - - - The ACK filtering may fail in some rare cases. If you think these - matter to you, better use stateful processing (tm module) for INVITE - processing. Particularly, the problem happens when a UA sends an - INVITE which already has a to-tag in it (e.g., a re-INVITE) - and &osips; want to reply to it. Than, it will keep the current to-tag, - which will be mirrored in ACK. &osips; will not see its signature and - forward the ACK downstream. Caused harm is not bad--just a useless - ACK is forwarded. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>enable_stats</varname> (integer) - - If the module should generate and export statistics to the core - manager. A zero value means disabled. - - - SL module provides statistics about how many replies were sent ( - splitted per code classes) and how many local ACKs were filtered out. - - - Default value is 1 (enabled). - - - enable_stats example - -modparam("sl", "enable_stats", 0) - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">sl_send_reply(code, reason)</function> - - - For the current request, a reply is sent back having the given code - and text reason. The reply is sent stateless, totally independent of - the Transaction module and with no retransmission for the INVITE's - replies. 'code' and 'reason' can contain pseudo-variables that are - replaced at runtime. - - Meaning of the parameters is as follows: - - - code (int) - Return code. - - - - reason (string) - Reason phrase. - - - - - This function can be used from REQUEST_ROUTE, ERROR_ROUTE. - - - <function>sl_send_reply</function> usage - -... -sl_send_reply(404, "Not found"); -... -sl_send_reply($err.rcode, $err.rreason); -... - - -
- -
- - <function moreinfo="none">sl_reply_error()</function> - - - Sends back an error reply describing the nature of the last internal - error. Usually this function should be used after a script function - that returned an error code. - - - This function can be used from REQUEST_ROUTE. - - - <function>sl_reply_error</function> usage - -... -sl_reply_error(); -... - - -
-
- -
- Exported Statistics -
- <varname>1xx_replies</varname> - - The number of 1xx_replies. - -
-
- <varname>2xx_replies</varname> - - The number of 2xx_replies. - -
-
- <varname>3xx_replies</varname> - - The number of 3xx_replies. - -
-
- <varname>4xx_replies</varname> - - The number of 4xx_replies. - -
-
- <varname>5xx_replies</varname> - - The number of 5xx_replies. - -
-
- <varname>6xx_replies</varname> - - The number of 6xx_replies. - -
-
- <varname>sent_replies</varname> - - The number of sent_replies. - -
-
- <varname>sent_err_replies</varname> - - The number of sent_err_replies. - -
-
- <varname>received_ACKs</varname> - - The number of received_ACKs. - -
-
- -
- diff --git a/modules/sngtc/README b/modules/sngtc/README deleted file mode 100644 index 7ba58354d5f..00000000000 --- a/modules/sngtc/README +++ /dev/null @@ -1,234 +0,0 @@ -sngtc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Functions - - 1.4.1. sngtc_offer() - 1.4.2. sngtc_callee_answer([listen_if_A], - [listen_if_B]) - - 1.4.3. sngtc_caller_answer() - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. sngtc_offer usage - 1.2. sngtc_callee_answer usage - 1.3. sngtc_caller_answer usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Sangoma transcoding module offers the possibility of - performing voice transcoding with the D-series transcoding - cards manufactured by Sangoma. The module makes use of the - Sangoma Transcoding API in order to manage transcoding sessions - on the dedicated equipment. For the cards in the network to be - detected, the Sangoma SOAP server must be up and running - (sngtc_server daemon). - -1.2. How it works - - The module performs several modifications in the SDP body of - SIP INVITE, 200 OK and ACK messages. In all transcoding - scenarios, the UAC performs early SDP negotiation, while the - UAS does late negotiation. This way, OpenSIPS becomes - responsible for intersecting the codec offer and answer, - together with the management of transcoding sessions on the - Sangoma cards. - - This scenario brings about a couple of restrictions: - * UACs MUST only perform early SDP negotiation - * UASs MUST support late SDP negotiation (rfc 3261 - requirement) - - Since the sngtc_node library performs several memory - allocations with each newly created transcoding session, the - module uses a dedicated process, responsible for the management - of the above-mentioned sessions. The sangoma_worker process - communicates with the OpenSIPS UDP receivers through a series - of pipes. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * sngtc_node library - download from Sangoma, unpack, make, - make install (required in order to compile this module). - * sngtc_server up and running (required in order for this - module to properly work). - -1.4. Exported Functions - -1.4.1. sngtc_offer() - - The function strips off the SDP offer from a SIP INVITE, thus - asking for another SDP offer from the opposite endpoint (late - negotiation). - - The following error codes may be returned: - * -1 - SDP parsing error - * -3 - internal error / no more memory - - The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.1. sngtc_offer usage -... - if (is_method("INVITE")) { - t_newtran(); - create_dialog(); - sngtc_offer(); - } -... - -1.4.2. sngtc_callee_answer([listen_if_A], [listen_if_B]) - - Handles the SDP offer from 200 OK responses, intersects both - offers with the capabilities of the transcoding card and - creates a new transcoding session on the card only if - necessary. It then rewrites the 200 OK SDP so that it contains - the information resulted from the codec intersection. - - Parameters explained: - - Since the D-series transcoding cards are connected through - either a PCI slot or simply an Ethernet connector, they cannot - be assigned global IPs. Consequently, the module will write the - local, private IP of the card in the SDP answers sent to each - of the endpoints. Since this will not work with non-local UAs, - the optional parameters force the RTP listen interface for each - UA. This way, the script writer can enforce a global IP for the - incoming RTP (which can be port forwarded to a transcoding - card). - * listen_if_A (string) - the interface where the UAC (the - caller) will send RTP after the call is established (IP - from the 'c=' SDP line(s)) - * listen_if_B (string) - the interface where the UAS (the - callee) will send RTP after the call is established (IP - from the 'c=' SDP line(s)) - - The following error codes may be returned: - * -1 - SDP parsing error - * -2 - failed to create transcoding session - * -3 - internal error / no more memory - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.2. sngtc_callee_answer usage -... -onreply_route[1] { - if ($rs == 200) - sngtc_callee_answer("11.12.13.14", "11.12.13.14"); -} -... - -1.4.3. sngtc_caller_answer() - - Attaches an SDP body to the caller's ACK request, so that it - matches the late SDP negotiation done by the UAS. - - The following error codes may be returned: - * -3 - internal error / no more memory - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - Example 1.3. sngtc_caller_answer usage -... - if (has_totag()) { - if (loose_route()) { - ... - if (is_method("ACK")) - sngtc_caller_answer(); - } - ... - } -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 33 14 2076 59 - 2. Razvan Crainea (@razvancrainea) 9 7 15 12 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 9 6 29 64 - 4. Vlad Patrascu (@rvlad-patrascu) 7 5 57 44 - 5. Maksym Sobolyev (@sobomax) 4 2 5 5 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Mar 2020 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Feb 2020 - 5. Liviu Chircu (@liviuchircu) Aug 2013 - Jun 2018 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu - (@liviuchircu), Peter Lemenkov (@lemenkov). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com diff --git a/modules/sngtc/README.md b/modules/sngtc/README.md new file mode 100644 index 00000000000..d5b7eef4ce7 --- /dev/null +++ b/modules/sngtc/README.md @@ -0,0 +1,180 @@ +--- +title: "sngtc Module" +description: "The **Sangoma transcoding module** offers the possibility of performing voice transcoding with the [D-series transcoding cards manufactured by Sangoma](https://wiki.sangoma.com/display/MTC/Media+Transcoding)." +--- + +## Admin Guide + + +### Overview + + +The **Sangoma transcoding module** offers the +possibility of performing voice transcoding with the +[D-series +transcoding cards manufactured by Sangoma](https://wiki.sangoma.com/display/MTC/Media+Transcoding). The module makes use +of the Sangoma Transcoding API in order to +manage transcoding sessions on the dedicated equipment. For the cards +in the network to be detected, the Sangoma SOAP server must be up and +running (*sngtc_server* daemon). + + +### How it works + + +The module performs several modifications in the SDP body of SIP INVITE, +200 OK and ACK messages. In all transcoding scenarios, the UAC performs early +SDP negotiation, while the UAS does late negotiation. This way, OpenSIPS +becomes responsible for intersecting the codec offer and answer, together with +the management of transcoding sessions on the Sangoma cards. + + +This scenario brings about a couple of +**restrictions**: + + +- UACs MUST only perform early SDP negotiation +- UASs MUST support late SDP negotiation (rfc 3261 requirement) + + +Since the *sngtc_node* library performs several memory +allocations with each newly created transcoding session, the module uses a +dedicated process, responsible for the management of the above-mentioned sessions. The +*sangoma_worker* process communicates with the OpenSIPS +UDP receivers through a series of pipes. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *dialog*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *sngtc_node library - [download from Sangoma](https://wiki.freepbx.org/display/MTC/Media+Transcoding+Download), +unpack, make, make install (required in order to compile this module)*. +- *sngtc_server up and running (required in order for +this module to properly work)*. + + +### Exported Functions + + +#### sngtc_offer() + + +The function strips off the SDP offer from a SIP INVITE, thus +asking for another SDP offer from the opposite endpoint (late negotiation). + +The following **error codes** may be returned: + + +- *-1* - SDP parsing error +- *-3* - internal error / no more memory + + +The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="sngtc_offer usage" +... + if (is_method("INVITE")) { + t_newtran(); + create_dialog(); + sngtc_offer(); + } +... +``` + + +#### sngtc_callee_answer([listen_if_A], [listen_if_B]) + + +Handles the SDP offer from 200 OK responses, intersects both offers with +the capabilities of the transcoding card and creates a new transcoding +session on the card **only if** necessary. It then rewrites the 200 OK SDP so that it +contains the information resulted from the codec intersection. + + +**Parameters** explained: + + +Since the D-series transcoding cards are connected through either a +PCI slot or simply an Ethernet connector, they cannot be assigned +global IPs. Consequently, the module will write the local, private IP of the +card in the SDP answers sent to each of the endpoints. Since this will not +work with non-local UAs, the optional parameters force the RTP listen +interface for each UA. This way, the script writer can enforce a global IP +for the incoming RTP (which can be port forwarded to a transcoding card). + + +- *listen_if_A* (string) - the interface where the UAC (the caller) will send RTP after the call is established (IP from the 'c=' SDP line(s)) +- *listen_if_B* (string) - the interface where the UAS (the callee) will send RTP after the call is established (IP from the 'c=' SDP line(s)) + + +The following **error codes** may be returned: + + +- *-1* - SDP parsing error +- *-2* - failed to create transcoding session +- *-3* - internal error / no more memory + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="sngtc_callee_answer usage" +... +onreply_route[1] { + if ($rs == 200) + sngtc_callee_answer("11.12.13.14", "11.12.13.14"); +} +... +``` + + +#### sngtc_caller_answer() + + +Attaches an SDP body to the caller's ACK request, so that it matches +the late SDP negotiation done by the UAS. + + +The following **error codes** may be returned: + + +- *-3* - internal error / no more memory + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. + + +```opensips title="sngtc_caller_answer usage" +... + if (has_totag()) { + if (loose_route()) { + ... + if (is_method("ACK")) + sngtc_caller_answer(); + } + ... + } +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sngtc/doc/contributors.xml b/modules/sngtc/doc/contributors.xml deleted file mode 100644 index d48c8bbf436..00000000000 --- a/modules/sngtc/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 33 - 14 - 2076 - 59 - - - 2. - Razvan Crainea (@razvancrainea) - 9 - 7 - 15 - 12 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 9 - 6 - 29 - 64 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 7 - 5 - 57 - 44 - - - 5. - Maksym Sobolyev (@sobomax) - 4 - 2 - 5 - 5 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Mar 2020 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Feb 2020 - - - 5. - Liviu Chircu (@liviuchircu) - Aug 2013 - Jun 2018 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov). -
- -
diff --git a/modules/sngtc/doc/sngtc.xml b/modules/sngtc/doc/sngtc.xml deleted file mode 100644 index 4c0655512e6..00000000000 --- a/modules/sngtc/doc/sngtc.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - sngtc Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - - diff --git a/modules/sngtc/doc/sngtc_admin.xml b/modules/sngtc/doc/sngtc_admin.xml deleted file mode 100644 index db097279a35..00000000000 --- a/modules/sngtc/doc/sngtc_admin.xml +++ /dev/null @@ -1,247 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Sangoma transcoding module offers the - possibility of performing voice transcoding with the - D-series - transcoding cards manufactured by Sangoma. The module makes use - of the Sangoma Transcoding API in order to - manage transcoding sessions on the dedicated equipment. For the cards - in the network to be detected, the Sangoma SOAP server must be up and - running (sngtc_server daemon). - -
- -
- How it works - - The module performs several modifications in the SDP body of SIP INVITE, - 200 OK and ACK messages. In all transcoding scenarios, the UAC performs early - SDP negotiation, while the UAS does late negotiation. This way, OpenSIPS - becomes responsible for intersecting the codec offer and answer, together with - the management of transcoding sessions on the Sangoma cards. - - - - This scenario brings about a couple of - restrictions: - - - - UACs MUST only perform early SDP negotiation - - - - - UASs MUST support late SDP negotiation (rfc 3261 requirement) - - - - - - - Since the sngtc_node library performs several memory - allocations with each newly created transcoding session, the module uses a - dedicated process, responsible for the management of the above-mentioned sessions. The - sangoma_worker process communicates with the OpenSIPS - UDP receivers through a series of pipes. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - dialog. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - sngtc_node library - download from Sangoma, - unpack, make, make install (required in order to compile this module). - - - - - sngtc_server up and running (required in order for - this module to properly work). - - - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">sngtc_offer()</function> - - - The function strips off the SDP offer from a SIP INVITE, thus - asking for another SDP offer from the opposite endpoint (late negotiation). - - - - The following error codes may be returned: - - - -1 - SDP parsing error - - - - -3 - internal error / no more memory - - - - - - - The function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function moreinfo="none">sngtc_offer</function> usage - -... - if (is_method("INVITE")) { - t_newtran(); - create_dialog(); - sngtc_offer(); - } -... - - -
- -
- - <function moreinfo="none">sngtc_callee_answer([listen_if_A], [listen_if_B]) - </function> - - - Handles the SDP offer from 200 OK responses, intersects both offers with - the capabilities of the transcoding card and creates a new transcoding - session on the card only if necessary. It then rewrites the 200 OK SDP so that it - contains the information resulted from the codec intersection. - - - Parameters explained: - - Since the D-series transcoding cards are connected through either a - PCI slot or simply an Ethernet connector, they cannot be assigned - global IPs. Consequently, the module will write the local, private IP of the - card in the SDP answers sent to each of the endpoints. Since this will not - work with non-local UAs, the optional parameters force the RTP listen - interface for each UA. This way, the script writer can enforce a global IP - for the incoming RTP (which can be port forwarded to a transcoding card). - - - listen_if_A (string) - the interface where the UAC (the caller) will send RTP after the call is established (IP from the 'c=' SDP line(s)) - - - - listen_if_B (string) - the interface where the UAS (the callee) will send RTP after the call is established (IP from the 'c=' SDP line(s)) - - - - - - - The following error codes may be returned: - - - -1 - SDP parsing error - - - - -2 - failed to create transcoding session - - - - -3 - internal error / no more memory - - - - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function moreinfo="none">sngtc_callee_answer</function> usage - -... -onreply_route[1] { - if ($rs == 200) - sngtc_callee_answer("11.12.13.14", "11.12.13.14"); -} -... - - -
- -
- - <function moreinfo="none">sngtc_caller_answer()</function> - - - Attaches an SDP body to the caller's ACK request, so that it matches - the late SDP negotiation done by the UAS. - - - - The following error codes may be returned: - - - -3 - internal error / no more memory - - - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE. - - - <function moreinfo="none">sngtc_caller_answer</function> usage - -... - if (has_totag()) { - if (loose_route()) { - ... - if (is_method("ACK")) - sngtc_caller_answer(); - } - ... - } -... - - -
- -
-
- diff --git a/modules/snmpstats/README b/modules/snmpstats/README deleted file mode 100644 index ce6d67046db..00000000000 --- a/modules/snmpstats/README +++ /dev/null @@ -1,766 +0,0 @@ -SNMPStats Module (Simple Network Management Protocal Statistic -Module) - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. General Scalar Statistics - 1.1.2. SNMP Tables - 1.1.3. Alarm Monitoring - - 1.2. How it works - - 1.2.1. How the SNMPStats module gets its data - 1.2.2. How data is moved from the SNMPStats module - to a NOC - - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. sipEntityType (String) - 1.4.2. MsgQueueMinorThreshold (Integer) - 1.4.3. MsgQueueMajorThreshold (Integer) - 1.4.4. dlg_minor_threshold (Integer) - 1.4.5. dlg_major_threshold (Integer) - 1.4.6. snmpgetPath (String) - 1.4.7. snmpCommunity (String) - - 1.5. Exported Functions - 1.6. Installation and Running - - 1.6.1. Compiling the SNMPStats Module - 1.6.2. Configuring SNMP daemon to allow connections - from the SNMPStats module. - - 1.6.3. Configuring the SNMPStats module for - communication with a Master Agent - - 1.6.4. Testing for a proper Configuration - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the sipEntityType parameter - 1.2. Setting the MsgQueueMinorThreshold parameter - 1.3. Setting the MsgQueueMajorThreshold parameter - 1.4. Setting the dlg_minor_threshold parameter - 1.5. Setting the dlg_major_threshold parameter - 1.6. Setting the snmpgetPath parameter - 1.7. Setting the snmpCommunity parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The SNMPStats module provides an SNMP management interface to - OpenSIPS. Specifically, it provides general SNMP queryable - scalar statistics, table representations of more complicated - data such as user and contact information, and alarm monitoring - capabilities. - -1.1.1. General Scalar Statistics - - The SNMPStats module provides a number of general scalar - statistics. Details are available in OPENSER-MIB, - OPENSER-REG-MIB, OPENSER-SIP-COMMON-MIB, and - OPENSER-SIP-SERVER-MIB. But briefly, these scalars are: - - openserSIPProtocolVersion, openserSIPServiceStartTime, - openserSIPEntityType, openserSIPSummaryInRequests, - openserSIPSummaryOutRequest, openserSIPSummaryInResponses, - openserSIPSummaryOutResponses, - openserSIPSummaryTotalTransactions, - openserSIPCurrentTransactions, openserSIPNumUnsupportedUris, - openserSIPNumUnsupportedMethods, - openserSIPOtherwiseDiscardedMsgs, openserSIPProxyStatefulness - openserSIPProxyRecordRoute, openserSIPProxyAuthMethod, - openserSIPNumProxyRequireFailures, - openserSIPRegMaxContactExpiryDuration, openserSIPRegMaxUsers, - openserSIPRegCurrentUsers, openserSIPRegDfltRegActiveInterval, - openserSIPRegAcceptedRegistrations, - openserSIPRegRejectedRegistrations, openserMsgQueueDepth. - openserCurNumDialogs, openserCurNumDialogsInProgress, - openserCurNumDialogsInSetup, openserTotalNumFailedDialogSetups - - There are also scalars associated with alarms. They are as - follows: - - openserMsgQueueMinorThreshold, openserMsgQueueMajorThreshold, - openserMsgQueueDepthAlarmStatus, - openserMsgQueueDepthMinorAlarm, openserMsgQueueDepthMajorAlarm, - openserDialogLimitMinorThreshold, - openserDialogLimitMajorThreshold, openserDialogUsageState, - openserDialogLimitAlarmStatus, openserDialogLimitMinorAlarm, - openserDialogLimitMajorAlarm - -1.1.2. SNMP Tables - - The SNMPStats module provides several tables, containing more - complicated data. The current available tables are: - - openserSIPPortTable, openserSIPMethodSupportedTable, - openserSIPStatusCodesTable, openserSIPRegUserTable, - openserSIPContactTable, openserSIPRegUserLookupTable - -1.1.3. Alarm Monitoring - - If enabled, the SNMPStats module will monitor for alarm - conditions. Currently, there are two alarm types defined. - 1. The number of active dialogs has passed a minor or major - threshold. The idea is that a network operation centre can - be made aware that their SIP servers may be overloaded, - without having to explicitly check for this condition. - If a minor or major condition has occurred, then a - openserDialogLimitMinorEvent trap or a - openserDialogLimitMajorEvent trap will be generated, - respectively. The minor and major thresholds are described - in the parameters section below. - 2. The number of bytes waiting to be consumed across all of - OpenSIPS's listening ports has passed a minor or major - threshold. The idea is that a network operation centre can - be made aware that a machine hosting a SIP server may be - entering a degraded state, and to investigate why this is - so. - If the number of bytes to be consumed passes a minor or - major threshold, then a openserMsgQueueDepthMinorEvent or - openserMsgQueueDepthMajorEvent trap will be sent out, - respectively. - - Full details of these traps can be found in the distributions - OPENSER-MIB file. - -1.2. How it works - -1.2.1. How the SNMPStats module gets its data - - The SNMPStats module uses OpenSIPSs internal statistic - framework to collect most of its data. However, there are two - exceptions. - 1. The openserSIPRegUserTable and openserSIPContactTable rely - on the usrloc modules callback system. Specifically, the - SNMPStats module will receive callbacks whenever a - user/contact is added to the system. - 2. The SNMPStats modules openserSIPMsgQueueDepthMinorEvent and - openserSIPMsgQueueDepthMajorEvent alarms rely on the - OpenSIPS core to find out what interfaces, ports, and - transports OpenSIPS is listening on. However,the module - will actually query the proc file system to find out the - number of bytes waiting to be consumed. (Currently, this - will only work on systems providing the proc file system). - -1.2.2. How data is moved from the SNMPStats module to a NOC - - We have now explained how the SNMPStats module gathers its - data. We still have not explained how it exports this data to a - NOC (Network Operations Centre) or administrator. - - The SNMPStats module expects to connect to a Master Agent. This - would be a SNMP daemon running either on the same system as the - OpenSIPS instance, or on another system. (Communication can - take place over TCP, so there is no restriction that this - daemon need be on the same system as OpenSIPS). - - If the master agent is unavailable when OpenSIPS first starts - up, the SNMPStats module will continue to run. However, you - will not be able to query it. Thankfully, the SNMPStats module - continually looks for its master agent. So even if the master - agent is started late, or if the link to the SNMPStats module - is severed due to a temporary hardware failure or crashed and - restarted master agent, the link will eventually be - re-established. No data should be lost, and querying can begin - again. - - To request for this data, you will need to query the master - agent. The master agent will then redirect the request to the - SNMPStats module, which will respond to the master agent, which - will in turn respond to your request. - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The SNMPStats module provides a plethora of statistics, some of - which are collected by other modules. If the dependent modules - are not loaded then those specific statistics will still be - returned, but with zeroed values. All other statistics will - continue to function normally. This means that the SNMPStats - module has no hard/mandatory dependencies on other modules. - There are however, soft dependencies, as follows: - * usrloc - all scalars and tables relating to users and - contacts are dependent on the usrloc module. If the module - is not loaded, the respective tables will be empty. - * dialog - all scalars relating to the number of dialogs are - dependent on the presence of the dialog module. - Furthermore, if the module is not loaded, then the - openserDialogLimitMinorEvent, and - openserDialogLimitMajorEvent alarm will be disabled. - - The contents of the openserSIPMethodSupportedTable change - depending on which modules are loaded. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * Net SNMP DEV (libsnmp-dev on debian) - SNMP library - (development files) must be installed at the time of - compilation. Furthermore, there are several shared objects - that must be loadable at the time SNMPStats is loaded. This - means that SNMP lib must be installed (but not necessarily - running) on the system that has loaded the SNMPStats - module. (Details can be found in the compilation section - below). - * SNMP tools(snmp on debian) - SNMP tools package to provide - the snmpget command (internally used by the SNMPStats - module. - -1.4. Exported Parameters - -1.4.1. sipEntityType (String) - - This parameter describes the entity type for this OpenSIPS - instance, and will be used in determining what is returned for - the openserSIPEntityType scalar. Valid parameters are: - - registrarServer, redirectServer, proxyServer, userAgent, other - - Example 1.1. Setting the sipEntityType parameter -... -modparam("snmpstats", "sipEntityType", "registrarServer") -modparam("snmpstats", "sipEntityType", "proxyServer") -... - - Note that as the above example shows, you can define this - parameter more than once. This is of course because a given - OpenSIPS instance can take on more than one role. - -1.4.2. MsgQueueMinorThreshold (Integer) - - The SNMPStats module monitors the number of bytes waiting to be - consumed by OpenSIPS. If the number of bytes waiting to be - consumed exceeds a minor threshold, the SNMPStats module will - send out an openserMsgQueueDepthMinorEvent trap to signal that - an alarm condition has occurred. The minor threshold is set - with the MsgQueueMinorThreshold parameter. - - Example 1.2. Setting the MsgQueueMinorThreshold parameter -... -modparam("snmpstats", "MsgQueueMinorThreshold", 2000) -... - - If this parameter is not set, then there will be no minor alarm - monitoring. - -1.4.3. MsgQueueMajorThreshold (Integer) - - The SNMPStats module monitors the number of bytes waiting to be - consumed by OpenSIPS. If the number of bytes waiting to be - consumed exceeds a major threshold, the SNMPStats module will - send out an openserMsgQueueDepthMajorEvent trap to signal that - an alarm condition has occurred. The major threshold is set - with the MsgQueueMajorThreshold parameter. - - Example 1.3. Setting the MsgQueueMajorThreshold parameter -... -modparam("snmpstats", "MsgQueueMajorThreshold", 5000) -... - - If this parameter is not set, then there will be no major alarm - monitoring. - -1.4.4. dlg_minor_threshold (Integer) - - The SNMPStats module monitors the number of active dialogs. If - the number of active dialogs exceeds a minor threshold, the - SNMPStats module will send out an openserDialogLimitMinorEvent - trap to signal that an alarm condition has occurred. The minor - threshold is set with the dlg_minor_threshold parameter. - - Example 1.4. Setting the dlg_minor_threshold parameter -... - modparam("snmpstats", "dlg_minor_threshold", 500) -... - - If this parameter is not set, then there will be no minor alarm - monitoring. - -1.4.5. dlg_major_threshold (Integer) - - The SNMPStats module monitors the number of active dialogs. If - the number of active dialogs exceeds a major threshold, the - SNMPStats module will send out an openserDialogLimitMajorEvent - trap to signal that an alarm condition has occurred. The major - threshold is set with the dlg_major_threshold parameter. - - Example 1.5. Setting the dlg_major_threshold parameter -... - modparam("snmpstats", "dlg_major_threshold", 750) -... - - If this parameter is not set, then there will be no major alarm - monitoring. - -1.4.6. snmpgetPath (String) - - The SNMPStats module provides the openserSIPServiceStartTime - scalar. This scalar requires the SNMPStats module to perform a - snmpget query to the master agent. You can use this parameter - to set the path to your instance of SNMP's snmpget program. - - Default value is “/usr/local/bin/”. - - Example 1.6. Setting the snmpgetPath parameter -... -modparam("snmpstats", "snmpgetPath", "/my/custom/path/") -... - -1.4.7. snmpCommunity (String) - - The SNMPStats module provides the openserSIPServiceStartTime - scalar. This scalar requires the SNMPStats module to perform a - snmpget query to the master agent. If you have defined a custom - community string for the snmp daemon, you need to specify it - with this parameter. - - Default value is “public”. - - Example 1.7. Setting the snmpCommunity parameter -... -modparam("snmpstats", "snmpCommunity", "customCommunityString") -... - -1.5. Exported Functions - - Currently, there are no exported functions. - -1.6. Installation and Running - - There are several things that need to be done to get the - SNMPStats module compiled and up and running. - -1.6.1. Compiling the SNMPStats Module - - In order for the SNMPStats module to compile, you will need to - have installed the packages providing SNMP (Simple Network - Management Protocol) libray and development files. - - The SNMPStats modules makefile requires that the SNMP script - "net-snmp-config" can run. - - IMPORTANT: By default, SNMP loads mibs from - /var/lib/mibs/ietf/.Keep in mind that you have to copy OpenSIPS - mibs wherevere your mibs folder is. - -1.6.2. Configuring SNMP daemon to allow connections from the -SNMPStats module. - - The SNMPStats module will communicate with the SNMP Master - Agent. This communication happens over a protocol known as - AgentX. This means you need to have an SMP daemon (acting as - Master Agent) running - it can be on the same machine or on a - different one. - - First you need to turn on AgentX support. The exact location of - the configuration file (snmpd.conf) may vary depending on your - system. By default, via a package installation, it is located - in: - /etc/snmp/snmpd.conf. - - At the very end of the file add the following line: - master agentx - - The line tells SNMP daemon to act as an AgentX master agent, so - that it can accept connections from sub-agents such as the - SNMPStats module. - - There is still one last step. Even though we have configured - SNMP to have AgentX support, we still need to tell the daemon - which interface and port to listen to for AgentX connections. - This is done also via the configuration file (snmpd.conf) : - agentXSocket tcp:localhost:705 - - This tells SNMP daemon to act as a master agent, listening on - the localhost UDP interface at port 705. - -1.6.3. Configuring the SNMPStats module for communication with a -Master Agent - - The previous section explained how to set up a SNMP master - agent to accept AgentX connections. We now need to tell the - SNMPStats module how to communicate with this master agent. - This is done by giving the SNMPStats module its own SNMP - configuration file. The file must be named "snmpstats.conf", - and must be in the same folder as the "snmpd.conf" file that - was configured above. By default this would be: - /etc/snmp/snmpstats.conf - - The default configuration file included with the distribution - can be used, and contains the following: - agentXSocket tcp:localhost:705 - - The above line tells the SNMPStats module to register with the - master agent on the localhost, port 705. The parameters should - match up with the snmpd process. Note that the master agent - (snmpd) does not need to be present on the same machine as - OpenSIPS. The localhost could be replaced with any other - machine. - -1.6.4. Testing for a proper Configuration - - As a quick test to make sure that the SNMPStats module - sub-agent can successfully connect to the SNMP Master agent, be - sure the snmpd service is stopped (/etc/init.d/snmpd stop) and - manually start snmpd with the following: - snmpd -f -Dagentx -x tcp:localhost:705 2>&1 | less - - You should see something similar to the following: - No log handling enabled - turning on stderr logging - registered debug token agentx, 1 - ... - Turning on AgentX master support. - agentx/master: initializing... - agentx/master: initializing... DONE - NET-SNMP version 5.3.1 - - Now, start up OpenSIPS in another window. In the snmpd window, - you should see a bunch of: - agentx/master: handle pdu (req=0x2c58ebd4,trans=0x0,sess=0x0) - agentx/master: open 0x81137c0 - agentx/master: opened 0x814bbe0 = 6 with flags = a0 - agentx/master: send response, stat 0 (req=0x2c58ebd4,trans=0x0,sess= -0x0) - agentx_build: packet built okay - - The messages beginning with "agentx" are debug messages stating - that something is happening with an AgentX sub-agent, appearing - because of the -Dagentx snmpd switch. The large number of debug - messages appear at startup as the SNMPStats module registers - all of its scalars and tables with the Master Agent. If you - receive these messages, then SNMPStats module and SNMP daemon - have both been configured correctly. - -Chapter 2. Frequently Asked Questions - - 2.1. - - Where can I find more about SNMP? - - There are many websites that explain SNMP at all levels of - detail. A great general introduction can be found at - http://en.wikipedia.org/wiki/SNMP If you are interested in the - nitty gritty details of the protocol, then please look at RFC - 3410. RFC 3410 maps out the many other RFCs that define SNMP, - and can be found at - http://www.rfc-archive.org/getrfc.php?rfc=3410 INFO: Also if - you want a nice tutorial for setting up snmpstats with OpenSIPS - try this one. - - 2.2. - - Where can I find more about NetSNMP? - - NetSNMP source code, documentation, FAQs, and tutorials can all - be found at http://net-snmp.sourceforge.net/. - - 2.3. - - Where can I find out more about AgentX? - - The full details of the AgentX protocol are explained in RFC - 2741, available at: - http://www.rfc-archive.org/getrfc.php?rfc=2741 - - 2.4. - - Why am I not receiving any SNMP Traps? - - Assuming you've configured the trap thresholds in opensips.cfg - with something similar to: - modparam("snmpstats", "MsgQueueMinorThreshold", 1234) - modparam("snmpstats", "MsgQueueMajorThreshold", 5678) - - modparam("snmpstats", "dlg_minor_threshold", 500) - modparam("snmpstats", "dlg_minor_threshold", 600) - - Then either OpenSIPS is not reaching these thresholds (which is - a good thing), or you haven't set up the trap monitor - correctly. To prove this to yourself, you can start NetSNMP - with: - snmpd -f -Dtrap -x localhost:705 - - The -f tells the NetSNMP process to not daemonize, and the - -Dtrap enables trap debug logs. You should see something - similar to the following: - registered debug token trap, 1 - trap: adding callback trap sink ----- You should see both - trapsess: adding to trap table ----- of these lines. - Turning on AgentX master support. - trap: send_trap 0 0 NET-SNMP-TC::linux - trap: sending trap type=167, version=1 - NET-SNMP version 5.3.1 - - If the two lines above did not appear, then you probably have - not included the following in your snmpd.conf file. - trap2sink machineToSendTrapsTo:machinesPortNumber. - - When a trap has been received by snmpd, the following will - appear in the above output: - sent_trap -1 -1 NET-SNMP-TC::linus - sending trap type=167, version=1 - - You'll also need a program to collect the traps and do - something with them (such as sending them to syslog). NetSNMP - provides snmptrapd for this. Other solutions exist as well. - Google is your friend. - - 2.5. - - OpenSIPS refuses to load the SNMPStats module. Why is it - displaying "load_module: could not open module snmpstats.so"? - - On some systems, you may receive the following error at stdout - or the log files depending on the configuration. - ERROR: load_module: could not open module : - libnetsnmpmibs.so.10: cannot open shared object file: No such - file or directory. - - This means one of two things: - 1. You did not install NetSNMP. ("make install" if building - from source) - 2. The dynamic linker cannot find the necessary libraries. - - In the second case, the fix is as follows: - 1. find / -name "libnetsnmpmibs*" - + You will find a copy unless you haven't installed - NetSNMP. Make note of the path. - 2. less /etc/ld.so.conf - + If the file is missing the path from step 1, then add - the path to ld.so.conf - 3. ldconfig - 4. Try starting OpenSIPS again. - - Alternatively, you may prefix your startup command with: - LD_LIBRARY_PATH=/path/noted/in/step/one/above - - For example, on my system I ran: - LD_LIBRARY_PATH=/usr/local/lib /etc/init.d/opens -ips start - - 2.6. - - How can I learn what all the scalars and tables are? - - All scalars and tables are named in the SNMPStats module - overview. The files OPENSER-MIB, OPENSER-REG-MIB, - OPENSER-SIP-COMMON-MIB and OPENSER-SIP-SERVER-MIB contain the - full definitions and descriptions. Note however, that the MIBs - may actually contain scalars and tables which are currently not - provided by the SNMPStats module. Therefore, it is better to - use NetSNMP's snmptranslate as an alternative. Take the - openserSIPEntityType scalar as an example. You can invoke - snmptranslate as follows: - snmptranslate -TBd openserSIPEntityType - - Which would result in something similar to the following: - -- FROM OPENSER-SIP-COMMON-MIB - -- TEXTUAL CONVENTION OpenSIPSSIPEntityRole - SYNTAX BITS {other(0), userAgent(1), proxyServer(2), redirect -Server(3), registrarServer(4)} - MAX-ACCESS read-only - STATUS current - DESCRIPTION " This object identifies the list of SIP entities this - row is related to. It is defined as a bit map. Each - bit represents a type of SIP entity. - If a bit has value 1, the SIP entity represented by - this row plays the role of this entity type. - - If a bit has value 0, the SIP entity represented by - this row does not act as this entity type - Combinations of bits can be set when the SIP entity - plays multiple SIP roles." - - 2.7. - - Why do snmpget, snmpwalk, and snmptable always time out? - - If your snmp operations are always returning with: "Timeout: No - Response from localhost", then chances are that you are making - the query with the wrong community string. Default installs - will most likely use "public" as their default community - strings. Grep your snmpd.conf file for the string - "rocommunity", and use the result as your community string in - your queries. - - 2.8. - - How do I use snmpget? - - NetSNMP's snmpget is used as follows: - snmpget -v 2c -c theCommunityString machineToSendTheMachineTo scalar -Element.0 - - For example, consider an snmpget on the openserSIPEntityType - scalar, run on the same machine running the OpenSIPS instance, - with the default "public" community string. The command would - be: - snmpget -v2c -c public localhost openserSIPEntityType.0 - - Which would result in something similar to: - OPENSER-SIP-COMMON-MIB::openserSIPEntityType.0 = BITS: F8 \ - other(0) userAgent(1) proxyServer(2) \ - redirectServer(3) registrarServer(4) - - 2.9. - - How do I use snmptable? - - NetSNMP's snmptable is used as follows: - snmptable -Ci -v 2c -c theCommunityString machineToSendTheMachineTo -theTableName - - For example, consider the openserSIPRegUserTable. If we run the - snmptable command on the same machine as the running OpenSIPS - instance, configured with the default "public" community - string. The command would be: - snmptable -Ci -v 2c -c public localhost openserSIPRegUserTable - - Which would result in something similar to: - index openserSIPUserUri openserSIPUserAuthenticationFailures - 1 DefaultUser 0 - 2 bogdan 0 - 3 jeffrey.magder 0 - - 2.10. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.11. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.12. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jeffrey Magder 117 4 13157 64 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 50 36 519 526 - 3. Razvan Crainea (@razvancrainea) 24 21 94 70 - 4. Liviu Chircu (@liviuchircu) 16 13 45 119 - 5. Ovidiu Sas (@ovidiusas) 13 3 6 505 - 6. Daniel-Constantin Mierla (@miconda) 12 10 48 41 - 7. Anca Vamanu 6 2 161 111 - 8. Maksym Sobolyev (@sobomax) 5 3 9 5 - 9. Henning Westerholt (@henningw) 5 3 5 5 - 10. Jesus Rodrigues 3 1 7 7 - - All remaining contributors: Julián Moreno Patiño, Klaus - Darilion, Konstantin Bokarius, Ken Rice, Peter Lemenkov - (@lemenkov), Ionut Ionita (@ionutrazvanionita), Sergio - Gutierrez, Vlad Patrascu (@rvlad-patrascu), Edson Gellert - Schubert, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Oct 2022 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Jan 2023 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2006 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Ionut Ionita (@ionutrazvanionita) Jan 2016 - Jan 2016 - 10. Walter Doekes (@wdoekes) May 2014 - May 2014 - - All remaining contributors: Ovidiu Sas (@ovidiusas), Sergio - Gutierrez, Henning Westerholt (@henningw), Klaus Darilion, Anca - Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Jeffrey - Magder. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov - (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, - Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu - (@bogdan-iancu), Henning Westerholt (@henningw), Klaus - Darilion, Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Jeffrey Magder. - - Documentation Copyrights: - - Copyright © 2006 SOMA Networks, Inc. diff --git a/modules/snmpstats/README.md b/modules/snmpstats/README.md new file mode 100644 index 00000000000..f43c9f55840 --- /dev/null +++ b/modules/snmpstats/README.md @@ -0,0 +1,727 @@ +--- +title: "SNMPStats Module" +description: "The SNMPStats module provides an SNMP management interface to OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +The SNMPStats module (Simple Network Management Protocal Statistic Module) provides an SNMP management interface to OpenSIPS. Specifically, it provides general SNMP queryable scalar statistics, table representations of more complicated data such as user and contact information, and alarm monitoring capabilities. + + +#### General Scalar Statistics + + +The SNMPStats module provides a number of general scalar +statistics. +Details are available in OPENSER-MIB, OPENSER-REG-MIB, +OPENSER-SIP-COMMON-MIB, and OPENSER-SIP-SERVER-MIB. But briefly, +these scalars are: + + +openserSIPProtocolVersion, openserSIPServiceStartTime, +openserSIPEntityType, +openserSIPSummaryInRequests, openserSIPSummaryOutRequest, +openserSIPSummaryInResponses, openserSIPSummaryOutResponses, +openserSIPSummaryTotalTransactions, openserSIPCurrentTransactions, +openserSIPNumUnsupportedUris, openserSIPNumUnsupportedMethods, +openserSIPOtherwiseDiscardedMsgs, openserSIPProxyStatefulness +openserSIPProxyRecordRoute, openserSIPProxyAuthMethod, +openserSIPNumProxyRequireFailures, +openserSIPRegMaxContactExpiryDuration, +openserSIPRegMaxUsers, openserSIPRegCurrentUsers, +openserSIPRegDfltRegActiveInterval, +openserSIPRegAcceptedRegistrations, +openserSIPRegRejectedRegistrations, openserMsgQueueDepth. +openserCurNumDialogs, openserCurNumDialogsInProgress, +openserCurNumDialogsInSetup, openserTotalNumFailedDialogSetups + + +There are also scalars associated with alarms. They are as follows: + + +openserMsgQueueMinorThreshold, openserMsgQueueMajorThreshold, +openserMsgQueueDepthAlarmStatus, openserMsgQueueDepthMinorAlarm, +openserMsgQueueDepthMajorAlarm, openserDialogLimitMinorThreshold, +openserDialogLimitMajorThreshold, openserDialogUsageState, +openserDialogLimitAlarmStatus, openserDialogLimitMinorAlarm, +openserDialogLimitMajorAlarm + + +#### SNMP Tables + + +The SNMPStats module provides several tables, containing more +complicated data. The current available tables are: + + +openserSIPPortTable, openserSIPMethodSupportedTable, +openserSIPStatusCodesTable, openserSIPRegUserTable, +openserSIPContactTable, openserSIPRegUserLookupTable + + +#### Alarm Monitoring + + +If enabled, the SNMPStats module will monitor for alarm conditions. +Currently, there are two alarm types defined. + + +1. The number of active dialogs has passed a minor or major +threshold. The idea is that a network operation centre can +be made aware that their SIP servers may be overloaded, +without having to explicitly check for this condition. +If a minor or major condition has occurred, then a +openserDialogLimitMinorEvent trap or a +openserDialogLimitMajorEvent trap will be generated, +respectively. The minor and major thresholds are +described in the parameters section below. +2. The number of bytes waiting to be consumed across all of +OpenSIPS's listening ports has passed a minor or major +threshold. The idea is that a network operation centre can +be made aware that a machine hosting a SIP server may be +entering a degraded state, and to investigate why this is so. +If the number of bytes to be consumed passes a minor or major +threshold, then a openserMsgQueueDepthMinorEvent or +openserMsgQueueDepthMajorEvent trap will be sent out, +respectively. + + +Full details of these traps can be found in the distributions +OPENSER-MIB file. + + +### How it works + + +#### How the SNMPStats module gets its data + + +The SNMPStats module uses OpenSIPSs internal statistic framework to +collect most of its data. However, there are two exceptions. + + +1. The openserSIPRegUserTable and openserSIPContactTable rely on the +usrloc modules callback system. Specifically, the SNMPStats +module will receive callbacks whenever a user/contact is added to +the system. +2. The SNMPStats modules openserSIPMsgQueueDepthMinorEvent and +openserSIPMsgQueueDepthMajorEvent alarms rely on the OpenSIPS +core to find out what interfaces, ports, and transports OpenSIPS +is listening on. However,the module will actually query the proc +file system to find out the number of bytes waiting to be consumed. +(Currently, this will only work on systems providing the proc file +system). + + +#### How data is moved from the SNMPStats module to a NOC + + +We have now explained how the SNMPStats module gathers its data. We still +have not explained how it exports this data to a NOC (Network Operations +Centre) or administrator. + + +The SNMPStats module expects to connect to a +*Master Agent*. This would be a SNMP daemon running +either on the same system as the OpenSIPS instance, or on another system. +(Communication can take place over TCP, so there is no restriction +that this daemon need be on the same system as OpenSIPS). + + +If the master agent is unavailable when OpenSIPS first starts up, the +SNMPStats module will continue to run. However, you will not be able to +query it. Thankfully, the SNMPStats module continually looks for its +master agent. So even if the master agent is started late, +or if the link to the SNMPStats module is severed due to a temporary +hardware failure or crashed and restarted master agent, the link will +eventually be re-established. No data should be lost, and querying can +begin again. + + +To request for this data, you will need to query the master agent. The +master agent will then redirect the request to the SNMPStats module, which +will respond to the master agent, which will in turn respond to +your request. + + +### Dependencies + + +#### OpenSIPS Modules + + +The SNMPStats module provides a plethora of statistics, some of which +are collected by other modules. If the dependent modules are not +loaded then those specific statistics will still be returned, but with +zeroed values. All other statistics will continue to function +normally. This means that the SNMPStats module has no +*hard/mandatory* dependencies on other modules. +There are however, *soft* dependencies, as follows: + + +- *usrloc* - all scalars and tables relating to users +and contacts are dependent on the usrloc module. If the module is +not loaded, the respective tables will be empty. +- *dialog* - all scalars relating to the number of +dialogs are dependent on the presence of the dialog module. +Furthermore, if the module is not loaded, then the +openserDialogLimitMinorEvent, and openserDialogLimitMajorEvent +alarm will be disabled. + + +The contents of the openserSIPMethodSupportedTable change depending +on which modules are loaded. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *Net SNMP DEV (libsnmp-dev on debian)* - SNMP +library (development files) must +be installed at the time of compilation. Furthermore, there are +several shared objects that must be loadable at the time SNMPStats +is loaded. This means that SNMP lib must be installed (but not +necessarily running) on the system that has loaded the SNMPStats +module. (Details can be found in the compilation section below). +- *SNMP tools(snmp on debian)* - SNMP +tools package to provide the snmpget command (internally used by +the SNMPStats module. + + +### Exported Parameters + + +#### sipEntityType (String) + + +This parameter describes the entity type for this OpenSIPS instance, +and will be used in determining what is returned for the +openserSIPEntityType scalar. Valid parameters are: + + +*registrarServer, redirectServer, proxyServer, userAgent, other* + + +```opensips title="Setting the sipEntityType parameter" +... +modparam("snmpstats", "sipEntityType", "registrarServer") +modparam("snmpstats", "sipEntityType", "proxyServer") +... + +``` + + +> [!NOTE] +> As the above example shows, you can define this parameter +> more than once. This is of course because a given OpenSIPS instance +> can take on more than one role. + + +#### MsgQueueMinorThreshold (Integer) + + +The SNMPStats module monitors the number of bytes waiting to be +consumed by OpenSIPS. If the number of bytes waiting to be consumed +exceeds a minor threshold, the SNMPStats module will send out an +openserMsgQueueDepthMinorEvent trap to signal that an alarm condition +has occurred. The minor threshold is set with the +MsgQueueMinorThreshold parameter. + + +```opensips title="Setting the MsgQueueMinorThreshold parameter" +... +modparam("snmpstats", "MsgQueueMinorThreshold", 2000) +... + +``` + + +If this parameter is not set, then there will be no minor alarm +monitoring. + + +#### MsgQueueMajorThreshold (Integer) + + +The SNMPStats module monitors the number of bytes waiting to be +consumed by OpenSIPS. If the number of bytes waiting to be consumed +exceeds a major threshold, the SNMPStats module will send out an +openserMsgQueueDepthMajorEvent trap to signal that an alarm condition +has occurred. The major threshold is set with the +MsgQueueMajorThreshold parameter. + + +```opensips title="Setting the MsgQueueMajorThreshold parameter" +... +modparam("snmpstats", "MsgQueueMajorThreshold", 5000) +... + +``` + + +If this parameter is not set, then there will be no major alarm +monitoring. + + +#### dlg_minor_threshold (Integer) + + +The SNMPStats module monitors the number of active dialogs. If the +number of active dialogs exceeds a minor threshold, the SNMPStats +module will send out an openserDialogLimitMinorEvent trap to signal +that an alarm condition has occurred. The minor threshold is set with +the dlg_minor_threshold parameter. + + +```opensips title="Setting the dlg_minor_threshold parameter" +... + modparam("snmpstats", "dlg_minor_threshold", 500) +... + +``` + + +If this parameter is not set, then there will be no minor alarm +monitoring. + + +#### dlg_major_threshold (Integer) + + +The SNMPStats module monitors the number of active dialogs. If +the number of active dialogs exceeds a major threshold, the SNMPStats +module will send out an openserDialogLimitMajorEvent trap to signal +that an alarm condition has occurred. The major threshold is set +with the dlg_major_threshold parameter. + + +```opensips title="Setting the dlg_major_threshold parameter" +... + modparam("snmpstats", "dlg_major_threshold", 750) +... + +``` + + +If this parameter is not set, then there will be no major alarm +monitoring. + + +#### snmpgetPath (String) + + +The SNMPStats module provides the openserSIPServiceStartTime scalar. +This scalar requires the SNMPStats module to perform a snmpget query +to the master agent. You can use this parameter to set the path to +your instance of SNMP's snmpget program. + + +*Default value is "/usr/local/bin/".* + + +```opensips title="Setting the snmpgetPath parameter" +... +modparam("snmpstats", "snmpgetPath", "/my/custom/path/") +... + +``` + + +#### snmpCommunity (String) + + +The SNMPStats module provides the openserSIPServiceStartTime scalar. +This scalar requires the SNMPStats module to perform a snmpget query +to the master agent. If you have defined a custom community string +for the snmp daemon, you need to specify it with this parameter. + + +*Default value is "public".* + + +```opensips title="Setting the snmpCommunity parameter" +... +modparam("snmpstats", "snmpCommunity", "customCommunityString") +... + +``` + + +### Exported Functions + + +Currently, there are no exported functions. + + +### Installation and Running + + +There are several things that need to be done to get the SNMPStats module +compiled and up and running. + + +#### Compiling the SNMPStats Module + + +In order for the SNMPStats module to compile, you will need to have +installed the packages providing SNMP (Simple Network Management +Protocol) libray and development files. + + +The SNMPStats modules makefile requires that the SNMP script +"net-snmp-config" can run. + + +> [!IMPORTANT] +> By default, SNMP loads *mibs* from +> */var/lib/mibs/ietf/*.Keep in mind that you have to copy OpenSIPS +> *mibs* wherevere your mibs folder is. + + +#### Configuring SNMP daemon to allow connections from the SNMPStats module. + + +The SNMPStats module will communicate with the SNMP Master Agent. This +communication happens over a protocol known as AgentX. This means you +need to have an SMP daemon (acting as Master Agent) running - it can +be on the same machine or on a different one. + + +First you need to turn on AgentX support. The exact location of +the configuration file (snmpd.conf) may vary depending on your system. +By default, via a package installation, it is located in: + + +```bash +/etc/snmp/snmpd.conf +``` + + +At the very end of the file add the following line: + + +```c +master agentx +``` + + +The line tells SNMP daemon to act as an AgentX master agent, so that it +can accept connections from sub-agents such as the SNMPStats module. + + +There is still one last step. Even though we have configured +SNMP to have AgentX support, we still need to tell the daemon which +interface and port to listen to for AgentX connections. This is done also +via the configuration file (snmpd.conf) : + + +```c +agentXSocket tcp:localhost:705 +``` + + +This tells SNMP daemon to act as a master agent, listening on the +localhost UDP interface at port 705. + + +#### Configuring the SNMPStats module for communication with a Master Agent + + +The previous section explained how to set up a SNMP master agent to accept +AgentX connections. We now need to tell the SNMPStats module how to +communicate with this master agent. This is done by giving the +SNMPStats module its own SNMP configuration file. The file must be named +"snmpstats.conf", and must be in the same folder as the "snmpd.conf" file +that was configured above. By default this would be: + + +```bash +/etc/snmp/snmpstats.conf +``` + + +The default configuration file included with the distribution can be used, +and contains the following: + + +```c +agentXSocket tcp:localhost:705 +``` + + +The above line tells the SNMPStats module to register with the master +agent on the localhost, port 705. The parameters should match up with +the snmpd process. +Note that the master agent (snmpd) does not need to be present on the same +machine as OpenSIPS. The localhost could be replaced with any other +machine. + + +#### Testing for a proper Configuration + + +As a quick test to make sure that the SNMPStats module sub-agent can +successfully connect to the SNMP Master agent, be sure the snmpd service +is stopped (/etc/init.d/snmpd stop) and manually start snmpd with the +following: + + +```bash +snmpd -f -Dagentx -x tcp:localhost:705 2>&1 | less +``` + + +You should see something similar to the following: + + +```c + No log handling enabled - turning on stderr logging + registered debug token agentx, 1 + ... + Turning on AgentX master support. + agentx/master: initializing... + agentx/master: initializing... DONE + NET-SNMP version 5.3.1 +``` + + +Now, start up OpenSIPS in another window. In the snmpd window, you should +see a bunch of: + + +```c + agentx/master: handle pdu (req=0x2c58ebd4,trans=0x0,sess=0x0) + agentx/master: open 0x81137c0 + agentx/master: opened 0x814bbe0 = 6 with flags = a0 + agentx/master: send response, stat 0 (req=0x2c58ebd4,trans=0x0,sess=0x0) + agentx_build: packet built okay +``` + + +The messages beginning with "agentx" are debug messages stating that +something is happening with an AgentX sub-agent, appearing because of +the -Dagentx snmpd switch. The large number of debug messages appear at +startup as the SNMPStats module registers all of its scalars +and tables with the Master Agent. If you receive these messages, then +SNMPStats module and SNMP daemon have both been configured correctly. + + +## Frequently Asked Questions + + +**Q: Where can I find more about SNMP?** + + +There are many websites that explain SNMP at all levels of detail. +A great general introduction can be found at http://en.wikipedia.org/wiki/SNMP + +If you are interested in the nitty gritty details of the protocol, +then please look at RFC 3410. RFC 3410 maps out the many other RFCs +that define SNMP, and can be found at http://www.rfc-archive.org/getrfc.php?rfc=3410 + +INFO: Also if you want a nice tutorial for setting up snmpstats with OpenSIPS try +[this one](http://saevolgo.blogspot.ro/2012/09/opensips-monitoring-using-snmp-part-i.html). + + +**Q: Where can I find more about NetSNMP?** + + +NetSNMP source code, documentation, FAQs, and tutorials can all be found at +http://net-snmp.sourceforge.net/. + + +**Q: Where can I find out more about AgentX?** + + +The full details of the AgentX protocol are explained in RFC 2741, +available at: http://www.rfc-archive.org/getrfc.php?rfc=2741 + + +**Q: Why am I not receiving any SNMP Traps?** + + +Assuming you've configured the trap thresholds in opensips.cfg with something similar to: + +Then either OpenSIPS is not reaching these thresholds (which is a good thing), +or you haven't set up the trap monitor correctly. To prove this to yourself, +you can start NetSNMP with: + +The -f tells the NetSNMP process to not daemonize, and the -Dtrap enables trap +debug logs. You should see something similar to the following: + +If the two lines above did not appear, then you probably have not included +the following in your snmpd.conf file. + +When a trap has been received by snmpd, the following will appear in the +above output: + +You'll also need a program to collect the traps and do something with them +(such as sending them to syslog). NetSNMP provides snmptrapd for this. Other +solutions exist as well. Google is your friend. + + +**Q: OpenSIPS refuses to load the SNMPStats module. Why is it displaying "load_module: could not open module snmpstats.so"?** + + +On some systems, you may receive the following error at stdout or the log files +depending on the configuration. + +This means one of two things: + +In the second case, the fix is as follows: + +Alternatively, you may prefix your startup command with: + +For example, on my system I ran: + + +**Q: How can I learn what all the scalars and tables are?** + + +All scalars and tables are named in the SNMPStats module overview. The files +OPENSER-MIB, OPENSER-REG-MIB, OPENSER-SIP-COMMON-MIB and OPENSER-SIP-SERVER-MIB +contain the full definitions and descriptions. Note however, that the MIBs +may actually contain scalars and tables which are currently not provided by the +SNMPStats module. Therefore, it is better to use NetSNMP's snmptranslate +as an alternative. Take the openserSIPEntityType scalar as an example. You can +invoke snmptranslate as follows: + + +```bash + snmptranslate -TBd openserSIPEntityType +``` + + +Which would result in something similar to the following: + + +```c + -- FROM OPENSER-SIP-COMMON-MIB + -- TEXTUAL CONVENTION OpenSIPSSIPEntityRole + SYNTAX BITS {other(0), userAgent(1), proxyServer(2), redirectServer(3), registrarServer(4)} + MAX-ACCESS read-only + STATUS current + DESCRIPTION " This object identifies the list of SIP entities this + row is related to. It is defined as a bit map. Each + bit represents a type of SIP entity. + If a bit has value 1, the SIP entity represented by + this row plays the role of this entity type. + + If a bit has value 0, the SIP entity represented by + this row does not act as this entity type + Combinations of bits can be set when the SIP entity + plays multiple SIP roles." +``` + + +**Q: Why do snmpget, snmpwalk, and snmptable always time out?** + + +If your snmp operations are always returning with: "Timeout: No Response +from localhost", then chances are that you are making the query with the wrong +community string. Default installs will most likely use "public" as their +default community strings. Grep your snmpd.conf file for the string +"rocommunity", and use the result as your community string in your queries. + + +**Q: How do I use snmpget?** + + +NetSNMP's snmpget is used as follows: + + +```bash + snmpget -v 2c -c theCommunityString machineToSendTheMachineTo scalarElement.0 +``` + + +For example, consider an snmpget on the openserSIPEntityType scalar, +run on the same machine running the OpenSIPS instance, with the default +"public" community string. The command would be: + + +```bash + snmpget -v2c -c public localhost openserSIPEntityType.0 +``` + + +Which would result in something similar to: + + +```c + OPENSER-SIP-COMMON-MIB::openserSIPEntityType.0 = BITS: F8 \ + other(0) userAgent(1) proxyServer(2) \ + redirectServer(3) registrarServer(4) +``` + + +**Q: How do I use snmptable?** + + +NetSNMP's snmptable is used as follows: + + +```bash + snmptable -Ci -v 2c -c theCommunityString machineToSendTheMachineTo theTableName +``` + + +For example, consider the openserSIPRegUserTable. If we run the snmptable +command on the same machine as the running OpenSIPS instance, configured with +the default "public" community string. The command would be: + + +```bash + snmptable -Ci -v 2c -c public localhost openserSIPRegUserTable +``` + + +Which would result in something similar to: + + +```c + index openserSIPUserUri openserSIPUserAuthenticationFailures + 1 DefaultUser 0 + 2 bogdan 0 + 3 jeffrey.magder 0 +``` + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/snmpstats/doc/contributors.xml b/modules/snmpstats/doc/contributors.xml deleted file mode 100644 index 3c16ad35dbe..00000000000 --- a/modules/snmpstats/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jeffrey Magder - 117 - 4 - 13157 - 64 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 50 - 36 - 519 - 526 - - - 3. - Razvan Crainea (@razvancrainea) - 24 - 21 - 94 - 70 - - - 4. - Liviu Chircu (@liviuchircu) - 16 - 13 - 45 - 119 - - - 5. - Ovidiu Sas (@ovidiusas) - 13 - 3 - 6 - 505 - - - 6. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 48 - 41 - - - 7. - Anca Vamanu - 6 - 2 - 161 - 111 - - - 8. - Maksym Sobolyev (@sobomax) - 5 - 3 - 9 - 5 - - - 9. - Henning Westerholt (@henningw) - 5 - 3 - 5 - 5 - - - 10. - Jesus Rodrigues - 3 - 1 - 7 - 7 - - - -
-All remaining contributors: Julián Moreno Patiño, Klaus Darilion, Konstantin Bokarius, Ken Rice, Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Sergio Gutierrez, Vlad Patrascu (@rvlad-patrascu), Edson Gellert Schubert, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Oct 2022 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Jan 2023 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2006 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Ionut Ionita (@ionutrazvanionita) - Jan 2016 - Jan 2016 - - - 10. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas), Sergio Gutierrez, Henning Westerholt (@henningw), Klaus Darilion, Anca Vamanu, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Jeffrey Magder. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Julián Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Bogdan-Andrei Iancu (@bogdan-iancu), Henning Westerholt (@henningw), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jeffrey Magder. -
- -
diff --git a/modules/snmpstats/doc/snmpstats.xml b/modules/snmpstats/doc/snmpstats.xml deleted file mode 100644 index dec875fa0a3..00000000000 --- a/modules/snmpstats/doc/snmpstats.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - SNMPStats Module (Simple Network Management Protocal Statistic Module) - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 SOMA Networks, Inc. - - diff --git a/modules/snmpstats/doc/snmpstats_admin.xml b/modules/snmpstats/doc/snmpstats_admin.xml deleted file mode 100644 index 7bcb73c87e1..00000000000 --- a/modules/snmpstats/doc/snmpstats_admin.xml +++ /dev/null @@ -1,584 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The SNMPStats module provides an SNMP management interface - to OpenSIPS. Specifically, it provides general SNMP queryable - scalar statistics, table representations of more complicated data - such as user and contact information, and alarm monitoring - capabilities. - -
- General Scalar Statistics - - The SNMPStats module provides a number of general scalar - statistics. - Details are available in OPENSER-MIB, OPENSER-REG-MIB, - OPENSER-SIP-COMMON-MIB, and OPENSER-SIP-SERVER-MIB. But briefly, - these scalars are: - - - openserSIPProtocolVersion, openserSIPServiceStartTime, - openserSIPEntityType, - openserSIPSummaryInRequests, openserSIPSummaryOutRequest, - openserSIPSummaryInResponses, openserSIPSummaryOutResponses, - openserSIPSummaryTotalTransactions, openserSIPCurrentTransactions, - openserSIPNumUnsupportedUris, openserSIPNumUnsupportedMethods, - openserSIPOtherwiseDiscardedMsgs, openserSIPProxyStatefulness - openserSIPProxyRecordRoute, openserSIPProxyAuthMethod, - openserSIPNumProxyRequireFailures, - openserSIPRegMaxContactExpiryDuration, - openserSIPRegMaxUsers, openserSIPRegCurrentUsers, - openserSIPRegDfltRegActiveInterval, - openserSIPRegAcceptedRegistrations, - openserSIPRegRejectedRegistrations, openserMsgQueueDepth. - openserCurNumDialogs, openserCurNumDialogsInProgress, - openserCurNumDialogsInSetup, openserTotalNumFailedDialogSetups - - - There are also scalars associated with alarms. They are as follows: - - - openserMsgQueueMinorThreshold, openserMsgQueueMajorThreshold, - openserMsgQueueDepthAlarmStatus, openserMsgQueueDepthMinorAlarm, - openserMsgQueueDepthMajorAlarm, openserDialogLimitMinorThreshold, - openserDialogLimitMajorThreshold, openserDialogUsageState, - openserDialogLimitAlarmStatus, openserDialogLimitMinorAlarm, - openserDialogLimitMajorAlarm - -
-
- SNMP Tables - - The SNMPStats module provides several tables, containing more - complicated data. The current available tables are: - - - - openserSIPPortTable, openserSIPMethodSupportedTable, - openserSIPStatusCodesTable, openserSIPRegUserTable, - openserSIPContactTable, openserSIPRegUserLookupTable - -
-
- Alarm Monitoring - - If enabled, the SNMPStats module will monitor for alarm conditions. - Currently, there are two alarm types defined. - - - - - - The number of active dialogs has passed a minor or major - threshold. The idea is that a network operation centre can - be made aware that their SIP servers may be overloaded, - without having to explicitly check for this condition. - - - If a minor or major condition has occurred, then a - openserDialogLimitMinorEvent trap or a - openserDialogLimitMajorEvent trap will be generated, - respectively. The minor and major thresholds are - described in the parameters section below. - - - - - The number of bytes waiting to be consumed across all of - OpenSIPS's listening ports has passed a minor or major - threshold. The idea is that a network operation centre can - be made aware that a machine hosting a SIP server may be - entering a degraded state, and to investigate why this is so. - - - If the number of bytes to be consumed passes a minor or major - threshold, then a openserMsgQueueDepthMinorEvent or - openserMsgQueueDepthMajorEvent trap will be sent out, - respectively. - - - - - - Full details of these traps can be found in the distributions - OPENSER-MIB file. - -
-
- - -
- How it works - -
- How the SNMPStats module gets its data - - The SNMPStats module uses OpenSIPSs internal statistic framework to - collect most of its data. However, there are two exceptions. - - - - The openserSIPRegUserTable and openserSIPContactTable rely on the - usrloc modules callback system. Specifically, the SNMPStats - module will receive callbacks whenever a user/contact is added to - the system. - - - - - The SNMPStats modules openserSIPMsgQueueDepthMinorEvent and - openserSIPMsgQueueDepthMajorEvent alarms rely on the OpenSIPS - core to find out what interfaces, ports, and transports OpenSIPS - is listening on. However,the module will actually query the proc - file system to find out the number of bytes waiting to be consumed. - (Currently, this will only work on systems providing the proc file - system). - - - - -
-
- How data is moved from the SNMPStats module to a NOC - - We have now explained how the SNMPStats module gathers its data. We still - have not explained how it exports this data to a NOC (Network Operations - Centre) or administrator. - - - The SNMPStats module expects to connect to a - Master Agent. This would be a SNMP daemon running - either on the same system as the OpenSIPS instance, or on another system. - (Communication can take place over TCP, so there is no restriction - that this daemon need be on the same system as OpenSIPS). - - - If the master agent is unavailable when OpenSIPS first starts up, the - SNMPStats module will continue to run. However, you will not be able to - query it. Thankfully, the SNMPStats module continually looks for its - master agent. So even if the master agent is started late, - or if the link to the SNMPStats module is severed due to a temporary - hardware failure or crashed and restarted master agent, the link will - eventually be re-established. No data should be lost, and querying can - begin again. - - - To request for this data, you will need to query the master agent. The - master agent will then redirect the request to the SNMPStats module, which - will respond to the master agent, which will in turn respond to - your request. - -
- -
- -
- Dependencies -
- &osips; Modules - - The SNMPStats module provides a plethora of statistics, some of which - are collected by other modules. If the dependent modules are not - loaded then those specific statistics will still be returned, but with - zeroed values. All other statistics will continue to function - normally. This means that the SNMPStats module has no - hard/mandatory dependencies on other modules. - There are however, soft dependencies, as follows: - - - - - usrloc - all scalars and tables relating to users - and contacts are dependent on the usrloc module. If the module is - not loaded, the respective tables will be empty. - - - - - - dialog - all scalars relating to the number of - dialogs are dependent on the presence of the dialog module. - Furthermore, if the module is not loaded, then the - openserDialogLimitMinorEvent, and openserDialogLimitMajorEvent - alarm will be disabled. - - - - - The contents of the openserSIPMethodSupportedTable change depending - on which modules are loaded. - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - Net SNMP DEV (libsnmp-dev on debian) - SNMP - library (development files) must - be installed at the time of compilation. Furthermore, there are - several shared objects that must be loadable at the time SNMPStats - is loaded. This means that SNMP lib must be installed (but not - necessarily running) on the system that has loaded the SNMPStats - module. (Details can be found in the compilation section below). - - - - - SNMP tools(snmp on debian) - SNMP - tools package to provide the snmpget command (internally used by - the SNMPStats module. - - - - -
-
-
- Exported Parameters -
- <varname>sipEntityType</varname> (String) - - - This parameter describes the entity type for this OpenSIPS instance, - and will be used in determining what is returned for the - openserSIPEntityType scalar. Valid parameters are: - - - - - registrarServer, redirectServer, proxyServer, userAgent, other - - - - - Setting the <varname>sipEntityType</varname> parameter - -... -modparam("snmpstats", "sipEntityType", "registrarServer") -modparam("snmpstats", "sipEntityType", "proxyServer") -... - - - - - Note that as the above example shows, you can define this parameter - more than once. This is of course because a given OpenSIPS instance - can take on more than one role. - -
- -
- <varname>MsgQueueMinorThreshold</varname> (Integer) - - - The SNMPStats module monitors the number of bytes waiting to be - consumed by OpenSIPS. If the number of bytes waiting to be consumed - exceeds a minor threshold, the SNMPStats module will send out an - openserMsgQueueDepthMinorEvent trap to signal that an alarm condition - has occurred. The minor threshold is set with the - MsgQueueMinorThreshold parameter. - - - - Setting the <varname>MsgQueueMinorThreshold</varname> parameter - -... -modparam("snmpstats", "MsgQueueMinorThreshold", 2000) -... - - - - - If this parameter is not set, then there will be no minor alarm - monitoring. - -
- -
- <varname>MsgQueueMajorThreshold</varname> (Integer) - - - The SNMPStats module monitors the number of bytes waiting to be - consumed by OpenSIPS. If the number of bytes waiting to be consumed - exceeds a major threshold, the SNMPStats module will send out an - openserMsgQueueDepthMajorEvent trap to signal that an alarm condition - has occurred. The major threshold is set with the - MsgQueueMajorThreshold parameter. - - - - Setting the <varname>MsgQueueMajorThreshold</varname> parameter - - -... -modparam("snmpstats", "MsgQueueMajorThreshold", 5000) -... - - - - - If this parameter is not set, then there will be no major alarm - monitoring. - -
- -
- <varname>dlg_minor_threshold</varname> (Integer) - - - The SNMPStats module monitors the number of active dialogs. If the - number of active dialogs exceeds a minor threshold, the SNMPStats - module will send out an openserDialogLimitMinorEvent trap to signal - that an alarm condition has occurred. The minor threshold is set with - the dlg_minor_threshold parameter. - - - - Setting the <varname>dlg_minor_threshold</varname> parameter - - -... - modparam("snmpstats", "dlg_minor_threshold", 500) -... - - - - - If this parameter is not set, then there will be no minor alarm - monitoring. - -
- -
- <varname>dlg_major_threshold</varname> (Integer) - - - The SNMPStats module monitors the number of active dialogs. If - the number of active dialogs exceeds a major threshold, the SNMPStats - module will send out an openserDialogLimitMajorEvent trap to signal - that an alarm condition has occurred. The major threshold is set - with the dlg_major_threshold parameter. - - - - Setting the <varname>dlg_major_threshold</varname> parameter - - -... - modparam("snmpstats", "dlg_major_threshold", 750) -... - - - - - If this parameter is not set, then there will be no major alarm - monitoring. - -
- -
- <varname>snmpgetPath</varname> (String) - - - The SNMPStats module provides the openserSIPServiceStartTime scalar. - This scalar requires the SNMPStats module to perform a snmpget query - to the master agent. You can use this parameter to set the path to - your instance of SNMP's snmpget program. - - - - - Default value is /usr/local/bin/. - - - - - Setting the <varname>snmpgetPath</varname> parameter - -... -modparam("snmpstats", "snmpgetPath", "/my/custom/path/") -... - - -
- -
- <varname>snmpCommunity</varname> (String) - - - The SNMPStats module provides the openserSIPServiceStartTime scalar. - This scalar requires the SNMPStats module to perform a snmpget query - to the master agent. If you have defined a custom community string - for the snmp daemon, you need to specify it with this parameter. - - - - - Default value is public. - - - - - Setting the <varname>snmpCommunity</varname> parameter - -... -modparam("snmpstats", "snmpCommunity", "customCommunityString") -... - - -
- -
-
- Exported Functions - - Currently, there are no exported functions. - -
-
- Installation and Running - - There are several things that need to be done to get the SNMPStats module - compiled and up and running. - - -
- - Compiling the SNMPStats Module - - - In order for the SNMPStats module to compile, you will need to have - installed the packages providing SNMP (Simple Network Management - Protocol) libray and development files. - - - - The SNMPStats modules makefile requires that the SNMP script - "net-snmp-config" can run. - - - - IMPORTANT: By default, SNMP loads mibs from - /var/lib/mibs/ietf/.Keep in mind that you have to copy &osips; - mibs wherevere your mibs folder is. - -
- -
- - Configuring SNMP daemon to allow connections from the SNMPStats module. - - - The SNMPStats module will communicate with the SNMP Master Agent. This - communication happens over a protocol known as AgentX. This means you - need to have an SMP daemon (acting as Master Agent) running - it can - be on the same machine or on a different one. - - - First you need to turn on AgentX support. The exact location of - the configuration file (snmpd.conf) may vary depending on your system. - By default, via a package installation, it is located in: - - /etc/snmp/snmpd.conf. - - At the very end of the file add the following line: - - master agentx - - The line tells SNMP daemon to act as an AgentX master agent, so that it - can accept connections from sub-agents such as the SNMPStats module. - - - There is still one last step. Even though we have configured - SNMP to have AgentX support, we still need to tell the daemon which - interface and port to listen to for AgentX connections. This is done also - via the configuration file (snmpd.conf) : - - agentXSocket tcp:localhost:705 - - This tells SNMP daemon to act as a master agent, listening on the - localhost UDP interface at port 705. - -
- -
- - Configuring the SNMPStats module for communication with a Master Agent - - - The previous section explained how to set up a SNMP master agent to accept - AgentX connections. We now need to tell the SNMPStats module how to - communicate with this master agent. This is done by giving the - SNMPStats module its own SNMP configuration file. The file must be named - "snmpstats.conf", and must be in the same folder as the "snmpd.conf" file - that was configured above. By default this would be: - - /etc/snmp/snmpstats.conf - - The default configuration file included with the distribution can be used, - and contains the following: - - agentXSocket tcp:localhost:705 - - The above line tells the SNMPStats module to register with the master - agent on the localhost, port 705. The parameters should match up with - the snmpd process. - Note that the master agent (snmpd) does not need to be present on the same - machine as OpenSIPS. The localhost could be replaced with any other - machine. - -
- -
- - Testing for a proper Configuration - - - As a quick test to make sure that the SNMPStats module sub-agent can - successfully connect to the SNMP Master agent, be sure the snmpd service - is stopped (/etc/init.d/snmpd stop) and manually start snmpd with the - following: - - snmpd -f -Dagentx -x tcp:localhost:705 2>&1 | less - - You should see something similar to the following: - - No log handling enabled - turning on stderr logging - registered debug token agentx, 1 - ... - Turning on AgentX master support. - agentx/master: initializing... - agentx/master: initializing... DONE - NET-SNMP version 5.3.1 - - Now, start up OpenSIPS in another window. In the snmpd window, you should - see a bunch of: - - agentx/master: handle pdu (req=0x2c58ebd4,trans=0x0,sess=0x0) - agentx/master: open 0x81137c0 - agentx/master: opened 0x814bbe0 = 6 with flags = a0 - agentx/master: send response, stat 0 (req=0x2c58ebd4,trans=0x0,sess=0x0) - agentx_build: packet built okay - - The messages beginning with "agentx" are debug messages stating that - something is happening with an AgentX sub-agent, appearing because of - the -Dagentx snmpd switch. The large number of debug messages appear at - startup as the SNMPStats module registers all of its scalars - and tables with the Master Agent. If you receive these messages, then - SNMPStats module and SNMP daemon have both been configured correctly. - -
- -
-
- diff --git a/modules/snmpstats/doc/snmpstats_faq.xml b/modules/snmpstats/doc/snmpstats_faq.xml deleted file mode 100644 index 6e65435b1e5..00000000000 --- a/modules/snmpstats/doc/snmpstats_faq.xml +++ /dev/null @@ -1,378 +0,0 @@ - - - - - &faqguide; - - - - Where can I find more about SNMP? - - - - There are many websites that explain SNMP at all levels of detail. - A great general introduction can be found at http://en.wikipedia.org/wiki/SNMP - - If you are interested in the nitty gritty details of the protocol, - then please look at RFC 3410. RFC 3410 maps out the many other RFCs - that define SNMP, and can be found at http://www.rfc-archive.org/getrfc.php?rfc=3410 - - INFO: Also if you want a nice tutorial for setting up snmpstats with &osips; try - this one. - - - - - - Where can I find more about NetSNMP? - - - - NetSNMP source code, documentation, FAQs, and tutorials can all be found at - http://net-snmp.sourceforge.net/. - - - - - - Where can I find out more about AgentX? - - - - The full details of the AgentX protocol are explained in RFC 2741, - available at: http://www.rfc-archive.org/getrfc.php?rfc=2741 - - - - - - Why am I not receiving any SNMP Traps? - - - - Assuming you've configured the trap thresholds in opensips.cfg with something similar to: - - - - modparam("snmpstats", "MsgQueueMinorThreshold", 1234) - modparam("snmpstats", "MsgQueueMajorThreshold", 5678) - - modparam("snmpstats", "dlg_minor_threshold", 500) - modparam("snmpstats", "dlg_minor_threshold", 600) - - - Then either OpenSIPS is not reaching these thresholds (which is a good thing), - or you haven't set up the trap monitor correctly. To prove this to yourself, - you can start NetSNMP with: - - - - snmpd -f -Dtrap -x localhost:705 - - - - The -f tells the NetSNMP process to not daemonize, and the -Dtrap enables trap - debug logs. You should see something similar to the following: - - - - registered debug token trap, 1 - trap: adding callback trap sink ----- You should see both - trapsess: adding to trap table ----- of these lines. - Turning on AgentX master support. - trap: send_trap 0 0 NET-SNMP-TC::linux - trap: sending trap type=167, version=1 - NET-SNMP version 5.3.1 - - - - If the two lines above did not appear, then you probably have not included - the following in your snmpd.conf file. - - - - trap2sink machineToSendTrapsTo:machinesPortNumber. - - - - When a trap has been received by snmpd, the following will appear in the - above output: - - - - sent_trap -1 -1 NET-SNMP-TC::linus - sending trap type=167, version=1 - - - - You'll also need a program to collect the traps and do something with them - (such as sending them to syslog). NetSNMP provides snmptrapd for this. Other - solutions exist as well. Google is your friend. - - - - - - OpenSIPS refuses to load the SNMPStats module. Why is it displaying "load_module: could not open module snmpstats.so"? - - - - - On some systems, you may receive the following error at stdout or the log files - depending on the configuration. - - - - ERROR: load_module: could not open module </usr/local/lib/opensips/modules/snmpstats.so>: - libnetsnmpmibs.so.10: cannot open shared object file: No such file or directory. - - - - This means one of two things: - - - - - - You did not install NetSNMP. ("make install" if building from source) - - - - - The dynamic linker cannot find the necessary libraries. - - - - - - In the second case, the fix is as follows: - - - - - - find / -name "libnetsnmpmibs*" - - - - You will find a copy unless you haven't installed NetSNMP. - Make note of the path. - - - - - - - - less /etc/ld.so.conf - - - - If the file is missing the path from step 1, then add the path to - ld.so.conf - - - - - - - - - ldconfig - - - - - Try starting OpenSIPS again. - - - - - - Alternatively, you may prefix your startup command with: - - - - LD_LIBRARY_PATH=/path/noted/in/step/one/above - - - - For example, on my system I ran: - - - - LD_LIBRARY_PATH=/usr/local/lib /etc/init.d/opensips start - - - - - - - How can I learn what all the scalars and tables are? - - - - All scalars and tables are named in the SNMPStats module overview. The files - OPENSER-MIB, OPENSER-REG-MIB, OPENSER-SIP-COMMON-MIB and OPENSER-SIP-SERVER-MIB - contain the full definitions and descriptions. Note however, that the MIBs - may actually contain scalars and tables which are currently not provided by the - SNMPStats module. Therefore, it is better to use NetSNMP's snmptranslate - as an alternative. Take the openserSIPEntityType scalar as an example. You can - invoke snmptranslate as follows: - - - snmptranslate -TBd openserSIPEntityType - - - Which would result in something similar to the following: - - - -- FROM OPENSER-SIP-COMMON-MIB - -- TEXTUAL CONVENTION OpenSIPSSIPEntityRole - SYNTAX BITS {other(0), userAgent(1), proxyServer(2), redirectServer(3), registrarServer(4)} - MAX-ACCESS read-only - STATUS current - DESCRIPTION " This object identifies the list of SIP entities this - row is related to. It is defined as a bit map. Each - bit represents a type of SIP entity. - If a bit has value 1, the SIP entity represented by - this row plays the role of this entity type. - - If a bit has value 0, the SIP entity represented by - this row does not act as this entity type - Combinations of bits can be set when the SIP entity - plays multiple SIP roles." - - - - - - - - Why do snmpget, snmpwalk, and snmptable always time out? - - - - If your snmp operations are always returning with: "Timeout: No Response - from localhost", then chances are that you are making the query with the wrong - community string. Default installs will most likely use "public" as their - default community strings. Grep your snmpd.conf file for the string - "rocommunity", and use the result as your community string in your queries. - - - - - - How do I use snmpget? - - - - NetSNMP's snmpget is used as follows: - - - snmpget -v 2c -c theCommunityString machineToSendTheMachineTo scalarElement.0 - - - For example, consider an snmpget on the openserSIPEntityType scalar, - run on the same machine running the OpenSIPS instance, with the default - "public" community string. The command would be: - - - snmpget -v2c -c public localhost openserSIPEntityType.0 - - - Which would result in something similar to: - - - OPENSER-SIP-COMMON-MIB::openserSIPEntityType.0 = BITS: F8 \ - other(0) userAgent(1) proxyServer(2) \ - redirectServer(3) registrarServer(4) - - - - - - - - How do I use snmptable? - - - - NetSNMP's snmptable is used as follows: - - - snmptable -Ci -v 2c -c theCommunityString machineToSendTheMachineTo theTableName - - - For example, consider the openserSIPRegUserTable. If we run the snmptable - command on the same machine as the running OpenSIPS instance, configured with - the default "public" community string. The command would be: - - - snmptable -Ci -v 2c -c public localhost openserSIPRegUserTable - - - Which would result in something similar to: - - - index openserSIPUserUri openserSIPUserAuthenticationFailures - 1 DefaultUser 0 - 2 bogdan 0 - 3 jeffrey.magder 0 - - - - - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/sockets_mgm/README b/modules/sockets_mgm/README deleted file mode 100644 index 7db6cdd4a5a..00000000000 --- a/modules/sockets_mgm/README +++ /dev/null @@ -1,323 +0,0 @@ -Dynamic Sockets Management Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Sockets - - 1.2.1. UDP handling - 1.2.2. TCP handling - - 1.3. Limitations - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. db_url (string) - 1.5.2. table_name (string) - 1.5.3. socket_column (string) - 1.5.4. advertised_column (string) - 1.5.5. tag_column (string) - 1.5.6. flags_column (string) - 1.5.7. tos_column (string) - 1.5.8. processes (integer) - 1.5.9. max_sockets (integer) - - 1.6. Exported MI Functions - - 1.6.1. sockets_reload - 1.6.2. sockets_list - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set “db_url” parameter - 1.2. Set “table_name” parameter - 1.3. Set “socket_column” parameter - 1.4. Set “advertised_column” parameter - 1.5. Set “tag_column” parameter - 1.6. Set “flags_column” parameter - 1.7. Set “tos_column” parameter - 1.8. Set “processes” parameter - 1.9. Set “max_sockets” parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides the means to provision and manage dynamic - sockets for OpenSIPS at runtime. The definition of the sockets - is stored in an SQL database and can be dynamically changed at - runtime. - - The module caches the entire table sockets and only adjusts the - dynamic socket list after a reload using the sockets_reload MI - command. - - The sockets_list MI command. can be used to show all the - dynamic sockets OpenSIPS is listening on. - -1.2. Sockets - - The module exclusively handles sockets used for SIP traffic - (e.g., UDP, TCP, TLS, WSS). It does not support BIN or HEP - listeners, as these cannot be dynamically utilized or enforced - in the script. - - The management of dynamic sockets is divided into two - behaviors, depending on whether the traffic is UDP-based or - TCP-based. Based on the nature of your traffic, ensure that - your settings are properly tuned to accommodate any sockets you - may provision dynamically. - -1.2.1. UDP handling - - All dynamically added UDP sockets are assigned to a group of - dedicated extra processes. The number of these processes can be - adjusted using the processes parameter. These processes handle - UDP-based socket traffic evenly by balancing requests across - the less loaded processes. The difference, however, is that - static sockets are bound to designated processes, while dynamic - sockets share the pool of extra processes. - -1.2.2. TCP handling - - In contrast to UDP traffic handling, TCP traffic is processed - in the same way as all other TCP traffic: requests are - dispatched to one of the existing static TCP processes. - -1.3. Limitations - - Although traffic processing by dynamic workers closely - resembles that of static ones, there are certain limitations - associated with using dynamic sockets: - - * UDP socket handling does not currently benefit from the - autoscaling feature for the designated extra processes. - This means that the number of processes defined at startup - will always be forked, and only these processes will handle - all traffic associated with dynamically added UDP sockets. - * As stated earlier, the module only supports SIP based - dynamic listener, no HEP or BIN. - * Sockets defined in the database cannot be expanded to more - than one listener. This means you cannot use an interface - name or an alias that resolves to multiple IPs as a host. - Only a single IP:port socket will be created, so - provisioning should ideally be done with an explicit IP. - * Due to some internal limitations, the dynamic sockets need - to be pre-allocated at startup. This means that the number - of dynamic sockets used at runtime have to be limited by a - static value, defined at startup. This is why it is - recommended to use a fairly high value for the sockets in - the max_sockets parameter - we're defaulting a confortable - 100 sockets. - * The sockets defined in the max_sockets are being rotated in - a FIFO manner - this way we are trying to avoid overlapping - sockets in a short period of time. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * A database module is needed for fetching the sockets. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. db_url (string) - - The database URL where the sockets are fetched from. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set “db_url” parameter -... -modparam("sockets_mgm", "db_url", "dbdriver://username:password@dbhost/d -bname") -... - -1.5.2. table_name (string) - - The database table name where the sockets are stored. - - Default value is “sockets”. - - Example 1.2. Set “table_name” parameter -... -modparam("sockets_mgm", "table_name", "sockets_def") -... - -1.5.3. socket_column (string) - - The database table column where the socket definition is - stored. - - Default value is “socket”. - - Example 1.3. Set “socket_column” parameter -... -modparam("sockets_mgm", "socket_column", "sock") -... - -1.5.4. advertised_column (string) - - The database table column where the advertised definition is - stored. - - Default value is “advertised”. - - Example 1.4. Set “advertised_column” parameter -... -modparam("advertiseds_mgm", "advertised_column", "adv") -... - -1.5.5. tag_column (string) - - The database table column where the tag definition is stored. - - Default value is “tag”. - - Example 1.5. Set “tag_column” parameter -... -modparam("tags_mgm", "tag_column", "sock") -... - -1.5.6. flags_column (string) - - The database table column where the flags definition is stored. - - Default value is “flags”. - - Example 1.6. Set “flags_column” parameter -... -modparam("flagss_mgm", "flags_column", "sock") -... - -1.5.7. tos_column (string) - - The database table column where the tos definition is stored. - - Default value is “tos”. - - Example 1.7. Set “tos_column” parameter -... -modparam("toss_mgm", "tos_column", "sock") -... - -1.5.8. processes (integer) - - The number of processes designated to handle UDP sockets. - - Default value is “8”. - - Example 1.8. Set “processes” parameter -... -modparam("sockets_mgm", "processes", 32) -... - -1.5.9. max_sockets (integer) - - The maximum number of sockets that can be defined dynamically. - See the Limitations section for more information. - - Default value is “100”. - - Example 1.9. Set “max_sockets” parameter -... -modparam("sockets_mgm", "max_sockets", 2000) -... - -1.6. Exported MI Functions - -1.6.1. sockets_reload - - MI command used to reload the sockets from the database. - - MI FIFO Command Format: - ## reload sockets from the database - opensips-mi sockets_reload - opensips-cli -x mi sockets_reload - -1.6.2. sockets_list - - MI command to list all the currently used dynamic sockets. - - MI FIFO Command Format: - ## reload sockets from the database - opensips-mi sockets_list - opensips-cli -x mi sockets_list - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 33 4 2207 572 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2025 - Jun 2025 - 2. Razvan Crainea (@razvancrainea) Mar 2025 - May 2025 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2025 OpenSIPS Solutions; diff --git a/modules/sockets_mgm/README.md b/modules/sockets_mgm/README.md new file mode 100644 index 00000000000..9e7802d7c0f --- /dev/null +++ b/modules/sockets_mgm/README.md @@ -0,0 +1,300 @@ +--- +title: "Dynamic Sockets Management Module" +description: "This module provides the means to provision and manage dynamic sockets for OpenSIPS at runtime." +--- + +## Admin Guide + + +### Overview + + +This module provides the means to provision and manage dynamic sockets +for OpenSIPS at runtime. The definition of the sockets is stored in +an SQL database and can be dynamically changed at runtime. + + +The module caches the entire table sockets and only adjusts the +dynamic socket list after a reload using the +[mi sockets reload](#mi_sockets_reload) MI command. + + +The [mi sockets list](#mi_sockets_list) MI command. +can be used to show all the dynamic sockets OpenSIPS is listening on. + + +### Sockets + + +The module exclusively handles sockets used for SIP traffic (e.g., +UDP, TCP, TLS, WSS). It does not support BIN or HEP listeners, as +these cannot be dynamically utilized or enforced in the script. + + +The management of dynamic sockets is divided into two behaviors, +depending on whether the traffic is UDP-based or TCP-based. Based on +the nature of your traffic, ensure that your settings are +properly tuned to accommodate any sockets you may provision +dynamically. + + +#### UDP handling + + +All dynamically added UDP sockets are assigned to a group of dedicated +extra processes. The number of these processes can be adjusted using +the [processes](#param_processes) parameter. These processes handle +UDP-based socket traffic evenly by balancing requests across the less +loaded processes. The difference, however, is that static sockets are +bound to designated processes, while dynamic sockets share the pool of +extra processes. + + +#### TCP handling + + +In contrast to UDP traffic handling, TCP traffic is processed in the +same way as all other TCP traffic: requests are dispatched to one of +the existing static TCP processes. + + +### Limitations + + +Although traffic processing by dynamic workers closely resembles that +of static ones, there are certain limitations associated with using +dynamic sockets: + + +- UDP socket handling does not currently benefit from the +autoscaling feature for the designated extra +processes. This means that the number of +[processes](#param_processes) defined at startup will +always be forked, and only these processes will handle all +traffic associated with dynamically added UDP sockets. +- As stated earlier, the module only supports SIP based dynamic +listener, no HEP or BIN. +- Sockets defined in the database cannot be expanded to more than +one listener. This means you cannot use an interface name or an +alias that resolves to multiple IPs as a host. Only a single +IP:port socket will be created, so provisioning should ideally be +done with an explicit IP. +- Due to some internal limitations, the dynamic sockets need to be +pre-allocated at startup. This means that the number of dynamic +sockets used at runtime have to be limited by a static value, +defined at startup. This is why it is recommended to use a fairly +high value for the sockets in the [max sockets](#param_max_sockets) +parameter - we're defaulting a confortable 100 sockets. +- The sockets defined in the [max sockets](#param_max_sockets) are +being rotated in a FIFO manner - this way we are trying to avoid +overlapping sockets in a short period of time. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *A database module is needed for fetching the sockets*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +The database URL where the sockets are fetched from. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set 'db_url' parameter" +... +modparam("sockets_mgm", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### table_name (string) + + +The database table name where the sockets are stored. + + +*Default value is "sockets".* + + +```opensips title="Set 'table_name' parameter" +... +modparam("sockets_mgm", "table_name", "sockets_def") +... +``` + + +#### socket_column (string) + + +The database table column where the socket definition is stored. + + +*Default value is "socket".* + + +```opensips title="Set 'socket_column' parameter" +... +modparam("sockets_mgm", "socket_column", "sock") +... +``` + + +#### advertised_column (string) + + +The database table column where the advertised definition is stored. + + +*Default value is "advertised".* + + +```opensips title="Set 'advertised_column' parameter" +... +modparam("advertiseds_mgm", "advertised_column", "adv") +... +``` + + +#### tag_column (string) + + +The database table column where the tag definition is stored. + + +*Default value is "tag".* + + +```opensips title="Set 'tag_column' parameter" +... +modparam("tags_mgm", "tag_column", "sock") +... +``` + + +#### flags_column (string) + + +The database table column where the flags definition is stored. + + +*Default value is "flags".* + + +```opensips title="Set 'flags_column' parameter" +... +modparam("flagss_mgm", "flags_column", "sock") +... +``` + + +#### tos_column (string) + + +The database table column where the tos definition is stored. + + +*Default value is "tos".* + + +```opensips title="Set 'tos_column' parameter" +... +modparam("toss_mgm", "tos_column", "sock") +... +``` + + +#### processes (integer) + + +The number of processes designated to handle UDP sockets. + + +*Default value is "8".* + + +```opensips title="Set 'processes' parameter" +... +modparam("sockets_mgm", "processes", 32) +... +``` + + +#### max_sockets (integer) + + +The maximum number of sockets that can be defined dynamically. +See the [limitations](#limitations) section for more information. + + +*Default value is "100".* + + +```opensips title="Set 'max_sockets' parameter" +... +modparam("sockets_mgm", "max_sockets", 2000) +... +``` + + +### Exported MI Functions + + +#### sockets_reload + + +MI command used to reload the sockets from the database. + + +MI FIFO Command Format: + + +```bash +## reload sockets from the database +opensips-mi sockets_reload +opensips-cli -x mi sockets_reload +``` + + +#### sockets_list + + +MI command to list all the currently used dynamic sockets. + + +MI FIFO Command Format: + + +```bash +## reload sockets from the database +opensips-mi sockets_list +opensips-cli -x mi sockets_list +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sockets_mgm/doc/contributors.xml b/modules/sockets_mgm/doc/contributors.xml deleted file mode 100644 index 8255198b8a9..00000000000 --- a/modules/sockets_mgm/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 33 - 4 - 2207 - 572 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2025 - Jun 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Mar 2025 - May 2025 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/sockets_mgm/doc/sockets_mgm.xml b/modules/sockets_mgm/doc/sockets_mgm.xml deleted file mode 100644 index 465e7c0d16c..00000000000 --- a/modules/sockets_mgm/doc/sockets_mgm.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Dynamic Sockets Management Module - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2025 OpenSIPS Solutions; - diff --git a/modules/sockets_mgm/doc/sockets_mgm_admin.xml b/modules/sockets_mgm/doc/sockets_mgm_admin.xml deleted file mode 100644 index 14380fd14db..00000000000 --- a/modules/sockets_mgm/doc/sockets_mgm_admin.xml +++ /dev/null @@ -1,361 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides the means to provision and manage dynamic sockets - for OpenSIPS at runtime. The definition of the sockets is stored in - an SQL database and can be dynamically changed at runtime. - - - The module caches the entire table sockets and only adjusts the - dynamic socket list after a reload using the - MI command. - - - The MI command. - can be used to show all the dynamic sockets OpenSIPS is listening on. - -
- -
- Sockets - - The module exclusively handles sockets used for SIP traffic (e.g., - UDP, TCP, TLS, WSS). It does not support BIN or HEP listeners, as - these cannot be dynamically utilized or enforced in the script. - - - The management of dynamic sockets is divided into two behaviors, - depending on whether the traffic is UDP-based or TCP-based. Based on - the nature of your traffic, ensure that your settings are - properly tuned to accommodate any sockets you may provision - dynamically. - -
- UDP handling - - All dynamically added UDP sockets are assigned to a group of dedicated - extra processes. The number of these processes can be adjusted using - the parameter. These processes handle - UDP-based socket traffic evenly by balancing requests across the less - loaded processes. The difference, however, is that static sockets are - bound to designated processes, while dynamic sockets share the pool of - extra processes. - - - -
-
- TCP handling - - In contrast to UDP traffic handling, TCP traffic is processed in the - same way as all other TCP traffic: requests are dispatched to one of - the existing static TCP processes. - -
-
- -
- Limitations - - Although traffic processing by dynamic workers closely resembles that - of static ones, there are certain limitations associated with using - dynamic sockets: - - - - - - UDP socket handling does not currently benefit from the - autoscaling feature for the designated extra - processes. This means that the number of - defined at startup will - always be forked, and only these processes will handle all - traffic associated with dynamically added UDP sockets. - - - - - As stated earlier, the module only supports SIP based dynamic - listener, no HEP or BIN. - - - - - Sockets defined in the database cannot be expanded to more than - one listener. This means you cannot use an interface name or an - alias that resolves to multiple IPs as a host. Only a single - IP:port socket will be created, so provisioning should ideally be - done with an explicit IP. - - - - - Due to some internal limitations, the dynamic sockets need to be - pre-allocated at startup. This means that the number of dynamic - sockets used at runtime have to be limited by a static value, - defined at startup. This is why it is recommended to use a fairly - high value for the sockets in the - parameter - we're defaulting a confortable 100 sockets. - - - - - The sockets defined in the are - being rotated in a FIFO manner - this way we are trying to avoid - overlapping sockets in a short period of time. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - A database module is needed for fetching the sockets. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - The database URL where the sockets are fetched from. - - - - Default value is &defaultdb;. - - - - Set <quote>db_url</quote> parameter - -... -modparam("sockets_mgm", "db_url", "&exampledb;") -... - - -
-
- <varname>table_name</varname> (string) - - The database table name where the sockets are stored. - - - - Default value is sockets. - - - - Set <quote>table_name</quote> parameter - -... -modparam("sockets_mgm", "table_name", "sockets_def") -... - - -
-
- <varname>socket_column</varname> (string) - - The database table column where the socket definition is stored. - - - - Default value is socket. - - - - Set <quote>socket_column</quote> parameter - -... -modparam("sockets_mgm", "socket_column", "sock") -... - - -
-
- <varname>advertised_column</varname> (string) - - The database table column where the advertised definition is stored. - - - - Default value is advertised. - - - - Set <quote>advertised_column</quote> parameter - -... -modparam("advertiseds_mgm", "advertised_column", "adv") -... - - -
-
- <varname>tag_column</varname> (string) - - The database table column where the tag definition is stored. - - - - Default value is tag. - - - - Set <quote>tag_column</quote> parameter - -... -modparam("tags_mgm", "tag_column", "sock") -... - - -
-
- <varname>flags_column</varname> (string) - - The database table column where the flags definition is stored. - - - - Default value is flags. - - - - Set <quote>flags_column</quote> parameter - -... -modparam("flagss_mgm", "flags_column", "sock") -... - - -
-
- <varname>tos_column</varname> (string) - - The database table column where the tos definition is stored. - - - - Default value is tos. - - - - Set <quote>tos_column</quote> parameter - -... -modparam("toss_mgm", "tos_column", "sock") -... - - -
-
- <varname>processes</varname> (integer) - - The number of processes designated to handle UDP sockets. - - - - Default value is 8. - - - - Set <quote>processes</quote> parameter - -... -modparam("sockets_mgm", "processes", 32) -... - - -
-
- <varname>max_sockets</varname> (integer) - - The maximum number of sockets that can be defined dynamically. - See the section for more information. - - - - Default value is 100. - - - - Set <quote>max_sockets</quote> parameter - -... -modparam("sockets_mgm", "max_sockets", 2000) -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">sockets_reload</function> - - - MI command used to reload the sockets from the database. - - - MI FIFO Command Format: - - - ## reload sockets from the database - opensips-mi sockets_reload - opensips-cli -x mi sockets_reload - -
-
- - <function moreinfo="none">sockets_list</function> - - - MI command to list all the currently used dynamic sockets. - - - MI FIFO Command Format: - - - ## reload sockets from the database - opensips-mi sockets_list - opensips-cli -x mi sockets_list - -
-
- -
diff --git a/modules/sockets_mgm/sockets_mgm.c b/modules/sockets_mgm/sockets_mgm.c index 5f6636cde01..49ef23601c2 100644 --- a/modules/sockets_mgm/sockets_mgm.c +++ b/modules/sockets_mgm/sockets_mgm.c @@ -60,6 +60,7 @@ static db_func_t sock_mgm_db_func; static unsigned long *sock_mgm_version; static unsigned int sock_mgm_max_sockets = SOCKETS_MGM_DEFAULT_MAX_SOCKS; static gen_lock_t *sock_mgm_lock; +static gen_lock_t *sock_mgm_reload_lock; static int *sock_mgm_proc_no; static int sock_mgm_unix[2]; extern int is_tcp_main; @@ -219,6 +220,11 @@ static int mod_init(void) LM_ERR("initializing sock_mgm_version lock\n"); return -1; } + sock_mgm_reload_lock = lock_alloc(); + if (!sock_mgm_reload_lock || !lock_init(sock_mgm_reload_lock)) { + LM_ERR("initializing sock_mgm_reload lock\n"); + return -1; + } if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock_mgm_unix) < 0) { LM_ERR("socketpair failed %d/%s\n", @@ -1145,6 +1151,21 @@ static void rpc_socket_reload_proc(int sender_id, void *_ver) int sockets_update_count = 0, fd; LM_NOTICE("Reloading process for version %lu\n", version); + + /* Serialize the entire send-IPC-to-mgm and receive-fd sequence across + * all non-dynamic (worker) processes. Without this, multiple workers + * calling receive_fd() concurrently on the shared sock_mgm_unix + * socketpair can steal each other's fd responses, causing the same + * socket to be added to a worker's listener list twice and corrupting + * it into a circular linked list (infinite loop in sock_listadd). + * + * Dynamic (mgm) processes don't use receive_fd - they create sockets + * directly - so they must NOT acquire this lock, otherwise they would + * deadlock with the worker that holds the lock while blocked on + * receive_fd waiting for the mgm to process rpc_sockets_send. */ + if (!sock_mgm_dynamic_proc) + lock_get(sock_mgm_reload_lock); + lock_get(sock_mgm_lock); if (*sock_mgm_version > version) { LM_WARN("new version %lu available (current=%lu)\n", *sock_mgm_version, version); @@ -1171,6 +1192,9 @@ static void rpc_socket_reload_proc(int sender_id, void *_ver) sock_mgm_update_fd(sock, fd); } } + + if (!sock_mgm_dynamic_proc) + lock_release(sock_mgm_reload_lock); } static int sockets_pool_init(void) diff --git a/modules/speeddial/README b/modules/speeddial/README deleted file mode 100644 index 1480f923fb9..00000000000 --- a/modules/speeddial/README +++ /dev/null @@ -1,401 +0,0 @@ -SpeedDial Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. user_column (string) - 1.3.3. domain_column (string) - 1.3.4. sd_user_column (string) - 1.3.5. sd_domain_column (string) - 1.3.6. new_uri_column (string) - 1.3.7. domain_prefix (string) - 1.3.8. use_domain (int) - - 1.4. Exported Functions - - 1.4.1. sd_lookup(table [, owner]) - - 1.5. Installation and Running - - 1.5.1. OpenSIPS config file - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set user_column parameter - 1.3. Set domain_column parameter - 1.4. Set sd_user_column parameter - 1.5. Set sd_domain_column parameter - 1.6. Set new_uri_column parameter - 1.7. Set domain_prefix parameter - 1.8. Set use_domain parameter - 1.9. sd_lookup usage - 1.10. OpenSIPS config script - sample speeddial usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides on-server speed dial facilities. An user - can store records consisting of pairs short numbers (2 digits) - and SIP addresses into a table of OpenSIPS. Then it can dial - the two digits whenever it wants to call the SIP address - associated with them. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * database module (mysql, dbtext, ...). - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - The URL of database where the table containing speed dial - records. - - Default value is - mysql://opensipsro:opensipsro@localhost/opensips. - - Example 1.1. Set db_url parameter -... -modparam("speeddial", "db_url", "mysql://user:xxx@localhost/db_name") -... - -1.3.2. user_column (string) - - The name of column storing the user name of the owner of the - speed dial record. - - Default value is “username”. - - Example 1.2. Set user_column parameter -... -modparam("speeddial", "user_column", "userid") -... - -1.3.3. domain_column (string) - - The name of column storing the domain of the owner of the speed - dial record. - - Default value is “domain”. - - Example 1.3. Set domain_column parameter -... -modparam("speeddial", "domain_column", "userdomain") -... - -1.3.4. sd_user_column (string) - - The name of the column storing the user part of the short dial - address. - - Default value is “sd_username”. - - Example 1.4. Set sd_user_column parameter -... -modparam("speeddial", "sd_user_column", "short_user") -... - -1.3.5. sd_domain_column (string) - - The name of the column storing the domain of the short dial - address. - - Default value is “sd_domain”. - - Example 1.5. Set sd_domain_column parameter -... -modparam("speeddial", "sd_domain_column", "short_domain") -... - -1.3.6. new_uri_column (string) - - The name of the column containing the URI that will be use to - replace the short dial URI. - - Default value is “new_uri”. - - Example 1.6. Set new_uri_column parameter -... -modparam("speeddial", "new_uri_column", "real_uri") -... - -1.3.7. domain_prefix (string) - - If the domain of the owner (From URI) starts with the value of - this parameter, then it is stripped before performing the - lookup of the short number. - - Default value is NULL. - - Example 1.7. Set domain_prefix parameter -... -modparam("speeddial", "domain_prefix", "tel.") -... - -1.3.8. use_domain (int) - - The parameter specifies wheter or not to use the domain when - searching a speed dial record (0 - no domain, 1 - use domain - from From URI, 2 - use both domains, from From URI and from - request URI). - - Default value is 0. - - Example 1.8. Set use_domain parameter -... -modparam("speeddial", "use_domain", 1) -... - -1.4. Exported Functions - -1.4.1. sd_lookup(table [, owner]) - - The function lookups the short dial number from R-URI in - 'table' and replaces the R-URI with associated address. - - Meaning of the parameters is as follows: - * table (string) - The name of the table storing the speed - dial records. - * owner (string) - The SIP URI of the owner of short dialing - codes. If not pressent, URI of From header is used. - - This function can be used from REQUEST_ROUTE. - - Example 1.9. sd_lookup usage -... -# 'speed_dial' is the default table name created by opensips db script -if($ru=~"sip:[0-9]{2}@.*") - sd_lookup("speed_dial"); -# use auth username -if($ru=~"sip:[0-9]{2}@.*") - sd_lookup("speed_dial", "sip:$au@$fd"); -... - -1.5. Installation and Running - -1.5.1. OpenSIPS config file - - Next picture displays a sample usage of speeddial. - - Example 1.10. OpenSIPS config script - sample speeddial usage -... -# sample config script to use speeddial module -# - -# ----------- global configuration parameters ------------------------ - -check_via=no # (cmd. line: -v) -dns=no # (cmd. line: -r) -rev_dns=no # (cmd. line: -R) - -# ------------------ module loading ---------------------------------- - -mpath="/usr/local/lib/opensips/modules" -loadmodule "sl.so" -loadmodule "tm.so" -loadmodule "rr.so" -loadmodule "maxfwd.so" -loadmodule "usrloc.so" -loadmodule "registrar.so" -loadmodule "textops.so" -loadmodule "mysql.so" -loadmodule "speeddial.so" -loadmodule "mi_fifo.so" - -# ----------------- setting module-specific parameters --------------- - -# -- mi_fifo params -- - -modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo") - -# -- usrloc params -- - -modparam("usrloc", "db_mode", 0) - -# ------------------------- request routing logic ------------------- - -# main routing logic -route{ - - # initial sanity checks - if (!mf_process_maxfwd_header("10")) - { - sl_send_reply(483,"Too Many Hops"); - exit; - }; - if ($ml >= 65535 ) - { - sl_send_reply(513, "Message too big"); - exit; - }; - - if (!$rm=="REGISTER") record_route(); - - if (loose_route()) - { - if (!t_relay()) - { - sl_reply_error(); - }; - exit; - }; - - if (!is_myself("$rd")) - { - if (!t_relay()) - { - sl_reply_error(); - }; - exit; - }; - - if (is_myself("$rd")) - { - if ($rm=="REGISTER") - { - save("location"); - exit; - }; - - if($ru=~"sip:[0-9]{2}@.*") - sd_lookup("speeddial"); - - lookup("aliases"); - if (!is_myself("$rd")) - { - if (!t_relay()) - { - sl_reply_error(); - }; - exit; - }; - - if (!lookup("location")) - { - sl_send_reply(404, "Not Found"); - exit; - }; - }; - - if (!t_relay()) - { - sl_reply_error(); - }; -} - - -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 27 23 90 147 - 2. Daniel-Constantin Mierla (@miconda) 21 16 127 137 - 3. Liviu Chircu (@liviuchircu) 15 12 38 61 - 4. Elena-Ramona Modroiu 12 2 1063 1 - 5. Razvan Crainea (@razvancrainea) 8 6 11 8 - 6. Vlad Patrascu (@rvlad-patrascu) 6 4 31 35 - 7. Henning Westerholt (@henningw) 4 2 50 41 - 8. Maksym Sobolyev (@sobomax) 4 2 4 5 - 9. Elena-Ramona Modroiu 4 2 4 1 - 10. Sergio Gutierrez 4 2 2 2 - - All remaining contributors: Walter Doekes (@wdoekes), Anca - Vamanu, Andrei Pelinescu-Onciul, Konstantin Bokarius, Julián - Moreno Patiño, Peter Lemenkov (@lemenkov), Edson Gellert - Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - 4. Razvan Crainea (@razvancrainea) Aug 2015 - Jul 2020 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2005 - Mar 2020 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Sergio Gutierrez Nov 2008 - Dec 2008 - 10. Daniel-Constantin Mierla (@miconda) May 2006 - Mar 2008 - - All remaining contributors: Konstantin Bokarius, Edson Gellert - Schubert, Henning Westerholt (@henningw), Anca Vamanu, - Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Elena-Ramona - Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei - Iancu (@bogdan-iancu), Sergio Gutierrez, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2004 Voice Sistem SRL diff --git a/modules/speeddial/README.md b/modules/speeddial/README.md new file mode 100644 index 00000000000..4878f979bb0 --- /dev/null +++ b/modules/speeddial/README.md @@ -0,0 +1,217 @@ +--- +title: "SpeedDial Module" +description: "This module provides on-server speed dial facilities." +--- + +## Admin Guide + + +### Overview + + +This module provides on-server speed dial facilities. An user can store +records consisting of pairs short numbers (2 digits) and SIP addresses +into a table of OpenSIPS. Then it can dial the two digits whenever it +wants to call the SIP address associated with them. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *database module (mysql, dbtext, ...)*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### db_url (string) + + +The URL of database where the table containing speed dial records. + + +*Default value is mysql://opensipsro:opensipsro@localhost/opensips.* + + +```opensips title="Set db_url parameter" +... +modparam("speeddial", "db_url", "mysql://user:xxx@localhost/db_name") +... +``` + + +#### user_column (string) + + +The name of column storing the user name of the owner of the speed dial +record. + + +*Default value is "username".* + + +```opensips title="Set user_column parameter" +... +modparam("speeddial", "user_column", "userid") +... +``` + + +#### domain_column (string) + + +The name of column storing the domain of the owner of the speed dial +record. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("speeddial", "domain_column", "userdomain") +... +``` + + +#### sd_user_column (string) + + +The name of the column storing the user part of the short dial address. + + +*Default value is "sd_username".* + + +```opensips title="Set sd_user_column parameter" +... +modparam("speeddial", "sd_user_column", "short_user") +... +``` + + +#### sd_domain_column (string) + + +The name of the column storing the domain of the short dial address. + + +*Default value is "sd_domain".* + + +```opensips title="Set sd_domain_column parameter" +... +modparam("speeddial", "sd_domain_column", "short_domain") +... +``` + + +#### new_uri_column (string) + + +The name of the column containing the URI that will be use to replace +the short dial URI. + + +*Default value is "new_uri".* + + +```opensips title="Set new_uri_column parameter" +... +modparam("speeddial", "new_uri_column", "real_uri") +... +``` + + +#### domain_prefix (string) + + +If the domain of the owner (From URI) starts with the value of this parameter, then +it is stripped before performing the lookup of the short number. + + +*Default value is NULL.* + + +```opensips title="Set domain_prefix parameter" +... +modparam("speeddial", "domain_prefix", "tel.") +... +``` + + +#### use_domain (int) + + +The parameter specifies wheter or not to use the domain when searching a +speed dial record (0 - no domain, 1 - use domain from From URI, +2 - use both domains, from From URI and from request URI). + + +*Default value is 0.* + + +```opensips title="Set use_domain parameter" +... +modparam("speeddial", "use_domain", 1) +... +``` + + +### Exported Functions + + +#### sd_lookup(table [, owner]) + + +The function lookups the short dial number from R-URI in 'table' and replaces the R-URI with associated address. + + +Meaning of the parameters is as follows: + + +- *table* (string) - The name of the table storing the +speed dial records. +- *owner* (string) - The SIP URI of the owner of +short dialing codes. If not pressent, URI of From header is used. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="sd_lookup usage" +... +# 'speed_dial' is the default table name created by opensips db script +if($ru=~"sip:[0-9]{2}@.*") + sd_lookup("speed_dial"); +# use auth username +if($ru=~"sip:[0-9]{2}@.*") + sd_lookup("speed_dial", "sip:$au@$fd"); +... +``` + + +## Samples + +[samples](./samples/samples.md "include") + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/speeddial/doc/contributors.xml b/modules/speeddial/doc/contributors.xml deleted file mode 100644 index 0466ba3964b..00000000000 --- a/modules/speeddial/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 27 - 23 - 90 - 147 - - - 2. - Daniel-Constantin Mierla (@miconda) - 21 - 16 - 127 - 137 - - - 3. - Liviu Chircu (@liviuchircu) - 15 - 12 - 38 - 61 - - - 4. - Elena-Ramona Modroiu - 12 - 2 - 1063 - 1 - - - 5. - Razvan Crainea (@razvancrainea) - 8 - 6 - 11 - 8 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 31 - 35 - - - 7. - Henning Westerholt (@henningw) - 4 - 2 - 50 - 41 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 5 - - - 9. - Elena-Ramona Modroiu - 4 - 2 - 4 - 1 - - - 10. - Sergio Gutierrez - 4 - 2 - 2 - 2 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Anca Vamanu, Andrei Pelinescu-Onciul, Konstantin Bokarius, Julián Moreno Patiño, Peter Lemenkov (@lemenkov), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 4. - Razvan Crainea (@razvancrainea) - Aug 2015 - Jul 2020 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2005 - Mar 2020 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Sergio Gutierrez - Nov 2008 - Dec 2008 - - - 10. - Daniel-Constantin Mierla (@miconda) - May 2006 - Mar 2008 - - - -
-All remaining contributors: Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Anca Vamanu, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Elena-Ramona Modroiu. -
- -
diff --git a/modules/speeddial/doc/speeddial.xml b/modules/speeddial/doc/speeddial.xml deleted file mode 100644 index 1799c6c7b7f..00000000000 --- a/modules/speeddial/doc/speeddial.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - SpeedDial Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2004 &voicesystem; - - diff --git a/modules/speeddial/doc/speeddial_admin.xml b/modules/speeddial/doc/speeddial_admin.xml deleted file mode 100644 index 880fe781643..00000000000 --- a/modules/speeddial/doc/speeddial_admin.xml +++ /dev/null @@ -1,265 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides on-server speed dial facilities. An user can store - records consisting of pairs short numbers (2 digits) and SIP addresses - into a table of OpenSIPS. Then it can dial the two digits whenever it - wants to call the SIP address associated with them. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - database module (mysql, dbtext, ...). - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>db_url</varname> (string) - - The URL of database where the table containing speed dial records. - - - - Default value is &defaultrodb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("speeddial", "db_url", "mysql://user:xxx@localhost/db_name") -... - - -
-
- <varname>user_column</varname> (string) - - The name of column storing the user name of the owner of the speed dial - record. - - - - Default value is username. - - - - Set <varname>user_column</varname> parameter - -... -modparam("speeddial", "user_column", "userid") -... - - -
-
- <varname>domain_column</varname> (string) - - The name of column storing the domain of the owner of the speed dial - record. - - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - -... -modparam("speeddial", "domain_column", "userdomain") -... - - -
-
- <varname>sd_user_column</varname> (string) - - The name of the column storing the user part of the short dial address. - - - - Default value is sd_username. - - - - Set <varname>sd_user_column</varname> parameter - -... -modparam("speeddial", "sd_user_column", "short_user") -... - - -
-
- <varname>sd_domain_column</varname> (string) - - The name of the column storing the domain of the short dial address. - - - - Default value is sd_domain. - - - - Set <varname>sd_domain_column</varname> parameter - -... -modparam("speeddial", "sd_domain_column", "short_domain") -... - - -
-
- <varname>new_uri_column</varname> (string) - - The name of the column containing the URI that will be use to replace - the short dial URI. - - - - Default value is new_uri. - - - - Set <varname>new_uri_column</varname> parameter - -... -modparam("speeddial", "new_uri_column", "real_uri") -... - - -
-
- <varname>domain_prefix</varname> (string) - - If the domain of the owner (From URI) starts with the value of this parameter, then - it is stripped before performing the lookup of the short number. - - - - Default value is NULL. - - - - Set <varname>domain_prefix</varname> parameter - -... -modparam("speeddial", "domain_prefix", "tel.") -... - - -
-
- <varname>use_domain</varname> (int) - - The parameter specifies wheter or not to use the domain when searching a - speed dial record (0 - no domain, 1 - use domain from From URI, - 2 - use both domains, from From URI and from request URI). - - - - Default value is 0. - - - - Set <varname>use_domain</varname> parameter - -... -modparam("speeddial", "use_domain", 1) -... - - -
-
-
- Exported Functions -
- - <function moreinfo="none">sd_lookup(table [, owner])</function> - - - The function lookups the short dial number from R-URI in 'table' and replaces the R-URI with associated address. - - Meaning of the parameters is as follows: - - - table (string) - The name of the table storing the - speed dial records. - - - - owner (string) - The SIP URI of the owner of - short dialing codes. If not pressent, URI of From header is used. - - - - - This function can be used from REQUEST_ROUTE. - - - <function>sd_lookup</function> usage - -... -# 'speed_dial' is the default table name created by opensips db script -if($ru=~"sip:[0-9]{2}@.*") - sd_lookup("speed_dial"); -# use auth username -if($ru=~"sip:[0-9]{2}@.*") - sd_lookup("speed_dial", "sip:$au@$fd"); -... - - -
-
-
- Installation and Running -
- &osips; config file - - Next picture displays a sample usage of speeddial. - - - &osips; config script - sample speeddial usage - -... -&speeddialcfg; -... - - -
-
-
- diff --git a/modules/speeddial/samples/samples.md b/modules/speeddial/samples/samples.md new file mode 100644 index 00000000000..3458d7b2812 --- /dev/null +++ b/modules/speeddial/samples/samples.md @@ -0,0 +1,4 @@ +### OpenSIPS Config Script - Speeddial Usage + +[speeddial.cfg](./speeddial.cfg "include") + diff --git a/modules/speeddial/doc/speeddial.cfg b/modules/speeddial/samples/speeddial.cfg similarity index 100% rename from modules/speeddial/doc/speeddial.cfg rename to modules/speeddial/samples/speeddial.cfg diff --git a/modules/sql_cacher/README.md b/modules/sql_cacher/README.md new file mode 100644 index 00000000000..9eda35c9116 --- /dev/null +++ b/modules/sql_cacher/README.md @@ -0,0 +1,422 @@ +--- +title: "SQL Cacher Module" +description: "The sql_cacher module introduces the possibility to cache data from a SQL-based database (using different OpenSIPS modules which implement the DB API) into a cache system implemented in OpenSIPS through the CacheDB Interface." +--- + +## Admin Guide + + +### Overview + + +The sql_cacher module introduces the possibility to cache data from a +SQL-based database (using different OpenSIPS modules which implement the DB API) +into a cache system implemented in OpenSIPS through the CacheDB Interface. +This is done by specifying the databases URLs, SQL table to be used, desired +columns to be cached and other details in the OpenSIPS configuration script. + + +The cached data is available in the script through the read-only pseudovariable +"$sql_cached_value" similar to a Key-Value system. A specified +column from the SQL table has the role of "key" therefore the value +of this column along with the name of a required column are provided as +"parameters" to the pseudovariable returning the appropriate value of the column. + + +There are two types of caching available: + + +- *full caching* - the entire SQL table (all the rows) is loaded +into the cache at OpenSIPS startup; +- *on demand* - the rows of the SQL table are loaded at runtime +when appropriate keys are requested. + + +For on demand caching, the stored values have a configurable expire period after +which they are permanently removed unless an MI reload function is called for a +specific key. In the case of full caching the data is automatically reloaded at +a configurable interval. Consequently if the data in the SQL database changes +and a MI reload function is called, the old data remains in cache only +until it expires. + + +### Dependencies + + +The following modules must be loaded before this module: + + +- *The OpenSIPS modules that offer actual database back-end +connection* + + +### Exported Parameters + + +#### cache_table (string) + + +This parameter can be set multiple times in order to cache multiple SQL +tables or even the same table but with a different configuration. The module +distinguishes those different entries by an "id" string. + + +The caching entry is specified via this parameter that has it's own +subparameters. Each of those parameters are separated by a +delimiter configured by [spec delimiter](#param_spec_delimiter) +and have the following format: +*param_name=param_value* +The parameters are: + + +- *id* : cache entry id +- *db_url* : the URL of the SQL database +- *cachedb_url* : the URL of the CacheDB database +- *table* : SQL database table name +- *key* : SQL database column name of the "key" column +- *key_type* : data type for the SQL "key" column: + - string + - int + + *If not present, default value is "string".* +- *columns* : names of the columns to be cached from the +SQL database, separated by a delimiter configured by +[columns delimiter](#param_columns_delimiter). +If not present, all the columns from the table will be cached +- *on_demand* : specifies the type of caching: + - 0 : full caching + - 1 : on demand + + *If not present, default value is "0".* +- *expire* : expire period for the values stored +in the cache for the on demand caching type in seconds +If not present, default value is "1 hour" + + +The parameters must be given in the exact order specified above. + + +Overall, the parameter does not have a default value, it must be set +at least once in order to cache any table. + + +```opensips title="cache_table parameter usage" +modparam("sql_cacher", "cache_table", +"id=caching_name +db_url=mysql://root:opensips@localhost/opensips_2_2 +cachedb_url=mongodb:mycluster://127.0.0.1:27017/db.col +table=table_name +key=column_name_0 +columns=column_name_1 column_name_2 column_name_3 +on_demand=0") +``` + + +#### spec_delimiter (string) + + +The delimiter to be used in the caching entry specification provided in the +*cache_table* parameter to separate the subparameters. It +must be a single character. + + +The default value is newline. + + +```opensips title="spec_delimiter parameter usage" +modparam("sql_cacher", "spec_delimiter", "\n") +``` + + +#### pvar_delimiter (string) + + +The delimiter to be used in the "$sql_cached_value" +pseudovariable to separate the caching id, the desired column name +and the value of the key. It must be a single character. + + +The default value is ":". + + +```opensips title="pvar_delimiter parameter usage" +modparam("sql_cacher", "pvar_delimiter", " ") +``` + + +#### columns_delimiter (string) + + +The delimiter to be used in the *columns* subparameter of +the caching entry specification provided in the *cache_table* +parameter to separate the desired columns names. It must be a single character. + + +The default value is " "(space). + + +```opensips title="columns_delimiter parameter usage" +modparam("sql_cacher", "columns_delimiter", ",") +``` + + +#### sql_fetch_nr_rows (integer) + + +The number of rows to be fetched into OpenSIPS private memory in one chunk from +the SQL database driver. When querying large tables, adjust this parameter +accordingly to avoid the filling of OpenSIPS private memory. + + +The default value is "100". + + +```opensips title="sql_fetch_nr_rows parameter usage" +modparam("sql_cacher", "sql_fetch_nr_rows", 1000) +``` + + +#### full_caching_expire (integer) + + +Expire period for the values stored in cache for the full caching type +in seconds. This is the longest time that deleted or modified data remains +in cache. + + +The default value is "24 hours". + + +```opensips title="full_caching_expire parameter usage" +modparam("sql_cacher", "full_caching_expire", 3600) +``` + + +#### reload_interval (integer) + + +This parameter represents how many seconds before the data expires (for full caching) the +automatic reloading is triggered. + + +The default value is "60 s". + + +```opensips title="reload_interval parameter usage" +modparam("sql_cacher", "reload_interval", 5) +``` + + +#### bigint_to_str (integer) + + +Controls bigint conversion. +By default bigint values are returned as int. +If the value stored in bigint is out of the int range, +by enabling bigint to string conversion, +the bigint value will be returned as string. + + +The default value is "0" (disabled). + + +```opensips title="bigint_to_str parameter usage" +modparam("sql_cacher", "bigint_to_str", 1) +``` + + +### Exported Functions + + +#### sql_cache_dump(caching_id, columns, result_avps) + + +Dump all *columns* cached within the given *caching_id*, +and write them to their respective *result_avps*. + + +Parameters: + + +- *caching_id* (string) - Identifier for the SQL cache +- *columns* (string) - the desired SQL columns to be dumped, +specified as comma-separated values +- *result_avps* (string) - comma-separated list of AVPs where +the results will be written to + + +Return Codes: + + +- **-1** - Internal Error +- **-2** - Zero Results Returned +- **1, 2, 3, ...** - Number of results returned into each output AVP + + +This function can be used from any route. + + +```opensips title="sql_cache_dump usage" +... +# Example of pulling all cached CNAM records +$var(n) = sql_cache_dump("cnam", "caller,callee,calling_name,fraud_score", + "$avp(caller),$avp(callee),$avp(cnam),$avp(fraud)"); +$var(i) = 0; +while ($var(i) < $var(n)) { + xlog("Caller $(avp(caller)[$var(i)]) has CNAM $(avp(cnam)[$var(i)])\n"); + $var(i) += 1; +} +... +``` + + +### Exported MI Functions + + +#### sql_cacher_reload + + +Reloads the entire SQL table in cache or the single key (if key provided) in +*full caching* mode. + + +Reloads the given key or invalidates all the keys in cache in *on demand* mode. + + +Parameters: + + +- *id* - the caching entry's id +- *key* (optional) - the specific key to be reloaded. + + +```bash title="sql_cacher_reload usage" +... +$ opensips-cli -x mi sql_cacher_reload subs_caching +... +$ opensips-cli -x mi sql_cacher_reload subs_caching alice@domain.com +... +``` + + +### Exported Pseudo-Variables + + +#### $sql_cached_value(id{sep}col{sep}key) + + +The cached data is available through this read-only PV.The format +is the following: + + +- *sep* : separator configured by +[pvar delimiter](#param_pvar_delimiter) +- *id* : cache entry id +- *col* : name of the required column +- *key* : value of the "key" column + + +```opensips title="sql_cached_value(id{sep}col{sep}key) pseudo-variable usage" +... +$avp(a) = $sql_cached_value(caching_name:column_name_1:key1); +... + +``` + + +### Usage Example + + +This section provides an usage example for the caching of an SQL table. + + +Suppose one in interested in caching the columns: "host_name", +"reply_code", "flags" and "next_domain" +from the "carrierfailureroute" table of the OpenSIPS database. + + +```c title="Example database content - carrierfailureroute table" +... ++----+---------+-----------+------------+--------+-----+-------------+ +| id | domain | host_name | reply_code | flags | mask | next_domain | ++----+---------+-----------+------------+-------+------+-------------+ +| 1 | 99 | | 408 | 16 | 16 | | +| 2 | 99 | gw1 | 404 | 0 | 0 | 100 | +| 3 | 99 | gw2 | 50. | 0 | 0 | 100 | +| 4 | 99 | | 404 | 2048 | 2112 | asterisk-1 | ++----+---------+-----------+------------+-------+------+-------------+ +... + +``` + + +In the first place, the details of the caching must be provided by setting +the module parameter "cache_table" in the OpenSIPS configuration script. + + +```opensips title="Setting the cache_table parameter" +modparam("sql_cacher", "cache_table", +"id=carrier_fr_caching +db_url=mysql://root:opensips@localhost/opensips +cachedb_url=mongodb:mycluster://127.0.0.1:27017/my_db.col +table=carrierfailureroute +key=id +columns=host_name reply_code flags next_domain") + +``` + + +Next, the values of the cached columns ca be accessed through the "$sql_cached_value" PV. + + +```opensips title="Accessing cached values" +... +$avp(rc1) = $sql_cached_value(carrier_fr_caching:reply_code:1); +$avp(rc2) = $sql_cached_value(carrier_fr_caching:reply_code:2); +... +var(some_id)=4; +$avp(nd) = $sql_cached_value(carrier_fr_caching:next_domain:$var(some_id)); +... +xlog("host name is: $sql_cached_value(carrier_fr_caching:host_name:2)"); +... + +``` + + +### Exported Status/Report Identifiers + + +The module provides the "sql_cacher" Status/Report group, where each +full cache is defined as a separate SR identifier. NOTE that there +are no identifiers created for the on-demand caches. + + +#### [cache_entry_id] + + +The status of these identifiers reflects the readiness/status of the +cached data (if available or not when being loaded from DB): + + +- *-2* - no data at all (initial status) +- *-1* - no data, initial loading in progress +- *1* - data loaded, partition ready +- *2* - data available, a reload in progress + + +In terms of reports/logs, the following events will be reported: + + +- starting DB data loading +- DB data loading failed, discarding +- DB data loading successfully completed +- N records loaded) + + +For how to access and use the Status/Report information, please see +[https://docs.opensips.org/manual/3-6/interface-statusreport/](>https://docs.opensips.org/manual/3-6/interface-statusreport/). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sql_cacher/doc/contributors.xml b/modules/sql_cacher/doc/contributors.xml deleted file mode 100644 index 0cfd83c16aa..00000000000 --- a/modules/sql_cacher/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 94 - 44 - 3640 - 1114 - - - 2. - Liviu Chircu (@liviuchircu) - 30 - 22 - 498 - 150 - - - 3. - Razvan Crainea (@razvancrainea) - 16 - 14 - 33 - 15 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 13 - 10 - 128 - 31 - - - 5. - Ovidiu Sas (@ovidiusas) - 7 - 5 - 83 - 7 - - - 6. - Maksym Sobolyev (@sobomax) - 7 - 5 - 8 - 9 - - - 7. - Bence Szigeti - 4 - 2 - 3 - 2 - - - 8. - Ionel Cerghit (@ionel-cerghit) - 4 - 1 - 50 - 92 - - - 9. - Dan Pascu (@danpascu) - 3 - 1 - 1 - 1 - - - 10. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Gang Zhuo. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2016 - May 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Feb 2016 - Jul 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2017 - Apr 2024 - - - 4. - Ovidiu Sas (@ovidiusas) - Mar 2017 - Apr 2024 - - - 5. - Bence Szigeti - Jan 2024 - Jan 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Oct 2020 - Nov 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - Aug 2015 - Jul 2022 - - - 8. - Gang Zhuo - Nov 2021 - Nov 2021 - - - 9. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - 10. - Dan Pascu (@danpascu) - May 2019 - May 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Ionel Cerghit (@ionel-cerghit). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov). -
- -
diff --git a/modules/sql_cacher/doc/sql_cacher.xml b/modules/sql_cacher/doc/sql_cacher.xml deleted file mode 100644 index 6282408bbca..00000000000 --- a/modules/sql_cacher/doc/sql_cacher.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - SQL Cacher Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - - diff --git a/modules/sql_cacher/doc/sql_cacher_admin.xml b/modules/sql_cacher/doc/sql_cacher_admin.xml deleted file mode 100644 index 37ecccdc99d..00000000000 --- a/modules/sql_cacher/doc/sql_cacher_admin.xml +++ /dev/null @@ -1,539 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The sql_cacher module introduces the possibility to cache data from a - SQL-based database (using different &osips; modules which implement the DB API) - into a cache system implemented in &osips; through the CacheDB Interface. - This is done by specifying the databases URLs, SQL table to be used, desired - columns to be cached and other details in the &osips; configuration script. - - - The cached data is available in the script through the read-only pseudovariable - $sql_cached_value similar to a Key-Value system. A specified - column from the SQL table has the role of key therefore the value - of this column along with the name of a required column are provided as - "parameters" to the pseudovariable returning the appropriate value of the column. - - - There are two types of caching available: - - - full caching - the entire SQL table (all the rows) is loaded - into the cache at &osips; startup; - - - on demand - the rows of the SQL table are loaded at runtime - when appropriate keys are requested. - - - - - For on demand caching, the stored values have a configurable expire period after - which they are permanently removed unless an MI reload function is called for a - specific key. In the case of full caching the data is automatically reloaded at - a configurable interval. Consequently if the data in the SQL database changes - and a MI reload function is called, the old data remains in cache only - until it expires. - -
-
- Dependencies - - The following modules must be loaded before this module: - - - The &osips; modules that offer actual database back-end - connection - - - -
-
- Exported Parameters -
- <varname>cache_table</varname> (string) - - This parameter can be set multiple times in order to cache multiple SQL - tables or even the same table but with a different configuration. The module - distinguishes those different entries by an id string. - - - The caching entry is specified via this parameter that has it's own - subparameters. Each of those parameters are separated by a - delimiter configured by - and have the following format: - param_name=param_value - The parameters are: - - - id : cache entry id - - - db_url : the URL of the SQL database - - - cachedb_url : the URL of the CacheDB database - - - table : SQL database table name - - - key : SQL database column name of the key column - - - key_type : data type for the SQL "key" column: - - - string - - - int - - - If not present, default value is string - - - columns : names of the columns to be cached from the - SQL database, separated by a delimiter configured by - . - If not present, all the columns from the table will be cached - - - on_demand : specifies the type of caching: - - - 0 : full caching - - - 1 : on demand - - - If not present, default value is 0 - - - expire : expire period for the values stored - in the cache for the on demand caching type in seconds - If not present, default value is 1 hour - - - - - The parameters must be given in the exact order specified above. - - - Overall, the parameter does not have a default value, it must be set - at least once in order to cache any table. - - - <varname>cache_table</varname> parameter usage - - -modparam("sql_cacher", "cache_table", -"id=caching_name -db_url=mysql://root:opensips@localhost/opensips_2_2 -cachedb_url=mongodb:mycluster://127.0.0.1:27017/db.col -table=table_name -key=column_name_0 -columns=column_name_1 column_name_2 column_name_3 -on_demand=0") - - - -
- -
- <varname>spec_delimiter</varname> (string) - - The delimiter to be used in the caching entry specification provided in the - cache_table parameter to separate the subparameters. It - must be a single character. - - - The default value is newline. - - - <varname>spec_delimiter</varname> parameter usage - - -modparam("sql_cacher", "spec_delimiter", "\n") - - - -
- -
- <varname>pvar_delimiter</varname> (string) - - The delimiter to be used in the $sql_cached_value - pseudovariable to separate the caching id, the desired column name - and the value of the key. It must be a single character. - - - The default value is :. - - - <varname>pvar_delimiter</varname> parameter usage - - -modparam("sql_cacher", "pvar_delimiter", " ") - - - -
- -
- <varname>columns_delimiter</varname> (string) - - The delimiter to be used in the columns subparameter of - the caching entry specification provided in the cache_table - parameter to separate the desired columns names. It must be a single character. - - - The default value is (space). - - - <varname>columns_delimiter</varname> parameter usage - - -modparam("sql_cacher", "columns_delimiter", ",") - - - -
- -
- <varname>sql_fetch_nr_rows</varname> (integer) - - The number of rows to be fetched into &osips; private memory in one chunk from - the SQL database driver. When querying large tables, adjust this parameter - accordingly to avoid the filling of &osips; private memory. - - - The default value is 100. - - - <varname>sql_fetch_nr_rows</varname> parameter usage - - -modparam("sql_cacher", "sql_fetch_nr_rows", 1000) - - - -
- -
- <varname>full_caching_expire</varname> (integer) - - Expire period for the values stored in cache for the full caching type - in seconds. This is the longest time that deleted or modified data remains - in cache. - - - The default value is 24 hours. - - - <varname>full_caching_expire</varname> parameter usage - - -modparam("sql_cacher", "full_caching_expire", 3600) - - - -
- -
- <varname>reload_interval</varname> (integer) - - This parameter represents how many seconds before the data expires (for full caching) the - automatic reloading is triggered. - - - The default value is 60 s. - - - <varname>reload_interval</varname> parameter usage - - -modparam("sql_cacher", "reload_interval", 5) - - - -
- -
- <varname>bigint_to_str</varname> (integer) - - Controls bigint conversion. - By default bigint values are returned as int. - If the value stored in bigint is out of the int range, - by enabling bigint to string conversion, - the bigint value will be returned as string. - - - The default value is 0 (disabled). - - - <varname>bigint_to_str</varname> parameter usage - - -modparam("sql_cacher", "bigint_to_str", 1) - - - -
- -
- -
-Exported Functions -
- - <function moreinfo="none">sql_cache_dump(caching_id, columns, result_avps)</function> - - - Dump all columns cached within the given caching_id, - and write them to their respective result_avps. - - - Parameters: - - - caching_id (string) - Identifier for the SQL cache - - - columns (string) - the desired SQL columns to be dumped, - specified as comma-separated values - - - result_avps (string) - comma-separated list of AVPs where - the results will be written to - - - - Return Codes: - - - -1 - Internal Error - - - -2 - Zero Results Returned - - - 1, 2, 3, ... - Number of results returned into each output AVP - - - - - - This function can be used from any route. - - - <function moreinfo="none">sql_cache_dump</function> usage - -... -# Example of pulling all cached CNAM records -$var(n) = sql_cache_dump("cnam", "caller,callee,calling_name,fraud_score", - "$avp(caller),$avp(callee),$avp(cnam),$avp(fraud)"); -$var(i) = 0; -while ($var(i) < $var(n)) { - xlog("Caller $(avp(caller)[$var(i)]) has CNAM $(avp(cnam)[$var(i)])\n"); - $var(i) += 1; -} -... - - -
-
- -
- Exported MI Functions -
- <function moreinfo="none">sql_cacher_reload</function> - - Reloads the entire SQL table in cache or the single key (if key provided) in - full caching mode. - - - Reloads the given key or invalidates all the keys in cache in on demand mode. - - Parameters: - - - id - the caching entry's id - - - key (optional) - the specific key to be reloaded. - - - - <function moreinfo="none">sql_cacher_reload</function> usage - -... -$ opensips-cli -x mi sql_cacher_reload subs_caching -... -$ opensips-cli -x mi sql_cacher_reload subs_caching alice@domain.com -... - - -
-
- -
- Exported Pseudo-Variables -
- <varname>$sql_cached_value(id{sep}col{sep}key)</varname> - - The cached data is available through this read-only PV.The format - is the following: - - - sep : separator configured by - - - - id : cache entry id - - - col : name of the required column - - - key : value of the key column - - - - - <function moreinfo="none">sql_cached_value(id{sep}col{sep}key) pseudo-variable</function> usage - -... -$avp(a) = $sql_cached_value(caching_name:column_name_1:key1); -... - - -
- -
- -
- Usage Example - - This section provides an usage example for the caching of an SQL table. - - - Suppose one in interested in caching the columns: host_name, - reply_code, flags and next_domain - from the carrierfailureroute table of the &osips; database. - - - Example database content - carrierfailureroute table - -... -+----+---------+-----------+------------+--------+-----+-------------+ -| id | domain | host_name | reply_code | flags | mask | next_domain | -+----+---------+-----------+------------+-------+------+-------------+ -| 1 | 99 | | 408 | 16 | 16 | | -| 2 | 99 | gw1 | 404 | 0 | 0 | 100 | -| 3 | 99 | gw2 | 50. | 0 | 0 | 100 | -| 4 | 99 | | 404 | 2048 | 2112 | asterisk-1 | -+----+---------+-----------+------------+-------+------+-------------+ -... - - - - In the first place, the details of the caching must be provided by setting - the module parameter cache_table in the &osips; configuration script. - - - Setting the <varname>cache_table</varname> parameter - -modparam("sql_cacher", "cache_table", -"id=carrier_fr_caching -db_url=mysql://root:opensips@localhost/opensips -cachedb_url=mongodb:mycluster://127.0.0.1:27017/my_db.col -table=carrierfailureroute -key=id -columns=host_name reply_code flags next_domain") - - - - Next, the values of the cached columns ca be accessed through the $sql_cached_value PV. - - - Accessing cached values - -... -$avp(rc1) = $sql_cached_value(carrier_fr_caching:reply_code:1); -$avp(rc2) = $sql_cached_value(carrier_fr_caching:reply_code:2); -... -var(some_id)=4; -$avp(nd) = $sql_cached_value(carrier_fr_caching:next_domain:$var(some_id)); -... -xlog("host name is: $sql_cached_value(carrier_fr_caching:host_name:2)"); -... - - -
- - -
- Exported Status/Report Identifiers - - - The module provides the "sql_cacher" Status/Report group, where each - full cache is defined as a separate SR identifier. NOTE that there - are no identifiers created for the on-demand caches. - -
- <varname>[cache_entry_id]</varname> - - The status of these identifiers reflects the readiness/status of the - cached data (if available or not when being loaded from DB): - - - - -2 - no data at all (initial status) - - - -1 - no data, initial loading in progress - - - 1 - data loaded, partition ready - - - 2 - data available, a reload in progress - - - - - In terms of reports/logs, the following events will be reported: - - - - starting DB data loading - - - DB data loading failed, discarding - - - DB data loading successfully completed - - - N records loaded) - - -
- - - For how to access and use the Status/Report information, please see - https://www.opensips.org/Documentation/Interface-StatusReport-3-3. - -
- - -
- diff --git a/modules/sqlops/README b/modules/sqlops/README deleted file mode 100644 index 5e8e45c31b8..00000000000 --- a/modules/sqlops/README +++ /dev/null @@ -1,804 +0,0 @@ -SQLops Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. usr_table (string) - 1.3.3. db_scheme (string) - 1.3.4. use_domain (integer) - 1.3.5. ps_id_max_buf_len (integer) - 1.3.6. bigint_to_str (int) - 1.3.7. uuid_column (string) - 1.3.8. username_column (string) - 1.3.9. domain_column (string) - 1.3.10. attribute_column (string) - 1.3.11. value_column (string) - 1.3.12. type_column (string) - - 1.4. Exported Functions - - 1.4.1. sql_query(query, [res_col_avps], [db_id]) - 1.4.2. sql_query_one(query, [res_col_vars], [db_id]) - - 1.4.3. - sql_select([columns],table,[filter],[order],[r - es_col_avps], [db_id]) - - 1.4.4. - sql_select_one([columns],table,[filter],[order - ],[res_col_vars], [db_id]) - - 1.4.5. sql_update(columns,table,[filter],[db_id]) - 1.4.6. sql_insert(table,columns,[db_id]) - 1.4.7. sql_delete(table,[filter],[db_id]) - 1.4.8. sql_replace(table,columns,[db_id]) - 1.4.9. sql_avp_load(source, name, [db_id], - [prefix]]) - - 1.4.10. sql_avp_store(source, name, [db_id]) - 1.4.11. sql_avp_delete(source, name, [db_id]) - - 1.5. Exported Asynchronous Functions - - 1.5.1. sql_query(query, [dest], [db_id]) - 1.5.2. sql_query_one(query, [dest], [db_id]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set usr_table parameter - 1.3. Set db_scheme parameter - 1.4. Set use_domain parameter - 1.5. Set ps_id_max_buf_len parameter - 1.6. Set bigint_to_str parameter - 1.7. Set uuid_column parameter - 1.8. Set username_column parameter - 1.9. Set domain_column parameter - 1.10. Set attribute_column parameter - 1.11. Set value_column parameter - 1.12. Set type_column parameter - 1.13. sql_query usage - 1.14. sql_query_one usage - 1.15. sql_select usage - 1.16. sql_select_one usage - 1.17. sql_update usage - 1.18. sql_insert usage - 1.19. sql_delete usage - 1.20. sql_avp_load usage - 1.21. sql_avp_store usage - 1.22. sql_avp_delete usage - 1.23. async sql_query usage - 1.24. async sql_query_one usage - -Chapter 1. Admin Guide - -1.1. Overview - - SQLops (SQL-operations) modules implements a set of script - functions for generic SQL standard queries (raw or structure - queries). It also provides a dedicated set of functions for DB - manipulation (loading/storing/removing) of user AVPs - (preferences). - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. db_url (string) - - DB URL for database connection. As the module allows the usage - of multiple DBs (DB URLs), the actual DB URL may be preceded by - an reference number. This reference number is to be passed to - AVPOPS function that what to explicitly use this DB connection. - If no reference number is given, 0 is assumed - this is the - default DB URL. - - This parameter is optional, it's default value being NULL. - - Example 1.1. Set db_url parameter -... -# default URL -modparam("sqlops","db_url","mysql://user:passwd@host/database") -# an additional DB URL -modparam("sqlops","db_url","1 postgres://user:passwd@host2/opensips") -... - -1.3.2. usr_table (string) - - DB table to be used for user preferences (AVPs) - - This parameter is optional, it's default value being - “usr_preferences”. - - Example 1.2. Set usr_table parameter -... -modparam("sqlops","usr_table","avptable") -... - -1.3.3. db_scheme (string) - - Definition of a DB scheme to be used for accessing a - non-standard User Preference -like table. - - Definition of a DB scheme. Scheme syntax is: - * db_scheme = name':'element[';'element]* - * element = - + 'uuid_col='string - + 'username_col='string - + 'domain_col='string - + 'value_col='string - + 'value_type='('integer'|'string') - + 'table='string - - Default value is “NULL”. - - Example 1.3. Set db_scheme parameter -... -modparam("sqlops","db_scheme", -"scheme1:table=subscriber;uuid_col=uuid;value_col=first_name") -... - -1.3.4. use_domain (integer) - - If the domain part of the a SIP URI should be used for - identifying an AVP in DB operations. - - Default value is 0 (no). - - Example 1.4. Set use_domain parameter -... -modparam("sqlops","use_domain",1) -... - -1.3.5. ps_id_max_buf_len (integer) - - The maximum size of the buffer used to build the query IDs - which are used for managing the Prepare Statements when comes - to the "sql_select|update|insert|replace|delete()" functions - - If the size is exceeded (when trying to build the PS query ID), - the PS support will be dropped for the query. If set to 0, the - PS support will be completly disabled. - - Default value is 1024. - - Example 1.5. Set ps_id_max_buf_len parameter -... -modparam("sqlops","ps_id_max_buf_len", 2048) -... - -1.3.6. bigint_to_str (int) - - Controls bigint conversion. By default bigint values are - returned as int. If the value stored in bigint is out of the - int range, by enabling bigint to string conversion, the bigint - value will be returned as string. - - Default value is “0”. - - Example 1.6. Set bigint_to_str parameter -... -# Return bigint as string -modparam("sqlops","bigint_to_str",1) -... - -1.3.7. uuid_column (string) - - Name of column containing the uuid (unique user id). - - Default value is “uuid”. - - Example 1.7. Set uuid_column parameter -... -modparam("sqlops","uuid_column","uuid") -... - -1.3.8. username_column (string) - - Name of column containing the username. - - Default value is “username”. - - Example 1.8. Set username_column parameter -... -modparam("sqlops","username_column","username") -... - -1.3.9. domain_column (string) - - Name of column containing the domain name. - - Default value is “domain”. - - Example 1.9. Set domain_column parameter -... -modparam("sqlops","domain_column","domain") -... - -1.3.10. attribute_column (string) - - Name of column containing the attribute name (AVP name). - - Default value is “attribute”. - - Example 1.10. Set attribute_column parameter -... -modparam("sqlops","attribute_column","attribute") -... - -1.3.11. value_column (string) - - Name of column containing the AVP value. - - Default value is “value”. - - Example 1.11. Set value_column parameter -... -modparam("sqlops","value_column","value") -... - -1.3.12. type_column (string) - - Name of column containing the AVP type. - - Default value is “type”. - - Example 1.12. Set type_column parameter -... -modparam("sqlops","type_column","type") -... - -1.4. Exported Functions - -1.4.1. sql_query(query, [res_col_avps], [db_id]) - - Make a database query and store the result in AVPs. - - The meaning and usage of the parameters: - * query (string) - must be a valid SQL query. The parameter - can contain pseudo-variables. - You must escape any pseudo-variables manually to prevent - SQL injection attacks. You can use the existing - transformations escape.common and unescape.common to escape - and unescape the content of any pseudo-variable. Failing to - escape the variables used in the query makes you vulnerable - to SQL injection, e.g. make it possible for an outside - attacker to alter your database content. The function - returns true if the query was successful, -2 in case the - query returned an empty result set, and -1 for all other - types of errors. - * res_col_avps (string, optional, no expand) - a list with - AVP names where to store the result. The format is - “$avp(name1);$avp(name2);...”. If this parameter is - omitted, the result is stored in “$avp(1);$avp(2);...”. If - the result consists of multiple rows, then multiple AVPs - with corresponding names will be added. The value type of - the AVP (string or integer) will be derived from the type - of the columns. If the value in the database is NULL, the - returned avp will be a string with the value. - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the “db_url” module parameter. It can - be either a constant, or a string/int variable. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.13. sql_query usage -... -sql_query("SELECT password, ha1 FROM subscriber WHERE username='$tu'", - "$avp(pass);$avp(hash)"); -sql_query("DELETE FROM subscriber"); -sql_query("DELETE FROM subscriber", , 2); - -$avp(id) = 2; -sql_query("DELETE FROM subscriber", , $avp(id)); -... - -1.4.2. sql_query_one(query, [res_col_vars], [db_id]) - - Similar to sql_query(), it makes a generic raw database query - and returns the results, but with the following differences: - * returns only one row - even if the query results in a multi - row result, only the first row will be returned to script. - * return variables are not limited to AVPs - the variables - for returning the query result may any kind of variable, of - course, as time as it is writeable. NOTE that the number of - return vairable MUST match (as number) the number of - returned columns. If less variables are provided, the query - will fail. - * NULL is returned - any a DB NULL value resulting from the - query will be pushed as NULL indicator (and NOT as - string) to the script variables. - - This function can be used from any type of route. - - Example 1.14. sql_query_one usage -... -sql_query_one("SELECT password, ha1 FROM subscriber WHERE username='$tU' -", - "$var(pass);$var(hash)"); -# $var(pass) or $var(hash) may be NULL if the corresponding columns -# are not populated -... -sql_query_one("SELECT value, type FROM usr_preferences WHERE username='$ -fU' and attribute='cfna'", - "$var(cf_uri);$var(type)"); -# the above query will return only one row, even if there are multiple ` -cfna` -# attributes for the user -... - -1.4.3. sql_select([columns],table,[filter],[order],[res_col_avps], -[db_id]) - - Function to perform a structured (not raw) SQL SELECT - operation. The query is performed via OpenSIPS internal SQL - interface, taking advantages of the prepared-statements support - (if the db backend provides something like that). The selected - columns are returned into a set of AVPs (one to one matching - the selected columns). - -Warning - - If using varibales in constructing the query, you must manually - escape their values in order to prevent SQL injection attacks. - You can use the existing transformations escape.common and - unescape.common to escape and unescape the content of any - pseudo-variable. Failing to escape the variables used in the - query makes you vulnerable to SQL injection, e.g. make it - possible for an outside attacker to alter your database - content. - - The function returns true if the query was successful, -2 in - case the query returned an empty result set, and -1 for all - other types of errors. - - The meaning and usage of the parameters: - * columns (string,optional) - JSON formated string holding an - array of columns to be returned by the select. Ex: - “["col1","col2"]”. If missing, a “*” (all columns) select - will be performed. - * table (string, mandatory) - the name of the table to be - queried. - * filter (string, optional) - JSON formated string holding - the "where" filter of the query. This must be an array of - (column, operator,value) pairs. The exact JSON syntax of - such a pair is “{"column":{"operator":"value"}}”.; - operators may be `>`, `<`, `=`, `!=` or custom string; The - values may be string, integer or `null`. To simplify the - usage with the `=` operator, you can use - “{"column":"value"}” If missing, all rows will be selected. - * order (string, optional) - the name of the column to oder - by (only ascending). - * res_col_avps (string, optional, no expand) - a list with - AVP names where to store the result. The format is - “$avp(name1);$avp(name2);...”. If this parameter is - omitted, the result is stored in “$avp(1);$avp(2);...”. If - the result consists of multiple rows, then multiple AVPs - with corresponding names will be added. The value type of - the AVP (string or integer) will be derived from the type - of the columns. If the value in the database is NULL, the - returned avp will be a string with the value. - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the db_url module parameter. It can be - either a constant, or a string/int variable. - - This function can be used from any type of route. - - Example 1.15. sql_select usage -... -sql_select('["password","ha1"]', 'subscriber', - '[ {"username": "$tu"}, {"domain": {"!=", null}}]', , - '$avp(pass);$avp(hash)'); -... - -1.4.4. -sql_select_one([columns],table,[filter],[order],[res_col_vars], -[db_id]) - - Similar to sql_select(), it makes a SELECT SQL query and - returns the results, but with the following differences: - * returns only one row - even if the query results in a multi - row result, only the first row will be returned to script. - * return variables are not limited to AVPs - the variables - for returning the query result may any kind of variable, of - course, as time as it is writeable. NOTE that the number of - return vairable MUST match (as number) the number of - returned columns. If less variables are provided, the query - will fail. - * NULL is returned - any a DB NULL value resulting from the - query will be pushed as NULL indicator (and NOT as - string) to the script variables. - - This function can be used from any type of route. - - Example 1.16. sql_select_one usage -... -sql_select_one('["value","type"]', 'usr_preferences', - '[ {"username": "$tu"}, {"attribute": "cfna"}]', , - '$var(cf_uri);$var(type)'); -# the above query will return only one row, even if there are multiple ` -cfna` -# attributes for the user -... - -1.4.5. sql_update(columns,table,[filter],[db_id]) - - Function to perform a structured (not raw) SQL UPDATE - operation. IMPORTANT: please see all the general notes from the - sql_select() function. - - The function returns true if the query was successful. - - The meaning and usage of the parameters: - * columns (string,mandatory) - JSON formated string holding - an array of (column,value) pairs to be updated by the - query. Ex: “[{"col1":"val1"},{"col2":"val1"}]”. - * table (string, mandatory) - the name of the table to be - queried. - * filter (string, optional) - JSON formated string holding - the "where" filter of the query. This must be an array of - (column, operator,value) pairs. The exact JSON syntax of - such a pair is “{"column":{"operator":"value"}}”.; - operators may be `>`, `<`, `=`, `!=` or custom string; The - values may be string, integer or `null`. To simplify the - usage with the `=` operator, you can use - “{"column":"value"}” If missing, all rows will be updated. - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the db_url module parameter. It can be - either a constant, or a string/int variable. - - This function can be used from any type of route. - - Example 1.17. sql_update usage -... -sql_update( '[{"password":"my_secret"}]', 'subscriber', - '[{"username": "$tu"}]'); -... - -1.4.6. sql_insert(table,columns,[db_id]) - - Function to perform a structured (not raw) SQL INSERT - operation. IMPORTANT: please see all the general notes from the - sql_select() function. - - The function returns true if the query was successful. - - The meaning and usage of the parameters: - * table (string, mandatory) - the name of the table to be - queried. - * columns (string,mandatory) - JSON formated string holding - an array of (column,value) pairs to be inserted. Ex: - “[{"col1":"val1"},{"col2":"val1"}]”. - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the db_url module parameter. It can be - either a constant, or a string/int variable. - - This function can be used from any type of route. - - Example 1.18. sql_insert usage -... -sql_insert( 'cc_agents', '[{"agentid":"agentX"},{"skills":"info"},{"loca -tion":null},{"msrp_location":"sip:agentX@opensips.com"},{"msrp_max_sessi -ons":2}]' ); -... - -1.4.7. sql_delete(table,[filter],[db_id]) - - Function to perform a structured (not raw) SQL DELETE - operation. IMPORTANT: please see all the general notes from the - sql_select() function. - - The function returns true if the query was successful. - - The meaning and usage of the parameters: - * table (string, mandatory) - the name of the table to delete - from. - * filter (string, optional) - JSON formated string holding - the "where" filter of the query. This must be an array of - (column, operator,value) pairs. The exact JSON syntax of - such a pair is “{"column":{"operator":"value"}}”.; - operators may be `>`, `<`, `=`, `!=` or custom string; The - values may be string, integer or `null`. To simplify the - usage with the `=` operator, you can use - “{"column":"value"}” If missing, all rows will be updated. - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the db_url module parameter. It can be - either a constant, or a string/int variable. - - This function can be used from any type of route. - - Example 1.19. sql_delete usage -... -sql_delete( 'subscriber', '[{"username": "$tu"}]'); -... - -1.4.8. sql_replace(table,columns,[db_id]) - - Function very similar to sql_insert() function, but performing - an SQL REPLACE operation instead. Note that not all SQL backend - in OpenSIPS may support a REPLACE operation. - - The function returns true if the query was successful. - -1.4.9. sql_avp_load(source, name, [db_id], [prefix]]) - - Loads from DB into memory the AVPs corresponding to the given - source. If given, it sets the script flags for loaded AVPs. It - returns true if it loaded some values in AVPs, false otherwise - (db error, no avp loaded ...). - - AVPs may be preceded by an optional prefix, in order to avoid - some conflicts. - - Meaning of the parameters is as follows: - * source (string, no expand) - what info is used for - identifying the AVPs. Parameter syntax: - + source = (pvar|str_value) - ['/'('username'|'domain'|'uri'|'uuid')]) - + pvar = any pseudo variable defined in OpenSIPS. If the - pvar is $ru (request uri), $fu (from uri), $tu (to - uri) or $ou (original uri), then the implicit flag is - 'uri'. Otherwise, the implicit flag is 'uuid'. - * name (string, no expand) - which AVPs will be loaded from - DB into memory. Parameter syntax is: - + name = avp_spec['/'(table_name|'$'db_scheme)] - * db_id (int, optional) - reference to a defined DB URL (a - numerical id) - see the “db_url” module parameter. - * prefix (string, optional) - static string which will - precede the names of the AVPs populated by this function. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.20. sql_avp_load usage -... -sql_avp_load("$fu", "$avp(678)"); -sql_avp_load("$ru/domain", "i/domain_preferences"); -sql_avp_load("$avp(uuid)", "$avp(404fwd)/fwd_table"); -sql_avp_load("$ru", "$avp(123)/$some_scheme"); - -# use DB URL id 3 -sql_avp_load("$ru", "$avp(1)", 3); - -# precede all loaded AVPs by the "caller_" prefix -sql_avp_load("$ru", "$avp(100)", , "caller_"); -xlog("Loaded: $avp(caller_100)\n"); - -... - -1.4.10. sql_avp_store(source, name, [db_id]) - - Stores to DB the AVPs corresponding to the given source. - - The meaning and usage of the parameters are identical as for - sql_avp_load(source, name) function. Please refer to its - description. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.21. sql_avp_store usage -... -sql_avp_store("$tu", "$avp(678)"); -sql_avp_store("$ru/username", "$avp(email)"); -# use DB URL id 3 -sql_avp_store("$ru", "$avp(1)", 3); -... - -1.4.11. sql_avp_delete(source, name, [db_id]) - - Deletes from DB the AVPs corresponding to the given source. - - The meaning and usage of the parameters are identical as for - sql_avp_load(source, name) function. Please refer to its - description. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.22. sql_avp_delete usage -... -sql_avp_delete("$tu", "$avp(678)"); -sql_avp_delete("$ru/username", "$avp(email)"); -sql_avp_delete("$avp(uuid)", "$avp(404fwd)/fwd_table"); -# use DB URL id 3 -sql_avp_delete("$ru", "$avp(1)", 3); -... - -1.5. Exported Asynchronous Functions - -1.5.1. sql_query(query, [dest], [db_id]) - - This function takes the same parameters and behaves identically - to sql_query(), but asynchronously (after launching the query, - the current SIP worker pauses the execution of the current SIP - message until the result is available and attempts to process - more SIP traffic). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - Example 1.23. async sql_query usage -... -{ -... -/* Example of a slow MySQL query - it should take around 5 seconds */ -async( - sql_query( - "SELECT table_name, table_version, SLEEP(0.1) from versi -on", - "$avp(tb_name); $avp(tb_ver); $avp(retcode)"), - my_resume_route); -/* script execution is halted right after the async() call */ -} - -/* We will be called when data is ready - meanwhile, the worker is free -*/ -route [my_resume_route] -{ - xlog("Results: \n$(avp(tb_name)[*])\n --------------------\n$(avp(tb_ver)[*])\n --------------------\n$(avp(retcode)[*])\n"); -} -... - -1.5.2. sql_query_one(query, [dest], [db_id]) - - This function takes the same parameters and behaves identically - to sql_query_one(), but asynchronously (after launching the - query, the current SIP worker pauses the execution of the - current SIP message until the result is available and attempts - to process more SIP traffic). - - This function can be used from any route. - - Example 1.24. async sql_query_one usage -... -{ -... -/* Example of a slow MySQL query - it should take around 5 seconds */ -async( - sql_query_one( - "SELECT table_name, table_version, SLEEP(0.1) from versi -on", - "$var(tb_name); $var(tb_ver); $var(retcode)"), - my_resume_route); -/* script execution is halted right after the async() call */ -} - -/* We will be called when data is ready - meanwhile, the worker is free -*/ -route [my_resume_route] -{ - xlog("Result: $var(tb_name) | $var(tb_ver) | $(var(retcode)\n"); -} -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 250 74 6054 7542 - 2. Daniel-Constantin Mierla (@miconda) 105 44 2927 2158 - 3. Liviu Chircu (@liviuchircu) 54 28 1116 948 - 4. Elena-Ramona Modroiu 52 11 4040 390 - 5. Razvan Crainea (@razvancrainea) 21 14 149 246 - 6. Elena-Ramona Modroiu 18 5 1051 192 - 7. Henning Westerholt (@henningw) 12 8 112 133 - 8. Vlad Paiu (@vladpaiu) 9 7 39 2 - 9. Ionut Ionita (@ionutrazvanionita) 8 5 180 12 - 10. Norman Brandinger (@NormB) 7 5 37 10 - - All remaining contributors: Kobi Eshun (@ekobi), Andrei - Pelinescu-Onciul, Maksym Sobolyev (@sobomax), Anca Vamanu, - Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Klaus - Darilion, John Burke (@john08burke), Andrey Vorobiev, Nick - Altmann (@nikbyte), Olle E. Johansson, Kennard White, Julián - Moreno Patiño, Konstantin Bokarius, Walter Doekes (@wdoekes), - Andreas Granig, Peter Lemenkov (@lemenkov), Sergio Gutierrez, - Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2005 - May 2025 - 2. Maksym Sobolyev (@sobomax) Oct 2022 - Apr 2025 - 3. Norman Brandinger (@NormB) Aug 2006 - Mar 2025 - 4. Nick Altmann (@nikbyte) Feb 2025 - Feb 2025 - 5. Liviu Chircu (@liviuchircu) Mar 2013 - May 2024 - 6. Ovidiu Sas (@ovidiusas) Jul 2015 - Apr 2024 - 7. Vlad Paiu (@vladpaiu) Jun 2011 - Jul 2023 - 8. Razvan Crainea (@razvancrainea) Jun 2011 - Mar 2023 - 9. John Burke (@john08burke) Jun 2022 - Jun 2022 - 10. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2019 - - All remaining contributors: Peter Lemenkov (@lemenkov), Andrey - Vorobiev, Julián Moreno Patiño, Ionut Ionita - (@ionutrazvanionita), Walter Doekes (@wdoekes), Anca Vamanu, - Kennard White, Sergio Gutierrez, Kobi Eshun (@ekobi), Henning - Westerholt (@henningw), Olle E. Johansson, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Klaus Darilion, Andreas Granig, Andrei - Pelinescu-Onciul, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Ovidiu Sas - (@ovidiusas), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan - Crainea (@razvancrainea), John Burke (@john08burke), Peter - Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Vlad - Paiu (@vladpaiu), Anca Vamanu, Norman Brandinger (@NormB), Kobi - Eshun (@ekobi), Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Elena-Ramona Modroiu, Klaus Darilion, Andrei - Pelinescu-Onciul, Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2009-2024 www.opensips-solutions.com - - Copyright © 2004-2008 Voice Sistem SRL diff --git a/modules/sqlops/README.md b/modules/sqlops/README.md new file mode 100644 index 00000000000..d46007a50ab --- /dev/null +++ b/modules/sqlops/README.md @@ -0,0 +1,811 @@ +--- +title: "SQLops Module" +description: "SQLops (SQL-operations) modules implements a set of script functions for generic SQL standard queries (raw or structure queries)." +--- + +## Admin Guide + + +### Overview + + +SQLops (SQL-operations) modules implements a set of script +functions for generic SQL standard queries (raw or structure queries). +It also provides a dedicated set of functions for DB manipulation +(loading/storing/removing) of user AVPs (preferences). + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### db_url (string) + + +DB URL for database connection. As the module allows the usage +of multiple DBs (DB URLs), the actual DB URL may be preceded by +an reference number. This reference number is to be passed to +AVPOPS function that what to explicitly use this DB connection. +If no reference number is given, 0 is assumed - this is the default +DB URL. + + +*This parameter is optional, it's default value being NULL.* + + +```opensips title="Set db_url parameter" +... +# default URL +modparam("sqlops","db_url","mysql://user:passwd@host/database") +# an additional DB URL +modparam("sqlops","db_url","1 postgres://user:passwd@host2/opensips") +... + +``` + + +#### usr_table (string) + + +DB table to be used for user preferences (AVPs) + + +*This parameter is optional, it's default value being +"usr_preferences".* + + +```opensips title="Set usr_table parameter" +... +modparam("sqlops","usr_table","avptable") +... + +``` + + +#### db_scheme (string) + + +Definition of a DB scheme to be used for accessing +a non-standard User Preference -like table. + + +Definition of a DB scheme. Scheme syntax is: + + +- *db_scheme = name':'element[';'element]** +- *element* = + - 'uuid_col='string + - 'username_col='string + - 'domain_col='string + - 'value_col='string + - 'value_type='('integer'|'string') + - 'table='string + + +*Default value is "NULL".* + + +```opensips title="Set db_scheme parameter" +... +modparam("sqlops","db_scheme", +"scheme1:table=subscriber;uuid_col=uuid;value_col=first_name") +... +``` + + +#### use_domain (integer) + + +If the domain part of the a SIP URI should be used for +identifying an AVP in DB operations. + + +*Default value is 0 (no).* + + +```opensips title="Set use_domain parameter" +... +modparam("sqlops","use_domain",1) +... +``` + + +#### ps_id_max_buf_len (integer) + + +The maximum size of the buffer used to build the query IDs which +are used for managing the Prepare Statements when comes to the +"sql_select|update|insert|replace|delete()" functions + + +If the size is exceeded (when trying to build the PS query ID), +the PS support will be dropped for the query. If set to 0, the PS +support will be completly disabled. + + +*Default value is 1024.* + + +```opensips title="Set ps_id_max_buf_len parameter" +... +modparam("sqlops","ps_id_max_buf_len", 2048) +... +``` + + +#### bigint_to_str (int) + + +Controls bigint conversion. +By default bigint values are returned as int. +If the value stored in bigint is out of the int range, +by enabling bigint to string conversion, +the bigint value will be returned as string. + + +*Default value is "0".* + + +```opensips title="Set bigint_to_str parameter" +... +# Return bigint as string +modparam("sqlops","bigint_to_str",1) +... +``` + + +#### uuid_column (string) + + +Name of column containing the uuid (unique user id). + + +*Default value is "uuid".* + + +```opensips title="Set uuid_column parameter" +... +modparam("sqlops","uuid_column","uuid") +... +``` + + +#### username_column (string) + + +Name of column containing the username. + + +*Default value is "username".* + + +```opensips title="Set username_column parameter" +... +modparam("sqlops","username_column","username") +... +``` + + +#### domain_column (string) + + +Name of column containing the domain name. + + +*Default value is "domain".* + + +```opensips title="Set domain_column parameter" +... +modparam("sqlops","domain_column","domain") +... +``` + + +#### attribute_column (string) + + +Name of column containing the attribute name (AVP name). + + +*Default value is "attribute".* + + +```opensips title="Set attribute_column parameter" +... +modparam("sqlops","attribute_column","attribute") +... +``` + + +#### value_column (string) + + +Name of column containing the AVP value. + + +*Default value is "value".* + + +```opensips title="Set value_column parameter" +... +modparam("sqlops","value_column","value") +... +``` + + +#### type_column (string) + + +Name of column containing the AVP type. + + +*Default value is "type".* + + +```opensips title="Set type_column parameter" +... +modparam("sqlops","type_column","type") +... +``` + + +### Exported Functions + + +#### sql_query(query, [res_col_avps], [db_id]) + + +Make a database query and store the result in AVPs. + + +The meaning and usage of the parameters: + + +- *query (string)* - must be a valid SQL +query. The parameter can contain pseudo-variables. +You must escape any pseudo-variables manually to prevent +SQL injection attacks. You can use the existing transformations +*escape.common* and +*unescape.common* +to escape and unescape the content of any pseudo-variable. +Failing to escape the variables used in the query makes you +vulnerable to SQL injection, e.g. make it possible for an +outside attacker to alter your database content. +The function returns true if the query was successful, -2 in +case the query returned an empty result set, and -1 for all +other types of errors. +- *res_col_avps (string, optional, no expand)* - a list with AVP names where +to store the result. The format is +"$avp(name1);$avp(name2);...". If this parameter +is omitted, the result is stored in +"$avp(1);$avp(2);...". If the result consists of +multiple rows, then multiple AVPs with corresponding names will +be added. The value type of the AVP (string or integer) will +be derived from the type of the columns. If the value in the +database is *NULL*, the returned avp will +be a string with the ** value. +- *db_id (int, optional)* - reference to a defined +DB URL (a numerical id) - see the "db_url" +module parameter. It can be either a constant, or a +string/int variable. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="sql_query usage" +... +sql_query("SELECT password, ha1 FROM subscriber WHERE username='$tu'", + "$avp(pass);$avp(hash)"); +sql_query("DELETE FROM subscriber"); +sql_query("DELETE FROM subscriber", , 2); + +$avp(id) = 2; +sql_query("DELETE FROM subscriber", , $avp(id)); +... +``` + + +#### sql_query_one(query, [res_col_vars], [db_id]) + + +Similar to [sql query](#func_sql_query), it makes a generic raw +database query and returns the results, but with the following +differences: + + +- *returns only one row* - even if +the query results in a multi row result, only the first row +will be returned to script. +- *return variables are not limited to AVPs* - +the variables for returning the query result may any kind +of variable, of course, as time as it is writeable. NOTE that +the number of return vairable MUST match (as number) the number +of returned columns. If less variables are provided, the query +will fail. +- *NULL is returned* - any a DB NULL +value resulting from the query will be pushed as NULL indicator +(and NOT as ** string) to the +script variables. + + +This function can be used from any type of route. + + +```opensips title="sql_query_one usage" +... +sql_query_one("SELECT password, ha1 FROM subscriber WHERE username='$tU'", + "$var(pass);$var(hash)"); +# $var(pass) or $var(hash) may be NULL if the corresponding columns +# are not populated +... +sql_query_one("SELECT value, type FROM usr_preferences WHERE username='$fU' and attribute='cfna'", + "$var(cf_uri);$var(type)"); +# the above query will return only one row, even if there are multiple `cfna` +# attributes for the user +... +``` + + +#### sql_select([columns],table,[filter],[order],[res_col_avps], [db_id]) + + +Function to perform a structured (not raw) SQL SELECT operation. +The query is performed via OpenSIPS internal SQL interface, taking +advantages of the prepared-statements support (if the db backend +provides something like that). The selected columns are returned +into a set of AVPs (one to one matching the selected columns). + + +> [!WARNING] +> If using varibales in constructing the query, you must +> manually escape their values in order to prevent SQL injection +> attacks. You can use the existing transformations +> *escape.common* and +> *unescape.common* +> to escape and unescape the content of any pseudo-variable. +> Failing to escape the variables used in the query makes you +> vulnerable to SQL injection, e.g. make it possible for an +> outside attacker to alter your database content. + + +The function returns true if the query was successful, -2 in +case the query returned an empty result set, and -1 for all +other types of errors. + + +The meaning and usage of the parameters: + + +- *columns (string,optional)* - JSON +formated string holding an array of columns to be returned by +the select. Ex: "["col1","col2"]". +If missing, a "*" (all columns) select will be +performed. +- *table (string, mandatory)* - the +name of the table to be queried. +- *filter (string, optional)* - JSON +formated string holding the "where" filter of the query. This +must be an array of (column, operator,value) pairs. The +exact JSON syntax of such a pair is +"{"column":{"operator":"value"}}".; operators +may be `>`, `<`, `=`, `!=` or custom string; The values +may be string, integer or `null`. To simplify the usage with +the `=` operator, you can use "{"column":"value"}" +If missing, all rows will be selected. +- *order (string, optional)* - the +name of the column to oder by (only ascending). +- *res_col_avps (string, optional, no expand)* - a list with AVP names where +to store the result. The format is +"$avp(name1);$avp(name2);...". If this parameter +is omitted, the result is stored in +"$avp(1);$avp(2);...". If the result consists of +multiple rows, then multiple AVPs with corresponding names will +be added. The value type of the AVP (string or integer) will +be derived from the type of the columns. If the value in the +database is *NULL*, the returned avp will +be a string with the ** value. +- *db_id (int, optional)* - reference +to a defined DB URL (a numerical id) - see the +[db url](#param_db_url) module parameter. It can +be either a constant, or a string/int variable. + + +This function can be used from any type of route. + + +```opensips title="sql_select usage" +... +sql_select('["password","ha1"]', 'subscriber', + '[ {"username": "$tu"}, {"domain": {"!=", null}}]', , + '$avp(pass);$avp(hash)'); +... + +``` + + +#### sql_select_one([columns],table,[filter],[order],[res_col_vars], [db_id]) + + +Similar to [sql select](#func_sql_select), it makes a SELECT SQL +query and returns the results, but with the following +differences: + + +- *returns only one row* - even if +the query results in a multi row result, only the first row +will be returned to script. +- *return variables are not limited to AVPs* - +the variables for returning the query result may any kind +of variable, of course, as time as it is writeable. NOTE that +the number of return vairable MUST match (as number) the number +of returned columns. If less variables are provided, the query +will fail. +- *NULL is returned* - any a DB NULL +value resulting from the query will be pushed as NULL indicator +(and NOT as ** string) to the +script variables. + + +This function can be used from any type of route. + + +```opensips title="sql_select_one usage" +... +sql_select_one('["value","type"]', 'usr_preferences', + '[ {"username": "$tu"}, {"attribute": "cfna"}]', , + '$var(cf_uri);$var(type)'); +# the above query will return only one row, even if there are multiple `cfna` +# attributes for the user +... + +``` + + +#### sql_update(columns,table,[filter],[db_id]) + + +Function to perform a structured (not raw) SQL UPDATE operation. +IMPORTANT: please see all the general notes from the +[sql select](#func_sql_select) function. + + +The function returns true if the query was successful. + + +The meaning and usage of the parameters: + + +- *columns (string,mandatory)* - JSON +formated string holding an array of (column,value) pairs to +be updated by the query. +Ex: "[{"col1":"val1"},{"col2":"val1"}]". +- *table (string, mandatory)* - the +name of the table to be queried. +- *filter (string, optional)* - JSON +formated string holding the "where" filter of the query. This +must be an array of (column, operator,value) pairs. The +exact JSON syntax of such a pair is +"{"column":{"operator":"value"}}".; operators +may be `>`, `<`, `=`, `!=` or custom string; The values +may be string, integer or `null`. To simplify the usage with +the `=` operator, you can use "{"column":"value"}" +If missing, all rows will be updated. +- *db_id (int, optional)* - reference +to a defined DB URL (a numerical id) - see the +[db url](#param_db_url) module parameter. It can +be either a constant, or a string/int variable. + + +This function can be used from any type of route. + + +```opensips title="sql_update usage" +... +sql_update( '[{"password":"my_secret"}]', 'subscriber', + '[{"username": "$tu"}]'); +... + +``` + + +#### sql_insert(table,columns,[db_id]) + + +Function to perform a structured (not raw) SQL INSERT operation. +IMPORTANT: please see all the general notes from the +[sql select](#func_sql_select) function. + + +The function returns true if the query was successful. + + +The meaning and usage of the parameters: + + +- *table (string, mandatory)* - the +name of the table to be queried. +- *columns (string,mandatory)* - JSON +formated string holding an array of (column,value) pairs to +be inserted. +Ex: "[{"col1":"val1"},{"col2":"val1"}]". +- *db_id (int, optional)* - reference +to a defined DB URL (a numerical id) - see the +[db url](#param_db_url) module parameter. It can +be either a constant, or a string/int variable. + + +This function can be used from any type of route. + + +```opensips title="sql_insert usage" +... +sql_insert( 'cc_agents', '[{"agentid":"agentX"},{"skills":"info"},{"location":null},{"msrp_location":"sip:agentX@opensips.com"},{"msrp_max_sessions":2}]' ); +... + +``` + + +#### sql_delete(table,[filter],[db_id]) + + +Function to perform a structured (not raw) SQL DELETE operation. +IMPORTANT: please see all the general notes from the +[sql select](#func_sql_select) function. + + +The function returns true if the query was successful. + + +The meaning and usage of the parameters: + + +- *table (string, mandatory)* - the +name of the table to delete from. +- *filter (string, optional)* - JSON +formated string holding the "where" filter of the query. This +must be an array of (column, operator,value) pairs. The +exact JSON syntax of such a pair is +"{"column":{"operator":"value"}}".; operators +may be `>`, `<`, `=`, `!=` or custom string; The values +may be string, integer or `null`. To simplify the usage with +the `=` operator, you can use "{"column":"value"}" +If missing, all rows will be updated. +- *db_id (int, optional)* - reference +to a defined DB URL (a numerical id) - see the +[db url](#param_db_url) module parameter. It can +be either a constant, or a string/int variable. + + +This function can be used from any type of route. + + +```opensips title="sql_delete usage" +... +sql_delete( 'subscriber', '[{"username": "$tu"}]'); +... + +``` + + +#### sql_replace(table,columns,[db_id]) + + +Function very similar to [sql insert](#func_sql_insert) function, +but performing an SQL REPLACE operation instead. Note that not all +SQL backend in OpenSIPS may support a REPLACE operation. + + +The function returns true if the query was successful. + + +#### sql_avp_load(source, name, [db_id], [prefix]]) + + +Loads from DB into memory the AVPs corresponding to the given +*source*. If given, it sets the script flags +for loaded AVPs. It returns true if it loaded some values +in AVPs, false otherwise (db error, no avp loaded ...). + + +AVPs may be preceded by an optional *prefix*, in +order to avoid some conflicts. + + +Meaning of the parameters is as follows: + + +- *source (string, no expand)* - what info is used for +identifying the AVPs. Parameter syntax: + - *source = (pvar|str_value) + ['/'('username'|'domain'|'uri'|'uuid')])* + - *pvar = any pseudo variable defined in OpenSIPS. If + the pvar is $ru (request uri), $fu (from uri), $tu (to uri) + or $ou (original uri), then the implicit flag is 'uri'. + Otherwise, the implicit flag is 'uuid'.* +- *name (string, no expand)* - which AVPs will be loaded +from DB into memory. Parameter syntax is: + - *name = avp_spec['/'(table_name|'$'db_scheme)]* +- *db_id (int, optional)* - reference to a defined +DB URL (a numerical id) - see the "db_url" +module parameter. +- *prefix (string, optional)* - static string which will +precede the names of the AVPs populated by this function. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="sql_avp_load usage" +... +sql_avp_load("$fu", "$avp(678)"); +sql_avp_load("$ru/domain", "i/domain_preferences"); +sql_avp_load("$avp(uuid)", "$avp(404fwd)/fwd_table"); +sql_avp_load("$ru", "$avp(123)/$some_scheme"); + +# use DB URL id 3 +sql_avp_load("$ru", "$avp(1)", 3); + +# precede all loaded AVPs by the "caller_" prefix +sql_avp_load("$ru", "$avp(100)", , "caller_"); +xlog("Loaded: $avp(caller_100)\n"); +... +``` + + +#### sql_avp_store(source, name, [db_id]) + + +Stores to DB the AVPs corresponding to the given +*source*. + + +The meaning and usage of the parameters are identical as for +*sql_avp_load(source, name)* +function. Please refer to its description. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="sql_avp_store usage" +... +sql_avp_store("$tu", "$avp(678)"); +sql_avp_store("$ru/username", "$avp(email)"); +# use DB URL id 3 +sql_avp_store("$ru", "$avp(1)", 3); +... +``` + + +#### sql_avp_delete(source, name, [db_id]) + + +Deletes from DB the AVPs corresponding to the given +*source*. + + +The meaning and usage of the parameters are identical as for +*sql_avp_load(source, name)* +function. Please refer to its description. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="sql_avp_delete usage" +... +sql_avp_delete("$tu", "$avp(678)"); +sql_avp_delete("$ru/username", "$avp(email)"); +sql_avp_delete("$avp(uuid)", "$avp(404fwd)/fwd_table"); +# use DB URL id 3 +sql_avp_delete("$ru", "$avp(1)", 3); +... +``` + + +### Exported Asynchronous Functions + + +#### sql_query(query, [dest], [db_id]) + + +This function takes the same parameters and behaves identically +to [sql query](#func_sql_query), but asynchronously +(after launching the query, the current SIP worker pauses the +execution of the current SIP message until the result is available +and attempts to process more SIP traffic). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, +BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. + + +```opensips title="async sql_query usage" +... +{ +... +/* Example of a slow MySQL query - it should take around 5 seconds */ +async( + sql_query( + "SELECT table_name, table_version, SLEEP(0.1) from version", + "$avp(tb_name); $avp(tb_ver); $avp(retcode)"), + my_resume_route); +/* script execution is halted right after the async() call */ +} + +/* We will be called when data is ready - meanwhile, the worker is free */ +route [my_resume_route] +{ + xlog("Results: \n$(avp(tb_name)[*])\n +-------------------\n$(avp(tb_ver)[*])\n +-------------------\n$(avp(retcode)[*])\n"); +} +... +``` + + +#### sql_query_one(query, [dest], [db_id]) + + +This function takes the same parameters and behaves identically +to [sql query one](#func_sql_query_one), but asynchronously +(after launching the query, the current SIP worker pauses the +execution of the current SIP message until the result is available +and attempts to process more SIP traffic). + + +This function can be used from any route. + + +```opensips title="async sql_query_one usage" +... +{ +... +/* Example of a slow MySQL query - it should take around 5 seconds */ +async( + sql_query_one( + "SELECT table_name, table_version, SLEEP(0.1) from version", + "$var(tb_name); $var(tb_ver); $var(retcode)"), + my_resume_route); +/* script execution is halted right after the async() call */ +} + +/* We will be called when data is ready - meanwhile, the worker is free */ +route [my_resume_route] +{ + xlog("Result: $var(tb_name) | $var(tb_ver) | $(var(retcode)\n"); +} +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sqlops/doc/contributors.xml b/modules/sqlops/doc/contributors.xml deleted file mode 100644 index bba7cebcb23..00000000000 --- a/modules/sqlops/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 250 - 74 - 6054 - 7542 - - - 2. - Daniel-Constantin Mierla (@miconda) - 105 - 44 - 2927 - 2158 - - - 3. - Liviu Chircu (@liviuchircu) - 54 - 28 - 1116 - 948 - - - 4. - Elena-Ramona Modroiu - 52 - 11 - 4040 - 390 - - - 5. - Razvan Crainea (@razvancrainea) - 21 - 14 - 149 - 246 - - - 6. - Elena-Ramona Modroiu - 18 - 5 - 1051 - 192 - - - 7. - Henning Westerholt (@henningw) - 12 - 8 - 112 - 133 - - - 8. - Vlad Paiu (@vladpaiu) - 9 - 7 - 39 - 2 - - - 9. - Ionut Ionita (@ionutrazvanionita) - 8 - 5 - 180 - 12 - - - 10. - Norman Brandinger (@NormB) - 7 - 5 - 37 - 10 - - - -
-All remaining contributors: Kobi Eshun (@ekobi), Andrei Pelinescu-Onciul, Maksym Sobolyev (@sobomax), Anca Vamanu, Ovidiu Sas (@ovidiusas), Vlad Patrascu (@rvlad-patrascu), Klaus Darilion, John Burke (@john08burke), Andrey Vorobiev, Nick Altmann (@nikbyte), Olle E. Johansson, Kennard White, Julián Moreno Patiño, Konstantin Bokarius, Walter Doekes (@wdoekes), Andreas Granig, Peter Lemenkov (@lemenkov), Sergio Gutierrez, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2005 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Oct 2022 - Apr 2025 - - - 3. - Norman Brandinger (@NormB) - Aug 2006 - Mar 2025 - - - 4. - Nick Altmann (@nikbyte) - Feb 2025 - Feb 2025 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2013 - May 2024 - - - 6. - Ovidiu Sas (@ovidiusas) - Jul 2015 - Apr 2024 - - - 7. - Vlad Paiu (@vladpaiu) - Jun 2011 - Jul 2023 - - - 8. - Razvan Crainea (@razvancrainea) - Jun 2011 - Mar 2023 - - - 9. - John Burke (@john08burke) - Jun 2022 - Jun 2022 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2019 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), Andrey Vorobiev, Julián Moreno Patiño, Ionut Ionita (@ionutrazvanionita), Walter Doekes (@wdoekes), Anca Vamanu, Kennard White, Sergio Gutierrez, Kobi Eshun (@ekobi), Henning Westerholt (@henningw), Olle E. Johansson, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Klaus Darilion, Andreas Granig, Andrei Pelinescu-Onciul, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), John Burke (@john08burke), Peter Lemenkov (@lemenkov), Ionut Ionita (@ionutrazvanionita), Vlad Paiu (@vladpaiu), Anca Vamanu, Norman Brandinger (@NormB), Kobi Eshun (@ekobi), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Klaus Darilion, Andrei Pelinescu-Onciul, Elena-Ramona Modroiu. -
- -
diff --git a/modules/sqlops/doc/sqlops.xml b/modules/sqlops/doc/sqlops.xml deleted file mode 100644 index cbb06fc442b..00000000000 --- a/modules/sqlops/doc/sqlops.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - SQLops Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009-2024 &osipssol; - ©right; 2004-2008 &voicesystem; - diff --git a/modules/sqlops/doc/sqlops_admin.xml b/modules/sqlops/doc/sqlops_admin.xml deleted file mode 100644 index 0e67535e7a2..00000000000 --- a/modules/sqlops/doc/sqlops_admin.xml +++ /dev/null @@ -1,1018 +0,0 @@ - - - - - &adminguide; - - -
- Overview - - SQLops (SQL-operations) modules implements a set of script - functions for generic SQL standard queries (raw or structure queries). - It also provides a dedicated set of functions for DB manipulation - (loading/storing/removing) of user AVPs (preferences). - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters -
- <varname>db_url</varname> (string) - - DB URL for database connection. As the module allows the usage - of multiple DBs (DB URLs), the actual DB URL may be preceded by - an reference number. This reference number is to be passed to - AVPOPS function that what to explicitly use this DB connection. - If no reference number is given, 0 is assumed - this is the default - DB URL. - - - - This parameter is optional, it's default value being NULL. - - - - Set <varname>db_url</varname> parameter - -... -# default URL -modparam("sqlops","db_url","mysql://user:passwd@host/database") -# an additional DB URL -modparam("sqlops","db_url","1 postgres://user:passwd@host2/opensips") -... - - -
-
- <varname>usr_table</varname> (string) - - DB table to be used for user preferences (AVPs) - - - - This parameter is optional, it's default value being - usr_preferences. - - - - Set <varname>usr_table</varname> parameter - -... -modparam("sqlops","usr_table","avptable") -... - - -
- -
- <varname>db_scheme</varname> (string) - - Definition of a DB scheme to be used for accessing - a non-standard User Preference -like table. - - - Definition of a DB scheme. Scheme syntax is: - - - db_scheme = name':'element[';'element]* - - element = - - 'uuid_col='string - - 'username_col='string - - 'domain_col='string - - 'value_col='string - - 'value_type='('integer'|'string') - - 'table='string - - - - - - - Default value is NULL. - - - - Set <varname>db_scheme</varname> parameter - - -... -modparam("sqlops","db_scheme", -"scheme1:table=subscriber;uuid_col=uuid;value_col=first_name") -... - - -
- -
- <varname>use_domain</varname> (integer) - - If the domain part of the a SIP URI should be used for - identifying an AVP in DB operations. - - - Default value is 0 (no). - - - - Set <varname>use_domain</varname> parameter - - -... -modparam("sqlops","use_domain",1) -... - - -
- -
- <varname>ps_id_max_buf_len</varname> (integer) - - The maximum size of the buffer used to build the query IDs which - are used for managing the Prepare Statements when comes to the - "sql_select|update|insert|replace|delete()" functions - - - If the size is exceeded (when trying to build the PS query ID), - the PS support will be dropped for the query. If set to 0, the PS - support will be completly disabled. - - - Default value is 1024. - - - - Set <varname>ps_id_max_buf_len</varname> parameter - - -... -modparam("sqlops","ps_id_max_buf_len", 2048) -... - - -
- -
- <varname>bigint_to_str</varname> (int) - - Controls bigint conversion. - By default bigint values are returned as int. - If the value stored in bigint is out of the int range, - by enabling bigint to string conversion, - the bigint value will be returned as string. - - - Default value is 0. - - - - Set <varname>bigint_to_str</varname> parameter - - -... -# Return bigint as string -modparam("sqlops","bigint_to_str",1) -... - - -
- -
- <varname>uuid_column</varname> (string) - - Name of column containing the uuid (unique user id). - - - Default value is uuid. - - - - Set <varname>uuid_column</varname> parameter - -... -modparam("sqlops","uuid_column","uuid") -... - - -
-
- <varname>username_column</varname> (string) - - Name of column containing the username. - - - Default value is username. - - - - Set <varname>username_column</varname> parameter - -... -modparam("sqlops","username_column","username") -... - - -
-
- <varname>domain_column</varname> (string) - - Name of column containing the domain name. - - - Default value is domain. - - - - Set <varname>domain_column</varname> parameter - -... -modparam("sqlops","domain_column","domain") -... - - -
-
- <varname>attribute_column</varname> (string) - - Name of column containing the attribute name (AVP name). - - - Default value is attribute. - - - - Set <varname>attribute_column</varname> parameter - - -... -modparam("sqlops","attribute_column","attribute") -... - - -
-
- <varname>value_column</varname> (string) - - Name of column containing the AVP value. - - - Default value is value. - - - - Set <varname>value_column</varname> parameter - - -... -modparam("sqlops","value_column","value") -... - - -
-
- <varname>type_column</varname> (string) - - Name of column containing the AVP type. - - - Default value is type. - - - - Set <varname>type_column</varname> parameter - - -... -modparam("sqlops","type_column","type") -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">sql_query(query, [res_col_avps], [db_id])</function> - - - Make a database query and store the result in AVPs. - - - The meaning and usage of the parameters: - - - - query (string) - must be a valid SQL - query. The parameter can contain pseudo-variables. - You must escape any pseudo-variables manually to prevent - SQL injection attacks. You can use the existing transformations - escape.common and - unescape.common - to escape and unescape the content of any pseudo-variable. - Failing to escape the variables used in the query makes you - vulnerable to SQL injection, e.g. make it possible for an - outside attacker to alter your database content. - The function returns true if the query was successful, -2 in - case the query returned an empty result set, and -1 for all - other types of errors. - - - - res_col_avps (string, optional, no expand) - a list with AVP names where - to store the result. The format is - $avp(name1);$avp(name2);.... If this parameter - is omitted, the result is stored in - $avp(1);$avp(2);.... If the result consists of - multiple rows, then multiple AVPs with corresponding names will - be added. The value type of the AVP (string or integer) will - be derived from the type of the columns. If the value in the - database is NULL, the returned avp will - be a string with the <null> value. - - - - db_id (int, optional) - reference to a defined - DB URL (a numerical id) - see the db_url - module parameter. It can be either a constant, or a - string/int variable. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - <function>sql_query</function> usage - -... -sql_query("SELECT password, ha1 FROM subscriber WHERE username='$tu'", - "$avp(pass);$avp(hash)"); -sql_query("DELETE FROM subscriber"); -sql_query("DELETE FROM subscriber", , 2); - -$avp(id) = 2; -sql_query("DELETE FROM subscriber", , $avp(id)); -... - - -
- -
- - <function moreinfo="none">sql_query_one(query, [res_col_vars], [db_id])</function> - - - Similar to , it makes a generic raw - database query and returns the results, but with the following - differences: - - - - returns only one row - even if - the query results in a multi row result, only the first row - will be returned to script. - - - - return variables are not limited to AVPs - - the variables for returning the query result may any kind - of variable, of course, as time as it is writeable. NOTE that - the number of return vairable MUST match (as number) the number - of returned columns. If less variables are provided, the query - will fail. - - - - NULL is returned - any a DB NULL - value resulting from the query will be pushed as NULL indicator - (and NOT as <null> string) to the - script variables. - - - - - This function can be used from any type of route. - - - <function>sql_query_one</function> usage - -... -sql_query_one("SELECT password, ha1 FROM subscriber WHERE username='$tU'", - "$var(pass);$var(hash)"); -# $var(pass) or $var(hash) may be NULL if the corresponding columns -# are not populated -... -sql_query_one("SELECT value, type FROM usr_preferences WHERE username='$fU' and attribute='cfna'", - "$var(cf_uri);$var(type)"); -# the above query will return only one row, even if there are multiple `cfna` -# attributes for the user -... - - -
- -
- - <function moreinfo="none">sql_select([columns],table,[filter],[order],[res_col_avps], [db_id]) - </function> - - - Function to perform a structured (not raw) SQL SELECT operation. - The query is performed via OpenSIPS internal SQL interface, taking - advantages of the prepared-statements support (if the db backend - provides something like that). The selected columns are returned - into a set of AVPs (one to one matching the selected columns). - - - If using varibales in constructing the query, you must - manually escape their values in order to prevent SQL injection - attacks. You can use the existing transformations - escape.common and - unescape.common - to escape and unescape the content of any pseudo-variable. - Failing to escape the variables used in the query makes you - vulnerable to SQL injection, e.g. make it possible for an - outside attacker to alter your database content. - - - - The function returns true if the query was successful, -2 in - case the query returned an empty result set, and -1 for all - other types of errors. - - - The meaning and usage of the parameters: - - - - columns (string,optional) - JSON - formated string holding an array of columns to be returned by - the select. Ex: ["col1","col2"]. - If missing, a * (all columns) select will be - performed. - - - - table (string, mandatory) - the - name of the table to be queried. - - - - filter (string, optional) - JSON - formated string holding the "where" filter of the query. This - must be an array of (column, operator,value) pairs. The - exact JSON syntax of such a pair is - {"column":{"operator":"value"}}.; operators - may be `>`, `<`, `=`, `!=` or custom string; The values - may be string, integer or `null`. To simplify the usage with - the `=` operator, you can use {"column":"value"} - If missing, all rows will be selected. - - - - order (string, optional) - the - name of the column to oder by (only ascending). - - - - res_col_avps (string, optional, no expand) - a list with AVP names where - to store the result. The format is - $avp(name1);$avp(name2);.... If this parameter - is omitted, the result is stored in - $avp(1);$avp(2);.... If the result consists of - multiple rows, then multiple AVPs with corresponding names will - be added. The value type of the AVP (string or integer) will - be derived from the type of the columns. If the value in the - database is NULL, the returned avp will - be a string with the <null> value. - - - - db_id (int, optional) - reference - to a defined DB URL (a numerical id) - see the - module parameter. It can - be either a constant, or a string/int variable. - - - - - This function can be used from any type of route. - - - <function>sql_select</function> usage - -... -sql_select('["password","ha1"]', 'subscriber', - '[ {"username": "$tu"}, {"domain": {"!=", null}}]', , - '$avp(pass);$avp(hash)'); -... - - -
- -
- - <function moreinfo="none">sql_select_one([columns],table,[filter],[order],[res_col_vars], [db_id])</function> - - - Similar to , it makes a SELECT SQL - query and returns the results, but with the following - differences: - - - - returns only one row - even if - the query results in a multi row result, only the first row - will be returned to script. - - - - return variables are not limited to AVPs - - the variables for returning the query result may any kind - of variable, of course, as time as it is writeable. NOTE that - the number of return vairable MUST match (as number) the number - of returned columns. If less variables are provided, the query - will fail. - - - - NULL is returned - any a DB NULL - value resulting from the query will be pushed as NULL indicator - (and NOT as <null> string) to the - script variables. - - - - - This function can be used from any type of route. - - - <function>sql_select_one</function> usage - -... -sql_select_one('["value","type"]', 'usr_preferences', - '[ {"username": "$tu"}, {"attribute": "cfna"}]', , - '$var(cf_uri);$var(type)'); -# the above query will return only one row, even if there are multiple `cfna` -# attributes for the user -... - - -
- -
- - <function moreinfo="none">sql_update(columns,table,[filter],[db_id]) - </function> - - - Function to perform a structured (not raw) SQL UPDATE operation. - IMPORTANT: please see all the general notes from the - function. - - - The function returns true if the query was successful. - - - The meaning and usage of the parameters: - - - - columns (string,mandatory) - JSON - formated string holding an array of (column,value) pairs to - be updated by the query. - Ex: [{"col1":"val1"},{"col2":"val1"}]. - - - - table (string, mandatory) - the - name of the table to be queried. - - - - filter (string, optional) - JSON - formated string holding the "where" filter of the query. This - must be an array of (column, operator,value) pairs. The - exact JSON syntax of such a pair is - {"column":{"operator":"value"}}.; operators - may be `>`, `<`, `=`, `!=` or custom string; The values - may be string, integer or `null`. To simplify the usage with - the `=` operator, you can use {"column":"value"} - If missing, all rows will be updated. - - - - db_id (int, optional) - reference - to a defined DB URL (a numerical id) - see the - module parameter. It can - be either a constant, or a string/int variable. - - - - - This function can be used from any type of route. - - - <function>sql_update</function> usage - -... -sql_update( '[{"password":"my_secret"}]', 'subscriber', - '[{"username": "$tu"}]'); -... - - -
- -
- - <function moreinfo="none">sql_insert(table,columns,[db_id]) - </function> - - - Function to perform a structured (not raw) SQL INSERT operation. - IMPORTANT: please see all the general notes from the - function. - - - The function returns true if the query was successful. - - - The meaning and usage of the parameters: - - - - table (string, mandatory) - the - name of the table to be queried. - - - - columns (string,mandatory) - JSON - formated string holding an array of (column,value) pairs to - be inserted. - Ex: [{"col1":"val1"},{"col2":"val1"}]. - - - - db_id (int, optional) - reference - to a defined DB URL (a numerical id) - see the - module parameter. It can - be either a constant, or a string/int variable. - - - - - This function can be used from any type of route. - - - <function>sql_insert</function> usage - -... -sql_insert( 'cc_agents', '[{"agentid":"agentX"},{"skills":"info"},{"location":null},{"msrp_location":"sip:agentX@opensips.com"},{"msrp_max_sessions":2}]' ); -... - - -
- -
- - <function moreinfo="none">sql_delete(table,[filter],[db_id]) - </function> - - - Function to perform a structured (not raw) SQL DELETE operation. - IMPORTANT: please see all the general notes from the - function. - - - The function returns true if the query was successful. - - - The meaning and usage of the parameters: - - - - table (string, mandatory) - the - name of the table to delete from. - - - - filter (string, optional) - JSON - formated string holding the "where" filter of the query. This - must be an array of (column, operator,value) pairs. The - exact JSON syntax of such a pair is - {"column":{"operator":"value"}}.; operators - may be `>`, `<`, `=`, `!=` or custom string; The values - may be string, integer or `null`. To simplify the usage with - the `=` operator, you can use {"column":"value"} - If missing, all rows will be updated. - - - - db_id (int, optional) - reference - to a defined DB URL (a numerical id) - see the - module parameter. It can - be either a constant, or a string/int variable. - - - - - This function can be used from any type of route. - - - <function>sql_delete</function> usage - -... -sql_delete( 'subscriber', '[{"username": "$tu"}]'); -... - - -
- -
- - <function moreinfo="none">sql_replace(table,columns,[db_id]) - </function> - - - Function very similar to function, - but performing an SQL REPLACE operation instead. Note that not all - SQL backend in OpenSIPS may support a REPLACE operation. - - - The function returns true if the query was successful. - -
- -
- - <function moreinfo="none">sql_avp_load(source, name, [db_id], [prefix]]) - </function> - - - Loads from DB into memory the AVPs corresponding to the given - source. If given, it sets the script flags - for loaded AVPs. It returns true if it loaded some values - in AVPs, false otherwise (db error, no avp loaded ...). - - - AVPs may be preceded by an optional prefix, in - order to avoid some conflicts. - - Meaning of the parameters is as follows: - - - source (string, no expand) - what info is used for - identifying the AVPs. Parameter syntax: - - - source = (pvar|str_value) - ['/'('username'|'domain'|'uri'|'uuid')]) - - - pvar = any pseudo variable defined in &osips;. If - the pvar is $ru (request uri), $fu (from uri), $tu (to uri) - or $ou (original uri), then the implicit flag is 'uri'. - Otherwise, the implicit flag is 'uuid'. - - - - - - name (string, no expand) - which AVPs will be loaded - from DB into memory. Parameter syntax is: - - - name = avp_spec['/'(table_name|'$'db_scheme)] - - - - - - db_id (int, optional) - reference to a defined - DB URL (a numerical id) - see the db_url - module parameter. - - - - prefix (string, optional) - static string which will - precede the names of the AVPs populated by this function. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - - <function>sql_avp_load</function> usage - -... -sql_avp_load("$fu", "$avp(678)"); -sql_avp_load("$ru/domain", "i/domain_preferences"); -sql_avp_load("$avp(uuid)", "$avp(404fwd)/fwd_table"); -sql_avp_load("$ru", "$avp(123)/$some_scheme"); - -# use DB URL id 3 -sql_avp_load("$ru", "$avp(1)", 3); - -# precede all loaded AVPs by the "caller_" prefix -sql_avp_load("$ru", "$avp(100)", , "caller_"); -xlog("Loaded: $avp(caller_100)\n"); - -... - - -
-
- - <function moreinfo="none">sql_avp_store(source, name, [db_id])</function> - - - Stores to DB the AVPs corresponding to the given - source. - - The meaning and usage of the parameters are identical as for - sql_avp_load(source, name) - function. Please refer to its description. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - - <function>sql_avp_store</function> usage - -... -sql_avp_store("$tu", "$avp(678)"); -sql_avp_store("$ru/username", "$avp(email)"); -# use DB URL id 3 -sql_avp_store("$ru", "$avp(1)", 3); -... - - -
-
- - <function moreinfo="none">sql_avp_delete(source, name, [db_id])</function> - - - Deletes from DB the AVPs corresponding to the given - source. - - The meaning and usage of the parameters are identical as for - sql_avp_load(source, name) - function. Please refer to its description. - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - <function>sql_avp_delete</function> usage - -... -sql_avp_delete("$tu", "$avp(678)"); -sql_avp_delete("$ru/username", "$avp(email)"); -sql_avp_delete("$avp(uuid)", "$avp(404fwd)/fwd_table"); -# use DB URL id 3 -sql_avp_delete("$ru", "$avp(1)", 3); -... - - -
- -
- - -
- Exported Asynchronous Functions -
- - <function moreinfo="none">sql_query(query, [dest], [db_id])</function> - - - This function takes the same parameters and behaves identically - to , but asynchronously - (after launching the query, the current SIP worker pauses the - execution of the current SIP message until the result is available - and attempts to process more SIP traffic). - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - BRANCH_ROUTE, LOCAL_ROUTE and ONREPLY_ROUTE. - - - <function>async sql_query</function> usage - -... -{ -... -/* Example of a slow MySQL query - it should take around 5 seconds */ -async( - sql_query( - "SELECT table_name, table_version, SLEEP(0.1) from version", - "$avp(tb_name); $avp(tb_ver); $avp(retcode)"), - my_resume_route); -/* script execution is halted right after the async() call */ -} - -/* We will be called when data is ready - meanwhile, the worker is free */ -route [my_resume_route] -{ - xlog("Results: \n$(avp(tb_name)[*])\n --------------------\n$(avp(tb_ver)[*])\n --------------------\n$(avp(retcode)[*])\n"); -} -... - - -
- -
- - <function moreinfo="none">sql_query_one(query, [dest], [db_id])</function> - - - This function takes the same parameters and behaves identically - to , but asynchronously - (after launching the query, the current SIP worker pauses the - execution of the current SIP message until the result is available - and attempts to process more SIP traffic). - - - This function can be used from any route. - - - <function>async sql_query_one</function> usage - -... -{ -... -/* Example of a slow MySQL query - it should take around 5 seconds */ -async( - sql_query_one( - "SELECT table_name, table_version, SLEEP(0.1) from version", - "$var(tb_name); $var(tb_ver); $var(retcode)"), - my_resume_route); -/* script execution is halted right after the async() call */ -} - -/* We will be called when data is ready - meanwhile, the worker is free */ -route [my_resume_route] -{ - xlog("Result: $var(tb_name) | $var(tb_ver) | $(var(retcode)\n"); -} -... - - -
- -
- - -
- diff --git a/modules/sst/README b/modules/sst/README deleted file mode 100644 index 6b612cd2fe9..00000000000 --- a/modules/sst/README +++ /dev/null @@ -1,375 +0,0 @@ -SST Module (SIP Session Timer) - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. How it works - 1.3. Dependencies - - 1.3.1. OpenSIPS Modules - 1.3.2. External Libraries or Applications - - 1.4. Exported Parameters - - 1.4.1. enable_stats (integer) - 1.4.2. min_se (integer) - 1.4.3. sst_interval (integer) - 1.4.4. reject_to_small (integer) - 1.4.5. sst_flag (string) - - 1.5. Exported Functions - - 1.5.1. sstCheckMin(send_reply_flag) - - 1.6. Exported Statistics - - 1.6.1. expired_sst - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Session timer call flow - 1.2. Set enable_stats parameter - 1.3. Set min_se parameter - 1.4. Set sst_interval parameter - 1.5. Set reject_to_small parameter - 1.6. Set sst_flag parameter - 1.7. sstCheckMin usage - -Chapter 1. Admin Guide - -1.1. Overview - - The sst module provides a way to update the dialog expire timer - based on the SIP INVITE/200 OK Session-Expires header value. - You can use the sst module in an OpenSIPS proxy to allow - freeing of local resources of dead (expired) calls. - - You can also use the sst module to validate the MIN_SE header - value and reply to any request with a "422 - Session Timer Too - Small" if the value is too small for your OpenSIPS - configuration. - -1.2. How it works - - The sst module uses the dialog module to be notified of any new - or updated dialogs. It will then look for and extract the - session-expire: header value (if there is one) and override the - dialog expire timer value for the current context dialog. - - You flag any call setup INVITE that you want to cause a timed - session to be established. This will cause OpenSIPS to request - the use of session times if the UAC does not request it. - - All of this happens with a properly configured dialog and sst - module and setting the dialog flag and the sst flag at the time - any INVITE sip message is seen. There is no opensips.cfg script - function call required to set the dialog expire timeout value. - See the dialog module users guide for more information. - - The sstCheckMin() script function can be used to varify the - Session-expires / MIN-SE header field values are not too small - for a proxy. If the SST min_se parameter value is smaller then - the messages Session-Expires / MIN-SE values, the test will - return true. You can also configure the function to send the - 422 response for you. - - The following was taken from the RFC as a call flow example: - - Example 1.1. Session timer call flow -+-------+ +-------+ +-------+ -| UAC-1 | | PROXY | | UAC-2 | -+-------+ +-------+ +-------+ - |(1) INVITE | | - |SE: 50 | | - |----------->| | - | |(2)sstCheckMin | - | |-----+ | - | | | | - | |<----+ | - |(3) 422 | | - |MSE:1800 | | - |<-----------| | - | | | - |(4)ACK | | - |----------->| | - | | | - |(5) INVITE | | - |SE: 1800 | | - |MSE: 1800 | | - |----------->| | - | |(6)sstCheckMin | - | |-----+ | - | | | | - | |<----+ | - | |(7)setflag | - | |create dialog | - | |Set expire | - | |-----+ | - | | | | - | |<----+ | - | | | - | |(8)INVITE | - | |SE: 1800 | - | |MSE: 1800 | - | |-------------->| - | | | - ... - -1.3. Dependencies - -1.3.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * dialog - dialog module and its decencies. (tm) - * sl - stateless module. - -1.3.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.4. Exported Parameters - -1.4.1. enable_stats (integer) - - If the statistics support should be enabled or not. Via - statistic variables, the module provide information about the - dialog processing. Set it to zero to disable or to non-zero to - enable it. - - Default value is “1” (enabled). - - Example 1.2. Set enable_stats parameter -... -modparam("sst", "enable_stats", 0) -... - -1.4.2. min_se (integer) - - The value is used to set the proxies MIN-SE value and is used - in the 422 reply as the proxies MIN-SE: header value if the - sstCheckMin() flag is set to true and the check fails. - - If not set and sstCheckMin() is called with the send-reply flag - set to true, the default 1800 seconds will be used as the - compare and the MIN-SE: header value if the 422 reply is sent. - - Default value is “1800” seconds. - - Example 1.3. Set min_se parameter -... -modparam("sst", "min_se", 2400) -... - -1.4.3. sst_interval (integer) - - The sst minimum interval in Session-Expires header if OpenSIPS - request the use of session times. The used value will be the - maximum value between OpenSIPS minSE, UAS minSE and this value. - - Per default the interval used will be the min_se value - - Default value is “0” seconds. - - Example 1.4. Set sst_interval parameter -... -modparam("sst", "sst_interval", 2400) -... - -1.4.4. reject_to_small (integer) - - In the initial INVITE if the UAC has requested a - Session-Expire: and it's value is smaller then our local - policies Min-SE (see min_se above), then the PROXY has the - right to reject the call by replying to the message with a 422 - Session Timer Too Small and state our local Min-SE: value. The - INVITE is NOT forwarded on through the PROXY. - - This flag if true will tell the SST module to reject the INVITE - with a 422 response. If false, the INVITE is forwarded through - the PROXY with out any modifications. - - Default value is “1” (true/on). - - Example 1.5. Set reject_to_small parameter -... -modparam("sst", "reject_to_small", 0) -... - -1.4.5. sst_flag (string) - - Keeping with OpenSIPS, the module will not do anything to any - message unless instructed to do so via the opensips.cfg script. - You must set the sst_flag value in the setflag() call of the - INVITE you want the sst module to process. But before you can - do that, you need to tell the sst module which flag value you - are assigning to sst. - - In most cases when ever you create a new dialog via - create_dialog() function,you will want to set the sst flag. If - create_dialog() is not called and the sst flag is set, it will - not have any effect. - - This parameter must be set of the module will not load. - - Default value is “Not set!”. - - Example 1.6. Set sst_flag parameter -... -modparam("sst", "sst_flag", "SST_FLAG") -... -route { - ... - if ($rm=="INVITE") { - setflag(SST_FLAG); # Set the sst flag - create_dialog(); # and then create the dialog - } - ... -} - -1.5. Exported Functions - -1.5.1. sstCheckMin(send_reply_flag) - - Check the current Session-Expires / MIN-SE values against the - sst_min_se parameter value. If the Session-Expires or MIN_SE - header value is less then modules minimum value, this function - will return true. - - If the fuction is called with the send_reply_flag set to true - (1) and the requested Session-Expires / MIN-SE values are too - small, a 422 reply will be sent for you. The 422 will carry a - MIN-SE: header with the sst min_se parameter value set. - - Meaning of the parameters is as follows: - * min_allowed (int, optional) - The value to compare the - MIN_SE header value to. - - Example 1.7. sstCheckMin usage - -... -modparam("sst", "sst_flag", "SST_FLAG") -modparam("sst", "min_se", 2400) # Must be >= 90 -... - -route { - if ($rm=="INVITE") { - if (sstCheckMin(1)) { - xlog("L_ERR", "422 Session Timer Too Small reply sent.\n -"); - exit; - } - # track the session timers via the dialog module - setflag(SST_FLAG); - create_dialog(); - } -} - -... - -1.6. Exported Statistics - -1.6.1. expired_sst - - Number of dialogs which got expired session timer. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 30 25 125 129 - 2. Ron Winacott 28 5 2083 265 - 3. Liviu Chircu (@liviuchircu) 19 16 54 68 - 4. Daniel-Constantin Mierla (@miconda) 15 12 104 104 - 5. Razvan Crainea (@razvancrainea) 14 10 106 140 - 6. Andrei Datcu (@andrei-datcu) 9 6 122 28 - 7. Vlad Patrascu (@rvlad-patrascu) 8 6 40 45 - 8. Ovidiu Sas (@ovidiusas) 7 4 174 60 - 9. Vlad Paiu (@vladpaiu) 6 4 7 15 - 10. Henning Westerholt (@henningw) 5 3 15 18 - - All remaining contributors: Anca Vamanu, Christophe Sollet - (@csollet), Ionut Ionita (@ionutrazvanionita), Damien Sandras - (@dsandras), Maksym Sobolyev (@sobomax), Konstantin Bokarius, - Dan Pascu (@danpascu), Ezequiel Lovelle (@lovelle), Peter - Lemenkov (@lemenkov), Edson Gellert Schubert, Elena-Ramona - Modroiu. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 2. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Ovidiu Sas (@ovidiusas) Mar 2008 - Jun 2022 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - May 2020 - 6. Razvan Crainea (@razvancrainea) Jun 2011 - Sep 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ionut Ionita (@ionutrazvanionita) Oct 2016 - Oct 2016 - 9. Vlad Paiu (@vladpaiu) Jun 2011 - Feb 2015 - 10. Ezequiel Lovelle (@lovelle) Oct 2014 - Oct 2014 - - All remaining contributors: Andrei Datcu (@andrei-datcu), - Damien Sandras (@dsandras), Christophe Sollet (@csollet), Anca - Vamanu, Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Dan Pascu (@danpascu), Elena-Ramona Modroiu, Ron Winacott. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Ovidiu Sas (@ovidiusas), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Christophe Sollet - (@csollet), Henning Westerholt (@henningw), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Elena-Ramona Modroiu, Ron Winacott. - - Documentation Copyrights: - - Copyright © 2006 SOMA Networks, Inc. diff --git a/modules/sst/README.md b/modules/sst/README.md new file mode 100644 index 00000000000..bc48a98b404 --- /dev/null +++ b/modules/sst/README.md @@ -0,0 +1,325 @@ +--- +title: "SIP Session Timer module" +description: "The sst module provides a way to update the dialog expire timer based on the SIP INVITE/200 OK Session-Expires header value." +--- + +## Admin Guide + + +### Overview + + +The sst module provides a way to update the +dialog expire timer based on the SIP INVITE/200 OK +Session-Expires header value. You can use the sst +module in an OpenSIPS proxy to allow freeing of local +resources of dead (expired) calls. + + +You can also use the sst module to validate the +MIN_SE header value and reply to any request with a +"422 - Session Timer Too Small" if the value is too +small for your OpenSIPS configuration. + + +### How it works + + +The sst module uses the dialog module to be notified of +any new or updated dialogs. It will then look for and extract +the session-expire: header value (if there is one) and +override the dialog expire timer value for the current context +dialog. + + +You flag any call setup INVITE that you want to cause a +timed session to be established. This will cause OpenSIPS to +request the use of session times if the UAC does not request +it. + + +All of this happens with a properly configured dialog +and sst module and setting the dialog flag and the sst flag at +the time any INVITE sip message is seen. There is no +opensips.cfg script function call required to set the dialog +expire timeout value. See the dialog module users guide for +more information. + + +The sstCheckMin() script function can be used to varify +the Session-expires / MIN-SE header field values are not too +small for a proxy. If the SST min_se parameter value is +smaller then the messages Session-Expires / MIN-SE values, the +test will return true. You can also configure the function to +send the 422 response for you. + + +The following was taken from the RFC as a call flow +example: + + +```c title="Session timer call flow" ++-------+ +-------+ +-------+ +| UAC-1 | | PROXY | | UAC-2 | ++-------+ +-------+ +-------+ + |(1) INVITE | | + |SE: 50 | | + |----------->| | + | |(2)sstCheckMin | + | |-----+ | + | | | | + | |<----+ | + |(3) 422 | | + |MSE:1800 | | + |<-----------| | + | | | + |(4)ACK | | + |----------->| | + | | | + |(5) INVITE | | + |SE: 1800 | | + |MSE: 1800 | | + |----------->| | + | |(6)sstCheckMin | + | |-----+ | + | | | | + | |<----+ | + | |(7)setflag | + | |create dialog | + | |Set expire | + | |-----+ | + | | | | + | |<----+ | + | | | + | |(8)INVITE | + | |SE: 1800 | + | |MSE: 1800 | + | |-------------->| + | | | + ... + +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded +before this module: + + +- *dialog* - dialog module and its decencies. (tm) +- *sl* - stateless module. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### enable_stats (integer) + + +If the statistics support should be enabled or +not. Via statistic variables, the module provide +information about the dialog processing. Set it to zero to +disable or to non-zero to enable it. + + +*Default value is "1" (enabled).* + + +```opensips title="Set enable_stats parameter" +... +modparam("sst", "enable_stats", 0) +... +``` + + +#### min_se (integer) + + +The value is used to set the proxies MIN-SE +value and is used in the 422 reply as the proxies +MIN-SE: header value if the sstCheckMin() flag is set +to true and the check fails. + + +If not set and sstCheckMin() is called with the +send-reply flag set to true, the default 1800 seconds +will be used as the compare and the MIN-SE: header +value if the 422 reply is sent. + + +*Default value is "1800" seconds.* + + +```opensips title="Set min_se parameter" +... +modparam("sst", "min_se", 2400) +... +``` + + +#### sst_interval (integer) + + +The sst minimum interval in Session-Expires header if OpenSIPS +request the use of session times. The used value will be the +maximum value between OpenSIPS minSE, UAS minSE and this value. + + +Per default the interval used will be the min_se value + + +*Default value is "0" seconds.* + + +```opensips title="Set sst_interval parameter" +... +modparam("sst", "sst_interval", 2400) +... +``` + + +#### reject_to_small (integer) + + +In the initial INVITE if the UAC has requested a +Session-Expire: and it's value is smaller then our +local policies Min-SE (see min_se above), then the +PROXY has the right to reject the call by replying to +the message with a 422 Session Timer Too Small and +state our local Min-SE: value. The INVITE is NOT +forwarded on through the PROXY. + + +This flag if true will tell the SST module to +reject the INVITE with a 422 response. If false, the +INVITE is forwarded through the PROXY with out any +modifications. + + +*Default value is "1" (true/on).* + + +```opensips title="Set reject_to_small parameter" +... +modparam("sst", "reject_to_small", 0) +... +``` + + +#### sst_flag (string) + + +Keeping with OpenSIPS, the module will not do +anything to any message unless instructed to do so via +the opensips.cfg script. You must set the sst_flag +value in the setflag() call of the INVITE you want the +sst module to process. But before you can do that, you +need to tell the sst module which flag value you are +assigning to sst. + + +In most cases when ever you create a new dialog +via create_dialog() function,you will want to set the sst flag. +If create_dialog() is not called and the sst flag is set, +it will not have any effect. + + +This parameter must be set of the module will +not load. + + +*Default value is "Not set!".* + + +```opensips title="Set sst_flag parameter" +... +modparam("sst", "sst_flag", "SST_FLAG") +... +route { + ... + if ($rm=="INVITE") { + setflag(SST_FLAG); # Set the sst flag + create_dialog(); # and then create the dialog + } + ... +} +``` + + +### Exported Functions + + +#### sstCheckMin(send_reply_flag) + + +Check the current Session-Expires / MIN-SE values +against the sst_min_se parameter value. If the +Session-Expires or MIN_SE header value is less then +modules minimum value, this function will return +true. + + +If the fuction is called with the +send_reply_flag set to true (1) and the requested +Session-Expires / MIN-SE values are too small, a 422 +reply will be sent for you. The 422 will carry a +MIN-SE: header with the sst min_se parameter value +set. + + +Meaning of the parameters is as follows: + + +- *min_allowed* (int, optional) - The value +to compare the MIN_SE header value to. + + +```opensips title="sstCheckMin usage" +... +modparam("sst", "sst_flag", "SST_FLAG") +modparam("sst", "min_se", 2400) # Must be >= 90 +... + +route { + if ($rm=="INVITE") { + if (sstCheckMin(1)) { + xlog("L_ERR", "422 Session Timer Too Small reply sent.\n"); + exit; + } + # track the session timers via the dialog module + setflag(SST_FLAG); + create_dialog(); + } +} + +... +``` + + +### Exported Statistics + + +#### expired_sst + + +Number of dialogs which got expired session timer. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/sst/doc/contributors.xml b/modules/sst/doc/contributors.xml deleted file mode 100644 index 9ec6b285674..00000000000 --- a/modules/sst/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 30 - 25 - 125 - 129 - - - 2. - Ron Winacott - 28 - 5 - 2083 - 265 - - - 3. - Liviu Chircu (@liviuchircu) - 19 - 16 - 54 - 68 - - - 4. - Daniel-Constantin Mierla (@miconda) - 15 - 12 - 104 - 104 - - - 5. - Razvan Crainea (@razvancrainea) - 14 - 10 - 106 - 140 - - - 6. - Andrei Datcu (@andrei-datcu) - 9 - 6 - 122 - 28 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 8 - 6 - 40 - 45 - - - 8. - Ovidiu Sas (@ovidiusas) - 7 - 4 - 174 - 60 - - - 9. - Vlad Paiu (@vladpaiu) - 6 - 4 - 7 - 15 - - - 10. - Henning Westerholt (@henningw) - 5 - 3 - 15 - 18 - - - -
-All remaining contributors: Anca Vamanu, Christophe Sollet (@csollet), Ionut Ionita (@ionutrazvanionita), Damien Sandras (@dsandras), Maksym Sobolyev (@sobomax), Konstantin Bokarius, Dan Pascu (@danpascu), Ezequiel Lovelle (@lovelle), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Elena-Ramona Modroiu. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Ovidiu Sas (@ovidiusas) - Mar 2008 - Jun 2022 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - May 2020 - - - 6. - Razvan Crainea (@razvancrainea) - Jun 2011 - Sep 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ionut Ionita (@ionutrazvanionita) - Oct 2016 - Oct 2016 - - - 9. - Vlad Paiu (@vladpaiu) - Jun 2011 - Feb 2015 - - - 10. - Ezequiel Lovelle (@lovelle) - Oct 2014 - Oct 2014 - - - -
-All remaining contributors: Andrei Datcu (@andrei-datcu), Damien Sandras (@dsandras), Christophe Sollet (@csollet), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dan Pascu (@danpascu), Elena-Ramona Modroiu, Ron Winacott. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Ovidiu Sas (@ovidiusas), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Christophe Sollet (@csollet), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Elena-Ramona Modroiu, Ron Winacott. -
- -
diff --git a/modules/sst/doc/sst.xml b/modules/sst/doc/sst.xml deleted file mode 100644 index a2e17be61f5..00000000000 --- a/modules/sst/doc/sst.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - SST Module (SIP Session Timer) - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 SOMA Networks, Inc. - - diff --git a/modules/sst/doc/sst_admin.xml b/modules/sst/doc/sst_admin.xml deleted file mode 100644 index 7477822a7ee..00000000000 --- a/modules/sst/doc/sst_admin.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The sst module provides a way to update the - dialog expire timer based on the SIP INVITE/200 OK - Session-Expires header value. You can use the sst - module in an OpenSIPS proxy to allow freeing of local - resources of dead (expired) calls. - - You can also use the sst module to validate the - MIN_SE header value and reply to any request with a - "422 - Session Timer Too Small" if the value is too - small for your OpenSIPS configuration. - -
- -
- How it works - - The sst module uses the dialog module to be notified of - any new or updated dialogs. It will then look for and extract - the session-expire: header value (if there is one) and - override the dialog expire timer value for the current context - dialog. - - You flag any call setup INVITE that you want to cause a - timed session to be established. This will cause OpenSIPS to - request the use of session times if the UAC does not request - it. - - All of this happens with a properly configured dialog - and sst module and setting the dialog flag and the sst flag at - the time any INVITE sip message is seen. There is no - opensips.cfg script function call required to set the dialog - expire timeout value. See the dialog module users guide for - more information. - - The sstCheckMin() script function can be used to varify - the Session-expires / MIN-SE header field values are not too - small for a proxy. If the SST min_se parameter value is - smaller then the messages Session-Expires / MIN-SE values, the - test will return true. You can also configure the function to - send the 422 response for you. - - The following was taken from the RFC as a call flow - example: - - - Session timer call flow - -+-------+ +-------+ +-------+ -| UAC-1 | | PROXY | | UAC-2 | -+-------+ +-------+ +-------+ - |(1) INVITE | | - |SE: 50 | | - |----------->| | - | |(2)sstCheckMin | - | |-----+ | - | | | | - | |<----+ | - |(3) 422 | | - |MSE:1800 | | - |<-----------| | - | | | - |(4)ACK | | - |----------->| | - | | | - |(5) INVITE | | - |SE: 1800 | | - |MSE: 1800 | | - |----------->| | - | |(6)sstCheckMin | - | |-----+ | - | | | | - | |<----+ | - | |(7)setflag | - | |create dialog | - | |Set expire | - | |-----+ | - | | | | - | |<----+ | - | | | - | |(8)INVITE | - | |SE: 1800 | - | |MSE: 1800 | - | |-------------->| - | | | - ... - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded - before this module: - - - - dialog - dialog module and its decencies. (tm) - - - - - sl - stateless module. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>enable_stats</varname> (integer) - - If the statistics support should be enabled or - not. Via statistic variables, the module provide - information about the dialog processing. Set it to zero to - disable or to non-zero to enable it. - - - - Default value is 1 (enabled). - - - - - Set <varname>enable_stats</varname> parameter - -... -modparam("sst", "enable_stats", 0) -... - - -
- -
- <varname>min_se</varname> (integer) - - The value is used to set the proxies MIN-SE - value and is used in the 422 reply as the proxies - MIN-SE: header value if the sstCheckMin() flag is set - to true and the check fails. - - If not set and sstCheckMin() is called with the - send-reply flag set to true, the default 1800 seconds - will be used as the compare and the MIN-SE: header - value if the 422 reply is sent. - - - - Default value is 1800 seconds. - - - - Set <varname>min_se</varname> parameter - -... -modparam("sst", "min_se", 2400) -... - - -
- -
- <varname>sst_interval</varname> (integer) - - The sst minimum interval in Session-Expires header if OpenSIPS - request the use of session times. The used value will be the - maximum value between OpenSIPS minSE, UAS minSE and this value. - - Per default the interval used will be the min_se value - - - - Default value is 0 seconds. - - - - Set <varname>sst_interval</varname> parameter - -... -modparam("sst", "sst_interval", 2400) -... - - -
- -
- <varname>reject_to_small</varname> (integer) - - In the initial INVITE if the UAC has requested a - Session-Expire: and it's value is smaller then our - local policies Min-SE (see min_se above), then the - PROXY has the right to reject the call by replying to - the message with a 422 Session Timer Too Small and - state our local Min-SE: value. The INVITE is NOT - forwarded on through the PROXY. - - This flag if true will tell the SST module to - reject the INVITE with a 422 response. If false, the - INVITE is forwarded through the PROXY with out any - modifications. - - - - Default value is 1 (true/on). - - - - Set <varname>reject_to_small</varname> parameter - -... -modparam("sst", "reject_to_small", 0) -... - - -
-
- <varname>sst_flag</varname> (string) - - Keeping with OpenSIPS, the module will not do - anything to any message unless instructed to do so via - the opensips.cfg script. You must set the sst_flag - value in the setflag() call of the INVITE you want the - sst module to process. But before you can do that, you - need to tell the sst module which flag value you are - assigning to sst. - - In most cases when ever you create a new dialog - via create_dialog() function,you will want to set the sst flag. - If create_dialog() is not called and the sst flag is set, - it will not have any effect. - - This parameter must be set of the module will - not load. - - - - Default value is Not set!. - - - - Set <varname>sst_flag</varname> parameter - -... -modparam("sst", "sst_flag", "SST_FLAG") -... -route { - ... - if ($rm=="INVITE") { - setflag(SST_FLAG); # Set the sst flag - create_dialog(); # and then create the dialog - } - ... -} - - -
- -
-
- Exported Functions -
- - <function moreinfo="none">sstCheckMin(send_reply_flag)</function> - - - Check the current Session-Expires / MIN-SE values - against the sst_min_se parameter value. If the - Session-Expires or MIN_SE header value is less then - modules minimum value, this function will return - true. - - If the fuction is called with the - send_reply_flag set to true (1) and the requested - Session-Expires / MIN-SE values are too small, a 422 - reply will be sent for you. The 422 will carry a - MIN-SE: header with the sst min_se parameter value - set. - - Meaning of the parameters is as follows: - - - min_allowed (int, optional) - The value - to compare the MIN_SE header value to. - - - - <function>sstCheckMin</function> usage - - -... -modparam("sst", "sst_flag", "SST_FLAG") -modparam("sst", "min_se", 2400) # Must be >= 90 -... - -route { - if ($rm=="INVITE") { - if (sstCheckMin(1)) { - xlog("L_ERR", "422 Session Timer Too Small reply sent.\n"); - exit; - } - # track the session timers via the dialog module - setflag(SST_FLAG); - create_dialog(); - } -} - -... - - -
-
- - -
- Exported Statistics -
- <varname>expired_sst</varname> - - Number of dialogs which got expired session timer. - -
-
- -
- diff --git a/modules/statistics/README b/modules/statistics/README deleted file mode 100644 index bff8c44647c..00000000000 --- a/modules/statistics/README +++ /dev/null @@ -1,402 +0,0 @@ -Statistics Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Statistic Groups - 1.3. Statistic Series - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. variable (string) - 1.5.2. stat_groups (string) - 1.5.3. stat_series_profile (string) - - 1.6. Exported Functions - - 1.6.1. update_stat(variable, value) - 1.6.2. reset_stat(variable) - 1.6.3. stat_iter_init(group, iter) - 1.6.4. stat_iter_next(name, val, iter) - 1.6.5. update_stat_series(profile, variable, value) - - 1.7. Exported Pseudo-Variables - - 1.7.1. $stat - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. variable example - 1.2. setting the stat_groups parameter - 1.3. setting the stat_series_profile parameter - 1.4. update_stat usage - 1.5. reset_stat usage - 1.6. stat_iter_init usage - 1.7. stat_iter_next usage - 1.8. update_stat_series usage - 1.9. $stat usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Statistics module is a wrapper over the internal statistics - manager, allowing the script writer to dynamically define and - use of statistic variables. - - By bringing the statistics support into the script, it takes - advantage of the script flexibility in defining logics, making - possible implementation of any kind of statistic scenario. - -1.2. Statistic Groups - - Starting with OpenSIPS 2.3, statistics may be grouped by - prefixing their names with the name of the desired group, along - with a colon separator (e.g. $stat(method:invite) or - update_stat("packets:$var(ptype)", "+1")). In order for this to - work, the groups must be defined prior to OpenSIPS startup - using the stat_groups module parameter. - - The module allows easy iteration over the statistics of a group - using the stat_iter_init() and stat_iter_next() functions. - - By default, all statistics belong to the "dynamic" group. - -1.3. Statistic Series - - Statistic series provide the ability to accumulate statistical - data over a pre-defined time window. Data is stored in a - circular buffer, pushing new data on top, and removing stale - values (values outside the timeframe) from the bottom. These - statistics can be used to provide per-time stats, such as ACD, - ASR, AST, etc, that can be read using the classic statistics - interface, through the $stat() variable. - - Statistic series profile describe the timeframe used to store - the data, as well as how the data is be accumulated and - interpreted. There are several types a statistic series can be - used, depending on the provisioned algorithm: - * accumulate - accumulates the specified values in a counter; - works similar to clasical statistics, except that they - reset after the specified timeframe - * average - returns an average of all the data fed within the - timeframe; can be useful when computing PDD, AST, ACD - stats. - * percentage - indicates the percentage of a set of values - out of the total amount of values fed; can be useful when - computing ASR, NER, CCR stats. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. variable (string) - - Name of a new statistic variable. The name may be followed by - additional flag which describe the variable behavior: - * no_reset : variable cannot be reset. - - Example 1.1. variable example -modparam("statistics", "variable", "register_counter") -modparam("statistics", "variable", "active_calls/no_reset") - -1.5.2. stat_groups (string) - - A comma-separated values string, specifying the statistic - groups that may be used throughout the OpenSIPS script. Groups - cannot contain leading or trailing whitespace characters. - - Example 1.2. setting the stat_groups parameter -modparam("statistics", "stat_groups", "method, packet, response") - -1.5.3. stat_series_profile (string) - - Used to define a statistic series profile. Has the following - format: name: [attr=value]*, where name represents the name of - the profile, and attr=value contains multiple settings of the - defined profile. Possible attributes and their values are: - * algorithm - indicates the way data should be stored and - accumulated over the specified timeframe. Possible values - are: accumulate, average and percentage, as described in - the Section 1.3, “Statistic Series” paragraph (default is - accumulate) - * hash_size - each statistic defined/used is stored in a hash - map attached to the profile; this setting tunes the size of - the hash (default is: 8) - * group - indicates the group where the statistics beloging - to this profile are grouped (as described in stat_groups - (default is to use the same group as the profile) - * window - the number of seconds a timeframe has; all older - values (out of the specified window) are discarded (default - is 60 seconds) - * slots - the number of slots per window; used to tune the - granularity of the circular buffer; the higher the number - of slots is, the more accurate the resulted statistic; - (default is the same value of the window parameter) - * percentage_factor - used for percentage algorithm profiles - to specify the percentage factor to be used (defaults to - 100) - - This parameter can be set multiple times, for each profile - needed. - - Example 1.3. setting the stat_series_profile parameter -... -# define a statistic that accumulates average values in the last minute -modparam("statistics", "stat_series_profile", "avg: algorithm=average") -... -# define a statistic that accumulates average values in the 10 minutes -# with 1 minute granularity (10 slots out of the 600s window) -modparam("statistics", "stat_series_profile", "avg_10m: algorithm=averag -e window=600 slots=10") -... -# define a statistic that computes the percentage of values in the last -hour -# with 10 minutes granularity (6 slots out of the 3600s window) -modparam("statistics", "stat_series_profile", "perc_1h: algorithm=percen -tage window=3600 slots=6") -... - -1.6. Exported Functions - -1.6.1. update_stat(variable, value) - - Updates the value of the statistic variable with the new value. - - Meaning of the parameters is as follows: - * variable (string) - variable to be updated; - * value (int) - value to update with; it may be also - negative. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.4. update_stat usage -... -update_stat("register_counter", 1); -... -$var(a_calls) = "active_calls"; -update_stat($var(a_calls), -1); -... - -1.6.2. reset_stat(variable) - - Resets to zero the value of the statistic variable. - - Meaning of the parameters is as follows: - * variable (string) - variable to be reset-ed - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.5. reset_stat usage -... -reset_stat("register_counter"); -... -$var(reg_counter) = "register_counter"; -update_stat($var(reg_counter)); -... - -1.6.3. stat_iter_init(group, iter) - - Re-initializes "iter" in order to begin iterating through all - statistics belonging to the given "group". - - Meaning of the parameters is as follows: - * group (string) - * iter (string) - internally matched to a corresponding - iterator - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.6. stat_iter_init usage -... -stat_iter_init("packet", "iter"); -... - -1.6.4. stat_iter_next(name, val, iter) - - Attempts to fetch the current statistic to which "iter" points. - If successful, the relevant data will be written to "name" and - "val", while also advancing "iter". Returns negative when - reaching the end of iteration. - - Meaning of the parameters is as follows: - * name (var) - * val (var) - * iter (string) - internally matched to a corresponding - iterator - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.7. stat_iter_next usage -... -# periodically clear packet-related data -timer_route [clear_packet_stats, 7200] { - stat_iter_init("packet", "iter"); - while (stat_iter_next($var(stat), $var(val), "iter")) - reset_stat("packet:$var(stat)"); -} -... - -1.6.5. update_stat_series(profile, variable, value) - - Updates the value of a series statistic. - - Meaning of the parameters is as follows: - * profile (string) - the profile as defined in - stat_series_profile - * variable (string) - variable to be updated; - * value (int) - value to update with; it may be also - negative; when using percentage algorithm, the resulted - value represents the percentage of positive values out of - the total number of values (positive + negative) - - This function can be used from any route. - - Example 1.8. update_stat_series usage -... -# account failed calls -update_stat_series("perc_1h", "ASR_1h", -1); - -# account successful calls -update_stat_series("perc_1h", "ASR_1h", 1); - -# compute average PDD -update_stat_series("avg", "PDD", $var(pdd_ms)); -... - -1.7. Exported Pseudo-Variables - -1.7.1. $stat - - Allows "get" or "reset" operations on the given statistics. - - The name of a statistic may be optionally prefixed with a - searching group, along with a colon separator. - - If a searching group is not provided, the statistic is first - searched for in the core groups. If not found, search continues - with the "dynamic" group which, by default, holds all - non-explicitly grouped statistics which are not exported by the - OpenSIPS core. - - Example 1.9. $stat usage -... -xlog("SHM used size = $stat(used_size), no_invites = $stat(method:invite -)\n"); -... -$stat(err_requests) = 0; -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 33 20 1037 227 - 2. Liviu Chircu (@liviuchircu) 29 21 519 164 - 3. Razvan Crainea (@razvancrainea) 20 13 691 19 - 4. Daniel-Constantin Mierla (@miconda) 11 9 22 18 - 5. Vlad Patrascu (@rvlad-patrascu) 9 4 97 201 - 6. Maksym Sobolyev (@sobomax) 6 4 6 7 - 7. Vlad Paiu (@vladpaiu) 5 2 144 1 - 8. Anca Vamanu 4 2 14 16 - 9. Peter Lemenkov (@lemenkov) 4 2 11 11 - 10. Henning Westerholt (@henningw) 4 2 4 4 - - All remaining contributors: Ionut Ionita (@ionutrazvanionita), - Ovidiu Sas (@ovidiusas), Konstantin Bokarius, Julián Moreno - Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2025 - 2. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2025 - 3. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 4. Razvan Crainea (@razvancrainea) Feb 2012 - Oct 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2006 - Apr 2019 - 7. Ionut Ionita (@ionutrazvanionita) Apr 2017 - Apr 2017 - 8. Julián Moreno Patiño Feb 2016 - Feb 2016 - 9. Vlad Paiu (@vladpaiu) Jul 2010 - Feb 2011 - 10. Anca Vamanu Oct 2007 - Sep 2009 - - All remaining contributors: Ovidiu Sas (@ovidiusas), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea - (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007-2017 OpenSIPS Project - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/statistics/README.md b/modules/statistics/README.md new file mode 100644 index 00000000000..8d84055f47d --- /dev/null +++ b/modules/statistics/README.md @@ -0,0 +1,360 @@ +--- +title: "Statistics Module" +description: "The Statistics module is a wrapper over the internal statistics manager, allowing the script writer to dynamically define and use of statistic variables." +--- + +## Admin Guide + + +### Overview + + +The Statistics module is a wrapper over the internal +statistics manager, allowing the script writer to dynamically define and +use of statistic variables. + + +By bringing the statistics support into the script, it takes advantage +of the script flexibility in defining logics, making possible +implementation of any kind of statistic scenario. + + +### Statistic Groups + + +Starting with OpenSIPS 2.3, statistics may be grouped by prefixing +their names with the name of the desired group, along with a colon +separator (e.g. **$stat(method:invite)** or +**update_stat("packets:$var(ptype)", "+1")**). +In order for this to work, the groups must be defined prior to OpenSIPS startup +using the **[stat groups](#param_stat_groups)** +module parameter. + + +The module allows easy iteration over the statistics of a group using +the **[stat iter init](#func_stat_iter_init)** +and **[stat iter next](#func_stat_iter_next)** +functions. + + +By default, all statistics belong to the +**"dynamic"** group. + + +### Statistic Series + + +Statistic series provide the ability to accumulate statistical data +over a pre-defined time window. Data is stored in a circular buffer, pushing +new data on top, and removing stale values (values outside the timeframe) from +the bottom. These statistics can be used to provide per-time stats, such as +ACD, ASR, AST, etc, that can be read using the classic statistics interface, +through the *$stat()* variable. + + +Statistic series profile describe the timeframe used to store the data, as +well as how the data is be accumulated and interpreted. There are several +types a statistic series can be used, depending on the provisioned algorithm: + + +- *accumulate* - accumulates the specified values in a +counter; works similar to clasical statistics, except that they reset +after the specified timeframe +- *average* - returns an average of all the data fed +within the timeframe; can be useful when computing PDD, AST, ACD stats. +- *percentage* - indicates the percentage of a set of +values out of the total amount of values fed; can be useful when computing +ASR, NER, CCR stats. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### variable (string) + + +Name of a new statistic variable. The name may be followed by additional +flag which describe the variable behavior: + + +- *no_reset* : variable cannot be reset. + + +```opensips title="variable example" +modparam("statistics", "variable", "register_counter") +modparam("statistics", "variable", "active_calls/no_reset") +``` + + +#### stat_groups (string) + + +A comma-separated values string, specifying the statistic groups that +may be used throughout the OpenSIPS script. Groups cannot contain leading or +trailing whitespace characters. + + +```opensips title="setting the stat_groups parameter" +modparam("statistics", "stat_groups", "method, packet, response") +``` + + +#### stat_series_profile (string) + + +Used to define a statistic series profile. Has the following format: +*name: [attr=value]**, where *name* +represents the name of the profile, and *attr=value* +contains multiple settings of the defined profile. Possible attributes +and their values are: + + +- *algorithm* - indicates the way data should be +stored and accumulated over the specified timeframe. Possible values are: +*accumulate*, *average* and +*percentage*, as described in the +**[section stat series](#statistic_series)** +paragraph (default is *accumulate*) +- *hash_size* - each statistic defined/used is stored in +a hash map attached to the profile; this setting tunes the size of the hash +(default is: 8) +- *group* - indicates the group where the statistics +beloging to this profile are grouped (as described in +**[stat groups](#param_stat_groups)** +(default is to use the same group as the profile) +- *window* - the number of seconds a timeframe has; +all older values (out of the specified window) are discarded +(default is *60* seconds) +- *slots* - the number of slots per window; used to tune +the granularity of the circular buffer; the higher the number of slots is, +the more accurate the resulted statistic; +(default is the same value of the *window* parameter) +- *percentage_factor* - used for +*percentage* algorithm profiles to specify the +percentage factor to be used (defaults to *100*) + + +This parameter can be set multiple times, for each profile needed. + + +```opensips title="setting the stat_series_profile parameter" +... +# define a statistic that accumulates average values in the last minute +modparam("statistics", "stat_series_profile", "avg: algorithm=average") +... +# define a statistic that accumulates average values in the 10 minutes +# with 1 minute granularity (10 slots out of the 600s window) +modparam("statistics", "stat_series_profile", "avg_10m: algorithm=average window=600 slots=10") +... +# define a statistic that computes the percentage of values in the last hour +# with 10 minutes granularity (6 slots out of the 3600s window) +modparam("statistics", "stat_series_profile", "perc_1h: algorithm=percentage window=3600 slots=6") +... +``` + + +### Exported Functions + + +#### update_stat(variable, value) + + +Updates the value of the statistic variable with the new value. + + +Meaning of the parameters is as follows: + + +- *variable* (string) - variable to be updated; +- *value* (int) - value to update with; it may be +also negative. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="update_stat usage" +... +update_stat("register_counter", 1); +... +$var(a_calls) = "active_calls"; +update_stat($var(a_calls), -1); +... +``` + + +#### reset_stat(variable) + + +Resets to zero the value of the statistic variable. + + +Meaning of the parameters is as follows: + + +- *variable* (string) - variable to be reset-ed + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="reset_stat usage" +... +reset_stat("register_counter"); +... +$var(reg_counter) = "register_counter"; +update_stat($var(reg_counter)); +... +``` + + +#### stat_iter_init(group, iter) + + +Re-initializes "iter" in order to begin iterating through all +statistics belonging to the given "group". + + +Meaning of the parameters is as follows: + + +- *group* (string) +- *iter* (string) - internally matched +to a corresponding iterator + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="stat_iter_init usage" +... +stat_iter_init("packet", "iter"); +... +``` + + +#### stat_iter_next(name, val, iter) + + +Attempts to fetch the current statistic to which "iter" points. +If successful, the relevant data will be written to "name" and "val", +while also advancing "iter". Returns negative when reaching the end of iteration. + + +Meaning of the parameters is as follows: + + +- *name* (var) +- *val* (var) +- *iter* (string) - internally matched +to a corresponding iterator + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="stat_iter_next usage" +... +# periodically clear packet-related data +timer_route [clear_packet_stats, 7200] { + stat_iter_init("packet", "iter"); + while (stat_iter_next($var(stat), $var(val), "iter")) + reset_stat("packet:$var(stat)"); +} +... +``` + + +#### update_stat_series(profile, variable, value) + + +Updates the value of a series statistic. + + +Meaning of the parameters is as follows: + + +- *profile* (string) - the profile as defined in +**[stat series profile](#param_stat_series_profile)** +- *variable* (string) - variable to be updated; +- *value* (int) - value to update with; it may be +also negative; when using *percentage* algorithm, the +resulted value represents the percentage of positive values out of the +total number of values (positive + negative) + + +This function can be used from any route. + + +```opensips title="update_stat_series usage" +... +# account failed calls +update_stat_series("perc_1h", "ASR_1h", -1); + +# account successful calls +update_stat_series("perc_1h", "ASR_1h", 1); + +# compute average PDD +update_stat_series("avg", "PDD", $var(pdd_ms)); +... +``` + + +### Exported Pseudo-Variables + + +#### $stat + + +Allows "get" or "reset" operations on the given statistics. + + +The name of a statistic may be optionally prefixed with a searching +group, along with a colon separator. + + +If a searching group is not provided, the statistic is first +searched for in the core groups. If not found, search continues with +the "dynamic" group which, by default, holds all non-explicitly +grouped statistics which are not exported by the OpenSIPS core. + + +```opensips title="$stat usage" +... +xlog("SHM used size = $stat(used_size), no_invites = $stat(method:invite)\n"); +... +$stat(err_requests) = 0; +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/statistics/doc/contributors.xml b/modules/statistics/doc/contributors.xml deleted file mode 100644 index 2ad832f2b56..00000000000 --- a/modules/statistics/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 33 - 20 - 1037 - 227 - - - 2. - Liviu Chircu (@liviuchircu) - 29 - 21 - 519 - 164 - - - 3. - Razvan Crainea (@razvancrainea) - 20 - 13 - 691 - 19 - - - 4. - Daniel-Constantin Mierla (@miconda) - 11 - 9 - 22 - 18 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 9 - 4 - 97 - 201 - - - 6. - Maksym Sobolyev (@sobomax) - 6 - 4 - 6 - 7 - - - 7. - Vlad Paiu (@vladpaiu) - 5 - 2 - 144 - 1 - - - 8. - Anca Vamanu - 4 - 2 - 14 - 16 - - - 9. - Peter Lemenkov (@lemenkov) - 4 - 2 - 11 - 11 - - - 10. - Henning Westerholt (@henningw) - 4 - 2 - 4 - 4 - - - -
-All remaining contributors: Ionut Ionita (@ionutrazvanionita), Ovidiu Sas (@ovidiusas), Konstantin Bokarius, Julián Moreno Patiño, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2025 - - - 2. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2025 - - - 3. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Feb 2012 - Oct 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2006 - Apr 2019 - - - 7. - Ionut Ionita (@ionutrazvanionita) - Apr 2017 - Apr 2017 - - - 8. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 9. - Vlad Paiu (@vladpaiu) - Jul 2010 - Feb 2011 - - - 10. - Anca Vamanu - Oct 2007 - Sep 2009 - - - -
-All remaining contributors: Ovidiu Sas (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu), Ovidiu Sas (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/statistics/doc/statistics.xml b/modules/statistics/doc/statistics.xml deleted file mode 100644 index b7aac6acdd6..00000000000 --- a/modules/statistics/doc/statistics.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Statistics Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007-2017 &osipsproj; - ©right; 2006 &voicesystem; - - diff --git a/modules/statistics/doc/statistics_admin.xml b/modules/statistics/doc/statistics_admin.xml deleted file mode 100644 index b7f51af4857..00000000000 --- a/modules/statistics/doc/statistics_admin.xml +++ /dev/null @@ -1,457 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Statistics module is a wrapper over the internal - statistics manager, allowing the script writer to dynamically define and - use of statistic variables. - - - By bringing the statistics support into the script, it takes advantage - of the script flexibility in defining logics, making possible - implementation of any kind of statistic scenario. - -
- -
- Statistic Groups - - Starting with OpenSIPS 2.3, statistics may be grouped by prefixing - their names with the name of the desired group, along with a colon - separator (e.g. $stat(method:invite) or -update_stat("packets:$var(ptype)", "+1")). - In order for this to work, the groups must be defined prior to OpenSIPS startup - using the - module parameter. - - - The module allows easy iteration over the statistics of a group using - the - and - functions. - - - By default, all statistics belong to the - "dynamic" group. - -
- -
- Statistic Series - - Statistic series provide the ability to accumulate statistical data - over a pre-defined time window. Data is stored in a circular buffer, pushing - new data on top, and removing stale values (values outside the timeframe) from - the bottom. These statistics can be used to provide per-time stats, such as - ACD, ASR, AST, etc, that can be read using the classic statistics interface, - through the $stat() variable. - - - Statistic series profile describe the timeframe used to store the data, as - well as how the data is be accumulated and interpreted. There are several - types a statistic series can be used, depending on the provisioned algorithm: - - - - accumulate - accumulates the specified values in a - counter; works similar to clasical statistics, except that they reset - after the specified timeframe - - - - - average - returns an average of all the data fed - within the timeframe; can be useful when computing PDD, AST, ACD stats. - - - - - percentage - indicates the percentage of a set of - values out of the total amount of values fed; can be useful when computing - ASR, NER, CCR stats. - - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>variable</varname> (string) - - Name of a new statistic variable. The name may be followed by additional - flag which describe the variable behavior: - - - - - no_reset : variable cannot be reset. - - - - - variable example - -modparam("statistics", "variable", "register_counter") -modparam("statistics", "variable", "active_calls/no_reset") - - -
-
- <varname>stat_groups</varname> (string) - - A comma-separated values string, specifying the statistic groups that - may be used throughout the OpenSIPS script. Groups cannot contain leading or - trailing whitespace characters. - - - setting the stat_groups parameter - -modparam("statistics", "stat_groups", "method, packet, response") - - -
-
- <varname>stat_series_profile</varname> (string) - - Used to define a statistic series profile. Has the following format: - name: [attr=value]*, where name - represents the name of the profile, and attr=value - contains multiple settings of the defined profile. Possible attributes - and their values are: - - - - algorithm - indicates the way data should be - stored and accumulated over the specified timeframe. Possible values are: - accumulate, average and - percentage, as described in the - - paragraph (default is accumulate) - - - - - hash_size - each statistic defined/used is stored in - a hash map attached to the profile; this setting tunes the size of the hash - (default is: 8) - - - - - group - indicates the group where the statistics - beloging to this profile are grouped (as described in - - (default is to use the same group as the profile) - - - - - window - the number of seconds a timeframe has; - all older values (out of the specified window) are discarded - (default is 60 seconds) - - - - - slots - the number of slots per window; used to tune - the granularity of the circular buffer; the higher the number of slots is, - the more accurate the resulted statistic; - (default is the same value of the window parameter) - - - - - percentage_factor - used for - percentage algorithm profiles to specify the - percentage factor to be used (defaults to 100) - - - - - - This parameter can be set multiple times, for each profile needed. - - - setting the stat_series_profile parameter - -... -# define a statistic that accumulates average values in the last minute -modparam("statistics", "stat_series_profile", "avg: algorithm=average") -... -# define a statistic that accumulates average values in the 10 minutes -# with 1 minute granularity (10 slots out of the 600s window) -modparam("statistics", "stat_series_profile", "avg_10m: algorithm=average window=600 slots=10") -... -# define a statistic that computes the percentage of values in the last hour -# with 10 minutes granularity (6 slots out of the 3600s window) -modparam("statistics", "stat_series_profile", "perc_1h: algorithm=percentage window=3600 slots=6") -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">update_stat(variable, value)</function> - - - Updates the value of the statistic variable with the new value. - - Meaning of the parameters is as follows: - - - variable (string) - variable to be updated; - - - - value (int) - value to update with; it may be - also negative. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>update_stat</function> usage - -... -update_stat("register_counter", 1); -... -$var(a_calls) = "active_calls"; -update_stat($var(a_calls), -1); -... - - -
- -
- - <function moreinfo="none">reset_stat(variable)</function> - - - Resets to zero the value of the statistic variable. - - Meaning of the parameters is as follows: - - - variable (string) - variable to be reset-ed - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>reset_stat</function> usage - -... -reset_stat("register_counter"); -... -$var(reg_counter) = "register_counter"; -update_stat($var(reg_counter)); -... - - -
-
- - <function moreinfo="none">stat_iter_init(group, iter)</function> - - - Re-initializes "iter" in order to begin iterating through all - statistics belonging to the given "group". - - Meaning of the parameters is as follows: - - - group (string) - - - - iter (string) - internally matched - to a corresponding iterator - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>stat_iter_init</function> usage - -... -stat_iter_init("packet", "iter"); -... - - -
-
- - <function moreinfo="none">stat_iter_next(name, val, iter)</function> - - - Attempts to fetch the current statistic to which "iter" points. - If successful, the relevant data will be written to "name" and "val", - while also advancing "iter". Returns negative when reaching the end of iteration. - - Meaning of the parameters is as follows: - - - name (var) - - - - val (var) - - - - iter (string) - internally matched - to a corresponding iterator - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>stat_iter_next</function> usage - -... -# periodically clear packet-related data -timer_route [clear_packet_stats, 7200] { - stat_iter_init("packet", "iter"); - while (stat_iter_next($var(stat), $var(val), "iter")) - reset_stat("packet:$var(stat)"); -} -... - - -
-
- - <function moreinfo="none">update_stat_series(profile, variable, value)</function> - - - Updates the value of a series statistic. - - Meaning of the parameters is as follows: - - - profile (string) - the profile as defined in - - - - - variable (string) - variable to be updated; - - - - value (int) - value to update with; it may be - also negative; when using percentage algorithm, the - resulted value represents the percentage of positive values out of the - total number of values (positive + negative) - - - - - This function can be used from any route. - - - <function>update_stat_series</function> usage - -... -# account failed calls -update_stat_series("perc_1h", "ASR_1h", -1); - -# account successful calls -update_stat_series("perc_1h", "ASR_1h", 1); - -# compute average PDD -update_stat_series("avg", "PDD", $var(pdd_ms)); -... - - -
-
- -
- Exported Pseudo-Variables - -
- <varname>$stat</varname> - - Allows "get" or "reset" operations on the given statistics. - - - The name of a statistic may be optionally prefixed with a searching - group, along with a colon separator. - - - If a searching group is not provided, the statistic is first - searched for in the core groups. If not found, search continues with - the "dynamic" group which, by default, holds all non-explicitly - grouped statistics which are not exported by the OpenSIPS core. - - - <varname>$stat</varname> usage - -... -xlog("SHM used size = $stat(used_size), no_invites = $stat(method:invite)\n"); -... -$stat(err_requests) = 0; -... - - - -
-
- -
- diff --git a/modules/status_report/README b/modules/status_report/README deleted file mode 100644 index ab9ff8291ba..00000000000 --- a/modules/status_report/README +++ /dev/null @@ -1,171 +0,0 @@ -Status/Reports Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. script_sr_group (string) - - 1.4. Exported Functions - - 1.4.1. sr_set_status( group, status, [details]) - 1.4.2. sr_add_report( group, report) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. script_sr_group example - 1.2. sr_set_status usage - 1.3. sr_add_report usage - -Chapter 1. Admin Guide - -1.1. Overview - - The Status/Report module is a wrapper over the internal - status/report framework, allowing the script writer to - dynamically define and use of SR groups. - - By bringing the Status/Report support into the script, it opens - the possibility to create custom reports from script, depending - on the logic you have there. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. script_sr_group (string) - - Name of a new Status/Report group to be created and later used - from script level. - - This parameter may be defined multiple times, in order to - define multiple groups. - - Example 1.1. script_sr_group example -modparam("status_report", "script_sr_group", "security") -modparam("status_report", "script_sr_group", "alarms") - -1.4. Exported Functions - -1.4.1. sr_set_status( group, status, [details]) - - Sets a new status (and details) for a Status/Report group. - - Meaning of the parameters is as follows: - * group (string) - the name of the SR group; you can change - the status only for the groups defined via this module (as - parameter). - * status (int) - the new status value ( strict positive - meaning OK, strict negative meaning NOT OK, 0 is not - accepts, it is converted to 1 automatically). - * details (string, optional) - a descripting text to detail - the status value - - This function can be used from any route. - - Example 1.2. sr_set_status usage -... -sr_set_status( "script_caching", 1, "completed"); -... - -1.4.2. sr_add_report( group, report) - - Adds a new report/log to a Status/Report group.This must have - been defined via this module too. - - Meaning of the parameters is as follows: - * group (string) - the name of the SR group; you can change - the status only for the groups defined via this module (as - parameter). - report (string) - the log to be added. - - This function can be used from any route. - - Example 1.3. sr_add_report usage -... -sr_add_report("security","IP $si detected as attacker"); -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 7 3 339 7 - 2. Liviu Chircu (@liviuchircu) 5 3 8 6 - 3. Maksym Sobolyev (@sobomax) 4 2 2 3 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) May 2024 - May 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2022 - Feb 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). - - Documentation Copyrights: - - Copyright © 2022 OpenSIPS Solutions diff --git a/modules/status_report/README.md b/modules/status_report/README.md new file mode 100644 index 00000000000..adeec1faae1 --- /dev/null +++ b/modules/status_report/README.md @@ -0,0 +1,124 @@ +--- +title: "Status/Reports Module" +description: "The Status/Report module is a wrapper over the internal status/report framework, allowing the script writer to dynamically define and use of SR groups." +--- + +## Admin Guide + + +### Overview + + +The Status/Report module is a wrapper over the +internal status/report framework, allowing the script writer to +dynamically define and use of SR groups. + + +By bringing the Status/Report support into the script, it opens the +possibility to create custom reports from script, depending on +the logic you have there. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### script_sr_group (string) + + +Name of a new Status/Report group to be created and later used +from script level. + + +This parameter may be defined multiple times, in order to define +multiple groups. + + +```opensips title="script_sr_group example" +modparam("status_report", "script_sr_group", "security") +modparam("status_report", "script_sr_group", "alarms") +``` + + +### Exported Functions + + +#### sr_set_status( group, status, [details]) + + +Sets a new status (and details) for a Status/Report group. + + +Meaning of the parameters is as follows: + + +- *group* (string) - the name of the +SR group; you can change the status only for the groups defined via +this module (as parameter). +- *status* (int) - the new status value +( strict positive meaning OK, strict negative meaning NOT OK, +0 is not accepts, it is converted to 1 automatically). +- *details* (string, optional) - a +descripting text to detail the status value + + +This function can be used from any route. + + +```opensips title="sr_set_status usage" +... +sr_set_status( "script_caching", 1, "completed"); +... +``` + + +#### sr_add_report( group, report) + + +Adds a new report/log to a Status/Report group.This must have been +defined via this module too. + + +Meaning of the parameters is as follows: + + +- *group* (string) - the name of the +SR group; you can change the status only for the groups defined via +this module (as parameter). +*report* (string) - the log to be added. + + +This function can be used from any route. + + +```opensips title="sr_add_report usage" +... +sr_add_report("security","IP $si detected as attacker"); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/status_report/doc/contributors.xml b/modules/status_report/doc/contributors.xml deleted file mode 100644 index 88da29f33f8..00000000000 --- a/modules/status_report/doc/contributors.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 7 - 3 - 339 - 7 - - - 2. - Liviu Chircu (@liviuchircu) - 5 - 3 - 8 - 6 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 3 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - May 2024 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2022 - Feb 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu). -
- -
diff --git a/modules/status_report/doc/status_report.xml b/modules/status_report/doc/status_report.xml deleted file mode 100644 index 919e6168b2b..00000000000 --- a/modules/status_report/doc/status_report.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Status/Reports Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssolname; - - diff --git a/modules/status_report/doc/status_report_admin.xml b/modules/status_report/doc/status_report_admin.xml deleted file mode 100644 index b88e6e906e4..00000000000 --- a/modules/status_report/doc/status_report_admin.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The Status/Report module is a wrapper over the - internal status/report framework, allowing the script writer to - dynamically define and use of SR groups. - - - By bringing the Status/Report support into the script, it opens the - possibility to create custom reports from script, depending on - the logic you have there. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- - Exported Parameters -
- <varname>script_sr_group</varname> (string) - - Name of a new Status/Report group to be created and later used - from script level. - - - This parameter may be defined multiple times, in order to define - multiple groups. - - - script_sr_group example - -modparam("status_report", "script_sr_group", "security") -modparam("status_report", "script_sr_group", "alarms") - - -
- -
- - -
- Exported Functions - -
- - <function moreinfo="none">sr_set_status( group, status, [details])</function> - - - Sets a new status (and details) for a Status/Report group. - - Meaning of the parameters is as follows: - - - group (string) - the name of the - SR group; you can change the status only for the groups defined via - this module (as parameter). - - - - status (int) - the new status value - ( strict positive meaning OK, strict negative meaning NOT OK, - 0 is not accepts, it is converted to 1 automatically). - - - - details (string, optional) - a - descripting text to detail the status value - - - - - This function can be used from any route. - - - <function>sr_set_status</function> usage - -... -sr_set_status( "script_caching", 1, "completed"); -... - - -
- -
- - <function moreinfo="none">sr_add_report( group, report)</function> - - - Adds a new report/log to a Status/Report group.This must have been - defined via this module too. - - Meaning of the parameters is as follows: - - - group (string) - the name of the - SR group; you can change the status only for the groups defined via - this module (as parameter). - - report (string) - the log to be added. - - - - - This function can be used from any route. - - - <function>sr_add_report</function> usage - -... -sr_add_report("security","IP $si detected as attacker"); -... - - -
- -
- -
- diff --git a/modules/stir_shaken/README b/modules/stir_shaken/README deleted file mode 100644 index b2b0dd104cb..00000000000 --- a/modules/stir_shaken/README +++ /dev/null @@ -1,553 +0,0 @@ -STIR/SHAKEN Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. auth_date_freshness (integer) - 1.3.2. verify_date_freshness (integer) - 1.3.3. ca_list (string) - 1.3.4. ca_dir (string) - 1.3.5. crl_list (string) - 1.3.6. crl_dir (string) - 1.3.7. e164_strict_mode (integer) - 1.3.8. e164_max_length (integer) - 1.3.9. require_date_hdr (integer) - - 1.4. Exported Functions - - 1.4.1. stir_shaken_auth(attest, origid, cert, pkey, - x5u, [orig], [dest], [out]) - - 1.4.2. stir_shaken_verify(cert, err_code, - err_reason, [orig], [dest]) - - 1.4.3. stir_shaken_check() - 1.4.4. stir_shaken_check_cert() - 1.4.5. stir_shaken_disengagement(token) - - 1.5. Exported Pseudo-Variables - - 1.5.1. $identity(field) - - 1.6. Exported MI Functions - - 1.6.1. stir_shaken_ca_reload - 1.6.2. stir_shaken_crl_reload - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set auth_date_freshness parameter - 1.2. Set verify_date_freshness parameter - 1.3. Set ca_list parameter - 1.4. Set ca_dir parameter - 1.5. Set crl_list parameter - 1.6. Set crl_dir parameter - 1.7. Set e164_strict_mode parameter - 1.8. Set e164_max_length parameter - 1.9. Set require_date_hdr parameter - 1.10. stir_shaken_auth() usage - 1.11. stir_shaken_verify() usage - 1.12. stir_shaken_check() usage - 1.13. stir_shaken_check_cert() usage - 1.14. stir_shaken_disengagement() usage - 1.15. identity usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module adds support for implementing STIR/SHAKEN (RFC - 8224, RFC 8588) Authentication and Verification services in - OpenSIPS. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * openssl (libssl). - -1.3. Exported Parameters - -1.3.1. auth_date_freshness (integer) - - The maximum number of seconds that the value in the Date header - field can be older than the current time. - - This parameter is only relevant for the stir_shaken_auth() - function. - - The default value is 60. - - Example 1.1. Set auth_date_freshness parameter -... -modparam("stir_shaken", "auth_date_freshness", 300) -... - -1.3.2. verify_date_freshness (integer) - - The maximum number of seconds that the value in the Date header - field can be older than the current time. Also, if the iat - value in the PASSporT is different than the Date value, but - remains within the permitted interval, it will be used in the - verification process (for the reconstructed PASSporT) instead - of the Date value. - - If the require_date_hdr parameter is set to not required and - the Date header is missing, the iat value will be used for this - check instead. - - This parameter is only relevant for the stir_shaken_verify() - function. - - The default value is 60. - - Example 1.2. Set verify_date_freshness parameter -... -modparam("stir_shaken", "verify_date_freshness", 300) -... - -1.3.3. ca_list (string) - - Path to a file containing trusted CA certificates for the - verifier. The certificates must be in PEM format, one after - another. - - Example 1.3. Set ca_list parameter -... -modparam("stir_shaken", "ca_list", "/stir_certs/ca_list.pem") -... - -1.3.4. ca_dir (string) - - Path to a directory containing trusted CA certificates for the - verifier. The certificates in the directory must be in hashed - form, as described in the openssl documentation for the Hashed - Directory Method. - - Example 1.4. Set ca_dir parameter -... -modparam("stir_shaken", "ca_dir", "/stir_certs/cas") -... - -1.3.5. crl_list (string) - - Path to a file containing certificate revocation lists (CRLs) - for the verifier. - - Example 1.5. Set crl_list parameter -... -modparam("stir_shaken", "crl_list", "/stir_certs/crl_list.pem") -... - -1.3.6. crl_dir (string) - - Path to a directory containing certificate revocation lists - (CRLs) for the verifier. The CRLs in the directory must be in - hashed form, as described in the openssl documentation for the - Hashed Directory Method. - - Example 1.6. Set crl_dir parameter -... -modparam("stir_shaken", "crl_dir", "/stir_certs/crls") -... - -1.3.7. e164_strict_mode (integer) - - Require a leading "+" to be present in the - originating/destination SHAKEN identity, on top of mandating an - E.164 telephone number by default. Additionally, require the - URI to be either a tel URI or a sip / sips URI with the - user=phone parameter. - - The default value is 0 (disabled). - - Example 1.7. Set e164_strict_mode parameter -... -modparam("stir_shaken", "e164_strict_mode", 1) -... - -1.3.8. e164_max_length (integer) - - This parameter allows the 15-digit number length restriction of - the E.164 format to be bypassed. Especially useful in scenarios - where various telephony number prefixes are in use, causing - some numbers to exceed the standard maximum length. - - The default value is 15. - - Example 1.8. Set e164_max_length parameter -... -modparam("stir_shaken", "e164_max_length", 16) -... - -1.3.9. require_date_hdr (integer) - - Specifies whether the Date header is mandatory when doing - verification with the stir_shaken_verify() function. - - A value of 1 means required and 0 not required. - - If the parameter is set to "not required" but the Date header - is present in the message, the header value will be used as - normally to check the freshness (as configured in the - verify_date_freshness parameter). If the Date header is indeed - missing, the value of the iat claim in the PASSporT will be - used instead. - - The default value is 1 (required). - - Example 1.9. Set require_date_hdr parameter -... -modparam("stir_shaken", "require_date_hdr", 0) -... - -1.4. Exported Functions - -1.4.1. stir_shaken_auth(attest, origid, cert, pkey, x5u, [orig], -[dest], [out]) - - This function performs the steps of an authentication service. - Before calling this function though, you must ensure: - * authority - the server is authoritative for the identity in - question; - * authentication - the originator is authorized to claim the - given identity. - - Meaning of the parameters is as follows: - * attest (string) - value of the 'attest' claim to be - included in the PASSporT. The following values can be used: - + A or full - + B or partial - + C or gateway - * origid (string) - value of the 'origid' claim to be - included in the PASSporT. Treated by the module as an - opaque string. - * cert (string) - the X.509 certificate used to compute the - signature, in PEM format. - * pkey (string) - the private key used to compute the - signature, in PEM format. - * x5u (string) - value of the 'x5u' claim to be included in - the PASSporT. Treated by the module as an opaque string. - * orig (string, optional) - telephone number to be used as - the originating identity in the PASSporT. If missing, this - value will be derived from the SIP message. - * dest (string, optional) - telephone number to be used as - the destination identity in the PASSporT. If missing, this - value will be derived from the SIP message. - * out (string, no expand, optional) - name of an output - variable to store the Identity header or the following - flags: - + req - the Identity header will be appended to the - current request message; - + rpl - the Identity header will be appended to all - replies that will be generated by OpenSIPS for this - request. - If this parameter is missing, the Identity header will be - appended to the current request message. - If an output variable is provided, it should be given as a - quoted string, eg. "$var(identity_hdr)". - - The function returns the following values: - * 1: Success - * -1: Internal error - * -3: Failed to derive identity from SIP message because the - URI is not a telephone number - * -4: Date header value is older than local policy for - freshness - * -5: The current time or Date header value does not fall - within the certificate validity - - This function can be used from REQUEST_ROUTE. - - Example 1.10. stir_shaken_auth() usage -... -stir_shaken_auth("A", "4437c7eb-8f7a-4f0e-a863-f53a0e60251a", - $var(cert), $var(privKey), "https://certs.example.org/cert.pem") -; -... - -1.4.2. stir_shaken_verify(cert, err_code, err_reason, [orig], -[dest]) - - This function performs the steps of an verification service. - - Meaning of the parameters is as follows: - * cert (string) - the X.509 certificate used to verify the - signature, in PEM format. - * err_code (var) - output variable that will store the SIP - response code associated with an eventual error of the - verification process. - * err_reason (var) - output variable that will store the SIP - response reason phrase associated with an eventual error of - the verification process. - * orig (string, optional) - telephone number to be used as - the originating identity in the verification prcess. If - missing, this value will be derived from the SIP message. - * dest (string, optional) - telephone number to be used as - the destination identity in the verification process. If - missing, this value will be derived from the SIP message. - - The function returns the following values: - * 1: Success - * -1: Internal error - * -2: No Identity or Date header found - * -3: Failed to derive identity from SIP message because the - URI is not a telephone number - * -4: Invalid identity header - * -5: Unsupported 'ppt' or 'alg' Identity header parameter - * -6: Date header value is older than local policy for - freshness - * -7: The Date header value does not fall within the - certificate validity - * -8: Invalid certificate - * -9: Signature does not verify successfully - - This function can be used from REQUEST_ROUTE. - - Example 1.11. stir_shaken_verify() usage -... -$var(rc) = stir_shaken_verify($var(cert), $var(err_code), $var(err_reaso -n)); -if ($var(rc) < -1) { - send_reply($var(err_sip_code), $var(err_sip_reason)); - exit; -} -... - -1.4.3. stir_shaken_check() - - This function checks the Identity header in order to validate - the STIR/SHAKEN information in terms of format. It detects - issues such as: missing or badly formated PASSporT claims, - unsupported extensions etc. - - The function returns the following values: - * 1: Success - * -1: Internal error - * -2: No Identity header found - * -3: Invalid identity header - * -4: Unsupported 'ppt' or 'alg' Identity header parameter - - This function can be used from REQUEST_ROUTE. - - Example 1.12. stir_shaken_check() usage -... -if (stir_shaken_check()) { - xlog("forwarding call to stir/shaken verification service\n"); - ... -} -... - -1.4.4. stir_shaken_check_cert() - - This function checks if the current time falls within the given - certificate's validity period. - - The function returns the following values: - * 1: Success - * -1: Internal error - * -2: Certificate is not valid - - This function can be used from REQUEST_ROUTE. - - Example 1.13. stir_shaken_check_cert() usage -... -# update expired cached certificates -cache_fetch("local", $identity(x5u), $var(cert)); -if (!stir_shaken_check_cert($var(cert))) { - rest_get($identity(x5u), $var(cert)); - cache_store("local", $identity(x5u), $var(cert)); -} -... - -1.4.5. stir_shaken_disengagement(token) - - This function add P-Identity-Bypass header with token value at - the end of SIP headers. - - Meaning of the parameters is as follows: - * token (string) - The token provided by the authority during - outage. - - The function returns the following values: - * 1: Success - * 0: Failed to add P-Identity-Bypass header - - This function can be used from REQUEST_ROUTE. - - Example 1.14. stir_shaken_disengagement() usage -... -if ( is_method("INVITE") && !has_totag()) { - # equivalent to sipmsgops module: append_hf("P-Identity-Bypass: -OSIP99-1234567890ABCDEF\r\n"); - stir_shaken_disengagement("OSIP99-1234567890ABCDEF"); -} -... - -1.5. Exported Pseudo-Variables - -1.5.1. $identity(field) - - This is a read-only pseudo-variable that provides access to the - parsed information from the Identity header, through the - following subnames: - * header - the entire PASSporT header; - * x5u - the value of the 'x5u' PASSporT claim; - * payload - the entire PASSporT payload; - * attest - the value of the 'attest' PASSporT claim; - * dest - the value of the 'tn' member of the 'dest' PASSporT - claim; - * iat - the value of the 'iat' PASSporT claim; - * orig - the value of the 'tn' member of the 'orig' PASSporT - claim; - * origid - the value of the 'origid' PASSporT claim; - - Example 1.15. identity usage -... - # acquire the certificate to use for the verification process - $var(rc) = rest_get($identity(x5u), $var(cert)); - if ($var(rc) < 0) { - send_reply(436, "Bad Identity Info"); - exit; - } - ... - xlog("Verified caller:$identity(orig), attestation level: $ident -ity(attest)\n"); -... - -1.6. Exported MI Functions - -1.6.1. stir_shaken_ca_reload - - Reload the file containing trusted CA certificates for the - verifier and the directory containing trusted CA certificates - for the verifier. - - Name: stir_shaken_ca_reload - - Parameters: none - - MI FIFO Command Format: -... -opensips-cli -x mi stir_shaken_ca_reload -"OK" -... - -1.6.2. stir_shaken_crl_reload - - Reload the file containing certificate revocation lists (CRLs) - for the verifier and the directory containing certificate - revocation lists for the verifier. - - Name: stir_shaken_crl_reload - - Parameters: none - - MI FIFO Command Format: -... -opensips-cli -x mi stir_shaken_crl_reload -"OK" -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 59 26 3129 324 - 2. Liviu Chircu (@liviuchircu) 24 18 252 123 - 3. MonkeyTester 14 9 388 14 - 4. Maksym Sobolyev (@sobomax) 7 5 23 35 - 5. Razvan Crainea (@razvancrainea) 6 4 49 25 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) 6 3 47 64 - 7. kworm83 4 2 7 2 - 8. tcresson 3 1 4 18 - 9. Patrice Fournier 3 1 3 1 - 10. Kevin 3 1 2 2 - - All remaining contributors: John Burke (@john08burke), Andriy - Pylypenko (@bambyster). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Patrice Fournier Nov 2025 - Nov 2025 - 2. Razvan Crainea (@razvancrainea) Jan 2021 - May 2025 - 3. MonkeyTester Aug 2023 - Aug 2024 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2024 - Jul 2024 - 5. Maksym Sobolyev (@sobomax) Jan 2021 - Jun 2024 - 6. Liviu Chircu (@liviuchircu) Nov 2019 - Apr 2024 - 7. tcresson Oct 2023 - Oct 2023 - 8. Kevin Feb 2022 - Feb 2022 - 9. kworm83 Jan 2022 - Jan 2022 - 10. Vlad Patrascu (@rvlad-patrascu) Oct 2019 - Aug 2021 - - All remaining contributors: John Burke (@john08burke), Andriy - Pylypenko (@bambyster). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), MonkeyTester, Vlad Patrascu - (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2019 www.opensips-solutions.com diff --git a/modules/stir_shaken/README.md b/modules/stir_shaken/README.md new file mode 100644 index 00000000000..faeb6af1caa --- /dev/null +++ b/modules/stir_shaken/README.md @@ -0,0 +1,528 @@ +--- +title: "STIR/SHAKEN Module" +description: "This module adds support for implementing STIR/SHAKEN (RFC 8224, RFC 8588) Authentication and Verification services in OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module adds support for implementing STIR/SHAKEN (RFC 8224, RFC 8588) +Authentication and Verification services in OpenSIPS. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *openssl (libssl)*. + + +### Exported Parameters + + +#### auth_date_freshness (integer) + + +The maximum number of seconds that the value in the Date header field +can be older than the current time. + + +This parameter is only relevant +for the [stir shaken auth](#func_stir_shaken_auth) function. + + +The default value is *60*. + + +```opensips title="Set auth_date_freshness parameter" +... +modparam("stir_shaken", "auth_date_freshness", 300) +... +``` + + +#### verify_date_freshness (integer) + + +The maximum number of seconds that the value in the Date header field can be +older than the current time. Also, if the *iat* value in +the PASSporT is different than the Date value, but remains within the +permitted interval, it will be used in the verification process (for the +reconstructed PASSporT) instead of the Date value. + + +If the [require date hdr](#param_require_date_hdr) parameter is set to not +required and the Date header is missing, the *iat* value +will be used for this check instead. + + +This parameter is only relevant for the +[stir shaken verify](#func_stir_shaken_verify) function. + + +The default value is *60*. + + +```opensips title="Set verify_date_freshness parameter" +... +modparam("stir_shaken", "verify_date_freshness", 300) +... +``` + + +#### ca_list (string) + + +Path to a file containing trusted CA certificates for the verifier. +The certificates must be in PEM format, one after another. + + +```opensips title="Set ca_list parameter" +... +modparam("stir_shaken", "ca_list", "/stir_certs/ca_list.pem") +... +``` + + +#### ca_dir (string) + + +Path to a directory containing trusted CA certificates for the verifier. +The certificates in the directory must be in hashed form, as described +in the [openssl documentation](https://www.openssl.org/docs/manmaster/man3/X509_LOOKUP_hash_dir.html) for the +*Hashed Directory Method*. + + +```opensips title="Set ca_dir parameter" +... +modparam("stir_shaken", "ca_dir", "/stir_certs/cas") +... +``` + + +#### crl_list (string) + + +Path to a file containing certificate revocation lists (CRLs) for the verifier. + + +```opensips title="Set crl_list parameter" +... +modparam("stir_shaken", "crl_list", "/stir_certs/crl_list.pem") +... +``` + + +#### crl_dir (string) + + +Path to a directory containing certificate revocation lists (CRLs) for +the verifier. The CRLs in the directory must be in hashed form, as described +in the [openssl documentation](https://www.openssl.org/docs/manmaster/man3/X509_LOOKUP_hash_dir.html) for the +*Hashed Directory Method*. + + +```opensips title="Set crl_dir parameter" +... +modparam("stir_shaken", "crl_dir", "/stir_certs/crls") +... +``` + + +#### e164_strict_mode (integer) + + +Require a leading *"+"* to be present in +the originating/destination SHAKEN identity, on top of mandating an E.164 +telephone number by default. Additionally, require the URI to be either +a *tel* URI or a *sip* / +*sips* URI with the *user=phone* +parameter. + + +The default value is *0* (disabled). + + +```opensips title="Set e164_strict_mode parameter" +... +modparam("stir_shaken", "e164_strict_mode", 1) +... +``` + + +#### e164_max_length (integer) + + +This parameter allows the 15-digit number length restriction of the E.164 +format to be bypassed. Especially useful in scenarios where various +telephony number prefixes are in use, causing some numbers to exceed +the standard maximum length. + + +The default value is *15*. + + +```opensips title="Set e164_max_length parameter" +... +modparam("stir_shaken", "e164_max_length", 16) +... +``` + + +#### require_date_hdr (integer) + + +Specifies whether the Date header is mandatory when doing verification +with the [stir shaken verify](#func_stir_shaken_verify) function. + + +A value of *1* means required and *0* +not required. + + +If the parameter is set to "not required" but the Date header is present in the +message, the header value will be used as normally to check the freshness (as +configured in the [verify date freshness](#param_verify_date_freshness) +parameter). If the Date header is indeed missing, the value of the +*iat* claim in the PASSporT will be used instead. + + +The default value is *1* (required). + + +```opensips title="Set require_date_hdr parameter" +... +modparam("stir_shaken", "require_date_hdr", 0) +... +``` + + +### Exported Functions + + +#### stir_shaken_auth(attest, origid, cert, pkey, x5u, [orig], [dest], [out]) + + +This function performs the steps of an authentication service. Before +calling this function though, you must ensure: + + +- authority - the server is authoritative for the identity in question; +- authentication - the originator is authorized to claim the given identity. + + +Meaning of the parameters is as follows: + + +- *attest (string)* - value of the 'attest' claim +to be included in the PASSporT. The following values can be used: + - *A* or *full* + - *B* or *partial* + - *C* or *gateway* +- *origid (string)* - value of the 'origid' claim +to be included in the PASSporT. Treated by the module as an opaque string. +- *cert (string)* - the X.509 certificate used to +compute the signature, in PEM format. +- *pkey (string)* - the private key used to +compute the signature, in PEM format. +- *x5u (string)* - value of the 'x5u' claim to be +included in the PASSporT. Treated by the module as an opaque string. +- *orig (string, optional)* - telephone number to +be used as the originating identity in the PASSporT. If missing, this value +will be derived from the SIP message. +- *dest (string, optional)* - telephone number to +be used as the destination identity in the PASSporT. If missing, this value +will be derived from the SIP message. +- *out (string, no expand, optional)* - name of an +output variable to store the Identity header or the following flags: + - *req* - the Identity header will be appended + - to the current request message; + - *rpl* - the Identity header will be appended + - to all replies that will be generated by OpenSIPS for this request. +If this parameter is missing, the Identity header will be appended +to the current request message. +If an output variable is provided, it should be given as a quoted string, +eg. *"$var(identity_hdr)"*. + + +The function returns the following values: + + +- 1: Success +- -1: Internal error +- -3: Failed to derive identity from SIP message because the +URI is not a telephone number +- -4: Date header value is older than local policy for freshness +- -5: The current time or Date header value does not fall within +the certificate validity + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="stir_shaken_auth() usage" +... +stir_shaken_auth("A", "4437c7eb-8f7a-4f0e-a863-f53a0e60251a", + $var(cert), $var(privKey), "https://certs.example.org/cert.pem"); +... +``` + + +#### stir_shaken_verify(cert, err_code, err_reason, [orig], [dest]) + + +This function performs the steps of an verification service. + + +Meaning of the parameters is as follows: + + +- *cert (string)* - the X.509 certificate used to +verify the signature, in PEM format. +- *err_code (var)* - output variable that will +store the SIP response code associated with an eventual error of the +verification process. +- *err_reason (var)* - output variable that will +store the SIP response reason phrase associated with an eventual error of the +verification process. +- *orig (string, optional)* - telephone number to +be used as the originating identity in the verification prcess. If missing, +this value will be derived from the SIP message. +- *dest (string, optional)* - telephone number to +be used as the destination identity in the verification process. If missing, +this value will be derived from the SIP message. + + +The function returns the following values: + + +- 1: Success +- -1: Internal error +- -2: No Identity or Date header found +- -3: Failed to derive identity from SIP message because the +URI is not a telephone number +- -4: Invalid identity header +- -5: Unsupported 'ppt' or 'alg' Identity header parameter +- -6: Date header value is older than local policy for freshness +- -7: The Date header value does not fall within the certificate validity +- -8: Invalid certificate +- -9: Signature does not verify successfully + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="stir_shaken_verify() usage" +... +$var(rc) = stir_shaken_verify($var(cert), $var(err_code), $var(err_reason)); +if ($var(rc) < -1) { + send_reply($var(err_sip_code), $var(err_sip_reason)); + exit; +} +... +``` + + +#### stir_shaken_check() + + +This function checks the Identity header in order to validate the +STIR/SHAKEN information in terms of format. It detects issues such as: +missing or badly formated PASSporT claims, unsupported extensions etc. + + +The function returns the following values: + + +- 1: Success +- -1: Internal error +- -2: No Identity header found +- -3: Invalid identity header +- -4: Unsupported 'ppt' or 'alg' Identity header parameter + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="stir_shaken_check() usage" +... +if (stir_shaken_check()) { + xlog("forwarding call to stir/shaken verification service\n"); + ... +} +... +``` + + +#### stir_shaken_check_cert() + + +This function checks if the current time falls within the given +certificate's validity period. + + +The function returns the following values: + + +- 1: Success +- -1: Internal error +- -2: Certificate is not valid + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="stir_shaken_check_cert() usage" +... +# update expired cached certificates +cache_fetch("local", $identity(x5u), $var(cert)); +if (!stir_shaken_check_cert($var(cert))) { + rest_get($identity(x5u), $var(cert)); + cache_store("local", $identity(x5u), $var(cert)); +} +... +``` + + +#### stir_shaken_disengagement(token) + + +This function add P-Identity-Bypass header with token value at the end of SIP headers. + + +Meaning of the parameters is as follows: + + +- *token (string)* - The token provided by the authority during outage. + + +The function returns the following values: + + +- 1: Success +- 0: Failed to add P-Identity-Bypass header + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="stir_shaken_disengagement() usage" +... +if ( is_method("INVITE") && !has_totag()) { + # equivalent to sipmsgops module: append_hf("P-Identity-Bypass: OSIP99-1234567890ABCDEF\r\n"); + stir_shaken_disengagement("OSIP99-1234567890ABCDEF"); +} +... +``` + + +### Exported Pseudo-Variables + + +#### $identity(field) + + +This is a read-only pseudo-variable that provides access to the +parsed information from the Identity header, through the following +subnames: + + +- *header* - the entire PASSporT header; +- *x5u* - the value of the 'x5u' PASSporT claim; +- *payload* - the entire PASSporT payload; +- *attest* - the value of the 'attest' PASSporT claim; +- *dest* - the value of the 'tn' member of the 'dest' +PASSporT claim; +- *iat* - the value of the 'iat' PASSporT claim; +- *orig* - the value of the 'tn' member of the 'orig' +PASSporT claim; +- *origid* - the value of the 'origid' PASSporT claim; + + +```opensips title="identity usage" +... + # acquire the certificate to use for the verification process + $var(rc) = rest_get($identity(x5u), $var(cert)); + if ($var(rc) < 0) { + send_reply(436, "Bad Identity Info"); + exit; + } + ... + xlog("Verified caller:$identity(orig), attestation level: $identity(attest)\n"); +... + +``` + + +### Exported MI Functions + + +#### stir_shaken_ca_reload + + +Reload the file containing trusted CA certificates for the verifier +and the directory containing trusted CA certificates for the verifier. + + +Name: *stir_shaken_ca_reload* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +... +$ opensips-cli -x mi stir_shaken_ca_reload +"OK" +... +``` + + +#### stir_shaken_crl_reload + + +Reload the file containing certificate revocation lists (CRLs) for the verifier +and the directory containing certificate revocation lists for the verifier. + + +Name: *stir_shaken_crl_reload* + + +Parameters: *none* + + +MI FIFO Command Format: + + +```bash +... +$ opensips-cli -x mi stir_shaken_crl_reload +"OK" +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/stir_shaken/doc/contributors.xml b/modules/stir_shaken/doc/contributors.xml deleted file mode 100644 index fbf704a21b2..00000000000 --- a/modules/stir_shaken/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 59 - 26 - 3129 - 324 - - - 2. - Liviu Chircu (@liviuchircu) - 24 - 18 - 252 - 123 - - - 3. - MonkeyTester - 14 - 9 - 388 - 14 - - - 4. - Maksym Sobolyev (@sobomax) - 7 - 5 - 23 - 35 - - - 5. - Razvan Crainea (@razvancrainea) - 6 - 4 - 49 - 25 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - 6 - 3 - 47 - 64 - - - 7. - kworm83 - 4 - 2 - 7 - 2 - - - 8. - tcresson - 3 - 1 - 4 - 18 - - - 9. - Patrice Fournier - 3 - 1 - 3 - 1 - - - 10. - Kevin - 3 - 1 - 2 - 2 - - - -
-All remaining contributors: John Burke (@john08burke), Andriy Pylypenko (@bambyster). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Patrice Fournier - Nov 2025 - Nov 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jan 2021 - May 2025 - - - 3. - MonkeyTester - Aug 2023 - Aug 2024 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2024 - Jul 2024 - - - 5. - Maksym Sobolyev (@sobomax) - Jan 2021 - Jun 2024 - - - 6. - Liviu Chircu (@liviuchircu) - Nov 2019 - Apr 2024 - - - 7. - tcresson - Oct 2023 - Oct 2023 - - - 8. - Kevin - Feb 2022 - Feb 2022 - - - 9. - kworm83 - Jan 2022 - Jan 2022 - - - 10. - Vlad Patrascu (@rvlad-patrascu) - Oct 2019 - Aug 2021 - - - -
-All remaining contributors: John Burke (@john08burke), Andriy Pylypenko (@bambyster). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), MonkeyTester, Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/stir_shaken/doc/stir_shaken.xml b/modules/stir_shaken/doc/stir_shaken.xml deleted file mode 100644 index 98c65454fe6..00000000000 --- a/modules/stir_shaken/doc/stir_shaken.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - STIR/SHAKEN Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2019 &osipssol; - - - diff --git a/modules/stir_shaken/doc/stir_shaken_admin.xml b/modules/stir_shaken/doc/stir_shaken_admin.xml deleted file mode 100644 index 781a8bcf827..00000000000 --- a/modules/stir_shaken/doc/stir_shaken_admin.xml +++ /dev/null @@ -1,693 +0,0 @@ - - - - - &adminguide; - -
- Overview - This module adds support for implementing STIR/SHAKEN (RFC 8224, RFC 8588) - Authentication and Verification services in &osips;. -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - openssl (libssl). - - - - -
-
-
- Exported Parameters - -
- <varname>auth_date_freshness</varname> (integer) - - The maximum number of seconds that the value in the Date header field - can be older than the current time. - - - This parameter is only relevant - for the function. - - The default value is 60. - - Set <varname>auth_date_freshness</varname> parameter - -... -modparam("stir_shaken", "auth_date_freshness", 300) -... - - -
- -
- <varname>verify_date_freshness</varname> (integer) - - The maximum number of seconds that the value in the Date header field can be - older than the current time. Also, if the iat value in - the PASSporT is different than the Date value, but remains within the - permitted interval, it will be used in the verification process (for the - reconstructed PASSporT) instead of the Date value. - - - If the parameter is set to not - required and the Date header is missing, the iat value - will be used for this check instead. - - - This parameter is only relevant for the - function. - - The default value is 60. - - Set <varname>verify_date_freshness</varname> parameter - -... -modparam("stir_shaken", "verify_date_freshness", 300) -... - - -
- -
- <varname>ca_list</varname> (string) - - Path to a file containing trusted CA certificates for the verifier. - The certificates must be in PEM format, one after another. - - - Set <varname>ca_list</varname> parameter - -... -modparam("stir_shaken", "ca_list", "/stir_certs/ca_list.pem") -... - - -
- -
- <varname>ca_dir</varname> (string) - - Path to a directory containing trusted CA certificates for the verifier. - The certificates in the directory must be in hashed form, as described - in the - openssl documentation for the - Hashed Directory Method. - - - Set <varname>ca_dir</varname> parameter - -... -modparam("stir_shaken", "ca_dir", "/stir_certs/cas") -... - - -
- -
- <varname>crl_list</varname> (string) - - Path to a file containing certificate revocation lists (CRLs) for the verifier. - - - Set <varname>crl_list</varname> parameter - -... -modparam("stir_shaken", "crl_list", "/stir_certs/crl_list.pem") -... - - -
- -
- <varname>crl_dir</varname> (string) - - Path to a directory containing certificate revocation lists (CRLs) for - the verifier. The CRLs in the directory must be in hashed form, as described - in the - openssl documentation for the - Hashed Directory Method. - - - Set <varname>crl_dir</varname> parameter - -... -modparam("stir_shaken", "crl_dir", "/stir_certs/crls") -... - - -
- -
- <varname>e164_strict_mode</varname> (integer) - - Require a leading "+" to be present in - the originating/destination SHAKEN identity, on top of mandating an E.164 - telephone number by default. Additionally, require the URI to be either - a tel URI or a sip / - sips URI with the user=phone - parameter. - - The default value is 0 (disabled). - - Set <varname>e164_strict_mode</varname> parameter - -... -modparam("stir_shaken", "e164_strict_mode", 1) -... - - -
- -
- <varname>e164_max_length</varname> (integer) - - This parameter allows the 15-digit number length restriction of the E.164 - format to be bypassed. Especially useful in scenarios where various - telephony number prefixes are in use, causing some numbers to exceed - the standard maximum length. - - The default value is 15. - - Set <varname>e164_max_length</varname> parameter - -... -modparam("stir_shaken", "e164_max_length", 16) -... - - -
- -
- <varname>require_date_hdr</varname> (integer) - - Specifies whether the Date header is mandatory when doing verification - with the function. - - - A value of 1 means required and 0 - not required. - - - If the parameter is set to "not required" but the Date header is present in the - message, the header value will be used as normally to check the freshness (as - configured in the - parameter). If the Date header is indeed missing, the value of the - iat claim in the PASSporT will be used instead. - - The default value is 1 (required). - - Set <varname>require_date_hdr</varname> parameter - -... -modparam("stir_shaken", "require_date_hdr", 0) -... - - -
- -
-
- Exported Functions - -
- - <function moreinfo="none">stir_shaken_auth(attest, origid, cert, pkey, x5u, [orig], [dest], [out])</function> - - - This function performs the steps of an authentication service. Before - calling this function though, you must ensure: - - - - authority - the server is authoritative for the identity in question; - - - authentication - the originator is authorized to claim the given identity. - - - - Meaning of the parameters is as follows: - - - attest (string) - value of the 'attest' claim - to be included in the PASSporT. The following values can be used: - - - A or full - - - B or partial - - - C or gateway - - - - - - origid (string) - value of the 'origid' claim - to be included in the PASSporT. Treated by the module as an opaque string. - - - - cert (string) - the X.509 certificate used to - compute the signature, in PEM format. - - - - pkey (string) - the private key used to - compute the signature, in PEM format. - - - - x5u (string) - value of the 'x5u' claim to be - included in the PASSporT. Treated by the module as an opaque string. - - - - orig (string, optional) - telephone number to - be used as the originating identity in the PASSporT. If missing, this value - will be derived from the SIP message. - - - - dest (string, optional) - telephone number to - be used as the destination identity in the PASSporT. If missing, this value - will be derived from the SIP message. - - - - out (string, no expand, optional) - name of an - output variable to store the Identity header or the following flags: - - - req - the Identity header will be appended - to the current request message; - - - - rpl - the Identity header will be appended - to all replies that will be generated by OpenSIPS for this request. - - - - - - - If this parameter is missing, the Identity header will be appended - to the current request message. - - - If an output variable is provided, it should be given as a quoted string, - eg. "$var(identity_hdr)". - - - - - The function returns the following values: - - - 1: Success - - - -1: Internal error - - - -3: Failed to derive identity from SIP message because the - URI is not a telephone number - - - -4: Date header value is older than local policy for freshness - - - -5: The current time or Date header value does not fall within - the certificate validity - - - This function can be used from REQUEST_ROUTE. - - <function>stir_shaken_auth()</function> usage - -... -stir_shaken_auth("A", "4437c7eb-8f7a-4f0e-a863-f53a0e60251a", - $var(cert), $var(privKey), "https://certs.example.org/cert.pem"); -... - - -
- -
- - <function moreinfo="none">stir_shaken_verify(cert, err_code, err_reason, [orig], [dest])</function> - - - This function performs the steps of an verification service. - - Meaning of the parameters is as follows: - - - cert (string) - the X.509 certificate used to - verify the signature, in PEM format. - - - - err_code (var) - output variable that will - store the SIP response code associated with an eventual error of the - verification process. - - - - err_reason (var) - output variable that will - store the SIP response reason phrase associated with an eventual error of the - verification process. - - - - orig (string, optional) - telephone number to - be used as the originating identity in the verification prcess. If missing, - this value will be derived from the SIP message. - - - - dest (string, optional) - telephone number to - be used as the destination identity in the verification process. If missing, - this value will be derived from the SIP message. - - - - The function returns the following values: - - - 1: Success - - - -1: Internal error - - - -2: No Identity or Date header found - - - -3: Failed to derive identity from SIP message because the - URI is not a telephone number - - - -4: Invalid identity header - - - -5: Unsupported 'ppt' or 'alg' Identity header parameter - - - -6: Date header value is older than local policy for freshness - - - -7: The Date header value does not fall within the certificate validity - - - -8: Invalid certificate - - - -9: Signature does not verify successfully - - - This function can be used from REQUEST_ROUTE. - - <function>stir_shaken_verify()</function> usage - -... -$var(rc) = stir_shaken_verify($var(cert), $var(err_code), $var(err_reason)); -if ($var(rc) < -1) { - send_reply($var(err_sip_code), $var(err_sip_reason)); - exit; -} -... - - -
- -
- - <function moreinfo="none">stir_shaken_check()</function> - - - This function checks the Identity header in order to validate the - STIR/SHAKEN information in terms of format. It detects issues such as: - missing or badly formated PASSporT claims, unsupported extensions etc. - - The function returns the following values: - - - 1: Success - - - -1: Internal error - - - -2: No Identity header found - - - -3: Invalid identity header - - - -4: Unsupported 'ppt' or 'alg' Identity header parameter - - - This function can be used from REQUEST_ROUTE. - - <function>stir_shaken_check()</function> usage - -... -if (stir_shaken_check()) { - xlog("forwarding call to stir/shaken verification service\n"); - ... -} -... - - -
- -
- - <function moreinfo="none">stir_shaken_check_cert()</function> - - - This function checks if the current time falls within the given - certificate's validity period. - - The function returns the following values: - - - 1: Success - - - -1: Internal error - - - -2: Certificate is not valid - - - This function can be used from REQUEST_ROUTE. - - <function>stir_shaken_check_cert()</function> usage - -... -# update expired cached certificates -cache_fetch("local", $identity(x5u), $var(cert)); -if (!stir_shaken_check_cert($var(cert))) { - rest_get($identity(x5u), $var(cert)); - cache_store("local", $identity(x5u), $var(cert)); -} -... - - -
- -
- - <function moreinfo="none">stir_shaken_disengagement(token)</function> - - - This function add P-Identity-Bypass header with token value at the end of SIP headers. - - Meaning of the parameters is as follows: - - - token (string) - The token provided by the authority during outage. - - - - The function returns the following values: - - - 1: Success - - - 0: Failed to add P-Identity-Bypass header - - - This function can be used from REQUEST_ROUTE. - - <function>stir_shaken_disengagement()</function> usage - -... -if ( is_method("INVITE") && !has_totag()) { - # equivalent to sipmsgops module: append_hf("P-Identity-Bypass: OSIP99-1234567890ABCDEF\r\n"); - stir_shaken_disengagement("OSIP99-1234567890ABCDEF"); -} -... - - -
- -
- -
- Exported Pseudo-Variables -
- - <varname>$identity(field)</varname> - - This is a read-only pseudo-variable that provides access to the - parsed information from the Identity header, through the following - subnames: - - - header - the entire PASSporT header; - - - - x5u - the value of the 'x5u' PASSporT claim; - - - - payload - the entire PASSporT payload; - - - - attest - the value of the 'attest' PASSporT claim; - - - - dest - the value of the 'tn' member of the 'dest' - PASSporT claim; - - - - iat - the value of the 'iat' PASSporT claim; - - - - orig - the value of the 'tn' member of the 'orig' - PASSporT claim; - - - - origid - the value of the 'origid' PASSporT claim; - - - - - <varname>identity</varname> usage - -... - # acquire the certificate to use for the verification process - $var(rc) = rest_get($identity(x5u), $var(cert)); - if ($var(rc) < 0) { - send_reply(436, "Bad Identity Info"); - exit; - } - ... - xlog("Verified caller:$identity(orig), attestation level: $identity(attest)\n"); -... - - -
-
- -
- Exported MI Functions - -
- - <function moreinfo="none">stir_shaken_ca_reload</function> - - - - Reload the file containing trusted CA certificates for the verifier - and the directory containing trusted CA certificates for the verifier. - - - - Name: stir_shaken_ca_reload - - - Parameters: none - - - MI FIFO Command Format: - - - -... -opensips-cli -x mi stir_shaken_ca_reload -"OK" -... - - -
- -
- - <function moreinfo="none">stir_shaken_crl_reload</function> - - - - Reload the file containing certificate revocation lists (CRLs) for the verifier - and the directory containing certificate revocation lists for the verifier. - - - - Name: stir_shaken_crl_reload - - - Parameters: none - - - MI FIFO Command Format: - - - -... -opensips-cli -x mi stir_shaken_crl_reload -"OK" -... - - -
- -
- -
diff --git a/modules/stir_shaken/stir_shaken.c b/modules/stir_shaken/stir_shaken.c index cc6da26fd79..684c5877b5b 100644 --- a/modules/stir_shaken/stir_shaken.c +++ b/modules/stir_shaken/stir_shaken.c @@ -522,9 +522,9 @@ static int add_disengagement_token(struct sip_msg *msg, str *token) { #define DISENGAGEMENT_HDR_S "P-Identity-Bypass: " - #define DISENGAGEMENT_HDR_L sizeof(DISENGAGEMENT_HDR_S) - - char *buf; + #define DISENGAGEMENT_HDR_L (sizeof(DISENGAGEMENT_HDR_S)-1) + + char *buf, *p; unsigned int len; struct lump* anchor; @@ -548,7 +548,7 @@ static int add_disengagement_token(struct sip_msg *msg, str *token) } /* calculate len (header + token + crlf) */ - len = strlen(DISENGAGEMENT_HDR_S) + strlen(token->s) + strlen(CRLF); + len = DISENGAGEMENT_HDR_L + token->len + CRLF_LEN; /* alloc pkg memory */ buf= pkg_malloc(len); if (!buf) { @@ -556,12 +556,13 @@ static int add_disengagement_token(struct sip_msg *msg, str *token) return -1; } - // push header in the buffer - strcpy(buf, DISENGAGEMENT_HDR_S); - // push token after the header - strcat(buf, token->s); - // push "\r\n" after the token - strcat(buf, CRLF); + p = buf; + memcpy(p, DISENGAGEMENT_HDR_S, DISENGAGEMENT_HDR_L); + p += DISENGAGEMENT_HDR_L; + memcpy(p, token->s, token->len); + p += token->len; + memcpy(p, CRLF, CRLF_LEN); + p += CRLF_LEN; /* insert buf at the end of previous headers */ if (insert_new_lump_after(anchor, buf, len, 0) == 0) { diff --git a/modules/stun/README b/modules/stun/README deleted file mode 100644 index da0c3e6607e..00000000000 --- a/modules/stun/README +++ /dev/null @@ -1,297 +0,0 @@ -Stun Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. The idea - 1.1.2. Basic Operation - 1.1.3. Supported STUN Attributes - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. primary_ip (str) - 1.3.2. primary_port (str) - 1.3.3. alternate_ip (str) - 1.3.4. alternate_port (str) - 1.3.5. use_listeners_as_primary (int) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set primary_ip parameter - 1.2. Set primary_port parameter - 1.3. Set alternate_ip parameter - 1.4. Set alternate_port parameter - 1.5. Set use_listeners_as_primary parameter - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. The idea - - A stun server working with the same port as SIP (5060) in order - to gain accurate information. The benefit would be an exact - external address in the case of NATs translating differently - when given different destination ports. The server may also - advertise different network addresses than the ones it is - actually listening on. - -1.1.2. Basic Operation - - The stun server will use 4 sockets: - * socket1 = ip1 : port1 - * socket2 = ip1 : port2 - * socket3 = ip2 : port1 - * socket4 = ip2 : port2 - - where ip1 / port1 represent an UDP SIP listener and ip2 / port2 - are configured via the alternate_ip and alternate_port - parameters. - - The sockets come from existing SIP sockets or are created. - - Socket1 must allways be a SIP UDP listener from OpenSIPS. - - If use_listeners_as_primary is enabled the STUN server will - actually use multiple sets of sockets obtained from the IP/port - combinations described above, each set corresponding to a SIP - UDP listener from OpenSIPS. - - The server will create a separate process. This process will - listen for data on created sockets. The server will register a - callback function to SIP. This function is called when a - specific (stun)header is found. - -1.1.3. Supported STUN Attributes - - This stun implements RFC3489 (and XOR_MAPPED_ADDRESS from - RFC5389) - - * MAPPED_ADDRESS - * RESPONSE_ADDRESS - * CHANGE_REQUEST - * SOURCE_ADDRESS - * CHANGED_ADDRESS - * ERROR_CODE - * UNKNOWN_ATTRIBUTES - * REFLECTED_FROM - * XOR_MAPPED_ADDRESS - - Not supported attributes: - - * USERNAME - * PASSWORD - * MESSAGE_INTEGRITY - - and associated ERROR_CODEs - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - - None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. primary_ip (str) - - The IP of an interface which is configured as an UDP SIP - listener in OpenSIPS. This is a mandatory parameter, unless - use_listeners_as_primary is enabled. - - Syntax: "ip [/ advertised_ip] - - By default, the primary_ip and the advertised primary_ip will - be identical. This may be changed with an optional "/ - xxx.xxx.xxx.xxx" string. - - Example 1.1. Set primary_ip parameter -... -modparam("stun", "primary_ip", "192.168.0.100") - -# Example of a STUN server within OpenSIPS which is behind NAT -modparam("stun", "primary_ip", "192.168.0.100 / 64.50.46.78") -... - -1.3.2. primary_port (str) - - The port configured (together with the primary_ip) as an UDP - SIP listener in OpenSIPS. The default value is 5060. - - Syntax: "port [/ advertised_port] - - By default, the primary_port and the advertised primary_port - will be identical. This may be changed with an optional "/ - adv_port" string. - - Example 1.2. Set primary_port parameter -... -modparam("stun", "primary_port", "5060") - -# Listening on a primary port, but advertising a different one -modparam("stun", "primary_port", "5060 / 5062") -... - -1.3.3. alternate_ip (str) - - Another IP from another interface. This is a mandatory - parameter. - - If use_listeners_as_primary is enabled, the alternate IP must - be either: - * an IP from an existing UDP SIP listener configured in - OpenSIPS, but one that is different from all the other UPD - listeners; - * an IP that is different from the UDP SIP listeners - configured in OpenSIPS. - - Syntax: "ip [/ advertised_ip] - - By default, the alternate_ip and the advertised alternate_ip - will be identical. This may be changed with an optional "/ - xxx.xxx.xxx.xxx" string. - - Example 1.3. Set alternate_ip parameter -... -modparam("stun","alternate_ip","11.22.33.44") - -# Example of a STUN server within OpenSIPS which is behind NAT -modparam("stun", "alternate_ip", "192.168.0.100 / 64.78.46.50") -... - -1.3.4. alternate_port (str) - - The port used by the STUN server for the second interface. The - default value is 3478 (default STUN port). - - If use_listeners_as_primary is enabled, the alternate port must - be either: - * a port from an existing UDP SIP listener configured in - OpenSIPS, but one that is different from all the other UPD - listeners; - * a port that is different from the UDP SIP listeners - configured in OpenSIPS. - - Syntax: "port [/ advertised_port] - - By default, the alternate_port and the advertised - alternate_port will be identical. This may be changed with an - optional "/ adv_port" string. - - Example 1.4. Set alternate_port parameter -... -modparam("stun","alternate_port","3479") - -# Listening on an alternate port, but advertising a different one -modparam("stun", "alternate_port", "5060 / 5062") -... - -1.3.5. use_listeners_as_primary (int) - - Setting this parameter to 1 will allow all configured UDP SIP - listeners to be automatically used as "primary" STUN sockets. - - The primary_ip and primary_port parameters will be ignored when - this behavior is enabled. - - The default value is 0 (disabled). - - Example 1.5. Set use_listeners_as_primary parameter -... -modparam("stun","use_listeners_as_primary",1) -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Pistolea 20 3 1891 19 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 19 14 194 179 - 3. Liviu Chircu (@liviuchircu) 18 13 268 119 - 4. Razvan Crainea (@razvancrainea) 14 12 27 20 - 5. Vlad Paiu (@vladpaiu) 7 5 25 4 - 6. Bernard 7 1 391 75 - 7. Maksym Sobolyev (@sobomax) 5 3 13 13 - 8. Peter Lemenkov (@lemenkov) 3 1 1 1 - 9. Vlad Patrascu (@rvlad-patrascu) 2 1 1 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Sep 2009 - May 2023 - 4. Bernard Oct 2021 - Oct 2021 - 5. Razvan Crainea (@razvancrainea) Oct 2011 - Sep 2019 - 6. Vlad Paiu (@vladpaiu) Sep 2011 - Aug 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 9. Razvan Pistolea Sep 2009 - Sep 2009 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bernard, Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), - Razvan Pistolea. - - Documentation Copyrights: - - Copyright © 2009 Voice Sistem SRL diff --git a/modules/stun/README.md b/modules/stun/README.md new file mode 100644 index 00000000000..69c9dd15425 --- /dev/null +++ b/modules/stun/README.md @@ -0,0 +1,261 @@ +--- +title: "Stun Module" +--- + +## Admin Guide + + +### Overview + + +#### The idea + + +A stun server working with the same port as SIP (5060) in order to +gain accurate information. The benefit would be an exact external +address in the case of NATs translating differently when given +different destination ports. The server may also advertise different +network addresses than the ones it is actually listening on. + + +#### Basic Operation + + +The stun server will use 4 sockets: + + +- socket1 = ip1 : port1 +- socket2 = ip1 : port2 +- socket3 = ip2 : port1 +- socket4 = ip2 : port2 + + +where *ip1* / *port1* +represent an UDP SIP listener and *ip2* / +*port2* are configured via the +[alternate ip](#param_alternate_ip) and +[alternate port](#param_alternate_port) +parameters. + + +The sockets come from existing SIP sockets or are created. + + +Socket1 must allways be a SIP UDP listener from OpenSIPS. + + +If [use listeners as primary](#param_use_listeners_as_primary) is enabled +the STUN server will actually use multiple sets of sockets obtained +from the IP/port combinations described above, each set corresponding +to a SIP UDP listener from OpenSIPS. + + +The server will create a separate process. +This process will listen for data on created sockets. +The server will register a callback function to SIP. +This function is called when a specific (stun)header is found. + + +#### Supported STUN Attributes + + +This stun implements RFC3489 (and XOR_MAPPED_ADDRESS from +RFC5389) + + +- MAPPED_ADDRESS +- RESPONSE_ADDRESS +- CHANGE_REQUEST +- SOURCE_ADDRESS +- CHANGED_ADDRESS +- ERROR_CODE +- UNKNOWN_ATTRIBUTES +- REFLECTED_FROM +- XOR_MAPPED_ADDRESS + + +Not supported attributes: + + +- USERNAME +- PASSWORD +- MESSAGE_INTEGRITY + + +and associated ERROR_CODEs + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +*None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### primary_ip (str) + + +The IP of an interface which is configured as an UDP SIP listener +in OpenSIPS. This is a mandatory parameter, unless +[use listeners as primary](#param_use_listeners_as_primary) is enabled. + + +Syntax: "ip [/ advertised_ip] + + +By default, the *primary_ip* and the advertised +*primary_ip* will be identical. +This may be changed with an optional "/ xxx.xxx.xxx.xxx" string. + + +```opensips title="Set primary_ip parameter" +... +modparam("stun", "primary_ip", "192.168.0.100") + +# Example of a STUN server within OpenSIPS which is behind NAT +modparam("stun", "primary_ip", "192.168.0.100 / 64.50.46.78") +... + +``` + + +#### primary_port (str) + + +The port configured (together with the *primary_ip*) as an UDP SIP +listener in OpenSIPS. The default value is 5060. + + +Syntax: "port [/ advertised_port] + + +By default, the *primary_port* and the advertised +*primary_port* will be identical. +This may be changed with an optional "/ adv_port" string. + + +```opensips title="Set primary_port parameter" +... +modparam("stun", "primary_port", "5060") + +# Listening on a primary port, but advertising a different one +modparam("stun", "primary_port", "5060 / 5062") +... + +``` + + +#### alternate_ip (str) + + +Another IP from another interface. This is a mandatory parameter. + + +If [use listeners as primary](#param_use_listeners_as_primary) is enabled, the +alternate IP must be either: + + +- an IP from an existing UDP SIP listener configured in OpenSIPS, +but one that is different from all the other UPD listeners; +- an IP that is different from the UDP SIP listeners configured in OpenSIPS. + + +Syntax: "ip [/ advertised_ip] + + +By default, the *alternate_ip* and the advertised +*alternate_ip* will be identical. +This may be changed with an optional "/ xxx.xxx.xxx.xxx" string. + + +```opensips title="Set alternate_ip parameter" +... +modparam("stun","alternate_ip","11.22.33.44") + +# Example of a STUN server within OpenSIPS which is behind NAT +modparam("stun", "alternate_ip", "192.168.0.100 / 64.78.46.50") +... + +``` + + +#### alternate_port (str) + + +The port used by the STUN server for the second interface. +The default value is 3478 (default STUN port). + + +If [use listeners as primary](#param_use_listeners_as_primary) is enabled, the +alternate port must be either: + + +- a port from an existing UDP SIP listener configured in OpenSIPS, +but one that is different from all the other UPD listeners; +- a port that is different from the UDP SIP listeners configured in OpenSIPS. + + +Syntax: "port [/ advertised_port] + + +By default, the *alternate_port* and the advertised +*alternate_port* will be identical. +This may be changed with an optional "/ adv_port" string. + + +```opensips title="Set alternate_port parameter" +... +modparam("stun","alternate_port","3479") + +# Listening on an alternate port, but advertising a different one +modparam("stun", "alternate_port", "5060 / 5062") +... + +``` + + +#### use_listeners_as_primary (int) + + +Setting this parameter to *1* will allow all +configured UDP SIP listeners to be automatically used as "primary" +STUN sockets. + + +The [primary ip](#param_primary_ip) and +[primary port](#param_primary_port) +parameters will be ignored when this behavior is enabled. + + +The default value is *0* (disabled). + + +```opensips title="Set use_listeners_as_primary parameter" +... +modparam("stun","use_listeners_as_primary",1) +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/stun/doc/contributors.xml b/modules/stun/doc/contributors.xml deleted file mode 100644 index e1a398c9935..00000000000 --- a/modules/stun/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Pistolea - 20 - 3 - 1891 - 19 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 19 - 14 - 194 - 179 - - - 3. - Liviu Chircu (@liviuchircu) - 18 - 13 - 268 - 119 - - - 4. - Razvan Crainea (@razvancrainea) - 14 - 12 - 27 - 20 - - - 5. - Vlad Paiu (@vladpaiu) - 7 - 5 - 25 - 4 - - - 6. - Bernard - 7 - 1 - 391 - 75 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 13 - 13 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 1 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Sep 2009 - May 2023 - - - 4. - Bernard - Oct 2021 - Oct 2021 - - - 5. - Razvan Crainea (@razvancrainea) - Oct 2011 - Sep 2019 - - - 6. - Vlad Paiu (@vladpaiu) - Sep 2011 - Aug 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 9. - Razvan Pistolea - Sep 2009 - Sep 2009 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bernard, Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Pistolea. -
- -
diff --git a/modules/stun/doc/stun.xml b/modules/stun/doc/stun.xml deleted file mode 100644 index 053e3b93cb8..00000000000 --- a/modules/stun/doc/stun.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - Stun Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2009 &voicesystem; - - diff --git a/modules/stun/doc/stun_admin.xml b/modules/stun/doc/stun_admin.xml deleted file mode 100644 index 9fd011a6525..00000000000 --- a/modules/stun/doc/stun_admin.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - &adminguide; - -
- Overview - -
- The idea - - A stun server working with the same port as SIP (5060) in order to - gain accurate information. The benefit would be an exact external - address in the case of NATs translating differently when given - different destination ports. The server may also advertise different - network addresses than the ones it is actually listening on. - -
- -
- Basic Operation - - The stun server will use 4 sockets: - - socket1 = ip1 : port1 - socket2 = ip1 : port2 - socket3 = ip2 : port1 - socket4 = ip2 : port2 - - where ip1 / port1 - represent an UDP SIP listener and ip2 / - port2 are configured via the - and - - parameters. - - - The sockets come from existing SIP sockets or are created. - - - Socket1 must allways be a SIP UDP listener from OpenSIPS. - - - If is enabled - the STUN server will actually use multiple sets of sockets obtained - from the IP/port combinations described above, each set corresponding - to a SIP UDP listener from OpenSIPS. - - - The server will create a separate process. - This process will listen for data on created sockets. - The server will register a callback function to SIP. - This function is called when a specific (stun)header is found. - -
- -
- Supported STUN Attributes - - This stun implements RFC3489 (and XOR_MAPPED_ADDRESS from - RFC5389) - - - - MAPPED_ADDRESS - RESPONSE_ADDRESS - CHANGE_REQUEST - SOURCE_ADDRESS - CHANGED_ADDRESS - ERROR_CODE - UNKNOWN_ATTRIBUTES - REFLECTED_FROM - XOR_MAPPED_ADDRESS - - - Not supported attributes: - - - USERNAME - PASSWORD - MESSAGE_INTEGRITY - - and associated ERROR_CODEs - - -
- -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - None. - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- - <varname>primary_ip</varname> (str) - - - The IP of an interface which is configured as an UDP SIP listener - in &osips;. This is a mandatory parameter, unless - is enabled. - - - Syntax: "ip [/ advertised_ip] - - - By default, the primary_ip and the advertised - primary_ip will be identical. - This may be changed with an optional "/ xxx.xxx.xxx.xxx" string. - - - Set - <varname>primary_ip</varname> parameter - - -... -modparam("stun", "primary_ip", "192.168.0.100") - -# Example of a STUN server within OpenSIPS which is behind NAT -modparam("stun", "primary_ip", "192.168.0.100 / 64.50.46.78") -... - - -
- -
- - <varname>primary_port</varname> (str) - - - The port configured (together with the primary_ip) as an UDP SIP - listener in &osips;. The default value is 5060. - - - Syntax: "port [/ advertised_port] - - - By default, the primary_port and the advertised - primary_port will be identical. - This may be changed with an optional "/ adv_port" string. - - - Set <varname>primary_port</varname> parameter - - -... -modparam("stun", "primary_port", "5060") - -# Listening on a primary port, but advertising a different one -modparam("stun", "primary_port", "5060 / 5062") -... - - -
- -
- - <varname>alternate_ip</varname> (str) - - - Another IP from another interface. This is a mandatory parameter. - - - If is enabled, the - alternate IP must be either: - - - - an IP from an existing UDP SIP listener configured in OpenSIPS, - but one that is different from all the other UPD listeners; - - - - - an IP that is different from the UDP SIP listeners configured in OpenSIPS. - - - - - - Syntax: "ip [/ advertised_ip] - - - By default, the alternate_ip and the advertised - alternate_ip will be identical. - This may be changed with an optional "/ xxx.xxx.xxx.xxx" string. - - - Set - <varname>alternate_ip</varname> parameter - - -... -modparam("stun","alternate_ip","11.22.33.44") - -# Example of a STUN server within OpenSIPS which is behind NAT -modparam("stun", "alternate_ip", "192.168.0.100 / 64.78.46.50") -... - - -
- -
- - <varname>alternate_port</varname> (str) - - - The port used by the STUN server for the second interface. - The default value is 3478 (default STUN port). - - - If is enabled, the - alternate port must be either: - - - - a port from an existing UDP SIP listener configured in OpenSIPS, - but one that is different from all the other UPD listeners; - - - - - a port that is different from the UDP SIP listeners configured in OpenSIPS. - - - - - - Syntax: "port [/ advertised_port] - - - By default, the alternate_port and the advertised - alternate_port will be identical. - This may be changed with an optional "/ adv_port" string. - - - Set - <varname>alternate_port</varname> parameter - - -... -modparam("stun","alternate_port","3479") - -# Listening on an alternate port, but advertising a different one -modparam("stun", "alternate_port", "5060 / 5062") -... - - -
- -
- - <varname>use_listeners_as_primary</varname> (int) - - - Setting this parameter to 1 will allow all - configured UDP SIP listeners to be automatically used as "primary" - STUN sockets. - - - The and - - parameters will be ignored when this behavior is enabled. - - - The default value is 0 (disabled). - - - Set - <varname>use_listeners_as_primary</varname> parameter - - -... -modparam("stun","use_listeners_as_primary",1) -... - - -
- -
- -
diff --git a/modules/tcp_mgm/README b/modules/tcp_mgm/README deleted file mode 100644 index 76185c50a9f..00000000000 --- a/modules/tcp_mgm/README +++ /dev/null @@ -1,156 +0,0 @@ -TCP Management Module (tcp_mgm) - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. [column-name]_col (string) - - 1.4. Exported MI Functions - - 1.4.1. tcp_reload - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Setting the db_url parameter - 1.2. Setting the db_table parameter - 1.3. Setting the [column-name]_col parameter - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides optional, SQL-based support for - fine-grained management of all TCP connections taking place on - OpenSIPS. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - At least one SQL database module must be loaded (e.g. - "db_xxx"). - -1.2.2. External Libraries or Applications - - None. - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Mandatory URL to the SQL database. - - Example 1.1. Setting the db_url parameter - -modparam("tcp_mgm", "db_url", "mysql://opensips:opensipsrw@localhost/ope -nsips") - - -1.3.2. db_table (string) - - The name of the table holding the TCP paths (rules). - - Default value is "tcp_mgm". - - Example 1.2. Setting the db_table parameter - -modparam("tcp_mgm", "db_table", "tcp_mgm") - - -1.3.3. [column-name]_col (string) - - Use a different name for column "column-name". - - Example 1.3. Setting the [column-name]_col parameter - -modparam("tcp_mgm", "connect_timeout_col", "connect_to") - - -1.4. Exported MI Functions - -1.4.1. tcp_reload - - Reload all TCP paths from the tcp_mgm table without disrupting - ongoing traffic. Note that the reloaded rules will NOT - immediately apply to existing TCP connections, rather only to - newly established ones. - - Example: - -# reload all TCP paths -$ opensips-cli -x mi tcp_reload -$ "OK" - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Liviu Chircu (@liviuchircu) 21 8 1281 62 - 2. Maksym Sobolyev (@sobomax) 5 3 9 10 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 2. Liviu Chircu (@liviuchircu) Apr 2022 - Jul 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2022 www.opensips-solutions.com diff --git a/modules/tcp_mgm/README.md b/modules/tcp_mgm/README.md new file mode 100644 index 00000000000..33a14aecccf --- /dev/null +++ b/modules/tcp_mgm/README.md @@ -0,0 +1,94 @@ +--- +title: "TCP Management Module (tcp_mgm)" +description: "This module provides optional, SQL-based support for fine-grained management of all TCP connections taking place on OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +This module provides optional, SQL-based support for fine-grained +management of all TCP connections taking place on OpenSIPS. + + +### Dependencies + + +#### OpenSIPS Modules + + +At least one SQL database module must be loaded (e.g. "db_xxx"). + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### db_url (string) + + +Mandatory URL to the SQL database. + + +```opensips title="Setting the db_url parameter" +modparam("tcp_mgm", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") +``` + + +#### db_table (string) + + +The name of the table holding the TCP paths (rules). + + +Default value is *"tcp_mgm"*. + + +```opensips title="Setting the db_table parameter" +modparam("tcp_mgm", "db_table", "tcp_mgm") +``` + + +#### [column-name]_col (string) + + +Use a different name for column *"column-name"*. + + +```opensips title="Setting the [column-name]_col parameter" +modparam("tcp_mgm", "connect_timeout_col", "connect_to") +``` + + +### Exported MI Functions + + +#### tcp_reload + + +Reload all TCP paths from the *tcp_mgm* table +without disrupting ongoing traffic. Note that the reloaded rules will +NOT immediately apply to existing TCP connections, rather only to +newly established ones. + + +Example: + + +```bash +# reload all TCP paths +$ opensips-cli -x mi tcp_reload +"OK" +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tcp_mgm/doc/contributors.xml b/modules/tcp_mgm/doc/contributors.xml deleted file mode 100644 index 9c485ded963..00000000000 --- a/modules/tcp_mgm/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Liviu Chircu (@liviuchircu) - 21 - 8 - 1281 - 62 - - - 2. - Maksym Sobolyev (@sobomax) - 5 - 3 - 9 - 10 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Apr 2022 - Jul 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/tcp_mgm/doc/tcp_mgm.xml b/modules/tcp_mgm/doc/tcp_mgm.xml deleted file mode 100644 index 505e7388115..00000000000 --- a/modules/tcp_mgm/doc/tcp_mgm.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - -%docentities; - -]> - - - - TCP Management Module (tcp_mgm) - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2022 &osipssol; - diff --git a/modules/tcp_mgm/doc/tcp_mgm_admin.xml b/modules/tcp_mgm/doc/tcp_mgm_admin.xml deleted file mode 100644 index c62fc3ee81f..00000000000 --- a/modules/tcp_mgm/doc/tcp_mgm_admin.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module provides optional, SQL-based support for fine-grained - management of all TCP connections taking place on OpenSIPS. - - -
- -
- Dependencies -
- &osips; Modules - - At least one SQL database module must be loaded (e.g. "db_xxx"). - -
- -
- External Libraries or Applications - - None. - -
-
- -
- Exported Parameters - -
- <varname>db_url (string)</varname> - - Mandatory URL to the SQL database. - - - Setting the <varname>db_url</varname> parameter - - -modparam("tcp_mgm", "db_url", "mysql://opensips:opensipsrw@localhost/opensips") - - - -
- - -
- <varname>db_table (string)</varname> - - The name of the table holding the TCP paths (rules). - - - Default value is "tcp_mgm". - - - Setting the <varname>db_table</varname> parameter - - -modparam("tcp_mgm", "db_table", "tcp_mgm") - - - -
- - -
- <varname>[column-name]_col (string)</varname> - - Use a different name for column "column-name". - - - Setting the <varname>[column-name]_col</varname> parameter - - -modparam("tcp_mgm", "connect_timeout_col", "connect_to") - - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">tcp_reload</function> - - - Reload all TCP paths from the tcp_mgm table - without disrupting ongoing traffic. Note that the reloaded rules will - NOT immediately apply to existing TCP connections, rather only to - newly established ones. - - Example: - - -# reload all TCP paths -$ opensips-cli -x mi tcp_reload -$ "OK" - -
- -
- -
diff --git a/modules/textops/README b/modules/textops/README deleted file mode 100644 index cb06fd52a4c..00000000000 --- a/modules/textops/README +++ /dev/null @@ -1,448 +0,0 @@ -textops Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Known Limitations - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Functions - - 1.3.1. search(re) - 1.3.2. search_body(re) - 1.3.3. search_append(re, txt) - 1.3.4. search_append_body(re, txt) - 1.3.5. replace(re, txt) - 1.3.6. replace_body(re, txt) - 1.3.7. replace_all(re, txt) - 1.3.8. replace_body_all(re, txt) - 1.3.9. replace_body_atonce(re, txt) - 1.3.10. subst('/re/repl/flags') - 1.3.11. subst_uri('/re/repl/flags') - 1.3.12. subst_user('/re/repl/flags') - 1.3.13. subst_body('/re/repl/flags') - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. search usage - 1.2. search_body usage - 1.3. search_append usage - 1.4. search_append_body usage - 1.5. replace usage - 1.6. replace_body usage - 1.7. replace_all usage - 1.8. replace_body_all usage - 1.9. replace_body_atonce usage - 1.10. subst usage - 1.11. subst_uri usage - 1.12. subst usage - 1.13. subst_body usage - -Chapter 1. Admin Guide - -1.1. Overview - - The module implements text based operations over the SIP - message processed by OpenSIPS. SIP is a text based protocol and - the module provides a large set of very useful functions to - manipulate the message at text level, e.g., regular expression - search and replace, Perl-like substitutions, etc. - - Note: all SIP-aware functions like insert_hf, append_hf or - codec operations have been moved to the sipmsgops module. - -1.1.1. Known Limitations - - search ignores folded lines. For example, - search(“(From|f):.*@foo.bar”) doesn't match the following From - header field: -From: medabeda - ;tag=1234 - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * No dependencies on other OpenSIPS modules. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Functions - -1.3.1. search(re) - - Searches for the re in the message. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.1. search usage -... -if ( search("[Ss][Ii][Pp]") ) { /*....*/ }; -... - -1.3.2. search_body(re) - - Searches for the re in the body of the message. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.2. search_body usage -... -if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ }; -... - -1.3.3. search_append(re, txt) - - Searches for the first match of re and appends txt after it. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - String to be appended. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.3. search_append usage -... -search_append("[Oo]pen[Ss]er", " SIP Proxy"); -... - -1.3.4. search_append_body(re, txt) - - Searches for the first match of re in the body of the message - and appends txt after it. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - String to be appended. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.4. search_append_body usage -... -search_append_body("[Oo]pen[Ss]er", " SIP Proxy"); -... - -1.3.5. replace(re, txt) - - Replaces the first occurrence of re with txt. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.5. replace usage -... -replace("opensips", "Open SIP Server"); -... - -1.3.6. replace_body(re, txt) - - Replaces the first occurrence of re in the body of the message - with txt. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.6. replace_body usage -... -replace_body("opensips", "Open SIP Server"); -... - -1.3.7. replace_all(re, txt) - - Replaces all occurrence of re with txt. - - Meaning of the parameters is as follows: - * re - (string) Regular expression. - * txt (string) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.7. replace_all usage -... -replace_all("opensips", "Open SIP Server"); -... - -1.3.8. replace_body_all(re, txt) - - Replaces all occurrence of re in the body of the message with - txt. Matching is done on a per-line basis. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.8. replace_body_all usage -... -replace_body_all("opensips", "Open SIP Server"); -... - -1.3.9. replace_body_atonce(re, txt) - - Replaces all occurrence of re in the body of the message with - txt. Matching is done over the whole body. - - Meaning of the parameters is as follows: - * re (string) - Regular expression. - * txt (string) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.9. replace_body_atonce usage -... -# strip the whole body from the message: -if(has_body() && replace_body_atonce("^.+$", "")) - remove_hf("Content-Type"); -... - -1.3.10. subst('/re/repl/flags') - - Replaces re with repl (sed or perl like). - - Meaning of the parameters is as follows: - * '/re/repl/flags' (string) - sed like regular expression. - flags can be a combination of i (case insensitive), g - (global) or s (match newline don't treat it as end of - line). - 're' - is regular expression - 'repl' - is replacement string - may contain - pseudo-variables - 'flags' - substitution flags (i - ignore case, g - global) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.10. subst usage -... -# replace the uri in to: with the message uri (just an example) -if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1\u\2/ig') ) {}; - -# replace the uri in to: with the value of avp sip_address (just an exam -ple) -if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\ -2/ig') ) {}; - -... - -1.3.11. subst_uri('/re/repl/flags') - - Runs the re substitution on the message uri (like subst but - works only on the uri) - - Meaning of the parameters is as follows: - * '/re/repl/flags' (string) - sed like regular expression. - flags can be a combination of i (case insensitive), g - (global) or s (match newline don't treat it as end of - line). - 're' - is regular expression - 'repl' - is replacement string - may contain - pseudo-variables - 'flags' - substitution flags (i - ignore case, g - global) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.11. subst_uri usage -... -# adds 3463 prefix to numeric uris, and save the original uri (\0 match) -# as a parameter: orig_uri (just an example) -if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:3463\1@\2;orig_uri=\0/i')){$ - -# adds the avp 'uri_prefix' as prefix to numeric uris, and save the orig -inal -# uri (\0 match) as a parameter: orig_uri (just an example) -if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\ -0/i')){$ - -... - -1.3.12. subst_user('/re/repl/flags') - - Runs the re substitution on the message uri (like subst_uri but - works only on the user portion of the uri) - - Meaning of the parameters is as follows: - * '/re/repl/flags' (string) - sed like regular expression. - flags can be a combination of i (case insensitive), g - (global) or s (match newline don't treat it as end of - line). - 're' - is regular expression - 'repl' - is replacement string - may contain - pseudo-variables - 'flags' - substitution flags (i - ignore case, g - global) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.12. subst usage -... -# adds 3463 prefix to uris ending with 3642 (just an example) -if (subst_user('/3642$/36423463/')){$ - -... -# adds avp 'user_prefix' as prefix to username in r-uri ending with 3642 -if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$ - -... - -1.3.13. subst_body('/re/repl/flags') - - Replaces re with repl (sed or perl like) in the body of the - message. - - Meaning of the parameters is as follows: - * '/re/repl/flags' (string) - sed like regular expression. - flags can be a combination of i (case insensitive), g - (global) or s (match newline don't treat it as end of - line). - 're' - is regular expression - 'repl' - is replacement string - may contain - pseudo-variables - 'flags' - substitution flags (i - ignore case, g - global) - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - Example 1.13. subst_body usage -... -if (subst_body("/^o=([^ ]*) /o=$fU /")) - xlog("successfully prepared an "o" line update!\n"); - -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 55 43 440 475 - 2. Daniel-Constantin Mierla (@miconda) 40 28 938 201 - 3. Razvan Crainea (@razvancrainea) 40 6 16 1952 - 4. Andrei Dragus 32 15 1540 196 - 5. Andrei Pelinescu-Onciul 28 21 446 134 - 6. Jiri Kuthan (@jiriatipteldotorg) 18 14 293 45 - 7. Liviu Chircu (@liviuchircu) 12 10 32 60 - 8. Jan Janak (@janakj) 12 6 496 27 - 9. Vlad Patrascu (@rvlad-patrascu) 10 5 129 147 - 10. Juha Heinanen (@juha-h) 8 5 210 8 - - All remaining contributors: Elena-Ramona Modroiu, Henning - Westerholt (@henningw), Maksym Sobolyev (@sobomax), Ovidiu Sas - (@ovidiusas), Anca Vamanu, Marc Haisenko, Andreas Heise, Klaus - Darilion, Vlad Paiu (@vladpaiu), Andreas Granig, Hugues - Mitonneau, Konstantin Bokarius, Saúl Ibarra Corretgé (@saghul), - Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Christophe - Sollet (@csollet). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Oct 2013 - May 2024 - 2. Maksym Sobolyev (@sobomax) Jul 2004 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2019 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2002 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Anca Vamanu Oct 2008 - May 2011 - 8. Ovidiu Sas (@ovidiusas) Dec 2010 - Jan 2011 - 9. Christophe Sollet (@csollet) Dec 2010 - Dec 2010 - 10. Vlad Paiu (@vladpaiu) Oct 2010 - Oct 2010 - - All remaining contributors: Andrei Dragus, Saúl Ibarra Corretgé - (@saghul), Hugues Mitonneau, Andreas Granig, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Henning Westerholt (@henningw), Juha Heinanen (@juha-h), - Andreas Heise, Klaus Darilion, Marc Haisenko, Elena-Ramona - Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri - Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu - Sas (@ovidiusas), Andrei Dragus, Anca Vamanu, Andreas Granig, - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Juha Heinanen (@juha-h), Klaus Darilion, Marc - Haisenko, Elena-Ramona Modroiu, Jan Janak (@janakj), Maksym - Sobolyev (@sobomax), Jiri Kuthan (@jiriatipteldotorg), Andrei - Pelinescu-Onciul. - - Documentation Copyrights: - - Copyright © 2003 FhG FOKUS diff --git a/modules/textops/README.md b/modules/textops/README.md new file mode 100644 index 00000000000..642e481c21b --- /dev/null +++ b/modules/textops/README.md @@ -0,0 +1,419 @@ +--- +title: "textops Module" +description: "The module implements text based operations over the SIP message processed by OpenSIPS." +--- + +## Admin Guide + + +### Overview + + +The module implements text based operations over the SIP message +processed by OpenSIPS. SIP is a text based protocol and the module +provides a large set of very useful functions to manipulate the +message at text level, e.g., regular expression search and replace, +Perl-like substitutions, etc. + + +> [!NOTE] +> All SIP-aware functions like *insert_hf*, +> *append_hf* or *codec* +> operations have been moved to the *sipmsgops* +> module. + + +#### Known Limitations + + +search ignores folded lines. For example, +search("(From|f):.*@foo.bar") +doesn't match the following From header field: + + +```c +From: medabeda + ;tag=1234 +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *No dependencies on other OpenSIPS modules*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Functions + + +#### search(re) + + +Searches for the re in the message. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="search usage" +... +if ( search("[Ss][Ii][Pp]") ) { /*....*/ }; +... +``` + + +#### search_body(re) + + +Searches for the re in the body of the message. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="search_body usage" +... +if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ }; +... +``` + + +#### search_append(re, txt) + + +Searches for the first match of re and appends txt after it. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) - String to be appended. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="search_append usage" +... +search_append("[Oo]pen[Ss]er", " SIP Proxy"); +... +``` + + +#### search_append_body(re, txt) + + +Searches for the first match of re in the body of the message +and appends txt after it. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) - String to be appended. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="search_append_body usage" +... +search_append_body("[Oo]pen[Ss]er", " SIP Proxy"); +... +``` + + +#### replace(re, txt) + + +Replaces the first occurrence of re with txt. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="replace usage" +... +replace("opensips", "Open SIP Server"); +... +``` + + +#### replace_body(re, txt) + + +Replaces the first occurrence of re in the body of the message +with txt. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="replace_body usage" +... +replace_body("opensips", "Open SIP Server"); +... +``` + + +#### replace_all(re, txt) + + +Replaces all occurrence of re with txt. + + +Meaning of the parameters is as follows: + + +- *re* - (string) Regular expression. +- *txt* (string) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="replace_all usage" +... +replace_all("opensips", "Open SIP Server"); +... +``` + + +#### replace_body_all(re, txt) + + +Replaces all occurrence of re in the body of the message +with txt. Matching is done on a per-line basis. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="replace_body_all usage" +... +replace_body_all("opensips", "Open SIP Server"); +... +``` + + +#### replace_body_atonce(re, txt) + + +Replaces all occurrence of re in the body of the message +with txt. Matching is done over the whole body. + + +Meaning of the parameters is as follows: + + +- *re* (string) - Regular expression. +- *txt* (string) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="replace_body_atonce usage" +... +# strip the whole body from the message: +if(has_body() && replace_body_atonce("^.+$", "")) + remove_hf("Content-Type"); +... +``` + + +#### subst('/re/repl/flags') + + +Replaces re with repl (sed or perl like). + + +Meaning of the parameters is as follows: + + +- *'/re/repl/flags'* (string) - sed like regular +expression. flags can be a combination of i (case insensitive), +g (global) or s (match newline don't treat it as end of line). +'re' - is regular expression +'repl' - is replacement string - may contain pseudo-variables +'flags' - substitution flags (i - ignore case, g - global) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="subst usage" +... +# replace the uri in to: with the message uri (just an example) +if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1\u\2/ig') ) {}; + +# replace the uri in to: with the value of avp sip_address (just an example) +if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\2/ig') ) {}; + +... +``` + + +#### subst_uri('/re/repl/flags') + + +Runs the re substitution on the message uri (like subst but works +only on the uri) + + +Meaning of the parameters is as follows: + + +- *'/re/repl/flags'* (string) - sed like regular +expression. flags can be a combination of i (case insensitive), +g (global) or s (match newline don't treat it as end of line). +'re' - is regular expression +'repl' - is replacement string - may contain pseudo-variables +'flags' - substitution flags (i - ignore case, g - global) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="subst_uri usage" +... +# adds 3463 prefix to numeric uris, and save the original uri (\0 match) +# as a parameter: orig_uri (just an example) +if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:3463\1@\2;orig_uri=\0/i')){$ + +# adds the avp 'uri_prefix' as prefix to numeric uris, and save the original +# uri (\0 match) as a parameter: orig_uri (just an example) +if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\0/i')){$ + +... +``` + + +#### subst_user('/re/repl/flags') + + +Runs the re substitution on the message uri (like subst_uri but works +only on the user portion of the uri) + + +Meaning of the parameters is as follows: + + +- *'/re/repl/flags'* (string) - sed like regular +expression. flags can be a combination of i (case insensitive), +g (global) or s (match newline don't treat it as end of line). +'re' - is regular expression +'repl' - is replacement string - may contain pseudo-variables +'flags' - substitution flags (i - ignore case, g - global) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="subst usage" +... +# adds 3463 prefix to uris ending with 3642 (just an example) +if (subst_user('/3642$/36423463/')){$ + +... +# adds avp 'user_prefix' as prefix to username in r-uri ending with 3642 +if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$ +... +``` + + +#### subst_body('/re/repl/flags') + + +Replaces re with repl (sed or perl like) in the body of the message. + + +Meaning of the parameters is as follows: + + +- *'/re/repl/flags'* (string) - sed like regular +expression. flags can be a combination of i (case insensitive), +g (global) or s (match newline don't treat it as end of line). +'re' - is regular expression +'repl' - is replacement string - may contain pseudo-variables +'flags' - substitution flags (i - ignore case, g - global) + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE, BRANCH_ROUTE. + + +```opensips title="subst_body usage" +... +if (subst_body("/^o=([^ ]*) /o=$fU /")) + xlog("successfully prepared an "o" line update!\n"); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/textops/doc/contributors.xml b/modules/textops/doc/contributors.xml deleted file mode 100644 index bf2832f0fce..00000000000 --- a/modules/textops/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 55 - 43 - 440 - 475 - - - 2. - Daniel-Constantin Mierla (@miconda) - 40 - 28 - 938 - 201 - - - 3. - Razvan Crainea (@razvancrainea) - 40 - 6 - 16 - 1952 - - - 4. - Andrei Dragus - 32 - 15 - 1540 - 196 - - - 5. - Andrei Pelinescu-Onciul - 28 - 21 - 446 - 134 - - - 6. - Jiri Kuthan (@jiriatipteldotorg) - 18 - 14 - 293 - 45 - - - 7. - Liviu Chircu (@liviuchircu) - 12 - 10 - 32 - 60 - - - 8. - Jan Janak (@janakj) - 12 - 6 - 496 - 27 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 10 - 5 - 129 - 147 - - - 10. - Juha Heinanen (@juha-h) - 8 - 5 - 210 - 8 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Henning Westerholt (@henningw), Maksym Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Anca Vamanu, Marc Haisenko, Andreas Heise, Klaus Darilion, Vlad Paiu (@vladpaiu), Andreas Granig, Hugues Mitonneau, Konstantin Bokarius, Saúl Ibarra Corretgé (@saghul), Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Christophe Sollet (@csollet). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Oct 2013 - May 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Jul 2004 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2019 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2002 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Anca Vamanu - Oct 2008 - May 2011 - - - 8. - Ovidiu Sas (@ovidiusas) - Dec 2010 - Jan 2011 - - - 9. - Christophe Sollet (@csollet) - Dec 2010 - Dec 2010 - - - 10. - Vlad Paiu (@vladpaiu) - Oct 2010 - Oct 2010 - - - -
-All remaining contributors: Andrei Dragus, Saúl Ibarra Corretgé (@saghul), Hugues Mitonneau, Andreas Granig, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Juha Heinanen (@juha-h), Andreas Heise, Klaus Darilion, Marc Haisenko, Elena-Ramona Modroiu, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas), Andrei Dragus, Anca Vamanu, Andreas Granig, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h), Klaus Darilion, Marc Haisenko, Elena-Ramona Modroiu, Jan Janak (@janakj), Maksym Sobolyev (@sobomax), Jiri Kuthan (@jiriatipteldotorg), Andrei Pelinescu-Onciul. -
- -
diff --git a/modules/textops/doc/textops.xml b/modules/textops/doc/textops.xml deleted file mode 100644 index 4498e4ed807..00000000000 --- a/modules/textops/doc/textops.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - textops Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2003 &fhg; - - diff --git a/modules/textops/doc/textops_admin.xml b/modules/textops/doc/textops_admin.xml deleted file mode 100644 index 721941cd8de..00000000000 --- a/modules/textops/doc/textops_admin.xml +++ /dev/null @@ -1,536 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module implements text based operations over the SIP message - processed by OpenSIPS. SIP is a text based protocol and the module - provides a large set of very useful functions to manipulate the - message at text level, e.g., regular expression search and replace, - Perl-like substitutions, etc. - - - Note: all SIP-aware functions like insert_hf, - append_hf or codec - operations have been moved to the sipmsgops - module. - -
- Known Limitations - - search ignores folded lines. For example, - search((From|f):.*@foo.bar) - doesn't match the following From header field: - - -From: medabeda - <sip:medameda@foo.bar>;tag=1234 - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - No dependencies on other &osips; modules. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- - -
- Exported Functions - - -
- - <function moreinfo="none">search_body(re)</function> - - - Searches for the re in the body of the message. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>search_body</function> usage - -... -if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ }; -... - - -
- -
- - <function moreinfo="none">search_append(re, txt)</function> - - - Searches for the first match of re and appends txt after it. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - String to be appended. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>search_append</function> usage - -... -search_append("[Oo]pen[Ss]er", " SIP Proxy"); -... - - -
- -
- - <function moreinfo="none">search_append_body(re, txt)</function> - - - Searches for the first match of re in the body of the message - and appends txt after it. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - String to be appended. - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>search_append_body</function> usage - -... -search_append_body("[Oo]pen[Ss]er", " SIP Proxy"); -... - - -
- -
- - <function moreinfo="none">replace(re, txt)</function> - - - Replaces the first occurrence of re with txt. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>replace</function> usage - -... -replace("opensips", "Open SIP Server"); -... - - -
- -
- - <function moreinfo="none">replace_body(re, txt)</function> - - - Replaces the first occurrence of re in the body of the message - with txt. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>replace_body</function> usage - -... -replace_body("opensips", "Open SIP Server"); -... - - -
- -
- - <function moreinfo="none">replace_all(re, txt)</function> - - - Replaces all occurrence of re with txt. - - Meaning of the parameters is as follows: - - - re - (string) Regular expression. - - - - txt (string) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>replace_all</function> usage - -... -replace_all("opensips", "Open SIP Server"); -... - - -
- -
- - <function moreinfo="none">replace_body_all(re, txt)</function> - - - Replaces all occurrence of re in the body of the message - with txt. Matching is done on a per-line basis. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>replace_body_all</function> usage - -... -replace_body_all("opensips", "Open SIP Server"); -... - - -
- -
- - <function moreinfo="none">replace_body_atonce(re, txt)</function> - - - Replaces all occurrence of re in the body of the message - with txt. Matching is done over the whole body. - - Meaning of the parameters is as follows: - - - re (string) - Regular expression. - - - - txt (string) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>replace_body_atonce</function> usage - -... -# strip the whole body from the message: -if(has_body() && replace_body_atonce("^.+$", "")) - remove_hf("Content-Type"); -... - - -
- -
- - <function moreinfo="none">subst('/re/repl/flags')</function> - - - Replaces re with repl (sed or perl like). - - Meaning of the parameters is as follows: - - - '/re/repl/flags' (string) - sed like regular - expression. flags can be a combination of i (case insensitive), - g (global) or s (match newline don't treat it as end of line). - - - 're' - is regular expression - - - 'repl' - is replacement string - may contain pseudo-variables - - - 'flags' - substitution flags (i - ignore case, g - global) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>subst</function> usage - -... -# replace the uri in to: with the message uri (just an example) -if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1\u\2/ig') ) {}; - -# replace the uri in to: with the value of avp sip_address (just an example) -if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\2/ig') ) {}; - -... - - -
- -
- - <function moreinfo="none">subst_uri('/re/repl/flags')</function> - - - Runs the re substitution on the message uri (like subst but works - only on the uri) - - Meaning of the parameters is as follows: - - - '/re/repl/flags' (string) - sed like regular - expression. flags can be a combination of i (case insensitive), - g (global) or s (match newline don't treat it as end of line). - - - 're' - is regular expression - - - 'repl' - is replacement string - may contain pseudo-variables - - - 'flags' - substitution flags (i - ignore case, g - global) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>subst_uri</function> usage - -... -# adds 3463 prefix to numeric uris, and save the original uri (\0 match) -# as a parameter: orig_uri (just an example) -if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:3463\1@\2;orig_uri=\0/i')){$ - -# adds the avp 'uri_prefix' as prefix to numeric uris, and save the original -# uri (\0 match) as a parameter: orig_uri (just an example) -if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\0/i')){$ - -... - - -
- -
- - <function moreinfo="none">subst_user('/re/repl/flags')</function> - - - Runs the re substitution on the message uri (like subst_uri but works - only on the user portion of the uri) - - Meaning of the parameters is as follows: - - - '/re/repl/flags' (string) - sed like regular - expression. flags can be a combination of i (case insensitive), - g (global) or s (match newline don't treat it as end of line). - - - 're' - is regular expression - - - 'repl' - is replacement string - may contain pseudo-variables - - - 'flags' - substitution flags (i - ignore case, g - global) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>subst</function> usage - -... -# adds 3463 prefix to uris ending with 3642 (just an example) -if (subst_user('/3642$/36423463/')){$ - -... -# adds avp 'user_prefix' as prefix to username in r-uri ending with 3642 -if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$ - -... - - -
- -
- - <function moreinfo="none">subst_body('/re/repl/flags')</function> - - - Replaces re with repl (sed or perl like) in the body of the message. - - Meaning of the parameters is as follows: - - - '/re/repl/flags' (string) - sed like regular - expression. flags can be a combination of i (case insensitive), - g (global) or s (match newline don't treat it as end of line). - - - 're' - is regular expression - - - 'repl' - is replacement string - may contain pseudo-variables - - - 'flags' - substitution flags (i - ignore case, g - global) - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE, BRANCH_ROUTE. - - - <function>subst_body</function> usage - -... -if (subst_body("/^o=([^ ]*) /o=$fU /")) - xlog("successfully prepared an "o" line update!\n"); - -... - - -
- -
-
- diff --git a/modules/tls_mgm/README b/modules/tls_mgm/README deleted file mode 100644 index 5370833bb23..00000000000 --- a/modules/tls_mgm/README +++ /dev/null @@ -1,1603 +0,0 @@ -TLS_MGM module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Usage - 1.3. TLS libraries - 1.4. TLS domains - 1.5. Defining TLS domains - 1.6. Dependencies - - 1.6.1. OpenSIPS Modules - 1.6.2. Dependencies of external libraries - - 1.7. Exported Functions - - 1.7.1. is_peer_verified - - 1.8. Exported MI Functions - - 1.8.1. tls_list - 1.8.2. tls_reload - - 1.9. OpenSIPS Exported parameters - - 1.9.1. listen=interface - 1.9.2. tls_library (string) - 1.9.3. tls_method ([domain]string) - 1.9.4. certificate ([domain](string) - 1.9.5. private_key ([domain](string) - 1.9.6. ca_list ([domain](string) - 1.9.7. ca_dir ([domain](string) - 1.9.8. crl_dir ([domain](string) - 1.9.9. crl_check_all ([domain](string) - 1.9.10. ciphers_list ([domain](string) - 1.9.11. dh_params ([domain](string) - 1.9.12. ec_curve ([domain](string) - 1.9.13. verify_cert ([domain](string) - 1.9.14. require_cert ([domain](string) - 1.9.15. client_tls_domain_avp (string) - 1.9.16. client_sip_domain_avp (string) - 1.9.17. db_url (string) - 1.9.18. db_table (string) - 1.9.19. domain_col (string) - 1.9.20. match_ip_address_col (string) - 1.9.21. match_sip_domain_col (string) - 1.9.22. tls_method_col (string) - 1.9.23. verify_cert_col (string) - 1.9.24. require_cert_col (string) - 1.9.25. certificate_col (string) - 1.9.26. private_key_col (string) - 1.9.27. crl_check_all_col (string) - 1.9.28. crl_dir_col (string) - 1.9.29. ca_list_col (string) - 1.9.30. ca_dir_col (string) - 1.9.31. cipher_list_col (string) - 1.9.32. dh_params_col (string) - 1.9.33. ec_curve_col (string) - 1.9.34. match_ip_address (string) - 1.9.35. match_sip_domain (string) - 1.9.36. server_domain, client_domain (string) - - 1.10. Variables - - 1.10.1. $tls_version - 1.10.2. $tls_description - 1.10.3. $tls_cipher_info - 1.10.4. $tls_cipher_bits - 1.10.5. $tls_[peer|my]_version - 1.10.6. $tls_[peer|my]_serial - 1.10.7. $tls_[peer|my]_[subject|issuer] - 1.10.8. $tls_[peer|my]_[subject|issuer]_cn - 1.10.9. $tls_[peer|my]_[subject|issuer]_locality - 1.10.10. $tls_[peer|my]_[subject|issuer]_country - 1.10.11. $tls_[peer|my]_[subject|issuer]_state - 1.10.12. - $tls_[peer|my]_[subject|issuer]_organization - - 1.10.13. $tls_[peer|my]_[subject|issuer]_unit - 1.10.14. $tls_[peer|my]_san_email - 1.10.15. $tls_[peer|my]_san_hostname - 1.10.16. $tls_[peer|my]_san_uri - 1.10.17. $tls_[peer|my]_san_ip - 1.10.18. $tls_peer_verified - 1.10.19. $tls_peer_revoked - 1.10.20. $tls_peer_expired - 1.10.21. $tls_peer_selfsigned - 1.10.22. $tls_peer_notBefore - 1.10.23. $tls_peer_notAfter - - 1.11. OpenSIPS with TLS - script example - 1.12. Debug TLS connections - - 2. Developer Guide - - 2.1. API Functions - - 2.1.1. find_server_domain - 2.1.2. find_client_domain - 2.1.3. get_handshake_timeout - 2.1.4. get_send_timeout - - 2.2. TLS_CONFIG - 2.3. TLS_INIT - - 2.3.1. ssl context - 2.3.2. pre_init_tls - 2.3.3. init_tls - 2.3.4. destroy_tls - 2.3.5. tls_init - 2.3.6. os_malloc, os_realloc, os_free - - 2.4. TLS_DOMAIN - - 2.4.1. tls_domains - 2.4.2. tls_find_server_domain - 2.4.3. tls_find_client_domain - 2.4.4. tls_find_client_domain_addr - 2.4.5. tls_find_client_domain_name - 2.4.6. tls_new__domain - 2.4.7. tls_new_server_domain - 2.4.8. tls_new_client_domain - 2.4.9. tls_new_client_domain_name - 2.4.10. tls_free_domains - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. is_peer_verified usage - 1.2. Set listen variable - 1.3. Set tls_library variable - 1.4. Set tls_method variable - 1.5. Set tls_method range variable - 1.6. Set certificate variable - 1.7. Set private_key variable - 1.8. Set ca_list variable - 1.9. Set ca_dir variable - 1.10. Set crl_dir variable - 1.11. Set crl_check_all variable - 1.12. Set ciphers_list variable - 1.13. Set dh_params variable - 1.14. Set verify_cert variable - 1.15. Set require_cert variable - 1.16. Set client_tls_domain_avp variable - 1.17. Set client_sip_domain_avp variable - 1.18. Usage of db_url block - 1.19. Usage of db_table block - 1.20. Usage of domain_col block - 1.21. Usage of match_ip_address_col block - 1.22. Usage of match_sip_domain_col block - 1.23. Usage of tls_method_col block - 1.24. Usage of vertify_cert_col block - 1.25. Usage of require_cert_col block - 1.26. Usage of certificate_col block - 1.27. Usage of private_key_col block - 1.28. Usage of crl_check_all block - 1.29. Usage of crl_dir_col block - 1.30. Usage of ca_list_col block - 1.31. Usage of ca_dir_col block - 1.32. Usage of cipher_list_col block - 1.33. Usage of dh_params_col block - 1.34. Usage of ec_curve_col block - 1.35. Set match_ip_address variable - 1.36. Set match_sip_domain variable - 1.37. Usage of tls_client_domain and tls_server_domain block - 1.38. Example of $tls_[peer|my]_[subject|issuer] - 1.39. Script with TLS support - 1.40. Example of TLS logging - -Chapter 1. Admin Guide - -1.1. Overview - - This module is a management module for TLS certificates and - parameters. It provides an interface for all the modules that - use the TLS protocol. It also exports pseudo variables with - certificate and TLS parameters. - -1.2. Usage - - This module is used to provision TLS certificates and - parameters for all the modules that use TLS transport (like - proto_tls or proto_wss). The module supports multiple virtual - domains that can be assigned to different listeners (servers) - or new connections (clients). Each TLS module that uses this - management module should assign itself to one or more domains. - - The module allows the definition of the TLS domains both via - module parameters (script level) and via an SQL table. - - A script example which details this module's usage can be found - in Section 1.11, “OpenSIPS with TLS - script example”. - -1.3. TLS libraries - - Besides TLS certificates and parameters, this module also acts - as an inteface between the actual TLS implemenation (provided - by openSSL or wolfSSL libraries) and transport protocol modules - like proto_tls or proto_wss. The tls_mgm module transparently - exposes the TLS operations implemented by tls_openssl and - tls_wolfssl modules to the higher-level OpenSIPS transport - modules. - - The TLS library selection ca be configured through the - tls_library module parameter. - -1.4. TLS domains - - The wording 'TLS domain' means that this TLS connection will - have different parameters than another TLS connection (from - another TLS domain). Thus, TLS domains are not directly related - to different SIP domains, although they are often used in - conjunction. Depending on the direction of the TLS handshake, a - TLS domain is called 'client domain' (=outgoing TLS connection) - or 'server domain' (= incoming TLS connection). - - If you run several SIP domains you can specify some parameters - for each of them separately (regardless if you have only one or - multiple socket=tls:ip:port entries in the config file). - - For example, TLS domains can be used in virtual hosting - scenarios with TLS. OpenSIPS offers SIP service for multiple - domains, e.g. atlanta.com and biloxi.com. Altough both domains - will be hosted on a single SIP proxy, the SIP proxy needs 2 - certificates: One for atlanta.com and one for biloxi.com. For - incoming TLS connections, the SIP proxy has to present the - respective certificate during the TLS handshake. As the SIP - proxy does not have a received SIP message yet (this is done - after the TLS handshake), the SIP proxy can not retrieve the - target domain from SIP (which would have been usually retrieved - from the domain in the request URI). Thus, distinction for - these domains must be done by using multiple listening sockets - or by having clients that send the Servername TLS - extension(SNI) in the handshake process. - - For outgoing TLS connections, the TLS domain is chosen based on - the destination socket of the underlying outgoing TCP - connection and/or by taking a decision at script level via an - AVP. For example, you can inspect headers like RURI or From and - match the domain in the SIP header with filters that you have - set up for the TLS domains. - - NOTE: Except tls_handshake_timeout and tls_send_timeout all TLS - parameters can be set per TLS domain. - -1.5. Defining TLS domains - - TLS domains can be defined in two ways: - * by setting the server_domain or client_domain module - parameters - * by provisioning in DB - - For the domains defined in the DB, the certificate, private - key, list of trusted CAs and Diffie-Hellman parameters are - provisioned as BLOB values while for script defined domains you - must provide path to files. - - You can define domains both in the DB and script at the same - time. - - For any TLS domain (defined through script or DB) if not - specified otherwise, the default settings are: - * method - SSLv23 - * verify_cert - 1 - * require_cert - 1 - * certificate - CFG_DIR/tls/cert.pem - * private_key - CFG_DIR/tls/ckey.pem - * crl_check_all - 0 - * crl_dir - none - * ca_list - none - * ca_dir - /etc/pki/CA/ - * cipher_list - the OpenSSL default ciphers - * dh_params - none - * ec_curve - none - -1.6. Dependencies - -1.6.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * tls_openssl or tls_wolfssl, unless tls_library is set to - 'none'. - -1.6.2. Dependencies of external libraries - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.7. Exported Functions - -1.7.1. is_peer_verified - - Returns 1 if the message is received via TLS and the peer was - verified during TLS connection handshake, otherwise it returns - -1 - - This function can be used from REQUEST_ROUTE. - - Example 1.1. is_peer_verified usage -... -if (is_peer_verified()) { - xlog("L_INFO","request from verified TLS peer\n"); -} else { - xlog("L_INFO","request not verified\n"); -} -... - -1.8. Exported MI Functions - -1.8.1. tls_list - - List all domains information. - -1.8.2. tls_reload - - Reloads the TLS domains information from the database. The - previous DB defined domains are discarded but the script - defined domains are preserved. - -1.9. OpenSIPS Exported parameters - - All these parameters can be used from the opensips.cfg file, to - configure the behavior of OpenSIPS-TLS. - -1.9.1. listen=interface - - Not specific to TLS. Allows to specify the protocol (udp, tcp, - tls), the IP address and the port where the listening server - will be. - - Example 1.2. Set listen variable -... -socket= tls:1.2.3.4:5061 -... - -1.9.2. tls_library (string) - - Selects which TLS library to use. Possible values are: - * auto - auto-detect which TLS library module (tls_openssl or - tls_wolfssl) was loaded. OpenSIPS will not start if no - module, or both modules are found. - * none - do not use any TLS library; this is useful when the - tls_mgm module is required only for the management of TLS - certificates and parameters by modules like db_mysql, - rabbitmq etc. ( and not for TLS operations by transport - modules like proto_tls etc.) - * openssl - use the openSSL library through the tls_openssl - module. - * wolfssl - use the wolfSSL library through the tls_wolfssl - module. - - Default value is auto. - - Example 1.3. Set tls_library variable -... -modparam("tls_mgm", "tls_library", "none") -... - -1.9.3. tls_method ([domain]string) - - Sets the TLS protocol. The domain part represents the name of - the TLS domain. The supported TLS methods are: - * TLSv1_3 - means OpenSIPS will accept only TLSv1.3 - connections. This version is only available starting with - OpenSSL 1.1.1 version. - * TLSv1_2 - means OpenSIPS will accept only TLSv1.2 - connections (rfc3261 conformant). - * TLSv1 - means OpenSIPS will accept only TLSv1 connections - (rfc3261 conformant). - * SSLv23 - means OpenSIPS will accept any of the above - methods, but the initial SSL hello must be v2 (in the - initial hello all the supported protocols are advertised - enabling switching to a higher and more secure version). - The initial v2 hello means it will not accept connections - from SSLv3 or TLSv1 only clients. - - If you are using an OpenSSL library newer than 1.1.0, you can - also specify a range of accepted TLS versions as - [VLOW]-[VHIGH]. If VLOW is not specified it will use the - minimum supported protocol version and if VHIGH is not - specified it will use the maximum supported protocol version. - This means that using a range where both the low and high - values are missing, will accept all the supported methods, but - unlike SSLv23 will not require the initial hello to be SSLv2. - - Default value is SSLv23. - -Warning - - For extended compatibility with older system, best use SSLv23. - - If you want RFC3261 conformance and all your clients support - TLSv1 (or you are planning to use encrypted "tunnels" only - between different OpenSIPS proxies) use TLSv1. If you want to - support older clients use SSLv23 (in fact most of the - applications with SSL support use the SSLv23 method). - - Example 1.4. Set tls_method variable -... -modparam("tls_mgm", "tls_method", "[dom]TLSv1") -... - - Example 1.5. Set tls_method range variable -... -modparam("tls_mgm", "tls_method", "[dom]TLSv1-TLSv1_3") # between v1 an -d v1.3 -modparam("tls_mgm", "tls_method", "[dom]TLSv1-") # v1 or higher -modparam("tls_mgm", "tls_method", "[dom]-TLSv1_2") # up to v1.2 -modparam("tls_mgm", "tls_method", "[dom]-") # all supported -... - -1.9.4. certificate ([domain](string) - - Public certificate file for OpenSIPS. It will be used as - server-side certificate for incoming TLS connections, and as a - client-side certificate for outgoing TLS connections. The - domain part represents the name of the TLS domain. - - Default value is "CFG_DIR/tls/cert.pem". - - Example 1.6. Set certificate variable -... -modparam("tls_mgm", "certificate", "[dom]/mycerts/certs/opensips_server_ -cert.pem") -... - -1.9.5. private_key ([domain](string) - - Private key of the above certificate. I must be kept in a safe - place with tight permissions! The domain part represents the - name of the TLS omain. - - Default value is "CFG_DIR/tls/ckey.pem". - - Example 1.7. Set private_key variable -... -modparam("tls_mgm", "private_key", "[dom]/mycerts/private/prik.pem") -... - -1.9.6. ca_list ([domain](string) - - List of trusted CAs. The file contains the certificates - accepted, one after the other. It MUST be a file, not a folder. - The domain part represents the name of the TLS domain. - - Default value is "". - - Example 1.8. Set ca_list variable -... -modparam("tls_mgm", "ca_list", "[dom]/mycerts/certs/ca_list.pem") -... - -1.9.7. ca_dir ([domain](string) - - Directory storing trusted CAs. The certificates in the - directory must be in hashed form, as described in the openssl - documentation for the Hashed Directory Method. The domain part - represents the name of the TLS domain. - - Default value is "/etc/pki/CA/". - - Example 1.9. Set ca_dir variable -... -modparam("tls_mgm", "ca_dir", "[dom]/mycerts/certs") -... - -1.9.8. crl_dir ([domain](string) - - Directory storing certificate revocation lists (CRLs). The - domain part represents the name of the TLS domain. - - If this parameter is not set, no CRLs will be used. - - Example 1.10. Set crl_dir variable -... -modparam("tls_mgm", "crl_dir", "[dom]/mycerts/crls") -... - -1.9.9. crl_check_all ([domain](string) - - Setting this parameter with a non-zero integer value enables - CRL checking for the entire certificate chain. - - By default, only the leaf certificate in the certificate chain - is checked. - - Example 1.11. Set crl_check_all variable -... -modparam("tls_mgm", "crl_check_all", "[dom]1") -... - -1.9.10. ciphers_list ([domain](string) - - You can specify the list of algorithms for authentication and - encryption that you allow. The domain part represents the name - of the TLS domain. To obtain a list of ciphers and then choose, - use the openssl application: - * openssl ciphers 'ALL:eNULL:!LOW:!EXPORT' - -Warning - - Do not use the NULL algorithms (no encryption) ... only for - testing!!! - - It defaults to the OpenSSL default ciphers. - - Example 1.12. Set ciphers_list variable -... -modparam("tls_mgm", "ciphers_list", "[dom]NULL") -... - -1.9.11. dh_params ([domain](string) - - You can specify a file which contains Diffie-Hellman parameters - as a PEM-file. This is needed if you would like to specify - ciphers including Diffie-Hellman mode. The domain part - represents the name of the TLS domain. - - It defaults to not set a dh param file. - - Example 1.13. Set dh_params variable -... -modparam("tls_mgm", "dh_params", "[dom]/etc/pki/CA/dh1024.pem") -... - -1.9.12. ec_curve ([domain](string) - - You can specify an elliptic curve which should be used for - ciphers which demand an elliptic curve. The domain part - represents the name of the TLS domain. - - It's usable only if TLS v1.1/1.2 support was compiled. A list - of curves which can be used you can get by - openssl ecparam -list_curves - - It defaults to not set a elliptic curve. - -1.9.13. verify_cert ([domain](string) - - Activates SSL_VERIFY_PEER in the ssl_context. For a detailed - explanation, check the openssl documentation. - - The domain part represents the name of the TLS domain. - - Default value is 1. - - Example 1.14. Set verify_cert variable -... -modparam("tls_mgm", "verify_cert", "[dom]0") -... - -1.9.14. require_cert ([domain](string) - - Activates SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the ssl_context. - For a detailed explanation, check the openssl documentation. - This parameter only makes sense for server domains and if the - verify_cert parameter is also set. - - The domain part represents the name of the TLS domain. - - Default value is 1. - - Example 1.15. Set require_cert variable -... -modparam("tls_mgm", "require_cert", "[dom]0") -... - -1.9.15. client_tls_domain_avp (string) - - Name of the AVP used for enforcing the selection of a specific - TLS client domain. Setting this AVP to the name of a TLS client - domain will result in using that specific domain regardless of - the standard matching mechanism. - - Note: If there is already an existing TLS connection to the - remote target, it will be reused and setting this AVP has no - effect. - - Note: You can force a particular domain to be used just for a - particular branch by setting the $bavp variable with the same - name. When both $bavp and $avp variables are set, the first one - takes precedence. - - No default value. - - Example 1.16. Set client_tls_domain_avp variable -... -modparam("tls_mgm", "client_tls_domain_avp", "tls_match_dom") -... - -1.9.16. client_sip_domain_avp (string) - - Name of the AVP that sets the SIP domain used in the TLS client - domain matching process. - - Note: If there is already an existing TLS connection to the - remote target, it will be reused and setting this AVP has no - effect. - - Note: You can force a particular SIP domain to be used just for - a particular branch by setting the $bavp variable with the same - name. When both $bavp and $avp variables are set, the first one - takes precedence. - - For the AVP usage example, refer to Section 1.9.36, - “server_domain, client_domain (string)”. - - No default value. - - Example 1.17. Set client_sip_domain_avp variable -... -modparam("tls_mgm", "client_sip_domain_avp", "sip_match_dom") -... - -1.9.17. db_url (string) - - The database url. It cannot be NULL. - - You cannot use the "tls_domain=dom_name" URL parameter for a - TLS connection to the database for the tls_mgm module itself. - - Example 1.18. Usage of db_url block -modparam("tls_mgm", "db_url", "mysql://root:admin@localhost/opensips") - -1.9.18. db_table (string) - - Sets the database table name. - - Default value is "tls_mgm". - - Example 1.19. Usage of db_table block -modparam("tls_mgm", "db_table", "tls_mgm") - -1.9.19. domain_col (string) - - Sets the name for the TLS domain column. - - Default value is "domain". - - Example 1.20. Usage of domain_col block -modparam("tls_mgm", "domain_col", "tls_domain") - -1.9.20. match_ip_address_col (string) - - Sets the IP address matching column name. - - Default value is "match_ip_address". - - Example 1.21. Usage of match_ip_address_col block -modparam("tls_mgm", "match_ip_address_col", "addr") - -1.9.21. match_sip_domain_col (string) - - Sets the SIP domain matching column name. - - Default value is "match_sip_domain". - - Example 1.22. Usage of match_sip_domain_col block -modparam("tls_mgm", "match_sip_domain_col", "addr") - -1.9.22. tls_method_col (string) - - Sets the method column name. - - Default value is "method". - - Example 1.23. Usage of tls_method_col block -modparam("tls_mgm", "tls_method_col", "method") - -1.9.23. verify_cert_col (string) - - Sets the verrify certificate column name. - - Default value is "verify_cert". - - Example 1.24. Usage of vertify_cert_col block -modparam("tls_mgm", "verify_cert_col", "verify_cert") - -1.9.24. require_cert_col (string) - - Sets the require certificate column name. - - Default value is "require_cert". - - Example 1.25. Usage of require_cert_col block -modparam("tls_mgm", "require_cert_col", "req") - -1.9.25. certificate_col (string) - - Sets the certificate column name. - - Default value is "certificate". - - Example 1.26. Usage of certificate_col block -modparam("tls_mgm", "certificate_col", "certificate") - -1.9.26. private_key_col (string) - - Sets the private key column name. - - Default value is "private_key". - - Example 1.27. Usage of private_key_col block -modparam("tls_mgm", "private_key_col", "pk") - -1.9.27. crl_check_all_col (string) - - Sets the crl_check_all column name. - - Default value is "crl_check_all". - - Example 1.28. Usage of crl_check_all block -modparam("tls_mgm", "crl_check_all_col", "crl_check") - -1.9.28. crl_dir_col (string) - - Sets the crl directory column name. - - Default value is "crl_dir". - - Example 1.29. Usage of crl_dir_col block -modparam("tls_mgm", "crl_dir_col", "crl_dir") - -1.9.29. ca_list_col (string) - - Sets the CA list column name. - - Default value is "ca_list". - - Example 1.30. Usage of ca_list_col block -modparam("tls_mgm", "ca_list_col", "ca_list") - -1.9.30. ca_dir_col (string) - - Sets the CA directory column name. - - Default value is "ca_dir". - - Example 1.31. Usage of ca_dir_col block -modparam("tls_mgm", "ca_dir_col", "ca_dir") - -1.9.31. cipher_list_col (string) - - Sets the cipher list column name. - - Default value is "cipher_list". - - Example 1.32. Usage of cipher_list_col block -modparam("tls_mgm", "cipher_list_col", "cipher_list") - -1.9.32. dh_params_col (string) - - Sets the Diffie-Hellmann parameters column name. - - Default value is "dh_params". - - Example 1.33. Usage of dh_params_col block -modparam("tls_mgm", "dh_params_col", "dh_parms") - -1.9.33. ec_curve_col (string) - - Sets the ec_curve column name. - - Default value is "ec_curve". - - Example 1.34. Usage of ec_curve_col block -modparam("tls_mgm", "ec_curve_col", "ec_curve") - -1.9.34. match_ip_address (string) - - The IP addresses and ports used to match a TLS connection with - a virtual TLS domain. For TLS server domains, these values will - be mathced against the socket on which the connection is - received. For TLS client domains, the values will be compared - with the destination socket of the connection. - - The parameter accepts a list of values, and the special value - "*" means: match any address. - - Default value is "*" (match any address). - - Example 1.35. Set match_ip_address variable -... -modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061, 10.0.0.11 -:5061") -... - -1.9.35. match_sip_domain (string) - - The SIP domains used to match a TLS connection with a virtual - TLS domain. For TLS server domains, these values will be - matched against the hostname provided in the TLS Servername - extension(SNI). For TLS client domains, the values will be - compared with the value of the client_sip_domain_avp AVP. - - The parameter accepts a list of FQDNs or the special values: - * * - match any sip domain( including no SNI provided, in - case of TLS server domains); - * none - match the TLS domain when there is no SNI provided - (make sense only for TLS server domains). Note that if a - SNI is provided, but does not match any other SIP domain - filter, the connection will be rejected. - - The FQDNs can be specified as with Unix shell-style wildcards. - If there are multiple potential matches, the most specific - domain will be selected(eg. a request for "foo.bar.com" is - matched with the domain specified with "foo.bar.com" versus the - one with "*.bar.com"). - - Default value is "*" (match any sip domain). - - Example 1.36. Set match_sip_domain variable -... -modparam("tls_mgm", "match_sip_domain", "[dom1]foo.com, bar.com, *.baz.c -om") -modparam("tls_mgm", "match_sip_domain", "[default_dom]*") -... - -1.9.36. server_domain, client_domain (string) - - You can define virtual TLS domains through these parameters. - - The value of these parameters represents the virtual tls - domain's name which is only used for identification. - - Example 1.37. Usage of tls_client_domain and tls_server_domain - block -... -socket=tls:10.0.0.10:5061 -... -# set the TLS client domain AVP -modparam("tls_mgm", "client_sip_domain_avp", "tls_sip_dom") -... - -# 'atlanta' server domain -modparam("tls_mgm", "server_domain", "dom1") -modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom1]atlanta.com") - -modparam("tls_mgm", "certificate", "[dom1]/certs/atlanta.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom1]/certs/atlanta.com/privkey.pem -") -modparam("tls_mgm", "ca_list", "[dom1]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom1]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom1]1") -modparam("tls_mgm", "require_cert", "[dom1]1") - -#'biloxi' server domain -modparam("tls_mgm", "server_domain", "dom2") -modparam("tls_mgm", "match_ip_address", "[dom2]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom2]biloxi.com") - -modparam("tls_mgm", "certificate", "[dom2]/certs/biloxi.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom2]/certs/biloxi.com/privkey.pem" -) -modparam("tls_mgm", "ca_list", "[dom2]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom2]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom2]1") -modparam("tls_mgm", "require_cert", "[dom2]1") - -# generic TLS server domain, if the client does not provide SNI -modparam("tls_mgm", "server_domain", "dom3") -modparam("tls_mgm", "match_ip_address", "[dom3]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom3]none") - -modparam("tls_mgm", "certificate", "[dom3]/certs/generic/cert.pem") -modparam("tls_mgm", "private_key", "[dom3]/certs/generic/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom3]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom3]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom3]1") -modparam("tls_mgm", "require_cert", "[dom3]1") - -# 'atlanta' client domain -modparam("tls_mgm", "client_domain", "dom4") -modparam("tls_mgm", "match_ip_address", "[dom4]*") -modparam("tls_mgm", "match_sip_domain", "[dom4]atlanta.com") - - -modparam("tls_mgm", "certificate", "[dom4]/certs/atlanta.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom4]/certs/atlanta.com/privkey.pem -") -modparam("tls_mgm", "ca_list", "[dom4]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom4]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom4]1") -modparam("tls_mgm", "require_cert", "[dom4]1") - -# 'biloxi' client domain -modparam("tls_mgm", "client_domain", "dom5") -modparam("tls_mgm", "match_ip_address", "[dom5]*") -modparam("tls_mgm", "match_sip_domain", "[dom5]biloxi.com") - -modparam("tls_mgm", "certificate", "[dom5]/certs/biloxi.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom5]/certs/biloxi.com/privkey.pem" -) -modparam("tls_mgm", "ca_list", "[dom5]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom5]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom5]1") -modparam("tls_mgm", "require_cert", "[dom5]1") - -# TLS client domain for GW provider -modparam("tls_mgm", "client_domain", "dom6") -modparam("tls_mgm", "match_ip_address", "[dom6]1.2.3.4:6677") -modparam("tls_mgm", "match_sip_domain", "[dom6]*") - -modparam("tls_mgm", "certificate", "[dom6]/certs/gw/cert.pem") -modparam("tls_mgm", "private_key", "[dom6]/certs/gw/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom6]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom6]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom6]0") - -... -route{ -... - # we match the TLS client domain using the SIP domain in the RURI - $avp(tls_sip_dom) = $rd; - t_relay(); - exit; -... - # calls to the PSTN GW, will match the correct TLS domain by IP - t_relay("tls:1.2.3.4:6677"); - exit; -... - -1.10. Variables - - This module exports the follong variables: - - Some variables are available for both, the peer'S certificate - and the local certificate. Further, some parameters can be read - from the “Subject” field or the “Issuer” field. - -1.10.1. $tls_version - - $tls_version - the TLS/SSL version which is used on the TLS - connection from which the message was received. String type. - -1.10.2. $tls_description - - $tls_description - the TLS/SSL description of the TLS - connection from which the message was received. String type. - -1.10.3. $tls_cipher_info - - $tls_cipher_info - the TLS/SSL cipher which is used on the TLS - connection from which the message was received. String type. - -1.10.4. $tls_cipher_bits - - $tls_cipher_bits - the number of cipher bits which are used on - the TLS connection from which the message was received. String - and Integer type. - -1.10.5. $tls_[peer|my]_version - - $tls_[peer|my]_version - the version of the certificate. String - type. - -1.10.6. $tls_[peer|my]_serial - - $tls_[peer|my]_serial - the serial number of the certificate. - String and Integer type. - -1.10.7. $tls_[peer|my]_[subject|issuer] - - $tls_[peer|my]_[subject|issuer] - ASCII dump of the fields in - the issuer/subject section of the certificate. String type. - - Example 1.38. Example of $tls_[peer|my]_[subject|issuer] -/C=AT/ST=Vienna/L=Vienna/O=enum.at/CN=enum.at - -1.10.8. $tls_[peer|my]_[subject|issuer]_cn - - $tls_[peer|my]_[subject|issuer]_cn - commonName in the - issuer/subject section of the certificate. String type. - -1.10.9. $tls_[peer|my]_[subject|issuer]_locality - - $tls_[peer|my]_[subject|issuer]_locality - localityName in the - issuer/subject section of the certificate. String type. - -1.10.10. $tls_[peer|my]_[subject|issuer]_country - - $tls_[peer|my]_[subject|issuer]_country - countryName in the - issuer/subject section of the certificate. String type. - -1.10.11. $tls_[peer|my]_[subject|issuer]_state - - $tls_[peer|my]_[subject|issuer]_state - stateOrProvinceName in - the issuer/subject section of the certificate. String type. - -1.10.12. $tls_[peer|my]_[subject|issuer]_organization - - $tls_[peer|my]_[subject|issuer]_organization - organizationName - in the issuer/subject section of the certificate. String type. - -1.10.13. $tls_[peer|my]_[subject|issuer]_unit - - $tls_[peer|my]_[subject|issuer]_unit - organizationalUnitName - in the issuer/subject section of the certificate. String type. - -1.10.14. $tls_[peer|my]_san_email - - $tls_[peer|my]_san_email - email address in the “subject - alternative name” extension. String type. - -1.10.15. $tls_[peer|my]_san_hostname - - $tls_[peer|my]_san_hostname - hostname (DNS) in the “subject - alternative name” extension. String type. - -1.10.16. $tls_[peer|my]_san_uri - - $tls_[peer|my]_san_uri - URI in the “subject alternative name” - extension. String type. - -1.10.17. $tls_[peer|my]_san_ip - - $tls_[peer|my]_san_ip - ip address in the “subject alternative - name” extension. String type. - -1.10.18. $tls_peer_verified - - $tls_peer_verified - Returns 1 if the peer's certificate was - successful verified. Otherwise it returns 0. String and Integer - type. - -1.10.19. $tls_peer_revoked - - $tls_peer_revoked - Returns 1 if the peer's certificate was - revoked. Otherwise it returns 0. String and Integer type. - -1.10.20. $tls_peer_expired - - $tls_peer_expired - Returns 1 if the peer's certificate is - expired. Otherwise it returns 0. String and Integer type. - -1.10.21. $tls_peer_selfsigned - - $tls_peer_selfsigned - Returns 1 if the peer's certificate is - selfsigned. Otherwise it returns 0. String and Integer type. - -1.10.22. $tls_peer_notBefore - - $tls_peer_notBefore - Returns the notBefore validity date of - the peer's certificate. String type. - -1.10.23. $tls_peer_notAfter - - $tls_peer_notAfter - Returns the notAfter validity date of the - peer's certificate. String type. - -1.11. OpenSIPS with TLS - script example - - IMPORTANT: The TLS support is based on TCP, and for allowing - OpenSIPS to use TCP, it must be started in multi-process mode. - So, there is a must to have the "fork" parameter set to "yes": - - NOTE: Since the TLS engine is quite memory consuming, increase - the used memory by the run time parameter "-m" (see OpenSIPS -h - for more details). - * fork = yes - - Example 1.39. Script with TLS support - # ----------- global configuration parameters ------------------------ - log_level=3 - stderror_enabled=no - syslog_enabled=yes - - check_via=no - dns=no - rev_dns=no - socket=udp:your_serv_IP:5060 - socket=tls:your_serv_IP:5061 - udp_workers=4 - - # ------------------ module loading ---------------------------------- - - loadmodule "proto_tls.so" - loadmodule "proto_udp.so" - - #TLS specific settings - loadmodule "tls_mgm.so" - - modparam("tls_mgm", "certificate", "/path/opensipsX_cert.pem") - modparam("tls_mgm", "private_key", "/path/privkey.pem") - modparam("tls_mgm", "ca_list", "/path/calist.pem") - modparam("tls_mgm", "ca_list", "/path/calist.pem") - modparam("tls_mgm", "require_cert", "1") - modparam("tls_mgm", "verify_cert", "1") - - alias=_DNS_ALIAS_ - - - loadmodule "sl.so" - loadmodule "rr.so" - loadmodule "maxfwd.so" - loadmodule "mysql.so" - loadmodule "usrloc.so" - loadmodule "registrar.so" - loadmodule "tm.so" - loadmodule "auth.so" - loadmodule "auth_db.so" - loadmodule "textops.so" - loadmodule "sipmsgops.so" - loadmodule "signaling.so" - loadmodule "uri_db.so" - - # ----------------- setting module-specific parameters --------------- - - # -- auth_db params -- - modparam("auth_db", "db_url", "sql_url") - modparam("auth_db", "password_column", "password") - modparam("auth_db", "calculate_ha1", 1) - - # -- registrar params -- - # no multiple registrations - modparam("registrar", "append_branches", 0) - - # ------------------------- request routing logic ------------------- - - # main routing logic - - route{ - - # initial sanity checks - if (!mf_process_maxfwd_header("10")) { - send_reply(483,"Too Many Hops"); - exit; - }; - - # if somene claims to belong to our domain in From, - # challenge him (skip REGISTERs -- we will chalenge them later) - if (is_myself("$fd")) { - setflag(1); - if ( is_method("INVITE|SUBSCRIBE|MESSAGE") - && !(is_myself("$si")) ) { - if (!(proxy_authorize( "domA.net", "subscriber" ))) { - proxy_challenge("domA.net","0"/*no-qop*/); - exit; - }; - if ($au!=$fU) { - xlog("FROM hdr Cheating attempt in INVITE\n"); - send_reply(403, - "That is ugly -- use From=id next time (OB)"); - exit; - }; - }; # non-REGISTER from other domain - } else if ( is_method("INVITE") && !is_myself("$rd") ) { - send_reply(403, "No relaying"); - exit; - }; - - /* ******** do record-route and loose-route ******* */ - if (!is_method("REGISTER")) - record_route(); - - if (loose_route()) { - append_hf("P-hint: rr-enforced\r\n"); - t_relay(); - exit; - }; - - /* ******* check for requests targeted out of our domain ******* */ - if ( !is_myself("$rd") ) { - append_hf("P-hint: OUTBOUND\r\n"); - if ($rd=="domB.net") { - t_relay("tls:domB.net:5061"); - } else if ($rd=="domC.net") { - t_relay("tls:domC.net:5061"); - } else { - t_relay(); - }; - exit; - }; - - /* ******* divert to other domain according to prefixes ******* */ - if (!is_method("REGISTER")) { - if ( $ru=~"sip:201") { - strip(3); - $rd = "domB.net"; - t_relay("tls:domB.net:5061"); - exit; - } else if ( $ru=~"sip:202" ) { - strip(3); - $rd = "domC.net"; - t_relay("tls:domC.net:5061"); - exit; - }; - }; - - /* ************ requests for our domain ********** */ - if (is_method("REGISTER")) { - if (!www_authorize( "domA.net", "subscriber" )) { - # challenge if none or invalid credentials - www_challenge( "domA.net" /* realm */, - "0" /* no qop -- some phones can't deal with it */); - exit; - }; - if ($au!=$tU) { - xlog("TO hdr Cheating attempt\n"); - send_reply(403, "That is ugly -- use To=id in REGISTERs"); - exit; - }; - # it is an authenticated request, update Contact database now - if (!save("location")) { - sl_reply_error(); - }; - exit; - }; - - # native SIP destinations are handled using USRLOC DB - if (!lookup("location")) { - # handle user which was not found - send_reply(404, "Not Found"); - exit; - }; - - # remove all present Alert-info headers - remove_hf("Alert-Info"); - - if (is_method("INVITE") && ($rP=="TLS" || isflagset(1))) { - append_hf("Alert-info: 1\r\n"); # cisco 7960 - append_hf("Alert-info: Bellcore-dr4\r\n"); # cisco ATA - append_hf("Alert-info: http://foo.bar/x.wav\r\n"); # snom - }; - - # do forwarding - if (!t_relay()) { - sl_reply_error(); - }; - - #end of script - } - -1.12. Debug TLS connections - - If you want to debug TLS connections, put the following log - statements into your OpenSIPS.cfg. This will dump all available - TLS pseudo variables. - - Example 1.40. Example of TLS logging -xlog("L_INFO","================= start TLS pseudo variables ============ -===\n"); -xlog("L_INFO","$$tls_version = '$tls_version'\n"); -xlog("L_INFO","$$tls_description = '$tls_description'\n"); -xlog("L_INFO","$$tls_cipher_info = '$tls_cipher_info'\n"); -xlog("L_INFO","$$tls_cipher_bits = '$tls_cipher_bits'\n"); -xlog("L_INFO","$$tls_peer_subject = '$tls_peer_subject'\n") -; -xlog("L_INFO","$$tls_peer_issuer = '$tls_peer_issuer'\n"); -xlog("L_INFO","$$tls_my_subject = '$tls_my_subject'\n"); -xlog("L_INFO","$$tls_my_issuer = '$tls_my_issuer'\n"); -xlog("L_INFO","$$tls_peer_version = '$tls_peer_version'\n") -; -xlog("L_INFO","$$tls_my_version = '$tls_my_version'\n"); -xlog("L_INFO","$$tls_peer_serial = '$tls_peer_serial'\n"); -xlog("L_INFO","$$tls_my_serial = '$tls_my_serial'\n"); -xlog("L_INFO","$$tls_peer_subject_cn = '$tls_peer_subject_cn'\ -n"); -xlog("L_INFO","$$tls_peer_issuer_cn = '$tls_peer_issuer_cn'\n -"); -xlog("L_INFO","$$tls_my_subject_cn = '$tls_my_subject_cn'\n" -); -xlog("L_INFO","$$tls_my_issuer_cn = '$tls_my_issuer_cn'\n") -; -xlog("L_INFO","$$tls_peer_subject_locality = '$tls_peer_subject_loca -lity'\n"); -xlog("L_INFO","$$tls_peer_issuer_locality = '$tls_peer_issuer_local -ity'\n"); -xlog("L_INFO","$$tls_my_subject_locality = '$tls_my_subject_locali -ty'\n"); -xlog("L_INFO","$$tls_my_issuer_locality = '$tls_my_issuer_localit -y'\n"); -xlog("L_INFO","$$tls_peer_subject_country = '$tls_peer_subject_coun -try'\n"); -xlog("L_INFO","$$tls_peer_issuer_country = '$tls_peer_issuer_count -ry'\n"); -xlog("L_INFO","$$tls_my_subject_country = '$tls_my_subject_countr -y'\n"); -xlog("L_INFO","$$tls_my_issuer_country = '$tls_my_issuer_country -'\n"); -xlog("L_INFO","$$tls_peer_subject_state = '$tls_peer_subject_stat -e'\n"); -xlog("L_INFO","$$tls_peer_issuer_state = '$tls_peer_issuer_state -'\n"); -xlog("L_INFO","$$tls_my_subject_state = '$tls_my_subject_state' -\n"); -xlog("L_INFO","$$tls_my_issuer_state = '$tls_my_issuer_state'\ -n"); -xlog("L_INFO","$$tls_peer_subject_organization = '$tls_peer_subject_orga -nization'\n"); -xlog("L_INFO","$$tls_peer_issuer_organization = '$tls_peer_issuer_organ -ization'\n"); -xlog("L_INFO","$$tls_my_subject_organization = '$tls_my_subject_organi -zation'\n"); -xlog("L_INFO","$$tls_my_issuer_organization = '$tls_my_issuer_organiz -ation'\n"); -xlog("L_INFO","$$tls_peer_subject_unit = '$tls_peer_subject_unit -'\n"); -xlog("L_INFO","$$tls_peer_issuer_unit = '$tls_peer_issuer_unit' -\n"); -xlog("L_INFO","$$tls_my_subject_unit = '$tls_my_subject_unit'\ -n"); -xlog("L_INFO","$$tls_my_issuer_unit = '$tls_my_issuer_unit'\n -"); -xlog("L_INFO","$$tls_peer_san_email = '$tls_peer_san_email'\n -"); -xlog("L_INFO","$$tls_my_san_email = '$tls_my_san_email'\n") -; -xlog("L_INFO","$$tls_peer_san_hostname = '$tls_peer_san_hostname -'\n"); -xlog("L_INFO","$$tls_my_san_hostname = '$tls_my_san_hostname'\ -n"); -xlog("L_INFO","$$tls_peer_san_uri = '$tls_peer_san_uri'\n") -; -xlog("L_INFO","$$tls_my_san_uri = '$tls_my_san_uri'\n"); -xlog("L_INFO","$$tls_peer_san_ip = '$tls_peer_san_ip'\n"); -xlog("L_INFO","$$tls_my_san_ip = '$tls_my_san_ip'\n"); -xlog("L_INFO","$$tls_peer_verified = '$tls_peer_verified'\n" -); -xlog("L_INFO","$$tls_peer_revoked = '$tls_peer_revoked'\n") -; -xlog("L_INFO","$$tls_peer_expired = '$tls_peer_expired'\n") -; -xlog("L_INFO","$$tls_peer_selfsigned = '$tls_peer_selfsigned'\ -n"); -xlog("L_INFO","$$tls_peer_notBefore = '$tls_peer_notBefore'\n -"); -xlog("L_INFO","$$tls_peer_notAfter = '$tls_peer_notAfter'\n" -); -xlog("L_INFO","================= end TLS pseudo variables ============== -=\n"); - -Chapter 2. Developer Guide - -2.1. API Functions - -2.1.1. find_server_domain - - struct tls_domain *find_server_domain(struct ip_addr *ip, - unsigned short port); - - Find a TLS server domain with given ip and port (local - listening socket). - -2.1.2. find_client_domain - - struct tls_domain *find_client_domain(struct ip_addr *ip, - unsigned short port); - - Find TLS client domain. - -2.1.3. get_handshake_timeout - - int get_handshake_timeout(void); - - Returns the handshanke timeout. - -2.1.4. get_send_timeout - - int get_send_timeout(void); - - Returns the send timeout. - -2.2. TLS_CONFIG - - It contains configuration variables for OpenSIPS's TLS - (timeouts, file paths, etc). - -2.3. TLS_INIT - - Initialization related functions and parameters. - -2.3.1. ssl context - - extern SSL_CTX *default_client_ctx; - - The ssl context is a member of the TLS domain strcuture. Thus, - every TLS domain, default and virtual - servers and clients, - have its own SSL context. - -2.3.2. pre_init_tls - - int init_tls(void); - - Called once to pre_initialize the tls subsystem, from the - main(). Called before parsing the configuration file. - -2.3.3. init_tls - - int init_tls(void); - - Called once to initialize the tls subsystem, from the main(). - Called after parsing the configuration file. - -2.3.4. destroy_tls - - void destroy_tls(void); - - Called once, just before cleanup. - -2.3.5. tls_init - - int tls_init(struct socket_info *c); - - Called once for each tls socket created, from main.c - -2.3.6. os_malloc, os_realloc, os_free - - Wrapper functions around the shm_* functions. OpenSSL uses - non-shared memory to create its objects, thus it would not work - in OpenSIPS. By creating these wrappers and configuring OpenSSL - to use them instead of its default memory functions, we have - all OpenSSL objects in shared memory, ready to use. - -2.4. TLS_DOMAIN - -2.4.1. tls_domains - - extern struct tls_domain *tls_default_server_domain; - - The default TLS server domain. - - extern struct tls_domain *tls_default_client_domain; - - The default TLS client domain. - - extern struct tls_domain *tls_server_domains; - - List with defined server domains. - - extern struct tls_domain *tls_client_domains; - - List with defined client domains. - -2.4.2. tls_find_server_domain - - struct tls_domain *tls_find_server_domain(struct ip_addr *ip, - unsigned short port); - - Find a TLS server domain with given ip and port (local - listening socket). - -2.4.3. tls_find_client_domain - - struct tls_domain *tls_find_client_domain(struct ip_addr *ip, - unsigned short port); - - Find TLS client domain. - -2.4.4. tls_find_client_domain_addr - - struct tls_domain *tls_find_client_domain_addr(struct ip_addr - *ip, unsigned short port); - - Find TLS client domain with given ip and port (socket of the - remote destination). - -2.4.5. tls_find_client_domain_name - - struct tls_domain *tls_find_client_name(str name); - - Find TLS client domain with given name. - -2.4.6. tls_new__domain - - struct tls_domain *tls_new_domain(int type); - - Creates new TLS: allocate memory, set the type and initialize - members - -2.4.7. tls_new_server_domain - - int tls_new_server_domain(struct ip_addr *ip, unsigned short - port); - - Creates and adds to the list of TLS server domains a new - domain. - -2.4.8. tls_new_client_domain - - int tls_new_client_domain(struct ip_addr *ip, unsigned short - port); - - Creates and adds to the list of TLS client domains a new socket - based domain. - -2.4.9. tls_new_client_domain_name - - int tls_new_client_domain_name(char *s, int len); - - Creates and adds to the list of TLS client domains a new name - based domain. - -2.4.10. tls_free_domains - - void tls_free_domains(void); - - Cleans up the entire domain lists. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 180 58 4821 4882 - 2. Razvan Crainea (@razvancrainea) 81 57 1415 724 - 3. Eseanu Marius Cristian (@eseanucristian) 53 11 4268 321 - 4. Liviu Chircu (@liviuchircu) 26 20 175 236 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 24 13 291 460 - 6. Dan Pascu (@danpascu) 17 13 90 176 - 7. Ionut Ionita (@ionutrazvanionita) 16 9 383 169 - 8. Ionel Cerghit (@ionel-cerghit) 8 1 494 109 - 9. Maksym Sobolyev (@sobomax) 7 4 61 75 - 10. Alexey Vasilyev (@vasilevalex) 4 2 33 19 - - All remaining contributors: Callum Guy (@spacetourist), Aleksei - Vasilev, jupiter, Fabian Gast (@fgast), Nick Altmann - (@nikbyte), Ovidiu Sas (@ovidiusas), Peter Lemenkov - (@lemenkov), Jupiter Tang. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Jupiter Tang Nov 2025 - Nov 2025 - 2. jupiter Apr 2025 - Apr 2025 - 3. Maksym Sobolyev (@sobomax) Mar 2016 - Nov 2023 - 4. Liviu Chircu (@liviuchircu) Oct 2015 - May 2023 - 5. Vlad Patrascu (@rvlad-patrascu) Apr 2017 - May 2023 - 6. Razvan Crainea (@razvancrainea) Sep 2015 - Apr 2022 - 7. Nick Altmann (@nikbyte) May 2021 - May 2021 - 8. Aleksei Vasilev Apr 2021 - Apr 2021 - 9. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2016 - Apr 2020 - 10. Dan Pascu (@danpascu) Jun 2019 - Feb 2020 - - All remaining contributors: Fabian Gast (@fgast), Alexey - Vasilyev (@vasilevalex), Callum Guy (@spacetourist), Peter - Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Ionut Ionita - (@ionutrazvanionita), Ionel Cerghit (@ionel-cerghit), Eseanu - Marius Cristian (@eseanucristian). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu - (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Dan Pascu (@danpascu), Callum Guy - (@spacetourist), Peter Lemenkov (@lemenkov), Eseanu Marius - Cristian (@eseanucristian). - - Documentation Copyrights: - - Copyright © 2015 www.opensips-solutions.com - - Copyright © 2013 Secusmart GmbH - - Copyright © 2006 enum.at - - Copyright © 2005 Cesc Santasusana - - Copyright © 2005 Voice Sistem SRL diff --git a/modules/tls_mgm/README.md b/modules/tls_mgm/README.md new file mode 100644 index 00000000000..3804b2764f5 --- /dev/null +++ b/modules/tls_mgm/README.md @@ -0,0 +1,1692 @@ +--- +title: "TLS_MGM module" +description: "This module is a management module for TLS certificates and parameters." +--- + +## Admin Guide + + +### Overview + + +This module is a management module for TLS certificates and +parameters. It provides an interface for all the modules that +use the TLS protocol. It also exports pseudo variables with +certificate and TLS parameters. + + +### Usage + + +This module is used to provision TLS certificates and parameters +for all the modules that use TLS transport (like +*proto_tls* or *proto_wss*). +The module supports multiple +virtual domains that can be assigned to different listeners +(servers) or new connections (clients). Each TLS module that uses +this management module should assign itself to one or more domains. + + +The module allows the definition of the TLS domains both via +module parameters (script level) and via an SQL table. + + +A script example which details this module's usage can be found in +[tls example](#opensips_with_tls_script_example). + + +### TLS libraries + + +Besides TLS certificates and parameters, this module also acts as +an inteface between the actual TLS implemenation (provided by +*openSSL* or *wolfSSL* libraries) +and transport protocol modules like *proto_tls* or +*proto_wss*. The *tls_mgm* module +transparently exposes the TLS operations implemented by +*tls_openssl* and *tls_wolfssl* modules +to the higher-level OpenSIPS transport modules. + + +The TLS library selection ca be configured through the +[tls library](#param_tls_library) module parameter. + + +### TLS domains + + +The wording 'TLS domain' means that this TLS connection will have different +parameters than another TLS connection (from another TLS domain). Thus, TLS +domains are not directly related to different SIP domains, although they +are often used in conjunction. Depending on the direction of the TLS handshake, a +TLS domain is called 'client domain' (=outgoing TLS connection) or 'server domain' +(= incoming TLS connection). + + +If you run several SIP domains you can specify some parameters for each of them +separately (regardless if you have only one or multiple socket=tls:ip:port entries +in the config file). + + +For example, TLS domains can be used in virtual hosting scenarios with TLS. +OpenSIPS offers SIP service for multiple domains, e.g. atlanta.com and biloxi.com. Altough +both domains will be hosted on a single SIP proxy, the SIP proxy needs 2 certificates: One +for atlanta.com and one for biloxi.com. For incoming TLS connections, the SIP proxy +has to present the respective certificate during the TLS handshake. As the SIP proxy +does not have a received SIP message yet (this is done after the TLS handshake), the SIP +proxy can not retrieve the target domain from SIP (which would have been usually retrieved +from the domain in the request URI). Thus, distinction for these domains must be done by using multiple listening sockets or by having clients that send the Servername TLS extension(SNI) in the +handshake process. + + +For outgoing TLS connections, the TLS domain is chosen based on the destination socket of the underlying outgoing TCP connection and/or by taking a decision at script level via an AVP. For example, you can inspect headers like RURI or From and match the domain in the SIP header with filters that you have set up for the TLS domains. + + +> [!NOTE] +> Except tls_handshake_timeout and tls_send_timeout all TLS parameters can be set per TLS domain. + + +### Defining TLS domains + + +TLS domains can be defined in two ways: + + +- by setting the *server_domain* or *client_domain* module parameters +- by provisioning in DB + + +For the domains defined in the DB, the certificate, private key, list of trusted CAs and Diffie-Hellman parameters are provisioned as BLOB values while for script defined domains you must provide path to files. + + +You can define domains both in the DB and script at the same time. + + +For any TLS domain (defined through script or DB) if not specified otherwise, the default settings are: + + +- method - *SSLv23* +- verify_cert - *1* +- require_cert - *1* +- certificate - *CFG_DIR/tls/cert.pem* +- private_key - *CFG_DIR/tls/ckey.pem* +- crl_check_all - *0* +- crl_dir - none +- ca_list - none +- ca_dir - */etc/pki/CA/* +- cipher_list - the OpenSSL default ciphers +- dh_params - none +- ec_curve - none + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *tls_openssl* or *tls_wolfssl*, +unless [tls library](#param_tls_library) is set to 'none'. + + +#### Dependencies of external libraries + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Functions + + +#### is_peer_verified + + +Returns 1 if the message is received via TLS and the peer was verified +during TLS connection handshake, otherwise it returns -1 + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="is_peer_verified usage" +... +if (is_peer_verified()) { + xlog("L_INFO","request from verified TLS peer\n"); +} else { + xlog("L_INFO","request not verified\n"); +} +... +``` + + +### Exported MI Functions + + +#### tls_list + + +List all domains information. + + +#### tls_reload + + +Reloads the TLS domains information from the database. +The previous DB defined domains are discarded but the +script defined domains are preserved. + + +### Exported Parameters + + +All these parameters can be used from the opensips.cfg file, +to configure the behavior of OpenSIPS-TLS. + + +#### listen=interface + + +Not specific to TLS. Allows to specify the protocol +(udp, tcp, tls), the IP address and the port where the +listening server will be. + + +```opensips title="Set listen variable" +... +socket= tls:1.2.3.4:5061 +... + +``` + + +#### tls_library (string) + + +Selects which TLS library to use. Possible values are: + + +- *auto* - auto-detect which TLS library +module (*tls_openssl* or *tls_wolfssl*) +was loaded. OpenSIPS will not start if no module, or both modules are +found. +- *none* - do not use any TLS library; this +is useful when the *tls_mgm* module is required only +for the management of TLS certificates and parameters by modules like +*db_mysql*, *rabbitmq* etc. ( +and not for TLS operations by transport modules like +*proto_tls* etc.) +- *openssl* - use the *openSSL* +library through the *tls_openssl* module. +- *wolfssl* - use the *wolfSSL* +library through the *tls_wolfssl* module. + + +Default value is *auto*. + + +```opensips title="Set tls_library variable" +... +modparam("tls_mgm", "tls_library", "none") +... + +``` + + +#### tls_method ([domain]string) + + +Sets the TLS protocol. The domain part represents the name of +the TLS domain. The supported TLS methods are: + + +- *TLSv1_3* - means OpenSIPS will +accept only TLSv1.3 connections. This version is only +available starting with OpenSSL 1.1.1 version. +- *TLSv1_2* - means OpenSIPS will +accept only TLSv1.2 connections (rfc3261 conformant). +- *TLSv1* - means OpenSIPS will +accept only TLSv1 connections (rfc3261 conformant). +- *SSLv23* - means OpenSIPS will +accept any of the above methods, but the initial SSL +hello must be v2 (in the initial hello all the supported +protocols are advertised enabling switching to a higher +and more secure version). The initial v2 hello means it +will not accept connections from SSLv3 or TLSv1 only +clients. + + +*If you are using an OpenSSL library newer than 1.1.0, you can +also specify a range of accepted TLS versions as [VLOW]-[VHIGH]. +If VLOW is not specified it will use the minimum supported +protocol version and if VHIGH is not specified it will use +the maximum supported protocol version. This means that using +a range where both the low and high values are missing, will +accept all the supported methods, but unlike SSLv23 will not +require the initial hello to be SSLv2.* + + +*Default value is SSLv23.* + + +> [!WARNING] +> For extended compatibility with older system, best use SSLv23. + + +If you want RFC3261 conformance and all your clients support +TLSv1 (or you are planning to use encrypted "tunnels" only +between different OpenSIPS proxies) use TLSv1. If you want to +support older clients use SSLv23 (in fact most of the +applications with SSL support use the SSLv23 method). + + +```opensips title="Set tls_method variable" +... +modparam("tls_mgm", "tls_method", "[dom]TLSv1") +... + +``` + + +```opensips title="Set tls_method range variable" +... +modparam("tls_mgm", "tls_method", "[dom]TLSv1-TLSv1_3") # between v1 and v1.3 +modparam("tls_mgm", "tls_method", "[dom]TLSv1-") # v1 or higher +modparam("tls_mgm", "tls_method", "[dom]-TLSv1_2") # up to v1.2 +modparam("tls_mgm", "tls_method", "[dom]-") # all supported +... + +``` + + +#### certificate ([domain](string) + + +Public certificate file for OpenSIPS. It will be used as +server-side certificate for incoming TLS connections, and as +a client-side certificate for outgoing TLS connections. The domain +part represents the name of the TLS domain. + + +*Default value is "CFG_DIR/tls/cert.pem".* + + +```opensips title="Set certificate variable" +... +modparam("tls_mgm", "certificate", "[dom]/mycerts/certs/opensips_server_cert.pem") +... + +``` + + +#### private_key ([domain](string) + + +Private key of the above certificate. I must be kept in a +safe place with tight permissions! The domain part +represents the name of the TLS omain. + + +*Default value is "CFG_DIR/tls/ckey.pem".* + + +```opensips title="Set private_key variable" +... +modparam("tls_mgm", "private_key", "[dom]/mycerts/private/prik.pem") +... + +``` + + +#### ca_list ([domain](string) + + +List of trusted CAs. The file contains the certificates +accepted, one after the other. It MUST be a file, not +a folder. The domain part represents the name +of the TLS domain. + + +*Default value is "".* + + +```opensips title="Set ca_list variable" +... +modparam("tls_mgm", "ca_list", "[dom]/mycerts/certs/ca_list.pem") +... + +``` + + +#### ca_dir ([domain](string) + + +Directory storing trusted CAs. The certificates in the directory +must be in hashed form, as described in the +[openssl documentation](https://www.openssl.org/docs/manmaster/man3/X509_LOOKUP_hash_dir.html) for the +*Hashed Directory Method*. The domain part +represents the name of the TLS domain. + + +*Default value is "/etc/pki/CA/".* + + +```opensips title="Set ca_dir variable" +... +modparam("tls_mgm", "ca_dir", "[dom]/mycerts/certs") +... + +``` + + +#### crl_dir ([domain](string) + + +Directory storing certificate revocation lists (CRLs). The domain +part represents the name of the TLS domain. + + +*If this parameter is not set, no CRLs will be used.* + + +```opensips title="Set crl_dir variable" +... +modparam("tls_mgm", "crl_dir", "[dom]/mycerts/crls") +... + +``` + + +#### crl_check_all ([domain](string) + + +Setting this parameter with a non-zero integer value enables CRL +checking for the entire certificate chain. + + +*By default, only the leaf certificate in the certificate chain +is checked.* + + +```opensips title="Set crl_check_all variable" +... +modparam("tls_mgm", "crl_check_all", "[dom]1") +... + +``` + + +#### ciphers_list ([domain](string) + + +You can specify the list of algorithms for authentication +and encryption that you allow. The domain part +represents the name of the TLS domain. To obtain a list of ciphers +and then choose, use the openssl application: + + +- openssl ciphers 'ALL:eNULL:!LOW:!EXPORT' + + +> [!WARNING] +> Do not use the NULL algorithms (no encryption) ... only for testing!!! + + +*It defaults to the OpenSSL default ciphers.* + + +```opensips title="Set ciphers_list variable" +... +modparam("tls_mgm", "ciphers_list", "[dom]NULL") +... + +``` + + +#### dh_params ([domain](string) + + +You can specify a file which contains Diffie-Hellman +parameters as a PEM-file. This is needed if you would like +to specify ciphers including Diffie-Hellman mode. The +domain part represents the name of the TLS domain. + + +*It defaults to not set a dh param file.* + + +```opensips title="Set dh_params variable" +... +modparam("tls_mgm", "dh_params", "[dom]/etc/pki/CA/dh1024.pem") +... +``` + + +#### ec_curve ([domain](string) + + +You can specify an elliptic curve which should be used for +ciphers which demand an elliptic curve. The domain part +represents the name of the TLS domain. + + +It's usable only if TLS v1.1/1.2 support was compiled. +A list of curves which can be used you can get by + + +```bash +openssl ecparam -list_curves +``` + + +*It defaults to not set a elliptic curve.* + + +#### verify_cert ([domain](string) + + +Activates SSL_VERIFY_PEER in the ssl_context. For a detailed +explanation, check the *openssl* documentation. + + +The domain part represents the name of the TLS domain. + + +Default value is *1*. + + +```opensips title="Set verify_cert variable" +... +modparam("tls_mgm", "verify_cert", "[dom]0") +... +``` + + +#### require_cert ([domain](string) + + +Activates SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the ssl_context. For a +detailed explanation, check the *openssl* +documentation. This parameter only makes sense for server domains +and if the [verify cert](#param_verify_cert) parameter is also set. + + +The domain part represents the name of the TLS domain. + + +Default value is *1*. + + +```opensips title="Set require_cert variable" +... +modparam("tls_mgm", "require_cert", "[dom]0") +... +``` + + +#### client_tls_domain_avp (string) + + +Name of the AVP used for enforcing the selection of a specific TLS +client domain. Setting this AVP to the name of a TLS client domain will +result in using that specific domain regardless of the standard matching +mechanism. + + +> [!NOTE] +> If there is already an existing TLS connection to the remote target, +> it will be reused and setting this AVP has no effect. + + +> [!NOTE] +> You can force a particular domain to be used just for a particular +> branch by setting the *$bavp* variable with the same +> name. When both *$bavp* and *$avp* +> variables are set, the first one takes precedence. + + +*No default value.* + + +```opensips title="Set client_tls_domain_avp variable" +... +modparam("tls_mgm", "client_tls_domain_avp", "tls_match_dom") +... +``` + + +#### client_sip_domain_avp (string) + + +Name of the AVP that sets the SIP domain used in the TLS client +domain matching process. + + +> [!NOTE] +> If there is already an existing TLS connection to the remote target, +> it will be reused and setting this AVP has no effect. + + +> [!NOTE] +> You can force a particular SIP domain to be used just for a particular +> branch by setting the *$bavp* variable with the same +> name. When both *$bavp* and *$avp* +> variables are set, the first one takes precedence. + + +For the AVP usage example, refer to [domains param](#param_server_domain_client_domain). + + +*No default value.* + + +```opensips title="Set client_sip_domain_avp variable" +... +modparam("tls_mgm", "client_sip_domain_avp", "sip_match_dom") +... +``` + + +#### db_url (string) + + +The database url. It cannot be NULL. + + +You cannot use the "tls_domain=*dom_name*" URL parameter +for a TLS connection to the database for the tls_mgm module itself. + + +```opensips title="Usage of db_url block" +modparam("tls_mgm", "db_url", "mysql://root:admin@localhost/opensips") +``` + + +#### db_table (string) + + +Sets the database table name. + + +Default value is "tls_mgm". + + +```opensips title="Usage of db_table block" +modparam("tls_mgm", "db_table", "tls_mgm") +``` + + +#### domain_col (string) + + +Sets the name for the TLS domain column. + + +Default value is "domain". + + +```opensips title="Usage of domain_col block" +modparam("tls_mgm", "domain_col", "tls_domain") +``` + + +#### match_ip_address_col (string) + + +Sets the IP address matching column name. + + +Default value is "match_ip_address". + + +```opensips title="Usage of match_ip_address_col block" +modparam("tls_mgm", "match_ip_address_col", "addr") +``` + + +#### match_sip_domain_col (string) + + +Sets the SIP domain matching column name. + + +Default value is "match_sip_domain". + + +```opensips title="Usage of match_sip_domain_col block" +modparam("tls_mgm", "match_sip_domain_col", "addr") +``` + + +#### tls_method_col (string) + + +Sets the method column name. + + +Default value is "method". + + +```opensips title="Usage of tls_method_col block" +modparam("tls_mgm", "tls_method_col", "method") +``` + + +#### verify_cert_col (string) + + +Sets the verrify certificate column name. + + +Default value is "verify_cert". + + +```opensips title="Usage of vertify_cert_col block" +modparam("tls_mgm", "verify_cert_col", "verify_cert") +``` + + +#### require_cert_col (string) + + +Sets the require certificate column name. + + +Default value is "require_cert". + + +```opensips title="Usage of require_cert_col block" +modparam("tls_mgm", "require_cert_col", "req") +``` + + +#### certificate_col (string) + + +Sets the certificate column name. + + +Default value is "certificate". + + +```opensips title="Usage of certificate_col block" +modparam("tls_mgm", "certificate_col", "certificate") +``` + + +#### private_key_col (string) + + +Sets the private key column name. + + +Default value is "private_key". + + +```opensips title="Usage of private_key_col block" +modparam("tls_mgm", "private_key_col", "pk") +``` + + +#### crl_check_all_col (string) + + +Sets the crl_check_all column name. + + +Default value is "crl_check_all". + + +```opensips title="Usage of crl_check_all block" +modparam("tls_mgm", "crl_check_all_col", "crl_check") +``` + + +#### crl_dir_col (string) + + +Sets the crl directory column name. + + +Default value is "crl_dir". + + +```opensips title="Usage of crl_dir_col block" +modparam("tls_mgm", "crl_dir_col", "crl_dir") +``` + + +#### ca_list_col (string) + + +Sets the CA list column name. + + +Default value is "ca_list". + + +```opensips title="Usage of ca_list_col block" +modparam("tls_mgm", "ca_list_col", "ca_list") +``` + + +#### ca_dir_col (string) + + +Sets the CA directory column name. + + +Default value is "ca_dir". + + +```opensips title="Usage of ca_dir_col block" +modparam("tls_mgm", "ca_dir_col", "ca_dir") +``` + + +#### cipher_list_col (string) + + +Sets the cipher list column name. + + +Default value is "cipher_list". + + +```opensips title="Usage of cipher_list_col block" +modparam("tls_mgm", "cipher_list_col", "cipher_list") +``` + + +#### dh_params_col (string) + + +Sets the Diffie-Hellmann parameters column name. + + +Default value is "dh_params". + + +```opensips title="Usage of dh_params_col block" +modparam("tls_mgm", "dh_params_col", "dh_parms") +``` + + +#### ec_curve_col (string) + + +Sets the ec_curve column name. + + +Default value is "ec_curve". + + +```opensips title="Usage of ec_curve_col block" +modparam("tls_mgm", "ec_curve_col", "ec_curve") +``` + + +#### match_ip_address (string) + + +The IP addresses and ports used to match a TLS connection with a +virtual TLS domain. For TLS server domains, these values will be +mathced against the socket on which the connection is received. For +TLS client domains, the values will be compared with the destination +socket of the connection. + + +The parameter accepts a list of values, and the special value "*" +means: match any address. + + +*Default value is "*" (match any address).* + + +```opensips title="Set match_ip_address variable" +... +modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061, 10.0.0.11:5061") +... +``` + + +#### match_sip_domain (string) + + +The SIP domains used to match a TLS connection with a +virtual TLS domain. For TLS server domains, these values will be +matched against the hostname provided in the TLS Servername extension(SNI). +For TLS client domains, the values will be compared with the value of +the [client sip domain avp](#param_client_sip_domain_avp) AVP. + + +The parameter accepts a list of FQDNs or the special values: + + +- \* - match any sip domain( +including no SNI provided, in case of TLS server domains); +- *none* - match the TLS domain +when there is no SNI provided (make sense only for TLS server +domains). Note that if a SNI is provided, but does not match any +other SIP domain filter, the connection will be rejected. + + +The FQDNs can be specified as with Unix shell-style wildcards. If +there are multiple potential matches, the most specific domain will +be selected(eg. a request for "foo.bar.com" is matched with the domain +specified with "foo.bar.com" versus the one with "*.bar.com"). + + +*Default value is "\*" (match any sip domain).* + + +```opensips title="Set match_sip_domain variable" +... +modparam("tls_mgm", "match_sip_domain", "[dom1]foo.com, bar.com, *.baz.com") +modparam("tls_mgm", "match_sip_domain", "[default_dom]*") +... + +``` + + +#### server_domain, client_domain (string) + + +You can define virtual TLS domains through these parameters. + + +The value of these parameters represents the virtual tls domain's +name which is only used for identification. + + +```opensips title="Usage of tls_client_domain and tls_server_domain block" +... +socket=tls:10.0.0.10:5061 +... +# set the TLS client domain AVP +modparam("tls_mgm", "client_sip_domain_avp", "tls_sip_dom") +... + +# 'atlanta' server domain +modparam("tls_mgm", "server_domain", "dom1") +modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061") +modparam("tls_mgm", "match_sip_domain", "[dom1]atlanta.com") + +modparam("tls_mgm", "certificate", "[dom1]/certs/atlanta.com/cert.pem") +modparam("tls_mgm", "private_key", "[dom1]/certs/atlanta.com/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom1]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom1]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom1]1") +modparam("tls_mgm", "require_cert", "[dom1]1") + +#'biloxi' server domain +modparam("tls_mgm", "server_domain", "dom2") +modparam("tls_mgm", "match_ip_address", "[dom2]10.0.0.10:5061") +modparam("tls_mgm", "match_sip_domain", "[dom2]biloxi.com") + +modparam("tls_mgm", "certificate", "[dom2]/certs/biloxi.com/cert.pem") +modparam("tls_mgm", "private_key", "[dom2]/certs/biloxi.com/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom2]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom2]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom2]1") +modparam("tls_mgm", "require_cert", "[dom2]1") + +# generic TLS server domain, if the client does not provide SNI +modparam("tls_mgm", "server_domain", "dom3") +modparam("tls_mgm", "match_ip_address", "[dom3]10.0.0.10:5061") +modparam("tls_mgm", "match_sip_domain", "[dom3]none") + +modparam("tls_mgm", "certificate", "[dom3]/certs/generic/cert.pem") +modparam("tls_mgm", "private_key", "[dom3]/certs/generic/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom3]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom3]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom3]1") +modparam("tls_mgm", "require_cert", "[dom3]1") + +# 'atlanta' client domain +modparam("tls_mgm", "client_domain", "dom4") +modparam("tls_mgm", "match_ip_address", "[dom4]*") +modparam("tls_mgm", "match_sip_domain", "[dom4]atlanta.com") + + +modparam("tls_mgm", "certificate", "[dom4]/certs/atlanta.com/cert.pem") +modparam("tls_mgm", "private_key", "[dom4]/certs/atlanta.com/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom4]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom4]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom4]1") +modparam("tls_mgm", "require_cert", "[dom4]1") + +# 'biloxi' client domain +modparam("tls_mgm", "client_domain", "dom5") +modparam("tls_mgm", "match_ip_address", "[dom5]*") +modparam("tls_mgm", "match_sip_domain", "[dom5]biloxi.com") + +modparam("tls_mgm", "certificate", "[dom5]/certs/biloxi.com/cert.pem") +modparam("tls_mgm", "private_key", "[dom5]/certs/biloxi.com/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom5]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom5]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom5]1") +modparam("tls_mgm", "require_cert", "[dom5]1") + +# TLS client domain for GW provider +modparam("tls_mgm", "client_domain", "dom6") +modparam("tls_mgm", "match_ip_address", "[dom6]1.2.3.4:6677") +modparam("tls_mgm", "match_sip_domain", "[dom6]*") + +modparam("tls_mgm", "certificate", "[dom6]/certs/gw/cert.pem") +modparam("tls_mgm", "private_key", "[dom6]/certs/gw/privkey.pem") +modparam("tls_mgm", "ca_list", "[dom6]/certs/wellknownCAs") +modparam("tls_mgm", "tls_method", "[dom6]tlsv1") +modparam("tls_mgm", "verify_cert", "[dom6]0") + +... +route{ +... + # we match the TLS client domain using the SIP domain in the RURI + $avp(tls_sip_dom) = $rd; + t_relay(); + exit; +... + # calls to the PSTN GW, will match the correct TLS domain by IP + t_relay("tls:1.2.3.4:6677"); + exit; +... + +``` + + +### Variables + + +This module exports the follong variables: + + +Some variables are available for both, the peer'S certificate and +the local certificate. Further, some parameters can be read from the +"Subject" field or the "Issuer" field. + + +#### $tls_version + + +*$tls_version* - the TLS/SSL version which is +used on the TLS connection from which the message was received. +String type. + + +#### $tls_description + + +*$tls_description* - the TLS/SSL description +of the TLS connection from which the message was received. String +type. + + +#### $tls_cipher_info + + +*$tls_cipher_info* - the TLS/SSL cipher which +is used on the TLS connection from which the message was received. +String type. + + +#### $tls_cipher_bits + + +*$tls_cipher_bits* - the number of cipher bits +which are used on the TLS connection from which the message was +received. String and Integer type. + + +#### $tls_[peer|my]_version + + +*$tls_[peer|my]_version* - the version of the +certificate. String type. + + +#### $tls_[peer|my]_serial + + +*$tls_[peer|my]_serial* - the serial number +of the certificate. String and Integer type. + + +#### $tls_[peer|my]_[subject|issuer] + + +*$tls_[peer|my]_[subject|issuer]* - ASCII dump +of the fields in the issuer/subject section of the certificate. +String type. + + +```c title="Example of $tls_[peer|my]_[subject|issuer]" +/C=AT/ST=Vienna/L=Vienna/O=enum.at/CN=enum.at +``` + + +#### $tls_[peer|my]_[subject|issuer]_cn + + +*$tls_[peer|my]_[subject|issuer]_cn* - +commonName in the issuer/subject section of the certificate. +String type. + + +#### $tls_[peer|my]_[subject|issuer]_locality + + +*$tls_[peer|my]_[subject|issuer]_locality* - +localityName in the issuer/subject section of the certificate. +String type. + + +#### $tls_[peer|my]_[subject|issuer]_country + + +*$tls_[peer|my]_[subject|issuer]_country* - +countryName in the issuer/subject section of the certificate. +String type. + + +#### $tls_[peer|my]_[subject|issuer]_state + + +*$tls_[peer|my]_[subject|issuer]_state* - +stateOrProvinceName in the issuer/subject section of the +certificate. String type. + + +#### $tls_[peer|my]_[subject|issuer]_organization + + +*$tls_[peer|my]_[subject|issuer]_organization* - +organizationName in the issuer/subject section of the certificate. +String type. + + +#### $tls_[peer|my]_[subject|issuer]_unit + + +*$tls_[peer|my]_[subject|issuer]_unit* - +organizationalUnitName in the issuer/subject section of the +certificate. String type. + + +#### $tls_[peer|my]_san_email + + +*$tls_[peer|my]_san_email* - email address in +the "subject alternative name" extension. String type. + + +#### $tls_[peer|my]_san_hostname + + +*$tls_[peer|my]_san_hostname* - hostname (DNS) +in the "subject alternative name" extension. String +type. + + +#### $tls_[peer|my]_san_uri + + +*$tls_[peer|my]_san_uri* - URI in the +"subject alternative name" extension. +String type. + + +#### $tls_[peer|my]_san_ip + + +*$tls_[peer|my]_san_ip* - ip address in the +"subject alternative name" extension. +String type. + + +#### $tls_peer_verified + + +*$tls_peer_verified* - Returns 1 if the peer's +certificate was successful verified. Otherwise it returns 0. +String and Integer type. + + +#### $tls_peer_revoked + + +*$tls_peer_revoked* - Returns 1 if the peer's +certificate was revoked. Otherwise it returns 0. +String and Integer type. + + +#### $tls_peer_expired + + +*$tls_peer_expired* - Returns 1 if the peer's +certificate is expired. Otherwise it returns 0. +String and Integer type. + + +#### $tls_peer_selfsigned + + +*$tls_peer_selfsigned* - Returns 1 if the +peer's certificate is selfsigned. Otherwise it returns 0. +String and Integer type. + + +#### $tls_peer_notBefore + + +*$tls_peer_notBefore* - Returns the notBefore +validity date of the peer's certificate. +String type. + + +#### $tls_peer_notAfter + + +*$tls_peer_notAfter* - Returns the notAfter +validity date of the peer's certificate. +String type. + + +### OpenSIPS with TLS - script example + + +> [!IMPORTANT] +> The TLS support is based on TCP, and for allowing OpenSIPS +> to use TCP, it must be started in multi-process mode. So, there is +> a must to have the "fork" parameter set to "yes": + + +> [!NOTE] +> Since the TLS engine is quite memory consuming, increase the +> used memory by the run time parameter "-m" (see OpenSIPS -h for more +> details). + + +- fork = yes + + +```opensips title="Script with TLS support" + # ----------- global configuration parameters ------------------------ + log_level=3 + stderror_enabled=no + syslog_enabled=yes + + check_via=no + dns=no + rev_dns=no + socket=udp:your_serv_IP:5060 + socket=tls:your_serv_IP:5061 + udp_workers=4 + + # ------------------ module loading ---------------------------------- + + loadmodule "proto_tls.so" + loadmodule "proto_udp.so" + + #TLS specific settings + loadmodule "tls_mgm.so" + + modparam("tls_mgm", "certificate", "/path/opensipsX_cert.pem") + modparam("tls_mgm", "private_key", "/path/privkey.pem") + modparam("tls_mgm", "ca_list", "/path/calist.pem") + modparam("tls_mgm", "ca_list", "/path/calist.pem") + modparam("tls_mgm", "require_cert", "1") + modparam("tls_mgm", "verify_cert", "1") + + alias=_DNS_ALIAS_ + + + loadmodule "sl.so" + loadmodule "rr.so" + loadmodule "maxfwd.so" + loadmodule "mysql.so" + loadmodule "usrloc.so" + loadmodule "registrar.so" + loadmodule "tm.so" + loadmodule "auth.so" + loadmodule "auth_db.so" + loadmodule "textops.so" + loadmodule "sipmsgops.so" + loadmodule "signaling.so" + loadmodule "uri_db.so" + + # ----------------- setting module-specific parameters --------------- + + # -- auth_db params -- + modparam("auth_db", "db_url", "sql_url") + modparam("auth_db", "password_column", "password") + modparam("auth_db", "calculate_ha1", 1) + + # -- registrar params -- + # no multiple registrations + modparam("registrar", "append_branches", 0) + + # ------------------------- request routing logic ------------------- + + # main routing logic + + route{ + + # initial sanity checks + if (!mf_process_maxfwd_header("10")) { + send_reply(483,"Too Many Hops"); + exit; + }; + + # if somene claims to belong to our domain in From, + # challenge him (skip REGISTERs -- we will chalenge them later) + if (is_myself("$fd")) { + setflag(1); + if ( is_method("INVITE|SUBSCRIBE|MESSAGE") + && !(is_myself("$si")) ) { + if (!(proxy_authorize( "domA.net", "subscriber" ))) { + proxy_challenge("domA.net","0"/*no-qop*/); + exit; + }; + if ($au!=$fU) { + xlog("FROM hdr Cheating attempt in INVITE\n"); + send_reply(403, + "That is ugly -- use From=id next time (OB)"); + exit; + }; + }; # non-REGISTER from other domain + } else if ( is_method("INVITE") && !is_myself("$rd") ) { + send_reply(403, "No relaying"); + exit; + }; + + /* ******** do record-route and loose-route ******* */ + if (!is_method("REGISTER")) + record_route(); + + if (loose_route()) { + append_hf("P-hint: rr-enforced\r\n"); + t_relay(); + exit; + }; + + /* ******* check for requests targeted out of our domain ******* */ + if ( !is_myself("$rd") ) { + append_hf("P-hint: OUTBOUND\r\n"); + if ($rd=="domB.net") { + t_relay("tls:domB.net:5061"); + } else if ($rd=="domC.net") { + t_relay("tls:domC.net:5061"); + } else { + t_relay(); + }; + exit; + }; + + /* ******* divert to other domain according to prefixes ******* */ + if (!is_method("REGISTER")) { + if ( $ru=~"sip:201") { + strip(3); + $rd = "domB.net"; + t_relay("tls:domB.net:5061"); + exit; + } else if ( $ru=~"sip:202" ) { + strip(3); + $rd = "domC.net"; + t_relay("tls:domC.net:5061"); + exit; + }; + }; + + /* ************ requests for our domain ********** */ + if (is_method("REGISTER")) { + if (!www_authorize( "domA.net", "subscriber" )) { + # challenge if none or invalid credentials + www_challenge( "domA.net" /* realm */, + "0" /* no qop -- some phones can't deal with it */); + exit; + }; + if ($au!=$tU) { + xlog("TO hdr Cheating attempt\n"); + send_reply(403, "That is ugly -- use To=id in REGISTERs"); + exit; + }; + # it is an authenticated request, update Contact database now + if (!save("location")) { + sl_reply_error(); + }; + exit; + }; + + # native SIP destinations are handled using USRLOC DB + if (!lookup("location")) { + # handle user which was not found + send_reply(404, "Not Found"); + exit; + }; + + # remove all present Alert-info headers + remove_hf("Alert-Info"); + + if (is_method("INVITE") && ($rP=="TLS" || isflagset(1))) { + append_hf("Alert-info: 1\r\n"); # cisco 7960 + append_hf("Alert-info: Bellcore-dr4\r\n"); # cisco ATA + append_hf("Alert-info: http://foo.bar/x.wav\r\n"); # snom + }; + + # do forwarding + if (!t_relay()) { + sl_reply_error(); + }; + + #end of script + } + +``` + + +### Debug TLS connections + + +If you want to debug TLS connections, put the following log +statements into your OpenSIPS.cfg. +This will dump all available TLS pseudo variables. + + +```opensips title="Example of TLS logging" +xlog("L_INFO","================= start TLS pseudo variables ===============\n"); +xlog("L_INFO","$$tls_version = '$tls_version'\n"); +xlog("L_INFO","$$tls_description = '$tls_description'\n"); +xlog("L_INFO","$$tls_cipher_info = '$tls_cipher_info'\n"); +xlog("L_INFO","$$tls_cipher_bits = '$tls_cipher_bits'\n"); +xlog("L_INFO","$$tls_peer_subject = '$tls_peer_subject'\n"); +xlog("L_INFO","$$tls_peer_issuer = '$tls_peer_issuer'\n"); +xlog("L_INFO","$$tls_my_subject = '$tls_my_subject'\n"); +xlog("L_INFO","$$tls_my_issuer = '$tls_my_issuer'\n"); +xlog("L_INFO","$$tls_peer_version = '$tls_peer_version'\n"); +xlog("L_INFO","$$tls_my_version = '$tls_my_version'\n"); +xlog("L_INFO","$$tls_peer_serial = '$tls_peer_serial'\n"); +xlog("L_INFO","$$tls_my_serial = '$tls_my_serial'\n"); +xlog("L_INFO","$$tls_peer_subject_cn = '$tls_peer_subject_cn'\n"); +xlog("L_INFO","$$tls_peer_issuer_cn = '$tls_peer_issuer_cn'\n"); +xlog("L_INFO","$$tls_my_subject_cn = '$tls_my_subject_cn'\n"); +xlog("L_INFO","$$tls_my_issuer_cn = '$tls_my_issuer_cn'\n"); +xlog("L_INFO","$$tls_peer_subject_locality = '$tls_peer_subject_locality'\n"); +xlog("L_INFO","$$tls_peer_issuer_locality = '$tls_peer_issuer_locality'\n"); +xlog("L_INFO","$$tls_my_subject_locality = '$tls_my_subject_locality'\n"); +xlog("L_INFO","$$tls_my_issuer_locality = '$tls_my_issuer_locality'\n"); +xlog("L_INFO","$$tls_peer_subject_country = '$tls_peer_subject_country'\n"); +xlog("L_INFO","$$tls_peer_issuer_country = '$tls_peer_issuer_country'\n"); +xlog("L_INFO","$$tls_my_subject_country = '$tls_my_subject_country'\n"); +xlog("L_INFO","$$tls_my_issuer_country = '$tls_my_issuer_country'\n"); +xlog("L_INFO","$$tls_peer_subject_state = '$tls_peer_subject_state'\n"); +xlog("L_INFO","$$tls_peer_issuer_state = '$tls_peer_issuer_state'\n"); +xlog("L_INFO","$$tls_my_subject_state = '$tls_my_subject_state'\n"); +xlog("L_INFO","$$tls_my_issuer_state = '$tls_my_issuer_state'\n"); +xlog("L_INFO","$$tls_peer_subject_organization = '$tls_peer_subject_organization'\n"); +xlog("L_INFO","$$tls_peer_issuer_organization = '$tls_peer_issuer_organization'\n"); +xlog("L_INFO","$$tls_my_subject_organization = '$tls_my_subject_organization'\n"); +xlog("L_INFO","$$tls_my_issuer_organization = '$tls_my_issuer_organization'\n"); +xlog("L_INFO","$$tls_peer_subject_unit = '$tls_peer_subject_unit'\n"); +xlog("L_INFO","$$tls_peer_issuer_unit = '$tls_peer_issuer_unit'\n"); +xlog("L_INFO","$$tls_my_subject_unit = '$tls_my_subject_unit'\n"); +xlog("L_INFO","$$tls_my_issuer_unit = '$tls_my_issuer_unit'\n"); +xlog("L_INFO","$$tls_peer_san_email = '$tls_peer_san_email'\n"); +xlog("L_INFO","$$tls_my_san_email = '$tls_my_san_email'\n"); +xlog("L_INFO","$$tls_peer_san_hostname = '$tls_peer_san_hostname'\n"); +xlog("L_INFO","$$tls_my_san_hostname = '$tls_my_san_hostname'\n"); +xlog("L_INFO","$$tls_peer_san_uri = '$tls_peer_san_uri'\n"); +xlog("L_INFO","$$tls_my_san_uri = '$tls_my_san_uri'\n"); +xlog("L_INFO","$$tls_peer_san_ip = '$tls_peer_san_ip'\n"); +xlog("L_INFO","$$tls_my_san_ip = '$tls_my_san_ip'\n"); +xlog("L_INFO","$$tls_peer_verified = '$tls_peer_verified'\n"); +xlog("L_INFO","$$tls_peer_revoked = '$tls_peer_revoked'\n"); +xlog("L_INFO","$$tls_peer_expired = '$tls_peer_expired'\n"); +xlog("L_INFO","$$tls_peer_selfsigned = '$tls_peer_selfsigned'\n"); +xlog("L_INFO","$$tls_peer_notBefore = '$tls_peer_notBefore'\n"); +xlog("L_INFO","$$tls_peer_notAfter = '$tls_peer_notAfter'\n"); +xlog("L_INFO","================= end TLS pseudo variables ===============\n"); +``` + + +## Developer Guide + + +### API Functions + + +#### find_server_domain + + +struct tls_domain *find_server_domain(struct ip_addr *ip, +unsigned short port); + + +Find a TLS server domain with given ip and port +(local listening socket). + + +#### find_client_domain + + +struct tls_domain *find_client_domain(struct ip_addr *ip, +unsigned short port); + + +Find TLS client domain. + + +#### get_handshake_timeout + + +int get_handshake_timeout(void); + + +Returns the handshanke timeout. + + +#### get_send_timeout + + +int get_send_timeout(void); + + +Returns the send timeout. + + +### TLS_CONFIG + + +It contains configuration variables for OpenSIPS's TLS (timeouts, +file paths, etc). + + +### TLS_INIT + + +Initialization related functions and parameters. + + +#### ssl context + + +extern SSL_CTX *default_client_ctx; + + +The ssl context is a member of the TLS domain strcuture. Thus, every +TLS domain, default and virtual - servers and clients, have its own SSL context. + + +#### pre_init_tls + + +int init_tls(void); + + +Called once to pre_initialize the tls subsystem, from the main(). +Called before parsing the configuration file. + + +#### init_tls + + +int init_tls(void); + + +Called once to initialize the tls subsystem, from the main(). +Called after parsing the configuration file. + + +#### destroy_tls + + +void destroy_tls(void); + + +Called once, just before cleanup. + + +#### tls_init + + +int tls_init(struct socket_info *c); + + +Called once for each tls socket created, from main.c + + +#### os_malloc, os_realloc, os_free + + +Wrapper functions around the shm_* functions. OpenSSL uses +non-shared memory to create its objects, thus it would not +work in OpenSIPS. By creating these wrappers and configuring +OpenSSL to use them instead of its default memory functions, +we have all OpenSSL objects in shared memory, ready to use. + + +### TLS_DOMAIN + + +#### tls_domains + + +extern struct tls_domain *tls_default_server_domain; + + +The default TLS server domain. + + +extern struct tls_domain *tls_default_client_domain; + + +The default TLS client domain. + + +extern struct tls_domain *tls_server_domains; + + +List with defined server domains. + + +extern struct tls_domain *tls_client_domains; + + +List with defined client domains. + + +#### tls_find_server_domain + + +struct tls_domain *tls_find_server_domain(struct ip_addr *ip, +unsigned short port); + + +Find a TLS server domain with given ip and port +(local listening socket). + + +#### tls_find_client_domain + + +struct tls_domain *tls_find_client_domain(struct ip_addr *ip, +unsigned short port); + + +Find TLS client domain. + + +#### tls_find_client_domain_addr + + +struct tls_domain *tls_find_client_domain_addr(struct ip_addr *ip, +unsigned short port); + + +Find TLS client domain with given ip and port +(socket of the remote destination). + + +#### tls_find_client_domain_name + + +struct tls_domain *tls_find_client_name(str name); + + +Find TLS client domain with given name. + + +#### tls_new__domain + + +struct tls_domain *tls_new_domain(int type); + + +Creates new TLS: allocate memory, set the type and initialize members + + +#### tls_new_server_domain + + +int tls_new_server_domain(struct ip_addr *ip, unsigned short port); + + +Creates and adds to the list of TLS server domains a new domain. + + +#### tls_new_client_domain + + +int tls_new_client_domain(struct ip_addr *ip, unsigned short port); + + +Creates and adds to the list of TLS client domains a new socket based domain. + + +#### tls_new_client_domain_name + + +int tls_new_client_domain_name(char *s, int len); + + +Creates and adds to the list of TLS client domains a new name based domain. + + +#### tls_free_domains + + +void tls_free_domains(void); + + +Cleans up the entire domain lists. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tls_mgm/doc/contributors.xml b/modules/tls_mgm/doc/contributors.xml deleted file mode 100644 index a7c0e8d4b4a..00000000000 --- a/modules/tls_mgm/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 180 - 58 - 4821 - 4882 - - - 2. - Razvan Crainea (@razvancrainea) - 81 - 57 - 1415 - 724 - - - 3. - Eseanu Marius Cristian (@eseanucristian) - 53 - 11 - 4268 - 321 - - - 4. - Liviu Chircu (@liviuchircu) - 26 - 20 - 175 - 236 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 24 - 13 - 291 - 460 - - - 6. - Dan Pascu (@danpascu) - 17 - 13 - 90 - 176 - - - 7. - Ionut Ionita (@ionutrazvanionita) - 16 - 9 - 383 - 169 - - - 8. - Ionel Cerghit (@ionel-cerghit) - 8 - 1 - 494 - 109 - - - 9. - Maksym Sobolyev (@sobomax) - 7 - 4 - 61 - 75 - - - 10. - Alexey Vasilyev (@vasilevalex) - 4 - 2 - 33 - 19 - - - -
-All remaining contributors: Callum Guy (@spacetourist), Aleksei Vasilev, jupiter, Fabian Gast (@fgast), Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Peter Lemenkov (@lemenkov), Jupiter Tang. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Jupiter Tang - Nov 2025 - Nov 2025 - - - 2. - jupiter - Apr 2025 - Apr 2025 - - - 3. - Maksym Sobolyev (@sobomax) - Mar 2016 - Nov 2023 - - - 4. - Liviu Chircu (@liviuchircu) - Oct 2015 - May 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - Apr 2017 - May 2023 - - - 6. - Razvan Crainea (@razvancrainea) - Sep 2015 - Apr 2022 - - - 7. - Nick Altmann (@nikbyte) - May 2021 - May 2021 - - - 8. - Aleksei Vasilev - Apr 2021 - Apr 2021 - - - 9. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2016 - Apr 2020 - - - 10. - Dan Pascu (@danpascu) - Jun 2019 - Feb 2020 - - - -
-All remaining contributors: Fabian Gast (@fgast), Alexey Vasilyev (@vasilevalex), Callum Guy (@spacetourist), Peter Lemenkov (@lemenkov), Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Ionel Cerghit (@ionel-cerghit), Eseanu Marius Cristian (@eseanucristian). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Dan Pascu (@danpascu), Callum Guy (@spacetourist), Peter Lemenkov (@lemenkov), Eseanu Marius Cristian (@eseanucristian). -
- -
diff --git a/modules/tls_mgm/doc/tls_mgm.xml b/modules/tls_mgm/doc/tls_mgm.xml deleted file mode 100644 index 14ef11b655a..00000000000 --- a/modules/tls_mgm/doc/tls_mgm.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - TLS_MGM module - &osipsname; - - - - &admin; - &devel; - &contrib; - - &docCopyrights; - ©right; 2015 &osipssol; - ©right; 2013 Secusmart GmbH - ©right; 2006 enum.at - ©right; 2005 Cesc Santasusana - ©right; 2005 &voicesystem; - - diff --git a/modules/tls_mgm/doc/tls_mgm_admin.xml b/modules/tls_mgm/doc/tls_mgm_admin.xml deleted file mode 100644 index 63a27c469cf..00000000000 --- a/modules/tls_mgm/doc/tls_mgm_admin.xml +++ /dev/null @@ -1,1593 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module is a management module for TLS certificates and - parameters. It provides an interface for all the modules that - use the TLS protocol. It also exports pseudo variables with - certificate and TLS parameters. - -
- -
- Usage - - This module is used to provision TLS certificates and parameters - for all the modules that use TLS transport (like - proto_tls or proto_wss). - The module supports multiple - virtual domains that can be assigned to different listeners - (servers) or new connections (clients). Each TLS module that uses - this management module should assign itself to one or more domains. - - - The module allows the definition of the TLS domains both via - module parameters (script level) and via an SQL table. - - - A script example which details this module's usage can be found in - . - -
- -
- TLS libraries - - Besides TLS certificates and parameters, this module also acts as - an inteface between the actual TLS implemenation (provided by - openSSL or wolfSSL libraries) - and transport protocol modules like proto_tls or - proto_wss. The tls_mgm module - transparently exposes the TLS operations implemented by - tls_openssl and tls_wolfssl modules - to the higher-level OpenSIPS transport modules. - - - The TLS library selection ca be configured through the - module parameter. - -
- -
- TLS domains - - The wording 'TLS domain' means that this TLS connection will have different - parameters than another TLS connection (from another TLS domain). Thus, TLS - domains are not directly related to different SIP domains, although they - are often used in conjunction. Depending on the direction of the TLS handshake, a - TLS domain is called 'client domain' (=outgoing TLS connection) or 'server domain' - (= incoming TLS connection). - - - If you run several SIP domains you can specify some parameters for each of them - separately (regardless if you have only one or multiple socket=tls:ip:port entries - in the config file). - - - For example, TLS domains can be used in virtual hosting scenarios with TLS. - &osips; offers SIP service for multiple domains, e.g. atlanta.com and biloxi.com. Altough - both domains will be hosted on a single SIP proxy, the SIP proxy needs 2 certificates: One - for atlanta.com and one for biloxi.com. For incoming TLS connections, the SIP proxy - has to present the respective certificate during the TLS handshake. As the SIP proxy - does not have a received SIP message yet (this is done after the TLS handshake), the SIP - proxy can not retrieve the target domain from SIP (which would have been usually retrieved - from the domain in the request URI). Thus, distinction for these domains must be done by using multiple listening sockets or by having clients that send the Servername TLS extension(SNI) in the - handshake process. - - - For outgoing TLS connections, the TLS domain is chosen based on the destination socket of the underlying outgoing TCP connection and/or by taking a decision at script level via an AVP. For example, you can inspect headers like RURI or From and match the domain in the SIP header with filters that you have set up for the TLS domains. - - - NOTE: Except tls_handshake_timeout and tls_send_timeout all TLS parameters can be set - per TLS domain. - -
- -
- Defining TLS domains - - TLS domains can be defined in two ways: - - by setting the server_domain or client_domain module parameters - - by provisioning in DB - - - For the domains defined in the DB, the certificate, private key, list of trusted CAs and Diffie-Hellman parameters are provisioned as BLOB values while for script defined domains you must provide path to files. - - You can define domains both in the DB and script at the same time. - - - For any TLS domain (defined through script or DB) if not specified otherwise, the default settings are: - - method - SSLv23 - verify_cert - 1 - require_cert - 1 - certificate - CFG_DIR/tls/cert.pem - private_key - CFG_DIR/tls/ckey.pem - crl_check_all - 0 - crl_dir - none - ca_list - none - ca_dir - /etc/pki/CA/ - cipher_list - the OpenSSL default ciphers - dh_params - none - ec_curve - none - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - tls_openssl or tls_wolfssl, - unless is set to 'none'. - - - - -
-
- Dependencies of external libraries - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">is_peer_verified</function> - - - Returns 1 if the message is received via TLS and the peer was verified - during TLS connection handshake, otherwise it returns -1 - - - This function can be used from REQUEST_ROUTE. - - - <function>is_peer_verified</function> usage - -... -if (is_peer_verified()) { - xlog("L_INFO","request from verified TLS peer\n"); -} else { - xlog("L_INFO","request not verified\n"); -} -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">tls_list</function> - - - List all domains information. - -
- -
- - <function moreinfo="none">tls_reload</function> - - - Reloads the TLS domains information from the database. - The previous DB defined domains are discarded but the - script defined domains are preserved. - -
-
- -
- &osips; Exported parameters - - All these parameters can be used from the opensips.cfg file, - to configure the behavior of &osips;-TLS. - - -
- <varname>listen</varname>=interface - - Not specific to TLS. Allows to specify the protocol - (udp, tcp, tls), the IP address and the port where the - listening server will be. - - - Set <varname>listen</varname> variable - -... -socket= tls:1.2.3.4:5061 -... - - -
- -
- <varname>tls_library</varname> (string) - - Selects which TLS library to use. Possible values are: - - - - auto - auto-detect which TLS library - module (tls_openssl or tls_wolfssl) - was loaded. OpenSIPS will not start if no module, or both modules are - found. - - - - none - do not use any TLS library; this - is useful when the tls_mgm module is required only - for the management of TLS certificates and parameters by modules like - db_mysql, rabbitmq etc. ( - and not for TLS operations by transport modules like - proto_tls etc.) - - - - openssl - use the openSSL - library through the tls_openssl module. - - - - wolfssl - use the wolfSSL - library through the tls_wolfssl module. - - - - - Default value is auto. - - - Set <varname>tls_library</varname> variable - -... -modparam("tls_mgm", "tls_library", "none") -... - - -
- -
- <varname>tls_method</varname> ([domain]string) - - Sets the TLS protocol. The domain part represents the name of - the TLS domain. The supported TLS methods are: - - - - TLSv1_3 - means &osips; will - accept only TLSv1.3 connections. This version is only - available starting with OpenSSL 1.1.1 version. - - - - TLSv1_2 - means &osips; will - accept only TLSv1.2 connections (rfc3261 conformant). - - - - TLSv1 - means &osips; will - accept only TLSv1 connections (rfc3261 conformant). - - - - SSLv23 - means &osips; will - accept any of the above methods, but the initial SSL - hello must be v2 (in the initial hello all the supported - protocols are advertised enabling switching to a higher - and more secure version). The initial v2 hello means it - will not accept connections from SSLv3 or TLSv1 only - clients. - - - - - If you are using an OpenSSL library newer than 1.1.0, you can - also specify a range of accepted TLS versions as [VLOW]-[VHIGH]. - If VLOW is not specified it will use the minimum supported - protocol version and if VHIGH is not specified it will use - the maximum supported protocol version. This means that using - a range where both the low and high values are missing, will - accept all the supported methods, but unlike SSLv23 will not - require the initial hello to be SSLv2. - - - Default value is SSLv23. - - - For extended compatibility with older system, best use SSLv23. - - - If you want RFC3261 conformance and all your clients support - TLSv1 (or you are planning to use encrypted "tunnels" only - between different &osips; proxies) use TLSv1. If you want to - support older clients use SSLv23 (in fact most of the - applications with SSL support use the SSLv23 method). - - - Set <varname>tls_method</varname> variable - -... -modparam("tls_mgm", "tls_method", "[dom]TLSv1") -... - - - - Set <varname>tls_method</varname> range variable - -... -modparam("tls_mgm", "tls_method", "[dom]TLSv1-TLSv1_3") # between v1 and v1.3 -modparam("tls_mgm", "tls_method", "[dom]TLSv1-") # v1 or higher -modparam("tls_mgm", "tls_method", "[dom]-TLSv1_2") # up to v1.2 -modparam("tls_mgm", "tls_method", "[dom]-") # all supported -... - - -
- -
- <varname>certificate</varname> ([domain](string) - - Public certificate file for &osips;. It will be used as - server-side certificate for incoming TLS connections, and as - a client-side certificate for outgoing TLS connections. The domain - part represents the name of the TLS domain. - - - Default value is "CFG_DIR/tls/cert.pem". - - - Set <varname>certificate</varname> variable - - -... -modparam("tls_mgm", "certificate", "[dom]/mycerts/certs/opensips_server_cert.pem") -... - - -
- -
- <varname>private_key</varname> ([domain](string) - - Private key of the above certificate. I must be kept in a - safe place with tight permissions! The domain part - represents the name of the TLS omain. - - - Default value is "CFG_DIR/tls/ckey.pem". - - - Set <varname>private_key</varname> variable - - -... -modparam("tls_mgm", "private_key", "[dom]/mycerts/private/prik.pem") -... - - -
- -
- <varname>ca_list</varname> ([domain](string) - - List of trusted CAs. The file contains the certificates - accepted, one after the other. It MUST be a file, not - a folder. The domain part represents the name - of the TLS domain. - - - Default value is "". - - - Set <varname>ca_list</varname> variable - -... -modparam("tls_mgm", "ca_list", "[dom]/mycerts/certs/ca_list.pem") -... - - -
- -
- <varname>ca_dir</varname> ([domain](string) - - Directory storing trusted CAs. The certificates in the directory - must be in hashed form, as described in the - - openssl documentation for the - Hashed Directory Method. The domain part - represents the name of the TLS domain. - - - Default value is "/etc/pki/CA/". - - - Set <varname>ca_dir</varname> variable - -... -modparam("tls_mgm", "ca_dir", "[dom]/mycerts/certs") -... - - -
- -
- <varname>crl_dir</varname> ([domain](string) - - Directory storing certificate revocation lists (CRLs). The domain - part represents the name of the TLS domain. - - - If this parameter is not set, no CRLs will be used. - - - Set <varname>crl_dir</varname> variable - -... -modparam("tls_mgm", "crl_dir", "[dom]/mycerts/crls") -... - - -
- -
- <varname>crl_check_all</varname> ([domain](string) - - Setting this parameter with a non-zero integer value enables CRL - checking for the entire certificate chain. - - - By default, only the leaf certificate in the certificate chain - is checked. - - - Set <varname>crl_check_all</varname> variable - -... -modparam("tls_mgm", "crl_check_all", "[dom]1") -... - - -
- -
- <varname>ciphers_list</varname> ([domain](string) - - You can specify the list of algorithms for authentication - and encryption that you allow. The domain part - represents the name of the TLS domain. To obtain a list of ciphers - and then choose, use the openssl application: - - - - openssl ciphers 'ALL:eNULL:!LOW:!EXPORT' - - - - Do not use the NULL algorithms (no encryption) ... only for testing!!! - - - It defaults to the OpenSSL default ciphers. - - - Set <varname>ciphers_list</varname> variable - - -... -modparam("tls_mgm", "ciphers_list", "[dom]NULL") -... - - -
- -
- <varname>dh_params</varname> ([domain](string) - - You can specify a file which contains Diffie-Hellman - parameters as a PEM-file. This is needed if you would like - to specify ciphers including Diffie-Hellman mode. The - domain part represents the name of the TLS domain. - - - It defaults to not set a dh param file. - - - Set <varname>dh_params</varname> variable - - -... -modparam("tls_mgm", "dh_params", "[dom]/etc/pki/CA/dh1024.pem") -... - - -
- -
- <varname>ec_curve</varname> ([domain](string) - - You can specify an elliptic curve which should be used for - ciphers which demand an elliptic curve. The domain part - represents the name of the TLS domain. - - - It's usable only if TLS v1.1/1.2 support was compiled. - A list of curves which can be used you can get by - - openssl ecparam -list_curves - - - - It defaults to not set a elliptic curve. - -
- -
- <varname>verify_cert</varname> ([domain](string) - - Activates SSL_VERIFY_PEER in the ssl_context. For a detailed - explanation, check the openssl documentation. - - The domain part represents the name of the TLS domain. - - Default value is 1. - - - Set <varname>verify_cert</varname> variable - -... -modparam("tls_mgm", "verify_cert", "[dom]0") -... - - -
- -
- <varname>require_cert</varname> ([domain](string) - - Activates SSL_VERIFY_FAIL_IF_NO_PEER_CERT in the ssl_context. For a - detailed explanation, check the openssl - documentation. This parameter only makes sense for server domains - and if the parameter is also set. - - The domain part represents the name of the TLS domain. - - Default value is 1. - - - Set <varname>require_cert</varname> variable - -... -modparam("tls_mgm", "require_cert", "[dom]0") -... - - -
- -
- <varname>client_tls_domain_avp</varname> (string) - - Name of the AVP used for enforcing the selection of a specific TLS - client domain. Setting this AVP to the name of a TLS client domain will - result in using that specific domain regardless of the standard matching - mechanism. - - - Note: If there is already an existing TLS connection to the remote target, - it will be reused and setting this AVP has no effect. - - - Note: You can force a particular domain to be used just for a particular - branch by setting the $bavp variable with the same - name. When both $bavp and $avp - variables are set, the first one takes precedence. - - - No default value. - - - Set <varname>client_tls_domain_avp</varname> variable - -... -modparam("tls_mgm", "client_tls_domain_avp", "tls_match_dom") -... - - -
- -
- <varname>client_sip_domain_avp</varname> (string) - - Name of the AVP that sets the SIP domain used in the TLS client - domain matching process. - - - Note: If there is already an existing TLS connection to the remote target, - it will be reused and setting this AVP has no effect. - - - Note: You can force a particular SIP domain to be used just for a particular - branch by setting the $bavp variable with the same - name. When both $bavp and $avp - variables are set, the first one takes precedence. - - - For the AVP usage example, refer to . - - - No default value. - - - Set <varname>client_sip_domain_avp</varname> variable - -... -modparam("tls_mgm", "client_sip_domain_avp", "sip_match_dom") -... - - -
- -
- <varname>db_url</varname> (string) - - The database url. It cannot be NULL. - - - You cannot use the "tls_domain=dom_name" URL parameter - for a TLS connection to the database for the tls_mgm module itself. - - - Usage of <varname>db_url</varname> block - - -modparam("tls_mgm", "db_url", "mysql://root:admin@localhost/opensips") - - -
- -
- - <varname>db_table</varname> (string) - - - Sets the database table name. - - Default value is "tls_mgm". - - Usage of <varname>db_table</varname> block - - -modparam("tls_mgm", "db_table", "tls_mgm") - - -
- -
- - <varname>domain_col</varname> (string) - - - Sets the name for the TLS domain column. - - Default value is "domain". - - Usage of <varname>domain_col</varname> block - - -modparam("tls_mgm", "domain_col", "tls_domain") - - -
- -
- - <varname>match_ip_address_col</varname> (string) - - - Sets the IP address matching column name. - - Default value is "match_ip_address". - - Usage of <varname>match_ip_address_col</varname> block - - -modparam("tls_mgm", "match_ip_address_col", "addr") - - -
- -
- - <varname>match_sip_domain_col</varname> (string) - - - Sets the SIP domain matching column name. - - Default value is "match_sip_domain". - - Usage of <varname>match_sip_domain_col</varname> block - - -modparam("tls_mgm", "match_sip_domain_col", "addr") - - -
- -
- - <varname>tls_method_col</varname> (string) - - - Sets the method column name. - - Default value is "method". - - Usage of <varname>tls_method_col</varname> block - - -modparam("tls_mgm", "tls_method_col", "method") - - -
- -
- - <varname>verify_cert_col</varname> (string) - - - Sets the verrify certificate column name. - - Default value is "verify_cert". - - Usage of <varname>vertify_cert_col</varname> block - - -modparam("tls_mgm", "verify_cert_col", "verify_cert") - - -
- -
- - <varname>require_cert_col</varname> (string) - - - Sets the require certificate column name. - - Default value is "require_cert". - - Usage of <varname>require_cert_col</varname> block - - -modparam("tls_mgm", "require_cert_col", "req") - - -
- -
- - <varname>certificate_col</varname> (string) - - - Sets the certificate column name. - - Default value is "certificate". - - Usage of <varname>certificate_col</varname> block - - -modparam("tls_mgm", "certificate_col", "certificate") - - -
- -
- - <varname>private_key_col</varname> (string) - - - Sets the private key column name. - - Default value is "private_key". - - Usage of <varname>private_key_col</varname> block - - -modparam("tls_mgm", "private_key_col", "pk") - - -
- -
- - <varname>crl_check_all_col</varname> (string) - - - Sets the crl_check_all column name. - - Default value is "crl_check_all". - - Usage of <varname>crl_check_all</varname> block - - -modparam("tls_mgm", "crl_check_all_col", "crl_check") - - -
- -
- - <varname>crl_dir_col</varname> (string) - - - Sets the crl directory column name. - - Default value is "crl_dir". - - Usage of <varname>crl_dir_col</varname> block - - -modparam("tls_mgm", "crl_dir_col", "crl_dir") - - -
-
- - <varname>ca_list_col</varname> (string) - - - Sets the CA list column name. - - Default value is "ca_list". - - Usage of <varname>ca_list_col</varname> block - - -modparam("tls_mgm", "ca_list_col", "ca_list") - - -
- - - -
- - <varname>ca_dir_col</varname> (string) - - - Sets the CA directory column name. - - Default value is "ca_dir". - - Usage of <varname>ca_dir_col</varname> block - - -modparam("tls_mgm", "ca_dir_col", "ca_dir") - - -
- - -
- - <varname>cipher_list_col</varname> (string) - - - Sets the cipher list column name. - - Default value is "cipher_list". - - Usage of <varname>cipher_list_col</varname> block - - -modparam("tls_mgm", "cipher_list_col", "cipher_list") - - -
- - -
- - <varname>dh_params_col</varname> (string) - - - Sets the Diffie-Hellmann parameters column name. - - Default value is "dh_params". - - Usage of <varname>dh_params_col</varname> block - - -modparam("tls_mgm", "dh_params_col", "dh_parms") - - -
- -
- - <varname>ec_curve_col</varname> (string) - - - Sets the ec_curve column name. - - Default value is "ec_curve". - - Usage of <varname>ec_curve_col</varname> block - - -modparam("tls_mgm", "ec_curve_col", "ec_curve") - - -
- -
- <varname>match_ip_address</varname> (string) - - The IP addresses and ports used to match a TLS connection with a - virtual TLS domain. For TLS server domains, these values will be - mathced against the socket on which the connection is received. For - TLS client domains, the values will be compared with the destination - socket of the connection. - - - The parameter accepts a list of values, and the special value "*" - means: match any address. - - - Default value is "*" (match any address). - - - Set <varname>match_ip_address</varname> variable - -... -modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061, 10.0.0.11:5061") -... - - -
- -
- <varname>match_sip_domain</varname> (string) - - The SIP domains used to match a TLS connection with a - virtual TLS domain. For TLS server domains, these values will be - matched against the hostname provided in the TLS Servername extension(SNI). - For TLS client domains, the values will be compared with the value of - the AVP. - - - The parameter accepts a list of FQDNs or the special values: - - * - match any sip domain( - including no SNI provided, in case of TLS server domains); - - none - match the TLS domain - when there is no SNI provided (make sense only for TLS server - domains). Note that if a SNI is provided, but does not match any - other SIP domain filter, the connection will be rejected. - - - - - The FQDNs can be specified as with Unix shell-style wildcards. If - there are multiple potential matches, the most specific domain will - be selected(eg. a request for "foo.bar.com" is matched with the domain - specified with "foo.bar.com" versus the one with "*.bar.com"). - - - Default value is "*" (match any sip domain). - - - Set <varname>match_sip_domain</varname> variable - -... -modparam("tls_mgm", "match_sip_domain", "[dom1]foo.com, bar.com, *.baz.com") -modparam("tls_mgm", "match_sip_domain", "[default_dom]*") -... - - -
- -
- <varname>server_domain, client_domain</varname> (string) - - You can define virtual TLS domains through these parameters. - - - The value of these parameters represents the virtual tls domain's - name which is only used for identification. - - - Usage of <varname>tls_client_domain</varname> and - <varname>tls_server_domain</varname> block - - -... -socket=tls:10.0.0.10:5061 -... -# set the TLS client domain AVP -modparam("tls_mgm", "client_sip_domain_avp", "tls_sip_dom") -... - -# 'atlanta' server domain -modparam("tls_mgm", "server_domain", "dom1") -modparam("tls_mgm", "match_ip_address", "[dom1]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom1]atlanta.com") - -modparam("tls_mgm", "certificate", "[dom1]/certs/atlanta.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom1]/certs/atlanta.com/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom1]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom1]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom1]1") -modparam("tls_mgm", "require_cert", "[dom1]1") - -#'biloxi' server domain -modparam("tls_mgm", "server_domain", "dom2") -modparam("tls_mgm", "match_ip_address", "[dom2]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom2]biloxi.com") - -modparam("tls_mgm", "certificate", "[dom2]/certs/biloxi.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom2]/certs/biloxi.com/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom2]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom2]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom2]1") -modparam("tls_mgm", "require_cert", "[dom2]1") - -# generic TLS server domain, if the client does not provide SNI -modparam("tls_mgm", "server_domain", "dom3") -modparam("tls_mgm", "match_ip_address", "[dom3]10.0.0.10:5061") -modparam("tls_mgm", "match_sip_domain", "[dom3]none") - -modparam("tls_mgm", "certificate", "[dom3]/certs/generic/cert.pem") -modparam("tls_mgm", "private_key", "[dom3]/certs/generic/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom3]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom3]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom3]1") -modparam("tls_mgm", "require_cert", "[dom3]1") - -# 'atlanta' client domain -modparam("tls_mgm", "client_domain", "dom4") -modparam("tls_mgm", "match_ip_address", "[dom4]*") -modparam("tls_mgm", "match_sip_domain", "[dom4]atlanta.com") - - -modparam("tls_mgm", "certificate", "[dom4]/certs/atlanta.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom4]/certs/atlanta.com/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom4]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom4]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom4]1") -modparam("tls_mgm", "require_cert", "[dom4]1") - -# 'biloxi' client domain -modparam("tls_mgm", "client_domain", "dom5") -modparam("tls_mgm", "match_ip_address", "[dom5]*") -modparam("tls_mgm", "match_sip_domain", "[dom5]biloxi.com") - -modparam("tls_mgm", "certificate", "[dom5]/certs/biloxi.com/cert.pem") -modparam("tls_mgm", "private_key", "[dom5]/certs/biloxi.com/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom5]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom5]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom5]1") -modparam("tls_mgm", "require_cert", "[dom5]1") - -# TLS client domain for GW provider -modparam("tls_mgm", "client_domain", "dom6") -modparam("tls_mgm", "match_ip_address", "[dom6]1.2.3.4:6677") -modparam("tls_mgm", "match_sip_domain", "[dom6]*") - -modparam("tls_mgm", "certificate", "[dom6]/certs/gw/cert.pem") -modparam("tls_mgm", "private_key", "[dom6]/certs/gw/privkey.pem") -modparam("tls_mgm", "ca_list", "[dom6]/certs/wellknownCAs") -modparam("tls_mgm", "tls_method", "[dom6]tlsv1") -modparam("tls_mgm", "verify_cert", "[dom6]0") - -... -route{ -... - # we match the TLS client domain using the SIP domain in the RURI - $avp(tls_sip_dom) = $rd; - t_relay(); - exit; -... - # calls to the PSTN GW, will match the correct TLS domain by IP - t_relay("tls:1.2.3.4:6677"); - exit; -... - - -
-
- - -
- Variables - - This module exports the follong variables: - - - Some variables are available for both, the peer'S certificate and - the local certificate. Further, some parameters can be read from the - Subject field or the Issuer field. - -
- $tls_version - - $tls_version - the TLS/SSL version which is - used on the TLS connection from which the message was received. - String type. - -
-
- $tls_description - - $tls_description - the TLS/SSL description - of the TLS connection from which the message was received. String - type. - -
-
- $tls_cipher_info - - $tls_cipher_info - the TLS/SSL cipher which - is used on the TLS connection from which the message was received. - String type. - -
-
- $tls_cipher_bits - - $tls_cipher_bits - the number of cipher bits - which are used on the TLS connection from which the message was - received. String and Integer type. - -
-
- $tls_[peer|my]_version - - $tls_[peer|my]_version - the version of the - certificate. String type. - -
-
- $tls_[peer|my]_serial - - $tls_[peer|my]_serial - the serial number - of the certificate. String and Integer type. - -
-
- $tls_[peer|my]_[subject|issuer] - - $tls_[peer|my]_[subject|issuer] - ASCII dump - of the fields in the issuer/subject section of the certificate. - String type. - - - Example of <varname>$tls_[peer|my]_[subject|issuer]</varname> - -/C=AT/ST=Vienna/L=Vienna/O=enum.at/CN=enum.at - - - -
-
- $tls_[peer|my]_[subject|issuer]_cn - - $tls_[peer|my]_[subject|issuer]_cn - - commonName in the issuer/subject section of the certificate. - String type. - -
-
- $tls_[peer|my]_[subject|issuer]_locality - - $tls_[peer|my]_[subject|issuer]_locality - - localityName in the issuer/subject section of the certificate. - String type. - -
-
- $tls_[peer|my]_[subject|issuer]_country - - $tls_[peer|my]_[subject|issuer]_country - - countryName in the issuer/subject section of the certificate. - String type. - -
-
- $tls_[peer|my]_[subject|issuer]_state - - $tls_[peer|my]_[subject|issuer]_state - - stateOrProvinceName in the issuer/subject section of the - certificate. String type. - -
-
- $tls_[peer|my]_[subject|issuer]_organization - - $tls_[peer|my]_[subject|issuer]_organization - - organizationName in the issuer/subject section of the certificate. - String type. - -
-
- $tls_[peer|my]_[subject|issuer]_unit - - $tls_[peer|my]_[subject|issuer]_unit - - organizationalUnitName in the issuer/subject section of the - certificate. String type. - -
-
- $tls_[peer|my]_san_email - - $tls_[peer|my]_san_email - email address in - the subject alternative name extension. String type. - -
-
- $tls_[peer|my]_san_hostname - - $tls_[peer|my]_san_hostname - hostname (DNS) - in the subject alternative name extension. String - type. - -
-
- $tls_[peer|my]_san_uri - - $tls_[peer|my]_san_uri - URI in the - subject alternative name extension. - String type. - -
-
- $tls_[peer|my]_san_ip - - $tls_[peer|my]_san_ip - ip address in the - subject alternative name extension. - String type. - -
-
- $tls_peer_verified - - $tls_peer_verified - Returns 1 if the peer's - certificate was successful verified. Otherwise it returns 0. - String and Integer type. - -
-
- $tls_peer_revoked - - $tls_peer_revoked - Returns 1 if the peer's - certificate was revoked. Otherwise it returns 0. - String and Integer type. - -
-
- $tls_peer_expired - - $tls_peer_expired - Returns 1 if the peer's - certificate is expired. Otherwise it returns 0. - String and Integer type. - -
-
- $tls_peer_selfsigned - - $tls_peer_selfsigned - Returns 1 if the - peer's certificate is selfsigned. Otherwise it returns 0. - String and Integer type. - -
-
- $tls_peer_notBefore - - $tls_peer_notBefore - Returns the notBefore - validity date of the peer's certificate. - String type. - -
-
- $tls_peer_notAfter - - $tls_peer_notAfter - Returns the notAfter - validity date of the peer's certificate. - String type. - -
-
- - - -
- &osips; with TLS - script example - - IMPORTANT: The TLS support is based on TCP, and for allowing &osips; - to use TCP, it must be started in multi-process mode. So, there is - a must to have the "fork" parameter set to "yes": - - - NOTE: Since the TLS engine is quite memory consuming, increase the - used memory by the run time parameter "-m" (see &osips; -h for more - details). - - - - fork = yes - - - - - Script with TLS support - - # ----------- global configuration parameters ------------------------ - log_level=3 - stderror_enabled=no - syslog_enabled=yes - - check_via=no - dns=no - rev_dns=no - socket=udp:your_serv_IP:5060 - socket=tls:your_serv_IP:5061 - udp_workers=4 - - # ------------------ module loading ---------------------------------- - - loadmodule "proto_tls.so" - loadmodule "proto_udp.so" - - #TLS specific settings - loadmodule "tls_mgm.so" - - modparam("tls_mgm", "certificate", "/path/opensipsX_cert.pem") - modparam("tls_mgm", "private_key", "/path/privkey.pem") - modparam("tls_mgm", "ca_list", "/path/calist.pem") - modparam("tls_mgm", "ca_list", "/path/calist.pem") - modparam("tls_mgm", "require_cert", "1") - modparam("tls_mgm", "verify_cert", "1") - - alias=_DNS_ALIAS_ - - - loadmodule "sl.so" - loadmodule "rr.so" - loadmodule "maxfwd.so" - loadmodule "mysql.so" - loadmodule "usrloc.so" - loadmodule "registrar.so" - loadmodule "tm.so" - loadmodule "auth.so" - loadmodule "auth_db.so" - loadmodule "textops.so" - loadmodule "sipmsgops.so" - loadmodule "signaling.so" - loadmodule "uri_db.so" - - # ----------------- setting module-specific parameters --------------- - - # -- auth_db params -- - modparam("auth_db", "db_url", "sql_url") - modparam("auth_db", "password_column", "password") - modparam("auth_db", "calculate_ha1", 1) - - # -- registrar params -- - # no multiple registrations - modparam("registrar", "append_branches", 0) - - # ------------------------- request routing logic ------------------- - - # main routing logic - - route{ - - # initial sanity checks - if (!mf_process_maxfwd_header("10")) { - send_reply(483,"Too Many Hops"); - exit; - }; - - # if somene claims to belong to our domain in From, - # challenge him (skip REGISTERs -- we will chalenge them later) - if (is_myself("$fd")) { - setflag(1); - if ( is_method("INVITE|SUBSCRIBE|MESSAGE") - && !(is_myself("$si")) ) { - if (!(proxy_authorize( "domA.net", "subscriber" ))) { - proxy_challenge("domA.net","0"/*no-qop*/); - exit; - }; - if ($au!=$fU) { - xlog("FROM hdr Cheating attempt in INVITE\n"); - send_reply(403, - "That is ugly -- use From=id next time (OB)"); - exit; - }; - }; # non-REGISTER from other domain - } else if ( is_method("INVITE") && !is_myself("$rd") ) { - send_reply(403, "No relaying"); - exit; - }; - - /* ******** do record-route and loose-route ******* */ - if (!is_method("REGISTER")) - record_route(); - - if (loose_route()) { - append_hf("P-hint: rr-enforced\r\n"); - t_relay(); - exit; - }; - - /* ******* check for requests targeted out of our domain ******* */ - if ( !is_myself("$rd") ) { - append_hf("P-hint: OUTBOUND\r\n"); - if ($rd=="domB.net") { - t_relay("tls:domB.net:5061"); - } else if ($rd=="domC.net") { - t_relay("tls:domC.net:5061"); - } else { - t_relay(); - }; - exit; - }; - - /* ******* divert to other domain according to prefixes ******* */ - if (!is_method("REGISTER")) { - if ( $ru=~"sip:201") { - strip(3); - $rd = "domB.net"; - t_relay("tls:domB.net:5061"); - exit; - } else if ( $ru=~"sip:202" ) { - strip(3); - $rd = "domC.net"; - t_relay("tls:domC.net:5061"); - exit; - }; - }; - - /* ************ requests for our domain ********** */ - if (is_method("REGISTER")) { - if (!www_authorize( "domA.net", "subscriber" )) { - # challenge if none or invalid credentials - www_challenge( "domA.net" /* realm */, - "0" /* no qop -- some phones can't deal with it */); - exit; - }; - if ($au!=$tU) { - xlog("TO hdr Cheating attempt\n"); - send_reply(403, "That is ugly -- use To=id in REGISTERs"); - exit; - }; - # it is an authenticated request, update Contact database now - if (!save("location")) { - sl_reply_error(); - }; - exit; - }; - - # native SIP destinations are handled using USRLOC DB - if (!lookup("location")) { - # handle user which was not found - send_reply(404, "Not Found"); - exit; - }; - - # remove all present Alert-info headers - remove_hf("Alert-Info"); - - if (is_method("INVITE") && ($rP=="TLS" || isflagset(1))) { - append_hf("Alert-info: 1\r\n"); # cisco 7960 - append_hf("Alert-info: Bellcore-dr4\r\n"); # cisco ATA - append_hf("Alert-info: http://foo.bar/x.wav\r\n"); # snom - }; - - # do forwarding - if (!t_relay()) { - sl_reply_error(); - }; - - #end of script - } - - -
- -
- Debug TLS connections - If you want to debug TLS connections, put the following log - statements into your &osips;.cfg. - This will dump all available TLS pseudo variables. - - - Example of TLS logging - -xlog("L_INFO","================= start TLS pseudo variables ===============\n"); -xlog("L_INFO","$$tls_version = '$tls_version'\n"); -xlog("L_INFO","$$tls_description = '$tls_description'\n"); -xlog("L_INFO","$$tls_cipher_info = '$tls_cipher_info'\n"); -xlog("L_INFO","$$tls_cipher_bits = '$tls_cipher_bits'\n"); -xlog("L_INFO","$$tls_peer_subject = '$tls_peer_subject'\n"); -xlog("L_INFO","$$tls_peer_issuer = '$tls_peer_issuer'\n"); -xlog("L_INFO","$$tls_my_subject = '$tls_my_subject'\n"); -xlog("L_INFO","$$tls_my_issuer = '$tls_my_issuer'\n"); -xlog("L_INFO","$$tls_peer_version = '$tls_peer_version'\n"); -xlog("L_INFO","$$tls_my_version = '$tls_my_version'\n"); -xlog("L_INFO","$$tls_peer_serial = '$tls_peer_serial'\n"); -xlog("L_INFO","$$tls_my_serial = '$tls_my_serial'\n"); -xlog("L_INFO","$$tls_peer_subject_cn = '$tls_peer_subject_cn'\n"); -xlog("L_INFO","$$tls_peer_issuer_cn = '$tls_peer_issuer_cn'\n"); -xlog("L_INFO","$$tls_my_subject_cn = '$tls_my_subject_cn'\n"); -xlog("L_INFO","$$tls_my_issuer_cn = '$tls_my_issuer_cn'\n"); -xlog("L_INFO","$$tls_peer_subject_locality = '$tls_peer_subject_locality'\n"); -xlog("L_INFO","$$tls_peer_issuer_locality = '$tls_peer_issuer_locality'\n"); -xlog("L_INFO","$$tls_my_subject_locality = '$tls_my_subject_locality'\n"); -xlog("L_INFO","$$tls_my_issuer_locality = '$tls_my_issuer_locality'\n"); -xlog("L_INFO","$$tls_peer_subject_country = '$tls_peer_subject_country'\n"); -xlog("L_INFO","$$tls_peer_issuer_country = '$tls_peer_issuer_country'\n"); -xlog("L_INFO","$$tls_my_subject_country = '$tls_my_subject_country'\n"); -xlog("L_INFO","$$tls_my_issuer_country = '$tls_my_issuer_country'\n"); -xlog("L_INFO","$$tls_peer_subject_state = '$tls_peer_subject_state'\n"); -xlog("L_INFO","$$tls_peer_issuer_state = '$tls_peer_issuer_state'\n"); -xlog("L_INFO","$$tls_my_subject_state = '$tls_my_subject_state'\n"); -xlog("L_INFO","$$tls_my_issuer_state = '$tls_my_issuer_state'\n"); -xlog("L_INFO","$$tls_peer_subject_organization = '$tls_peer_subject_organization'\n"); -xlog("L_INFO","$$tls_peer_issuer_organization = '$tls_peer_issuer_organization'\n"); -xlog("L_INFO","$$tls_my_subject_organization = '$tls_my_subject_organization'\n"); -xlog("L_INFO","$$tls_my_issuer_organization = '$tls_my_issuer_organization'\n"); -xlog("L_INFO","$$tls_peer_subject_unit = '$tls_peer_subject_unit'\n"); -xlog("L_INFO","$$tls_peer_issuer_unit = '$tls_peer_issuer_unit'\n"); -xlog("L_INFO","$$tls_my_subject_unit = '$tls_my_subject_unit'\n"); -xlog("L_INFO","$$tls_my_issuer_unit = '$tls_my_issuer_unit'\n"); -xlog("L_INFO","$$tls_peer_san_email = '$tls_peer_san_email'\n"); -xlog("L_INFO","$$tls_my_san_email = '$tls_my_san_email'\n"); -xlog("L_INFO","$$tls_peer_san_hostname = '$tls_peer_san_hostname'\n"); -xlog("L_INFO","$$tls_my_san_hostname = '$tls_my_san_hostname'\n"); -xlog("L_INFO","$$tls_peer_san_uri = '$tls_peer_san_uri'\n"); -xlog("L_INFO","$$tls_my_san_uri = '$tls_my_san_uri'\n"); -xlog("L_INFO","$$tls_peer_san_ip = '$tls_peer_san_ip'\n"); -xlog("L_INFO","$$tls_my_san_ip = '$tls_my_san_ip'\n"); -xlog("L_INFO","$$tls_peer_verified = '$tls_peer_verified'\n"); -xlog("L_INFO","$$tls_peer_revoked = '$tls_peer_revoked'\n"); -xlog("L_INFO","$$tls_peer_expired = '$tls_peer_expired'\n"); -xlog("L_INFO","$$tls_peer_selfsigned = '$tls_peer_selfsigned'\n"); -xlog("L_INFO","$$tls_peer_notBefore = '$tls_peer_notBefore'\n"); -xlog("L_INFO","$$tls_peer_notAfter = '$tls_peer_notAfter'\n"); -xlog("L_INFO","================= end TLS pseudo variables ===============\n"); - - - -
- - - -
diff --git a/modules/tls_mgm/doc/tls_mgm_devel.xml b/modules/tls_mgm/doc/tls_mgm_devel.xml deleted file mode 100644 index 5c9b4b8bd25..00000000000 --- a/modules/tls_mgm/doc/tls_mgm_devel.xml +++ /dev/null @@ -1,242 +0,0 @@ - - - - - &develguide; - -
- API Functions -
- find_server_domain - - struct tls_domain *find_server_domain(struct ip_addr *ip, - unsigned short port); - - - Find a TLS server domain with given ip and port - (local listening socket). - -
- -
- find_client_domain - - struct tls_domain *find_client_domain(struct ip_addr *ip, - unsigned short port); - - - Find TLS client domain. - -
- -
- get_handshake_timeout - - int get_handshake_timeout(void); - - - Returns the handshanke timeout. - -
- -
- get_send_timeout - - int get_send_timeout(void); - - - Returns the send timeout. - -
-
-
- TLS_CONFIG - - It contains configuration variables for &osips;'s TLS (timeouts, - file paths, etc). - -
- -
- TLS_INIT - - Initialization related functions and parameters. - -
- ssl context - - extern SSL_CTX *default_client_ctx; - - - The ssl context is a member of the TLS domain strcuture. Thus, every - TLS domain, default and virtual - servers and clients, have its own SSL context. - -
-
- pre_init_tls - - int init_tls(void); - - - Called once to pre_initialize the tls subsystem, from the main(). - Called before parsing the configuration file. - -
-
- init_tls - - int init_tls(void); - - - Called once to initialize the tls subsystem, from the main(). - Called after parsing the configuration file. - -
-
- destroy_tls - - void destroy_tls(void); - - - Called once, just before cleanup. - -
-
- tls_init - - int tls_init(struct socket_info *c); - - - Called once for each tls socket created, from main.c - -
-
- os_malloc, os_realloc, os_free - - Wrapper functions around the shm_* functions. OpenSSL uses - non-shared memory to create its objects, thus it would not - work in &osips;. By creating these wrappers and configuring - OpenSSL to use them instead of its default memory functions, - we have all OpenSSL objects in shared memory, ready to use. - -
-
- -
- TLS_DOMAIN -
- tls_domains - - extern struct tls_domain *tls_default_server_domain; - - - The default TLS server domain. - - - extern struct tls_domain *tls_default_client_domain; - - - The default TLS client domain. - - - extern struct tls_domain *tls_server_domains; - - - List with defined server domains. - - - extern struct tls_domain *tls_client_domains; - - - List with defined client domains. - -
-
- tls_find_server_domain - - struct tls_domain *tls_find_server_domain(struct ip_addr *ip, - unsigned short port); - - - Find a TLS server domain with given ip and port - (local listening socket). - -
-
- tls_find_client_domain - - struct tls_domain *tls_find_client_domain(struct ip_addr *ip, - unsigned short port); - - - Find TLS client domain. - -
-
- tls_find_client_domain_addr - - struct tls_domain *tls_find_client_domain_addr(struct ip_addr *ip, - unsigned short port); - - - Find TLS client domain with given ip and port - (socket of the remote destination). - -
-
- tls_find_client_domain_name - - struct tls_domain *tls_find_client_name(str name); - - - Find TLS client domain with given name. - -
-
- tls_new__domain - - struct tls_domain *tls_new_domain(int type); - - - Creates new TLS: allocate memory, set the type and initialize members - -
-
- tls_new_server_domain - - int tls_new_server_domain(struct ip_addr *ip, unsigned short port); - - - Creates and adds to the list of TLS server domains a new domain. - -
-
- tls_new_client_domain - - int tls_new_client_domain(struct ip_addr *ip, unsigned short port); - - - Creates and adds to the list of TLS client domains a new socket based domain. - -
-
- tls_new_client_domain_name - - int tls_new_client_domain_name(char *s, int len); - - - Creates and adds to the list of TLS client domains a new name based domain. - -
-
- tls_free_domains - - void tls_free_domains(void); - - - Cleans up the entire domain lists. - -
-
- -
diff --git a/modules/tls_mgm/tls_domain.c b/modules/tls_mgm/tls_domain.c index 1dd66a9f9fb..f47837f09e7 100644 --- a/modules/tls_mgm/tls_domain.c +++ b/modules/tls_mgm/tls_domain.c @@ -33,6 +33,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/* needed to expose FNM_CASEFOLD from on glibc */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include "../../mem/mem.h" #include "../../lib/csv.h" #include "../../redact_pii.h" @@ -404,7 +409,9 @@ tls_find_domain_by_filters(struct ip_addr *ip, unsigned short port, for (i = 0; i < dom_array->size; i++) { memcpy(fnm_s, domain_filter->s, domain_filter->len); fnm_s[domain_filter->len] = 0; - if (!fnmatch(dom_array->arr[i].hostname->s.s, fnm_s, 0)) { + /* SNI hostnames are DNS names, so match case-insensitively + * (RFC 6066 / RFC 4343) */ + if (!fnmatch(dom_array->arr[i].hostname->s.s, fnm_s, FNM_CASEFOLD)) { ref_tls_dom(dom_array->arr[i].dom_link); if (dom_lock) lock_stop_read(dom_lock); diff --git a/modules/tls_mgm/tls_helper.h b/modules/tls_mgm/tls_helper.h index adfecd557d1..184c962bab2 100644 --- a/modules/tls_mgm/tls_helper.h +++ b/modules/tls_mgm/tls_helper.h @@ -44,7 +44,12 @@ #define DOM_FLAG_CLI (1<<1) #define DOM_FLAG_DB (1<<2) +#define TLS_VERIFY_NONE 0 +#define TLS_VERIFY_PEER (1<<0) +#define TLS_VERIFY_FAIL_IF_NO_PEER_CERT (1<<1) + #include "tls_config_helper.h" +#include "../../dprint.h" #include "../../locking.h" enum { @@ -100,4 +105,87 @@ struct tls_domain { struct tls_domain *next; }; +static inline int get_ssl_ctx_verify_mode(struct tls_domain *d) +{ + int verify_mode; + + /* Set verification procedure + * The verification can be made null with SSL_VERIFY_NONE, or + * at least easier with SSL_VERIFY_CLIENT_ONCE instead of + * SSL_VERIFY_FAIL_IF_NO_PEER_CERT. + * For extra control, instead of 0, we can specify a callback function: + * int (*verify_callback)(int, X509_STORE_CTX *) + * Also, depth 2 may be not enough in some scenarios ... though no need + * to increase it much further */ + + if (d->flags & DOM_FLAG_SRV) { + /* Server mode: + * SSL_VERIFY_NONE + * the server will not send a client certificate request to the + * client, so the client will not send a certificate. + * SSL_VERIFY_PEER + * the server sends a client certificate request to the client. + * The certificate returned (if any) is checked. If the verification + * process fails, the TLS/SSL handshake is immediately terminated + * with an alert message containing the reason for the verification + * failure. The behaviour can be controlled by the additional + * SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags. + * SSL_VERIFY_FAIL_IF_NO_PEER_CERT + * if the client did not return a certificate, the TLS/SSL handshake + * is immediately terminated with a ``handshake failure'' alert. + * This flag must be used together with SSL_VERIFY_PEER. + * SSL_VERIFY_CLIENT_ONCE + * only request a client certificate on the initial TLS/SSL + * handshake. Do not ask for a client certificate again in case of + * a renegotiation. This flag must be used together with + * SSL_VERIFY_PEER. + */ + + if (d->verify_cert) { + verify_mode = TLS_VERIFY_PEER; + if (d->require_client_cert) { + LM_INFO("client verification activated. Client " + "certificates are mandatory.\n"); + verify_mode |= TLS_VERIFY_FAIL_IF_NO_PEER_CERT; + } else { + LM_INFO("client verification activated. Client " + "certificates are NOT mandatory.\n"); + } + } else { + verify_mode = TLS_VERIFY_NONE; + LM_INFO("client verification NOT activated. Weaker security.\n"); + } + } else { + /* Client mode: + * SSL_VERIFY_NONE + * if not using an anonymous cipher (by default disabled), the + * server will send a certificate which will be checked. The result + * of the certificate verification process can be checked after the + * TLS/SSL handshake using the SSL_get_verify_result(3) function. + * The handshake will be continued regardless of the verification + * result. + * SSL_VERIFY_PEER + * the server certificate is verified. If the verification process + * fails, the TLS/SSL handshake is immediately terminated with an + * alert message containing the reason for the verification failure. + * If no server certificate is sent, because an anonymous cipher is + * used, SSL_VERIFY_PEER is ignored. + * SSL_VERIFY_FAIL_IF_NO_PEER_CERT + * ignored + * SSL_VERIFY_CLIENT_ONCE + * ignored + */ + + if (d->verify_cert) { + verify_mode = TLS_VERIFY_PEER; + LM_INFO("server verification activated.\n"); + } else { + verify_mode = TLS_VERIFY_NONE; + LM_INFO("server verification NOT activated. Weaker security.\n"); + } + } + + return verify_mode; +} + #endif /* TLS_HELPER_H */ diff --git a/modules/tls_mgm/tls_mgm.c b/modules/tls_mgm/tls_mgm.c index 29b1241bb62..4540263ae35 100644 --- a/modules/tls_mgm/tls_mgm.c +++ b/modules/tls_mgm/tls_mgm.c @@ -642,11 +642,21 @@ static int init_tls_dom(struct tls_domain *d) } if (!d->cert.s) { - init_flags |= TLS_DOM_CERT_FILE_FL; - LM_NOTICE("no certificate for tls domain '%.*s' defined, using default '%s'\n", - d->name.len, ZSW(d->name.s), tls_cert_file); - d->cert.s = tls_cert_file; - d->cert.len = len(tls_cert_file); + /* Client domains can operate without a certificate (RFC 8446 4.4.2.4, + * RFC 5246 7.4.6) - an empty certificate message will be sent if the + * server requests one. Server domains require a certificate. */ + if (d->flags & DOM_FLAG_SRV) { + init_flags |= TLS_DOM_CERT_FILE_FL; + LM_NOTICE("no certificate for tls server domain '%.*s' defined, " + "using default '%s'\n", + d->name.len, ZSW(d->name.s), tls_cert_file); + d->cert.s = tls_cert_file; + d->cert.len = len(tls_cert_file); + } else { + LM_INFO("no certificate for tls client domain '%.*s', " + "will not send client certificate\n", + d->name.len, ZSW(d->name.s)); + } } if (!d->ca.s) { @@ -722,6 +732,15 @@ static int init_tls_domains(struct tls_domain **dom) prev = NULL; while (d) { if (!d->pkey.s) { + /* Client domains without a certificate don't need a private key */ + if (!d->cert.s && (d->flags & DOM_FLAG_CLI)) { + LM_DBG("no private key needed for tls client domain '%.*s' " + "(no certificate configured)\n", + d->name.len, ZSW(d->name.s)); + prev = d; + d = d->next; + continue; + } LM_NOTICE("no private key for tls domain '%.*s' defined, using default '%s'\n", d->name.len, ZSW(d->name.s), tls_pkey_file); d->pkey.s = tls_pkey_file; diff --git a/modules/tls_openssl/README b/modules/tls_openssl/README deleted file mode 100644 index 2b136f908f8..00000000000 --- a/modules/tls_openssl/README +++ /dev/null @@ -1,106 +0,0 @@ -tls_openssl Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements TLS operations using the openSSL - libarary. It provides the primitives required by the tls_mgm - module in order to expose a higher-level API used by TLS-based - protocol modules like proto_tls or proto_wss etc. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.2. External Libraries or Applications - - OpenSIPS TLS v1.0 support requires the following packages: - * openssl or libssl >= 0.9.6 - * openssl-dev or libssl-dev - - OpenSIPS TLS v1.1/1.2 support requires the following packages: - * openssl or libssl >= 1.0.1e - * openssl-dev or libssl-dev - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 25 5 2195 39 - 2. James Stanley 4 2 13 8 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 3 3 - 4. Maksym Sobolyev (@sobomax) 3 1 1 1 - 5. Your Name 2 1 0 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Your Name Jul 2024 - Jul 2024 - 2. James Stanley Apr 2023 - Feb 2024 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) May 2023 - May 2023 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2021 - Oct 2021 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2021 www.opensips-solutions.com diff --git a/modules/tls_openssl/README.md b/modules/tls_openssl/README.md new file mode 100644 index 00000000000..a58c1d4a18d --- /dev/null +++ b/modules/tls_openssl/README.md @@ -0,0 +1,54 @@ +--- +title: "tls_openssl Module" +description: "This module implements TLS operations using the [openSSL](https://www.openssl.org/) libarary." +--- + +## Admin Guide + + +### Overview + + +This module implements TLS operations using the +[openSSL](https://www.openssl.org/) libarary. It provides the primitives +required by the *tls_mgm* module in order to expose a +higher-level API used by TLS-based protocol modules like +*proto_tls* or *proto_wss* etc. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +OpenSIPS TLS v1.0 support requires the following packages: + + +- *openssl* or +*libssl* >= 0.9.6 +- *openssl-dev* or +*libssl-dev* + + +OpenSIPS TLS v1.1/1.2 support requires the following packages: + + +- *openssl* or +*libssl* >= 1.0.1e +- *openssl-dev* or +*libssl-dev* + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tls_openssl/doc/contributors.xml b/modules/tls_openssl/doc/contributors.xml deleted file mode 100644 index c9abafb0ba6..00000000000 --- a/modules/tls_openssl/doc/contributors.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 25 - 5 - 2195 - 39 - - - 2. - James Stanley - 4 - 2 - 13 - 8 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 3 - 3 - - - 4. - Maksym Sobolyev (@sobomax) - 3 - 1 - 1 - 1 - - - 5. - Your Name - 2 - 1 - 0 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Your Name - Jul 2024 - Jul 2024 - - - 2. - James Stanley - Apr 2023 - Feb 2024 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2023 - May 2023 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2021 - Oct 2021 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/tls_openssl/doc/tls_openssl.xml b/modules/tls_openssl/doc/tls_openssl.xml deleted file mode 100644 index 67fccd7462c..00000000000 --- a/modules/tls_openssl/doc/tls_openssl.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - -%docentities; - -]> - - - - tls_openssl Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2021 &osipssol; - - diff --git a/modules/tls_openssl/doc/tls_openssl_admin.xml b/modules/tls_openssl/doc/tls_openssl_admin.xml deleted file mode 100644 index d9f629ab215..00000000000 --- a/modules/tls_openssl/doc/tls_openssl_admin.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements TLS operations using the - - openSSL libarary. It provides the primitives - required by the tls_mgm module in order to expose a - higher-level API used by TLS-based protocol modules like - proto_tls or proto_wss etc. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - &osips; TLS v1.0 support requires the following packages: - - - openssl or - libssl >= 0.9.6 - - - - openssl-dev or - libssl-dev - - - - - - &osips; TLS v1.1/1.2 support requires the following packages: - - - openssl or - libssl >= 1.0.1e - - - - openssl-dev or - libssl-dev - - - - -
-
- -
diff --git a/modules/tls_openssl/openssl.c b/modules/tls_openssl/openssl.c index 522b6825852..e8aa979e5db 100644 --- a/modules/tls_openssl/openssl.c +++ b/modules/tls_openssl/openssl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "../../dprint.h" #include "../../mem/shm_mem.h" @@ -162,6 +163,30 @@ static void openssl_on_exit(int status, void *param) } #endif +#if OPENSSL_VERSION_NUMBER >= 0x10100000L +/* + * Clean up OpenSSL per-thread state (ERR_STATE, DRBG, etc.) in the parent + * process before fork(). CRYPTO_set_mem_functions() routes all OpenSSL + * allocations to shared memory, but per-thread structures use thread-local + * storage pointers that are inherited across fork(). Without this cleanup, + * child processes inherit a stale pointer to the parent's per-thread state + * in shared memory; if the parent frees or re-creates that state, the + * child's next OpenSSL call triggers a double-free (detected by + * QM_MALLOC_DBG as SIGABRT). + * + * After OPENSSL_thread_stop(), the thread-local pointer is NULL. Both + * parent and child lazily allocate fresh per-thread state on the next + * OpenSSL call. + * + * This complements the on_exit(_exit) workaround above, which prevents the + * same class of double-free at process *exit* time. + */ +static void openssl_pre_fork(void) +{ + OPENSSL_thread_stop(); +} +#endif + #if (OPENSSL_VERSION_NUMBER < 0x10100000L) static int check_for_krb(void) { @@ -297,6 +322,13 @@ static int mod_init(void) on_exit(openssl_on_exit, NULL); #endif +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + if (pthread_atfork(openssl_pre_fork, NULL, NULL) != 0) { + LM_ERR("failed to register atfork handler for OpenSSL cleanup\n"); + return -1; + } +#endif + return 0; } diff --git a/modules/tls_openssl/openssl_config.c b/modules/tls_openssl/openssl_config.c index a27df6c2fed..9b2e80beba5 100644 --- a/modules/tls_openssl/openssl_config.c +++ b/modules/tls_openssl/openssl_config.c @@ -169,82 +169,17 @@ int tls_get_method(str *method_str, return 0; } -static void get_ssl_ctx_verify_mode(struct tls_domain *d, int *verify_mode) +static int get_openssl_verify_mode(struct tls_domain *d) { - /* Set verification procedure - * The verification can be made null with SSL_VERIFY_NONE, or - * at least easier with SSL_VERIFY_CLIENT_ONCE instead of - * SSL_VERIFY_FAIL_IF_NO_PEER_CERT. - * For extra control, instead of 0, we can specify a callback function: - * int (*verify_callback)(int, X509_STORE_CTX *) - * Also, depth 2 may be not enough in some scenarios ... though no need - * to increase it much further */ - - if (d->flags & DOM_FLAG_SRV) { - /* Server mode: - * SSL_VERIFY_NONE - * the server will not send a client certificate request to the - * client, so the client will not send a certificate. - * SSL_VERIFY_PEER - * the server sends a client certificate request to the client. - * The certificate returned (if any) is checked. If the verification - * process fails, the TLS/SSL handshake is immediately terminated - * with an alert message containing the reason for the verification - * failure. The behaviour can be controlled by the additional - * SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE flags. - * SSL_VERIFY_FAIL_IF_NO_PEER_CERT - * if the client did not return a certificate, the TLS/SSL handshake - * is immediately terminated with a ``handshake failure'' alert. - * This flag must be used together with SSL_VERIFY_PEER. - * SSL_VERIFY_CLIENT_ONCE - * only request a client certificate on the initial TLS/SSL - * handshake. Do not ask for a client certificate again in case of - * a renegotiation. This flag must be used together with - * SSL_VERIFY_PEER. - */ + int tls_verify_mode = get_ssl_ctx_verify_mode(d); + int verify_mode = SSL_VERIFY_NONE; - if( d->verify_cert ) { - *verify_mode = SSL_VERIFY_PEER; - if( d->require_client_cert ) { - LM_INFO("client verification activated. Client " - "certificates are mandatory.\n"); - *verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - } else - LM_INFO("client verification activated. Client " - "certificates are NOT mandatory.\n"); - } else { - *verify_mode = SSL_VERIFY_NONE; - LM_INFO("client verification NOT activated. Weaker security.\n"); - } - } else { - /* Client mode: - * SSL_VERIFY_NONE - * if not using an anonymous cipher (by default disabled), the - * server will send a certificate which will be checked. The result - * of the certificate verification process can be checked after the - * TLS/SSL handshake using the SSL_get_verify_result(3) function. - * The handshake will be continued regardless of the verification - * result. - * SSL_VERIFY_PEER - * the server certificate is verified. If the verification process - * fails, the TLS/SSL handshake is immediately terminated with an - * alert message containing the reason for the verification failure. - * If no server certificate is sent, because an anonymous cipher is - * used, SSL_VERIFY_PEER is ignored. - * SSL_VERIFY_FAIL_IF_NO_PEER_CERT - * ignored - * SSL_VERIFY_CLIENT_ONCE - * ignored - */ + if (tls_verify_mode & TLS_VERIFY_PEER) + verify_mode |= SSL_VERIFY_PEER; + if (tls_verify_mode & TLS_VERIFY_FAIL_IF_NO_PEER_CERT) + verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - if( d->verify_cert ) { - *verify_mode = SSL_VERIFY_PEER; - LM_INFO("server verification activated.\n"); - } else { - *verify_mode = SSL_VERIFY_NONE; - LM_INFO("server verification NOT activated. Weaker security.\n"); - } - } + return verify_mode; } /* This callback is called during each verification process, @@ -328,6 +263,8 @@ int openssl_reg_sni_cb(tls_sni_cb_f cb) int openssl_switch_ssl_ctx(struct tls_domain *dom, void *ssl_ctx) { + int verify_mode = 0; + SSL_set_SSL_CTX((SSL *)ssl_ctx, ((void**)dom->ctx)[process_no]); if (!SSL_set_ex_data((SSL *)ssl_ctx, SSL_EX_DOM_IDX, dom)) { @@ -335,6 +272,9 @@ int openssl_switch_ssl_ctx(struct tls_domain *dom, void *ssl_ctx) return -1; } + verify_mode = get_openssl_verify_mode(dom); + SSL_set_verify((SSL *)ssl_ctx, verify_mode, NULL); /* NULL = use the previously defined callback */ + return 0; } @@ -741,7 +681,7 @@ int openssl_init_tls_dom(struct tls_domain *d, int init_flags) &d->method_max) < 0) return -1; - get_ssl_ctx_verify_mode(d, &verify_mode); + verify_mode = get_openssl_verify_mode(d); tcp_procs = count_child_processes(); @@ -832,14 +772,16 @@ int openssl_init_tls_dom(struct tls_domain *d, int init_flags) } /* - * load certificate + * load certificate (optional for client domains per RFC 8446 4.4.2.4) */ - if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { - if (load_certificate(((void**)d->ctx)[i], d->cert.s) < 0) - return -1; - } else - if (load_certificate_db(((void**)d->ctx)[i], &d->cert) < 0) - return -1; + if (d->cert.s) { + if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { + if (load_certificate(((void**)d->ctx)[i], d->cert.s) < 0) + return -1; + } else + if (load_certificate_db(((void**)d->ctx)[i], &d->cert) < 0) + return -1; + } /** * load crl from directory diff --git a/modules/tls_openssl/openssl_conn_ops.c b/modules/tls_openssl/openssl_conn_ops.c index c39d8eb8e2a..79a4f06f6db 100644 --- a/modules/tls_openssl/openssl_conn_ops.c +++ b/modules/tls_openssl/openssl_conn_ops.c @@ -341,8 +341,10 @@ void openssl_tls_conn_clean(struct tcp_connection *c, struct tls_domain **tls_do if (c->extra_data) { d = SSL_get_ex_data(c->extra_data, SSL_EX_DOM_IDX); - openssl_tls_update_fd(c,c->s); - openssl_tls_conn_shutdown(c); + if (c->s != -1) { + openssl_tls_update_fd(c, c->s); + openssl_tls_conn_shutdown(c); + } SSL_free((SSL *) c->extra_data); c->extra_data = 0; } diff --git a/modules/tls_wolfssl/README b/modules/tls_wolfssl/README deleted file mode 100644 index 99b642c346a..00000000000 --- a/modules/tls_wolfssl/README +++ /dev/null @@ -1,146 +0,0 @@ -tls_wolfssl Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. Compilation - 1.2.2. OpenSIPS Modules - 1.2.3. External Libraries or Applications - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - -Chapter 1. Admin Guide - -1.1. Overview - - This module implements TLS operations using the wolfSSL - libarary. It provides the primitives required by the tls_mgm - module in order to expose a higher-level API used by TLS-based - protocol modules like proto_tls or proto_wss. - - The wolfSSL library is statically-linked and bundled with this - module so no installation or external dependency is required. - -1.2. Dependencies - -1.2.1. Compilation - - The following packages must be installed before compiling this - module: - * autoconf. - * automake. - * libtool. - -1.2.2. OpenSIPS Modules - - The following modules must be loaded before this module: - * None. - -1.2.3. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -Chapter 2. Frequently Asked Questions - - 2.1. - - Why do I get the following error when compiling the module? - make[1]: Entering directory '/usr/local/src/opensips/modules/tls_wol -fssl' - /bin/sh: 3: ./autogen.sh: not found - env: './configure': No such file or directory - make[1]: *** [Makefile:15: lib/lib/libwolfssl.a] Error 127 - make[1]: Leaving directory '/usr/local/src/opensips/modules/tls_wolf -ssl' - make: *** [Makefile:197: modules] Error 2 - - If you obtained the OpenSIPS sources by cloning the repository - from Github, without using the --recursive option for the git - clone command, you did not properly fetch the wolfSSL library - code, which is included as a git submodule pointing to the - official wolfSSL repository. - - In order to fetch the wolfSSL library code you can run: - git submodule update --init - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 29 22 553 114 - 2. Razvan Crainea (@razvancrainea) 12 8 217 75 - 3. Maksym Sobolyev (@sobomax) 4 2 2 2 - 4. James Stanley 3 1 6 1 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 3 3 - 6. Liviu Chircu (@liviuchircu) 3 1 2 2 - 7. Bence Szigeti 3 1 1 1 - 8. Alexey Vasilyev (@vasilevalex) 2 1 11 0 - 9. vladpaiu 2 1 8 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. vladpaiu Jun 2025 - Jun 2025 - 2. Razvan Crainea (@razvancrainea) Aug 2023 - Oct 2024 - 3. James Stanley Feb 2024 - Feb 2024 - 4. Liviu Chircu (@liviuchircu) Oct 2023 - Oct 2023 - 5. Bence Szigeti Oct 2023 - Oct 2023 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) May 2023 - May 2023 - 7. Vlad Patrascu (@rvlad-patrascu) May 2021 - Mar 2023 - 8. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 9. Alexey Vasilyev (@vasilevalex) Jan 2022 - Jan 2022 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2021 www.opensips-solutions.com diff --git a/modules/tls_wolfssl/README.md b/modules/tls_wolfssl/README.md new file mode 100644 index 00000000000..146ceb6fb58 --- /dev/null +++ b/modules/tls_wolfssl/README.md @@ -0,0 +1,77 @@ +--- +title: "tls_wolfssl Module" +description: "This module implements TLS operations using the [wolfSSL](https://www.wolfssl.com/) libarary." +--- + +## Admin Guide + + +### Overview + + +This module implements TLS operations using the +[wolfSSL](https://www.wolfssl.com/) libarary. It provides the primitives +required by the *tls_mgm* module in order to expose a +higher-level API used by TLS-based protocol modules like +*proto_tls* or *proto_wss*. + + +The *wolfSSL* library is statically-linked and bundled +with this module so no installation or external dependency is required. + + +### Dependencies + + +#### Compilation + + +The following packages must be installed before compiling this module: + + +- *autoconf*. +- *automake*. +- *libtool*. + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +## Frequently Asked Questions + + +**Q: Why do I get the following error when compiling the module?** + + +If you obtained the OpenSIPS sources by cloning the repository from Github, +without using the *--recursive* option for the +*git clone* command, you did not properly fetch the +*wolfSSL* library code, which is included as a git submodule +pointing to the official *wolfSSL* repository. + +In order to fetch the *wolfSSL* library code you can run: + +```bash +git submodule update --init +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tls_wolfssl/doc/contributors.xml b/modules/tls_wolfssl/doc/contributors.xml deleted file mode 100644 index 03350f4fc17..00000000000 --- a/modules/tls_wolfssl/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 29 - 22 - 553 - 114 - - - 2. - Razvan Crainea (@razvancrainea) - 12 - 8 - 217 - 75 - - - 3. - Maksym Sobolyev (@sobomax) - 4 - 2 - 2 - 2 - - - 4. - James Stanley - 3 - 1 - 6 - 1 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 3 - 3 - - - 6. - Liviu Chircu (@liviuchircu) - 3 - 1 - 2 - 2 - - - 7. - Bence Szigeti - 3 - 1 - 1 - 1 - - - 8. - Alexey Vasilyev (@vasilevalex) - 2 - 1 - 11 - 0 - - - 9. - vladpaiu - 2 - 1 - 8 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - vladpaiu - Jun 2025 - Jun 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2023 - Oct 2024 - - - 3. - James Stanley - Feb 2024 - Feb 2024 - - - 4. - Liviu Chircu (@liviuchircu) - Oct 2023 - Oct 2023 - - - 5. - Bence Szigeti - Oct 2023 - Oct 2023 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - May 2023 - May 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2021 - Mar 2023 - - - 8. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 9. - Alexey Vasilyev (@vasilevalex) - Jan 2022 - Jan 2022 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/tls_wolfssl/doc/tls_wolfssl.xml b/modules/tls_wolfssl/doc/tls_wolfssl.xml deleted file mode 100644 index 0ea490f7179..00000000000 --- a/modules/tls_wolfssl/doc/tls_wolfssl.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - tls_wolfssl Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2021 &osipssol; - - diff --git a/modules/tls_wolfssl/doc/tls_wolfssl_admin.xml b/modules/tls_wolfssl/doc/tls_wolfssl_admin.xml deleted file mode 100644 index 84b207908ff..00000000000 --- a/modules/tls_wolfssl/doc/tls_wolfssl_admin.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - - &adminguide; - -
- Overview - - This module implements TLS operations using the - - wolfSSL libarary. It provides the primitives - required by the tls_mgm module in order to expose a - higher-level API used by TLS-based protocol modules like - proto_tls or proto_wss. - - - The wolfSSL library is statically-linked and bundled - with this module so no installation or external dependency is required. - -
- -
- Dependencies -
- Compilation - - The following packages must be installed before compiling this module: - - - - autoconf. - - - - - automake. - - - - - libtool. - - - - -
- -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
diff --git a/modules/tls_wolfssl/doc/tls_wolfssl_faq.xml b/modules/tls_wolfssl/doc/tls_wolfssl_faq.xml deleted file mode 100644 index 757eb6fa778..00000000000 --- a/modules/tls_wolfssl/doc/tls_wolfssl_faq.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - &faqguide; - - - - Why do I get the following error when compiling the module? - - make[1]: Entering directory '/usr/local/src/opensips/modules/tls_wolfssl' - /bin/sh: 3: ./autogen.sh: not found - env: './configure': No such file or directory - make[1]: *** [Makefile:15: lib/lib/libwolfssl.a] Error 127 - make[1]: Leaving directory '/usr/local/src/opensips/modules/tls_wolfssl' - make: *** [Makefile:197: modules] Error 2 - - - - - If you obtained the OpenSIPS sources by cloning the repository from Github, - without using the --recursive option for the - git clone command, you did not properly fetch the - wolfSSL library code, which is included as a git submodule - pointing to the official wolfSSL repository. - - - In order to fetch the wolfSSL library code you can run: - - git submodule update --init - - - - - - - \ No newline at end of file diff --git a/modules/tls_wolfssl/wolfssl.c b/modules/tls_wolfssl/wolfssl.c index 242db15eaf6..6991757bad7 100644 --- a/modules/tls_wolfssl/wolfssl.c +++ b/modules/tls_wolfssl/wolfssl.c @@ -22,6 +22,8 @@ #include #include +#include +#include #include #include @@ -139,6 +141,125 @@ static void _wolfssl_show_ciphers(void) } } +#if defined(F_MALLOC) || defined(Q_MALLOC) +#if defined(__CPU_sparc64) || defined(__CPU_sparc) || \ + UINTPTR_MAX > 0xffffffffUL +#define OSS_SHM_ALIGNMENT 8 +#else +#define OSS_SHM_ALIGNMENT 4 +#endif +#else +#define OSS_SHM_ALIGNMENT 8 +#endif + +#if defined(WOLFSSL_GENERAL_ALIGNMENT) && \ + WOLFSSL_GENERAL_ALIGNMENT > OSS_SHM_ALIGNMENT +#define OSS_ALIGN WOLFSSL_GENERAL_ALIGNMENT +#elif defined(WOLFSSL_USE_ALIGN) && 16 > OSS_SHM_ALIGNMENT +#define OSS_ALIGN 16 +#endif + +#ifdef OSS_ALIGN +/* + * wolfSSL may use aligned instructions requiring stricter alignment than + * shm_malloc() provides. Over-allocate and return an aligned pointer, + * stashing the original shm pointer in the slot before it. + * + * [pad 0..15] [void *orig] [aligned user data ...] + * ^ returned to caller + */ +#define OSS_PAD (sizeof(void *) + OSS_ALIGN - 1) + +/* Return an OSS_ALIGN-aligned pointer, storing raw just before it */ +static inline void *oss_aligned(void *raw) +{ + uintptr_t a = ((uintptr_t)raw + OSS_PAD) & ~(uintptr_t)(OSS_ALIGN - 1); + ((void **)a)[-1] = raw; + return (void *)a; +} + +/* Re-align after shm_realloc. off is the old raw-to-aligned offset. + * memmove before writing back-pointer: the slot may overlap old data. */ +static inline void *oss_realigned(void *new_raw, size_t off, size_t size) +{ + uintptr_t a; + + if (!new_raw) + return NULL; + + a = ((uintptr_t)new_raw + OSS_PAD) & ~(uintptr_t)(OSS_ALIGN - 1); + + if (a != (uintptr_t)new_raw + off) + memmove((void *)a, (char *)new_raw + off, size); + + ((void **)a)[-1] = new_raw; + return (void *)a; +} + +#ifndef WOLFSSL_DEBUG_MEMORY +static void *oss_malloc(size_t size) +{ + void *raw = shm_malloc(size + OSS_PAD); + return raw ? oss_aligned(raw) : NULL; +} + +static void oss_free(void *ptr) +{ + if (ptr) + shm_free(((void **)ptr)[-1]); +} + +static void *oss_realloc(void *ptr, size_t size) +{ + void *raw; + size_t off; + + if (!size) { + oss_free(ptr); + return NULL; + } + + if (!ptr) + return oss_malloc(size); + + raw = ((void **)ptr)[-1]; + off = (char *)ptr - (char *)raw; + return oss_realigned(shm_realloc(raw, size + OSS_PAD), off, size); +} +#else +static void *oss_malloc(size_t size, const char* func, unsigned int line) +{ + void *raw = shm_malloc_func(size + OSS_PAD, "wolfssl.lib", func, line); + return raw ? oss_aligned(raw) : NULL; +} + +static void oss_free(void *ptr, const char* func, unsigned int line) +{ + if (ptr) + shm_free_func(((void **)ptr)[-1], "wolfssl.lib", func, line); +} + +static void *oss_realloc(void *ptr, size_t size, const char* func, unsigned int line) +{ + void *raw; + size_t off; + + if (!size) { + oss_free(ptr, func, line); + return NULL; + } + + if (!ptr) + return oss_malloc(size, func, line); + + raw = ((void **)ptr)[-1]; + off = (char *)ptr - (char *)raw; + return oss_realigned( + shm_realloc_func(raw, size + OSS_PAD, "wolfssl.lib", func, line), + off, size); +} +#endif +#else #ifndef WOLFSSL_DEBUG_MEMORY static void *oss_malloc(size_t size) { @@ -170,6 +291,7 @@ static void *oss_realloc(void *ptr, size_t size, const char* func, unsigned int return shm_realloc_func(ptr, size, "wolfssl.lib", func, line); } #endif +#endif #ifdef __WOLFSSL_ON_EXIT static void _wolfssl_on_exit(int status, void *param) diff --git a/modules/tls_wolfssl/wolfssl_config.c b/modules/tls_wolfssl/wolfssl_config.c index 2ac17e3b1dd..250c6aa33e1 100644 --- a/modules/tls_wolfssl/wolfssl_config.c +++ b/modules/tls_wolfssl/wolfssl_config.c @@ -119,6 +119,19 @@ int tls_get_method(str *method_str, return 0; } +static int get_wolfssl_verify_mode(struct tls_domain *d) +{ + int tls_verify_mode = get_ssl_ctx_verify_mode(d); + int verify_mode = SSL_VERIFY_NONE; + + if (tls_verify_mode & TLS_VERIFY_PEER) + verify_mode |= SSL_VERIFY_PEER; + if (tls_verify_mode & TLS_VERIFY_FAIL_IF_NO_PEER_CERT) + verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + + return verify_mode; +} + static int verify_callback(int pre_verify_ok, WOLFSSL_X509_STORE_CTX *ctx) { char buf[256]; WOLFSSL_X509 *cert; @@ -195,6 +208,8 @@ int _wolfssl_reg_sni_cb(tls_sni_cb_f cb) int _wolfssl_switch_ssl_ctx(struct tls_domain *dom, void *ssl_ctx) { + int verify_mode = 0; + wolfSSL_set_SSL_CTX((WOLFSSL *)ssl_ctx, dom->ctx); if (!wolfSSL_set_ex_data((WOLFSSL *)ssl_ctx, SSL_EX_DOM_IDX, dom)) { @@ -202,6 +217,9 @@ int _wolfssl_switch_ssl_ctx(struct tls_domain *dom, void *ssl_ctx) return -1; } + verify_mode = get_wolfssl_verify_mode(dom); + wolfSSL_set_verify((WOLFSSL *)ssl_ctx, verify_mode, verify_callback); + return 0; } @@ -485,30 +503,7 @@ int _wolfssl_init_tls_dom(struct tls_domain *d, int init_flags) wolfSSL_CTX_set_servername_arg(d->ctx, d); } - if (d->flags & DOM_FLAG_SRV) { - if (d->verify_cert ) { - verify_mode = SSL_VERIFY_PEER; - if (d->require_client_cert ) { - LM_INFO("client verification activated. Client " - "certificates are mandatory.\n"); - verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - } else { - LM_INFO("client verification activated. Client " - "certificates are NOT mandatory.\n"); - } - } else { - verify_mode = SSL_VERIFY_NONE; - LM_INFO("client verification NOT activated. Weaker security.\n"); - } - } else { - if (d->verify_cert ) { - verify_mode = SSL_VERIFY_PEER; - LM_INFO("server verification activated.\n"); - } else { - verify_mode = SSL_VERIFY_NONE; - LM_INFO("server verification NOT activated. Weaker security.\n"); - } - } + verify_mode = get_wolfssl_verify_mode(d); wolfSSL_CTX_set_verify(d->ctx, verify_mode, verify_callback); wolfSSL_CTX_set_verify_depth(d->ctx, VERIFY_DEPTH_S); @@ -533,12 +528,15 @@ int _wolfssl_init_tls_dom(struct tls_domain *d, int init_flags) goto end; } - if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { - if (load_certificate(d->ctx, d->cert.s) < 0) - goto end; - } else { - if (load_certificate_db(d->ctx, &d->cert) < 0) - goto end; + /* load certificate (optional for client domains per RFC 8446 4.4.2.4) */ + if (d->cert.s) { + if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { + if (load_certificate(d->ctx, d->cert.s) < 0) + goto end; + } else { + if (load_certificate_db(d->ctx, &d->cert) < 0) + goto end; + } } if (d->crl_directory && load_crl(d->ctx, d->crl_directory, diff --git a/modules/tm/README b/modules/tm/README deleted file mode 100644 index 4861dc0fe2a..00000000000 --- a/modules/tm/README +++ /dev/null @@ -1,2006 +0,0 @@ -tm Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Per-Branch flags - 1.1.2. Timeout-Based Failover - 1.1.3. DNS Failover - 1.1.4. Anycast Scenario - 1.1.5. Usage Scope - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. fr_timeout (integer) - 1.3.2. fr_inv_timeout (integer) - 1.3.3. wt_timer (integer) - 1.3.4. delete_timer (integer) - 1.3.5. T1_timer (integer) - 1.3.6. T2_timer (integer) - 1.3.7. ruri_matching (integer) - 1.3.8. via1_matching (integer) - 1.3.9. unix_tx_timeout (integer) - 1.3.10. restart_fr_on_each_reply (integer) - 1.3.11. tw_append (string) - 1.3.12. pass_provisional_replies (integer) - 1.3.13. syn_branch (integer) - 1.3.14. onreply_avp_mode (integer) - 1.3.15. disable_6xx_block (integer) - 1.3.16. enable_stats (integer) - 1.3.17. minor_branch_flag (string/integer) - 1.3.18. timer_partitions (integer) - 1.3.19. auto_100trying (integer) - 1.3.20. tm_replication_cluster (integer) - 1.3.21. cluster_param (string) - 1.3.22. cluster_auto_cancel (boolean) - 1.3.23. local_request_route (string) - 1.3.24. local_reply_route (string) - - 1.4. Exported Functions - - 1.4.1. t_relay([flags],[outbound_proxy]) - 1.4.2. t_reply(code, reason_phrase) - 1.4.3. t_reply_with_body(code, reason_phrase, body) - 1.4.4. t_newtran() - 1.4.5. t_check_trans() - 1.4.6. t_check_status(re) - 1.4.7. t_local_replied(reply) - 1.4.8. t_was_cancelled() - 1.4.9. t_cancel_branch([flags]) - 1.4.10. t_new_request( method, RURI, from, to [, - body[, ctx]]) - - 1.4.11. t_on_failure(failure_route) - 1.4.12. t_on_reply(reply_route) - 1.4.13. t_on_branch(branch_route) - 1.4.14. t_inject_branches(source[,flags]) - 1.4.15. t_wait_for_new_branches([branches]) - 1.4.16. t_wait_no_more_branches() - 1.4.17. t_add_hdrs("sip_hdrs") - 1.4.18. t_add_cancel_reason("Reason_hdr") - 1.4.19. t_replicate(URI,[flags]) - 1.4.20. t_write_req(info,fifo) - t_write_unix(info,sock) - - 1.4.21. t_flush_flags() - 1.4.22. t_anycast_replicate() - 1.4.23. t_reply_by_callid(code, reason_phrase, - [callid], [cseq]) - - 1.4.24. t_get_branch_idx_by_attr(attr, [val_str], - [val_int], [result_var], [offset]) - - 1.5. Exported Pseudo-Variables - - 1.5.1. $T_branch_idx - 1.5.2. $T_reply_code - 1.5.3. $T_fr_timeout - 1.5.4. $T_fr_inv_timeout - 1.5.5. $T_ruri - 1.5.6. $bavp(name) - 1.5.7. $T_id - 1.5.8. $T_branch_last_reply_code - 1.5.9. $tm.branch.uri[] - 1.5.10. $tm.branch.duri[] - 1.5.11. $tm.branch.path[] - 1.5.12. $tm.branch.q[] - 1.5.13. $tm.branch.flags[] - 1.5.14. $tm.branch.socket[] - 1.5.15. $tm.branch.flag()[] - 1.5.16. $tm.branch.attr()[] - 1.5.17. $tm.branch.last_received[] - 1.5.18. $tm.branch.type[] - - 1.6. Exported MI Functions - - 1.6.1. t_uac_dlg - 1.6.2. t_uac_cancel - 1.6.3. t_hash - 1.6.4. t_reply - - 1.7. Exported Statistics - - 1.7.1. received_replies - 1.7.2. relayed_replies - 1.7.3. local_replies - 1.7.4. UAS_transactions - 1.7.5. UAC_transactions - 1.7.6. 2xx_transactions - 1.7.7. 3xx_transactions - 1.7.8. 4xx_transactions - 1.7.9. 5xx_transactions - 1.7.10. 6xx_transactions - 1.7.11. inuse_transactions - 1.7.12. retransmission_req_T1_1 - 1.7.13. retransmission_req_T1_2 - 1.7.14. retransmission_req_T1_3 - 1.7.15. retransmission_req_T2 - 1.7.16. retransmission_rpl_T2 - 1.7.17. timeout_finalresponse - 1.7.18. timeout_finalresponse - - 2. Developer Guide - - 2.1. Functions - - 2.1.1. load_tm(*import_structure) - - 3. Frequently Asked Questions - 4. Contributors - - 4.1. By Commit Statistics - 4.2. By Commit Activity - - 5. Documentation - - 5.1. Contributors - - List of Tables - - 4.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 4.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set fr_timeout parameter - 1.2. Set fr_inv_timeout parameter - 1.3. Set wt_timer parameter - 1.4. Set delete_timer parameter - 1.5. Set T1_timer parameter - 1.6. Set T2_timer parameter - 1.7. Set ruri_matching parameter - 1.8. Set via1_matching parameter - 1.9. Set unix_tx_timeout parameter - 1.10. Set restart_fr_on_each_reply parameter - 1.11. Set tw_append parameter - 1.12. Set pass_provisional_replies parameter - 1.13. Set syn_branch parameter - 1.14. Set onreply_avp_mode parameter - 1.15. Set disable_6xx_block parameter - 1.16. Set enable_stats parameter - 1.17. Set minor_branch_flag parameter - 1.18. Set timer_partitions parameter - 1.19. Set auto_100trying parameter - 1.20. Set tm_replication_cluster parameter - 1.21. Set the cluster_param parameter - 1.22. Set the cluster_auto_cancel parameter - 1.23. Set the local_request_route parameter - 1.24. Set the local_reply_route parameter - 1.25. t_relay usage - 1.26. t_reply usage - 1.27. t_reply_with_body usage - 1.28. t_newtran usage - 1.29. t_check_trans usage - 1.30. t_check_status usage - 1.31. t_local_replied usage - 1.32. t_was_cancelled usage - 1.33. t_cancel_branch usage - 1.34. t_new_request usage - 1.35. t_on_failure usage - 1.36. t_on_reply usage - 1.37. t_on_branch usage - 1.38. t_inject_branches usage - 1.39. t_wait_for_new_branches usage - 1.40. t_wait_no_more_branches usage - 1.41. t_add_hdrs usage - 1.42. t_add_cancel_reason usage - 1.43. t_replicate usage - 1.44. t_write_req/unix usage - 1.45. t_flush_flags usage - 1.46. t_anycast_replicate usage - 1.47. t_reply_by_callid usage - 1.48. t_get_branch_idx_by_attr usage - -Chapter 1. Admin Guide - -1.1. Overview - - TM module enables stateful processing of SIP transactions. The - main use of stateful logic, which is costly in terms of memory - and CPU, is some services inherently need state. For example, - transaction-based accounting (module acc) needs to process - transaction state as opposed to individual messages, and any - kinds of forking must be implemented statefully. Other use of - stateful processing is it trading CPU caused by retransmission - processing for memory. That makes however only sense if CPU - consumption per request is huge. For example, if you want to - avoid costly DNS resolution for every retransmission of a - request to an unresolvable destination, use stateful mode. - Then, only the initial message burdens server by DNS queries, - subsequent retransmissions will be dropped and will not result - in more processes blocked by DNS resolution. The price is more - memory consumption and higher processing latency. - - From user's perspective, the major function is t_relay(). It - setup transaction state, absorb retransmissions from upstream, - generate downstream retransmissions and correlate replies to - requests. - - In general, if TM is used, it copies clones of received SIP - messages in shared memory. That costs the memory and also CPU - time (memcpys, lookups, shmem locks, etc.) Note that non-TM - functions operate over the received message in private memory, - that means that any core operations will have no effect on - statefully processed messages after creating the transactional - state. For example, calling record_route after t_relay is - pretty useless, as the RR is added to privately held message - whereas its TM clone is being forwarded. - - TM is quite big and uneasy to program--lot of mutexes, shared - memory access, malloc and free, timers--you really need to be - careful when you do anything. To simplify TM programming, there - is the instrument of callbacks. The callback mechanisms allow - programmers to register their functions to specific event. See - t_hooks.h for a list of possible events. - - Other things programmers may want to know is UAC--it is a very - simplistic code which allows you to generate your own - transactions. Particularly useful for things like NOTIFYs or IM - gateways. The UAC takes care of all the transaction machinery: - retransmissions , FR timeouts, forking, etc. See t_uac - prototype in uac.h for more details. Who wants to see the - transaction result may register for a callback. - -1.1.1. Per-Branch flags - - First what is the idea with the branch concept: branch route is - a route to be execute separately for each branch before being - sent out - changes in that route should reflect only on that - branch. - - There are several types of flags in OpenSIPS : - * message/transaction flags - they are visible everywhere in - the transaction (in all routes and in all sequential - replies/request). - * branch flags - flags that are visible only from a specific - branch - in all replies and routes connected to this - branch. - * script flags - flags that exist only during script - execution. They are not store anywhere and are lost once - the top level route was left. - - For example: I have a call parallel forking to GW and to a - user. And I would like to know from which branch I will get the - final negative reply (if so). I will set a branch route before - relaying the calls (with the 2 branches). The branch route will - be separately executed for each branch; in the branch going to - GW (I can identified it by looking to RURI), I will set a - branch flag. This flag will appear only in the onreply route - run for replied from GW. It will be also be visible in failure - route if the final elected reply belongs to the GW branch. This - flags will not be visible in the other branch (in routes - executing replies from the other branch). - - For how to define branch flags and use via script, see - t_on_branch() and the setbflag(), resetbflag() and isbflagset() - script functions. - - Also, modules may set branch flags before transaction creation - (for the moment this feature is not available in script). The - REGISTRAR module was the first to use this type of flags. The - NAT flag is pushed in branch flags instead in message flags - -1.1.2. Timeout-Based Failover - - Timeouts can be used to trigger failover behavior. E.g. if we - send a call to a gateway and the gateway does not send a - provisional response within 3 seconds, we want to cancel this - call and send the call to another gateway. Another example is - to ring a SIP client only for 30 seconds and then redirect the - call to the voicemail. - - The transaction module exports two types of timeouts: - * fr_timeout - used when no response was received yet. If - there is no response after fr_timeout seconds, the timer - triggers (and failure route will be executed if - t_on_failure() was called). For INVITE transactions, if a - provisional response was received, the timeout is reset to - fr_inv_timeout seconds and RT_T2 for all other - transactions. Once a final response is received, the - transaction has finished. - * fr_inv_timeout - this timeout starts counting down once a - provisional response was received for an INVITE - transaction. - - For example: You want to have failover if there is no - provisional response after 3 seconds, but you want to ring for - 60 seconds. Thus, set the fr_timeout to 3 and fr_inv_timeout to - 60. - -1.1.3. DNS Failover - - DNS based failover can be use when relaying stateful requests. - According to RFC 3263, DNS failover should be done on transport - level or transaction level. TM module supports them both. - - Failover at transport level may be triggered by a failure of - sending out the request message. A failure occurs if the - corresponding interface was found for sending the request, if - the TCP connection was refused or if a generic internal error - happened during send. There is no ICMP error report support. - - Failover at transaction level may be triggered when the - transaction completed either with a 503 reply, either with a - timeout without any received reply. In such a case, - automatically, a new branch will be forked if any other - destination IPs can be used to deliver the requests. The new - branch will be a clone of the winning branch. - - The set of destinations IPs is step-by-step build (on demand) - based on the NAPTR, SRV and A records available for the - destination domain. - - DNS-based failover is by default applied excepting when this - failover is globally disabled (see the core parameter - disable_dns_failover) or when the relay flag (per transaction) - is set (see the t_relay() function). - -1.1.4. Anycast Scenario - - Doing a load balancing scenario using Anycast IPs, one might - run into an issue where a transaction request comes on one - instance, and the reply (or replies) comes on different ones. - This would normaly break the transaction state, because the - local transaction will start re-transmissios and would - eventually timeout. Moreover, from UA's perspective, the reply - whould have been sent, but since it reaches a proxy that is not - aware of that transaction, it will not be forwarded (nor ACKed - in case of INVITES). And from this point things can escalade - quickly. - - To sort out these problems, the module uses a distributed - mechanism to figure out where the transaction for a specific - reply was created. When an instance receives a reply that does - not have an associated transaction, it replicates it to be - handled by the instance that “owns” it. This is achieved using - the clusterer module support. - - Setting up an anycast scenario is very simple: all the - instances that are part of an anycast secnario must be set up - in a cluster (more info at the tm_replication_cluster param). - When a transaction is created, a special identifier is appended - to the branch parameter, namely the instance that created the - transaction. When a reply comes in, the transaction module - checks who “owns” the transaction. If the identifier is the - instance's own id, then the reply is processed locally. - Otherwise it is replicated to the node indicated by the id. - Replication is done in a very efficient manner, using the - proto_bin transport. - - Special handling is applied to CANCEL and ACK methods. Due to - the fact that these methods do not contain the special - identifier in the branch parameter (since they are generated by - the UAC and not by us), there is no way to determine who “owns” - the transaction. Therefore, if we do not find a local - transaction for these requests, we broadcast them to all the - other instances using the t_anycast_replicate() function. - Again, this is done in a very efficient manner using the - proto_bin transport. - -1.1.5. Usage Scope - - Transaction functions and variables are only designed to be - called on SIP request messages where a transaction can be - created, or in routes that are transaction aware, such as - branch_route[name], failure_route[name] or onreply_route[name]. - Using TM functtions or variables in a route that is not - transaction aware, such as the generic onreply_route, - error_route or timer_route[name, timer] may lead to undefined - behavior, and most of the time in bogus or malformed - signalling. Therefore it is strongly recommended to avoid using - them in non-tm context aware routes. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * clusterer module, if the anycast scenario is enabled (see - tm_replication_cluster param for more information). - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. fr_timeout (integer) - - Timeout which is triggered if no final reply for a request or - ACK for a negative INVITE reply arrives (in seconds). - - Default value is 30 seconds. - - Example 1.1. Set fr_timeout parameter -... -modparam("tm", "fr_timeout", 10) -... - -1.3.2. fr_inv_timeout (integer) - - Timeout which is triggered if no final reply for an INVITE - arrives after a provisional message was received (in seconds). - This timeout starts counting down once the first provisional - response is received. Thus, fast failover (no 100 trying from - gateway) can be achieved by setting fr_timeout to low values. - See example below. - - Default value is 120 seconds. - - Example 1.2. Set fr_inv_timeout parameter -... -modparam("tm", "fr_inv_timeout", 200) -... - -1.3.3. wt_timer (integer) - - Time for which a transaction stays in memory to absorb delayed - messages after it completed; also, when this timer hits, - retransmission of local cancels is stopped (a puristic but - complex behavior would be not to enter wait state until local - branches are finished by a final reply or FR timer--we - simplified). - - For non-INVITE transaction this timer relates to timer J of RFC - 3261 section 17.2.2. According to the RFC this timer should be - 64*T1 (= 32 seconds). But this would increase memory usage as - the transactions are kept in memory very long. - - Default value is 5 seconds. - - Example 1.3. Set wt_timer parameter -... -modparam("tm", "wt_timer", 10) -... - -1.3.4. delete_timer (integer) - - Time after which a to-be-deleted transaction currently ref-ed - by a process will be tried to be deleted again. - - Default value is 2 seconds. - - Example 1.4. Set delete_timer parameter -... -modparam("tm", "delete_timer", 5) -... - -1.3.5. T1_timer (integer) - - Retransmission T1 period, in milliseconds. - - Default value is 500 milliseconds. - - Example 1.5. Set T1_timer parameter -... -modparam("tm", "T1_timer", 700) -... - -1.3.6. T2_timer (integer) - - Maximum retransmission period, in milliseconds. - - Default value is 4000 milliseconds. - - Example 1.6. Set T2_timer parameter -... -modparam("tm", "T2_timer", 8000) -... - -1.3.7. ruri_matching (integer) - - Should be request-uri matching used as a part of pre-3261 - transaction matching as the standard wants us to do so? Turn - only off for better interaction with devices that are broken - and send different r-uri in CANCEL/ACK than in original INVITE. - - Default value is 1 (true). - - Example 1.7. Set ruri_matching parameter -... -modparam("tm", "ruri_matching", 0) -... - -1.3.8. via1_matching (integer) - - Should be top most VIA matching used as a part of pre-3261 - transaction matching as the standard wants us to do so? Turn - only off for better interaction with devices that are broken - and send different top most VIA in CANCEL/ACK than in original - INVITE. - - Default value is 1 (true). - - Example 1.8. Set via1_matching parameter -... -modparam("tm", "via1_matching", 0) -... - -1.3.9. unix_tx_timeout (integer) - - Send timeout to be used by function which use UNIX sockets (as - t_write_unix). - - Default value is 2 seconds. - - Example 1.9. Set unix_tx_timeout parameter -... -modparam("tm", "unix_tx_timeout", 5) -... - -1.3.10. restart_fr_on_each_reply (integer) - - If true (non null value), the final response timer will be - re-triggered for each received provisional reply. In this case, - final response timeout may occur after a time longer than - fr_inv_timeout (if UAS keeps sending provisional replies) - - Default value is 1 (true). - - Example 1.10. Set restart_fr_on_each_reply parameter -... -modparam("tm", "restart_fr_on_each_reply", 0) -... - -1.3.11. tw_append (string) - - List of additional information to be appended by t_write_req - and t_write_unix functions. - - Default value is null string. - - Syntax of the parameter is: - * tw_append = append_name':' element (';'element)* - * element = ( [name '='] variable) - - Each element will be appended per line in “name: value” format. - Element “$rb (message body)” is the only one which does not - accept name; the body it will be printed all the time at the - end, disregarding its position in the definition string. - - Example 1.11. Set tw_append parameter -... -modparam("tm", "tw_append", - "test: ua=$hdr(User-Agent) ;avp=$avp(avp);$rb;time=$Ts") -... - -1.3.12. pass_provisional_replies (integer) - - Enable/disable passing of provisional replies to FIFO - applications. - - Default value is 0. - - Example 1.12. Set pass_provisional_replies parameter -... -modparam("tm", "pass_provisional_replies", 1) -... - -1.3.13. syn_branch (integer) - - Enable/disable the usage of stateful synonym branch IDs in the - generated Via headers. They are faster but not reboot-safe. - - Default value is 1 (use synonym branches). - - Example 1.13. Set syn_branch parameter -... -modparam("tm", "syn_branch", 0) -... - -1.3.14. onreply_avp_mode (integer) - - Describes how the AVPs should be handled in reply route: - * 0 - the AVPs will be per message only; they will not - interfere with the AVPS stored in transaction; initially - there will be an empty list and at the end of the route, - all AVPs that were created will be discarded. - * 1 - the AVPs will be the transaction AVPs; initially the - transaction AVPs will be visible; at the end of the route, - the list will attached back to transaction (with all the - changes) - - In mode 1, you can see the AVPs you set in request route, - branch route or failure route. The side effect is performance - as more locking is required in order to keep the AVP's list - integrity. - - Default value is 0. - - Example 1.14. Set onreply_avp_mode parameter -... -modparam("tm", "onreply_avp_mode", 1) -... - -1.3.15. disable_6xx_block (integer) - - Tells how the 6xx replies should be internally handled: - * 0 - the 6xx replies will block any further serial forking - (adding new branches). This is the RFC3261 behaviour. - * 1 - the 6xx replies will be handled as any other negative - reply - serial forking will be allowed. Logically, you need - to break RFC3261 if you want to do redirects to - announcement and voicemail services. - - Default value is 0. - - Example 1.15. Set disable_6xx_block parameter -... -modparam("tm", "disable_6xx_block", 1) -... - -1.3.16. enable_stats (integer) - - Enables statistics support in TM module - If enabled, the TM - module will internally keep several statistics and export them - via the MI - Management Interface. - - Default value is 1 (enabled). - - Example 1.16. Set enable_stats parameter -... -modparam("tm", "enable_stats", 0) -... - -1.3.17. minor_branch_flag (string/integer) - - A branch flag index to be used in script to mark the minor - branches ( before t_relay() ). - - A minor branch is a branch OpenSIPS will not wait to complete - during parallel forking. So, if the rest of the branches are - negativly replied OpenSIPS will not wait for a final answer - from the minor branch, but it will simply cancel it. - - Main applicability of minor branch is to fork a branch to a - media server for injecting (via 183 Early Media) some pre-call - media - of course, this branch will be transparanent for the - rest of the call branches (from branch selection point of - view). - - Default value is none (disabled). - - Example 1.17. Set minor_branch_flag parameter -... -modparam("tm", "minor_branch_flag", "MINOR_BFLAG") -... - -1.3.18. timer_partitions (integer) - - The number of partitions for the internal TM timers - (retransmissions, delete, wait, etc). Partitioning the timers - increase the throughput under heavly load by handling timer - events in parallel, rather than all serial. - - Recomanded range for timer partitions is max 16 (soft limit). - - Default value is 1 (disabled). - - Example 1.18. Set timer_partitions parameter -... -# Enable two timer partitions -modparam("tm", "timer_partitions", 2) -... - -1.3.19. auto_100trying (integer) - - This parameter controls if the TM module should automatically - generate an 100 Trying stateful reply when an INVITE - transaction is created. - - You may want to disable this behavior if you want to control - from script level when the 100 Trying is to be sent out. - - Default value is 1 (enabled). - - Example 1.19. Set auto_100trying parameter -... -# Disable automatic 100 Trying -modparam("tm", "auto_100trying", 0) -... - -1.3.20. tm_replication_cluster (integer) - - This parameter should be used in an anycast setup, and - specifies the cluster id of all the nodes that use an anycast - IP. - - Check out the tm_anycast section for more details. - - Anycast replication is disabled by default. - - Example 1.20. Set tm_replication_cluster parameter -... -# replicate anycast messages in cluster 1 -modparam("tm", "tm_replication_cluster", 1) -... - -1.3.21. cluster_param (string) - - This parameter should be used in an anycast setup, and - specifies the name of the parameter used in the VIA branch - param to specifiy the instance id that created the transaction. - - Check out the tm_anycast section for more details. - - Default value is cid. - - Example 1.21. Set the cluster_param parameter -... -modparam("tm", "cluster_param", "tid") -... - -1.3.22. cluster_auto_cancel (boolean) - - This parameter should be used in an anycast setup, and - specifies whether a CANCEL message received on a listener that - is marked as anycast should be automatically handled, or should - get in the OpenSIPS script. If this parameter is enabled - (default), CANCEL messages received on an anycast listener will - never enter the script, thus making the script cleaner. - - Check out the tm_anycast section for more details. - - Default value is yes (enabled). - - Example 1.22. Set the cluster_auto_cancel parameter -... -# disable auto-cancel handling -modparam("tm", "cluster_auto_cancel", no) -... - -1.3.23. local_request_route (string) - - This parameter points to a route, which is executed whenever TM - is about to send out a locally generated request (e.g., through - the B2B modules or through MI). - - The purpose of this route is limited to exposing the content of - the request as SIP message - - The route is executed with the generated message by TM, - incorporating all modifications. - - IMPORTANT: this route is executed AFTER the local_route (if - defined) and it expose all the changes from that route. - - IMPORTANT: this route is to be used in a read-only manner, - inspection only. Any changes you do here will discarded. - - IMPORTANT: this route does not offer any message, transactional - or dialog context, so do not rely on any variables with scope - (like AVPs). - - Example 1.23. Set the local_request_route parameter -... -# Execute the route "local_request_route" upon sending a request -modparam("tm", "local_request_route", "tm_local_request") - -route[tm_local_request] { - if (is_method("INVITE") && $rb(application/sdp) && !has_totag()) - { - $avp(sdp_request) := $rb(application/sdp); - } -} -... - -1.3.24. local_reply_route (string) - - This parameter points to a route, which is executed whenever TM - is about to send out a locally generated reply (e.g., through - the B2B modules or through MI). - - The purpose of this route is limited to exposing the content of - the reply as SIP message - - IMPORTANT: this route is to be used in a read-only manner, - inspection only. Any changes you do here will discarded. - - IMPORTANT: this route does not offer any message, transactional - or dialog context, so do not rely on any variables with scope - (like AVPs). - - Example 1.24. Set the local_reply_route parameter -... -# Execute the route "tm_local_reply" upon sending a request -modparam("tm", "local_reply_route", "tm_local_reply") - -route[tm_local_reply] { - if (is_method("BYE")) { - $var(rc) = rest_get("http://localhost/qos/delete", - $var(recv_body), $var(recv_ct), -$var(rcode)); - } -} - -... - -1.4. Exported Functions - -1.4.1. t_relay([flags],[outbound_proxy]) - - Relay a message statefully to destination indicated in current - URI. (If the original URI was rewritten by UsrLoc, RR, - strip/prefix, etc., the new URI will be taken). Returns a - negative value on failure--you may still want to send a - negative reply upstream statelessly not to leave upstream UAC - in lurch. - - The coresponding transaction may or may not be already created. - If not yet created, the function will automatically create it. - - The function may take two optional parameters. - - The first parameter is a comma separated list of string flags - for controlling the internal behaviour. The supported flags - are: - * no-auto-477 - (old 0x02 flag) do not internally generate - and send a "477 Send failed (477/TM)" SIP reply in case of - a global forwarding failure (i.e. forwarding for each - branch has failed due to internal errors, bad R-URI, bad - message, lack of network reachability, etc.). - This flag only applies if the transaction was not - previously created by t_newtran(). When a global forwarding - failure occurs, no SIP request is relayed and therefore no - negative SIP reply or timeout will show up on the - failure_route, if one is set. - Useful if you want to implement a failover logic for when - none of the currently created branches can be forwarded to. - * no-dns-failover - (old 0x04 flag) disable the DNS failover - for the transaction. Only first IP will be used. It - disables the failover both at transport and transaction - level. - * pass-reason-hdr - (old 0x08 flag) If the request is a - CANCEL, trust and pass further the Reason header from the - received CANCEL - shortly, will propagate the Reason - header. - * allow-no-cancel - (old 0x10 flag) Allows OpenSIPS to - inspect and follow the Content-Disposition "no-cancel" - indication (if present). As per RFC3841, section 9.1, the - TM module may be instructed not to cancel all ongoing - branches when a 2xx reply is received. It will keep the - pending branches ongoing until (1) all branches will - receive a final reply or (2) the transactionhits the - timeout. - - The second parameter is a string representing an outbound proxy - (a fixed destination) where the message should be sent. The - destination is specified as “[proto:]host[:port]”. If a - destination URI “$du” for this message was set before the - function is called then this value will be used as the - destination instead of the function parameter. - - In case of error, the function returns the following codes: - * -1 - generic internal error - * -2 - bad message (parsing errors) - * -3 - no destination available (no branches were added or - request already cancelled) - * -4 - bad destination (unresolvable address) - * -5 - destination filtered (black listed) - * -6 - generic send failed - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.25. t_relay usage -... -if (!t_relay()) { - sl_reply_error(); - exit; -} -... -t_relay( ,"tcp:192.168.1.10:5060"); -... -t_relay(0x1, "mydomain.com:5070"); -... - -1.4.2. t_reply(code, reason_phrase) - - Sends a stateful SIP reply to the currently processed requests. - Note that if the transaction was not created yet, it will - automatically created by internally using the t_newtran - function. - - Meaning of the parameters is as follows: - * code (int) - Reply code number. - * reason_phrase (string) - Reason string. - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - Example 1.26. t_reply usage -... -t_reply(404, "Use $rU not found"); -... - -1.4.3. t_reply_with_body(code, reason_phrase, body) - - Sends a stateful SIP reply with a body to the currently - processed requests. Note that if the transaction was not - created yet, it will automatically created by internally using - the t_newtran function. - - Meaning of the parameters is as follows: - * code (int) - Reply code number. - * reason_phrase (string) - Reason string. - * body (string) - Reply body. - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - Example 1.27. t_reply_with_body usage -... - if(is_method("INVITE")) - { - append_to_reply("Contact: $var(contact)\r\n" - "Content-Type: application/sdp\r\n"); - t_reply_with_body(200, "Ok", $var(body)); - exit; - } -... - -1.4.4. t_newtran() - - Creates the SIP transaction for the currently processed SIP - request, thus switching to stateful processing. For INVITE - requests, a 100 Trying reply will be immediately sent, unless - auto_100trying is disabled. Once a SIP transaction is created, - calling t_newtran() for retransmitted requests will end the - OpenSIPS script execution, with the lastly sent reply being - retransmitted upstream. - - This function can be used from REQUEST_ROUTE. - - Example 1.28. t_newtran usage -... -t_newtran(); # 100 Trying is fired here -xlog("doing my complicated routing logic\n"); -.... -t_relay(); # send the call further -... - -1.4.5. t_check_trans() - - Returns true if the current request is associated to a - transaction. The relationship between the request and - transaction is defined as follows: - * non-CANCEL/non-ACK requests - if the request belongs to a - transaction (it's a retransmision), the function will do a - standard processing of the retransmission and will - break/stop the script. The function returns false if the - request is not a retransmission. - * CANCEL request - true if the cancelled INVITE transaction - exists. - * ACK request - true if the ACK is a hop-by-hop ACK (to a - negative reply) corresponding to an previous INVITE - transaction. IMPORTANT: this function returns false (return - code -2) for end-to-end ACKs (to 2xx replies from a - different transaction). - - Note: To detect retransmissions using this function you have to - make sure that the initial request has already created a - transaction, e.g. by using t_relay(). If the processing of - requests may take long time (e.g. DB lookups) and the - retransmission arrives before t_relay() is called, you can use - the t_newtran() function to manually create a transaction. - - This function can be used from REQUEST_ROUTE and BRANCH_ROUTE. - - Example 1.29. t_check_trans usage -... -if ( is_method("CANCEL") ) { - if ( t_check_trans() ) - t_relay(); - exit; -} -... - -1.4.6. t_check_status(re) - - Returns true if the regualr expression “re” match the reply - code of the response message as follows: - * in routing block - the code of the last sent reply. - * in on_reply block - the code of the current received reply. - * in on_failure block - the code of the selected negative - final reply. - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE . - - Example 1.30. t_check_status usage -... -if (t_check_status("(487)|(408)")) { - log("487 or 408 negative reply\n"); -} -... - -1.4.7. t_local_replied(reply) - - Returns true if all or last (depending of the parameter) - reply(es) were local generated (and not received). - - Parameter may be “all” or “last”. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - Example 1.31. t_local_replied usage -... -if (t_local_replied("all")) { - log ("no reply received\n"); -} -... - -1.4.8. t_was_cancelled() - - Retuns true if called for an INVITE transaction that was - explicitly cancelled by UAC side via a CANCEL request. - - This function can be used from ONREPLY_ROUTE, FAILURE_ROUTE. - - Example 1.32. t_was_cancelled usage -... -if (t_was_cancelled()) { - log("transaction was cancelled by UAC\n"); -} -... - -1.4.9. t_cancel_branch([flags]) - - This function is to be call when a reply is received for - cancelling a set of branches (see flags) of the current call. - - Meaning of the parameters is as follows: - * flags (string, optional) - set of flags (char based flags) - to control what branches to be cancelled: - + a - all - cancel all pending branches - + o - others - cancel all the other pending branches - except the current one - + empty - current - cancel only the current branch - - This function can be used from ONREPLY_ROUTE. - - Example 1.33. t_cancel_branch usage -onreply_route[3] { -... - if (t_check_status(183)) { - # no support for early media - t_cancel_branch(); - } -... -} - -1.4.10. t_new_request( method, RURI, from, to [, body[, ctx]]) - - This function generates and sends out a new SIP request (in a - stateful way). The new request is completly unrelated to the - currently processed SIP message. - - Meaning of the parameters is as follows (all do accept - variables): - * method (string) - the SIP method - * RURI (string) - the SIP Request URI (the request will be - sent out to this destination) - * from (string) - the SIP From hdr information as "[display - ]URI" - * to (string) - the SIP To hdr information as "[display ]URI" - * body (string, optional) - the SIP body content starting - with the content type string: "conten_type body" - * ctx (string, optional) - a context string that will be - added to the new transaction as an AVP with name "uac_ctx" - (it may be visible in local route) - - Example 1.34. t_new_request usage -... - # send a MESSAGE request - t_new_request("MESSAGE","sip:alice@192.168.2.2","BOB sip:userB@m -ydomain.net","ALICE sip:userA@mydomain.net","text/plain Hello Alice!")) -{ -... - -1.4.11. t_on_failure(failure_route) - - Sets reply routing block, to which control is passed after a - transaction completed with a negative result but before sending - a final reply. In the referred block, you can either start a - new branch (good for services such as forward_on_no_reply) or - send a final reply on your own (good for example for message - silo, which received a negative reply from upstream and wants - to tell upstream “202 I will take care of it”). - - As not all functions are available from failure route, please - check the documentation for each function to see the - permissions. Any other commands may result in unpredictable - behavior and possible server failure. - - Only one failure_route can be armed for a request. If you use - many times t_on_failure(), only the last one has effect. - - Note that whenever failure_route is entered, RURI is set to - value of the winning branch. - - Meaning of the parameters is as follows: - * failure_route (string) - Reply route block to be called. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - Example 1.35. t_on_failure usage -... -route { - t_on_failure("1"); - t_relay(); -} - -failure_route[1] { - seturi("sip:user@voicemail"); - t_relay(); -} -... - -1.4.12. t_on_reply(reply_route) - - Sets reply routing block, to which control is passed each time - a reply (provisional or final) for the transaction is received. - The route is not called for local generated replies! In the - referred block, you can inspect the reply and perform text - operations on it. - - As not all functions are available from this type of route, - please check the documentation for each function to see the - permissions. Any other commands may result in unpredictable - behavior and possible server failure. - - If called from branch route, the reply route will be set only - for the current branch - that's it, it will be called only for - relies belonging to that particular branch. Of course, from - branch route, you can set different reply routes for each - branch. - - When called from a non-branc route, the reply route will be - globally set for tha current transaction - it will be called - for all replies belonging to that transaction. NOTE that only - one> onreply_route can be armed for a transaction. If you use - many times t_on_reply(), only the last one has effect. - - If the processed reply is provisionla reply (1xx code), by - calling the drop() function (exported by core), the execution - of the route will end and the reply will not be forwarded - further. - - Meaning of the parameters is as follows: - * reply_route (string) - Reply route block to be called. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - Example 1.36. t_on_reply usage -... -route { - seturi("sip:bob@opensips.org"); # first branch - append_branch("sip:alice@opensips.org"); # second branch - - t_on_reply("global"); # the "global" reply route - # is set the whole transaction - t_on_branch("1"); - - t_relay(); -} - -branch_route[1] { - if ($rU=="alice") - t_on_reply("alice"); # the "alice" reply route - # is set only for second branch -} - -onreply_route[alice] { - xlog("received reply from alice\n"); -} - -onreply_route[global] { - if (t_check_status("1[0-9][0-9]")) { - setflag(LOG_FLAG); - log("provisional reply received\n"); - if (t_check_status("183")) - drop; - } -} -... - -1.4.13. t_on_branch(branch_route) - - Sets a branch route to be execute separately for each branch of - the transaction before being sent out - changes in that route - should reflect only on that branch. - - As not all functions are available from this type of route, - please check the documentation for each function to see the - permissions. Any other commands may result in unpredictable - behavior and possible server failure. - - Only one branch_route can be armed for a request. If you use - many time t_on_branch(), only the last one has effect. - - By calling the drop() function (exported by core), the - execution of the branch route will end and the branch will not - be forwarded further. - - Meaning of the parameters is as follows: - * branch_route (string) - Branch route block to be called. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - Example 1.37. t_on_branch usage -... -route { - t_on_branch("1"); - t_relay(); -} - -branch_route[1] { - if ($ru=~"bad_uri") { - xlog("dropping branch $ru \n"); - drop; - } - if ($ru=~"GW_uri") { - append_rpid(); - } -} -... - -1.4.14. t_inject_branches(source[,flags]) - - The function adds new SIP branches (destinations) to an - existing transaction and fires them (sends them out). The - transaction may already have ongoing branches (like in ringing - state), which will not be affected by the injection of the new - branches. Also it is possible for the transaction not to have - any ongoing branches at the moment of the injection (still, the - transaction must wait for new branches, even if all existing - ones are completed - see the t_wait_for_new_branches() function - for this). - - The main usage scenario for this function (and also what makes - it different from t_relay() is the ability to add new branches - to an ongoing transaction from script routes not related to the - transaction ( like timer route, event route, notification - route, and other). In such routes, other functions/module used - before the injection will point to the transaction to be - affected by this injection - see the event_routing module. - - Parameters: - * source (string) - where to take the description for the new - branches to be injected. It can be - + event - the branch will be taken from the event - attributes exposed in an event notification route (see - event_routing module). - + msg - the branches will be taken from the RURI of the - SIP message and from the additional branches (created - by append_branch() function or similar). - * flags (string, optional) - some additional flags related to - the injection process: - + cancel or c - cancel all the ongoing existing branches - from the transaction before injecting the new - branches. - + l (last) - this is the last injected branch on this - transaction, do not wait for any other branches to be - injected. - - Example 1.38. t_inject_branches usage -... -route[event_notification] { - t_inject_branches("event"); -} -... - -1.4.15. t_wait_for_new_branches([branches]) - - This function instructs the existing SIP transaction to wait - for new branches to be injected even after the completion of - the existing branches. This waiting will be done until the - Final Response INVITE timer (fr_inv_timeout) will hit for the - transaction OR until the maximum number of branches were - injected (see parameter); of course, the waiting will be - terminated if the transaction gets a 2xx final reply from one - of the branches. - - Normally if you have a transaction with two branches and they - get, let's say, a 404 and 486 replies, the branches will be - completed and transaction terminated by sending the 404 reply - to the caller. Still, if you do t_wait_for_new_branches before - relaying the transaction, the transaction will not terminate - upon the completion of the branches and not send the 404 to the - caller - it will wait for new branches to be injected (see - t_inject_branches() function) until the fr_inv timer hits. - - Parameters: - * branches (integer, options) - what is the maximum number of - branches to be waited for. - - Example 1.39. t_wait_for_new_branches usage -... -t_newtran(); -t_wait_for_new_branches(); -t_relay(); -... - -1.4.16. t_wait_no_more_branches() - - This function instructs the existing SIP transaction to stop - wait for new any new branches to be injected. This functions - should be used for a transaction that is waiting for dynamic - branches, via the t_wait_for_new_branches() function. - - Usage scenario: your transaction is waiting for dynamic new - branches (as a reusult of Push Notification). To a point, on an - ongoing branch you receive a final reply - and the fact that - the branch fails translates into stop waiting for any more - branche (this is an example of a logic on deciding how long to - wait for more branches, depending on the answers you get from - various devices, fix or mobile). - - Example 1.40. t_wait_no_more_branches usage -... -t_wait_no_more_branches(); -... - -1.4.17. t_add_hdrs("sip_hdrs") - - Attach a set of headers to the existing transaction - these - headers will be appended to all requests related to the - transaction (outgoing branches, local ACKS, CANCELs). - - Parameters: - * sip_hdrs (string) - - Example 1.41. t_add_hdrs usage -... -t_add_hdrs("X-origin: 1.1.1.1\r\n"); -... - -1.4.18. t_add_cancel_reason("Reason_hdr") - - This function is used to enforce from the script level a custom - "Reason" header into a CANCEL request. Normally, the Reason - header is inherited form the received CANCEL (note that CANCEL - propagates in a hop-by-hop manner - it is re-generated at each - hop), but this function can overwrite it. It must be called - before relaying the CANCEL request and its input must be a - fully formated Reason header with name, body and CRLF. - - Parameters: - * reason_hdr (string) - - Example 1.42. t_add_cancel_reason usage -... -t_add_cancel_reason("Reason: SIP ;cause=200 ;text=\"Call completed elsew -here\"\r\n"); -t_relay(); -... - -1.4.19. t_replicate(URI,[flags]) - - Replicates a request to another destination. No information due - the replicated request (like reply code) will be forwarded to - the original SIP UAC. - - The destination is specified by a SIP URI. If multiple - destinations are to be used, the additional SIP URIs have to be - set as branches. - - Parameters: - * uri (string) - * flags (string, optional) - a set of flags for controlling - the internal behaviour - for description see the above - “t_relay([flags])” function. Note that only no-dns-failover - is applicable here. - - This functions can be used from REQUEST_ROUTE. - - Example 1.43. t_replicate usage -... -t_replicate("sip:1.2.3.4:5060"); -t_replicate("sip:1.2.3.4:5060;transport=tcp"); -t_replicate("sip:1.2.3.4",0x4); -... - -1.4.20. t_write_req(info,fifo) t_write_unix(info,sock) - - Write via FIFO file or UNIX socket a lot of information - regarding the request. Which information should be written may - be control via the “tw_append” parameter. - - Parameters: - * info (string) - * path (string) - - This functions can be used from REQUEST_ROUTE, FAILURE_ROUTE - and BRANCH_ROUTE. - - Example 1.44. t_write_req/unix usage -... -modparam("tm","tw_append","append1:Email=$avp(email);UA=$ua") -modparam("tm","tw_append","append2:body=$rb") -... -t_write_req("voicemail/append1","/tmp/appx_fifo"); -... -t_write_unix("logger/append2","/var/run/logger.sock"); -... - -1.4.21. t_flush_flags() - - Flush the flags from current request into the already created - transaction. It make sense only in routing block if the - transaction was created via t_newtran() and the flags have been - altered since. - - This function can be used from REQUEST_ROUTE and BRANCH_ROUTE . - - Example 1.45. t_flush_flags usage -... -t_flush_flags(); -... - -1.4.22. t_anycast_replicate() - - This function is used in an anycast setup to replicate a CANCEL - or ACK method for whom there are no local transactions found. - The function broadcasts the message to all the other nodes in - the cluster, but only the “owner” of the transaction will be - able to handle it. - - Example 1.46. t_anycast_replicate usage -... -if (is_method("ACK|CANCEL") && !t_check_trans()) { - t_anycast_replicate(); - exit; -} -... - -1.4.23. t_reply_by_callid(code, reason_phrase, [callid], [cseq]) - - This function is used to send a reply to an existing INVITE - transaction. The usual use case is when OpenSIPS is used as an - UAS and when an INVITE is receveid, it is "parked" locally on - OpenSIPS by replying to it with “t_reply(180, "Ringing")” or - “t_reply(183, "Session Progress")” and later we need to handle - CANCEL or BYE for it and send '487 Request Terminated' to the - original INVITE transaction. - - The callid and cseq used to identify the transaction will be - obtained from the current messsage being processed. But they - can be passed explicitly so that for example we can handle a - BYE where the cseq must be the cseq of the INVITE minus one. - - This function can be used from REQUEST_ROUTE. - - Example 1.47. t_reply_by_callid usage -... -route{ - if($rU == "LOCAL_PARK") { - if(is_method("INVITE")) { - $T_fr_timeout = 10; - $T_fr_inv_timeout = 10; - append_to_reply("Contact: sip:LOCAL_PARK@$socket -_in(ip):$socket_in(port)\r\n"); - t_reply(180, "Ringing"); - t_wait_for_new_branches(); - } else if(is_method("CANCEL")) { - if(!t_reply_by_callid(487, "Request Terminated") -) { - sl_send_reply(481, "Call Leg/Transaction - Does Not Exist"); - } else { - sl_send_reply(200, "OK"); - } - } else if(is_method("BYE")) { - $var(prev_cseq) = ($(cs{s.int}) - 1); - if(!t_reply_by_callid(487, "Request Terminated", - , $var(prev_cseq))) { - sl_send_reply(481, "Call Leg/Transaction - Does Not Exist"); - } else { - sl_send_reply(200, "OK"); - } - } else if(is_method("ACK")) { - t_relay(); - } - exit; - } -} -... - -1.4.24. t_get_branch_idx_by_attr(attr, [val_str], [val_int], -[result_var], [offset]) - - This function may be used to search for the index of another - branch of the current transaction. The searching is done based - on the per-branch attribute - you need to provide the name of - the attribute at least. Optionally you can provide a value - (string or integer) for the attribute used for searching. As - input, the function may take an optional branch offset - (absolute value, covering all branches of the transaction) - where the search should start from. - - The function returns true if a branch (having the given name - and value for the attribute) was found. The status of the - branch (like if ongoing, completed ) is not relevant. If found, - the "result_var" variable will be populated with the branch - index (as integer). - - This function can be used from ONREPLY_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.48. t_get_branch_idx_by_attr usage -... - # search for a branch which has the "name" attribute - # with string value "pstn" - if (t_get_branch_idx_by_attr("name", "pstn", , $var(idx))) { - xlog("found branch has index $var(idx)\n"); - } -... - -1.5. Exported Pseudo-Variables - - Exported variables are listed in the next sections. - -1.5.1. $T_branch_idx - - $T_branch_idx - the index (starting with 0 for the first - branch) of the currently proccessed branch. This index makes - sense only in BRANCH and REPLY routes (where the processing is - per branch) and in FAILURE route (where it points to the branch - with the last final reply on the transaction). In all the other - types of routes, the value of this index will be NULL. - -1.5.2. $T_reply_code - - $T_reply_code - the code of the reply, as follows: in - request_route will be the last stateful sent reply; in - reply_route will be the current processed reply; in - failure_route will be the negative winning reply. In case of - no-reply or error, '0' value is returned. - -1.5.3. $T_fr_timeout - - $T_fr_timeout (R/W) - the timeout for the final reply to the - current transaction - - With each different request received, $T_fr_timeout will - initially be equal to the fr_timeout parameter. - - "$T_fr_timeout = NULL;" will reset it to fr_timeout. - -1.5.4. $T_fr_inv_timeout - - $T_fr_inv_timeout (R/W) - the timeout for the final reply to an - INVITE request, after a 1XX reply was received. This variable - may also be set in an onreply_route (e.g. on 180 Ringing, after - 100 Trying) and still take effect. - - With each different request received, $T_fr_inv_timeout will - initially be equal to the fr_inv_timeout parameter. - - "$T_fr_inv_timeout = NULL;" will reset it to fr_inv_timeout. - -1.5.5. $T_ruri - - $T_ruri - the ruri of the current branch; this information is - taken from the transaction structure, so you can access this - information for any sip message (request/reply) that has a - transaction. - -1.5.6. $bavp(name) - - $bavp(name) - a particular type of avp that can have different - values for each branch. They can only be used in BRANCH, REPLY - and FAILURE routes. Otherwise NULL value is returned. - -1.5.7. $T_id - - $T_id - returns the ID of the current transaction. The ID is an - opaque hexa string, unique for each transaction. If there is no - current transaction, NULL value is returned. - -1.5.8. $T_branch_last_reply_code - - $T_branch_last_reply_code - returns the last reply code - received for a branch specified as parameter. If no parameter - is specified, the last reply for the current branch is - retrieved. - -1.5.9. $tm.branch.uri[] - - $tm.branch.uri - gives read-only access over the Request URI - (as string) of a TM existing branch. The status of the branch - (completed, ongoing, etc) is not relevant. - - The TM (UAC side) branches are created when the request is sent - to new destinations via "t_relay()" or "t_inject()". - - The indexing of the branches starts from 0, giving access to - all branches (past and active) of the transaction. Nevertheless - the indexing supports two optional suffixes, to simplify the - scripting: - * /active - the indexing starts also from 0, but it is - relative to the last set of branches - the parallel - branches created by the last "t_relay()"-ing. - * /all - similar to "no suffix" case, meaning it is an - absolute index, covering all the branches of the - trasactions (resulted from all "t_relay()"s performed over - the transaction). - - IF no index is specified, the current branch used. This depends - on the scripting context. Like in reply route, the current - branch is the branch the reply came for; in branch route, the - current branch is the branch to be sent out; in failure route, - the current branch is the winning branch. - - NOTES: - * The index ALL ( "*" ) is not supported; - * In branch route, only the "$tm.branch.attr" and - "$tm.branch.flag" variables work for the current branch - (the rest of the branch related variables will return NULL) - * Negative values are accepted, meaning indexing from the end - ( -1 is the latest/higher branch) - - The variable can be used in BRANCH, ONREPLY and FAILURE routes. - -1.5.10. $tm.branch.duri[] - - $tm.branch.duri - 100% similar to $tm.branch.uri, but returning - the Detination-URI value of the branch. - -1.5.11. $tm.branch.path[] - - $tm.branch.path - 100% similar to $tm.branch.uri, but returning - the PATH value of the branch. - -1.5.12. $tm.branch.q[] - - $tm.branch.q - 100% similar to $tm.branch.uri, but returning - the Q value of the branch. - -1.5.13. $tm.branch.flags[] - - $tm.branch.flags - 100% similar to $tm.branch.uri, but - returning the list (comma separated) of per-branch flags which - are set for the branch. - -1.5.14. $tm.branch.socket[] - - $tm.branch.socket - 100% similar to $tm.branch.uri, but - returning the socket description (proto:ip:port) used for - sending the branch out. - -1.5.15. $tm.branch.flag()[] - - $tm.branch.flag(name) - similar to $tm.branch.uri, but gives - read/write access to a single branch flag (by its name). - - The accepted values are 0 for FALSE, pozitive non-zero for - TRUE. The returned values are 0 for FALSE and 1 for TRUE. - - The flags operated here are the same as the bflags you can - operated with via the "[re]setbflag()" functions. - -1.5.16. $tm.branch.attr()[] - - $tm.branch.attr(name) - similar to $tm.branch.uri, but gives - read/write access to the attributed attached to the branch. - - An attribute can have whatever name (no need to be pre-defined) - and it can have a single value (at a time), string or integer. - -1.5.17. $tm.branch.last_received[] - - $tm.branch.last_received - 100% similar to $tm.branch.uri, but - returning the reply code of the last received reply (from the - network) on this branch. NULL is returned in no reply was - received so far. - -1.5.18. $tm.branch.type[] - - $tm.branch.type - 100% similar to $tm.branch.uri, but returning - the type of the current branch. This may be "phone" if it not a - real branch (has no SIP signalling, used by waiting for branch - injection) or "sip" (a real signalling branch). - -1.6. Exported MI Functions - -1.6.1. t_uac_dlg - - Generates and sends a local SIP request. - - Parameters: - * method - request method - * ruri - request SIP URI - * headers - set of additional headers to be added to the - request; at least “From” and “To” headers must be - specified) - * next_hop (optional) - next hop SIP URI (OBP). - * socket (optional) - local socket to be used for sending the - request. - * body (optional) - request body (if present, requires the - “Content-Type” and “Content-length” headers) - - MI FIFO Command Format: - opensips-cli -x mi t_uac_dlg method=INVITE ruri="sip:ali -ce@127.0.0.1:7050" headers="From: sip:bobster@127.0.0.1:1337\r\nTo: sip: -alice@127.0.0.1:7050\r\nContact: sip:bobster@127.0.0.1:1337\r\n" - -1.6.2. t_uac_cancel - - Generates and sends a CANCEL for an existing SIP request. - - Parameters: - * callid - callid of the INVITE request to be cancelled. - * cseq - cseq of the INVITE request to be cancelled. - - MI FIFO Command Format: - opensips-cli -x mi t_uac_cancel "1-23454@127.0.0.1" "1 I -NVITE" - -1.6.3. t_hash - - Gets information about the load of TM internal hash table. - - Parameters: - * none - - MI FIFO Command Format: - opensips-cli -x mi t_hash - -1.6.4. t_reply - - Generates and sends a reply for an existing inbound SIP - transaction. - - Parameters: - * code - reply code - * reason - reason phrase. - * trans_id - transaction identifier (has the hash_entry:label - format) - * to_tag - To tag to be added to TO header - * new_headers (optional) - extra headers to be appended to - the reply. - * body - (optional) reply body (if present, requires the - “Content-Type” and “Content-length” headers) - - MI FIFO Command Format: - opensips-cli -x mi t_reply 403 Forbidden 46961:127968763 -7 abcde . - -1.7. Exported Statistics - - Exported statistics are listed in the next sections. All - statistics except “inuse_transactions” can be reset. - -1.7.1. received_replies - - Total number of total replies received by TM module. - -1.7.2. relayed_replies - - Total number of replies received and relayed by TM module. - -1.7.3. local_replies - - Total number of replies local generated by TM module. - -1.7.4. UAS_transactions - - Total number of transactions created by received requests. - -1.7.5. UAC_transactions - - Total number of transactions created by local generated - requests. - -1.7.6. 2xx_transactions - - Total number of transactions completed with 2xx replies. - -1.7.7. 3xx_transactions - - Total number of transactions completed with 3xx replies. - -1.7.8. 4xx_transactions - - Total number of transactions completed with 4xx replies. - -1.7.9. 5xx_transactions - - Total number of transactions completed with 5xx replies. - -1.7.10. 6xx_transactions - - Total number of transactions completed with 6xx replies. - -1.7.11. inuse_transactions - - Number of transactions existing in memory at current time. - -1.7.12. retransmission_req_T1_1 - - Number of request retransmissions due to T1 1 timer, the first - retransmission interval (typical 500ms). - -1.7.13. retransmission_req_T1_2 - - Number of request retransmissions due to T1 2 timer, the second - retransmission interval (typical 1s). - -1.7.14. retransmission_req_T1_3 - - Number of request retransmissions due to T1 3 timer, the third - retransmission interval (typical 2s). - -1.7.15. retransmission_req_T2 - - Number of request retransmissions due to T2 , the final - retransmission interval (typical 4s). - -1.7.16. retransmission_rpl_T2 - - Number of reply retransmissions, all done with the same - retransmission interval T2, typical 4s. - -1.7.17. timeout_finalresponse - - Number of transactional timeouts without receiving any kind of - reply (not even provisional) from the B side. Such timeouts - indicate a communication / reachability issue. Note: a single - transaction may count multiple such timeouts due forking. - -1.7.18. timeout_finalresponse - - Number of transactional INVITE timeouts without receiving a - FINAL reply (provisional may be received) from the B side. Such - timeouts indicate a "not answer" event and it is not a - signalling issue. Note: a single transaction may count multiple - such timeouts due forking. - -Chapter 2. Developer Guide - -2.1. Functions - -2.1.1. load_tm(*import_structure) - - For programmatic use only--import the TM API. See the cpl_c, - acc or jabber modules to see how it works. - - Meaning of the parameters is as follows: - * import_structure - Pointer to the import structure - see - “struct tm_binds” in modules/tm/tm_load.h - -Chapter 3. Frequently Asked Questions - - 3.1. - - What happened with old cancel_call() function - - The function was replace (as functionality) by - cancel_branch("a") - cancel all braches. - - 3.2. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 4. Contributors - -4.1. By Commit Statistics - - Table 4.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 1119 646 22978 16883 - 2. Jiri Kuthan (@jiriatipteldotorg) 541 198 18723 11167 - 3. Jan Janak (@janakj) 162 76 6462 1840 - 4. Razvan Crainea (@razvancrainea) 146 113 2081 877 - 5. Andrei Pelinescu-Onciul 146 105 2447 1210 - 6. Liviu Chircu (@liviuchircu) 119 91 1319 946 - 7. Vlad Paiu (@vladpaiu) 45 33 675 339 - 8. Daniel-Constantin Mierla (@miconda) 43 37 322 166 - 9. Vlad Patrascu (@rvlad-patrascu) 40 18 916 826 - 10. Anca Vamanu 37 19 778 651 - - All remaining contributors: Henning Westerholt (@henningw), Dan - Pascu (@danpascu), Maksym Sobolyev (@sobomax), Ovidiu Sas - (@ovidiusas), Juha Heinanen (@juha-h), Ionut Ionita - (@ionutrazvanionita), Raphael Coeffic, Nils Ohlmeier, Klaus - Darilion, Peter Lemenkov (@lemenkov), Andreas Granig, Elias - Baixas, Marcus Hunger, Christophe Sollet (@csollet), Jeffrey - Magder, Ezequiel Lovelle (@lovelle), Carsten Bock, Saúl Ibarra - Corretgé (@saghul), Elena-Ramona Modroiu, John Riordan, Julián - Moreno Patiño, Andrei Dragus, Jesus Rodrigues, Konstantin - Bokarius, Aron Podrigal (@ar45), Anonymous, Dusan Klinec - (@ph4r05), Mark Dalby, Walter Doekes (@wdoekes), Alexey - Vasilyev (@vasilevalex), Fabian Gast (@fgast), Nick Altmann - (@nikbyte), Zero King (@l2dy), Edson Gellert Schubert, - MayamaTakeshi, Ingo Wolfsberger, Daniel Hsueh. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -4.2. By Commit Activity - - Table 4.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Razvan Crainea (@razvancrainea) Jul 2010 - Oct 2025 - 2. Liviu Chircu (@liviuchircu) Jan 2013 - Oct 2025 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Nov 2001 - Sep 2025 - 4. Vlad Paiu (@vladpaiu) Jun 2011 - Apr 2025 - 5. Carsten Bock Mar 2024 - Mar 2024 - 6. Maksym Sobolyev (@sobomax) Mar 2004 - Nov 2023 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2023 - 8. MayamaTakeshi Oct 2022 - Oct 2022 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Feb 2021 - 10. Zero King (@l2dy) Mar 2020 - Mar 2020 - - All remaining contributors: Dan Pascu (@danpascu), Fabian Gast - (@fgast), Aron Podrigal (@ar45), Alexey Vasilyev - (@vasilevalex), Ionut Ionita (@ionutrazvanionita), Julián - Moreno Patiño, Nick Altmann (@nikbyte), Ovidiu Sas - (@ovidiusas), Dusan Klinec (@ph4r05), Ezequiel Lovelle - (@lovelle), Walter Doekes (@wdoekes), Christophe Sollet - (@csollet), Saúl Ibarra Corretgé (@saghul), Anonymous, Mark - Dalby, Anca Vamanu, Andrei Dragus, John Riordan, Henning - Westerholt (@henningw), Klaus Darilion, Daniel-Constantin - Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, - Jesus Rodrigues, Marcus Hunger, Juha Heinanen (@juha-h), - Jeffrey Magder, Elias Baixas, Daniel Hsueh, Andreas Granig, - Elena-Ramona Modroiu, Ingo Wolfsberger, Andrei - Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan - (@jiriatipteldotorg), Raphael Coeffic, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 5. Documentation - -5.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Carsten Bock, Razvan Crainea - (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Fabian Gast - (@fgast), Alexey Vasilyev (@vasilevalex), Peter Lemenkov - (@lemenkov), Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), - Vlad Paiu (@vladpaiu), Anca Vamanu, Henning Westerholt - (@henningw), Klaus Darilion, Daniel-Constantin Mierla - (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dan - Pascu (@danpascu), Juha Heinanen (@juha-h), Elena-Ramona - Modroiu, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). - - Documentation Copyrights: - - Copyright © 2005-2008 Voice Sistem SRL - - Copyright © 2003 FhG FOKUS diff --git a/modules/tm/README.md b/modules/tm/README.md new file mode 100644 index 00000000000..adeccff3f81 --- /dev/null +++ b/modules/tm/README.md @@ -0,0 +1,2219 @@ +--- +title: "tm Module" +description: "TM module enables stateful processing of SIP transactions." +--- + +## Admin Guide + + +### Overview + + +TM module enables stateful processing of SIP +transactions. The main use of stateful logic, which is costly in +terms of memory and CPU, is some services +inherently need state. For example, transaction-based accounting +(module acc) needs to process transaction state as opposed to +individual messages, and any kinds of forking must be implemented +statefully. Other use of stateful processing is it trading +CPU caused by retransmission processing for memory. +That makes however only sense if CPU consumption +per request is huge. For example, if you want to avoid costly +DNS resolution for every retransmission of a +request to an unresolvable destination, use stateful mode. Then, +only the initial message burdens server by DNS +queries, subsequent retransmissions will be dropped and will not +result in more processes blocked by DNS resolution. +The price is more memory consumption and higher processing latency. + + +From user's perspective, the major function is t_relay(). It setup +transaction state, absorb retransmissions from upstream, generate +downstream retransmissions and correlate replies to requests. + + +In general, if TM is used, it copies clones of +received SIP messages in shared memory. That costs the memory and +also CPU time (memcpys, lookups, shmem locks, etc.) +Note that non-TM functions operate over the +received message in private memory, that means that any core +operations will have no effect on statefully processed messages after +creating the transactional state. For example, calling record_route +*after* t_relay is pretty useless, as the +RR is added to privately held message whereas its +TM clone is being forwarded. + + +TM is quite big and uneasy to program--lot of +mutexes, shared memory access, malloc and free, timers--you really +need to be careful when you do anything. To simplify +TM programming, there is the instrument of +callbacks. The callback mechanisms allow programmers to register +their functions to specific event. See t_hooks.h for a list of +possible events. + + +Other things programmers may want to know is UAC--it is a very +simplistic code which allows you to generate your own transactions. +Particularly useful for things like NOTIFYs or IM +gateways. The UAC takes care of all the transaction machinery: +retransmissions , FR timeouts, forking, etc. See t_uac prototype +in uac.h for more details. Who wants to see the transaction result +may register for a callback. + + +#### Per-Branch flags + + +First what is the idea with the branch concept: branch route is a +route to be execute separately for each branch before being sent +out - changes in that route should reflect only on that branch. + + +There are several types of flags in OpenSIPS : + + +- *message/transaction* flags - they are +visible everywhere in the transaction (in all routes and in +all sequential replies/request). +- *branch* flags - flags that are visible only +from a specific branch - in all replies and routes connected +to this branch. +- *script* flags - flags that exist only +during script execution. They are not store anywhere and are +lost once the top level route was left. + + +For example: I have a call parallel forking to GW and to a user. And I +would like to know from which branch I will get the final negative +reply (if so). I will set a branch route before relaying the calls +(with the 2 branches). The branch route will be separately executed +for each branch; in the branch going to GW (I can identified it by +looking to RURI), I will set a branch flag. This flag will appear +only in the onreply route run for replied from GW. It will be also be +visible in failure route if the final elected reply belongs to the +GW branch. This flags will not be visible in the other branch +(in routes executing replies from the other branch). + + +For how to define branch flags and use via script, see +[t on branch](#func_t_on_branch) and the setbflag(), resetbflag() and +isbflagset() script functions. + + +Also, modules may set branch flags before transaction creation +(for the moment this feature is not available in script). The +REGISTRAR module was the first to use this type of flags. The NAT flag +is pushed in branch flags instead in message flags + + +#### Timeout-Based Failover + + +Timeouts can be used to trigger failover behavior. E.g. if we send a call +to a gateway and the gateway does not send a provisional response within 3 +seconds, we want to cancel this call and send the call to another +gateway. Another example is to ring a SIP client only for 30 seconds +and then redirect the call to the voicemail. + + +The transaction module exports two types of timeouts: + + +- **[fr timeout](#param_fr_timeout)** - used when no response was +received yet. If there is no response after +*[fr timeout](#param_fr_timeout)* seconds, the timer triggers +(and failure route will be executed if t_on_failure() was +called). For INVITE transactions, if a provisional response was +received, the timeout is reset to *[fr inv timeout](#param_fr_inv_timeout)* +seconds and RT_T2 for all other transactions. Once a final response +is received, the transaction has finished. +- **fr_inv_timeout** - this timeout +starts counting down once a provisional response was received +for an INVITE transaction. + + +For example: You want to have failover if there is no provisional +response after 3 seconds, but you want to ring for 60 seconds. +Thus, set the *[fr timeout](#param_fr_timeout)* to 3 and +*fr_inv_timeout* to 60. + + +#### DNS Failover + + +DNS based failover can be use when relaying stateful requests. +According to RFC 3263, DNS failover should be done on transport level +or transaction level. TM module supports them both. + + +Failover at transport level may be triggered by a failure of sending +out the request message. A failure occurs if the corresponding +interface was found for sending the request, if the TCP connection +was refused or if a generic internal error happened during send. There +is no ICMP error report support. + + +Failover at transaction level may be triggered when the transaction +completed either with a 503 reply, either with a timeout without +any received reply. In such a case, automatically, a new branch will +be forked if any other destination IPs can be used to deliver the +requests. The new branch will be a clone of the winning branch. + + +The set of destinations IPs is step-by-step build (on demand) based on +the NAPTR, SRV and A records available for the destination domain. + + +DNS-based failover is by default applied excepting when this failover +is globally disabled (see the core parameter disable_dns_failover) or +when the relay flag (per transaction) is set (see the t_relay() +function). + + +#### Anycast Scenario + + +Doing a load balancing scenario using +[Anycast IPs](https://en.wikipedia.org/wiki/Anycast), +one might run into an issue where a transaction request comes on +one instance, and the reply (or replies) comes on different ones. +This would normaly break the transaction state, because the local +transaction will start re-transmissios and would eventually timeout. +Moreover, from UA's perspective, the reply whould have been sent, +but since it reaches a proxy that is not aware of that transaction, +it will not be forwarded (nor ACKed in case of INVITES). And from +this point things can escalade quickly. + + +To sort out these problems, the module uses a distributed mechanism +to figure out where the transaction for a specific reply was created. +When an instance receives a reply that does not have an associated +transaction, it replicates it to be handled by the instance that +"owns" it. This is achieved using the +*clusterer* module support. + + +Setting up an anycast scenario is very simple: all the instances +that are part of an anycast secnario must be set up in a cluster +(more info at the [tm replication cluster](#param_tm_replication_cluster) param). +When a transaction is created, a special identifier is appended to +the branch parameter, namely the instance that created the +transaction. When a reply comes in, the transaction module checks who +"owns" the transaction. If the identifier is the +instance's own id, then the reply is processed locally. Otherwise +it is replicated to the node indicated by the id. Replication is +done in a very efficient manner, using the +*proto_bin* transport. + + +Special handling is applied to *CANCEL* and +*ACK* methods. Due to the fact that these +methods do not contain the special identifier in the branch +parameter (since they are generated by the UAC and not by us), +there is no way to determine who "owns" the transaction. +Therefore, if we do not find a local transaction for these +requests, we broadcast them to all the other instances using +the [t anycast replicate](#func_t_anycast_replicate) function. Again, +this is done in a very efficient manner using the +*proto_bin* transport. + + +#### Usage Scope + + +Transaction functions and variables are only designed to be +called on SIP request messages where a transaction can be created, or +in routes that are transaction aware, such as +*branch_route[name]*, +*failure_route[name]* or +*onreply_route[name]*. Using TM functtions or +variables in a route that is not transaction aware, such as +the generic *onreply_route*, +*error_route* or +*timer_route[name, timer]* may lead to undefined +behavior, and most of the time in bogus or malformed signalling. +Therefore it is strongly recommended to avoid using them in non-tm +context aware routes. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *clusterer* module, if the anycast +scenario is enabled (see [tm replication cluster](#param_tm_replication_cluster) +param for more information). + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### fr_timeout (integer) + + +Timeout which is triggered if no final reply for a request or ACK for a +negative INVITE reply arrives (in seconds). + + +*Default value is 30 seconds.* + + +```opensips title="Set fr_timeout parameter" +... +modparam("tm", "fr_timeout", 10) +... +``` + + +#### fr_inv_timeout (integer) + + +Timeout which is triggered if no final reply for an INVITE arrives after a +provisional message was received (in seconds). This timeout starts +counting down once the first provisional response is received. Thus, +fast failover (no 100 trying from gateway) can be achieved by setting +*[fr timeout](#param_fr_timeout)* to low values. +See example below. + + +*Default value is 120 seconds.* + + +```opensips title="Set fr_inv_timeout parameter" +... +modparam("tm", "fr_inv_timeout", 200) +... +``` + + +#### wt_timer (integer) + + +Time for which a transaction stays in memory to absorb delayed +messages after it completed; also, when this timer hits, +retransmission of local cancels is stopped (a puristic but complex +behavior would be not to enter wait state until local branches +are finished by a final reply or FR timer--we simplified). + + +For non-INVITE transaction this timer relates to timer J of RFC 3261 +section 17.2.2. According to the RFC this timer should be 64*T1 +(= 32 seconds). But this would increase memory usage as the transactions +are kept in memory very long. + + +*Default value is 5 seconds.* + + +```opensips title="Set wt_timer parameter" +... +modparam("tm", "wt_timer", 10) +... +``` + + +#### delete_timer (integer) + + +Time after which a to-be-deleted transaction currently ref-ed by a +process will be tried to be deleted again. + + +*Default value is 2 seconds.* + + +```opensips title="Set delete_timer parameter" +... +modparam("tm", "delete_timer", 5) +... +``` + + +#### T1_timer (integer) + + +Retransmission T1 period, in milliseconds. + + +*Default value is 500 milliseconds.* + + +```opensips title="Set T1_timer parameter" +... +modparam("tm", "T1_timer", 700) +... +``` + + +#### T2_timer (integer) + + +Maximum retransmission period, in milliseconds. + + +*Default value is 4000 milliseconds.* + + +```opensips title="Set T2_timer parameter" +... +modparam("tm", "T2_timer", 8000) +... +``` + + +#### ruri_matching (integer) + + +Should be request-uri matching used as a part of pre-3261 transaction +matching as the standard wants us to do so? Turn only off for better +interaction with devices that are broken and send different r-uri in +CANCEL/ACK than in original INVITE. + + +*Default value is 1 (true).* + + +```opensips title="Set ruri_matching parameter" +... +modparam("tm", "ruri_matching", 0) +... +``` + + +#### via1_matching (integer) + + +Should be top most VIA matching used as a part of pre-3261 transaction +matching as the standard wants us to do so? Turn only off for better +interaction with devices that are broken and send different top most +VIA in CANCEL/ACK than in original INVITE. + + +*Default value is 1 (true).* + + +```opensips title="Set via1_matching parameter" +... +modparam("tm", "via1_matching", 0) +... +``` + + +#### unix_tx_timeout (integer) + + +Send timeout to be used by function which use UNIX sockets +(as t_write_unix). + + +*Default value is 2 seconds.* + + +```opensips title="Set unix_tx_timeout parameter" +... +modparam("tm", "unix_tx_timeout", 5) +... +``` + + +#### restart_fr_on_each_reply (integer) + + +If true (non null value), the final response timer will be re-triggered +for each received provisional reply. In this case, final response +timeout may occur after a time longer than *[fr inv timeout](#param_fr_inv_timeout)* +(if UAS keeps sending provisional replies) + + +*Default value is 1 (true).* + + +```opensips title="Set restart_fr_on_each_reply parameter" +... +modparam("tm", "restart_fr_on_each_reply", 0) +... +``` + + +#### tw_append (string) + + +List of additional information to be appended by t_write_req and +t_write_unix functions. + + +*Default value is null string.* + + +Syntax of the parameter is: + + +- *tw_append = append_name':' element (';'element)** +- *element = ( [name '='] variable)* + + +Each element will be appended per line in +"name: value" format. Element +"$rb (message body)" +is the only one which does not accept name; the body it will be +printed all the time at the end, disregarding its position in the +definition string. + + +```opensips title="Set tw_append parameter" +... +modparam("tm", "tw_append", + "test: ua=$hdr(User-Agent) ;avp=$avp(avp);$rb;time=$Ts") +... +``` + + +#### pass_provisional_replies (integer) + + +Enable/disable passing of provisional replies to FIFO applications. + + +*Default value is 0.* + + +```opensips title="Set pass_provisional_replies parameter" +... +modparam("tm", "pass_provisional_replies", 1) +... +``` + + +#### syn_branch (integer) + + +Enable/disable the usage of stateful synonym branch IDs in the +generated Via headers. They are faster but not reboot-safe. + + +*Default value is 1 (use synonym branches).* + + +```opensips title="Set syn_branch parameter" +... +modparam("tm", "syn_branch", 0) +... +``` + + +#### onreply_avp_mode (integer) + + +Describes how the AVPs should be handled in reply route: + + +- *0* - the AVPs will be per message only; they +will not interfere with the AVPS stored in transaction; initially +there will be an empty list and at the end of the route, all AVPs +that were created will be discarded. +- *1* - the AVPs will be the transaction AVPs; +initially the transaction AVPs will be visible; at the end of the +route, the list will attached back to transaction (with all the +changes) + + +In mode 1, you can see the AVPs you set in request route, branch route +or failure route. The side effect is performance as more locking is +required in order to keep the AVP's list integrity. + + +*Default value is 0.* + + +```opensips title="Set onreply_avp_mode parameter" +... +modparam("tm", "onreply_avp_mode", 1) +... +``` + + +#### disable_6xx_block (integer) + + +Tells how the 6xx replies should be internally handled: + + +- *0* - the 6xx replies will block any further +serial forking (adding new branches). This is the RFC3261 +behaviour. +- *1* - the 6xx replies will be handled as any +other negative reply - serial forking will be allowed. +Logically, you need to break RFC3261 if you want to do redirects +to announcement and voicemail services. + + +*Default value is 0.* + + +```opensips title="Set disable_6xx_block parameter" +... +modparam("tm", "disable_6xx_block", 1) +... +``` + + +#### enable_stats (integer) + + +Enables statistics support in TM module - If enabled, the TM module +will internally keep several statistics and export them via the +MI - Management Interface. + + +*Default value is 1 (enabled).* + + +```opensips title="Set enable_stats parameter" +... +modparam("tm", "enable_stats", 0) +... +``` + + +#### minor_branch_flag (string/integer) + + +A branch flag index to be used in script to mark the minor branches +( before t_relay() ). + + +A minor branch is a branch OpenSIPS will not wait to complete during +parallel forking. So, if the rest of the branches are negativly replied +OpenSIPS will not wait for a final answer from the minor branch, but +it will simply cancel it. + + +Main applicability of minor branch is to fork a branch to a media +server for injecting (via 183 Early Media) some pre-call media - of +course, this branch will be transparanent for the rest of the call +branches (from branch selection point of view). + + +*Default value is none (disabled).* + + +```opensips title="Set minor_branch_flag parameter" +... +modparam("tm", "minor_branch_flag", "MINOR_BFLAG") +... +``` + + +#### timer_partitions (integer) + + +The number of partitions for the internal TM timers (retransmissions, +delete, wait, etc). Partitioning the timers increase the throughput +under heavly load by handling timer events in parallel, rather than +all serial. + + +Recomanded range for timer partitions is max 16 (soft limit). + + +*Default value is 1 (disabled).* + + +```opensips title="Set timer_partitions parameter" +... +# Enable two timer partitions +modparam("tm", "timer_partitions", 2) +... +``` + + +#### auto_100trying (integer) + + +This parameter controls if the TM module should automatically +generate an 100 Trying stateful reply when an INVITE transaction +is created. + + +You may want to disable this behavior if you want to control from +script level when the 100 Trying is to be sent out. + + +*Default value is 1 (enabled).* + + +```opensips title="Set auto_100trying parameter" +... +# Disable automatic 100 Trying +modparam("tm", "auto_100trying", 0) +... +``` + + +#### tm_replication_cluster (integer) + + +This parameter should be used in an anycast setup, and specifies +the cluster id of all the nodes that use an anycast IP. + + +Check out the [tm anycast](#anycast_scenario) section for more details. + + +*Anycast replication is disabled by default.* + + +```opensips title="Set tm_replication_cluster parameter" +... +# replicate anycast messages in cluster 1 +modparam("tm", "tm_replication_cluster", 1) +... +``` + + +#### cluster_param (string) + + +This parameter should be used in an anycast setup, and specifies +the name of the parameter used in the VIA branch param to specifiy +the instance id that created the transaction. + + +Check out the [tm anycast](#anycast_scenario) section for more details. + + +*Default value is *cid*.* + + +```opensips title="Set the cluster_param parameter" +... +modparam("tm", "cluster_param", "tid") +... +``` + + +#### cluster_auto_cancel (boolean) + + +This parameter should be used in an anycast setup, and specifies +whether a *CANCEL* message received on a +listener that is marked as anycast should be automatically handled, +or should get in the OpenSIPS script. If this parameter is enabled +(default), *CANCEL* messages received on an +anycast listener will never enter the script, thus making the +script cleaner. + + +Check out the [tm anycast](#anycast_scenario) section for more details. + + +*Default value is *yes* (enabled).* + + +```opensips title="Set the cluster_auto_cancel parameter" +... +# disable auto-cancel handling +modparam("tm", "cluster_auto_cancel", no) +... +``` + + +#### local_request_route (string) + + +This parameter points to a route, which is executed whenever TM is +about to send out a locally generated request (e.g., through the +B2B modules or through MI). + + +The purpose of this route is limited to exposing the content of the +request as SIP message + + +The route is executed with the generated message by TM, incorporating +all modifications. + + +> [!IMPORTANT] +> This route is executed AFTER the local_route (if defined) +> and it expose all the changes from that route. + + +> [!IMPORTANT] +> This route is to be used in a read-only manner, inspection +> only. Any changes you do here will discarded. + + +> [!IMPORTANT] +> This route does not offer any message, transactional or +> dialog context, so do not rely on any variables with scope (like AVPs). + + +```opensips title="Set the local_request_route parameter" +... +# Execute the route "local_request_route" upon sending a request +modparam("tm", "local_request_route", "tm_local_request") + +route[tm_local_request] { + if (is_method("INVITE") && $rb(application/sdp) && !has_totag()) { + $avp(sdp_request) := $rb(application/sdp); + } +} +... +``` + + +#### local_reply_route (string) + + +This parameter points to a route, which is executed whenever TM is +about to send out a locally generated reply (e.g., through the +B2B modules or through MI). + + +The purpose of this route is limited to exposing the content of the +reply as SIP message + + +> [!IMPORTANT] +> This route is to be used in a read-only manner, inspection +> only. Any changes you do here will discarded. + + +> [!IMPORTANT] +> This route does not offer any message, transactional or +> dialog context, so do not rely on any variables with scope (like AVPs). + + +```opensips title="Set the local_reply_route parameter" +... +# Execute the route "tm_local_reply" upon sending a request +modparam("tm", "local_reply_route", "tm_local_reply") + +route[tm_local_reply] { + if (is_method("BYE")) { + $var(rc) = rest_get("http://localhost/qos/delete", + $var(recv_body), $var(recv_ct), $var(rcode)); + } +} + +... +``` + + +### Exported Functions + + +#### t_relay([flags],[outbound_proxy]) + + +Relay a message statefully to destination indicated in current URI. +(If the original URI was rewritten by UsrLoc, RR, strip/prefix, etc., +the new URI will be taken). Returns a negative value on failure--you +may still want to send a negative reply upstream statelessly not to +leave upstream UAC in lurch. + + +The coresponding transaction may or may not be already created. If not +yet created, the function will automatically create it. + + +The function may take two optional parameters. + + +The first parameter is a comma separated list of string flags for +controlling the internal behaviour. The supported flags are: + + +- *no-auto-477* - (old +*0x02* flag) do not internally generate +and send a "477 Send failed (477/TM)" SIP reply in case of a +global forwarding failure (i.e. forwarding for each branch has +failed due to internal errors, bad R-URI, bad message, lack of +network reachability, etc.). + + This flag only applies if the transaction was + not previously created by [t newtran](#func_t_newtran). + When a global forwarding failure occurs, no SIP request is + relayed and therefore no negative SIP reply or timeout will + show up on the failure_route, if one is set. +Useful if you want to implement a failover logic for when none +of the currently created branches can be forwarded to. +- *no-dns-failover* - (old +*0x04* flag) disable the DNS failover +for the transaction. Only first IP will be used. It disables +the failover both at transport and transaction level. +- *pass-reason-hdr* - (old +*0x08* flag) If the request is a CANCEL, +trust and pass further the Reason header from the received +CANCEL - shortly, will propagate the Reason header. +- *allow-no-cancel* - (old +*0x10* flag) Allows OpenSIPS to inspect +and follow the Content-Disposition "no-cancel" indication (if +present). As per RFC3841, section 9.1, the TM module may be +instructed not to cancel all ongoing branches when a 2xx reply +is received. It will keep the pending branches ongoing until +(1) all branches will receive a final reply or (2) the +transactionhits the timeout. + + +The second parameter is a string representing an outbound proxy +(a fixed destination) where the message should be sent. The +destination is specified as "[proto:]host[:port]". If a +destination URI "$du" for this message was set before the +function is called then this value will be used as the destination +instead of the function parameter. + + +In case of error, the function returns the following codes: + + +- *-1* - generic internal error +- *-2* - bad message (parsing errors) +- *-3* - no destination available +(no branches were added or request already cancelled) +- *-4* - bad destination +(unresolvable address) +- *-5* - destination filtered +(black listed) +- *-6* - generic send failed + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="t_relay usage" +... +if (!t_relay()) { + sl_reply_error(); + exit; +} +... +t_relay( ,"tcp:192.168.1.10:5060"); +... +t_relay(0x1, "mydomain.com:5070"); +... +``` + + +#### t_reply(code, reason_phrase) + + +Sends a stateful SIP reply to the currently processed requests. Note +that if the transaction was not created yet, it will automatically +created by internally using the +`t_newtran` function. + + +Meaning of the parameters is as follows: + + +- *code (int)* - Reply code number. +- *reason_phrase (string)* - Reason string. + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + + +```opensips title="t_reply usage" +... +t_reply(404, "Use $rU not found"); +... +``` + + +#### t_reply_with_body(code, reason_phrase, body) + + +Sends a stateful SIP reply with a body to the currently processed +requests. Note that if the transaction was not created yet, it will +automatically created by internally using the +`t_newtran` function. + + +Meaning of the parameters is as follows: + + +- *code (int)* - Reply code number. +- *reason_phrase (string)* - Reason string. +- *body (string)* - Reply body. + + +This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. + + +```opensips title="t_reply_with_body usage" +... + if(is_method("INVITE")) + { + append_to_reply("Contact: $var(contact)\r\n" + "Content-Type: application/sdp\r\n"); + t_reply_with_body(200, "Ok", $var(body)); + exit; + } +... +``` + + +#### t_newtran() + + +Creates the SIP transaction for the currently processed SIP request, +thus switching to stateful processing. For INVITE requests, a 100 +Trying reply will be immediately sent, unless +[auto 100trying](#param_auto_100trying) is disabled. Once a SIP +transaction is created, calling [t newtran](#func_t_newtran) for +retransmitted requests will end the OpenSIPS script execution, with the +lastly sent reply being retransmitted upstream. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="t_newtran usage" +... +t_newtran(); # 100 Trying is fired here +xlog("doing my complicated routing logic\n"); +.... +t_relay(); # send the call further +... +``` + + +#### t_check_trans() + + +Returns true if the current request is associated to a transaction. +The relationship between the request and transaction is defined as +follows: + + +- *non-CANCEL/non-ACK requests* - if the +request belongs to a transaction (it's a retransmision), the +function will do a standard processing of the retransmission and +will break/stop the script. The function returns false if the +request is not a retransmission. +- *CANCEL request* - true if the cancelled +INVITE transaction exists. +- *ACK request* - true if the ACK is a +hop-by-hop ACK (to a negative reply) corresponding to an previous +INVITE transaction. [!IMPORTANT] this function returns false (return +code *-2*) for end-to-end ACKs (to 2xx replies +from a different transaction). + + +> [!NOTE] +> To detect retransmissions using this function you have to make +> sure that the initial request has already created a transaction, e.g. +> by using t_relay(). If the processing of requests may take long time +> (e.g. DB lookups) and the retransmission arrives before t_relay() is +> called, you can use the t_newtran() function to manually create a +> transaction. + + +This function can be used from REQUEST_ROUTE and BRANCH_ROUTE. + + +```opensips title="t_check_trans usage" +... +if ( is_method("CANCEL") ) { + if ( t_check_trans() ) + t_relay(); + exit; +} +... +``` + + +#### t_check_status(re) + + +Returns true if the regualr expression "re" match the +reply code of the response message as follows: + + +- *in routing block* - the code of the +last sent reply. +- *in on_reply block* - the code of the +current received reply. +- *in on_failure block* - the code of the +selected negative final reply. + + +This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, +FAILURE_ROUTE and BRANCH_ROUTE . + + +```opensips title="t_check_status usage" +... +if (t_check_status("(487)|(408)")) { + log("487 or 408 negative reply\n"); +} +... +``` + + +#### t_local_replied(reply) + + +Returns true if all or last (depending of the parameter) reply(es) were +local generated (and not received). + + +Parameter may be "all" or "last". + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +FAILURE_ROUTE and ONREPLY_ROUTE. + + +```opensips title="t_local_replied usage" +... +if (t_local_replied("all")) { + log ("no reply received\n"); +} +... +``` + + +#### t_was_cancelled() + + +Retuns true if called for an INVITE transaction that was explicitly +cancelled by UAC side via a CANCEL request. + + +This function can be used from ONREPLY_ROUTE, FAILURE_ROUTE. + + +```opensips title="t_was_cancelled usage" +... +if (t_was_cancelled()) { + log("transaction was cancelled by UAC\n"); +} +... +``` + + +#### t_cancel_branch([flags]) + + +This function is to be call when a reply is received for cancelling a +set of branches (see flags) of the current call. + + +Meaning of the parameters is as follows: + + +- *flags (string, optional)* - set of flags +(char based flags) to control what branches to be cancelled: + + - *a* - all - cancel all pending +branches + - *o* - others - cancel all the other +pending branches except the current one + - *empty* - current - cancel only the +current branch + + +This function can be used from ONREPLY_ROUTE. + + +```opensips title="t_cancel_branch usage" +onreply_route[3] { +... + if (t_check_status(183)) { + # no support for early media + t_cancel_branch(); + } +... +} +``` + + +#### t_new_request( method, RURI, from, to [, body[, ctx]]) + + +This function generates and sends out a new SIP request (in a stateful way). +The new request is completly unrelated to the currently processed SIP message. + + +Meaning of the parameters is as follows (all do accept variables): + + +- *method (string)* - the SIP method +- *RURI (string)* - the SIP Request URI (the request +will be sent out to this destination) +- *from (string)* - the SIP From hdr information as +"[display ]URI" +- *to (string)* - the SIP To hdr information as +"[display ]URI" +- *body (string, optional)* - the SIP body content +starting with the content type string: "conten_type body" +- *ctx (string, optional)* - a context string that will +be added to the new transaction as an AVP with name "uac_ctx" (it may be visible +in local route) + + +```opensips title="t_new_request usage" +... + # send a MESSAGE request + t_new_request("MESSAGE","sip:alice@192.168.2.2","BOB sip:userB@mydomain.net","ALICE sip:userA@mydomain.net","text/plain Hello Alice!")) { +... +``` + + +#### t_on_failure(failure_route) + + +Sets reply routing block, to which control is passed after a +transaction completed with a negative result but before sending a +final reply. In the referred block, you can either start a new branch +(good for services such as forward_on_no_reply) or send a final reply +on your own (good for example for message silo, which received a +negative reply from upstream and wants to tell upstream "202 I +will take care of it"). + + +As not all functions are available from failure route, please check +the documentation for each function to see the permissions. +Any other commands may result in unpredictable behavior and +possible server failure. + + +Only one failure_route can be armed for a request. If you use many +times t_on_failure(), only the last one has effect. + + +Note that whenever failure_route is entered, RURI is set to value +of the winning branch. + + +Meaning of the parameters is as follows: + + +- *failure_route (string)* - Reply route block to be +called. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +ONREPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="t_on_failure usage" +... +route { + t_on_failure("1"); + t_relay(); +} + +failure_route[1] { + seturi("sip:user@voicemail"); + t_relay(); +} +... +``` + + +#### t_on_reply(reply_route) + + +Sets reply routing block, to which control is passed each time a reply +(provisional or final) for the transaction is received. +The route is not called for local generated replies! In the referred +block, you can inspect the reply and perform text operations on it. + + +As not all functions are available from this type of route, please +check the documentation for each function to see the permissions. +Any other commands may result in unpredictable behavior and +possible server failure. + + +If called from branch route, the reply route will be set only for the +current branch - that's it, it will be called only for relies belonging +to that particular branch. Of course, from branch route, you can set +different reply routes for each branch. + + +When called from a non-branc route, the reply route will be globally +set for tha current transaction - it will be called for all replies +belonging to that transaction. NOTE that only +*one>* onreply_route can be armed for a transaction. +If you use many times t_on_reply(), only the last one has effect. + + +If the processed reply is provisionla reply (1xx code), by calling +the drop() function (exported by core), the execution of the route +will end and the reply will not be forwarded further. + + +Meaning of the parameters is as follows: + + +- *reply_route (string)* - Reply route block to be +called. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +ONREPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="t_on_reply usage" +... +route { + seturi("sip:bob@opensips.org"); # first branch + append_branch("sip:alice@opensips.org"); # second branch + + t_on_reply("global"); # the "global" reply route + # is set the whole transaction + t_on_branch("1"); + + t_relay(); +} + +branch_route[1] { + if ($rU=="alice") + t_on_reply("alice"); # the "alice" reply route + # is set only for second branch +} + +onreply_route[alice] { + xlog("received reply from alice\n"); +} + +onreply_route[global] { + if (t_check_status("1[0-9][0-9]")) { + setflag(LOG_FLAG); + log("provisional reply received\n"); + if (t_check_status("183")) + drop; + } +} +... +``` + + +#### t_on_branch(branch_route) + + +Sets a branch route to be execute separately for each branch of the +transaction before being sent out - changes in that route should +reflect only on that branch. + + +As not all functions are available from this type of route, please +check the documentation for each function to see the permissions. +Any other commands may result in unpredictable behavior and +possible server failure. + + +Only one branch_route can be armed for a request. If you use many +time t_on_branch(), only the last one has effect. + + +By calling the drop() function (exported by core), the execution of +the branch route will end and the branch will not be forwarded further. + + +Meaning of the parameters is as follows: + + +- *branch_route (string)* - Branch route block to be +called. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, +ONREPLY_ROUTE and FAILURE_ROUTE. + + +```opensips title="t_on_branch usage" +... +route { + t_on_branch("1"); + t_relay(); +} + +branch_route[1] { + if ($ru=~"bad_uri") { + xlog("dropping branch $ru \n"); + drop; + } + if ($ru=~"GW_uri") { + append_rpid(); + } +} +... +``` + + +#### t_inject_branches(source[,flags]) + + +The function adds new SIP branches (destinations) to an existing +transaction and fires them (sends them out). The transaction may +already have ongoing branches (like in ringing state), which will not +be affected by the injection of the new branches. Also it is possible +for the transaction not to have any ongoing branches at the moment of +the injection (still, the transaction must wait for new branches, even +if all existing ones are completed - see +the [t wait for new branches](#func_t_wait_for_new_branches) function for this). + + +The main usage scenario for this function (and also what makes it +different from [t relay](#func_t_relay) is the ability to add new +branches to an ongoing transaction from script routes not related to +the transaction ( like timer route, event route, notification route, +and other). In such routes, other functions/module used before the +injection will point to the transaction to be affected by this +injection - see the *event_routing* module. + + +Parameters: + + +- *source (string)* - where to take the description +for the new branches to be injected. It can be: + - *event* - the branch will be taken from + the event attributes exposed in an event notification route + (see *event_routing* module). + - *msg* - the branches will be taken from + the RURI of the SIP message and from the additional + branches (created by append_branch() function or similar). +- *flags (string, optional)* - some additional flags +related to the injection process: + - *cancel* or *c* - cancel all the ongoing existing branches from the transaction before injecting the new branches. + - *l* (last) - this is the last injected branch on this transaction, do not wait for any other branches to be injected. + + +```opensips title="t_inject_branches usage" +... +route[event_notification] { + t_inject_branches("event"); +} +... +``` + + +#### t_wait_for_new_branches([branches]) + + +This function instructs the existing SIP transaction to wait for new +branches to be injected even after the completion of the existing +branches. This waiting will be done until the Final Response INVITE +timer (fr_inv_timeout) will hit for the transaction OR until the +maximum number of branches were injected (see parameter); of course, +the waiting will be terminated if the transaction gets a 2xx final +reply from one of the branches. + + +Normally if you have a transaction with two branches and +they get, let's say, a 404 and 486 replies, the branches will be +completed and transaction terminated by sending the 404 reply to the +caller. Still, if you do *t_wait_for_new_branches* +before relaying the transaction, the transaction will not terminate +upon the completion of the branches and not send the 404 to the caller + - it will wait for new branches to be injected (see +[t inject branches](#func_t_inject_branches) function) until the fr_inv timer +hits. + + +Parameters: + + +- *branches (integer, options)* - what is the +maximum number of branches to be waited for. + + +```opensips title="t_wait_for_new_branches usage" +... +t_newtran(); +t_wait_for_new_branches(); +t_relay(); +... +``` + + +#### t_wait_no_more_branches() + + +This function instructs the existing SIP transaction to stop wait +for new any new branches to be injected. This functions should be +used for a transaction that is waiting for dynamic branches, via the +[t wait for new branches](#func_t_wait_for_new_branches) function. + + +Usage scenario: your transaction is waiting for dynamic new branches +(as a reusult of Push Notification). To a point, on an ongoing +branch you receive a final reply - and the fact that the branch fails +translates into stop waiting for any more branche (this is an example +of a logic on deciding how long to wait for more branches, depending +on the answers you get from various devices, fix or mobile). + + +```opensips title="t_wait_no_more_branches usage" +... +t_wait_no_more_branches(); +... +``` + + +#### t_add_hdrs("sip_hdrs") + + +Attach a set of headers to the existing transaction - these headers +will be appended to all requests related to the transaction (outgoing +branches, local ACKS, CANCELs). + + +Parameters: + + +- *sip_hdrs (string)* + + +```opensips title="t_add_hdrs usage" +... +t_add_hdrs("X-origin: 1.1.1.1\r\n"); +... +``` + + +#### t_add_cancel_reason("Reason_hdr") + + +This function is used to enforce from the script level a custom +"Reason" header into a CANCEL request. Normally, the Reason header is +inherited form the received CANCEL (note that CANCEL propagates in a +hop-by-hop manner - it is re-generated at each hop), but this function +can overwrite it. It must be called before relaying the CANCEL request +and its input must be a fully formated Reason header with name, body +and CRLF. + + +Parameters: + + +- *reason_hdr (string)* + + +```opensips title="t_add_cancel_reason usage" +... +t_add_cancel_reason("Reason: SIP ;cause=200 ;text=\"Call completed elsewhere\"\r\n"); +t_relay(); +... +``` + + +#### t_replicate(URI,[flags]) + + +Replicates a request to another destination. No information due the +replicated request (like reply code) will be forwarded to the +original SIP UAC. + + +The destination is specified by a SIP URI. If multiple destinations are +to be used, the additional SIP URIs have to be set as branches. + + +Parameters: + + +- *uri (string)* +- *flags (string, optional)* - a set of flags for +controlling the internal behaviour - for description see the above +"t_relay([flags])" function. Note that only +*no-dns-failover* is +applicable here. + + +This functions can be used from REQUEST_ROUTE. + + +```opensips title="t_replicate usage" +... +t_replicate("sip:1.2.3.4:5060"); +t_replicate("sip:1.2.3.4:5060;transport=tcp"); +t_replicate("sip:1.2.3.4",0x4); +... +``` + + +#### t_write_req(info,fifo) t_write_unix(info,sock) + + +Write via FIFO file or UNIX socket a lot of information regarding the +request. Which information should be written may be control via the +"tw_append" parameter. + + +Parameters: + + +- *info (string)* +- *path (string)* + + +This functions can be used from REQUEST_ROUTE, FAILURE_ROUTE and +BRANCH_ROUTE. + + +```opensips title="t_write_req/unix usage" +... +modparam("tm","tw_append","append1:Email=$avp(email);UA=$ua") +modparam("tm","tw_append","append2:body=$rb") +... +t_write_req("voicemail/append1","/tmp/appx_fifo"); +... +t_write_unix("logger/append2","/var/run/logger.sock"); +... +``` + + +#### t_flush_flags() + + +Flush the flags from current request into the already created +transaction. It make sense only in routing block if the transaction was +created via t_newtran() and the flags have been altered since. + + +This function can be used from REQUEST_ROUTE and BRANCH_ROUTE . + + +```opensips title="t_flush_flags usage" +... +t_flush_flags(); +... +``` + + +#### t_anycast_replicate() + + +This function is used in an anycast setup to replicate a +*CANCEL* or *ACK* method +for whom there are no local transactions found. The function +broadcasts the message to all the other nodes in the cluster, +but only the "owner" of the transaction will be +able to handle it. + + +```opensips title="t_anycast_replicate usage" +... +if (is_method("ACK|CANCEL") && !t_check_trans()) { + t_anycast_replicate(); + exit; +} +... +``` + + +#### t_reply_by_callid(code, reason_phrase, [callid], [cseq]) + + +This function is used to send a reply to an existing INVITE +transaction. The usual use case is when OpenSIPS is used as an UAS +and when an INVITE is receveid, it is "parked" locally on +OpenSIPS by replying to it with +"t_reply(180, "Ringing")" or +"t_reply(183, "Session Progress")" +and later we need to handle CANCEL or BYE for it and send +'487 Request Terminated' to the original INVITE transaction. + + +The callid and cseq used to identify the transaction +will be obtained from the current messsage being processed. +But they can be passed explicitly so that for example we can +handle a BYE where the cseq must be the cseq +of the INVITE minus one. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="t_reply_by_callid usage" +... +route{ + if($rU == "LOCAL_PARK") { + if(is_method("INVITE")) { + $T_fr_timeout = 10; + $T_fr_inv_timeout = 10; + append_to_reply("Contact: sip:LOCAL_PARK@$socket_in(ip):$socket_in(port)\r\n"); + t_reply(180, "Ringing"); + t_wait_for_new_branches(); + } else if(is_method("CANCEL")) { + if(!t_reply_by_callid(487, "Request Terminated")) { + sl_send_reply(481, "Call Leg/Transaction Does Not Exist"); + } else { + sl_send_reply(200, "OK"); + } + } else if(is_method("BYE")) { + $var(prev_cseq) = ($(cs{s.int}) - 1); + if(!t_reply_by_callid(487, "Request Terminated", , $var(prev_cseq))) { + sl_send_reply(481, "Call Leg/Transaction Does Not Exist"); + } else { + sl_send_reply(200, "OK"); + } + } else if(is_method("ACK")) { + t_relay(); + } + exit; + } +} +... +``` + + +#### t_get_branch_idx_by_attr(attr, [val_str], [val_int], [result_var], [offset]) + + +This function may be used to search for the index of another branch +of the current transaction. The searching is done based on the +per-branch attribute - you need to provide the name of the attribute +at least. Optionally you can provide a value (string or integer) for +the attribute used for searching. As input, the function may take an +optional branch offset (absolute value, covering all branches of the +transaction) where the search should start from. + + +The function returns true if a branch (having the given name and +value for the attribute) was found. The status of the branch (like +if ongoing, completed ) is not relevant. If found, the "result_var" +variable will be populated with the branch index (as integer). + + +This function can be used from ONREPLY_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="t_get_branch_idx_by_attr usage" +... + # search for a branch which has the "name" attribute + # with string value "pstn" + if (t_get_branch_idx_by_attr("name", "pstn", , $var(idx))) { + xlog("found branch has index $var(idx)\n"); + } +... +``` + + +### Exported Pseudo-Variables + + +Exported variables are listed in the next sections. + + +#### $T_branch_idx + + +*$T_branch_idx* - the index (starting with 0 +for the first branch) of the currently proccessed branch. This +index makes sense only in BRANCH and REPLY routes (where the +processing is per branch) and in FAILURE route (where it points +to the branch with the last final reply on the transaction). In all +the other types of routes, the value of this index will be NULL. + + +#### $T_reply_code + + +*$T_reply_code* - the code of the reply, as +follows: in request_route will be the last stateful sent reply; +in reply_route will be the current processed reply; in +failure_route will be the negative winning reply. In case of +no-reply or error, '0' value is returned. + + +#### $T_fr_timeout + + +*$T_fr_timeout (R/W)* - the timeout +for the final reply to the current transaction + + +With each different +request received, *$T_fr_timeout* will initially +be equal to the +**[fr timeout](#param_fr_timeout)** parameter. + + +*"$T_fr_timeout = NULL;"* will reset it to +**[fr timeout](#param_fr_timeout)**. + + +#### $T_fr_inv_timeout + + +*$T_fr_inv_timeout (R/W)* - the timeout +for the final reply to an INVITE request, after a 1XX reply +was received. This variable may also be set in an onreply_route +(e.g. on 180 Ringing, after 100 Trying) and still take effect. + + +With each different request received, +*$T_fr_inv_timeout* will initially be equal to the +**[fr inv timeout](#param_fr_inv_timeout)** parameter. + + +*"$T_fr_inv_timeout = NULL;"* will reset it to +**[fr inv timeout](#param_fr_inv_timeout)**. + + +#### $T_ruri + + +*$T_ruri* - the ruri of the current branch; this +information is taken from the transaction structure, so you can +access this information for any sip message (request/reply) that +has a transaction. + + +#### $bavp(name) + + +*$bavp(name)* - a particular type of avp that +can have different values for each branch. They can only be used in +BRANCH, REPLY and FAILURE routes. Otherwise NULL value is returned. + + +#### $T_id + + +*$T_id* - returns the ID of the current +transaction. The ID is an opaque hexa string, unique for each +transaction. If there is no current transaction, NULL value is +returned. + + +#### $T_branch_last_reply_code + + +*$T_branch_last_reply_code* - returns the last reply +code received for a branch specified as parameter. If no parameter is +specified, the last reply for the current branch is retrieved. + + +#### $tm.branch.uri[] + + +*$tm.branch.uri* - gives read-only +access over the Request URI (as string) of a TM existing +branch. The status of the branch (completed, ongoing, etc) +is not relevant. + + +The TM (UAC side) branches are created when the request is +sent to new destinations via "t_relay()" or "t_inject()". + + +The indexing of the branches starts from 0, giving access to +all branches (past and active) of the transaction. Nevertheless +the indexing supports two optional suffixes, to simplify the +scripting: + + +- */active* - the indexing starts also +from 0, but it is relative to the last set of branches - +the parallel branches created by the last "t_relay()"-ing. +- */all* - similar to "no suffix" case, +meaning it is an absolute index, covering all the +branches of the trasactions (resulted from all "t_relay()"s +performed over the transaction). + + +IF no index is specified, the current branch used. This depends +on the scripting context. Like in reply route, the current +branch is the branch the reply came for; in branch route, the +current branch is the branch to be sent out; in failure route, +the current branch is the winning branch. + + +> [!NOTE] +> The index ALL ( "*" ) is not supported. + +> [!NOTE] +> In branch route, only the "$tm.branch.attr" and +> "$tm.branch.flag" variables work for the current branch +> (the rest of the branch related variables will return NULL). + +> [!NOTE] +> Negative values are accepted, meaning indexing from the +> end ( -1 is the latest/higher branch). + + +The variable can be used in BRANCH, ONREPLY and FAILURE routes. + + +#### $tm.branch.duri[] + + +*$tm.branch.duri* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the Detination-URI value of the branch. + + +#### $tm.branch.path[] + + +*$tm.branch.path* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the PATH value of the branch. + + +#### $tm.branch.q[] + + +*$tm.branch.q* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the Q value of the branch. + + +#### $tm.branch.flags[] + + +*$tm.branch.flags* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the list (comma separated) of per-branch flags which are +set for the branch. + + +#### $tm.branch.socket[] + + +*$tm.branch.socket* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the socket description (proto:ip:port) used for sending the +branch out. + + +#### $tm.branch.flag()[] + + +*$tm.branch.flag(name)* - similar to +**[tm branch uri](#pv_tm_branch_uri)**, but gives read/write access to a single branch flag (by its name). + + +The accepted values are 0 for FALSE, pozitive non-zero for +TRUE. The returned values are 0 for FALSE and 1 for TRUE. + + +The flags operated here are the same as the bflags you can +operated with via the "[re]setbflag()" functions. + + +#### $tm.branch.attr()[] + + +*$tm.branch.attr(name)* - similar to +**[tm branch uri](#pv_tm_branch_uri)**, but gives read/write access to the attributed attached to the branch. + + +An attribute can have whatever name (no need to be +pre-defined) and it can have a single value (at a time), +string or integer. + + +#### $tm.branch.last_received[] + + +*$tm.branch.last_received* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the reply code of the last received reply (from the +network) on this branch. NULL is returned in no reply was +received so far. + + +#### $tm.branch.type[] + + +*$tm.branch.type* - 100% similar to +**[tm branch uri](#pv_tm_branch_uri)**, but returning the type of the current branch. This may be "phone" if it +not a real branch (has no SIP signalling, used by waiting for +branch injection) or "sip" (a real signalling branch). + + +### Exported MI Functions + + +#### t_uac_dlg + + +Generates and sends a local SIP request. + + +Parameters: + + +- *method* - request method +- *ruri* - request SIP URI +- *headers* - set of additional headers to +be added to the request; at least +"From" and "To" headers must be +specified) +- *next_hop* (optional) - next hop SIP URI (OBP). +- *socket* (optional) - local socket to be used for +sending the request. +- *body* (optional) - request body (if present, requires the +"Content-Type" and "Content-length" +headers) + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi t_uac_dlg method=INVITE ruri="sip:alice@127.0.0.1:7050" headers="From: sip:bobster@127.0.0.1:1337\r\nTo: sip:alice@127.0.0.1:7050\r\nContact: sip:bobster@127.0.0.1:1337\r\n" +``` + + +#### t_uac_cancel + + +Generates and sends a CANCEL for an existing SIP request. + + +Parameters: + + +- *callid* - callid of the INVITE request +to be cancelled. +- *cseq* - cseq of the INVITE request to be +cancelled. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi t_uac_cancel "1-23454@127.0.0.1" "1 INVITE" +``` + + +#### t_hash + + +Gets information about the load of TM internal hash table. + + +Parameters: + + +- *none* + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi t_hash +``` + + +#### t_reply + + +Generates and sends a reply for an existing inbound SIP transaction. + + +Parameters: + + +- *code* - reply code +- *reason* - reason phrase. +- *trans_id* - transaction identifier +(has the hash_entry:label format) +- *to_tag* - To tag to be added to TO header +- *new_headers* (optional) - extra headers to be +appended to the reply. +- *body* - (optional) reply body (if present, requires the +"Content-Type" and "Content-length" +headers) + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi t_reply 403 Forbidden 46961:1279687637 abcde . +``` + + +### Exported Statistics + + +Exported statistics are listed in the next sections. All statistics +except "inuse_transactions" can be reset. + + +#### received_replies + + +Total number of total replies received by TM module. + + +#### relayed_replies + + +Total number of replies received and relayed by TM module. + + +#### local_replies + + +Total number of replies local generated by TM module. + + +#### UAS_transactions + + +Total number of transactions created by received requests. + + +#### UAC_transactions + + +Total number of transactions created by local generated requests. + + +#### 2xx_transactions + + +Total number of transactions completed with 2xx replies. + + +#### 3xx_transactions + + +Total number of transactions completed with 3xx replies. + + +#### 4xx_transactions + + +Total number of transactions completed with 4xx replies. + + +#### 5xx_transactions + + +Total number of transactions completed with 5xx replies. + + +#### 6xx_transactions + + +Total number of transactions completed with 6xx replies. + + +#### inuse_transactions + + +Number of transactions existing in memory at current time. + + +#### retransmission_req_T1_1 + + +Number of request retransmissions due to T1 1 timer, +the first retransmission interval (typical 500ms). + + +#### retransmission_req_T1_2 + + +Number of request retransmissions due to T1 2 timer, +the second retransmission interval (typical 1s). + + +#### retransmission_req_T1_3 + + +Number of request retransmissions due to T1 3 timer, +the third retransmission interval (typical 2s). + + +#### retransmission_req_T2 + + +Number of request retransmissions due to T2 , +the final retransmission interval (typical 4s). + + +#### retransmission_rpl_T2 + + +Number of reply retransmissions, all done with the same +retransmission interval T2, typical 4s. + + +#### timeout_finalresponse + + +Number of transactional timeouts without receiving any kind of reply (not +even provisional) from the B side. Such timeouts indicate a +communication / reachability issue. Note: a single transaction may count +multiple such timeouts due forking. + + +#### timeout_finalresponse + + +Number of transactional INVITE timeouts without receiving a FINAL reply +(provisional may be received) from the B side. Such timeouts indicate a +"not answer" event and it is not a signalling issue. +Note: a single transaction may count multiple such timeouts due forking. + + +## Developer Guide + + +### Functions + + +#### load_tm(*import_structure) + + +For programmatic use only--import the TM API. +See the cpl_c, acc or jabber modules to see how it works. + + +Meaning of the parameters is as follows: + + +- *import_structure* - Pointer to +the import structure - see "struct tm_binds" in +modules/tm/tm_load.h + + +## Frequently Asked Questions + + +**Q: What happened with old cancel_call() function** + + +The function was replace (as functionality) by cancel_branch("a") - +cancel all braches. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tm/cluster.c b/modules/tm/cluster.c index 467eb8429c5..3bdff5517c0 100644 --- a/modules/tm/cluster.c +++ b/modules/tm/cluster.c @@ -47,10 +47,12 @@ struct clusterer_binds cluster_api; static void tm_repl_cancel(bin_packet_t *packet, str *buf, struct receive_info *ri) { + static context_p my_ctx = NULL; int itmp; char *tmp; str stmp; struct cell *t; + context_p old_ctx; /* build a nice static message, exactly how t_lookupOriginalT() expects */ struct sip_msg msg; struct via_body via; @@ -119,6 +121,19 @@ static void tm_repl_cancel(bin_packet_t *packet, str *buf, struct receive_info * LM_DBG("Got CANCEL with branch id=%.*s\n", branch.value.len, branch.value.s); + old_ctx = current_processing_ctx; + + if (my_ctx==NULL) { + my_ctx = context_alloc(CONTEXT_GLOBAL); + if (my_ctx==NULL) { + LM_ERR("failed to alloc new ctx in pkg\n"); + free_sip_msg(&msg); + return; + } + } + memset( my_ctx, 0, context_size(CONTEXT_GLOBAL) ); + set_global_context(my_ctx); + /* try to get the transaction */ set_t(T_UNDEFINED); /* set undefined, because we might have already got a cancel here */ reset_cancelled_t(); @@ -126,7 +141,7 @@ static void tm_repl_cancel(bin_packet_t *packet, str *buf, struct receive_info * /* if transaction is not here, must be somebody else's */ if (!t) { LM_DBG("Original transaction not here!\n"); - return; + goto cleanup_ctx; } /* transaction is located here - do a proper parsing if not done already */ @@ -159,6 +174,13 @@ static void tm_repl_cancel(bin_packet_t *packet, str *buf, struct receive_info * if ((t=get_t()) != NULL && t != T_UNDEFINED) t_unref_cell(t); +cleanup_ctx: + if (current_processing_ctx==NULL) + my_ctx=NULL; + else + context_destroy(CONTEXT_GLOBAL, my_ctx); + set_global_context(old_ctx); + free_sip_msg(&msg); } @@ -388,7 +410,7 @@ static void *tm_replicate_cancel(struct sip_msg *msg) break; } bin_free_packet(&packet); - return NULL; /* dummy return to comply with TM_BIN_PUSH() */ + return rc == CLUSTERER_SEND_SUCCESS ? (void *)1 : NULL; } #undef TM_BIN_PUSH /** @@ -432,7 +454,7 @@ static int tm_replicate_broadcast(struct sip_msg *msg) bin_packet_t *packet = tm_replicate_packet(msg, TM_CLUSTER_REQUEST); if (!packet) - return -1; + return 0; rc = cluster_api.send_all(packet, tm_repl_cluster); switch (rc) { @@ -453,7 +475,7 @@ static int tm_replicate_broadcast(struct sip_msg *msg) break; } bin_free_packet(packet); - return 0; + return rc == CLUSTERER_SEND_SUCCESS; } /** diff --git a/modules/tm/doc/contributors.xml b/modules/tm/doc/contributors.xml deleted file mode 100644 index 667c3d0687d..00000000000 --- a/modules/tm/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 1119 - 646 - 22978 - 16883 - - - 2. - Jiri Kuthan (@jiriatipteldotorg) - 541 - 198 - 18723 - 11167 - - - 3. - Jan Janak (@janakj) - 162 - 76 - 6462 - 1840 - - - 4. - Razvan Crainea (@razvancrainea) - 146 - 113 - 2081 - 877 - - - 5. - Andrei Pelinescu-Onciul - 146 - 105 - 2447 - 1210 - - - 6. - Liviu Chircu (@liviuchircu) - 119 - 91 - 1319 - 946 - - - 7. - Vlad Paiu (@vladpaiu) - 45 - 33 - 675 - 339 - - - 8. - Daniel-Constantin Mierla (@miconda) - 43 - 37 - 322 - 166 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 40 - 18 - 916 - 826 - - - 10. - Anca Vamanu - 37 - 19 - 778 - 651 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Dan Pascu (@danpascu), Maksym Sobolyev (@sobomax), Ovidiu Sas (@ovidiusas), Juha Heinanen (@juha-h), Ionut Ionita (@ionutrazvanionita), Raphael Coeffic, Nils Ohlmeier, Klaus Darilion, Peter Lemenkov (@lemenkov), Andreas Granig, Elias Baixas, Marcus Hunger, Christophe Sollet (@csollet), Jeffrey Magder, Ezequiel Lovelle (@lovelle), Carsten Bock, Saúl Ibarra Corretgé (@saghul), Elena-Ramona Modroiu, John Riordan, Julián Moreno Patiño, Andrei Dragus, Jesus Rodrigues, Konstantin Bokarius, Aron Podrigal (@ar45), Anonymous, Dusan Klinec (@ph4r05), Mark Dalby, Walter Doekes (@wdoekes), Alexey Vasilyev (@vasilevalex), Fabian Gast (@fgast), Nick Altmann (@nikbyte), Zero King (@l2dy), Edson Gellert Schubert, MayamaTakeshi, Ingo Wolfsberger, Daniel Hsueh. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Razvan Crainea (@razvancrainea) - Jul 2010 - Oct 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jan 2013 - Oct 2025 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Nov 2001 - Sep 2025 - - - 4. - Vlad Paiu (@vladpaiu) - Jun 2011 - Apr 2025 - - - 5. - Carsten Bock - Mar 2024 - Mar 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Mar 2004 - Nov 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2023 - - - 8. - MayamaTakeshi - Oct 2022 - Oct 2022 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Feb 2021 - - - 10. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Fabian Gast (@fgast), Aron Podrigal (@ar45), Alexey Vasilyev (@vasilevalex), Ionut Ionita (@ionutrazvanionita), Julián Moreno Patiño, Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Dusan Klinec (@ph4r05), Ezequiel Lovelle (@lovelle), Walter Doekes (@wdoekes), Christophe Sollet (@csollet), Saúl Ibarra Corretgé (@saghul), Anonymous, Mark Dalby, Anca Vamanu, Andrei Dragus, John Riordan, Henning Westerholt (@henningw), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Marcus Hunger, Juha Heinanen (@juha-h), Jeffrey Magder, Elias Baixas, Daniel Hsueh, Andreas Granig, Elena-Ramona Modroiu, Ingo Wolfsberger, Andrei Pelinescu-Onciul, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg), Raphael Coeffic, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Carsten Bock, Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Fabian Gast (@fgast), Alexey Vasilyev (@vasilevalex), Peter Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Anca Vamanu, Henning Westerholt (@henningw), Klaus Darilion, Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Dan Pascu (@danpascu), Juha Heinanen (@juha-h), Elena-Ramona Modroiu, Jan Janak (@janakj), Jiri Kuthan (@jiriatipteldotorg). -
- -
diff --git a/modules/tm/doc/tm.xml b/modules/tm/doc/tm.xml deleted file mode 100644 index 20510ca7df3..00000000000 --- a/modules/tm/doc/tm.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - tm Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2008 &voicesystem; - ©right; 2003 &fhg; - diff --git a/modules/tm/doc/tm_admin.xml b/modules/tm/doc/tm_admin.xml deleted file mode 100644 index 115c8eee4b1..00000000000 --- a/modules/tm/doc/tm_admin.xml +++ /dev/null @@ -1,2569 +0,0 @@ - - - - - &adminguide; - -
- Overview - - TM module enables stateful processing of SIP - transactions. The main use of stateful logic, which is costly in - terms of memory and CPU, is some services - inherently need state. For example, transaction-based accounting - (module acc) needs to process transaction state as opposed to - individual messages, and any kinds of forking must be implemented - statefully. Other use of stateful processing is it trading - CPU caused by retransmission processing for memory. - That makes however only sense if CPU consumption - per request is huge. For example, if you want to avoid costly - DNS resolution for every retransmission of a - request to an unresolvable destination, use stateful mode. Then, - only the initial message burdens server by DNS - queries, subsequent retransmissions will be dropped and will not - result in more processes blocked by DNS resolution. - The price is more memory consumption and higher processing latency. - - - From user's perspective, the major function is t_relay(). It setup - transaction state, absorb retransmissions from upstream, generate - downstream retransmissions and correlate replies to requests. - - - In general, if TM is used, it copies clones of - received SIP messages in shared memory. That costs the memory and - also CPU time (memcpys, lookups, shmem locks, etc.) - Note that non-TM functions operate over the - received message in private memory, that means that any core - operations will have no effect on statefully processed messages after - creating the transactional state. For example, calling record_route - after t_relay is pretty useless, as the - RR is added to privately held message whereas its - TM clone is being forwarded. - - - TM is quite big and uneasy to program--lot of - mutexes, shared memory access, malloc and free, timers--you really - need to be careful when you do anything. To simplify - TM programming, there is the instrument of - callbacks. The callback mechanisms allow programmers to register - their functions to specific event. See t_hooks.h for a list of - possible events. - - - Other things programmers may want to know is UAC--it is a very - simplistic code which allows you to generate your own transactions. - Particularly useful for things like NOTIFYs or IM - gateways. The UAC takes care of all the transaction machinery: - retransmissions , FR timeouts, forking, etc. See t_uac prototype - in uac.h for more details. Who wants to see the transaction result - may register for a callback. - -
- Per-Branch flags - - First what is the idea with the branch concept: branch route is a - route to be execute separately for each branch before being sent - out - changes in that route should reflect only on that branch. - - - There are several types of flags in &osips; : - - - - - message/transaction flags - they are - visible everywhere in the transaction (in all routes and in - all sequential replies/request). - - - - - branch flags - flags that are visible only - from a specific branch - in all replies and routes connected - to this branch. - - - - - script flags - flags that exist only - during script execution. They are not store anywhere and are - lost once the top level route was left. - - - - - For example: I have a call parallel forking to GW and to a user. And I - would like to know from which branch I will get the final negative - reply (if so). I will set a branch route before relaying the calls - (with the 2 branches). The branch route will be separately executed - for each branch; in the branch going to GW (I can identified it by - looking to RURI), I will set a branch flag. This flag will appear - only in the onreply route run for replied from GW. It will be also be - visible in failure route if the final elected reply belongs to the - GW branch. This flags will not be visible in the other branch - (in routes executing replies from the other branch). - - - For how to define branch flags and use via script, see - and the setbflag(), resetbflag() and - isbflagset() script functions. - - - Also, modules may set branch flags before transaction creation - (for the moment this feature is not available in script). The - REGISTRAR module was the first to use this type of flags. The NAT flag - is pushed in branch flags instead in message flags - -
-
- Timeout-Based Failover - - Timeouts can be used to trigger failover behavior. E.g. if we send a call - to a gateway and the gateway does not send a provisional response within 3 - seconds, we want to cancel this call and send the call to another - gateway. Another example is to ring a SIP client only for 30 seconds - and then redirect the call to the voicemail. - - - The transaction module exports two types of timeouts: - - - - - - used when no response was - received yet. If there is no response after - seconds, the timer triggers - (and failure route will be executed if t_on_failure() was - called). For INVITE transactions, if a provisional response was - received, the timeout is reset to - seconds and RT_T2 for all other transactions. Once a final response - is received, the transaction has finished. - - - - - fr_inv_timeout - this timeout - starts counting down once a provisional response was received - for an INVITE transaction. - - - - - For example: You want to have failover if there is no provisional - response after 3 seconds, but you want to ring for 60 seconds. - Thus, set the to 3 and - fr_inv_timeout to 60. - -
-
- DNS Failover - - DNS based failover can be use when relaying stateful requests. - According to RFC 3263, DNS failover should be done on transport level - or transaction level. TM module supports them both. - - - Failover at transport level may be triggered by a failure of sending - out the request message. A failure occurs if the corresponding - interface was found for sending the request, if the TCP connection - was refused or if a generic internal error happened during send. There - is no ICMP error report support. - - - Failover at transaction level may be triggered when the transaction - completed either with a 503 reply, either with a timeout without - any received reply. In such a case, automatically, a new branch will - be forked if any other destination IPs can be used to deliver the - requests. The new branch will be a clone of the winning branch. - - - The set of destinations IPs is step-by-step build (on demand) based on - the NAPTR, SRV and A records available for the destination domain. - - - DNS-based failover is by default applied excepting when this failover - is globally disabled (see the core parameter disable_dns_failover) or - when the relay flag (per transaction) is set (see the t_relay() - function). - -
-
- Anycast Scenario - - Doing a load balancing scenario using - Anycast IPs, - one might run into an issue where a transaction request comes on - one instance, and the reply (or replies) comes on different ones. - This would normaly break the transaction state, because the local - transaction will start re-transmissios and would eventually timeout. - Moreover, from UA's perspective, the reply whould have been sent, - but since it reaches a proxy that is not aware of that transaction, - it will not be forwarded (nor ACKed in case of INVITES). And from - this point things can escalade quickly. - - - To sort out these problems, the module uses a distributed mechanism - to figure out where the transaction for a specific reply was created. - When an instance receives a reply that does not have an associated - transaction, it replicates it to be handled by the instance that - owns it. This is achieved using the - clusterer module support. - - - Setting up an anycast scenario is very simple: all the instances - that are part of an anycast secnario must be set up in a cluster - (more info at the param). - When a transaction is created, a special identifier is appended to - the branch parameter, namely the instance that created the - transaction. When a reply comes in, the transaction module checks who - owns the transaction. If the identifier is the - instance's own id, then the reply is processed locally. Otherwise - it is replicated to the node indicated by the id. Replication is - done in a very efficient manner, using the - proto_bin transport. - - - Special handling is applied to CANCEL and - ACK methods. Due to the fact that these - methods do not contain the special identifier in the branch - parameter (since they are generated by the UAC and not by us), - there is no way to determine who owns the transaction. - Therefore, if we do not find a local transaction for these - requests, we broadcast them to all the other instances using - the function. Again, - this is done in a very efficient manner using the - proto_bin transport. - -
-
- Usage Scope - - Transaction functions and variables are only designed to be - called on SIP request messages where a transaction can be created, or - in routes that are transaction aware, such as - branch_route[name], - failure_route[name] or - onreply_route[name]. Using TM functtions or - variables in a route that is not transaction aware, such as - the generic onreply_route, - error_route or - timer_route[name, timer] may lead to undefined - behavior, and most of the time in bogus or malformed signalling. - Therefore it is strongly recommended to avoid using them in non-tm - context aware routes. - -
-
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - clusterer module, if the anycast - scenario is enabled (see - param for more information). - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>fr_timeout</varname> (integer) - - Timeout which is triggered if no final reply for a request or ACK for a - negative INVITE reply arrives (in seconds). - - - - Default value is 30 seconds. - - - - Set <varname>fr_timeout</varname> parameter - -... -modparam("tm", "fr_timeout", 10) -... - - -
- -
- <varname>fr_inv_timeout</varname> (integer) - - Timeout which is triggered if no final reply for an INVITE arrives after a - provisional message was received (in seconds). This timeout starts - counting down once the first provisional response is received. Thus, - fast failover (no 100 trying from gateway) can be achieved by setting - to low values. - See example below. - - - - Default value is 120 seconds. - - - - Set <varname>fr_inv_timeout</varname> parameter - -... -modparam("tm", "fr_inv_timeout", 200) -... - - -
- -
- <varname>wt_timer</varname> (integer) - - Time for which a transaction stays in memory to absorb delayed - messages after it completed; also, when this timer hits, - retransmission of local cancels is stopped (a puristic but complex - behavior would be not to enter wait state until local branches - are finished by a final reply or FR timer--we simplified). - - - For non-INVITE transaction this timer relates to timer J of RFC 3261 - section 17.2.2. According to the RFC this timer should be 64*T1 - (= 32 seconds). But this would increase memory usage as the transactions - are kept in memory very long. - - - - Default value is 5 seconds. - - - - Set <varname>wt_timer</varname> parameter - -... -modparam("tm", "wt_timer", 10) -... - - -
- -
- <varname>delete_timer</varname> (integer) - - Time after which a to-be-deleted transaction currently ref-ed by a - process will be tried to be deleted again. - - - - Default value is 2 seconds. - - - - Set <varname>delete_timer</varname> parameter - -... -modparam("tm", "delete_timer", 5) -... - - -
- -
- <varname>T1_timer</varname> (integer) - - Retransmission T1 period, in milliseconds. - - - - Default value is 500 milliseconds. - - - - Set <varname>T1_timer</varname> parameter - -... -modparam("tm", "T1_timer", 700) -... - - -
- -
- <varname>T2_timer</varname> (integer) - - Maximum retransmission period, in milliseconds. - - - - Default value is 4000 milliseconds. - - - - Set <varname>T2_timer</varname> parameter - -... -modparam("tm", "T2_timer", 8000) -... - - -
- -
- <varname>ruri_matching</varname> (integer) - - Should be request-uri matching used as a part of pre-3261 transaction - matching as the standard wants us to do so? Turn only off for better - interaction with devices that are broken and send different r-uri in - CANCEL/ACK than in original INVITE. - - - - Default value is 1 (true). - - - - Set <varname>ruri_matching</varname> parameter - -... -modparam("tm", "ruri_matching", 0) -... - - -
- -
- <varname>via1_matching</varname> (integer) - - Should be top most VIA matching used as a part of pre-3261 transaction - matching as the standard wants us to do so? Turn only off for better - interaction with devices that are broken and send different top most - VIA in CANCEL/ACK than in original INVITE. - - - - Default value is 1 (true). - - - - Set <varname>via1_matching</varname> parameter - -... -modparam("tm", "via1_matching", 0) -... - - -
- -
- <varname>unix_tx_timeout</varname> (integer) - - Send timeout to be used by function which use UNIX sockets - (as t_write_unix). - - - - Default value is 2 seconds. - - - - Set <varname>unix_tx_timeout</varname> parameter - -... -modparam("tm", "unix_tx_timeout", 5) -... - - -
- -
- <varname>restart_fr_on_each_reply</varname> (integer) - - If true (non null value), the final response timer will be re-triggered - for each received provisional reply. In this case, final response - timeout may occur after a time longer than - (if UAS keeps sending provisional replies) - - - - Default value is 1 (true). - - - - Set <varname>restart_fr_on_each_reply</varname> parameter - -... -modparam("tm", "restart_fr_on_each_reply", 0) -... - - -
- -
- <varname>tw_append</varname> (string) - - List of additional information to be appended by t_write_req and - t_write_unix functions. - - - - Default value is null string. - - - - Syntax of the parameter is: - - - tw_append = append_name':' element (';'element)* - - - element = ( [name '='] variable) - - - - - Each element will be appended per line in - name: value format. Element - $rb (message body) - is the only one which does not accept name; the body it will be - printed all the time at the end, disregarding its position in the - definition string. - - - Set <varname>tw_append</varname> parameter - -... -modparam("tm", "tw_append", - "test: ua=$hdr(User-Agent) ;avp=$avp(avp);$rb;time=$Ts") -... - - -
- -
- <varname>pass_provisional_replies</varname> (integer) - - Enable/disable passing of provisional replies to FIFO applications. - - - - Default value is 0. - - - - Set <varname>pass_provisional_replies</varname> parameter - -... -modparam("tm", "pass_provisional_replies", 1) -... - - -
- -
- <varname>syn_branch</varname> (integer) - - Enable/disable the usage of stateful synonym branch IDs in the - generated Via headers. They are faster but not reboot-safe. - - - - Default value is 1 (use synonym branches). - - - - Set <varname>syn_branch</varname> parameter - -... -modparam("tm", "syn_branch", 0) -... - - -
- -
- <varname>onreply_avp_mode</varname> (integer) - - Describes how the AVPs should be handled in reply route: - - - 0 - the AVPs will be per message only; they - will not interfere with the AVPS stored in transaction; initially - there will be an empty list and at the end of the route, all AVPs - that were created will be discarded. - - - 1 - the AVPs will be the transaction AVPs; - initially the transaction AVPs will be visible; at the end of the - route, the list will attached back to transaction (with all the - changes) - - - - - In mode 1, you can see the AVPs you set in request route, branch route - or failure route. The side effect is performance as more locking is - required in order to keep the AVP's list integrity. - - - - Default value is 0. - - - - Set <varname>onreply_avp_mode</varname> parameter - -... -modparam("tm", "onreply_avp_mode", 1) -... - - -
- -
- <varname>disable_6xx_block</varname> (integer) - - Tells how the 6xx replies should be internally handled: - - - 0 - the 6xx replies will block any further - serial forking (adding new branches). This is the RFC3261 - behaviour. - - - 1 - the 6xx replies will be handled as any - other negative reply - serial forking will be allowed. - Logically, you need to break RFC3261 if you want to do redirects - to announcement and voicemail services. - - - - - - Default value is 0. - - - - Set <varname>disable_6xx_block</varname> parameter - -... -modparam("tm", "disable_6xx_block", 1) -... - - -
- -
- <varname>enable_stats</varname> (integer) - - Enables statistics support in TM module - If enabled, the TM module - will internally keep several statistics and export them via the - MI - Management Interface. - - - - Default value is 1 (enabled). - - - - Set <varname>enable_stats</varname> parameter - -... -modparam("tm", "enable_stats", 0) -... - - -
- -
- <varname>minor_branch_flag</varname> (string/integer) - - A branch flag index to be used in script to mark the minor branches - ( before t_relay() ). - - - A minor branch is a branch OpenSIPS will not wait to complete during - parallel forking. So, if the rest of the branches are negativly replied - OpenSIPS will not wait for a final answer from the minor branch, but - it will simply cancel it. - - - Main applicability of minor branch is to fork a branch to a media - server for injecting (via 183 Early Media) some pre-call media - of - course, this branch will be transparanent for the rest of the call - branches (from branch selection point of view). - - - - Default value is none (disabled). - - - - Set <varname>minor_branch_flag</varname> parameter - -... -modparam("tm", "minor_branch_flag", "MINOR_BFLAG") -... - - -
- -
- <varname>timer_partitions</varname> (integer) - - The number of partitions for the internal TM timers (retransmissions, - delete, wait, etc). Partitioning the timers increase the throughput - under heavly load by handling timer events in parallel, rather than - all serial. - - - Recomanded range for timer partitions is max 16 (soft limit). - - - - Default value is 1 (disabled). - - - - Set <varname>timer_partitions</varname> parameter - -... -# Enable two timer partitions -modparam("tm", "timer_partitions", 2) -... - - -
- -
- <varname>auto_100trying</varname> (integer) - - This parameter controls if the TM module should automatically - generate an 100 Trying stateful reply when an INVITE transaction - is created. - - - You may want to disable this behavior if you want to control from - script level when the 100 Trying is to be sent out. - - - - Default value is 1 (enabled). - - - - Set <varname>auto_100trying</varname> parameter - -... -# Disable automatic 100 Trying -modparam("tm", "auto_100trying", 0) -... - - -
- -
- <varname>tm_replication_cluster</varname> (integer) - - This parameter should be used in an anycast setup, and specifies - the cluster id of all the nodes that use an anycast IP. - - - Check out the section for more details. - - - - Anycast replication is disabled by default. - - - - Set <varname>tm_replication_cluster</varname> parameter - -... -# replicate anycast messages in cluster 1 -modparam("tm", "tm_replication_cluster", 1) -... - - -
- -
- <varname>cluster_param</varname> (string) - - This parameter should be used in an anycast setup, and specifies - the name of the parameter used in the VIA branch param to specifiy - the instance id that created the transaction. - - - Check out the section for more details. - - - - Default value is cid. - - - - Set the <varname>cluster_param</varname> parameter - -... -modparam("tm", "cluster_param", "tid") -... - - -
- -
- <varname>cluster_auto_cancel</varname> (boolean) - - This parameter should be used in an anycast setup, and specifies - whether a CANCEL message received on a - listener that is marked as anycast should be automatically handled, - or should get in the &osips; script. If this parameter is enabled - (default), CANCEL messages received on an - anycast listener will never enter the script, thus making the - script cleaner. - - - Check out the section for more details. - - - - Default value is yes (enabled). - - - - Set the <varname>cluster_auto_cancel</varname> parameter - -... -# disable auto-cancel handling -modparam("tm", "cluster_auto_cancel", no) -... - - -
- -
- <varname>local_request_route</varname> (string) - - This parameter points to a route, which is executed whenever TM is - about to send out a locally generated request (e.g., through the - B2B modules or through MI). - - - The purpose of this route is limited to exposing the content of the - request as SIP message - - - The route is executed with the generated message by TM, incorporating - all modifications. - - - IMPORTANT: this route is executed AFTER the local_route (if defined) - and it expose all the changes from that route. - - - IMPORTANT: this route is to be used in a read-only manner, inspection - only. Any changes you do here will discarded. - - - IMPORTANT: this route does not offer any message, transactional or - dialog context, so do not rely on any variables with scope (like AVPs). - - - Set the <varname>local_request_route</varname> parameter - -... -# Execute the route "local_request_route" upon sending a request -modparam("tm", "local_request_route", "tm_local_request") - -route[tm_local_request] { - if (is_method("INVITE") && $rb(application/sdp) && !has_totag()) { - $avp(sdp_request) := $rb(application/sdp); - } -} -... - - -
- -
- <varname>local_reply_route</varname> (string) - - This parameter points to a route, which is executed whenever TM is - about to send out a locally generated reply (e.g., through the - B2B modules or through MI). - - - The purpose of this route is limited to exposing the content of the - reply as SIP message - - - IMPORTANT: this route is to be used in a read-only manner, inspection - only. Any changes you do here will discarded. - - - IMPORTANT: this route does not offer any message, transactional or - dialog context, so do not rely on any variables with scope (like AVPs). - - - Set the <varname>local_reply_route</varname> parameter - -... -# Execute the route "tm_local_reply" upon sending a request -modparam("tm", "local_reply_route", "tm_local_reply") - -route[tm_local_reply] { - if (is_method("BYE")) { - $var(rc) = rest_get("http://localhost/qos/delete", - $var(recv_body), $var(recv_ct), $var(rcode)); - } -} - -... - - -
- -
- - -
- Exported Functions -
- - <function moreinfo="none">t_relay([flags],[outbound_proxy])</function> - - - Relay a message statefully to destination indicated in current URI. - (If the original URI was rewritten by UsrLoc, RR, strip/prefix, etc., - the new URI will be taken). Returns a negative value on failure--you - may still want to send a negative reply upstream statelessly not to - leave upstream UAC in lurch. - - - The coresponding transaction may or may not be already created. If not - yet created, the function will automatically create it. - - - The function may take two optional parameters. - - - The first parameter is a comma separated list of string flags for - controlling the internal behaviour. The supported flags are: - - - - no-auto-477 - (old - 0x02 flag) do not internally generate - and send a "477 Send failed (477/TM)" SIP reply in case of a - global forwarding failure (i.e. forwarding for each branch has - failed due to internal errors, bad R-URI, bad message, lack of - network reachability, etc.). - - - This flag only applies if the transaction was - not previously created by . - When a global forwarding failure occurs, no SIP request is - relayed and therefore no negative SIP reply or timeout will - show up on the failure_route, if one is set. - - - Useful if you want to implement a failover logic for when none - of the currently created branches can be forwarded to. - - - - no-dns-failover - (old - 0x04 flag) disable the DNS failover - for the transaction. Only first IP will be used. It disables - the failover both at transport and transaction level. - - - - pass-reason-hdr - (old - 0x08 flag) If the request is a CANCEL, - trust and pass further the Reason header from the received - CANCEL - shortly, will propagate the Reason header. - - - - allow-no-cancel - (old - 0x10 flag) Allows OpenSIPS to inspect - and follow the Content-Disposition "no-cancel" indication (if - present). As per RFC3841, section 9.1, the TM module may be - instructed not to cancel all ongoing branches when a 2xx reply - is received. It will keep the pending branches ongoing until - (1) all branches will receive a final reply or (2) the - transactionhits the timeout. - - - - - - The second parameter is a string representing an outbound proxy - (a fixed destination) where the message should be sent. The - destination is specified as [proto:]host[:port]. If a - destination URI $du for this message was set before the - function is called then this value will be used as the destination - instead of the function parameter. - - - In case of error, the function returns the following codes: - - - - -1 - generic internal error - - - - -2 - bad message (parsing errors) - - - - -3 - no destination available - (no branches were added or request already cancelled) - - - - -4 - bad destination - (unresolvable address) - - - - -5 - destination filtered - (black listed) - - - - -6 - generic send failed - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>t_relay</function> usage - -... -if (!t_relay()) { - sl_reply_error(); - exit; -} -... -t_relay( ,"tcp:192.168.1.10:5060"); -... -t_relay(0x1, "mydomain.com:5070"); -... - - -
- -
- - <function moreinfo="none">t_reply(code, reason_phrase)</function> - - - Sends a stateful SIP reply to the currently processed requests. Note - that if the transaction was not created yet, it will automatically - created by internally using the - t_newtran function. - - Meaning of the parameters is as follows: - - - code (int) - Reply code number. - - - - reason_phrase (string) - Reason string. - - - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. - - - <function>t_reply</function> usage - -... -t_reply(404, "Use $rU not found"); -... - - -
- -
- - <function moreinfo="none">t_reply_with_body(code, reason_phrase, body)</function> - - - Sends a stateful SIP reply with a body to the currently processed - requests. Note that if the transaction was not created yet, it will - automatically created by internally using the - t_newtran function. - - Meaning of the parameters is as follows: - - - code (int) - Reply code number. - - - - reason_phrase (string) - Reason string. - - - - body (string) - Reply body. - - - - - - This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - - - <function>t_reply_with_body</function> usage - -... - if(is_method("INVITE")) - { - append_to_reply("Contact: $var(contact)\r\n" - "Content-Type: application/sdp\r\n"); - t_reply_with_body(200, "Ok", $var(body)); - exit; - } -... - - -
- -
- - <function moreinfo="none">t_newtran()</function> - - - Creates the SIP transaction for the currently processed SIP request, - thus switching to stateful processing. For INVITE requests, a 100 - Trying reply will be immediately sent, unless - is disabled. Once a SIP - transaction is created, calling for - retransmitted requests will end the OpenSIPS script execution, with the - lastly sent reply being retransmitted upstream. - - - This function can be used from REQUEST_ROUTE. - - - <function>t_newtran</function> usage - -... -t_newtran(); # 100 Trying is fired here -xlog("doing my complicated routing logic\n"); -.... -t_relay(); # send the call further -... - - -
- -
- - <function moreinfo="none">t_check_trans()</function> - - - Returns true if the current request is associated to a transaction. - The relationship between the request and transaction is defined as - follows: - - - - non-CANCEL/non-ACK requests - if the - request belongs to a transaction (it's a retransmision), the - function will do a standard processing of the retransmission and - will break/stop the script. The function returns false if the - request is not a retransmission. - - - - CANCEL request - true if the cancelled - INVITE transaction exists. - - - - ACK request - true if the ACK is a - hop-by-hop ACK (to a negative reply) corresponding to an previous - INVITE transaction. IMPORTANT: this function returns false (return - code -2) for end-to-end ACKs (to 2xx replies - from a different transaction). - - - - - Note: To detect retransmissions using this function you have to make - sure that the initial request has already created a transaction, e.g. - by using t_relay(). If the processing of requests may take long time - (e.g. DB lookups) and the retransmission arrives before t_relay() is - called, you can use the t_newtran() function to manually create a - transaction. - - - This function can be used from REQUEST_ROUTE and BRANCH_ROUTE. - - - <function>t_check_trans</function> usage - -... -if ( is_method("CANCEL") ) { - if ( t_check_trans() ) - t_relay(); - exit; -} -... - - -
- -
- - <function moreinfo="none">t_check_status(re)</function> - - - Returns true if the regualr expression re match the - reply code of the response message as follows: - - - in routing block - the code of the - last sent reply. - - - - in on_reply block - the code of the - current received reply. - - - - in on_failure block - the code of the - selected negative final reply. - - - - - - This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, - FAILURE_ROUTE and BRANCH_ROUTE . - - - <function>t_check_status</function> usage - -... -if (t_check_status("(487)|(408)")) { - log("487 or 408 negative reply\n"); -} -... - - -
- -
- - <function moreinfo="none">t_local_replied(reply)</function> - - - Returns true if all or last (depending of the parameter) reply(es) were - local generated (and not received). - - - Parameter may be all or last. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - FAILURE_ROUTE and ONREPLY_ROUTE. - - - <function>t_local_replied</function> usage - -... -if (t_local_replied("all")) { - log ("no reply received\n"); -} -... - - -
- -
- - <function moreinfo="none">t_was_cancelled()</function> - - - Retuns true if called for an INVITE transaction that was explicitly - cancelled by UAC side via a CANCEL request. - - - This function can be used from ONREPLY_ROUTE, FAILURE_ROUTE. - - - <function>t_was_cancelled</function> usage - -... -if (t_was_cancelled()) { - log("transaction was cancelled by UAC\n"); -} -... - - -
- -
- - <function moreinfo="none">t_cancel_branch([flags])</function> - - - This function is to be call when a reply is received for cancelling a - set of branches (see flags) of the current call. - - Meaning of the parameters is as follows: - - - flags (string, optional) - set of flags - (char based flags) to control what branches to be cancelled: - - - - a - all - cancel all pending - branches - - - - o - others - cancel all the other - pending branches except the current one - - - - empty - current - cancel only the - current branch - - - - - - - - This function can be used from ONREPLY_ROUTE. - - - <function>t_cancel_branch</function> usage - -onreply_route[3] { -... - if (t_check_status(183)) { - # no support for early media - t_cancel_branch(); - } -... -} - - -
- -
- - <function moreinfo="none">t_new_request( method, RURI, from, to [, body[, ctx]])</function> - - - This function generates and sends out a new SIP request (in a stateful way). - The new request is completly unrelated to the currently processed SIP message. - - Meaning of the parameters is as follows (all do accept variables): - - - method (string) - the SIP method - - - - RURI (string) - the SIP Request URI (the request - will be sent out to this destination) - - - - from (string) - the SIP From hdr information as - "[display ]URI" - - - - to (string) - the SIP To hdr information as - "[display ]URI" - - - - body (string, optional) - the SIP body content - starting with the content type string: "conten_type body" - - - - ctx (string, optional) - a context string that will - be added to the new transaction as an AVP with name "uac_ctx" (it may be visible - in local route) - - - - - - <function>t_new_request</function> usage - -... - # send a MESSAGE request - t_new_request("MESSAGE","sip:alice@192.168.2.2","BOB sip:userB@mydomain.net","ALICE sip:userA@mydomain.net","text/plain Hello Alice!")) { -... - - -
- -
- - <function moreinfo="none">t_on_failure(failure_route)</function> - - - Sets reply routing block, to which control is passed after a - transaction completed with a negative result but before sending a - final reply. In the referred block, you can either start a new branch - (good for services such as forward_on_no_reply) or send a final reply - on your own (good for example for message silo, which received a - negative reply from upstream and wants to tell upstream 202 I - will take care of it). - - - As not all functions are available from failure route, please check - the documentation for each function to see the permissions. - Any other commands may result in unpredictable behavior and - possible server failure. - - - Only one failure_route can be armed for a request. If you use many - times t_on_failure(), only the last one has effect. - - - Note that whenever failure_route is entered, RURI is set to value - of the winning branch. - - Meaning of the parameters is as follows: - - - failure_route (string) - Reply route block to be - called. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - - <function>t_on_failure</function> usage - -... -route { - t_on_failure("1"); - t_relay(); -} - -failure_route[1] { - seturi("sip:user@voicemail"); - t_relay(); -} -... - - -
- -
- - <function moreinfo="none">t_on_reply(reply_route)</function> - - - Sets reply routing block, to which control is passed each time a reply - (provisional or final) for the transaction is received. - The route is not called for local generated replies! In the referred - block, you can inspect the reply and perform text operations on it. - - - As not all functions are available from this type of route, please - check the documentation for each function to see the permissions. - Any other commands may result in unpredictable behavior and - possible server failure. - - - If called from branch route, the reply route will be set only for the - current branch - that's it, it will be called only for relies belonging - to that particular branch. Of course, from branch route, you can set - different reply routes for each branch. - - - When called from a non-branc route, the reply route will be globally - set for tha current transaction - it will be called for all replies - belonging to that transaction. NOTE that only - one> onreply_route can be armed for a transaction. - If you use many times t_on_reply(), only the last one has effect. - - - If the processed reply is provisionla reply (1xx code), by calling - the drop() function (exported by core), the execution of the route - will end and the reply will not be forwarded further. - - Meaning of the parameters is as follows: - - - reply_route (string) - Reply route block to be - called. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - - <function>t_on_reply</function> usage - -... -route { - seturi("sip:bob@opensips.org"); # first branch - append_branch("sip:alice@opensips.org"); # second branch - - t_on_reply("global"); # the "global" reply route - # is set the whole transaction - t_on_branch("1"); - - t_relay(); -} - -branch_route[1] { - if ($rU=="alice") - t_on_reply("alice"); # the "alice" reply route - # is set only for second branch -} - -onreply_route[alice] { - xlog("received reply from alice\n"); -} - -onreply_route[global] { - if (t_check_status("1[0-9][0-9]")) { - setflag(LOG_FLAG); - log("provisional reply received\n"); - if (t_check_status("183")) - drop; - } -} -... - - -
- -
- - <function moreinfo="none">t_on_branch(branch_route)</function> - - - Sets a branch route to be execute separately for each branch of the - transaction before being sent out - changes in that route should - reflect only on that branch. - - - As not all functions are available from this type of route, please - check the documentation for each function to see the permissions. - Any other commands may result in unpredictable behavior and - possible server failure. - - - Only one branch_route can be armed for a request. If you use many - time t_on_branch(), only the last one has effect. - - - By calling the drop() function (exported by core), the execution of - the branch route will end and the branch will not be forwarded further. - - Meaning of the parameters is as follows: - - - branch_route (string) - Branch route block to be - called. - - - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, - ONREPLY_ROUTE and FAILURE_ROUTE. - - - <function>t_on_branch</function> usage - -... -route { - t_on_branch("1"); - t_relay(); -} - -branch_route[1] { - if ($ru=~"bad_uri") { - xlog("dropping branch $ru \n"); - drop; - } - if ($ru=~"GW_uri") { - append_rpid(); - } -} -... - - -
- -
- - <function moreinfo="none">t_inject_branches(source[,flags])</function> - - - The function adds new SIP branches (destinations) to an existing - transaction and fires them (sends them out). The transaction may - already have ongoing branches (like in ringing state), which will not - be affected by the injection of the new branches. Also it is possible - for the transaction not to have any ongoing branches at the moment of - the injection (still, the transaction must wait for new branches, even - if all existing ones are completed - see - the function for this). - - - The main usage scenario for this function (and also what makes it - different from is the ability to add new - branches to an ongoing transaction from script routes not related to - the transaction ( like timer route, event route, notification route, - and other). In such routes, other functions/module used before the - injection will point to the transaction to be affected by this - injection - see the event_routing module. - - Parameters: - - - source (string) - where to take the description - for the new branches to be injected. It can be - - - event - the branch will be taken from - the event attributes exposed in an event notification route - (see event_routing module). - - - msg - the branches will be taken from - the RURI of the SIP message and from the additional - branches (created by append_branch() function or similar). - - - - - flags (string, optional) - some additional flags - related to the injection process: - - - cancel or c - - cancel all the ongoing - existing branches from the transaction before injecting - the new branches. - - - l (last) - this is the last injected - branch on this transaction, do not wait for any other - branches to be injected. - - - - - - - <function>t_inject_branches</function> usage - -... -route[event_notification] { - t_inject_branches("event"); -} -... - - -
- -
- - <function moreinfo="none">t_wait_for_new_branches([branches])</function> - - - This function instructs the existing SIP transaction to wait for new - branches to be injected even after the completion of the existing - branches. This waiting will be done until the Final Response INVITE - timer (fr_inv_timeout) will hit for the transaction OR until the - maximum number of branches were injected (see parameter); of course, - the waiting will be terminated if the transaction gets a 2xx final - reply from one of the branches. - - - Normally if you have a transaction with two branches and - they get, let's say, a 404 and 486 replies, the branches will be - completed and transaction terminated by sending the 404 reply to the - caller. Still, if you do t_wait_for_new_branches - before relaying the transaction, the transaction will not terminate - upon the completion of the branches and not send the 404 to the caller - - it will wait for new branches to be injected (see - function) until the fr_inv timer - hits. - - Parameters: - - - branches (integer, options) - what is the - maximum number of branches to be waited for. - - - - <function>t_wait_for_new_branches</function> usage - -... -t_newtran(); -t_wait_for_new_branches(); -t_relay(); -... - - -
- -
- - <function moreinfo="none">t_wait_no_more_branches()</function> - - - This function instructs the existing SIP transaction to stop wait - for new any new branches to be injected. This functions should be - used for a transaction that is waiting for dynamic branches, via the - function. - - - Usage scenario: your transaction is waiting for dynamic new branches - (as a reusult of Push Notification). To a point, on an ongoing - branch you receive a final reply - and the fact that the branch fails - translates into stop waiting for any more branche (this is an example - of a logic on deciding how long to wait for more branches, depending - on the answers you get from various devices, fix or mobile). - - - <function>t_wait_no_more_branches</function> usage - -... -t_wait_no_more_branches(); -... - - -
- -
- - <function moreinfo="none">t_add_hdrs("sip_hdrs")</function> - - - Attach a set of headers to the existing transaction - these headers - will be appended to all requests related to the transaction (outgoing - branches, local ACKS, CANCELs). - - Parameters: - - - sip_hdrs (string) - - - - <function>t_add_hdrs</function> usage - -... -t_add_hdrs("X-origin: 1.1.1.1\r\n"); -... - - -
- -
- - <function moreinfo="none">t_add_cancel_reason("Reason_hdr")</function> - - - This function is used to enforce from the script level a custom - "Reason" header into a CANCEL request. Normally, the Reason header is - inherited form the received CANCEL (note that CANCEL propagates in a - hop-by-hop manner - it is re-generated at each hop), but this function - can overwrite it. It must be called before relaying the CANCEL request - and its input must be a fully formated Reason header with name, body - and CRLF. - - Parameters: - - - reason_hdr (string) - - - - <function>t_add_cancel_reason</function> usage - -... -t_add_cancel_reason("Reason: SIP ;cause=200 ;text=\"Call completed elsewhere\"\r\n"); -t_relay(); -... - - -
- - -
- - <function moreinfo="none">t_replicate(URI,[flags])</function> - - - Replicates a request to another destination. No information due the - replicated request (like reply code) will be forwarded to the - original SIP UAC. - - - The destination is specified by a SIP URI. If multiple destinations are - to be used, the additional SIP URIs have to be set as branches. - - Parameters: - - - uri (string) - - - flags (string, optional) - a set of flags for - controlling the internal behaviour - for description see the above - t_relay([flags]) function. Note that only - no-dns-failover is - applicable here. - - - - This functions can be used from REQUEST_ROUTE. - - - <function>t_replicate</function> usage - -... -t_replicate("sip:1.2.3.4:5060"); -t_replicate("sip:1.2.3.4:5060;transport=tcp"); -t_replicate("sip:1.2.3.4",0x4); -... - - -
- -
- - <function moreinfo="none">t_write_req(info,fifo)</function> - <function moreinfo="none">t_write_unix(info,sock)</function> - - - Write via FIFO file or UNIX socket a lot of information regarding the - request. Which information should be written may be control via the - tw_append parameter. - - Parameters: - - - info (string) - - - path (string) - - - - This functions can be used from REQUEST_ROUTE, FAILURE_ROUTE and - BRANCH_ROUTE. - - - <function>t_write_req/unix</function> usage - -... -modparam("tm","tw_append","append1:Email=$avp(email);UA=$ua") -modparam("tm","tw_append","append2:body=$rb") -... -t_write_req("voicemail/append1","/tmp/appx_fifo"); -... -t_write_unix("logger/append2","/var/run/logger.sock"); -... - - -
- -
- - <function moreinfo="none">t_flush_flags()</function> - - - Flush the flags from current request into the already created - transaction. It make sense only in routing block if the transaction was - created via t_newtran() and the flags have been altered since. - - - This function can be used from REQUEST_ROUTE and BRANCH_ROUTE . - - - <function>t_flush_flags</function> usage - -... -t_flush_flags(); -... - - -
- -
- - <function moreinfo="none">t_anycast_replicate()</function> - - - This function is used in an anycast setup to replicate a - CANCEL or ACK method - for whom there are no local transactions found. The function - broadcasts the message to all the other nodes in the cluster, - but only the owner of the transaction will be - able to handle it. - - - <function>t_anycast_replicate</function> usage - -... -if (is_method("ACK|CANCEL") && !t_check_trans()) { - t_anycast_replicate(); - exit; -} -... - - -
- -
- - <function moreinfo="none">t_reply_by_callid(code, reason_phrase, [callid], [cseq])</function> - - - This function is used to send a reply to an existing INVITE - transaction. The usual use case is when OpenSIPS is used as an UAS - and when an INVITE is receveid, it is "parked" locally on - OpenSIPS by replying to it with - t_reply(180, "Ringing") or - t_reply(183, "Session Progress") - and later we need to handle CANCEL or BYE for it and send - '487 Request Terminated' to the original INVITE transaction. - - - The callid and cseq used to identify the transaction - will be obtained from the current messsage being processed. - But they can be passed explicitly so that for example we can - handle a BYE where the cseq must be the cseq - of the INVITE minus one. - - - This function can be used from REQUEST_ROUTE. - - - <function>t_reply_by_callid</function> usage - -... -route{ - if($rU == "LOCAL_PARK") { - if(is_method("INVITE")) { - $T_fr_timeout = 10; - $T_fr_inv_timeout = 10; - append_to_reply("Contact: sip:LOCAL_PARK@$socket_in(ip):$socket_in(port)\r\n"); - t_reply(180, "Ringing"); - t_wait_for_new_branches(); - } else if(is_method("CANCEL")) { - if(!t_reply_by_callid(487, "Request Terminated")) { - sl_send_reply(481, "Call Leg/Transaction Does Not Exist"); - } else { - sl_send_reply(200, "OK"); - } - } else if(is_method("BYE")) { - $var(prev_cseq) = ($(cs{s.int}) - 1); - if(!t_reply_by_callid(487, "Request Terminated", , $var(prev_cseq))) { - sl_send_reply(481, "Call Leg/Transaction Does Not Exist"); - } else { - sl_send_reply(200, "OK"); - } - } else if(is_method("ACK")) { - t_relay(); - } - exit; - } -} -... - - -
- -
- - <function moreinfo="none">t_get_branch_idx_by_attr(attr, [val_str], [val_int], [result_var], [offset])</function> - - - This function may be used to search for the index of another branch - of the current transaction. The searching is done based on the - per-branch attribute - you need to provide the name of the attribute - at least. Optionally you can provide a value (string or integer) for - the attribute used for searching. As input, the function may take an - optional branch offset (absolute value, covering all branches of the - transaction) where the search should start from. - - - The function returns true if a branch (having the given name and - value for the attribute) was found. The status of the branch (like - if ongoing, completed ) is not relevant. If found, the "result_var" - variable will be populated with the branch index (as integer). - - - This function can be used from ONREPLY_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>t_get_branch_idx_by_attr</function> usage - -... - # search for a branch which has the "name" attribute - # with string value "pstn" - if (t_get_branch_idx_by_attr("name", "pstn", , $var(idx))) { - xlog("found branch has index $var(idx)\n"); - } -... - - -
- - -
- -
- Exported Pseudo-Variables - - Exported variables are listed in the next sections. - -
- $T_branch_idx - - $T_branch_idx - the index (starting with 0 - for the first branch) of the currently proccessed branch. This - index makes sense only in BRANCH and REPLY routes (where the - processing is per branch) and in FAILURE route (where it points - to the branch with the last final reply on the transaction). In all - the other types of routes, the value of this index will be NULL. - -
-
- $T_reply_code - - $T_reply_code - the code of the reply, as - follows: in request_route will be the last stateful sent reply; - in reply_route will be the current processed reply; in - failure_route will be the negative winning reply. In case of - no-reply or error, '0' value is returned. - -
-
- $T_fr_timeout - - $T_fr_timeout (R/W) - the timeout - for the final reply to the current transaction - - - With each different - request received, $T_fr_timeout will initially - be equal to the - parameter. - - - "$T_fr_timeout = NULL;" will reset it to - . - -
-
- $T_fr_inv_timeout - - $T_fr_inv_timeout (R/W) - the timeout - for the final reply to an INVITE request, after a 1XX reply - was received. This variable may also be set in an onreply_route - (e.g. on 180 Ringing, after 100 Trying) and still take effect. - - - With each different request received, - $T_fr_inv_timeout will initially be equal to the - - parameter. - - - "$T_fr_inv_timeout = NULL;" will reset it to - . - -
-
- $T_ruri - - $T_ruri - the ruri of the current branch; this - information is taken from the transaction structure, so you can - access this information for any sip message (request/reply) that - has a transaction. - -
-
- $bavp(name) - - $bavp(name) - a particular type of avp that - can have different values for each branch. They can only be used in - BRANCH, REPLY and FAILURE routes. Otherwise NULL value is returned. - -
-
- $T_id - - $T_id - returns the ID of the current - transaction. The ID is an opaque hexa string, unique for each - transaction. If there is no current transaction, NULL value is - returned. - -
-
- $T_branch_last_reply_code - - $T_branch_last_reply_code - returns the last reply - code received for a branch specified as parameter. If no parameter is - specified, the last reply for the current branch is retrieved. - -
-
- $tm.branch.uri[] - - $tm.branch.uri - gives read-only - access over the Request URI (as string) of a TM existing - branch. The status of the branch (completed, ongoing, etc) - is not relevant. - - - The TM (UAC side) branches are created when the request is - sent to new destinations via "t_relay()" or "t_inject()". - - - The indexing of the branches starts from 0, giving access to - all branches (past and active) of the transaction. Nevertheless - the indexing supports two optional suffixes, to simplify the - scripting: - - - /active - the indexing starts also - from 0, but it is relative to the last set of branches - - the parallel branches created by the last "t_relay()"-ing. - - - /all - similar to "no suffix" case, - meaning it is an absolute index, covering all the - branches of the trasactions (resulted from all "t_relay()"s - performed over the transaction). - - - - - IF no index is specified, the current branch used. This depends - on the scripting context. Like in reply route, the current - branch is the branch the reply came for; in branch route, the - current branch is the branch to be sent out; in failure route, - the current branch is the winning branch. - - - NOTES: - - - The index ALL ( "*" ) is not supported; - - - In branch route, only the "$tm.branch.attr" and - "$tm.branch.flag" variables work for the current branch - (the rest of the branch related variables will return NULL) - - - Negative values are accepted, meaning indexing from the - end ( -1 is the latest/higher branch) - - - - - The variable can be used in BRANCH, ONREPLY and FAILURE routes. - -
-
- $tm.branch.duri[] - - $tm.branch.duri - 100% similar to - , but returning the Detination-URI value of the branch. - -
-
- $tm.branch.path[] - - $tm.branch.path - 100% similar to - , but returning the PATH value of the branch. - -
-
- $tm.branch.q[] - - $tm.branch.q - 100% similar to - , but returning the Q value of the branch. - -
-
- $tm.branch.flags[] - - $tm.branch.flags - 100% similar to - , but returning the list (comma separated) of per-branch flags which are - set for the branch. - -
-
- $tm.branch.socket[] - - $tm.branch.socket - 100% similar to - , but returning the socket description (proto:ip:port) used for sending the - branch out. - -
-
- $tm.branch.flag()[] - - $tm.branch.flag(name) - similar to - , but gives read/write access to a single branch flag (by its name). - - - The accepted values are 0 for FALSE, pozitive non-zero for - TRUE. The returned values are 0 for FALSE and 1 for TRUE. - - - The flags operated here are the same as the bflags you can - operated with via the "[re]setbflag()" functions. - -
-
- $tm.branch.attr()[] - - $tm.branch.attr(name) - similar to - , but gives read/write access to the attributed attached to the branch. - - - An attribute can have whatever name (no need to be - pre-defined) and it can have a single value (at a time), - string or integer. - -
-
- $tm.branch.last_received[] - - $tm.branch.last_received - 100% similar to - , but returning the reply code of the last received reply (from the - network) on this branch. NULL is returned in no reply was - received so far. - -
-
- $tm.branch.type[] - - $tm.branch.type - 100% similar to - , but returning the type of the current branch. This may be "phone" if it - not a real branch (has no SIP signalling, used by waiting for - branch injection) or "sip" (a real signalling branch). - -
-
- - -
- Exported MI Functions - -
- - <function moreinfo="none">t_uac_dlg</function> - - - Generates and sends a local SIP request. - - Parameters: - - - method - request method - - - ruri - request SIP URI - - - headers - set of additional headers to - be added to the request; at least - From and To headers must be - specified) - - - next_hop (optional) - next hop SIP URI (OBP). - - - socket (optional) - local socket to be used for - sending the request. - - - body (optional) - request body (if present, requires the - Content-Type and Content-length - headers) - - - - MI FIFO Command Format: - - - opensips-cli -x mi t_uac_dlg method=INVITE ruri="sip:alice@127.0.0.1:7050" headers="From: sip:bobster@127.0.0.1:1337\r\nTo: sip:alice@127.0.0.1:7050\r\nContact: sip:bobster@127.0.0.1:1337\r\n" - -
- -
- - <function moreinfo="none">t_uac_cancel</function> - - - Generates and sends a CANCEL for an existing SIP request. - - Parameters: - - - callid - callid of the INVITE request - to be cancelled. - - - cseq - cseq of the INVITE request to be - cancelled. - - - - MI FIFO Command Format: - - - opensips-cli -x mi t_uac_cancel "1-23454@127.0.0.1" "1 INVITE" - -
- -
- - <function moreinfo="none">t_hash</function> - - - Gets information about the load of TM internal hash table. - - Parameters: - - - none - - - - MI FIFO Command Format: - - - opensips-cli -x mi t_hash - -
- -
- - <function moreinfo="none">t_reply</function> - - - Generates and sends a reply for an existing inbound SIP transaction. - - Parameters: - - - code - reply code - - - reason - reason phrase. - - - trans_id - transaction identifier - (has the hash_entry:label format) - - - to_tag - To tag to be added to TO header - - - new_headers (optional) - extra headers to be - appended to the reply. - - - body - (optional) reply body (if present, requires the - Content-Type and Content-length - headers) - - - - MI FIFO Command Format: - - - opensips-cli -x mi t_reply 403 Forbidden 46961:1279687637 abcde . - -
- -
- - -
- Exported Statistics - - Exported statistics are listed in the next sections. All statistics - except inuse_transactions can be reset. - -
- received_replies - - Total number of total replies received by TM module. - -
-
- relayed_replies - - Total number of replies received and relayed by TM module. - -
-
- local_replies - - Total number of replies local generated by TM module. - -
-
- UAS_transactions - - Total number of transactions created by received requests. - -
-
- UAC_transactions - - Total number of transactions created by local generated requests. - -
-
- 2xx_transactions - - Total number of transactions completed with 2xx replies. - -
-
- 3xx_transactions - - Total number of transactions completed with 3xx replies. - -
-
- 4xx_transactions - - Total number of transactions completed with 4xx replies. - -
-
- 5xx_transactions - - Total number of transactions completed with 5xx replies. - -
-
- 6xx_transactions - - Total number of transactions completed with 6xx replies. - -
-
- inuse_transactions - - Number of transactions existing in memory at current time. - -
-
- retransmission_req_T1_1 - - Number of request retransmissions due to T1 1 timer, - the first retransmission interval (typical 500ms). - -
-
- retransmission_req_T1_2 - - Number of request retransmissions due to T1 2 timer, - the second retransmission interval (typical 1s). - -
-
- retransmission_req_T1_3 - - Number of request retransmissions due to T1 3 timer, - the third retransmission interval (typical 2s). - -
-
- retransmission_req_T2 - - Number of request retransmissions due to T2 , - the final retransmission interval (typical 4s). - -
-
- retransmission_rpl_T2 - - Number of reply retransmissions, all done with the same - retransmission interval T2, typical 4s. - -
-
- timeout_finalresponse - - Number of transactional timeouts without receiving any kind of reply (not - even provisional) from the B side. Such timeouts indicate a - communication / reachability issue. Note: a single transaction may count - multiple such timeouts due forking. - -
-
- timeout_finalresponse - - Number of transactional INVITE timeouts without receiving a FINAL reply - (provisional may be received) from the B side. Such timeouts indicate a - "not answer" event and it is not a signalling issue. - Note: a single transaction may count multiple such timeouts due forking. - -
-
- -
- diff --git a/modules/tm/doc/tm_devel.xml b/modules/tm/doc/tm_devel.xml deleted file mode 100644 index bc64c12842f..00000000000 --- a/modules/tm/doc/tm_devel.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - &develguide; -
- Functions -
- - <function moreinfo="none">load_tm(*import_structure)</function> - - - For programmatic use only--import the TM API. - See the cpl_c, acc or jabber modules to see how it works. - - Meaning of the parameters is as follows: - - - import_structure - Pointer to - the import structure - see struct tm_binds in - modules/tm/tm_load.h - - - -
-
-
- diff --git a/modules/tm/doc/tm_faq.xml b/modules/tm/doc/tm_faq.xml deleted file mode 100644 index 620771c81f1..00000000000 --- a/modules/tm/doc/tm_faq.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - &faqguide; - - - - - What happened with old cancel_call() function - - - - The function was replace (as functionality) by cancel_branch("a") - - cancel all braches. - - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - - diff --git a/modules/tm/t_fwd.c b/modules/tm/t_fwd.c index 9ced228c09a..8c92cdc2ce6 100644 --- a/modules/tm/t_fwd.c +++ b/modules/tm/t_fwd.c @@ -51,6 +51,7 @@ #include "../../mem/mem.h" #include "../../parser/parser_f.h" #include "../../parser/parse_body.h" +#include "../../context.h" #include "t_funcs.h" #include "t_hooks.h" #include "t_msgbuilder.h" @@ -1084,6 +1085,50 @@ int t_wait_no_more_branches( struct cell *t, int extra) } +int t_wait_no_more_branches_timeout(struct cell *t, int code) +{ + static context_p my_ctx = NULL; + context_p old_ctx; + struct cell *old_t; + branch_bm_t cancel_bitmap = 0; + int b; + + for (b = t->nr_of_outgoings - 1; b >= t->first_branch; b--) { + if (t->uac[b].flags & T_UAC_IS_PHONY) { + if (t->uac[b].last_received < 200) { + old_ctx = current_processing_ctx; + old_t = get_t(); + if (my_ctx == NULL) { + my_ctx = context_alloc(CONTEXT_GLOBAL); + if (my_ctx == NULL) { + LM_ERR("failed to alloc new ctx in pkg\n"); + return -1; + } + } + memset(my_ctx, 0, context_size(CONTEXT_GLOBAL)); + set_global_context(my_ctx); + set_t(t); + + _tm_branch_index = b; + LOCK_REPLIES(t); + relay_reply(t, FAKED_REPLY, b, code, &cancel_bitmap); + _tm_branch_index = 0; + + if (current_processing_ctx == NULL) + my_ctx = NULL; + else + context_destroy(CONTEXT_GLOBAL, my_ctx); + set_global_context(old_ctx); + set_t(old_t); + } + t->uac[b].br_flags = t->nr_of_outgoings; + return 0; + } + } + + return -1; +} + int t_inject_branch( struct cell *t, struct sip_msg *msg, int flags) { static struct sip_msg faked_req; diff --git a/modules/tm/t_fwd.h b/modules/tm/t_fwd.h index 51a6234bc45..8352a87e193 100644 --- a/modules/tm/t_fwd.h +++ b/modules/tm/t_fwd.h @@ -58,8 +58,7 @@ struct script_route_ref *get_on_branch(); typedef int (*tgetbranch_f)(void); int get_branch_index(void); -extern int w_t_wait_for_new_branches(struct sip_msg* msg); - +extern int w_t_wait_for_new_branches(struct sip_msg* msg, unsigned int br_to_wait); extern int w_t_inject_branches(struct sip_msg* msg, void *source, void *extra_flags); int t_inject_ul_event_branch(void); @@ -67,6 +66,7 @@ int t_inject_ul_event_branch(void); int t_inject_branch( struct cell *t, struct sip_msg *msg, int flags); int t_wait_no_more_branches( struct cell *t, int extra); +int t_wait_no_more_branches_timeout(struct cell *t, int code); void get_cancel_reason(struct sip_msg *msg, int flags, str *reason); diff --git a/modules/tm/timer.c b/modules/tm/timer.c index b9edbe1b636..9177efe84e7 100644 --- a/modules/tm/timer.c +++ b/modules/tm/timer.c @@ -216,13 +216,13 @@ static void delete_cell( struct cell *p_cell, int unlock ) if (is_in_timer_list2(& p_cell->uac[i].local_cancel.retr_timer)) { LM_ERR("transaction %p scheduled for deletion and" " still on RETR/cancel (req %d), timeout %lld\n", p_cell, i, - p_cell->uac[i].request.retr_timer.time_out); + p_cell->uac[i].local_cancel.retr_timer.time_out); abort(); } if (is_in_timer_list2(& p_cell->uac[i].local_cancel.fr_timer)) { LM_ERR("transaction %p scheduled for deletion and" " still on FR/cancel (req %d), timeout %lld\n", p_cell, i, - p_cell->uac[i].request.fr_timer.time_out); + p_cell->uac[i].local_cancel.fr_timer.time_out); abort(); } } diff --git a/modules/tm/tm.c b/modules/tm/tm.c index c09081c94ee..410177fc8c9 100644 --- a/modules/tm/tm.c +++ b/modules/tm/tm.c @@ -160,6 +160,7 @@ static int w_t_new_request(struct sip_msg* msg, str *method, static int t_wait_for_new_branches(struct sip_msg* msg, unsigned int* br_to_wait); static int w_t_wait_no_more_branches(struct sip_msg* msg); +static int api_t_wait_no_more_branches(void); static int t_reply_by_callid(struct sip_msg* msg, unsigned int* code, str* text, str* callid, str* cseq); static int t_get_branch_idx_by_attr(struct sip_msg* msg, @@ -810,6 +811,7 @@ int load_tm( struct tm_binds *tmb) tmb->setlocalTholder = setlocalTholder; tmb->get_branch_index = get_branch_index; tmb->t_wait_for_new_branches = w_t_wait_for_new_branches; + tmb->t_wait_no_more_branches = api_t_wait_no_more_branches; tmb->t_inject_ul_event_branch = t_inject_ul_event_branch; /* tm context functions */ @@ -1712,9 +1714,9 @@ int w_t_inject_branches(struct sip_msg* msg, void *source, void *extra_flags) } -int w_t_wait_for_new_branches(struct sip_msg* msg) +int w_t_wait_for_new_branches(struct sip_msg* msg, unsigned int br_to_wait) { - return t_wait_for_new_branches(msg, 0); + return t_wait_for_new_branches(msg, &br_to_wait); } @@ -1769,6 +1771,39 @@ static int w_t_wait_no_more_branches(struct sip_msg* msg) } +static int api_t_wait_no_more_branches(void) +{ + struct cell *t; + int is_local = 0, rc; + + t = get_t(); + if (t != T_NULL_CELL && t != T_UNDEFINED) { + is_local = 1; + } else { + if (remote_T == NULL) + return -1; + + if (remote_T->hash == 0 && remote_T->label == 0) { + LM_BUG("invalid T ID (bad hexa %d,%d) found in remote_T\n", + remote_T->hash, remote_T->label); + return -1; + } + + if (t_lookup_ident(&t, remote_T->hash, remote_T->label) < 0) { + LM_DBG("transaction %u:%u not found anymore\n", + remote_T->hash, remote_T->label); + return -1; + } + } + + rc = t_wait_no_more_branches_timeout(t, 408) < 0 ? -1 : 1; + + if (!is_local) + t_unref_cell(t); + + return rc; +} + static int t_reply_by_callid(struct sip_msg* msg, unsigned int* code, str* text, str* callid, str* cseq_number) { struct cell *trans; diff --git a/modules/tm/tm_load.h b/modules/tm/tm_load.h index 9900f14de17..47c89eff264 100644 --- a/modules/tm/tm_load.h +++ b/modules/tm/tm_load.h @@ -96,8 +96,23 @@ struct tm_binds { set_localT_holder_f setlocalTholder; tgetbranch_f get_branch_index; - /* Return: 1 on success, -1 otherwise */ - int (*t_wait_for_new_branches) (struct sip_msg *msg); + /** + * Keep the transaction in an unresolved state (no final response), even if + * all pending branches are completed. The transaction will then complete + * when either the specified @num_br number of branches have completed, or + * if it times out. + * + * Return: 1 on success, -1 otherwise + */ + int (*t_wait_for_new_branches) (struct sip_msg *msg, unsigned int num_br); + + /** + * Stop waiting for any still-pending phony branch created by + * t_wait_for_new_branches(). + * + * Return: 1 on success, -1 otherwise + */ + int (*t_wait_no_more_branches) (void); /** * Injects and relays a new branch for the current transaction using the diff --git a/modules/topology_hiding/README b/modules/topology_hiding/README deleted file mode 100644 index d1abf1cd79a..00000000000 --- a/modules/topology_hiding/README +++ /dev/null @@ -1,452 +0,0 @@ -topology_hiding Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. th_callid_passwd (string) - 1.3.2. th_callid_prefix (string) - 1.3.3. th_passed_contact_uri_params (string) - 1.3.4. th_passed_contact_params (string) - 1.3.5. force_dialog (int) - 1.3.6. th_contact_encode_passwd (string) - 1.3.7. th_contact_encode_param (string) - 1.3.8. th_contact_encode_scheme (string) - 1.3.9. th_contact_caller_username_var (string) - 1.3.10. th_contact_callee_username_var (string) - - 1.4. Exported Functions - - 1.4.1. topology_hiding() - 1.4.2. topology_hiding_match([dlg_match_mode]) - - 1.5. Exported Pseudo-Variables - - 1.5.1. $TH_callee_callid - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set th_callid_passwd parameter - 1.2. Set th_callid_prefix parameter - 1.3. Set th_passed_contact_uri_params parameter - 1.4. Set th_passed_contact_params parameter - 1.5. Set force_dialog parameter - 1.6. Set th_contact_encode_passwd parameter - 1.7. Set th_contact_encode_param parameter - 1.8. Set th_contact_encode_scheme parameter - 1.9. Set th_contact_caller_username_var parameter - 1.10. Set th_contact_callee_username_var parameter - 1.11. topology_hiding usage - 1.12. Calling topology_hiding_match() function for topology - hiding sequential requests - - 1.13. topology_hiding_match_dialog() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This is a module which provides topology hiding capabilities. - The module can work on top of the dialog module, or as a - standalone module ( thus alowing topology hiding for all types - of requests ) - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction Module. - * Dialog Module, if “force_dialog” module parameter is - enabled, or a dialog is created from the configuration - script. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. th_callid_passwd (string) - - The string password that will be used for encoding/decoding the - callid in case of topology_hiding with callid mangling. - - Default value is “"OpenSIPS"” - - Example 1.1. Set th_callid_passwd parameter -... -modparam("topology_hiding", "th_callid_passwd", "my_topo_hiding_secret") -... - -1.3.2. th_callid_prefix (string) - - The prefix that will be used for detecting callids which have - been encoded by the dialog topology hiding. Make sure to change - this value in case your SIP path contains multiple OpenSIPS - boxes with topology hiding. - - Default value is “"DLGCH_"” - - Example 1.2. Set th_callid_prefix parameter -... -modparam("topology_hiding", "th_callid_prefix", "MYCALLIDPREFIX_") -... - -1.3.3. th_passed_contact_uri_params (string) - - List of semicolon-separated Contact URI parameters that will be - passed from one side to the other for topology hiding calls. To - be used when end-to-end functionality uses such Contact URI - parameters. - - Default value is “empty” - do not pass any parameters - - Example 1.3. Set th_passed_contact_uri_params parameter -... -modparam("topology_hiding", "th_passed_contact_uri_params", "paramname1; -myparam;custom_param") -... - -1.3.4. th_passed_contact_params (string) - - List of semicolon-separated Contact header parameters that will - be passed from one side to the other for topology hiding calls. - To be used when end-to-end functionality uses such Contact - header parameters. - - Default value is “empty” - do not pass any parameters - - Example 1.4. Set th_passed_contact_params parameter -... -modparam("topology_hiding", "th_passed_contact_params", "paramname1;mypa -ram;custom_param") -... - -1.3.5. force_dialog (int) - - If set to 1, the module will internally create the dialog ( if - not already created ). This will only work for INVITE based - dialogs, and the dialog module must be loaded. - - Default value is “0” - - Example 1.5. Set force_dialog parameter -... -modparam("topology_hiding", "force_dialog", 1) -... - -1.3.6. th_contact_encode_passwd (string) - - When not relying on the dialog module ( due to script writer - preference or simply when doing topo hiding for non INVITE - dialogs ), the module will store the needed information in a - Contact URI param. The parameter configures the string password - that will be used for encoding/decoding that specific param . - - Default value is “"ToPoCtPaSS"” - - Example 1.6. Set th_contact_encode_passwd parameter -... -modparam("topology_hiding", "th_contact_encode_passwd", "my_topoh_passwd -") -... - -1.3.7. th_contact_encode_param (string) - - When not relying on the dialog module ( due to script writer - preference or simply when doing topo hiding for non INVITE - dialogs ), the module will store the needed information in a - Contact URI param. The parameter configures the respective - parameter name. - - Default value is “"thinfo"” - - Example 1.7. Set th_contact_encode_param parameter -... -modparam("topology_hiding", "th_contact_encode_param", "customparam") -... - -1.3.8. th_contact_encode_scheme (string) - - When not relying on the dialog module ( due to script writer - preference or simply when doing topo hiding for non INVITE - dialogs ), the module will store the needed information in a - Contact URI param. This parameter configures the encoding - scheme to be used for the data stored in the Contact URI param. - Possible values are: - * base64 - * base32 - - Default value is “"base64"” - - Example 1.8. Set th_contact_encode_scheme parameter -... -modparam("topology_hiding", "th_contact_encode_scheme", "base32") -... - -1.3.9. th_contact_caller_username_var (string) - - Variable used to store the value of the contact username - advertised to the caller. - - Default value is “_th_contact_caller_username_var_” - - Example 1.9. Set th_contact_caller_username_var parameter -... -modparam("topology_hiding", "th_contact_caller_username_var", "__topo_hi -ding_username_var__") -... - -1.3.10. th_contact_callee_username_var (string) - - Variable used to store the value of the contact username - advertised to the callee. - - Default value is “_th_contact_callee_username_var_” - - Example 1.10. Set th_contact_callee_username_var parameter -... -modparam("topology_hiding", "th_contact_callee_username_var", "__topo_hi -ding_username_var__") -... - -1.4. Exported Functions - -1.4.1. topology_hiding() - - By calling this function on an initial request, the modules - will hide the topology, meaning that it will strip and restore - all the Via, Record-Route and Route headers and it will replace - the contact with the IP address of the interface where the - request was received. - - You must note however, that the detection of the future - in-dialog requests(BYE, reInvite, etc.) for these dialogs on - which topology hiding is applied, is not done automatically. - Without topology hiding and only normal dialog, the detection - was done when loose_route was called. But now, for this dialogs - where topology hiding is applied, the in dialog requests - reaching OpenSIPS won't have any Route headers and the RURI - will point to OpenSIPS machine. So, to be able to match the - in-dialog requests to the corresponding dialog, a script - function must be called. It's name is topology_hiding_match and - you can read it's description above. The in-dialog topology - requests are requests with a to tag, RURI pointing to opensips - and with a method specific to a Invite dialog. For this kind of - requests you should call topology_hiding_match() function. If - the request is successfully matched and fixed as according to - the topology hiding logic,the function returns success. - - Optionally,the function also receives a string parameter, which - holds string flags. Current options for the string flags are : - * U - Propagate the Username in the Contact header URI - * D - Dialog ID (DID) is pushed into Contact username, rather - than URI param. This option makes sense only when using - topology hiding with dialog support. - * a - Preserve the advertised Contact header advertised to - the caller throughout the entire dialog. - * A - Preserve the advertised Contact header advertised to - the callee throughout the entire dialog. - * D - Dialog ID (DID) is pushed into Contact username, rather - than URI param. This option makes sense only when using - topology hiding with dialog support. - * C - Encode the callid header - There are many cases where propagating the callid towards - the callee side is not a good idea, since sometimes the - callid contains the IP of the actual caller side, thus - revealing part of the network topology. - When using the "C" flag, the callid will be automatically - encoded / decoded, transparent for the script writer - - inside OpenSIPS (script,MI functions, etc ) all the - variables related to the callid will represent the callid - value for the caller side. If the callid for the callee - side is needed, refer to the $TH_callee_callid pvar. - Note: Changing the callid of the call using the "C" flag is - only available when doing topology_hiding with dialog - support. Using this flag without dialog support will not - change the callid at all!. - - The second parameter can be used to advertise a particular - username in the Contact header URI, either on the caller, - either on the callee leg, separated by /. The format of the - parameter is - caller_username|/[caller_contact_username][/callee_contact_user - name]. If the separator is missing, the same contact username - is advertised on both legs. If the separator is being used, you - can control the username put in contact per leg. - - Example 1.11. topology_hiding usage -... -if(!has_totag() && is_method("INVITE")) { - topology_hiding(); -} -... -... -if(!has_totag() && is_method("INVITE")) { - topology_hiding("U"); -} -... -# set "opensips" for both caller and the callee's Contact username -if(!has_totag() && is_method("INVITE")) { - topology_hiding("U", "opensips"); -} -... -# set "caller" in the caller's Contact username -if(!has_totag() && is_method("INVITE")) { - topology_hiding("U", "/caller"); -} -... -# set "callee" in the callee's Contact username -if(!has_totag() && is_method("INVITE")) { - topology_hiding("U", "//callee"); -} -... -# set "caller" in the caller's Contact username and -# "callee" in the callee's Contact username -if(!has_totag() && is_method("INVITE")) { - topology_hiding("U", "/caller/callee"); -} -... - - Example 1.12. Calling topology_hiding_match() function for - topology hiding sequential requests -... -if (has_totag()) - if(topology_hiding_match()) - { - xlog("Found a request $rm belonging to an existing topol -ogy hiding dialog\n"); - route(relay); - exit; - } -} -... - -1.4.2. topology_hiding_match([dlg_match_mode]) - - This function is to be used to match and fix a sequential - request belong to an existing topology hiding dialog. - - With regards to dialog matching (including the optional - parameter), this function behaves identically to - match_dialog(). Please see the dialog module documentation for - further details regarding dialog matching options. - - The function returns true if a topology hiding dialog exists - for the request and the request has been successfully fixed. - - This function can be used from REQUEST_ROUTE. - - Example 1.13. topology_hiding_match_dialog() usage -... - if (has_totag()) { - if (!topology_hiding_match() ) { - xlog(" cannot match request to a dialog \n"); - send_reply(404,"Not found"); - } else - route(RELAY); - } -... - -1.5. Exported Pseudo-Variables - -1.5.1. $TH_callee_callid - - Read only variable that will contain the callid as it is - propagated towards the callee side, in case - topology_hiding("C") is called. - - NULL will be returned if there is no topology hiding dialog for - the request or if topology_hiding with callid encoding was not - used for the current dialog. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Razvan Crainea (@razvancrainea) 39 27 728 290 - 2. Vlad Paiu (@vladpaiu) 32 8 2700 25 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 25 21 146 88 - 4. Liviu Chircu (@liviuchircu) 17 15 81 56 - 5. Vlad Patrascu (@rvlad-patrascu) 9 6 82 72 - 6. Maksym Sobolyev (@sobomax) 8 6 9 10 - 7. Alexey Vasilyev (@vasilevalex) 4 2 3 15 - 8. Peter Lemenkov (@lemenkov) 4 2 2 2 - 9. James Stanley 3 1 2 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2015 - Mar 2025 - 2. Razvan Crainea (@razvancrainea) Aug 2015 - Mar 2025 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2015 - Dec 2023 - 4. James Stanley Dec 2023 - Dec 2023 - 5. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 6. Vlad Patrascu (@rvlad-patrascu) May 2017 - Feb 2020 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jan 2020 - 8. Alexey Vasilyev (@vasilevalex) Sep 2019 - Sep 2019 - 9. Vlad Paiu (@vladpaiu) Feb 2015 - Mar 2016 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu - (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2015 OpenSIPS Foundation diff --git a/modules/topology_hiding/README.md b/modules/topology_hiding/README.md new file mode 100644 index 00000000000..3c11a6f471e --- /dev/null +++ b/modules/topology_hiding/README.md @@ -0,0 +1,359 @@ +--- +title: "Topology Hiding Module" +description: "This is a module which provides topology hiding capabilities." +--- + +## Admin Guide + + +### Overview + + +This is a module which provides topology hiding capabilities. +The module can work on top of the dialog module, or as a standalone module ( thus alowing topology hiding for all +types of requests ) + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM - Transaction Module*. +- *Dialog Module*, if "force_dialog" +module parameter is enabled, or a dialog is created from the +configuration script. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### th_callid_passwd (string) + + +The string password that will be used for encoding/decoding the callid in case of topology_hiding with callid mangling. + + +*Default value is ""OpenSIPS""* + + +```opensips title="Set th_callid_passwd parameter" +... +modparam("topology_hiding", "th_callid_passwd", "my_topo_hiding_secret") +... +``` + + +#### th_callid_prefix (string) + + +The prefix that will be used for detecting callids which have been encoded by the dialog topology hiding. Make sure to change this value in case your SIP path contains multiple OpenSIPS boxes with topology hiding. + + +*Default value is ""DLGCH_""* + + +```opensips title="Set th_callid_prefix parameter" +... +modparam("topology_hiding", "th_callid_prefix", "MYCALLIDPREFIX_") +... +``` + + +#### th_passed_contact_uri_params (string) + + +List of semicolon-separated Contact URI parameters that will be passed from one side to the other for topology hiding calls. To be used when end-to-end functionality uses such Contact URI parameters. + + +*Default value is "empty" - do not pass any parameters* + + +```opensips title="Set th_passed_contact_uri_params parameter" +... +modparam("topology_hiding", "th_passed_contact_uri_params", "paramname1;myparam;custom_param") +... +``` + + +#### th_passed_contact_params (string) + + +List of semicolon-separated Contact header parameters that will be passed from one side to the other for topology hiding calls. To be used when end-to-end functionality uses such Contact header parameters. + + +*Default value is "empty" - do not pass any parameters* + + +```opensips title="Set th_passed_contact_params parameter" +... +modparam("topology_hiding", "th_passed_contact_params", "paramname1;myparam;custom_param") +... +``` + + +#### force_dialog (int) + + +If set to 1, the module will internally create the dialog ( if not already created ). This will only work for INVITE based dialogs, and the dialog module must be loaded. + + +*Default value is "0"* + + +```opensips title="Set force_dialog parameter" +... +modparam("topology_hiding", "force_dialog", 1) +... +``` + + +#### th_contact_encode_passwd (string) + + +When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. The parameter configures the string password that will be used for encoding/decoding that specific param . + + +*Default value is ""ToPoCtPaSS""* + + +```opensips title="Set th_contact_encode_passwd parameter" +... +modparam("topology_hiding", "th_contact_encode_passwd", "my_topoh_passwd") +... +``` + + +#### th_contact_encode_param (string) + + +When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. The parameter configures the respective parameter name. + + +*Default value is ""thinfo""* + + +```opensips title="Set th_contact_encode_param parameter" +... +modparam("topology_hiding", "th_contact_encode_param", "customparam") +... +``` + + +#### th_contact_encode_scheme (string) + + +When not relying on the dialog module ( due to script writer preference or simply when doing topo hiding for non INVITE dialogs ), the module will store the needed information in a Contact URI param. This parameter configures the encoding scheme to be used for the data stored in +the Contact URI param. Possible values are: + + +- *base64* +- *base32* + + +*Default value is ""base64""* + + +```opensips title="Set th_contact_encode_scheme parameter" +... +modparam("topology_hiding", "th_contact_encode_scheme", "base32") +... +``` + + +#### th_contact_caller_username_var (string) + + +Variable used to store the value of the contact username advertised to the caller. + + +*Default value is "_th_contact_caller_username_var_"* + + +```opensips title="Set th_contact_caller_username_var parameter" +... +modparam("topology_hiding", "th_contact_caller_username_var", "__topo_hiding_username_var__") +... +``` + + +#### th_contact_callee_username_var (string) + + +Variable used to store the value of the contact username advertised to the callee. + + +*Default value is "_th_contact_callee_username_var_"* + + +```opensips title="Set th_contact_callee_username_var parameter" +... +modparam("topology_hiding", "th_contact_callee_username_var", "__topo_hiding_username_var__") +... +``` + + +### Exported Functions + + +#### topology_hiding() + + +By calling this function on an initial request, the modules will +hide the topology, meaning that it will strip and restore all the Via, +Record-Route and Route headers and it will replace the contact with the +IP address of the interface where the request was received. + + +You must note however, that the detection of the future in-dialog requests(BYE, reInvite, etc.) +for these dialogs on which topology hiding is applied, is not done automatically. +Without topology hiding and only normal dialog, the detection was +done when loose_route was called. But now, for this dialogs where topology +hiding is applied, the in dialog requests reaching OpenSIPS won't have any Route headers +and the RURI will point to OpenSIPS machine. +So, to be able to match the in-dialog requests to the corresponding dialog, a script +function must be called. It's name is *topology_hiding_match* and you can read +it's description above. +The in-dialog topology requests are requests with a to tag, +RURI pointing to opensips and with a method specific to a +Invite dialog. For this kind of requests you should call +topology_hiding_match() function. If the request is successfully matched and fixed as according to the topology hiding logic,the function returns success. + + +Optionally,the function also receives a string parameter, which holds string flags. +Current options for the string flags are : + + +- *U* - Propagate the Username in the Contact header URI +- *D* - Dialog ID (DID) is pushed into Contact username, rather than URI param. This option makes sense only when using topology hiding with dialog support. +- *a* - Preserve the advertised Contact header advertised to the caller throughout the entire dialog. +- *A* - Preserve the advertised Contact header advertised to the callee throughout the entire dialog. +- *D* - Dialog ID (DID) is pushed into Contact username, rather than URI param. This option makes sense only when using topology hiding with dialog support. +- *C* - Encode the callid header +There are many cases where propagating the callid towards the callee side is not a good idea, since sometimes the callid contains the IP of the actual caller side, thus revealing part of the network topology. +When using the "C" flag, the callid will be automatically encoded / decoded, transparent for the script writer - inside OpenSIPS (script,MI functions, etc ) all the variables related to the callid will represent the callid value for the caller side. If the callid for the callee side is needed, refer to the $TH_callee_callid pvar. +*Note:* Changing the callid of the call using the "C" flag is only +available when doing topology_hiding with *dialog support*. Using this +flag without dialog support will not change the callid at all!. + + +The second parameter can be used to advertise a particular +*username* in the Contact header URI, either on the +*caller*, either on the *callee* +leg, separated by */*. The format of the parameter is +*caller_username|/[caller_contact_username][/callee_contact_username]*. +If the separator is missing, the same contact username is advertised on +both legs. If the separator is being used, you can control the username +put in contact per leg. + + +```opensips title="topology_hiding usage" +... +if(!has_totag() && is_method("INVITE")) { + topology_hiding(); +} +... +... +if(!has_totag() && is_method("INVITE")) { + topology_hiding("U"); +} +... +# set "opensips" for both caller and the callee's Contact username +if(!has_totag() && is_method("INVITE")) { + topology_hiding("U", "opensips"); +} +... +# set "caller" in the caller's Contact username +if(!has_totag() && is_method("INVITE")) { + topology_hiding("U", "/caller"); +} +... +# set "callee" in the callee's Contact username +if(!has_totag() && is_method("INVITE")) { + topology_hiding("U", "//callee"); +} +... +# set "caller" in the caller's Contact username and +# "callee" in the callee's Contact username +if(!has_totag() && is_method("INVITE")) { + topology_hiding("U", "/caller/callee"); +} +... +``` + + +```opensips title="Calling topology_hiding_match() function for topology hiding sequential requests" +... +if (has_totag()) + if(topology_hiding_match()) + { + xlog("Found a request $rm belonging to an existing topology hiding dialog\n"); + route(relay); + exit; + } +} +... +``` + + +#### topology_hiding_match([dlg_match_mode]) + + +This function is to be used to match and fix a sequential request +belong to an existing topology hiding dialog. + + +With regards to dialog matching (including the optional parameter), +this function behaves identically to match_dialog(). Please see the +dialog module documentation for further details regarding dialog +matching options. + + +The function returns true if a topology hiding dialog exists for the request and the request has been successfully fixed. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="topology_hiding_match_dialog() usage" +... + if (has_totag()) { + if (!topology_hiding_match() ) { + xlog(" cannot match request to a dialog \n"); + send_reply(404,"Not found"); + } else + route(RELAY); + } +... +``` + + +### Exported Pseudo-Variables + + +#### $TH_callee_callid + + +Read only variable that will contain the callid as it is propagated towards the callee side, in case topology_hiding("C") is called. + + +NULL will be returned if there is no topology hiding dialog for the request or if topology_hiding with callid encoding was not used for the current dialog. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/topology_hiding/doc/contributors.xml b/modules/topology_hiding/doc/contributors.xml deleted file mode 100644 index 1382ed99da2..00000000000 --- a/modules/topology_hiding/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Razvan Crainea (@razvancrainea) - 39 - 27 - 728 - 290 - - - 2. - Vlad Paiu (@vladpaiu) - 32 - 8 - 2700 - 25 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 25 - 21 - 146 - 88 - - - 4. - Liviu Chircu (@liviuchircu) - 17 - 15 - 81 - 56 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - 9 - 6 - 82 - 72 - - - 6. - Maksym Sobolyev (@sobomax) - 8 - 6 - 9 - 10 - - - 7. - Alexey Vasilyev (@vasilevalex) - 4 - 2 - 3 - 15 - - - 8. - Peter Lemenkov (@lemenkov) - 4 - 2 - 2 - 2 - - - 9. - James Stanley - 3 - 1 - 2 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2015 - Mar 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2015 - Mar 2025 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2015 - Dec 2023 - - - 4. - James Stanley - Dec 2023 - Dec 2023 - - - 5. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Feb 2020 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jan 2020 - - - 8. - Alexey Vasilyev (@vasilevalex) - Sep 2019 - Sep 2019 - - - 9. - Vlad Paiu (@vladpaiu) - Feb 2015 - Mar 2016 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/topology_hiding/doc/topology_hiding.xml b/modules/topology_hiding/doc/topology_hiding.xml deleted file mode 100644 index c9ea71c6a9c..00000000000 --- a/modules/topology_hiding/doc/topology_hiding.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - topology_hiding Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2015 OpenSIPS Foundation - - diff --git a/modules/topology_hiding/th_no_dlg_logic.c b/modules/topology_hiding/th_no_dlg_logic.c index ec73937280c..2bf17c9dfd0 100644 --- a/modules/topology_hiding/th_no_dlg_logic.c +++ b/modules/topology_hiding/th_no_dlg_logic.c @@ -30,6 +30,7 @@ #include "thinfo_codec.h" #include #include +#include #define START_THINFO_BUF_SZ 1000 #define THINFO_MAX_BUFFER_SIZE 10000 @@ -602,6 +603,16 @@ static inline int _th_no_dlg_onrequest(struct sip_msg *req, uint16_t flags, str ((contact_body_t *) ((_m)->contact->parsed))->contacts == NULL || \ ((contact_body_t *) ((_m)->contact->parsed))->contacts->next != NULL) +static inline int topo_ct_short_len(int len, short *out, const char *field) +{ + if (len < 0 || len > SHRT_MAX) { + LM_ERR("%s too long for encoded contact (%d)\n", field, len); + return -1; + } + *out = (short)len; + return 0; +} + static char* build_encoded_contact_suffix_legacy(struct sip_msg* msg, str *routes, unsigned int rrs_to_ignore, int *suffix_len, int flags) { short rr_len,ct_len,addr_len,flags_len,enc_len; char *suffix_plain = NULL,*suffix_enc = NULL,*p = NULL,*s = NULL; @@ -631,15 +642,17 @@ static char* build_encoded_contact_suffix_legacy(struct sip_msg* msg, str *route if (routes && routes->len > 0) { rr_set = *routes; - rr_len = (short)routes->len; + if (topo_ct_short_len(routes->len, &rr_len, "route set") < 0) + return NULL; LM_DBG("XXX: adding [%.*s]\n", routes->len, routes->s); } else if(msg->record_route){ if (print_rr_body(msg->record_route, &rr_set, !is_req, 0, &rrs_to_ignore) != 0){ LM_ERR("failed to print route records \n"); return NULL; } - rr_len = (short)rr_set.len; rr_set_free_str = rr_set.s; + if (topo_ct_short_len(rr_set.len, &rr_len, "route set") < 0) + goto error; } else { rr_len = 0; } @@ -649,14 +662,17 @@ static char* build_encoded_contact_suffix_legacy(struct sip_msg* msg, str *route goto error; } else { contact = ((contact_body_t *)msg->contact->parsed)->contacts->uri; - ct_len = (short)contact.len; + if (topo_ct_short_len(contact.len, &ct_len, "contact") < 0) + goto error; } flags_str.s = int2str(flags, &flags_str.len); - flags_len = (short)flags_str.len; - - addr_len = (short)msg->rcv.bind_address->sock_str.len; - local_len += rr_len + ct_len + flags_len + addr_len; + if (topo_ct_short_len(flags_str.len, &flags_len, "flags") < 0) + goto error; + + if (topo_ct_short_len(msg->rcv.bind_address->sock_str.len, &addr_len, "bind address") < 0) + goto error; + local_len += rr_len + ct_len + flags_len + addr_len; enc_len = th_ct_enc_scheme == ENC_BASE64 ? calc_word64_encode_len(local_len) : calc_word32_encode_len(local_len); total_len = enc_len + diff --git a/modules/topology_hiding/topo_hiding_logic.c b/modules/topology_hiding/topo_hiding_logic.c index 837469e3308..aae8c42f4d8 100644 --- a/modules/topology_hiding/topo_hiding_logic.c +++ b/modules/topology_hiding/topo_hiding_logic.c @@ -1032,4 +1032,4 @@ static int dlg_th_callid_pre_parse(struct sip_msg *msg,int want_from) error: reset_proc_log_level(); return -1; -} \ No newline at end of file +} diff --git a/modules/tracer/README b/modules/tracer/README deleted file mode 100644 index d20a577b889..00000000000 --- a/modules/tracer/README +++ /dev/null @@ -1,575 +0,0 @@ -Tracer Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. trace_on (integer) - 1.3.2. trace_local_ip (str) - 1.3.3. trace_id (str) - 1.3.4. syslog_default_facility (string) - 1.3.5. syslog_default_level (integer) - 1.3.6. file_mode (integer) - - 1.4. Exported Functions - - 1.4.1. trace(trace_id, [scope], [type], - [trace_attrs], [flags], [correlation_id]) - - 1.5. Exported MI Functions - - 1.5.1. trace - 1.5.2. trace_start - 1.5.3. trace_stop - - 1.6. Database setup - 1.7. Known issues - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set trace_on parameter - 1.2. Set trace_local_ip parameter - 1.3. Set trace_id parameter - 1.4. Set syslog_default_facility parameter - 1.5. Set syslog_default_level parameter - 1.6. Set file_mode parameter - 1.7. trace() usage - -Chapter 1. Admin Guide - -1.1. Overview - - Offer a possibility to store incoming/outgoing SIP messages in - database. Since version 2.2, proto_hep module needs to be - loaded in order to duplicate with hep. All hep parameters moved - inside proto_hep. - - The 2.2 version of OpenSIPS came with a major improvement in - tracer module. Now all you have to do is call trace() function - with the proper parameters and it will do the job for you. Now - you can trace messages, transactions and dialogs with the same - function. Also, you can trace to multiple databases, multiple - hep destinations and sip destinations using only one parameter. - All you need now is defining trace_id parameters in modparam - section and switch between them in tracer function. Also you - cand turn tracing on and off using trace_on either globally(for - all trace_ids) or for a certain trace_id. - - IMPORTANT: In 2.2 version support for stateless trace has been - removed. - - The tracing tracing can be turned on/off using fifo command. - - opensips-cli -x mi trace on opensips-cli -x mi trace - [some_trace_id] on - - opensips-cli -x mi trace off opensips-cli -x mi trace - [some_trace_id] off - - Starting with OpenSIPS 3.0 you can use the trace_start to - create dynamic dynamic tracing destinations based on some - custom filters. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * database module - mysql, postrgress, dbtext, unixodbc... - only if you are using a database type trace id - * b2b_logic - only if you want to trace B2B sessions. - * dialog - only if you want to trace SIP dialogs (INVITE - based). - * tm - only if you want to trace SIP transactions. - * proto_hep - only if you want to trace / replicate messages - over HEP protocol. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.3. Exported Parameters - -1.3.1. trace_on (integer) - - Parameter to enable/disable trace (on(1)/off(0)) - - Default value is "1"(enabled). - - Example 1.1. Set trace_on parameter -... -modparam("tracer", "trace_on", 1) -... - -1.3.2. trace_local_ip (str) - - The address to be used in the fields that specify the source - address (protocol, ip and port) for locally generated messages. - If not set, the module sets it to the address of the socket - that will be used to send the message. Protocol and/or port are - optional and if omitted will take the default values: udp and - 5060. - - Default value is "NULL". - - Example 1.2. Set trace_local_ip parameter -... -#Resulting address: udp:10.1.1.1:5064 -modparam("tracer", "trace_local_ip", "10.1.1.1:5064") -... - -... -#Resulting address: tcp:10.1.1.1:5060 -modparam("tracer, "trace_local_ip", "tcp:10.1.1.1") -... - -... -#Resulting address: tcp:10.1.1.1:5064 -modparam("tracer", "trace_local_ip", "tcp:10.1.1.1:5064") -... - -... -#Resulting address: udp:10.1.1.1:5060 -modparam("tracer", "trace_local_ip", "10.1.1.1") -... - -1.3.3. trace_id (str) - - Specify a destination for the trace. This can be a hep id - defined in proto_hep, a sip uri, a file, a syslog facility or a - database url and a table. All parameters inside trace_id must - be separated by ;, excepting the last one. The parameters are - given in key-value format, the possible keys being uri for HEP - and SIP IDs and uri and table for databases. The format is - [id_name]key1=value1;key2=value2;. HEP id's MUST be defined in - proto_hep in order to be able to use them here. - - When the uri is a file, the path to the file has to be - specified after the colon. The output is always appended if the - file exists, or created if it doesn't, using file_mode - permissions. - - When the uri is syslog, it has to follow the following format: - syslog[:FACILITY[:LEVEL]]. The default facility and levels are - the ones used by OpenSIPS (syslog_facility and log_level). - These can be tuned using syslog_default_facility and - syslog_default_level parameters. - - One can declare multiple types of tracing under the same trace - id, being identified by their name. So if you define two - database url, one hep uri and one sip uri with the same name, - when calling trace() with this name tracing shall be done to - all the destinations. - - All the old parameter such as db_url, table and duplicate_uri - will form the trace id with the name "default". - - No default value. If not set the module will be useless. - - Example 1.3. Set trace_id parameter -... -/*DB trace id*/ -modparam("tracer", "trace_id", -"[tid] -uri=mysql://xxxx:xxxx@10.10.10.10/opensips; -table=new_sip_trace;") -/* hep trace id with the hep id defined in proto_hep; check proto_hep do -cs - * for more information */ -modparam("proto_hep", "hep_id", "[hid]10.10.10.10") -modparam("tracer", "trace_id", "[tid]uri=hep:hid") -/*sip trace id*/ -modparam("tracer", "trace_id", -"[tid]uri=sip:10.10.10.11:5060") -/* notice that they all have the same name - * meaning that calling trace("tid",...) - * will do sql, sip and hep tracing */ -/*file trace id*/ -modparam("tracer", "trace_id", -"[tid]uri=file:/path/to/file") -/*syslog trace id at error (level -1)*/ -modparam("tracer", "trace_id", -"[tid]uri=syslog:local0:-1") -... - -1.3.4. syslog_default_facility (string) - - When syslog tracing is used, this parameter specifies the log - facility to write traces to. - - Default value is the value of syslog_facility. - - Example 1.4. Set syslog_default_facility parameter -... -modparam("tracer", "syslog_default_facility", "LOG_DAEMON") -... - -1.3.5. syslog_default_level (integer) - - When syslog tracing is used, this parameter specifies the level - to write traces to. - - Default value is the value of log_level. - - Example 1.5. Set syslog_default_level parameter -... -modparam("tracer", "syslog_default_level", 2) # NOTICE -... - -1.3.6. file_mode (integer) - - When file tracing is used, this parameter specifies the - permissions to be used to create the trace files. It follows - the UNIX conventions. - - Default value is 0600 (rw-------). - - Example 1.6. Set file_mode parameter -... -modparam("tracer", "file_mode", 0644) -... - -1.4. Exported Functions - -1.4.1. trace(trace_id, [scope], [type], [trace_attrs], [flags], -[correlation_id]) - - This function has replaced the sip_trace() in OpenSIPS 3.0. - - Store or replicate current processed SIP message, transaction / - dialog or B2B session. It is stored in the form prior applying - chages made to it. The traced_user_avp parameter is now an - argument to trace() function. Since version 2.2, this function - also catches internally generated replies in stateless - mode(sl_send_reply(...)). - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, - ONREPLY_ROUTE, BRANCH_ROUTE. - - Meaning of the parameters is as follows: - * trace_id (string) the name of the trace_id specifying where - to do the tracing. - * scope (string, optional) what do you want to trace: dialog, - transaction, B2B session or only the message. If not - specified, will try the topmost trace that can be done: if - dialog module loaded will trace dialogs, else if tm module - loaded will trace transaction and if none of these loaded - will trace messages. - Types can be the following: - + 'm'/'M' trace messages. Is the only one you should use - in stateless mode. - + 't'/'T' trace transactions. If tm module not loaded, - it will be in stateless transaction aware mode meaning - that will catch selected requests both in and out and - internally generated replies. - + 'd'/'D' trace dialog - + 'b'/'B' trace all the traffic related to the B2B - session to be later created - * type (string, optional) list of types of messages to be - traced by this function; if not set only sip messages shall - be traced; if the parameter is set, but sip is not - specified, sip shall not be traced; all the parameters from - the list shall be separated by '|' - Current possible types to be traced are the following: - + sip - enable sip messages tracing; - + xlog - enable xlog messages tracing in current - scope(dialog, transaction, B2B session or message); - + rest - enable rest messages tracing; - * trace_attrs (string, optional) this parameter replaces the - traced_user_avp from the old version. To avoid duplicating - an entry only for this parameter, whatever you put - here(string/pvar) shall be stored in the trace_attrs column - in the sip_trace table. - * flags (string,pvar) are some control flags over the tracing - process (how and what to be traced). - + C - trace only the SIP caller side; - + c - trace onlt the SIP callee side; - If both C and c flags are missing, tracing of both - sides/legs is assumed. - NOTE these flags are supported only by transactional and - dialog tracing - * correlation_id (string,pvar) a custom SIP correlation ID to - be forced (normally the SIP Call-ID is used) to correlate - this traffic (transaction, dialog) with other traffic. - - Example 1.7. trace() usage -... -/* see declaration of tid in trace_id section */ - $var(trace_id) = "tid"; - $var(user) = "osip_user@opensips.org"; - -... -/* Example 1: how to trace a dialog sip and xlog */ - if (has_totag()) { - match_dialog(); - } else { - if (is_method("INVITE") { - trace($var(trace_id), "d", "sip|xlog", $var(user -)); - } - } -... -/* Example 2: how to trace initial INVITE and BYE, sip and rest */ - if (has_totag()) { - if (is_method("BYE")) { - trace($var(trace_id), "m", "sip|rest", $var(user -)); - } - } else { - if (is_method("INVITE")) { - trace($var(trace_id), "m", "sip|rest", $var(user -)); - } - } - -... -/* Example 3: trace initial INVITE transaction's only xlog and rest, no -sip */ - if (!has_totag()) { - if (is_method("INVITE")) { - trace($var(trace_id), "t", "xlog|rest", $var(use -r)); - } - } -... -/* Example 4: stateless transaction aware mode!*/ -/* tm module must not be loaded */ - if (is_method("REGISTER")) { - trace($var(trace_id), "t", "xlog|rest", $var(user)); - if (!www_authorize("", "subscriber")) { - /* tracer will also catch the 401 generated by w -ww_challenge() */ - www_challenge("", "auth"); - } - } - -1.5. Exported MI Functions - -1.5.1. trace - - Enable/disable tracing(globally or for a specific trace id) or - dump info about trace ids. This command requires named - parameters (each parameter is ginven in the format - param_name=param_value). - - Name: trace - - Parameters: - * id (optional) - the name of the tracing instance. If this - parameter is missing the command will either dump info for - all tace ids(and return the global tracing state) or set - the global tracing state. - * mode (optional) - possible values are: - + "on" - enable tracing - + "off" - disable tracing - If the first parameter is missing, the command wil set the - global tracing state, otherwise it will set the state for a - specific trace id. If you turn global trace on but some of - the trace ids had tracing set to off, then they shall not - do tracing. If you want to turn the tracing on for all - trace ids you will have to set it separately for each of - them. - If this parameter is missing but the first is set, the - command will only dump info about that specific trace id. - If both parameters are missing, the command will return the - global tracing state and dump info for each id. - - MI FIFO Command Format: -# Display global tracing mode and all trace destinations: -opensips-cli -x mi trace -# Turn off global tracing: -opensips-cli -x mi trace mode=off -# Turn on tracing for destination id tid2: -opensips-cli -x mi trace id=tid2 mode=on - -1.5.2. trace_start - - Creates a dynamic tracing destination based using custom - filters. This function can be used to debug calls for certain - destinations real-time. - - Dynamic destinations are not restart persistent! - - Name: trace_start - - Parameters: - * id - the name of the tracing instance. - * uri - the destination uri for this instance. - * filter (optional) - used to filter the traffic received by - the sender. This parameter should be an array that can - contain multiple filters in the condition=value format. - Possible values for the condition argument are: - + caller - - filter based on the caller (From username) - + callee - - filter based on the callee (R-URI username) - + ip - - filter based on the source IP of the message - The condition parameter can consist of multiple different - filters. In order to satisfy the overall condition and send - traffic to the desired destination, all conditions have to - be satisfied. - If this parameter is missing all traffic is forwarded to - the destination. - The filter is applied for any incoming request - * scope - the scope to engage the tracing for. The format - received by this parameter is similar to the one received - by the trace() function. - * type - the type of messages you want to receive. The format - received by this parameter is similar to the one received - by the trace() function. - - MI FIFO Command to start tracing calls from IP 127.0.0.1 to HEP - destination 10.0.0.1:9060: - opensips-cli -x mi trace_start id=ip_filter uri=hep:10.0 -.0.1:9060 filter=ip=127.0.0.1 - - MI FIFO Command to start tracing calls from user Alice to user - Bob: - opensips-cli -x mi trace_start id=alice_bob uri=hep:10.0 -.0.1:9060 filter=caller=Alice filter=caller=Bob - -1.5.3. trace_stop - - Stops OpenSIPS from sending traffic to a dynamic trace id - created using the trace_start command. - - Name: trace_stop - - Parameters: - * id - the name of the tracing instance to be stopped. - - MI FIFO Command to stop tracing calls from user Alice to user - Bob: - opensips-cli -x mi trace_stop alice_bob - -1.6. Database setup - - Before running OpenSIPS with tracer, you have to setup the - database tables where the module will store the data. For that, - if the table were not created by the installation script or you - choose to install everything by yourself you can use the - tracer-create.sql SQL script in the database directories in the - opensips/scripts folder as template. You can also find the - complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -1.7. Known issues - - ACKs related to a transaction that are leaving OpenSIPS are not - traced since they are handled statelessly using forward_request - function. Fixing it would mean to register a fwdcb callback - that would be called for all the messages but would be used - only by ACKs, which would be highly ineffective. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 115 88 1319 876 - 2. Ionut Ionita (@ionutrazvanionita) 107 52 2676 1887 - 3. Razvan Crainea (@razvancrainea) 76 54 1665 453 - 4. Daniel-Constantin Mierla (@miconda) 49 26 2215 191 - 5. Liviu Chircu (@liviuchircu) 26 23 87 80 - 6. Vlad Paiu (@vladpaiu) 24 10 402 568 - 7. Vlad Patrascu (@rvlad-patrascu) 17 8 286 335 - 8. Henning Westerholt (@henningw) 11 6 146 155 - 9. Andrei Datcu (@andrei-datcu) 11 5 284 135 - 10. Alexandr Dubovikov (@adubovikov) 7 1 500 4 - - All remaining contributors: Maksym Sobolyev (@sobomax), Dan - Pascu (@danpascu), Ovidiu Sas (@ovidiusas), Walter Doekes - (@wdoekes), Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), - Zero King (@l2dy), Andreas Heise, Nick Altmann (@nikbyte), - Sergio Gutierrez, okhowang, Konstantin Bokarius, Iouri Kharon, - Edson Gellert Schubert, Elena-Ramona Modroiu, Eric Tamme - (@etamme). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jul 2006 - Jul 2024 - 2. Razvan Crainea (@razvancrainea) Jun 2011 - Jul 2024 - 3. Liviu Chircu (@liviuchircu) Jan 2013 - May 2024 - 4. Ovidiu Sas (@ovidiusas) Mar 2020 - Apr 2024 - 5. Vlad Paiu (@vladpaiu) Jun 2011 - Dec 2023 - 6. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 8. okhowang Mar 2023 - Mar 2023 - 9. Peter Lemenkov (@lemenkov) Jun 2018 - Sep 2022 - 10. Nick Altmann (@nikbyte) Feb 2022 - Feb 2022 - - All remaining contributors: Walter Doekes (@wdoekes), Zero King - (@l2dy), Dan Pascu (@danpascu), Eric Tamme (@etamme), Ionut - Ionita (@ionutrazvanionita), Dusan Klinec (@ph4r05), Andrei - Datcu (@andrei-datcu), Alexandr Dubovikov (@adubovikov), Sergio - Gutierrez, Daniel-Constantin Mierla (@miconda), Iouri Kharon, - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Andreas Heise, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov - (@lemenkov), Nick Altmann (@nikbyte), Razvan Crainea - (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Liviu - Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas), Ionut Ionita - (@ionutrazvanionita), Andrei Datcu (@andrei-datcu), Alexandr - Dubovikov (@adubovikov), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw), Elena-Ramona Modroiu. - - Documentation Copyrights: - - Copyright © 2006 Voice Sistem SRL diff --git a/modules/tracer/README.md b/modules/tracer/README.md new file mode 100644 index 00000000000..f5eea3256e4 --- /dev/null +++ b/modules/tracer/README.md @@ -0,0 +1,534 @@ +--- +title: "Tracer Module" +description: "Offer a possibility to store incoming/outgoing SIP messages in database." +--- + +## Admin Guide + + +### Overview + + +Offer a possibility to store incoming/outgoing SIP messages in database. +Since version 2.2, proto_hep module needs to be loaded in order to duplicate +with hep. All hep parameters moved inside proto_hep. + + +The 2.2 version of OpenSIPS came with a major improvement in tracer module. +Now all you have to do is call *trace()* function +with the proper parameters and it will do the job for you. Now you can trace +messages, transactions and dialogs with the same function. Also, you can trace +to multiple databases, multiple hep destinations and sip destinations using +only one parameter. All you need now is defining *trace_id* +parameters in modparam section and switch between them in +tracer function. Also you cand turn tracing on +and off using *trace_on* either globally(for all trace_ids) +or for a certain trace_id. + + +> [!IMPORTANT] +> In 2.2 version support for stateless trace has been removed. + + +The tracing tracing can be turned on/off using fifo command. + +```bash +opensips-cli -x mi trace on +opensips-cli -x mi trace [some_trace_id] on + + +opensips-cli -x mi trace off +opensips-cli -x mi trace [some_trace_id] off +``` + +Starting with OpenSIPS 3.0 you can use the *trace_start* to +create dynamic dynamic tracing destinations based on some custom filters. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *database module* - mysql, postrgress, +dbtext, unixodbc... only if you are using a database type +trace id +- *b2b_logic* - only if you want to trace +B2B sessions. +- *dialog* - only if you want to trace +SIP dialogs (INVITE based). +- *tm* - only if you want to trace +SIP transactions. +- *proto_hep* - only if you want to +trace / replicate messages over HEP protocol. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### trace_on (integer) + + +Parameter to enable/disable trace (on(1)/off(0)) + + +*Default value is "1"(enabled).* + + +```opensips title="Set trace_on parameter" +... +modparam("tracer", "trace_on", 1) +... +``` + + +#### trace_local_ip (str) + + +The address to be used in the fields that specify the source address +(protocol, ip and port) for locally generated messages. If not set, +the module sets it to the address of the socket that will be used to send +the message. Protocol and/or port are optional and if omitted will take +the default values: udp and 5060. + + +*Default value is "NULL".* + + +```opensips title="Set trace_local_ip parameter" +... +#Resulting address: udp:10.1.1.1:5064 +modparam("tracer", "trace_local_ip", "10.1.1.1:5064") +... + +... +#Resulting address: tcp:10.1.1.1:5060 +modparam("tracer, "trace_local_ip", "tcp:10.1.1.1") +... + +... +#Resulting address: tcp:10.1.1.1:5064 +modparam("tracer", "trace_local_ip", "tcp:10.1.1.1:5064") +... + +... +#Resulting address: udp:10.1.1.1:5060 +modparam("tracer", "trace_local_ip", "10.1.1.1") +... +``` + + +#### trace_id (str) + + +Specify a destination for the trace. This can be a hep id defined +in proto_hep, a sip uri, a file, a syslog facility or a database +url and a table. All parameters inside +*trace_id* must be separated by +*;*, excepting the last one. The parameters +are given in key-value format, the possible keys being +*uri* for HEP and SIP IDs and +*uri* and *table* +for databases. The format is +*[id_name]key1=value1;key2=value2;*. HEP +id's **MUST** be defined in proto_hep in order +to be able to use them here. + + +When the uri is a *file*, the path to the file has +to be specified after the colon. The output is always appended if the file +exists, or created if it doesn't, using [file mode](#param_file_mode) +permissions. + + +When the uri is *syslog*, it has to follow the following +format: *syslog[:FACILITY[:LEVEL]]*. The default +facility and levels are the ones used by OpenSIPS +(*syslog_facility* and *log_level*). +These can be tuned using +[syslog default facility](#param_syslog_default_facility) and +[syslog default level](#param_syslog_default_level) parameters. + + +One can declare multiple types of tracing under the same trace +id, being identified by their name. So if you define two +database url, one hep uri and one sip uri with the same name, +when calling trace() with this name tracing shall be done +to all the destinations. + + +All the old parameter such as db_url, table and duplicate_uri +will form the trace id with the name "default". + + +*No default value. If not set the module will be useless.* + + +```opensips title="Set trace_id parameter" +... +/*DB trace id*/ +modparam("tracer", "trace_id", +"[tid] +uri=mysql://xxxx:xxxx@10.10.10.10/opensips; +table=new_sip_trace;") +/* hep trace id with the hep id defined in proto_hep; check proto_hep docs + * for more information */ +modparam("proto_hep", "hep_id", "[hid]10.10.10.10") +modparam("tracer", "trace_id", "[tid]uri=hep:hid") +/*sip trace id*/ +modparam("tracer", "trace_id", +"[tid]uri=sip:10.10.10.11:5060") +/* notice that they all have the same name + * meaning that calling trace("tid",...) + * will do sql, sip and hep tracing */ +/*file trace id*/ +modparam("tracer", "trace_id", +"[tid]uri=file:/path/to/file") +/*syslog trace id at error (level -1)*/ +modparam("tracer", "trace_id", +"[tid]uri=syslog:local0:-1") +... +``` + + +#### syslog_default_facility (string) + + +When *syslog* tracing is used, this parameter specifies +the log facility to write traces to. + + +*Default value is the value of *syslog_facility*.* + + +```opensips title="Set syslog_default_facility parameter" +... +modparam("tracer", "syslog_default_facility", "LOG_DAEMON") +... +``` + + +#### syslog_default_level (integer) + + +When *syslog* tracing is used, this parameter specifies +the level to write traces to. + + +*Default value is the value of *log_level*.* + + +```opensips title="Set syslog_default_level parameter" +... +modparam("tracer", "syslog_default_level", 2) # NOTICE +... +``` + + +#### file_mode (integer) + + +When *file* tracing is used, this parameter +specifies the permissions to be used to create the trace files. +It follows the UNIX conventions. + + +*Default value is *0600 (rw-------)*.* + + +```opensips title="Set file_mode parameter" +... +modparam("tracer", "file_mode", 0644) +... +``` + + +### Exported Functions + + +#### trace(trace_id, [scope], [type], [trace_attrs], [flags], [correlation_id]) + + +This function has replaced the *sip_trace()* in OpenSIPS 3.0. + + +Store or replicate current processed SIP message, transaction / dialog or B2B session. +It is stored in the form prior applying chages made to it. The traced_user_avp +parameter is now an argument to trace() function. Since version 2.2, this function +also catches internally generated replies in stateless mode(sl_send_reply(...)). + + +This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. + + +Meaning of the parameters is as follows: + + +- *trace_id (string)* +the name of the *trace_id* specifying where to do +the tracing. +- *scope (string, optional)* what do you +want to trace: dialog, transaction, B2B session or only the message. +If not specified, will try the topmost trace that can be done: +if dialog module loaded will trace dialogs, else if tm module loaded +will trace transaction and if none of these loaded will trace messages. +Types can be the following: + + - *'m'/'M'* trace messages. Is the only +one you should use in stateless mode. + - *'t'/'T'* trace transactions. If tm +module not loaded, it will be in stateless transaction aware +mode meaning that will catch selected requests both in and out +and internally generated replies. + - *'d'/'D'* trace dialog + - *'b'/'B'* trace all the traffic +related to the B2B session to be later created +- *type (string, optional)* list of types of messages to +be traced by this function; if not set only sip messages shall be traced; +if the parameter is set, but *sip* is not specified, +*sip* shall not be traced; +all the parameters from the list shall be separated by '|' +Current possible types to be traced are the following: + + - *sip* - enable sip messages +tracing; + - *xlog* - enable xlog messages +tracing in current scope(dialog, transaction, B2B session +or message); + - *rest* - enable rest messages +tracing; +- *trace_attrs (string, optional)* this parameter +replaces the traced_user_avp from the old version. To avoid duplicating +an entry only for this parameter, whatever you put here(string/pvar) +shall be stored in the trace_attrs column in the sip_trace table. +- *flags (string,pvar)* are some control +flags over the tracing process (how and what to be traced). + + - *C* - trace only the SIP caller side; + - *c* - trace onlt the SIP callee side; +If both *C* and *c* flags are missing, tracing of both sides/legs is assumed. +NOTE these flags are supported only by transactional and dialog tracing +- *correlation_id (string,pvar)* a custom +SIP correlation ID to be forced (normally the SIP Call-ID is used) +to correlate this traffic (transaction, dialog) with other traffic. + + +```opensips title="trace() usage" +... +/* see declaration of tid in trace_id section */ + $var(trace_id) = "tid"; + $var(user) = "osip_user@opensips.org"; + +... +/* Example 1: how to trace a dialog sip and xlog */ + if (has_totag()) { + match_dialog(); + } else { + if (is_method("INVITE") { + trace($var(trace_id), "d", "sip|xlog", $var(user)); + } + } +... +/* Example 2: how to trace initial INVITE and BYE, sip and rest */ + if (has_totag()) { + if (is_method("BYE")) { + trace($var(trace_id), "m", "sip|rest", $var(user)); + } + } else { + if (is_method("INVITE")) { + trace($var(trace_id), "m", "sip|rest", $var(user)); + } + } + +... +/* Example 3: trace initial INVITE transaction's only xlog and rest, no sip */ + if (!has_totag()) { + if (is_method("INVITE")) { + trace($var(trace_id), "t", "xlog|rest", $var(user)); + } + } +... +/* Example 4: stateless transaction aware mode!*/ +/* tm module must not be loaded */ + if (is_method("REGISTER")) { + trace($var(trace_id), "t", "xlog|rest", $var(user)); + if (!www_authorize("", "subscriber")) { + /* tracer will also catch the 401 generated by www_challenge() */ + www_challenge("", "auth"); + } + } +``` + + +### Exported MI Functions + + +#### trace + + +Enable/disable tracing(globally or for a specific trace id) or dump +info about trace ids. This command requires named parameters +(each parameter is ginven in the format param_name=param_value). + + +Name: *trace* + + +Parameters: + + +- *id* (optional) - the name of the tracing instance. +If this parameter is missing the command will +either dump info for all tace ids(and return the global tracing state) +or set the global tracing state. +- *mode* (optional) - +possible values are: + + - "on" - enable tracing + - "off" - disable tracing +If the first parameter is missing, the command wil set the global +tracing state, otherwise it will set the state for a specific trace id. +If you turn global trace on but some of the trace ids had tracing set to +off, then they shall not do tracing. If you want to turn the tracing on +for all trace ids you will have to set it separately for each of them. +If this parameter is missing but the first is set, the command will +only dump info about that specific trace id. If both parameters are +missing, the command will return the global tracing state and dump +info for each id. + + +MI FIFO Command Format: + + +```bash +# Display global tracing mode and all trace destinations: +opensips-cli -x mi trace +# Turn off global tracing: +opensips-cli -x mi trace mode=off +# Turn on tracing for destination id tid2: +opensips-cli -x mi trace id=tid2 mode=on + +``` + + +#### trace_start + + +Creates a dynamic tracing destination based using custom filters. +This function can be used to debug calls for certain destinations +real-time. + + +Dynamic destinations are not restart persistent! + + +Name: *trace_start* + + +Parameters: + + +- *id* - the name of the tracing instance. +- *uri* - the destination uri for this instance. +- *filter* (optional) - used to filter the traffic +received by the sender. This parameter should be an array that can +contain multiple filters in the *condition=value* +format. +Possible values for the *condition* argument are: + + - caller + - callee + - ip +The *condition* parameter can consist of multiple different filters. +In order to satisfy the overall condition and send traffic to the desired destination, +all conditions have to be satisfied. +If this parameter is missing all traffic is forwarded to the destination. +The filter is applied for any incoming request +- *scope* - the scope to engage the tracing for. +The format received by this parameter is similar to the one +received by the *trace()* function. +- *type* - the type of messages you want to receive. +The format received by this parameter is similar to the one +received by the *trace()* function. + + +MI FIFO Command to start tracing calls from IP 127.0.0.1 to HEP destination 10.0.0.1:9060: + + +```bash +opensips-cli -x mi trace_start id=ip_filter uri=hep:10.0.0.1:9060 filter=ip=127.0.0.1 +``` + + +MI FIFO Command to start tracing calls from user Alice to user Bob: + + +```bash +opensips-cli -x mi trace_start id=alice_bob uri=hep:10.0.0.1:9060 filter=caller=Alice filter=caller=Bob +``` + + +#### trace_stop + + +Stops OpenSIPS from sending traffic to a dynamic trace id created +using the *trace_start* command. + + +Name: *trace_stop* + + +Parameters: + + +- *id* - the name of the tracing instance to be stopped. + + +MI FIFO Command to stop tracing calls from user Alice to user Bob: + + +```bash +opensips-cli -x mi trace_stop alice_bob +``` + + +### Database setup + + +Before running OpenSIPS with tracer, you have to setup the database +tables where the module will store the data. For that, if the +table were not created by the installation script or you choose +to install everything by yourself you can use the tracer-create.sql +SQL script in the database directories in the +opensips/scripts folder as template. +You can also find the complete database documentation on the +project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +### Known Issues + + +ACKs related to a transaction that are leaving OpenSIPS are not +traced since they are handled statelessly using forward_request function. +Fixing it would mean to register a fwdcb callback that would be called +for all the messages but would be used only by ACKs, which would be +highly ineffective. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/tracer/doc/contributors.xml b/modules/tracer/doc/contributors.xml deleted file mode 100644 index 64b5ea4316c..00000000000 --- a/modules/tracer/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 115 - 88 - 1319 - 876 - - - 2. - Ionut Ionita (@ionutrazvanionita) - 107 - 52 - 2676 - 1887 - - - 3. - Razvan Crainea (@razvancrainea) - 76 - 54 - 1665 - 453 - - - 4. - Daniel-Constantin Mierla (@miconda) - 49 - 26 - 2215 - 191 - - - 5. - Liviu Chircu (@liviuchircu) - 26 - 23 - 87 - 80 - - - 6. - Vlad Paiu (@vladpaiu) - 24 - 10 - 402 - 568 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 17 - 8 - 286 - 335 - - - 8. - Henning Westerholt (@henningw) - 11 - 6 - 146 - 155 - - - 9. - Andrei Datcu (@andrei-datcu) - 11 - 5 - 284 - 135 - - - 10. - Alexandr Dubovikov (@adubovikov) - 7 - 1 - 500 - 4 - - - -
-All remaining contributors: Maksym Sobolyev (@sobomax), Dan Pascu (@danpascu), Ovidiu Sas (@ovidiusas), Walter Doekes (@wdoekes), Peter Lemenkov (@lemenkov), Dusan Klinec (@ph4r05), Zero King (@l2dy), Andreas Heise, Nick Altmann (@nikbyte), Sergio Gutierrez, okhowang, Konstantin Bokarius, Iouri Kharon, Edson Gellert Schubert, Elena-Ramona Modroiu, Eric Tamme (@etamme). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jul 2006 - Jul 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Jun 2011 - Jul 2024 - - - 3. - Liviu Chircu (@liviuchircu) - Jan 2013 - May 2024 - - - 4. - Ovidiu Sas (@ovidiusas) - Mar 2020 - Apr 2024 - - - 5. - Vlad Paiu (@vladpaiu) - Jun 2011 - Dec 2023 - - - 6. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 8. - okhowang - Mar 2023 - Mar 2023 - - - 9. - Peter Lemenkov (@lemenkov) - Jun 2018 - Sep 2022 - - - 10. - Nick Altmann (@nikbyte) - Feb 2022 - Feb 2022 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Zero King (@l2dy), Dan Pascu (@danpascu), Eric Tamme (@etamme), Ionut Ionita (@ionutrazvanionita), Dusan Klinec (@ph4r05), Andrei Datcu (@andrei-datcu), Alexandr Dubovikov (@adubovikov), Sergio Gutierrez, Daniel-Constantin Mierla (@miconda), Iouri Kharon, Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Andreas Heise, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Liviu Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas), Ionut Ionita (@ionutrazvanionita), Andrei Datcu (@andrei-datcu), Alexandr Dubovikov (@adubovikov), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Elena-Ramona Modroiu. -
- -
diff --git a/modules/tracer/doc/tracer.xml b/modules/tracer/doc/tracer.xml deleted file mode 100644 index 238c88b7f8d..00000000000 --- a/modules/tracer/doc/tracer.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - -%docentities; - -]> - - - - Tracer Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006 &voicesystem; - diff --git a/modules/tracer/doc/tracer_admin.xml b/modules/tracer/doc/tracer_admin.xml deleted file mode 100644 index ea123b29849..00000000000 --- a/modules/tracer/doc/tracer_admin.xml +++ /dev/null @@ -1,671 +0,0 @@ - - - - - &adminguide; - -
- Overview - - Offer a possibility to store incoming/outgoing SIP messages in database. - Since version 2.2, proto_hep module needs to be loaded in order to duplicate - with hep. All hep parameters moved inside proto_hep. - - - The 2.2 version of &osips; came with a major improvement in tracer module. - Now all you have to do is call trace() function - with the proper parameters and it will do the job for you. Now you can trace - messages, transactions and dialogs with the same function. Also, you can trace - to multiple databases, multiple hep destinations and sip destinations using - only one parameter. All you need now is defining trace_id - parameters in modparam section and switch between them in - tracer function. Also you cand turn tracing on - and off using trace_on either globally(for all trace_ids) - or for a certain trace_id. - - - - IMPORTANT: In 2.2 version support for stateless trace has been removed. - - - - The tracing tracing can be turned on/off using fifo command. - - - opensips-cli -x mi trace on - opensips-cli -x mi trace [some_trace_id] on - - - opensips-cli -x mi trace off - opensips-cli -x mi trace [some_trace_id] off - - - - Starting with &osips; 3.0 you can use the trace_start to - create dynamic dynamic tracing destinations based on some custom filters. - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - database module - mysql, postrgress, - dbtext, unixodbc... only if you are using a database type - trace id - - - - - b2b_logic - only if you want to trace - B2B sessions. - - - - - dialog - only if you want to trace - SIP dialogs (INVITE based). - - - - - tm - only if you want to trace - SIP transactions. - - - - - proto_hep - only if you want to - trace / replicate messages over HEP protocol. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>trace_on</varname> (integer) - - Parameter to enable/disable trace (on(1)/off(0)) - - - - Default value is "1"(enabled). - - - - Set <varname>trace_on</varname> parameter - -... -modparam("tracer", "trace_on", 1) -... - - -
- -
- <varname>trace_local_ip</varname> (str) - - The address to be used in the fields that specify the source address - (protocol, ip and port) for locally generated messages. If not set, - the module sets it to the address of the socket that will be used to send - the message. Protocol and/or port are optional and if omitted will take - the default values: udp and 5060. - - - - Default value is "NULL". - - - - Set <varname>trace_local_ip</varname> parameter - -... -#Resulting address: udp:10.1.1.1:5064 -modparam("tracer", "trace_local_ip", "10.1.1.1:5064") -... - -... -#Resulting address: tcp:10.1.1.1:5060 -modparam("tracer, "trace_local_ip", "tcp:10.1.1.1") -... - -... -#Resulting address: tcp:10.1.1.1:5064 -modparam("tracer", "trace_local_ip", "tcp:10.1.1.1:5064") -... - -... -#Resulting address: udp:10.1.1.1:5060 -modparam("tracer", "trace_local_ip", "10.1.1.1") -... - - -
- -
- <varname>trace_id</varname> (str) - - Specify a destination for the trace. This can be a hep id defined - in proto_hep, a sip uri, a file, a syslog facility or a database - url and a table. All parameters inside - trace_id must be separated by - ;, excepting the last one. The parameters - are given in key-value format, the possible keys being - uri for HEP and SIP IDs and - uri and table - for databases. The format is - [id_name]key1=value1;key2=value2;. HEP - id's MUST be defined in proto_hep in order - to be able to use them here. - - - When the uri is a file, the path to the file has - to be specified after the colon. The output is always appended if the file - exists, or created if it doesn't, using - permissions. - - - When the uri is syslog, it has to follow the following - format: syslog[:FACILITY[:LEVEL]]. The default - facility and levels are the ones used by &osips; - (syslog_facility and log_level). - These can be tuned using - and - parameters. - - - One can declare multiple types of tracing under the same trace - id, being identified by their name. So if you define two - database url, one hep uri and one sip uri with the same name, - when calling trace() with this name tracing shall be done - to all the destinations. - - - All the old parameter such as db_url, table and duplicate_uri - will form the trace id with the name "default". - - - - No default value. If not set the module will be useless. - - - - Set <varname>trace_id</varname> parameter - -... -/*DB trace id*/ -modparam("tracer", "trace_id", -"[tid] -uri=mysql://xxxx:xxxx@10.10.10.10/opensips; -table=new_sip_trace;") -/* hep trace id with the hep id defined in proto_hep; check proto_hep docs - * for more information */ -modparam("proto_hep", "hep_id", "[hid]10.10.10.10") -modparam("tracer", "trace_id", "[tid]uri=hep:hid") -/*sip trace id*/ -modparam("tracer", "trace_id", -"[tid]uri=sip:10.10.10.11:5060") -/* notice that they all have the same name - * meaning that calling trace("tid",...) - * will do sql, sip and hep tracing */ -/*file trace id*/ -modparam("tracer", "trace_id", -"[tid]uri=file:/path/to/file") -/*syslog trace id at error (level -1)*/ -modparam("tracer", "trace_id", -"[tid]uri=syslog:local0:-1") -... - - -
-
- <varname>syslog_default_facility</varname> (string) - - When syslog tracing is used, this parameter specifies - the log facility to write traces to. - - - - Default value is the value of syslog_facility. - - - - Set <varname>syslog_default_facility</varname> parameter - -... -modparam("tracer", "syslog_default_facility", "LOG_DAEMON") -... - - -
-
- <varname>syslog_default_level</varname> (integer) - - When syslog tracing is used, this parameter specifies - the level to write traces to. - - - - Default value is the value of log_level. - - - - Set <varname>syslog_default_level</varname> parameter - -... -modparam("tracer", "syslog_default_level", 2) # NOTICE -... - - -
-
- <varname>file_mode</varname> (integer) - - When file tracing is used, this parameter - specifies the permissions to be used to create the trace files. - It follows the UNIX conventions. - - - - Default value is 0600 (rw-------). - - - - Set <varname>file_mode</varname> parameter - -... -modparam("tracer", "file_mode", 0644) -... - - -
- -
- -
- Exported Functions -
- - <function moreinfo="none">trace(trace_id, [scope], [type], [trace_attrs], [flags], [correlation_id])</function> - - This function has replaced the sip_trace() in &osips; 3.0. - - Store or replicate current processed SIP message, transaction / dialog or B2B session. - It is stored in the form prior applying chages made to it. The traced_user_avp - parameter is now an argument to trace() function. Since version 2.2, this function - also catches internally generated replies in stateless mode(sl_send_reply(...)). - - - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE. - - Meaning of the parameters is as follows: - - - trace_id (string) - the name of the trace_id specifying where to do - the tracing. - - - - scope (string, optional) what do you - want to trace: dialog, transaction, B2B session or only the message. - If not specified, will try the topmost trace that can be done: - if dialog module loaded will trace dialogs, else if tm module loaded - will trace transaction and if none of these loaded will trace messages. - - Types can be the following: - - - 'm'/'M' trace messages. Is the only - one you should use in stateless mode. - - - 't'/'T' trace transactions. If tm - module not loaded, it will be in stateless transaction aware - mode meaning that will catch selected requests both in and out - and internally generated replies. - - - 'd'/'D' trace dialog - - - 'b'/'B' trace all the traffic - related to the B2B session to be later created - - - - - type (string, optional) list of types of messages to - be traced by this function; if not set only sip messages shall be traced; - if the parameter is set, but sip is not specified, - sip shall not be traced; - all the parameters from the list shall be separated by '|' - Current possible types to be traced are the following: - - - sip - enable sip messages - tracing; - - - xlog - enable xlog messages - tracing in current scope(dialog, transaction, B2B session - or message); - - - rest - enable rest messages - tracing; - - - - - trace_attrs (string, optional) this parameter - replaces the traced_user_avp from the old version. To avoid duplicating - an entry only for this parameter, whatever you put here(string/pvar) - shall be stored in the trace_attrs column in the sip_trace table. - - - - flags (string,pvar) are some control - flags over the tracing process (how and what to be traced). - - - - C - trace only the SIP caller side; - - - c - trace onlt the SIP callee side; - - - If both C and c flags are missing, tracing of both sides/legs is assumed. - NOTE these flags are supported only by transactional and dialog tracing - - - - correlation_id (string,pvar) a custom - SIP correlation ID to be forced (normally the SIP Call-ID is used) - to correlate this traffic (transaction, dialog) with other traffic. - - - - - - <function>trace()</function> usage - -... -/* see declaration of tid in trace_id section */ - $var(trace_id) = "tid"; - $var(user) = "osip_user@opensips.org"; - -... -/* Example 1: how to trace a dialog sip and xlog */ - if (has_totag()) { - match_dialog(); - } else { - if (is_method("INVITE") { - trace($var(trace_id), "d", "sip|xlog", $var(user)); - } - } -... -/* Example 2: how to trace initial INVITE and BYE, sip and rest */ - if (has_totag()) { - if (is_method("BYE")) { - trace($var(trace_id), "m", "sip|rest", $var(user)); - } - } else { - if (is_method("INVITE")) { - trace($var(trace_id), "m", "sip|rest", $var(user)); - } - } - -... -/* Example 3: trace initial INVITE transaction's only xlog and rest, no sip */ - if (!has_totag()) { - if (is_method("INVITE")) { - trace($var(trace_id), "t", "xlog|rest", $var(user)); - } - } -... -/* Example 4: stateless transaction aware mode!*/ -/* tm module must not be loaded */ - if (is_method("REGISTER")) { - trace($var(trace_id), "t", "xlog|rest", $var(user)); - if (!www_authorize("", "subscriber")) { - /* tracer will also catch the 401 generated by www_challenge() */ - www_challenge("", "auth"); - } - } - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">trace</function> - - - Enable/disable tracing(globally or for a specific trace id) or dump - info about trace ids. This command requires named parameters - (each parameter is ginven in the format param_name=param_value). - - - Name: trace - - - Parameters: - - - - - id (optional) - the name of the tracing instance. - If this parameter is missing the command will - either dump info for all tace ids(and return the global tracing state) - or set the global tracing state. - - - - - mode (optional) - - possible values are: - - - "on" - enable tracing - "off" - disable tracing - - - If the first parameter is missing, the command wil set the global - tracing state, otherwise it will set the state for a specific trace id. - If you turn global trace on but some of the trace ids had tracing set to - off, then they shall not do tracing. If you want to turn the tracing on - for all trace ids you will have to set it separately for each of them. - - - If this parameter is missing but the first is set, the command will - only dump info about that specific trace id. If both parameters are - missing, the command will return the global tracing state and dump - info for each id. - - - - - - MI FIFO Command Format: - - -# Display global tracing mode and all trace destinations: -opensips-cli -x mi trace -# Turn off global tracing: -opensips-cli -x mi trace mode=off -# Turn on tracing for destination id tid2: -opensips-cli -x mi trace id=tid2 mode=on - -
- -
- - <function moreinfo="none">trace_start</function> - - - Creates a dynamic tracing destination based using custom filters. - This function can be used to debug calls for certain destinations - real-time. - - - Dynamic destinations are not restart persistent! - - - Name: trace_start - - - Parameters: - - - - - id - the name of the tracing instance. - - - - - uri - the destination uri for this instance. - - - - - filter (optional) - used to filter the traffic - received by the sender. This parameter should be an array that can - contain multiple filters in the condition=value - format. - Possible values for the condition argument are: - - - caller - filter based on the caller (From username) - callee - filter based on the callee (R-URI username) - ip - filter based on the source IP of the message - - - The condition parameter can consist of multiple different filters. - In order to satisfy the overall condition and send traffic to the desired destination, - all conditions have to be satisfied. - - - If this parameter is missing all traffic is forwarded to the destination. - - - The filter is applied for any incoming request - - - - - scope - the scope to engage the tracing for. - The format received by this parameter is similar to the one - received by the trace() function. - - - - - type - the type of messages you want to receive. - The format received by this parameter is similar to the one - received by the trace() function. - - - - - - MI FIFO Command to start tracing calls from IP 127.0.0.1 to HEP destination 10.0.0.1:9060: - - - opensips-cli -x mi trace_start id=ip_filter uri=hep:10.0.0.1:9060 filter=ip=127.0.0.1 - - - - MI FIFO Command to start tracing calls from user Alice to user Bob: - - - opensips-cli -x mi trace_start id=alice_bob uri=hep:10.0.0.1:9060 filter=caller=Alice filter=caller=Bob - -
- -
- - <function moreinfo="none">trace_stop</function> - - - Stops &osips; from sending traffic to a dynamic trace id created - using the trace_start command. - - - Name: trace_stop - - - Parameters: - - - - - id - the name of the tracing instance to be stopped. - - - - - - MI FIFO Command to stop tracing calls from user Alice to user Bob: - - - opensips-cli -x mi trace_stop alice_bob - -
- - -
- -
- Database setup - - Before running &osips; with tracer, you have to setup the database - tables where the module will store the data. For that, if the - table were not created by the installation script or you choose - to install everything by yourself you can use the tracer-create.sql - SQL script in the database directories in the - opensips/scripts folder as template. - You can also find the complete database documentation on the - project webpage, &osipsdbdocslink;. - -
- -
- Known issues - - ACKs related to a transaction that are leaving &osips; are not - traced since they are handled statelessly using forward_request function. - Fixing it would mean to register a fwdcb callback that would be called - for all the messages but would be used only by ACKs, which would be - highly ineffective. - -
- -
- diff --git a/modules/trie/README b/modules/trie/README deleted file mode 100644 index d4d742914db..00000000000 --- a/modules/trie/README +++ /dev/null @@ -1,335 +0,0 @@ -Trie Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. Introduction - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. trie_table(str) - 1.3.2. no_concurrent_reload (int) - 1.3.3. use_partitions (int) - 1.3.4. db_partitions_url (str) - 1.3.5. db_partitions_table (str) - 1.3.6. extra_prefix_chars (str) - - 1.4. Exported Functions - - 1.4.1. trie_search(number, [flags], - [trie_attrs_pvar], [match_prefix_pvar], - [partition]) - - 1.5. Exported MI Functions - - 1.5.1. trie_reload - 1.5.2. trie_reload_status - 1.5.3. trie_search - 1.5.4. trie_number_delete - 1.5.5. trie_number_upsert - - 1.6. Installation - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set trie_table parameter - 1.2. Set no_concurrent_reload parameter - 1.3. Set use_partitions parameter - 1.4. Set db_partitions_url parameter - 1.5. Set db_partitions_table parameter - 1.6. Set extra_prefix_chars parameter - 1.7. trie_search usage - 1.8. trie_reload_status usage when use_partitions is 0 - -Chapter 1. Admin Guide - -1.1. Overview - -1.1.1. Introduction - - Trie is a module for efficiently caching and lookup of a set of - prefixes ( stored in a trie data structure ) - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - -1.2.2. External Libraries or Applications - - * none. - -1.3. Exported Parameters - -1.3.1. trie_table(str) - - The name of the db table storing prefix rules. - - Default value is “trie_table”. - - Example 1.1. Set trie_table parameter -... -modparam("trie", "trie_table", "my_prefix_table") -... - -1.3.2. no_concurrent_reload (int) - - If enabled, the module will not allow do run multiple - trie_reload MI commands in parallel (with overlapping) Any new - reload will be rejected (and discarded) while an existing - reload is in progress. - - If you have a large routing set (millions of rules/prefixes), - you should consider disabling concurrent reload as they will - exhaust the shared memory (by reloading into memory, in the - same time, multiple instances of routing data). - - Default value is “0 (disabled)”. - - Example 1.2. Set no_concurrent_reload parameter -... -# do not allow parallel reload operations -modparam("trie", "no_concurrent_reload", 1) -... - -1.3.3. use_partitions (int) - - Flag to configure whether to use partitions for tries. If this - flag is set then the db_partitions_url and db_partitions_table - variables become mandatory. - - Default value is “0”. - - Example 1.3. Set use_partitions parameter -... -modparam("trie", "use_partitions", 1) -... - -1.3.4. db_partitions_url (str) - - The url to the database containing partition-specific - information.The use_partitions parameter must be set to 1. - - Default value is “"NULL"”. - - Example 1.4. Set db_partitions_url parameter -... -modparam("trie", "db_partitions_url", "mysql://user:password@localhost/o -pensips_partitions") -... - -1.3.5. db_partitions_table (str) - - The name of the table containing partition definitions. To be - used with use_partitions and db_partitions_url. - - Default value is “trie_partitions”. - - Example 1.5. Set db_partitions_table parameter -... -modparam("trie", "db_partitions_table", "trie_partition_defs") -... - -1.3.6. extra_prefix_chars (str) - - List of ASCII (0-127) characters to be additionally accepted in - the prefixes. By default only '0' - '9' chars (digits) are - accepted. - - Default value is “NULL”. - - Example 1.6. Set extra_prefix_chars parameter -... -modparam("trie", "extra_prefix_chars", "#-%") -... - -1.4. Exported Functions - -1.4.1. trie_search(number, [flags], [trie_attrs_pvar], -[match_prefix_pvar], [partition]) - - Function to search for an entry ( number ) in a trie. - - This function can be used from all routes. - - If you set use_partitions to 1 the partition last parameter - becomes mandatory. - - All parameters are optional. Any of them may be ignored, - provided the necessary separation marks "," are properly - placed. - * number (str) - number to be searched in the trie - * flags (string, optional) - a list of letter-like flags for - controlling the routing behavior. Possible flags are: - + L - Do strict length matching over the prefix - - actually the trie engine will do full number matching - and not prefix matching anymore. - * trie_attrs_pvar (var, optional) - a writable variable which - will be populated with the attributes of the matched trie - rule. - * match_prefix_pvar (var, optional) - a writable variable - which will be the actual prefix matched in the trie. - * partition (string, optional) - the name of the trie - partition to be used. This parameter is to be defined ONLY - if the "use_partition" module parameter is turned on. - - Example 1.7. trie_search usage -... -if (trie_search("$rU","L",$avp(code_attrs),,"my_partition")) { - # we found it in the trie, it's a match - xlog("We found $rU in the trie with attrs $avp(code_attrs) \n"); -} - -1.5. Exported MI Functions - -1.5.1. trie_reload - - Command to reload trie rules from database. - * if use_partition is set to 0 - all routing rules will be - reloaded. - * if use_partition is set to 1, the parameters are: - + partition_name (optional) - if not provided all the - partitions will be reloaded, otherwise just the - partition given as parameter will be reloaded. - - MI FIFO Command Format: - opensips-cli -x mi trie_reload part_1 - -1.5.2. trie_reload_status - - Gets the time of the last reload for any partition. - * if use_partition is set to 0 - the function doesn't receive - any parameter. It will list the date of the last reload for - the default (and only) partition. - * if use_partition is set to 1, the parameters are: - + partition_name (optional) - if not provided the - function will list the time of the last update for - every partition. Otherwise, the function will list the - time of the last reload for the given partition. - - Example 1.8. trie_reload_status usage when use_partitions is 0 -$ opensips-cli -x mi trie_reload_status -Date:: Tue Aug 12 12:26:00 2014 - -1.5.3. trie_search - - Tries to match a number in the existing tries loaded from the - database. - * if use_partition is set to 1 the function will have 2 - parameters: - + partition_name - + number - the number to test against - * if use_partition is set to 0 the function will have 1 - parameter: - + number - the number to test against - - MI FIFO Command Format: - opensips-cli -x mi trie_search partition_name=part1 numb -er=012340987 - -1.5.4. trie_number_delete - - Deletes individual entries in the trie, without reloading all - of the data - * if use_partition is set to 1 the function will have 2 - parameters: - + partition_name - + number - the array of numbers to delete - - MI FIFO Command Format: - opensips-cli -x mi trie_number_delete partition_name=par -t1 number=["012340987","4858345"] - -1.5.5. trie_number_upsert - - Upserts ( insert if not found, update is found ) an array of - numbers in the trie, without reloading all of the data - * if use_partition is set to 1 the function will have 3 - parameters: - + partition_name - + number - the array of numbers to update - + attrs - the array of new attributes for the numbers - - MI FIFO Command Format: - opensips-cli -x mi trie_number_upsert partition_name=par -t1 number=["012340987"] attrs=["my_attrs"] - -1.6. Installation - - The module requires some tables in the OpenSIPS database. You - can also find the complete database documentation on the - project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Paiu (@vladpaiu) 28 4 2652 4 - 2. Razvan Crainea (@razvancrainea) 4 2 2 2 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Vlad Paiu (@vladpaiu) Dec 2024 - May 2025 - 2. Razvan Crainea (@razvancrainea) Jan 2025 - Jan 2025 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Paiu (@vladpaiu). - - Documentation Copyrights: - - Copyright © 2024 OpenSIPS Project diff --git a/modules/trie/README.md b/modules/trie/README.md new file mode 100644 index 00000000000..509af9e4c1f --- /dev/null +++ b/modules/trie/README.md @@ -0,0 +1,314 @@ +--- +title: "Trie Module" +--- + +## Admin Guide + + +### Overview + + +#### Introduction + + +Trie is a module for efficiently caching and lookup of a set of prefixes ( stored in a trie data structure ) + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. + + +#### External Libraries or Applications + + +- *none*. + + +### Exported Parameters + + +#### trie_table(str) + + +The name of the db table storing prefix rules. + + +*Default value is "trie_table".* + + +```opensips title="Set trie_table parameter" +... +modparam("trie", "trie_table", "my_prefix_table") +... +``` + + +#### no_concurrent_reload (int) + + +If enabled, the module will not allow do run multiple trie_reload +MI commands in parallel (with overlapping) Any new reload will +be rejected (and discarded) while an existing reload is in +progress. + + +If you have a large routing set (millions of rules/prefixes), you +should consider disabling concurrent reload as they will exhaust +the shared memory (by reloading into memory, in the same time, +multiple instances of routing data). + + +*Default value is "0 (disabled)".* + + +```opensips title="Set no_concurrent_reload parameter" +... +# do not allow parallel reload operations +modparam("trie", "no_concurrent_reload", 1) +... +``` + + +#### use_partitions (int) + + +Flag to configure whether to use partitions for tries. If this +flag is set then the `db_partitions_url` and +`db_partitions_table` +variables become mandatory. + + +*Default value is "0".* + + +```opensips title="Set use_partitions parameter" +... +modparam("trie", "use_partitions", 1) +... +``` + + +#### db_partitions_url (str) + + +The url to the database containing partition-specific +information.The `use_partitions` parameter +must be set to 1. + + +*Default value is ""NULL"".* + + +```opensips title="Set db_partitions_url parameter" +... +modparam("trie", "db_partitions_url", "mysql://user:password@localhost/opensips_partitions") +... +``` + + +#### db_partitions_table (str) + + +The name of the table containing partition definitions. To be +used with `use_partitions` and `db_partitions_url`. + + +*Default value is "trie_partitions".* + + +```opensips title="Set db_partitions_table parameter" +... +modparam("trie", "db_partitions_table", "trie_partition_defs") +... +``` + + +#### extra_prefix_chars (str) + + +List of ASCII (0-127) characters to be additionally accepted in +the prefixes. By default only '0' - '9' chars (digits) are +accepted. + + +*Default value is "NULL".* + + +```opensips title="Set extra_prefix_chars parameter" +... +modparam("trie", "extra_prefix_chars", "#-%") +... +``` + + +### Exported Functions + + +#### trie_search(number, [flags], [trie_attrs_pvar], [match_prefix_pvar], [partition]) + + +Function to search for an entry ( number ) in a trie. + + +This function can be used from all routes. + + +If you set `use_partitions` to 1 the +**partition** last parameter becomes +mandatory. + + +All parameters are optional. Any of them may be ignored, provided +the necessary separation marks "," are properly placed. + + +- **number** (str) - number to be searched in the trie +- **flags** (string, optional) - a list +of letter-like flags for controlling the routing behavior. +Possible flags are: + + - **L** - Do strict length matching +over the prefix - actually the trie engine will do full number +matching and not prefix matching anymore. +- **trie_attrs_pvar** (var, optional) - a +writable variable which will be populated with the attributes of the +matched trie rule. +- **match_prefix_pvar** (var, optional) - a +writable variable which will be the actual prefix matched in the trie. +- **partition** (string, optional) - the name +of the trie partition to be used. This parameter is to be defined +ONLY if the "use_partition" module parameter is turned on. + + +```opensips title="trie_search usage" +... +if (trie_search("$rU","L",$avp(code_attrs),,"my_partition")) { + # we found it in the trie, it's a match + xlog("We found $rU in the trie with attrs $avp(code_attrs) \n"); +} +``` + + +### Exported MI Functions + + +#### trie_reload + + +Command to reload trie rules from database. + + +- if `use_partition` is set to 0 - all routing rules will be reloaded. +- if `use_partition` is set to 1, the parameters are: + - *partition_name* (optional) - if not provided + all the partitions will be reloaded, otherwise just the partition given as parameter will be reloaded. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi trie_reload part_1 +``` + + +#### trie_reload_status + + +Gets the time of the last reload for any partition. + + +- if `use_partition` is set to 0 - the function +doesn't receive any parameter. It will list the date of the +last reload for the default (and only) partition. +- if `use_partition` is set to 1, the parameters are: + - *partition_name* (optional) - if not provided + the function will list the time of the last update for every + partition. Otherwise, the function will list the time of the last + reload for the given partition. + + +```bash title="trie_reload_status usage when use_partitions is 0" +$ opensips-cli -x mi trie_reload_status +Date:: Tue Aug 12 12:26:00 2014 +``` + + +#### trie_search + + +Tries to match a number in the existing tries loaded from the database. + + +- if `use_partition` is set to 1 the function +will have 2 parameters: + - *partition_name* + - *number* - the number to test against +- if `use_partition` is set to 0 the function will have 1 parameter: + - *number* - the number to test against + +MI FIFO Command Format: + +```bash +opensips-cli -x mi trie_search partition_name=part1 number=012340987 +``` + + +#### trie_number_delete + + +Deletes individual entries in the trie, without reloading all of the data + + +- if `use_partition` is set to 1 the function +will have 2 parameters: + - *partition_name* + - *number* - the array of numbers to delete + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi trie_number_delete partition_name=part1 number=["012340987","4858345"] +``` + + +#### trie_number_upsert + + +Upserts ( insert if not found, update is found ) an array of numbers in the trie, without reloading all of the data + + +- if `use_partition` is set to 1 the function +will have 3 parameters: + - *partition_name* + - *number* - the array of numbers to update + - *attrs* - the array of new attributes for the numbers + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi trie_number_upsert partition_name=part1 number=["012340987"] attrs=["my_attrs"] +``` + + +### Installation + + +The module requires some tables in the OpenSIPS database. +You can also find the complete database documentation on the project webpage, [https://opensips.org/docs/db/db-schema-devel.html](https://opensips.org/docs/db/db-schema-devel.html). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/trie/doc/contributors.xml b/modules/trie/doc/contributors.xml deleted file mode 100644 index 5ebffbc6200..00000000000 --- a/modules/trie/doc/contributors.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Paiu (@vladpaiu) - 28 - 4 - 2652 - 4 - - - 2. - Razvan Crainea (@razvancrainea) - 4 - 2 - 2 - 2 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Vlad Paiu (@vladpaiu) - Dec 2024 - May 2025 - - - 2. - Razvan Crainea (@razvancrainea) - Jan 2025 - Jan 2025 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Paiu (@vladpaiu). -
- -
diff --git a/modules/trie/doc/trie.xml b/modules/trie/doc/trie.xml deleted file mode 100644 index 613c69ee2a4..00000000000 --- a/modules/trie/doc/trie.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -%docentities; - -]> - - - - Trie Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2024 OpenSIPS Project - - - diff --git a/modules/trie/doc/trie_admin.xml b/modules/trie/doc/trie_admin.xml deleted file mode 100644 index e2a4f1d76f8..00000000000 --- a/modules/trie/doc/trie_admin.xml +++ /dev/null @@ -1,453 +0,0 @@ - - - - &adminguide; - -
- Overview -
- Introduction - - Trie is a module for efficiently caching and lookup of a set of prefixes ( stored in a trie data structure ) - -
- -
- - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - - a database module. - - - - -
- -
- External Libraries or Applications - - - - none. - - - - -
-
- -
- Exported Parameters -
- <varname>trie_table</varname>(str) - - The name of the db table storing prefix rules. - - - Default value is trie_table. - - - - Set <varname>trie_table</varname> parameter - -... -modparam("trie", "trie_table", "my_prefix_table") -... - - -
- -
- <varname>no_concurrent_reload</varname> (int) - - If enabled, the module will not allow do run multiple trie_reload - MI commands in parallel (with overlapping) Any new reload will - be rejected (and discarded) while an existing reload is in - progress. - - - If you have a large routing set (millions of rules/prefixes), you - should consider disabling concurrent reload as they will exhaust - the shared memory (by reloading into memory, in the same time, - multiple instances of routing data). - - - Default value is 0 (disabled). - - - - Set <varname>no_concurrent_reload</varname> parameter - -... -# do not allow parallel reload operations -modparam("trie", "no_concurrent_reload", 1) -... - - -
- -
- <varname>use_partitions</varname> (int) - - Flag to configure whether to use partitions for tries. If this - flag is set then the db_partitions_url and - db_partitions_table - variables become mandatory. - - - Default value is 0. - - - - Set <varname>use_partitions</varname> parameter - -... -modparam("trie", "use_partitions", 1) -... - - -
- -
- <varname>db_partitions_url</varname> (str) - - The url to the database containing partition-specific - information.The use_partitions parameter - must be set to 1. - - - Default value is "NULL". - - - - Set <varname>db_partitions_url</varname> parameter - -... -modparam("trie", "db_partitions_url", "mysql://user:password@localhost/opensips_partitions") -... - - -
- -
- <varname>db_partitions_table</varname> (str) - - The name of the table containing partition definitions. To be - used with use_partitions and db_partitions_url. - - - Default value is trie_partitions. - - - - Set <varname>db_partitions_table</varname> parameter - -... -modparam("trie", "db_partitions_table", "trie_partition_defs") -... - - -
- -
- <varname>extra_prefix_chars</varname> (str) - - List of ASCII (0-127) characters to be additionally accepted in - the prefixes. By default only '0' - '9' chars (digits) are - accepted. - - - Default value is NULL. - - - - Set <varname>extra_prefix_chars</varname> parameter - -... -modparam("trie", "extra_prefix_chars", "#-%") -... - - -
-
- -
- Exported Functions - -
- - -
- Exported MI Functions -
- - <function moreinfo="none">trie_reload</function> - - - Command to reload trie rules from database. - - - - - if use_partition is set to 0 - all routing rules will be reloaded. - - - - - - if use_partition is set to 1, the parameters are: - - - partition_name (optional) - if not provided - all the partitions will be reloaded, otherwise just the partition given as parameter will be reloaded. - - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi trie_reload part_1 - -
- -
- <varname>trie_reload_status</varname> - - Gets the time of the last reload for any partition. - - - - - if use_partition is set to 0 - the function - doesn't receive any parameter. It will list the date of the - last reload for the default (and only) partition. - - - - - if use_partition is set to 1, the parameters are: - - - partition_name (optional) - if not provided - the function will list the time of the last update for every - partition. Otherwise, the function will list the time of the last - reload for the given partition. - - - - - - - <function>trie_reload_status</function> usage when <varname>use_partitions</varname> is 0 - -$ opensips-cli -x mi trie_reload_status -Date:: Tue Aug 12 12:26:00 2014 - - -
- -
- <varname>trie_search</varname> - - Tries to match a number in the existing tries loaded from the database. - - - - - if use_partition is set to 1 the function - will have 2 parameters: - - - partition_name - - - number - the number to test against - - - - - - - if use_partition is set to 0 the function will have 1 parameter: - - - number - the number to test against - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi trie_search partition_name=part1 number=012340987 - -
- -
- - <function moreinfo="none">trie_number_delete</function> - - - Deletes individual entries in the trie, without reloading all of the data - - - - - - if use_partition is set to 1 the function - will have 2 parameters: - - - partition_name - - - number - the array of numbers to delete - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi trie_number_delete partition_name=part1 number=["012340987","4858345"] - -
- -
- - <function moreinfo="none">trie_number_upsert</function> - - - Upserts ( insert if not found, update is found ) an array of numbers in the trie, without reloading all of the data - - - - - - if use_partition is set to 1 the function - will have 3 parameters: - - - partition_name - - - number - the array of numbers to update - - - attrs - the array of new attributes for the numbers - - - - - - - MI FIFO Command Format: - - - opensips-cli -x mi trie_number_upsert partition_name=part1 number=["012340987"] attrs=["my_attrs"] - -
- -
- - -
- Installation - - The module requires some tables in the OpenSIPS database. - You can also find the complete database documentation on the project webpage, &osipsdbdocslink;. - -
- -
diff --git a/modules/trie/trie_db_def.c b/modules/trie/trie_db_def.c index 13a26351505..ba4a528cdea 100644 --- a/modules/trie/trie_db_def.c +++ b/modules/trie/trie_db_def.c @@ -30,7 +30,7 @@ #define ATTRS_TRIE_COL "attrs" #define DISABLED_TRIE_COL "enabled" -str trie_table = str_init("trie"); +str trie_table = str_init("trie_table"); str prefix_trie_col = str_init(PREFIX_TRIE_COL); str attrs_trie_col = str_init(ATTRS_TRIE_COL); str enabled_trie_col = str_init(DISABLED_TRIE_COL); diff --git a/modules/uac/README b/modules/uac/README deleted file mode 100644 index f4ff4b49c77..00000000000 --- a/modules/uac/README +++ /dev/null @@ -1,395 +0,0 @@ -UAC Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. restore_mode (string) - 1.3.2. restore_passwd (string) - 1.3.3. rr_from_store_param (string) - 1.3.4. rr_to_store_param (string) - 1.3.5. force_dialog (int) - - 1.4. Exported Functions - - 1.4.1. uac_replace_from([display],uri) - uac_replace_to([display],uri) - - 1.4.2. uac_restore_from() uac_restore_to() - 1.4.3. uac_auth() - 1.4.4. uac_inc_cseq() - - 2. Frequently Asked Questions - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set restore_mode parameter - 1.2. Set restore_passwd parameter - 1.3. Set rr_from_store_param parameter - 1.4. Set rr_to_store_param parameter - 1.5. Set force_dialog parameter - 1.6. uac_replace_from/uac_replace_to usage - 1.7. uac_restore_from/uac_restore_to usage - 1.8. uac_auth usage - 1.9. uac_inc_cseq usage - -Chapter 1. Admin Guide - -1.1. Overview - - UAC (User Agent Client) module provides some basic UAC - functionalities like FROM / TO header manipulation - (anonymization) or client authentication. - - If the dialog module is loaded and a dialog can be created, - then the auto mode can be done more efficiently. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction Module. - * RR - Record-Route Module, but only if restore mode for FROM - URI is set to “auto”. - * UAC_AUTH - UAC Authentication Module. - * Dialog Module, if “force_dialog” module parameter is - enabled, or a dialog is created from the configuration - script. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. restore_mode (string) - - There are 3 mode of restoring the original headers (FROM/TO) - URI: - * “none” - no information about original URI is stored; - restoration is not possible. - * “manual” - all following replies will be restored, except - for the sequential requests - these must be manually - updated based on original URI. - * “auto” - all sequential requests and replies will be - automatically updated based on stored original URI. - - This parameter is optional, it's default value being “auto”. - - Example 1.1. Set restore_mode parameter -... -modparam("uac","restore_mode","auto") -... - -1.3.2. restore_passwd (string) - - String password to be used to encrypt the RR storing parameter - (when replacing the TO/FROM headers). If empty, no encryption - will be used. - - Default value of this parameter is empty. - - Example 1.2. Set restore_passwd parameter -... -modparam("uac","restore_passwd","my_secret_passwd") -... - -1.3.3. rr_from_store_param (string) - - Name of Record-Route header parameter that will be used to - store (encoded) the original FROM URI. - - This parameter is optional, it's default value being “vsf”. - - Example 1.3. Set rr_from_store_param parameter -... -modparam("uac","rr_from_store_param","my_Fparam") -... - -1.3.4. rr_to_store_param (string) - - Name of Record-Route header parameter that will be used to - store (encoded) the original TO URI. - - This parameter is optional, it's default value being “vst”. - - Example 1.4. Set rr_to_store_param parameter -... -modparam("uac","rr_to_store_param","my_Tparam") -... - -1.3.5. force_dialog (int) - - Force create dialog if it is not created from the configuration - script. - - Default value is no. - - Example 1.5. Set force_dialog parameter -... -modparam("uac", "force_dialog", yes) -... - -1.4. Exported Functions - -1.4.1. uac_replace_from([display],uri) uac_replace_to([display],uri) - - Replace in FROM/TO header the display name or/and the URI part. - - Both parameters are string. The display is optional. If - missing, only the URI will be changed in the message. - - IMPORTANT: calling the function more than once per branch will - lead to inconsistent changes over the request.Be sure you do - the change only ONCE per branch. Note that calling the function - from REQUEST ROUTE affects all the branches!, so no other - change will be possible in the future. For per branch changes - use BRANCH and FAILURE route. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.6. uac_replace_from/uac_replace_to usage -... -# replace both display and uri -uac_replace_from($avp(display),$avp(uri)); -# replace only display and do not touch uri -uac_replace_from("batman",""); -# remove display and replace uri -uac_replace_from("","sip:robin@gotham.org"); -# remove display and do not touch uri -uac_replace_from("",""); -# replace the URI without touching the display -uac_replace_from( , "sip:batman@gotham.org"); -... - -1.4.2. uac_restore_from() uac_restore_to() - - This function will check if the FROM/TO URI was modified and - will use the information stored in header parameter to restore - the original FROM/TO URI value. - - NOTE - this function should be used only if you configured - MANUAL restoring of the headers (see restore_mode param). For - AUTO and NONE, there is no need to use this function. - - This function can be used from REQUEST_ROUTE. - - Example 1.7. uac_restore_from/uac_restore_to usage -... -uac_restore_from(); -... - -1.4.3. uac_auth() - - This function can be called only from failure route and will - build the authentication response header and insert it into the - request without sending anything. Credentials for buiding the - authentication response will be taken from the list of - credentials provided by the uac_auth module (static or via - AVPs). - - As optional parameter, the function may receive a list of auth - algorithms to be considered / supported during authentication: - * MD5, MD5-sess - * SHA-256, SHA-256-sess (may be missing, depends on lib - support) - * SHA-512-256, SHA-512-256-sess (may be missing, depends on - lib support) - - Note that the CSeq is automatically increased during - authentication. - - This function can be used from FAILURE_ROUTE. - - NOTE: when used without dialog support, the uac_auth() function - cannot be used for authenticating in-dialog requests, as there - is no mechanism to store the CSeq changes that are required for - ensuring the correctness of the dialog. The only exception are - BYE messages, which are the last messages within a call, hence - no further adjustments are needed. The function can still be - used for authenticating the initial INVITE though. - - Example 1.8. uac_auth usage -... -uac_auth(); -... -failure_route[check_auth] { - ... - if ($T_reply_code==407) { - if (uac_auth("MD5,MD5-sess")) { - # auth is succesful, just relay - t_relay(); - exit; - } - # auth failed (no credentials maybe) - # so continue handling the 407 reply - } - ... -} -... - -1.4.4. uac_inc_cseq() - - This function can be called to increase the CSeq of an ongoing - request. - - It receives as the cseq parameter the value that the CSeq - should be incremented with. - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - Example 1.9. uac_inc_cseq usage -... -uac_inc_cseq(1); -... - -Chapter 2. Frequently Asked Questions - - 2.1. - - What happened with auth_username_avp, auth_realm_avp and - auth_password_avp parameters - - Due some restructuring of the UAC auth modules, these - parameters were moved into the "uac_auth" module. This module - is now responsible for handling all the credentials (static - defined or dynamically defined via AVPs). The UAC module will - still see the credentials defined via the AVPs. - $ - - 2.2. - - Where can I find more about OpenSIPS? - - Take a look at https://opensips.org/. - - 2.3. - - Where can I post a question about this module? - - First at all check if your question was already answered on one - of our mailing lists: - * User Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/users - * Developer Mailing List - - http://lists.opensips.org/cgi-bin/mailman/listinfo/devel - - E-mails regarding any stable OpenSIPS release should be sent to - and e-mails regarding development - versions should be sent to . - - If you want to keep the mail private, send it to - . - - 2.4. - - How can I report a bug? - - Please follow the guidelines provided at: - https://github.com/OpenSIPS/opensips/issues. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 129 75 4208 1076 - 2. Ovidiu Sas (@ovidiusas) 35 8 403 1351 - 3. Razvan Crainea (@razvancrainea) 32 24 560 148 - 4. Liviu Chircu (@liviuchircu) 27 19 305 298 - 5. Daniel-Constantin Mierla (@miconda) 15 11 138 88 - 6. Vlad Patrascu (@rvlad-patrascu) 10 5 150 175 - 7. Maksym Sobolyev (@sobomax) 10 3 168 294 - 8. Vlad Paiu (@vladpaiu) 9 5 243 18 - 9. Andreas Heise 7 3 105 129 - 10. Edson Gellert Schubert 5 1 0 201 - - All remaining contributors: Elena-Ramona Modroiu, Henning - Westerholt (@henningw), Konstantin Bokarius, Peter Lemenkov - (@lemenkov), Dan Pascu (@danpascu), Dusan Klinec (@ph4r05), - Jesus Rodrigues, Sergio Gutierrez. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - Oct 2024 - 2. Razvan Crainea (@razvancrainea) Aug 2010 - Aug 2023 - 3. Ovidiu Sas (@ovidiusas) Mar 2011 - Jun 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2005 - Apr 2023 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Mar 2023 - 6. Maksym Sobolyev (@sobomax) Mar 2021 - Feb 2023 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Dusan Klinec (@ph4r05) Dec 2015 - Dec 2015 - 9. Vlad Paiu (@vladpaiu) Aug 2011 - Sep 2015 - 10. Sergio Gutierrez Nov 2008 - Nov 2008 - - All remaining contributors: Dan Pascu (@danpascu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Jesus - Rodrigues, Andreas Heise, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei - Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ovidiu Sas - (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona - Modroiu. - - Documentation Copyrights: - - Copyright © 2005-2009 Voice Sistem SRL diff --git a/modules/uac/README.md b/modules/uac/README.md new file mode 100644 index 00000000000..4304960f719 --- /dev/null +++ b/modules/uac/README.md @@ -0,0 +1,335 @@ +--- +title: "UAC Module" +description: "UAC (User Agent Client) module provides some basic UAC functionalities like FROM / TO header manipulation (anonymization) or client authentication." +--- + +## Admin Guide + + +### Overview + + +UAC (User Agent Client) module provides some basic UAC +functionalities like FROM / TO header manipulation (anonymization) +or client authentication. + + +If the dialog module is loaded and a dialog can be created, +then the auto mode can be done more efficiently. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM - Transaction Module*. +- *RR - Record-Route Module*, but only if +restore mode for FROM URI is set to "auto". +- *UAC_AUTH - UAC Authentication Module*. +- *Dialog Module*, if "force_dialog" +module parameter is enabled, or a dialog is created from the +configuration script. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### restore_mode (string) + + +There are 3 mode of restoring the original headers (FROM/TO) URI: + + +- "none" - no information about original URI is +stored; restoration is not possible. +- "manual" - all following replies will be restored, +except for the sequential requests - these must be manually +updated based on original URI. +- "auto" - all sequential requests and replies will +be automatically updated based on stored original URI. + + +*This parameter is optional, it's default value being +"auto".* + + +```opensips title="Set restore_mode parameter" +... +modparam("uac","restore_mode","auto") +... +``` + + +#### restore_passwd (string) + + +String password to be used to encrypt the RR storing parameter +(when replacing the TO/FROM headers). If empty, no encryption +will be used. + + +*Default value of this parameter is empty.* + + +```opensips title="Set restore_passwd parameter" +... +modparam("uac","restore_passwd","my_secret_passwd") +... +``` + + +#### rr_from_store_param (string) + + +Name of Record-Route header parameter that will be used to store +(encoded) the original FROM URI. + + +*This parameter is optional, it's default value being +"vsf".* + + +```opensips title="Set rr_from_store_param parameter" +... +modparam("uac","rr_from_store_param","my_Fparam") +... +``` + + +#### rr_to_store_param (string) + + +Name of Record-Route header parameter that will be used to store +(encoded) the original TO URI. + + +*This parameter is optional, it's default value being +"vst".* + + +```opensips title="Set rr_to_store_param parameter" +... +modparam("uac","rr_to_store_param","my_Tparam") +... +``` + + +#### force_dialog (int) + + +Force create dialog if it is not created from the configuration script. + + +Default value is no. + + +```opensips title="Set force_dialog parameter" +... +modparam("uac", "force_dialog", yes) +... +``` + + +### Exported Functions + + +#### uac_replace_from([display],uri) uac_replace_to([display],uri) + + +Replace in FROM/TO header the *display* name or/and +the *URI* part. + + +Both parameters are string. The *display* is optional. +If missing, only the URI will be changed in the message. + + +> [!IMPORTANT] +> Calling the function more than once per branch will lead +> to inconsistent changes over the request.Be sure you do the change +> only ONCE per branch. Note that calling the function from REQUEST +> ROUTE affects all the branches!, so no other change will be +> possible in the future. For per branch changes use BRANCH and +> FAILURE route. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and +FAILURE_ROUTE. + + +```opensips title="uac_replace_from/uac_replace_to usage" +... +# replace both display and uri +uac_replace_from($avp(display),$avp(uri)); +# replace only display and do not touch uri +uac_replace_from("batman",""); +# remove display and replace uri +uac_replace_from("","sip:robin@gotham.org"); +# remove display and do not touch uri +uac_replace_from("",""); +# replace the URI without touching the display +uac_replace_from( , "sip:batman@gotham.org"); +... + +``` + + +#### uac_restore_from() uac_restore_to() + + +This function will check if the FROM/TO URI was modified and will +use the information stored in header parameter to restore +the original FROM/TO URI value. + + +> [!NOTE] +> This function should be used only if you configured MANUAL +> restoring of the headers (see restore_mode param). For AUTO +> and NONE, there is no need to use this function. + + +This function can be used from REQUEST_ROUTE. + + +```opensips title="uac_restore_from/uac_restore_to usage" +... +uac_restore_from(); +... +``` + + +#### uac_auth() + + +This function can be called only from failure route and will +build the authentication response header and insert it into the +request without sending anything. +Credentials for buiding the authentication response will be taken +from the list of credentials provided by the uac_auth module (static +or via AVPs). + + +As optional parameter, the function may receive a list of auth +algorithms to be considered / supported during authentication: + + +- MD5, MD5-sess +- SHA-256, SHA-256-sess (may be missing, depends on lib support) +- SHA-512-256, SHA-512-256-sess (may be missing, depends on lib support) + + +> [!NOTE] +> The CSeq is automatically increased during authentication. + + +This function can be used from FAILURE_ROUTE. + + +> [!NOTE] +> When used without dialog support, the +> *uac_auth()* function cannot be used for authenticating +> in-dialog requests, as there is no mechanism to store the CSeq changes that +> are required for ensuring the correctness of the dialog. The only exception are +> *BYE* messages, which are the last messages within a call, +> hence no further adjustments are needed. The function can still be used for +> authenticating the initial INVITE though. + + +```opensips title="uac_auth usage" +... +uac_auth(); +... +failure_route[check_auth] { + ... + if ($T_reply_code==407) { + if (uac_auth("MD5,MD5-sess")) { + # auth is succesful, just relay + t_relay(); + exit; + } + # auth failed (no credentials maybe) + # so continue handling the 407 reply + } + ... +} +... + +``` + + +#### uac_inc_cseq() + + +This function can be called to increase the CSeq of an ongoing request. + + +It receives as the *cseq* parameter the value that +the CSeq should be incremented with. + + +This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. + + +```opensips title="uac_inc_cseq usage" +... +uac_inc_cseq(1); +... +``` + + +## Frequently Asked Questions + + +**Q: What happened with auth_username_avp, auth_realm_avp and auth_password_avp parameters** + + +Due some restructuring of the UAC auth modules, these parameters were moved into the "uac_auth" module. +This module is now responsible for handling all the credentials (static defined or dynamically defined +via AVPs). The UAC module will still see the credentials defined via the AVPs. + + +**Q: Where can I find more about OpenSIPS?** + + +Take a look at [https://opensips.org/](https://opensips.org/). + + +**Q: Where can I post a question about this module?** + + +First at all check if your question was already answered on one of +our mailing lists: + +E-mails regarding any stable OpenSIPS release should be sent to +users@lists.opensips.org and e-mails regarding development versions +should be sent to devel@lists.opensips.org. + +If you want to keep the mail private, send it to +users@lists.opensips.org. + + +**Q: How can I report a bug?** + + +Please follow the guidelines provided at: +[https://github.com/OpenSIPS/opensips/issues](https://github.com/OpenSIPS/opensips/issues). + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/uac/doc/contributors.xml b/modules/uac/doc/contributors.xml deleted file mode 100644 index d9a945d059d..00000000000 --- a/modules/uac/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 129 - 75 - 4208 - 1076 - - - 2. - Ovidiu Sas (@ovidiusas) - 35 - 8 - 403 - 1351 - - - 3. - Razvan Crainea (@razvancrainea) - 32 - 24 - 560 - 148 - - - 4. - Liviu Chircu (@liviuchircu) - 27 - 19 - 305 - 298 - - - 5. - Daniel-Constantin Mierla (@miconda) - 15 - 11 - 138 - 88 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 10 - 5 - 150 - 175 - - - 7. - Maksym Sobolyev (@sobomax) - 10 - 3 - 168 - 294 - - - 8. - Vlad Paiu (@vladpaiu) - 9 - 5 - 243 - 18 - - - 9. - Andreas Heise - 7 - 3 - 105 - 129 - - - 10. - Edson Gellert Schubert - 5 - 1 - 0 - 201 - - - -
-All remaining contributors: Elena-Ramona Modroiu, Henning Westerholt (@henningw), Konstantin Bokarius, Peter Lemenkov (@lemenkov), Dan Pascu (@danpascu), Dusan Klinec (@ph4r05), Jesus Rodrigues, Sergio Gutierrez. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - Oct 2024 - - - 2. - Razvan Crainea (@razvancrainea) - Aug 2010 - Aug 2023 - - - 3. - Ovidiu Sas (@ovidiusas) - Mar 2011 - Jun 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2005 - Apr 2023 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Mar 2023 - - - 6. - Maksym Sobolyev (@sobomax) - Mar 2021 - Feb 2023 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Dusan Klinec (@ph4r05) - Dec 2015 - Dec 2015 - - - 9. - Vlad Paiu (@vladpaiu) - Aug 2011 - Sep 2015 - - - 10. - Sergio Gutierrez - Nov 2008 - Nov 2008 - - - -
-All remaining contributors: Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Jesus Rodrigues, Andreas Heise, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Ovidiu Sas (@ovidiusas), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Jesus Rodrigues, Elena-Ramona Modroiu. -
- -
diff --git a/modules/uac/doc/uac.xml b/modules/uac/doc/uac.xml deleted file mode 100644 index e6c748d169d..00000000000 --- a/modules/uac/doc/uac.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - UAC Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005-2009 &voicesystem; - - diff --git a/modules/uac/doc/uac_admin.xml b/modules/uac/doc/uac_admin.xml deleted file mode 100644 index 4edd382b5b1..00000000000 --- a/modules/uac/doc/uac_admin.xml +++ /dev/null @@ -1,369 +0,0 @@ - - - - - &adminguide; - - -
- Overview - - UAC (User Agent Client) module provides some basic UAC - functionalities like FROM / TO header manipulation (anonymization) - or client authentication. - - - If the dialog module is loaded and a dialog can be created, - then the auto mode can be done more efficiently. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction Module. - - - - - RR - Record-Route Module, but only if - restore mode for FROM URI is set to auto. - - - - - UAC_AUTH - UAC Authentication Module. - - - - - Dialog Module, if force_dialog - module parameter is enabled, or a dialog is created from the - configuration script. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters - -
- <varname>restore_mode</varname> (string) - - There are 3 mode of restoring the original headers (FROM/TO) URI: - - - - none - no information about original URI is - stored; restoration is not possible. - - - - - manual - all following replies will be restored, - except for the sequential requests - these must be manually - updated based on original URI. - - - - - auto - all sequential requests and replies will - be automatically updated based on stored original URI. - - - - - - - This parameter is optional, it's default value being - auto. - - - - Set <varname>restore_mode</varname> parameter - - -... -modparam("uac","restore_mode","auto") -... - - -
- -
- <varname>restore_passwd</varname> (string) - - String password to be used to encrypt the RR storing parameter - (when replacing the TO/FROM headers). If empty, no encryption - will be used. - - - - Default value of this parameter is empty. - - - - Set <varname>restore_passwd</varname> parameter - -... -modparam("uac","restore_passwd","my_secret_passwd") -... - - -
- -
- <varname>rr_from_store_param</varname> (string) - - Name of Record-Route header parameter that will be used to store - (encoded) the original FROM URI. - - - - This parameter is optional, it's default value being - vsf. - - - - Set <varname>rr_from_store_param</varname> parameter - -... -modparam("uac","rr_from_store_param","my_Fparam") -... - - -
- -
- <varname>rr_to_store_param</varname> (string) - - Name of Record-Route header parameter that will be used to store - (encoded) the original TO URI. - - - - This parameter is optional, it's default value being - vst. - - - - Set <varname>rr_to_store_param</varname> parameter - -... -modparam("uac","rr_to_store_param","my_Tparam") -... - - -
- -
- <varname>force_dialog</varname> (int) - - Force create dialog if it is not created from the configuration script. - - - Default value is no. - - - Set <varname>force_dialog</varname> parameter - -... -modparam("uac", "force_dialog", yes) -... - - -
-
- - -
- Exported Functions - -
- - <function moreinfo="none">uac_replace_from([display],uri)</function> - <function moreinfo="none">uac_replace_to([display],uri)</function> - - - Replace in FROM/TO header the display name or/and - the URI part. - - - Both parameters are string. The display is optional. - If missing, only the URI will be changed in the message. - - - IMPORTANT: calling the function more than once per branch will lead - to inconsistent changes over the request.Be sure you do the change - only ONCE per branch. Note that calling the function from REQUEST - ROUTE affects all the branches!, so no other change will be - possible in the future. For per branch changes use BRANCH and - FAILURE route. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and - FAILURE_ROUTE. - - - <function>uac_replace_from</function>/<function>uac_replace_to</function> usage - -... -# replace both display and uri -uac_replace_from($avp(display),$avp(uri)); -# replace only display and do not touch uri -uac_replace_from("batman",""); -# remove display and replace uri -uac_replace_from("","sip:robin@gotham.org"); -# remove display and do not touch uri -uac_replace_from("",""); -# replace the URI without touching the display -uac_replace_from( , "sip:batman@gotham.org"); -... - - -
- -
- - <function moreinfo="none">uac_restore_from()</function> - <function moreinfo="none">uac_restore_to()</function> - - - This function will check if the FROM/TO URI was modified and will - use the information stored in header parameter to restore - the original FROM/TO URI value. - - - NOTE - this function should be used only if you configured MANUAL - restoring of the headers (see restore_mode param). For AUTO - and NONE, there is no need to use this function. - - - This function can be used from REQUEST_ROUTE. - - - <function>uac_restore_from</function>/<function>uac_restore_to</function> usage - -... -uac_restore_from(); -... - - -
- -
- - <function moreinfo="none">uac_auth()</function> - - - This function can be called only from failure route and will - build the authentication response header and insert it into the - request without sending anything. - Credentials for buiding the authentication response will be taken - from the list of credentials provided by the uac_auth module (static - or via AVPs). - - - As optional parameter, the function may receive a list of auth - algorithms to be considered / supported during authentication: - - - - MD5, MD5-sess - - - SHA-256, SHA-256-sess (may be missing, depends on lib support) - - - SHA-512-256, SHA-512-256-sess (may be missing, depends on lib support) - - - - Note that the CSeq is automatically increased during authentication. - - - This function can be used from FAILURE_ROUTE. - - - NOTE: when used without dialog support, the - uac_auth() function cannot be used for authenticating - in-dialog requests, as there is no mechanism to store the CSeq changes that - are required for ensuring the correctness of the dialog. The only exception are - BYE messages, which are the last messages within a call, - hence no further adjustments are needed. The function can still be used for - authenticating the initial INVITE though. - - - <function>uac_auth</function> usage - -... -uac_auth(); -... -failure_route[check_auth] { - ... - if ($T_reply_code==407) { - if (uac_auth("MD5,MD5-sess")) { - # auth is succesful, just relay - t_relay(); - exit; - } - # auth failed (no credentials maybe) - # so continue handling the 407 reply - } - ... -} -... - - -
- -
- - <function moreinfo="none">uac_inc_cseq()</function> - - - This function can be called to increase the CSeq of an ongoing request. - - - It receives as the cseq parameter the value that - the CSeq should be incremented with. - - - This function can be used from REQUEST_ROUTE, BRANCH_ROUTE and FAILURE_ROUTE. - - - <function>uac_inc_cseq</function> usage - -... -uac_inc_cseq(1); -... - - -
-
- -
- diff --git a/modules/uac/doc/uac_faq.xml b/modules/uac/doc/uac_faq.xml deleted file mode 100644 index ade4b08ff46..00000000000 --- a/modules/uac/doc/uac_faq.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - &faqguide; - - - - - What happened with auth_username_avp, auth_realm_avp and auth_password_avp parameters - - - - Due some restructuring of the UAC auth modules, these parameters were moved into the "uac_auth" module. - This module is now responsible for handling all the credentials (static defined or dynamically defined - via AVPs). The UAC module will still see the credentials defined via the AVPs. - $ - $ - $ - - - - Where can I find more about OpenSIPS? - - - - Take a look at &osipshomelink;. - - - - - - - Where can I post a question about this module? - - - - First at all check if your question was already answered on one of - our mailing lists: - - - - User Mailing List - &osipsuserslink; - - - Developer Mailing List - &osipsdevlink; - - - - E-mails regarding any stable &osips; release should be sent to - &osipsusersmail; and e-mails regarding development versions - should be sent to &osipsdevmail;. - - - If you want to keep the mail private, send it to - &osipshelpmail;. - - - - - - - How can I report a bug? - - - - Please follow the guidelines provided at: - &osipsbugslink;. - - - - - - diff --git a/modules/uac_auth/README b/modules/uac_auth/README deleted file mode 100644 index 56194f91d85..00000000000 --- a/modules/uac_auth/README +++ /dev/null @@ -1,205 +0,0 @@ -UAC AUTH Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - - 1.1.1. RFC 8760 Support (Strenghtened - Authentication) - - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. credential (string) - 1.3.2. auth_realm_avp (string) - 1.3.3. auth_username_avp (string) - 1.3.4. auth_password_avp (string) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set credential parameter - 1.2. Set auth_realm_avp parameter - 1.3. Set auth_username_avp parameter - 1.4. Set auth_password_avp parameter - -Chapter 1. Admin Guide - -1.1. Overview - - UAC AUTH (User Agent Client Authentication) module provides a - common API for building authentication headers. - - It also provides a common set of authentication credetials to - be used by other modules. - - Note that authentication provided by this module supports both - qop "auth" and qop "auth-int" but if both values are presented - by the server, "auth" will be prefered. - -1.1.1. RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, auth_db and uac_auth - modules include support for two new digest authentication - algorithms ("SHA-256" and "SHA-512-256"), according to the RFC - 8760 specs. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - * None. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. credential (string) - - Contains a multiple definition of credentials used to perform - authentication. - - NOTE that the password can be provided as a plain text password - or as a precalculated HA1 as a hexa (lower case) string (of 32 - chars) prefixed with "0x" (so a total of 34 chars). - - This parameter is required if UAC authentication is used. - - Example 1.1. Set credential parameter -... -modparam("uac_auth","credential","username:domain:password") -modparam("uac_auth","credential","username:domain:0xc17ba8157756f263d07e -158504204629") -... - -1.3.2. auth_realm_avp (string) - - The definition of an AVP that might contain the realm to be - used to perform authentication. - - If you define it, you also need to define “auth_username_avp” - (auth_username_avp) and “auth_password_avp” - (auth_password_avp). - - Example 1.2. Set auth_realm_avp parameter -... -modparam("uac_auth","auth_realm_avp","$avp(10)") -... - -1.3.3. auth_username_avp (string) - - The definition of an AVP that might contain the username to be - used to perform authentication. - - If you define it, you also need to define “auth_realm_avp” - (auth_realm_avp) and “auth_password_avp” (auth_password_avp). - - Example 1.3. Set auth_username_avp parameter -... -modparam("uac_auth","auth_username_avp","$avp(11)") -... - -1.3.4. auth_password_avp (string) - - The definition of an AVP that might contain the password to be - used to perform authentication. The password can be provided as - a plain text password or as a precalculated HA1 as a hexa - (lower case) string (of 32 chars) prefixed with "0x" (so a - total of 34 chars) (for example - "0xc17ba8157756f263d07e158504204629") - - If you define it, you also need to define “auth_realm_avp” - (auth_realm_avp) and “auth_username_avp” (auth_username_avp). - - Example 1.4. Set auth_password_avp parameter -... -modparam("uac_auth","auth_password_avp","$avp(12)") -... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 16 7 869 15 - 2. Liviu Chircu (@liviuchircu) 11 8 41 62 - 3. Maksym Sobolyev (@sobomax) 11 4 123 260 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 10 7 229 9 - 5. Razvan Crainea (@razvancrainea) 8 6 8 11 - 6. Vlad Patrascu (@rvlad-patrascu) 6 4 44 30 - 7. Bence Szigeti 3 1 7 1 - 8. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - Sep 2024 - 2. Bence Szigeti Apr 2023 - Apr 2023 - 3. Maksym Sobolyev (@sobomax) Sep 2020 - Feb 2023 - 4. Razvan Crainea (@razvancrainea) Sep 2011 - Jan 2021 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Jul 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2012 - Apr 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Ovidiu Sas (@ovidiusas) Jun 2011 - Oct 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei - Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas). - - Documentation Copyrights: - - Copyright © 2013 www.opensips-solutions.com - - Copyright © 2011 VoIP Embedded, Inc. diff --git a/modules/uac_auth/README.md b/modules/uac_auth/README.md new file mode 100644 index 00000000000..d23b3fe4087 --- /dev/null +++ b/modules/uac_auth/README.md @@ -0,0 +1,155 @@ +--- +title: "UAC AUTH Module" +description: "UAC AUTH (User Agent Client Authentication) module provides a common API for building authentication headers." +--- + +## Admin Guide + + +### Overview + + +UAC AUTH (User Agent Client Authentication) module provides a +common API for building authentication headers. + + +It also provides a common set of authentication credetials to +be used by other modules. + + +Note that authentication provided by this module supports both +qop "auth" and qop "auth-int" but if both values are presented +by the server, "auth" will be prefered. + + +#### RFC 8760 Support (Strenghtened Authentication) + + +Starting with OpenSIPS 3.2, the [auth](../auth), +[auth_db](../auth_db) and +[uac_auth](../uac_auth) +modules include support for two new digest authentication algorithms +("SHA-256" and "SHA-512-256"), according to the +[RFC 8760](https://datatracker.ietf.org/doc/html/rfc8760) +specs. + + +### Dependencies + + +#### OpenSIPS Modules + + +- *None.* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### credential (string) + + +Contains a multiple definition of credentials used to perform +authentication. + + +> [!NOTE] +> The password can be provided as a plain text password or +> as a precalculated HA1 as a hexa (lower case) string +> (of 32 chars) prefixed with "0x" (so a total of 34 chars). + + +*This parameter is required if UAC authentication is used.* + + +```opensips title="Set credential parameter" +... +modparam("uac_auth","credential","username:domain:password") +modparam("uac_auth","credential","username:domain:0xc17ba8157756f263d07e158504204629") +... + +``` + + +#### auth_realm_avp (string) + + +The definition of an AVP that might contain the realm to be used +to perform authentication. + + +*If you define it, you also need to define +"auth_username_avp" +([auth username avp](#param_auth_username_avp)) and +"auth_password_avp" +([auth password avp](#param_auth_password_avp)).* + + +```opensips title="Set auth_realm_avp parameter" +... +modparam("uac_auth","auth_realm_avp","$avp(10)") +... + +``` + + +#### auth_username_avp (string) + + +The definition of an AVP that might contain the username to be used +to perform authentication. + + +*If you define it, you also need to define +"auth_realm_avp" +([auth realm avp](#param_auth_realm_avp)) and +"auth_password_avp" +([auth password avp](#param_auth_password_avp)).* + + +```opensips title="Set auth_username_avp parameter" +... +modparam("uac_auth","auth_username_avp","$avp(11)") +... + +``` + + +#### auth_password_avp (string) + + +The definition of an AVP that might contain the password to be used +to perform authentication. The password can be provided as a plain +text password or as a precalculated HA1 as a hexa (lower case) string +(of 32 chars) prefixed with "0x" (so a total of 34 chars) (for example +"0xc17ba8157756f263d07e158504204629") + + +*If you define it, you also need to define +"auth_realm_avp" +([auth realm avp](#param_auth_realm_avp)) and +"auth_username_avp" +([auth username avp](#param_auth_username_avp)).* + + +```opensips title="Set auth_password_avp parameter" +... +modparam("uac_auth","auth_password_avp","$avp(12)") +... + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/uac_auth/doc/contributors.xml b/modules/uac_auth/doc/contributors.xml deleted file mode 100644 index 796a4c0b6a0..00000000000 --- a/modules/uac_auth/doc/contributors.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 16 - 7 - 869 - 15 - - - 2. - Liviu Chircu (@liviuchircu) - 11 - 8 - 41 - 62 - - - 3. - Maksym Sobolyev (@sobomax) - 11 - 4 - 123 - 260 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 10 - 7 - 229 - 9 - - - 5. - Razvan Crainea (@razvancrainea) - 8 - 6 - 8 - 11 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 44 - 30 - - - 7. - Bence Szigeti - 3 - 1 - 7 - 1 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - Sep 2024 - - - 2. - Bence Szigeti - Apr 2023 - Apr 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Sep 2020 - Feb 2023 - - - 4. - Razvan Crainea (@razvancrainea) - Sep 2011 - Jan 2021 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Jul 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2012 - Apr 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Ovidiu Sas (@ovidiusas) - Jun 2011 - Oct 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Ovidiu Sas (@ovidiusas). -
- -
diff --git a/modules/uac_auth/doc/uac_auth.xml b/modules/uac_auth/doc/uac_auth.xml deleted file mode 100644 index 4204fa09588..00000000000 --- a/modules/uac_auth/doc/uac_auth.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - UAC AUTH Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2013 &osipssol; - ©right; 2011 VoIP Embedded, Inc. - - diff --git a/modules/uac_auth/doc/uac_auth_admin.xml b/modules/uac_auth/doc/uac_auth_admin.xml deleted file mode 100644 index 294ffa43d0c..00000000000 --- a/modules/uac_auth/doc/uac_auth_admin.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - &adminguide; - - -
- Overview - - UAC AUTH (User Agent Client Authentication) module provides a - common API for building authentication headers. - - - It also provides a common set of authentication credetials to - be used by other modules. - - - Note that authentication provided by this module supports both - qop "auth" and qop "auth-int" but if both values are presented - by the server, "auth" will be prefered. - - -
- RFC 8760 Support (Strenghtened Authentication) - - Starting with OpenSIPS 3.2, the auth, - auth_db and - uac_auth - modules include support for two new digest authentication algorithms - ("SHA-256" and "SHA-512-256"), according to the - RFC 8760 - specs. - -
-
- -
- Dependencies -
- &osips; Modules - - - None. - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters - -
- <varname>credential</varname> (string) - - Contains a multiple definition of credentials used to perform - authentication. - - - NOTE that the password can be provided as a plain text password or - as a precalculated HA1 as a hexa (lower case) string - (of 32 chars) prefixed with "0x" (so a total of 34 chars). - - - - This parameter is required if UAC authentication is used. - - - - Set <varname>credential</varname> parameter - -... -modparam("uac_auth","credential","username:domain:password") -modparam("uac_auth","credential","username:domain:0xc17ba8157756f263d07e158504204629") -... - - -
- -
- <varname>auth_realm_avp</varname> (string) - - The definition of an AVP that might contain the realm to be used - to perform authentication. - - - If you define it, you also need to define - auth_username_avp - () and - auth_password_avp - (). - - - Set <varname>auth_realm_avp</varname> parameter - -... -modparam("uac_auth","auth_realm_avp","$avp(10)") -... - - -
- -
- <varname>auth_username_avp</varname> (string) - - The definition of an AVP that might contain the username to be used - to perform authentication. - - - If you define it, you also need to define - auth_realm_avp - () and - auth_password_avp - (). - - - Set <varname>auth_username_avp</varname> parameter - -... -modparam("uac_auth","auth_username_avp","$avp(11)") -... - - -
- -
- <varname>auth_password_avp</varname> (string) - - The definition of an AVP that might contain the password to be used - to perform authentication. The password can be provided as a plain - text password or as a precalculated HA1 as a hexa (lower case) string - (of 32 chars) prefixed with "0x" (so a total of 34 chars) (for example - "0xc17ba8157756f263d07e158504204629") - - - If you define it, you also need to define - auth_realm_avp - () and - auth_username_avp - (). - - - Set <varname>auth_password_avp</varname> parameter - -... -modparam("uac_auth","auth_password_avp","$avp(12)") -... - - -
- -
- -
- diff --git a/modules/uac_redirect/README b/modules/uac_redirect/README deleted file mode 100644 index ecd4d0809d1..00000000000 --- a/modules/uac_redirect/README +++ /dev/null @@ -1,345 +0,0 @@ -UAC_REDIRECT Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. default_filter (string) - 1.3.2. deny_filter (string) - 1.3.3. accept_filter (string) - - 1.4. Exported Functions - - 1.4.1. set_deny_filter(filter,flags) - 1.4.2. set_accept_filter(filter,flags) - 1.4.3. get_redirects([max_total], [max_branch]) - - 1.5. Script Example - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set default_filter module parameter - 1.2. Set deny_filter module parameter - 1.3. Set accept_filter module parameter - 1.4. set_deny_filter usage - 1.5. set_accept_filter usage - 1.6. get_redirects usage - 1.7. Redirection script example - -Chapter 1. Admin Guide - -1.1. Overview - - UAC REDIRECT - User Agent Client redirection - module enhance - OpenSIPS with the functionality of being able to handle - (interpret, filter, log and follow) redirect responses ( 3xx - replies class). - - UAC REDIRECT module offer stateful processing, gathering the - contacts from all 3xx branches of a call. - - The module provide a powerful mechanism for selecting and - filtering the contacts to be used for the new redirect: - * number based - limits like the number of total contacts to - be used or the maximum number of contacts per branch to be - selected. - * Regular Expression based - combinations of deny and accept - filters allow a strict control of the contacts to be used - for redirection. - - When selecting from a 3xx branch the contacts to be used, the - contacts will be ordered and prioritized based on the “q” - value. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * TM - Transaction Module, for accessing replies. - * ACC - Accounting Module, but only if the logging feature is - used. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None - -1.3. Exported Parameters - -1.3.1. default_filter (string) - - The default behavior in filtering contacts. It may be “accept” - or “deny”. - - The default value is “accept”. - - Example 1.1. Set default_filter module parameter -... -modparam("uac_redirect","default_filter","deny") -... - -1.3.2. deny_filter (string) - - The regular expression for default deny filtering. It make sens - to be defined on only if the default_filter parameter is set to - “accept”. All contacts matching the deny_filter will be - rejected; the rest of them will be accepted for redirection. - - The parameter may be defined only one - multiple definition - will overwrite the previous definitions. If more regular - expression need to be defined, use the set_deny_filter() - scripting function. - - This parameter is optional, it's default value being NULL. - - Example 1.2. Set deny_filter module parameter -... -modparam("uac_redirect","deny_filter",".*@siphub\.net") -... - -1.3.3. accept_filter (string) - - The regular expression for default accept filtering. It make - sens to be defined on only if the default_filter parameter is - set to “deny”. All contacts matching the accept_filter will be - accepted; the rest of them will be rejected for redirection. - - The parameter may be defined only one - multiple definition - will overwrite the previous definitions. If more regular - expression need to be defined, use the set_accept_filter() - scripting function. - - This parameter is optional, it's default value being NULL. - - Example 1.3. Set accept_filter module parameter -... -modparam("uac_redirect","accept_filter",".*@siphub\.net") -... - -1.4. Exported Functions - -1.4.1. set_deny_filter(filter,flags) - - Sets additional deny filters. Maximum 6 may be combined. This - additional filter will apply only to the current message - it - will not have a global effect. - - Parameters: - * filter (string) - regular expression - * flags (string) - Default or previous added deny filter may be reset - depending of the parameter value: - + reset_all - reset both default and previous added deny - filters; - + reset_default - reset only the default deny filter; - + reset_added - reset only the previous added deny - filters; - + empty - no reset, just add the filter. - - This function can be used from FAILURE_ROUTE. - - Example 1.4. set_deny_filter usage -... -set_deny_filter(".*@domain2.net","reset_all"); -set_deny_filter(".*@domain1.net",""); -... - -1.4.2. set_accept_filter(filter,flags) - - Sets additional accept filters. Maximum 6 may be combined. This - additional filter will apply only to the current message - it - will not have a global effect. - - Parameters: - * filter (string) - regular expression - * flags (string) - Default or previous added deny filter may be reset - depending of the parameter value: - + reset_all - reset both default and previous added - accept filters; - + reset_default - reset only the default accept filter; - + reset_added - reset only the previous added accept - filters; - + empty - no reset, just add the filter. - - This function can be used from FAILURE_ROUTE. - - Example 1.5. set_accept_filter usage -... -set_accept_filter(".*@domain2.net","reset_added"); -set_accept_filter(".*@domain1.net",""); -... - -1.4.3. get_redirects([max_total], [max_branch]) - - The function may be called only from failure routes. It will - extract the contacts from all 3xx branches and append them as - new branches. Note that the function will not forward the new - branches, this must be done explicitly from script. - - How many contacts (in total and per branch) are selected - depends on the max_total and max_branch parameters: - * max_total (int, optional) - max overall number of contacts - to be selected - * max_branch (int, optional) - max number of contacts per - branch to be selected - - Both “max_total” and “max_branch” default to 0 (unlimited). - - NOTE that during the selection process, each set of contacts - from a specific branch are ordered based on “q” value. - - This function can be used from FAILURE_ROUTE. - - Example 1.6. get_redirects usage -... -# no restrictions -get_redirects(); -... -# no limits per branch, but not more than 6 overall contacts -get_redirects(6); -... -# max 2 contacts per branch, but no overall limit -get_redirects(, 2); -... - -1.5. Script Example - - Example 1.7. Redirection script example -loadmodule "modules/sl/sl.so" -loadmodule "modules/usrloc/usrloc.so" -loadmodule "modules/registrar/registrar.so" -loadmodule "modules/tm/tm.so" -loadmodule "modules/acc/acc.so" -loadmodule "modules/uac_redirect/uac_redirect.so" - -modparam("usrloc", "db_mode", 0) - -route{ - if (is_myself("$rd")) { - - if ($rm=="REGISTER") { - save("location"); - exit; - }; - - if (!lookup("location")) { - sl_send_reply(404, "Not Found"); - exit; - }; - } - - t_on_failure("do_redirect"); - - if (!t_relay()) { - sl_reply_error(); - }; -} - -failure_route[do_redirect] { - if (get_redirects(3, 1)) - t_relay(); -} - - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 48 30 1716 144 - 2. Liviu Chircu (@liviuchircu) 18 10 106 372 - 3. Daniel-Constantin Mierla (@miconda) 12 10 24 20 - 4. Rob Gagnon (@rgagnon24) 8 6 50 48 - 5. Razvan Crainea (@razvancrainea) 8 6 11 10 - 6. Henning Westerholt (@henningw) 7 5 12 11 - 7. Vlad Patrascu (@rvlad-patrascu) 5 3 25 6 - 8. Maksym Sobolyev (@sobomax) 4 2 3 4 - 9. Anca Vamanu 3 1 30 55 - 10. Konstantin Bokarius 3 1 2 5 - - All remaining contributors: Andreas Granig, Peter Lemenkov - (@lemenkov), Edson Gellert Schubert, Elena-Ramona Modroiu, - Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Bogdan-Andrei Iancu (@bogdan-iancu) Jun 2005 - May 2025 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 3. Razvan Crainea (@razvancrainea) Feb 2012 - Sep 2019 - 4. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 5. Liviu Chircu (@liviuchircu) Mar 2014 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Rob Gagnon (@rgagnon24) Mar 2015 - Mar 2015 - 8. Walter Doekes (@wdoekes) May 2014 - May 2014 - 9. Daniel-Constantin Mierla (@miconda) Nov 2006 - Mar 2008 - 10. Konstantin Bokarius Mar 2008 - Mar 2008 - - All remaining contributors: Edson Gellert Schubert, Henning - Westerholt (@henningw), Anca Vamanu, Andreas Granig, - Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Peter - Lemenkov (@lemenkov), Rob Gagnon (@rgagnon24), Razvan Crainea - (@razvancrainea), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt - (@henningw). - - Documentation Copyrights: - - Copyright © 2005 Voice Sistem SRL diff --git a/modules/uac_redirect/README.md b/modules/uac_redirect/README.md new file mode 100644 index 00000000000..3a4350f1d9b --- /dev/null +++ b/modules/uac_redirect/README.md @@ -0,0 +1,311 @@ +--- +title: "UAC REDIRECT Module" +description: "UAC REDIRECT - User Agent Client redirection - module enhance OpenSIPS with the functionality of being able to handle (interpret, filter, log and follow) redirect responses ( 3xx replies class)." +--- + +## Admin Guide + + +### Overview + + +UAC REDIRECT - User Agent Client redirection - module enhance OpenSIPS +with the functionality of being able to handle (interpret, filter, +log and follow) redirect responses ( 3xx replies class). + + +UAC REDIRECT module offer stateful processing, gathering the +contacts from all 3xx branches of a call. + + +The module provide a powerful mechanism for selecting and filtering +the contacts to be used for the new redirect: + + +- *number based* - limits like the +number of total contacts to be used or the maximum number of +contacts per branch to be selected. +- *Regular Expression based* - combinations +of deny and accept filters allow a strict control of the +contacts to be used for redirection. + + +When selecting from a 3xx branch the contacts to be used, the contacts +will be ordered and prioritized based on the "q" value. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *TM* - Transaction Module, for accessing +replies. +- *ACC* - Accounting Module, but only if the +logging feature is used. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *None* + + +### Exported Parameters + + +#### default_filter (string) + + +The default behavior in filtering contacts. It may be +"accept" or "deny". + + +*The default value is "accept".* + + +```opensips title="Set default_filter module parameter" +... +modparam("uac_redirect","default_filter","deny") +... + +``` + + +#### deny_filter (string) + + +The regular expression for default deny filtering. It make sens +to be defined on only if the `default_filter` +parameter is set to "accept". All contacts matching +the `deny_filter` will be rejected; the rest +of them will be accepted for redirection. + + +The parameter may be defined only one - multiple definition will +overwrite the previous definitions. If more regular expression +need to be defined, use the +`set_deny_filter()` scripting +function. + + +*This parameter is optional, it's default +value being NULL.* + + +```opensips title="Set deny_filter module parameter" +... +modparam("uac_redirect","deny_filter",".*@siphub\.net") +... + +``` + + +#### accept_filter (string) + + +The regular expression for default accept filtering. It make sens +to be defined on only if the `default_filter` +parameter is set to "deny". All contacts matching +the `accept_filter` will be accepted; the rest +of them will be rejected for redirection. + + +The parameter may be defined only one - multiple definition will +overwrite the previous definitions. If more regular expression +need to be defined, use the +`set_accept_filter()` scripting +function. + + +*This parameter is optional, it's default +value being NULL.* + + +```opensips title="Set accept_filter module parameter" +... +modparam("uac_redirect","accept_filter",".*@siphub\.net") +... + +``` + + +### Exported Functions + + +#### set_deny_filter(filter,flags) + + +Sets additional deny filters. Maximum 6 may be combined. This +additional filter will apply only to the current message - it +will not have a global effect. + + +Parameters: + + +- *filter* (string) - regular expression +- *flags* (string) +Default or previous added deny filter may be reset depending of +the parameter value: + + - *reset_all* - reset both default +and previous added deny filters; + - *reset_default* - reset only the +default deny filter; + - *reset_added* - reset only the +previous added deny filters; + - *empty* - no reset, just add the +filter. + + +This function can be used from FAILURE_ROUTE. + + +```opensips title="set_deny_filter usage" +... +set_deny_filter(".*@domain2.net","reset_all"); +set_deny_filter(".*@domain1.net",""); +... + +``` + + +#### set_accept_filter(filter,flags) + + +Sets additional accept filters. Maximum 6 may be combined. This +additional filter will apply only to the current message - it +will not have a global effect. + + +Parameters: + + +- *filter* (string) - regular expression +- *flags* (string) +Default or previous added deny filter may be reset depending of +the parameter value: + + - *reset_all* - reset both default +and previous added accept filters; + - *reset_default* - reset only the +default accept filter; + - *reset_added* - reset only the +previous added accept filters; + - *empty* - no reset, just add +the filter. + + +This function can be used from FAILURE_ROUTE. + + +```opensips title="set_accept_filter usage" +... +set_accept_filter(".*@domain2.net","reset_added"); +set_accept_filter(".*@domain1.net",""); +... + +``` + + +#### get_redirects([max_total], [max_branch]) + + +The function may be called only from failure routes. It will +extract the contacts from all 3xx branches and append them +as new branches. Note that the function will not forward the +new branches, this must be done explicitly from script. + + +How many contacts (in total and per branch) are selected +depends on the *max_total* and +*max_branch* parameters: + + +- max_total (int, optional) - max overall number of contacts to be selected +- max_branch (int, optional) - max number of contacts per branch to be selected + + +Both "max_total" and "max_branch" +default to 0 (unlimited). + + +> [!NOTE] +> During the selection process, each set of contacts +> from a specific branch are ordered based on "q" +> value. + + +This function can be used from FAILURE_ROUTE. + + +```opensips title="get_redirects usage" +... +# no restrictions +get_redirects(); +... +# no limits per branch, but not more than 6 overall contacts +get_redirects(6); +... +# max 2 contacts per branch, but no overall limit +get_redirects(, 2); +... + +``` + + +### Script Example + + +```opensips title="Redirection script example" +loadmodule "modules/sl/sl.so" +loadmodule "modules/usrloc/usrloc.so" +loadmodule "modules/registrar/registrar.so" +loadmodule "modules/tm/tm.so" +loadmodule "modules/acc/acc.so" +loadmodule "modules/uac_redirect/uac_redirect.so" + +modparam("usrloc", "db_mode", 0) + +route{ + if (is_myself("$rd")) { + + if ($rm=="REGISTER") { + save("location"); + exit; + }; + + if (!lookup("location")) { + sl_send_reply(404, "Not Found"); + exit; + }; + } + + t_on_failure("do_redirect"); + + if (!t_relay()) { + sl_reply_error(); + }; +} + +failure_route[do_redirect] { + if (get_redirects(3, 1)) + t_relay(); +} + + +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/uac_redirect/doc/contributors.xml b/modules/uac_redirect/doc/contributors.xml deleted file mode 100644 index 5d411c228e8..00000000000 --- a/modules/uac_redirect/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 48 - 30 - 1716 - 144 - - - 2. - Liviu Chircu (@liviuchircu) - 18 - 10 - 106 - 372 - - - 3. - Daniel-Constantin Mierla (@miconda) - 12 - 10 - 24 - 20 - - - 4. - Rob Gagnon (@rgagnon24) - 8 - 6 - 50 - 48 - - - 5. - Razvan Crainea (@razvancrainea) - 8 - 6 - 11 - 10 - - - 6. - Henning Westerholt (@henningw) - 7 - 5 - 12 - 11 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 25 - 6 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 3 - 4 - - - 9. - Anca Vamanu - 3 - 1 - 30 - 55 - - - 10. - Konstantin Bokarius - 3 - 1 - 2 - 5 - - - -
-All remaining contributors: Andreas Granig, Peter Lemenkov (@lemenkov), Edson Gellert Schubert, Elena-Ramona Modroiu, Walter Doekes (@wdoekes). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - Jun 2005 - May 2025 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 3. - Razvan Crainea (@razvancrainea) - Feb 2012 - Sep 2019 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 5. - Liviu Chircu (@liviuchircu) - Mar 2014 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Rob Gagnon (@rgagnon24) - Mar 2015 - Mar 2015 - - - 8. - Walter Doekes (@wdoekes) - May 2014 - May 2014 - - - 9. - Daniel-Constantin Mierla (@miconda) - Nov 2006 - Mar 2008 - - - 10. - Konstantin Bokarius - Mar 2008 - Mar 2008 - - - -
-All remaining contributors: Edson Gellert Schubert, Henning Westerholt (@henningw), Anca Vamanu, Andreas Granig, Elena-Ramona Modroiu. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Liviu Chircu (@liviuchircu), Peter Lemenkov (@lemenkov), Rob Gagnon (@rgagnon24), Razvan Crainea (@razvancrainea), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw). -
- -
diff --git a/modules/uac_redirect/doc/uac_redirect.xml b/modules/uac_redirect/doc/uac_redirect.xml deleted file mode 100644 index 9081bd65e65..00000000000 --- a/modules/uac_redirect/doc/uac_redirect.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - UAC_REDIRECT Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2005 &voicesystem; - - diff --git a/modules/uac_redirect/doc/uac_redirect_admin.xml b/modules/uac_redirect/doc/uac_redirect_admin.xml deleted file mode 100644 index c4258d15485..00000000000 --- a/modules/uac_redirect/doc/uac_redirect_admin.xml +++ /dev/null @@ -1,392 +0,0 @@ - - - - - &adminguide; - - -
- Overview - - UAC REDIRECT - User Agent Client redirection - module enhance &osips; - with the functionality of being able to handle (interpret, filter, - log and follow) redirect responses ( 3xx replies class). - - - UAC REDIRECT module offer stateful processing, gathering the - contacts from all 3xx branches of a call. - - - The module provide a powerful mechanism for selecting and filtering - the contacts to be used for the new redirect: - - - - number based - limits like the - number of total contacts to be used or the maximum number of - contacts per branch to be selected. - - - - Regular Expression based - combinations - of deny and accept filters allow a strict control of the - contacts to be used for redirection. - - - - - When selecting from a 3xx branch the contacts to be used, the contacts - will be ordered and prioritized based on the q value. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - TM - Transaction Module, for accessing - replies. - - - - - ACC - Accounting Module, but only if the - logging feature is used. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - None - - - - -
-
- -
- Exported Parameters -
- <varname>default_filter</varname> (string) - - The default behavior in filtering contacts. It may be - accept or deny. - - - - The default value is accept. - - - - Set <varname>default_filter</varname> - module parameter - -... -modparam("uac_redirect","default_filter","deny") -... - - -
-
- <varname>deny_filter</varname> (string) - - The regular expression for default deny filtering. It make sens - to be defined on only if the default_filter - parameter is set to accept. All contacts matching - the deny_filter will be rejected; the rest - of them will be accepted for redirection. - - - The parameter may be defined only one - multiple definition will - overwrite the previous definitions. If more regular expression - need to be defined, use the - set_deny_filter() scripting - function. - - - - This parameter is optional, it's default - value being NULL. - - - - Set <varname>deny_filter</varname> - module parameter - -... -modparam("uac_redirect","deny_filter",".*@siphub\.net") -... - - -
-
- <varname>accept_filter</varname> (string) - - The regular expression for default accept filtering. It make sens - to be defined on only if the default_filter - parameter is set to deny. All contacts matching - the accept_filter will be accepted; the rest - of them will be rejected for redirection. - - - The parameter may be defined only one - multiple definition will - overwrite the previous definitions. If more regular expression - need to be defined, use the - set_accept_filter() scripting - function. - - - - This parameter is optional, it's default - value being NULL. - - - - Set <varname>accept_filter</varname> - module parameter - -... -modparam("uac_redirect","accept_filter",".*@siphub\.net") -... - - -
-
- - -
- Exported Functions -
- - <function moreinfo="none">set_deny_filter(filter,flags) - </function> - - - Sets additional deny filters. Maximum 6 may be combined. This - additional filter will apply only to the current message - it - will not have a global effect. - - Parameters: - - - filter (string) - regular expression - - - flags (string) - - Default or previous added deny filter may be reset depending of - the parameter value: - - - - reset_all - reset both default - and previous added deny filters; - - - - reset_default - reset only the - default deny filter; - - - - reset_added - reset only the - previous added deny filters; - - - - empty - no reset, just add the - filter. - - - - - - - This function can be used from FAILURE_ROUTE. - - - <function>set_deny_filter</function> usage - -... -set_deny_filter(".*@domain2.net","reset_all"); -set_deny_filter(".*@domain1.net",""); -... - - -
- -
- - <function moreinfo="none">set_accept_filter(filter,flags) - </function> - - - Sets additional accept filters. Maximum 6 may be combined. This - additional filter will apply only to the current message - it - will not have a global effect. - - Parameters: - - - filter (string) - regular expression - - - flags (string) - - Default or previous added deny filter may be reset depending of - the parameter value: - - - - reset_all - reset both default - and previous added accept filters; - - - - reset_default - reset only the - default accept filter; - - - - reset_added - reset only the - previous added accept filters; - - - - empty - no reset, just add - the filter. - - - - - - - This function can be used from FAILURE_ROUTE. - - - <function>set_accept_filter</function> usage - -... -set_accept_filter(".*@domain2.net","reset_added"); -set_accept_filter(".*@domain1.net",""); -... - - -
- -
- - <function moreinfo="none">get_redirects([max_total], [max_branch])</function> - - - The function may be called only from failure routes. It will - extract the contacts from all 3xx branches and append them - as new branches. Note that the function will not forward the - new branches, this must be done explicitly from script. - - - How many contacts (in total and per branch) are selected - depends on the max_total and - max_branch parameters: - - - - max_total (int, optional) - max overall number of contacts to be selected - - - max_branch (int, optional) - max number of contacts per branch to be selected - - - - Both max_total and max_branch - default to 0 (unlimited). - - - NOTE that during the selection process, each set of contacts - from a specific branch are ordered based on q - value. - - - This function can be used from FAILURE_ROUTE. - - - <function>get_redirects</function> usage - -... -# no restrictions -get_redirects(); -... -# no limits per branch, but not more than 6 overall contacts -get_redirects(6); -... -# max 2 contacts per branch, but no overall limit -get_redirects(, 2); -... - - -
-
- -
- Script Example - - Redirection script example - -loadmodule "modules/sl/sl.so" -loadmodule "modules/usrloc/usrloc.so" -loadmodule "modules/registrar/registrar.so" -loadmodule "modules/tm/tm.so" -loadmodule "modules/acc/acc.so" -loadmodule "modules/uac_redirect/uac_redirect.so" - -modparam("usrloc", "db_mode", 0) - -route{ - if (is_myself("$rd")) { - - if ($rm=="REGISTER") { - save("location"); - exit; - }; - - if (!lookup("location")) { - sl_send_reply(404, "Not Found"); - exit; - }; - } - - t_on_failure("do_redirect"); - - if (!t_relay()) { - sl_reply_error(); - }; -} - -failure_route[do_redirect] { - if (get_redirects(3, 1)) - t_relay(); -} - - - - -
- - - -
- diff --git a/modules/uac_registrant/README b/modules/uac_registrant/README deleted file mode 100644 index 372aae16b13..00000000000 --- a/modules/uac_registrant/README +++ /dev/null @@ -1,586 +0,0 @@ -UAC Registrant Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. hash_size (integer) - 1.3.2. timer_interval (integer) - 1.3.3. failure_retry_interval (integer) - 1.3.4. enable_clustering (integer) - 1.3.5. db_url (string) - 1.3.6. table_name (string) - 1.3.7. registrar_column (string) - 1.3.8. proxy_column (string) - 1.3.9. aor_column (string) - 1.3.10. third_party_registrant_column (string) - 1.3.11. username_column (string) - 1.3.12. password_column (string) - 1.3.13. binding_URI_column (string) - 1.3.14. binding_params_column (string) - 1.3.15. expiry_column (string) - 1.3.16. forced_socket_column (string) - 1.3.17. cluster_shtag_column (string) - 1.3.18. state_column (string) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. reg_list - 1.5.2. reg_reload - 1.5.3. reg_enable - 1.5.4. reg_disable - 1.5.5. reg_force_register - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set hash_size parameter - 1.2. Set timer_interval parameter - 1.3. Set failure_retry_interval parameter - 1.4. Set enable_clustering parameter - 1.5. Set “db_url” parameter - 1.6. Set “table_name” parameter - 1.7. Set “registrar_column” parameter - 1.8. Set “proxy_column” parameter - 1.9. Set “aor_column” parameter - 1.10. Set “third_party_registrant_column” parameter - 1.11. Set “username_column” parameter - 1.12. Set “password_column” parameter - 1.13. Set “binding_URI_column” parameter - 1.14. Set “binding_params_column” parameter - 1.15. Set “expiry_column” parameter - 1.16. Set “forced_socket_column” parameter - 1.17. Set “cluster_shtag_column” parameter - 1.18. Set “state_column” parameter - -Chapter 1. Admin Guide - -1.1. Overview - - The module enable OpenSIPS to register itself on a remote SIP - registrar. - - At startup, the registrant records are loaded into a hash table - in memory and a timer is started. The hash index is computed - over the AOR field. - - The timer interval for checking records in a hash bucket is - computed by dividing the timer_interval module param by the - number of hash buckets. When the timer fires for the first - time, the first hash bucket will be checked and REGISTERs will - be sent out for each record that is found. On the next timeout - fire, the second hash bucket will be checked and so on. If the - configured timer_interval module param is lower then the number - of buckets, the module will fail to start. - - Example: setting the timer_interval module to 8 with a - hash_size of 2, will result in having 4 hash buckets (2^2=4) - and buckets will be checked one by one every 2s (8/4=2). - - Each registrant has it's own state. Registrant's status can be - inspected via "reg_list" MI comand. - - UAC registrant states: - * 0 - NOT_REGISTERED_STATE - the initial state (no REGISTER - has been sent out yet); - * 1 - REGISTERING_STATE - waiting for a reply from the - registrar after a REGISTER without authentication header - was sent; - * 2 - AUTHENTICATING_STATE - waiting for a reply from the - registrar after a REGISTER with authentication header was - sent; - * 3 - REGISTERED_STATE - the uac is successfully registered; - * 4 - REGISTER_TIMEOUT_STATE : no reply received from the - registrar; - * 5 - INTERNAL_ERROR_STATE - some errors were - found/encountered during the processing of a reply; - * 6 - WRONG_CREDENTIALS_STATE - credentials rejected by the - registrar; - * 7 - REGISTRAR_ERROR_STATE - error reply received from the - registrar; - * 8 - UNREGISTERING_STATE - waiting for a reply from the - registrar after an unREGISTER without authentication header - was sent; - * 9 - AUTHENTICATING_UNREGISTER_STATE - waiting for a reply - from the registrar after an unREGISTER with authentication - header was sent; - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * uac_auth - UAC authentication module - -1.2.2. External Libraries or Applications - - None. - -1.3. Exported Parameters - -1.3.1. hash_size (integer) - - The size of the hash table internally used to keep the - registrants. A larger table distributes better the registration - load in time but consumes more memory. The hash size is a power - of number two. - - Default value is 1. - - Example 1.1. Set hash_size parameter -... -modparam("uac_registrant", "hash_size", 2) -... - -1.3.2. timer_interval (integer) - - Defines the periodic timer for checking the registrations - status. - - Default value is 100. - - Example 1.2. Set timer_interval parameter -... -modparam("uac_registrant", "timer_interval", 120) -... - -1.3.3. failure_retry_interval (integer) - - Defines a custom interval to retry the registration upon - error/failure. Normally, after any kind of failure (timeout, - credentials, internal error), the registration is re-taken - after "expires" seconds. The parameter here, if set, overrides - that value. - - Default value is 0 (not set). - - Example 1.3. Set failure_retry_interval parameter -... -modparam("uac_registrant", "failure_retry_interval", 3600) -... - -1.3.4. enable_clustering (integer) - - This parameter enables the clustering support in the module. - This is used to share this registration between all the nodes - in the cluster. When using this option, you should define (for - each registrant record) a sharing tag - this sharing tag will - control at the cluster level which node is entitled to perform - the registation (only the node having that tag as active will - do the registation, the onther nodes being idle). - - Default value is 0 / off. - - Example 1.4. Set enable_clustering parameter -... -modparam("uac_registrant", "enable_clustering", 1) -... - -1.3.5. db_url (string) - - Database where to load the registrants from. - - Default value is “NULL” (use default DB URL from core). - - Example 1.5. Set “db_url” parameter -... -modparam("uac_registrant", "db_url", "mysql://user:passw@localhost/datab -ase") -... - -1.3.6. table_name (string) - - The database table that holds the registrant records. - - Default value is “registrant”. - - Example 1.6. Set “table_name” parameter -... -modparam("uac_registrant", "table_name", "my_registrant") -... - -1.3.7. registrar_column (string) - - The column's name in the database storing the URI pointing to - the remote registrar (mandatory field). OpenSIPS expects a - valid URI. - - Default value is “registrar”. - - Example 1.7. Set “registrar_column” parameter -... -modparam("uac_registrant", "registrar_column", "registrant_uri") -... - -1.3.8. proxy_column (string) - - The column's name in the database storing the URI pointing to - the outbond proxy (not mandatory field). An empty or NULL value - means no outbound proxy, otherwise OpenSIPS expects a valid - URI. - - Default value is “proxy”. - - Example 1.8. Set “proxy_column” parameter -... -modparam("uac_registrant", "proxy_column", "proxy_uri") -... - -1.3.9. aor_column (string) - - The column's name in the database storing the URI defining the - address of record (mandatory field). The URI stored here will - be used in the To URI of the REGISTER. OpenSIPS expects a valid - URI. - - Default value is “aor”. - - Example 1.9. Set “aor_column” parameter -... -modparam("uac_registrant", "aor_column", "to_uri") -... - -1.3.10. third_party_registrant_column (string) - - The column's name in the database storing the URI defining the - third party registrant (not mandatory field). The URI stored - here will be used in the From URI of the REGISTER. An empty or - NULL value means no third party registration (the From URI will - be identical to To URI), otherwise OpenSIPS expects a valid - URI. - - Default value is “third_party_registrant”. - - Example 1.10. Set “third_party_registrant_column” parameter -... -modparam("uac_registrant", "third_party_registrant_column", "from_uri") -... - -1.3.11. username_column (string) - - The column's name in the database storing the username for - authentication (mandatory if the registrar requires - authentication). - - Default value is “username”. - - Example 1.11. Set “username_column” parameter -... -modparam("uac_registrant", "username_column", "auth_username") -... - -1.3.12. password_column (string) - - The column's name in the database storing the password for - authentication (mandatory if the registrar requires - authntication). - - Default value is “password”. - - Example 1.12. Set “password_column” parameter -... -modparam("uac_registrant", "password_column", "auth_passowrd") -... - -1.3.13. binding_URI_column (string) - - The column's name in the database storing the binding URI in - REGISTER (mandatory field). The URI stored here will be used in - the Contact URI of the REGISTER. OpenSIPS expects a valid URI. - - Default value is “binding_URI”. - - Example 1.13. Set “binding_URI_column” parameter -... -modparam("uac_registrant", "binding_URI_column", "contact_uri") -... - -1.3.14. binding_params_column (string) - - The column's name in the database storing the binding params in - REGISTER (not mandatory field). If not NULL or not empty, the - string stored here will be added as params to the Contact URI - in REGISTER (it MUST start with “;”. - - If the following two params are present, then the binding will - be enforced to be unique (if two bindings are received in a - 200ok, a complete binding removal will be performed before - re-registering): - * reg-id - * +sip.instance - - Example of params that will force unique binding: -;reg-id=1;+sip.instance="" - - Default value is “binding_params”. - - Example 1.14. Set “binding_params_column” parameter -... -modparam("uac_registrant", "binding_params_column", "contact_params") -... - -1.3.15. expiry_column (string) - - The column's name in the database storing the expiration time - (not mandatory). - - Default value is “expiry”. - - Example 1.15. Set “expiry_column” parameter -... -modparam("uac_registrant", "expiry_column", "registration_timeout") -... - -1.3.16. forced_socket_column (string) - - The column's name in the database storing the socket for - sending the REGISTER (not mandatory). If a forced socket is - provided, the socket MUST be explicitely set as a global - listening socket in the config (see “listen” core parameter). - - Default value is “forced_socket”. - - Example 1.16. Set “forced_socket_column” parameter -... -modparam("uac_registrant", "forced_socket_column", "fs") -... - -1.3.17. cluster_shtag_column (string) - - The column's name in the database storing the cluster sharing - tag in [tag_name/cluster_id] format (not mandatory). If a - cluster sharing tag is provided, the REGISTER requests will be - fired out only when the tag is active. - - Default value is “cluster_shtag”. - - Example 1.17. Set “cluster_shtag_column” parameter -... -modparam("uac_registrant", "cluster_shtag_column", "sh") -... - -1.3.18. state_column (string) - - The column's name in the database storing the current state of - the registrant. When a registrant is disabled, OpenSIPS will no - longer send REGISTERs for it. A value of 0 for this column - means enabled and 1 disabled. - - Default value is “state”. - - Example 1.18. Set “state_column” parameter -... -modparam("uac_registrant", "state_column", "status") -... - -1.4. Exported Functions - - None to be used in configuration file. - -1.5. Exported MI Functions - -1.5.1. reg_list - - Lists the registrant records and their status. - - Name: reg_list - - Parameters: - * aor (optional) - URI defining the address of record. If - provided, contact and registrar parameters are also - required and only a specific record will be listed. - * contact (optional) - Contact URI. If provided, aor and - registrar parameters are also required and only a specific - record will be listed. - * registrar (optional) - URI pointing to the remote - registrar. If provided, aor and contact parameters are also - required and only a specific record will be listed. - - MI FIFO Command Format: -opensips-cli -x mi reg_list -... -opensips-cli -x mi reg_list sip:alice@opensips.org sip:alice@127.0.0.1: -5060 sip:opensips.org - -1.5.2. reg_reload - - Reloads the registrant records from the database. - - Name: reg_reload - - Parameters: none - * aor (optional) - URI defining the address of record. If - provided, contact and registrar parameters are also - required and only a specific record will be reloaded. - * contact (optional) - Contact URI. If provided, aor and - registrar parameters are also required and only a specific - record will be reloaded. - * registrar (optional) - URI pointing to the remote - registrar. If provided, aor and contact parameters are also - required and only a specific record will be reloaded. - - MI FIFO Command Format: -opensips-cli -x mi reg_reload -... -opensips-cli -x mi reg_leload sip:alice@opensips.org sip:alice@127.0.0. -1:5060 sip:opensips.org - -1.5.3. reg_enable - - Enables a specific registrant. OpenSIPS will immediately send a - REGISTER if the registrant was previously disabled and will - update the state in the database. - - Name: reg_enable - - Parameters: none - * aor - URI defining the address of record. - * contact - Contact URI. - * registrar - URI pointing to the remote registrar. - - MI FIFO Command Format: -opensips-cli -x mi reg_enable sip:alice@opensips.org sip:alice@127.0.0. -1:5060 sip:opensips.org - -1.5.4. reg_disable - - Disables a specific registrant. OpenSIPS will immediately send - an unREGISTER if the registrant was previously enabled and will - update the state in the database. - - Name: reg_disable - - Parameters: none - * aor - URI defining the address of record. If provided, - contact and registrar parameters are also required and only - a specific record will be disabled. - * contact - Contact URI. If provided, aor and registrar - parameters are also required and only a specific record - will be disabled. - * registrar - URI pointing to the remote registrar. If - provided, aor and contact parameters are also required and - only a specific record will be disabled. - - MI FIFO Command Format: -opensips-cli -x mi reg_disable sip:alice@opensips.org sip:alice@127.0.0 -.1:5060 sip:opensips.org - -1.5.5. reg_force_register - - Forces the re-registration (or registation) of a specific - registrant (depending on its state). Note that the registrant - must be enabled. - - Name: reg_force_register - - Parameters: - * aor - URI defining the address of record. If provided, - contact and registrar parameters are also required and only - a specific record will be forced to re-register. - * contact - Contact URI. If provided, aor and registrar - parameters are also required and only a specific record - will be forced to re-register. - * registrar - URI pointing to the remote registrar. If - provided, aor and contact parameters are also required and - only a specific record will be forced to re-register. - - MI FIFO Command Format: -opensips-cli -x mi reg_force_register sip:alice@opensips.org sip:alice@ -127.0.0.1:5060 sip:opensips.org - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Ovidiu Sas (@ovidiusas) 143 41 5688 3268 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 18 13 451 49 - 3. Liviu Chircu (@liviuchircu) 17 14 57 68 - 4. Vlad Patrascu (@rvlad-patrascu) 16 7 732 118 - 5. Razvan Crainea (@razvancrainea) 11 9 26 36 - 6. Nick Altmann (@nikbyte) 5 3 43 4 - 7. Maksym Sobolyev (@sobomax) 5 3 20 16 - 8. James Stanley 4 2 21 14 - 9. Vlad Paiu (@vladpaiu) 4 2 6 3 - 10. sagarmalam 3 1 15 1 - - All remaining contributors: Walter Doekes (@wdoekes), James - Stanley, Peter Lemenkov (@lemenkov), okhowang(王沛文). - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Nick Altmann (@nikbyte) Nov 2015 - Mar 2025 - 2. okhowang(王沛文) Jul 2024 - Jul 2024 - 3. James Stanley Dec 2023 - Jun 2024 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Dec 2012 - May 2024 - 5. Ovidiu Sas (@ovidiusas) Feb 2011 - Dec 2023 - 6. Maksym Sobolyev (@sobomax) Mar 2021 - Nov 2023 - 7. James Stanley Mar 2023 - Mar 2023 - 8. Razvan Crainea (@razvancrainea) Sep 2011 - Nov 2021 - 9. Liviu Chircu (@liviuchircu) Mar 2014 - Jul 2021 - 10. Walter Doekes (@wdoekes) Apr 2021 - Apr 2021 - - All remaining contributors: sagarmalam, Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Vlad Paiu - (@vladpaiu). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad - Patrascu (@rvlad-patrascu), Ovidiu Sas (@ovidiusas), Razvan - Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu - Chircu (@liviuchircu). - - Documentation Copyrights: - - Copyright © 2011-2014 VoIP Embedded, Inc. diff --git a/modules/uac_registrant/README.md b/modules/uac_registrant/README.md new file mode 100644 index 00000000000..8664ebbfd14 --- /dev/null +++ b/modules/uac_registrant/README.md @@ -0,0 +1,626 @@ +--- +title: "UAC Registrant Module" +description: "The module enable OpenSIPS to register itself on a remote SIP registrar." +--- + +## Admin Guide + + +### Overview + + +The module enable OpenSIPS to register itself on a remote SIP registrar. + + +At startup, the registrant records are loaded into +a hash table in memory and a timer is started. +The hash index is computed over the AOR field. + + +The timer interval for checking records in a hash bucket is computed +by dividing the timer_interval module param by the number of hash buckets. +When the timer fires for the first time, the first hash bucket will be checked and +REGISTERs will be sent out for each record that is found. +On the next timeout fire, the second hash bucket will be checked and so on. +If the configured timer_interval module param is lower then the number of buckets, +the module will fail to start. + + +Example: setting the timer_interval module to 8 with a hash_size of 2, will result +in having 4 hash buckets (2^2=4) and buckets will be checked one by one every 2s (8/4=2). + + +Each registrant has it's own state. +Registrant's status can be inspected via "reg_list" MI comand. + + +UAC registrant states: + + +- *0* + - NOT_REGISTERED_STATE - +the initial state (no REGISTER has been sent out yet); +- *1* + - REGISTERING_STATE - waiting for a reply from the registrar +after a REGISTER without authentication header was sent; +- *2* + - AUTHENTICATING_STATE - waiting for a reply from the registrar +after a REGISTER with authentication header was sent; +- *3* + - REGISTERED_STATE - the uac is successfully registered; +- *4* + - REGISTER_TIMEOUT_STATE : +no reply received from the registrar; +- *5* + - INTERNAL_ERROR_STATE - +some errors were found/encountered during the +processing of a reply; +- *6* + - WRONG_CREDENTIALS_STATE - +credentials rejected by the registrar; +- *7* + - REGISTRAR_ERROR_STATE - +error reply received from the registrar; +- *8* + - UNREGISTERING_STATE - waiting for a reply from the registrar +after an unREGISTER without authentication header was sent; +- *9* + - AUTHENTICATING_UNREGISTER_STATE - waiting for a reply from the registrar +after an unREGISTER with authentication header was sent; + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *uac_auth - UAC authentication module* + + +#### External Libraries or Applications + + +None. + + +### Exported Parameters + + +#### hash_size (integer) + + +The size of the hash table internally used to keep the registrants. +A larger table distributes better the registration load in time but consumes more memory. +The hash size is a power of number two. + + +*Default value is 1.* + + +```opensips title="Set hash_size parameter" +... +modparam("uac_registrant", "hash_size", 2) +... +``` + + +#### timer_interval (integer) + + +Defines the periodic timer for checking the registrations status. + + +*Default value is 100.* + + +```opensips title="Set timer_interval parameter" +... +modparam("uac_registrant", "timer_interval", 120) +... +``` + + +#### failure_retry_interval (integer) + + +Defines a custom interval to retry the registration upon error/failure. +Normally, after any kind of failure (timeout, credentials, internal +error), the registration is re-taken after "expires" seconds. The +parameter here, if set, overrides that value. + + +*Default value is 0 (not set).* + + +```opensips title="Set failure_retry_interval parameter" +... +modparam("uac_registrant", "failure_retry_interval", 3600) +... +``` + + +#### enable_clustering (integer) + + +This parameter enables the clustering support in the module. This is +used to share this registration between all the nodes in the cluster. +When using this option, you should define (for each registrant record) +a sharing tag - this sharing tag will control at the cluster level +which node is entitled to perform the registation (only the node having +that tag as active will do the registation, the onther nodes being +idle). + + +*Default value is 0 / off.* + + +```opensips title="Set enable_clustering parameter" +... +modparam("uac_registrant", "enable_clustering", 1) +... +``` + + +#### db_url (string) + + +Database where to load the registrants from. + + +*Default value is "NULL" (use default DB URL from core).* + + +```opensips title="Set 'db_url' parameter" +... +modparam("uac_registrant", "db_url", "mysql://user:passw@localhost/database") +... +``` + + +#### table_name (string) + + +The database table that holds the registrant records. + + +*Default value is "registrant".* + + +```opensips title="Set 'table_name' parameter" +... +modparam("uac_registrant", "table_name", "my_registrant") +... +``` + + +#### registrar_column (string) + + +The column's name in the database storing the +URI pointing to the remote registrar (mandatory field). +OpenSIPS expects a valid URI. + + +*Default value is "registrar".* + + +```opensips title="Set 'registrar_column' parameter" +... +modparam("uac_registrant", "registrar_column", "registrant_uri") +... +``` + + +#### proxy_column (string) + + +The column's name in the database storing the +URI pointing to the outbond proxy (not mandatory field). +An empty or NULL value means no outbound proxy, +otherwise OpenSIPS expects a valid URI. + + +*Default value is "proxy".* + + +```opensips title="Set 'proxy_column' parameter" +... +modparam("uac_registrant", "proxy_column", "proxy_uri") +... +``` + + +#### aor_column (string) + + +The column's name in the database storing the +URI defining the address of record (mandatory field). +The URI stored here will be used in the To URI of the REGISTER. +OpenSIPS expects a valid URI. + + +*Default value is "aor".* + + +```opensips title="Set 'aor_column' parameter" +... +modparam("uac_registrant", "aor_column", "to_uri") +... +``` + + +#### third_party_registrant_column (string) + + +The column's name in the database storing the +URI defining the third party registrant (not mandatory field). +The URI stored here will be used in the From URI of the REGISTER. +An empty or NULL value means no third party registration +(the From URI will be identical to To URI), +otherwise OpenSIPS expects a valid URI. + + +*Default value is "third_party_registrant".* + + +```opensips title="Set 'third_party_registrant_column' parameter" +... +modparam("uac_registrant", "third_party_registrant_column", "from_uri") +... +``` + + +#### username_column (string) + + +The column's name in the database storing the +username for authentication (mandatory if the registrar requires authentication). + + +*Default value is "username".* + + +```opensips title="Set 'username_column' parameter" +... +modparam("uac_registrant", "username_column", "auth_username") +... +``` + + +#### password_column (string) + + +The column's name in the database storing the +password for authentication (mandatory if the registrar requires authntication). + + +*Default value is "password".* + + +```opensips title="Set 'password_column' parameter" +... +modparam("uac_registrant", "password_column", "auth_passowrd") +... +``` + + +#### binding_URI_column (string) + + +The column's name in the database storing the +binding URI in REGISTER (mandatory field). +The URI stored here will be used in the Contact URI of the REGISTER. +OpenSIPS expects a valid URI. + + +*Default value is "binding_URI".* + + +```opensips title="Set 'binding_URI_column' parameter" +... +modparam("uac_registrant", "binding_URI_column", "contact_uri") +... +``` + + +#### binding_params_column (string) + + +The column's name in the database storing the +binding params in REGISTER (not mandatory field). +If not NULL or not empty, the string stored here will be added +as params to the Contact URI in REGISTER (it MUST start with ";". + + +If the following two params are present, then the binding will be enforced +to be unique (if two bindings are received in a 200ok, a complete binding +removal will be performed before re-registering): + + +- *reg-id* +- *+sip.instance* + + +Example of params that will force unique binding: + + +```c +;reg-id=1;+sip.instance="" + +``` + + +*Default value is "binding_params".* + + +```opensips title="Set 'binding_params_column' parameter" +... +modparam("uac_registrant", "binding_params_column", "contact_params") +... +``` + + +#### expiry_column (string) + + +The column's name in the database storing the +expiration time (not mandatory). + + +*Default value is "expiry".* + + +```opensips title="Set 'expiry_column' parameter" +... +modparam("uac_registrant", "expiry_column", "registration_timeout") +... +``` + + +#### forced_socket_column (string) + + +The column's name in the database storing the +socket for sending the REGISTER (not mandatory). +If a forced socket is provided, the socket MUST be +explicitely set as a global listening socket in the config +(see "listen" core parameter). + + +*Default value is "forced_socket".* + + +```opensips title="Set 'forced_socket_column' parameter" +... +modparam("uac_registrant", "forced_socket_column", "fs") +... +``` + + +#### cluster_shtag_column (string) + + +The column's name in the database storing the +cluster sharing tag in [tag_name/cluster_id] format (not mandatory). +If a cluster sharing tag is provided, the REGISTER requests will +be fired out only when the tag is active. + + +*Default value is "cluster_shtag".* + + +```opensips title="Set 'cluster_shtag_column' parameter" +... +modparam("uac_registrant", "cluster_shtag_column", "sh") +... +``` + + +#### state_column (string) + + +The column's name in the database storing the current state of the +registrant. When a registrant is disabled, OpenSIPS will no longer send +REGISTERs for it. A value of *0* for this column means +enabled and *1* disabled. + + +*Default value is "state".* + + +```opensips title="Set 'state_column' parameter" +... +modparam("uac_registrant", "state_column", "status") +... +``` + + +### Exported Functions + + +None to be used in configuration file. + + +### Exported MI Functions + + +#### reg_list + + +Lists the registrant records and their status. + + +Name: *reg_list* + + +Parameters: + + +- *aor* (optional) - URI defining the address +of record. If provided, *contact* and +*registrar* parameters are also required and +only a specific record will be listed. +- *contact* (optional) - Contact URI. If +provided, +*aor* and *registrar* +parameters are also required and only a specific record will +be listed. +- *registrar* (optional) - URI pointing to the +remote registrar. If provided, *aor* and +*contact* parameters are also required and +only a specific record will be listed. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi reg_list +... +opensips-cli -x mi reg_list sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org +``` + + +#### reg_reload + + +Reloads the registrant records from the database. + + +Name: *reg_reload* + + +Parameters: *none* + + +- *aor* (optional) - URI defining the address +of record. If provided, *contact* and +*registrar* parameters are also required and +only a specific record will be reloaded. +- *contact* (optional) - Contact URI. If +provided, +*aor* and *registrar* +parameters are also required and only a specific record will +be reloaded. +- *registrar* (optional) - URI pointing to the +remote registrar. If provided, *aor* and +*contact* parameters are also required and +only a specific record will be reloaded. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi reg_reload +... +opensips-cli -x mi reg_leload sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org +``` + + +#### reg_enable + + +Enables a specific registrant. OpenSIPS will immediately send +a REGISTER if the registrant was previously disabled and will update +the state in the database. + + +Name: *reg_enable* + + +Parameters: *none* + + +- *aor* - URI defining the address of record. +- *contact* - Contact URI. +- *registrar* - URI pointing to the remote registrar. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi reg_enable sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org +``` + + +#### reg_disable + + +Disables a specific registrant. OpenSIPS will immediately send +an unREGISTER if the registrant was previously enabled and will update +the state in the database. + + +Name: *reg_disable* + + +Parameters: *none* + + +- *aor* - URI defining the address +of record. If provided, *contact* and +*registrar* parameters are also required and +only a specific record will be disabled. +- *contact* - Contact URI. If provided, +*aor* and *registrar* +parameters are also required and only a specific record will +be disabled. +- *registrar* - URI pointing to the remote +registrar. If provided, *aor* and +*contact* parameters are also required and +only a specific record will be disabled. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi reg_disable sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org +``` + + +#### reg_force_register + + +Forces the re-registration (or registation) of a specific +registrant (depending on its state). Note that the registrant must be +enabled. + + +Name: *reg_force_register* + + +Parameters: + + +- *aor* - URI defining the address +of record. If provided, *contact* and +*registrar* parameters are also required and +only a specific record will be forced to re-register. +- *contact* - Contact URI. If provided, +*aor* and *registrar* +parameters are also required and only a specific record will be +forced to re-register. +- *registrar* - URI pointing to the remote +registrar. If provided, *aor* and +*contact* parameters are also required and +only a specific record will be forced to re-register. + + +MI FIFO Command Format: + + +```bash +opensips-cli -x mi reg_force_register sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/uac_registrant/doc/contributors.xml b/modules/uac_registrant/doc/contributors.xml deleted file mode 100644 index eb32f400116..00000000000 --- a/modules/uac_registrant/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Ovidiu Sas (@ovidiusas) - 143 - 41 - 5688 - 3268 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 18 - 13 - 451 - 49 - - - 3. - Liviu Chircu (@liviuchircu) - 17 - 14 - 57 - 68 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 16 - 7 - 732 - 118 - - - 5. - Razvan Crainea (@razvancrainea) - 11 - 9 - 26 - 36 - - - 6. - Nick Altmann (@nikbyte) - 5 - 3 - 43 - 4 - - - 7. - Maksym Sobolyev (@sobomax) - 5 - 3 - 20 - 16 - - - 8. - James Stanley - 4 - 2 - 21 - 14 - - - 9. - Vlad Paiu (@vladpaiu) - 4 - 2 - 6 - 3 - - - 10. - sagarmalam - 3 - 1 - 15 - 1 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), James Stanley, Peter Lemenkov (@lemenkov), okhowang(王沛文). - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Nick Altmann (@nikbyte) - Nov 2015 - Mar 2025 - - - 2. - okhowang(王沛文) - Jul 2024 - Jul 2024 - - - 3. - James Stanley - Dec 2023 - Jun 2024 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Dec 2012 - May 2024 - - - 5. - Ovidiu Sas (@ovidiusas) - Feb 2011 - Dec 2023 - - - 6. - Maksym Sobolyev (@sobomax) - Mar 2021 - Nov 2023 - - - 7. - James Stanley - Mar 2023 - Mar 2023 - - - 8. - Razvan Crainea (@razvancrainea) - Sep 2011 - Nov 2021 - - - 9. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jul 2021 - - - 10. - Walter Doekes (@wdoekes) - Apr 2021 - Apr 2021 - - - -
-All remaining contributors: sagarmalam, Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Vlad Paiu (@vladpaiu). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Bogdan-Andrei Iancu (@bogdan-iancu), Vlad Patrascu (@rvlad-patrascu), Ovidiu Sas (@ovidiusas), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu). -
- -
diff --git a/modules/uac_registrant/doc/uac_registrant.xml b/modules/uac_registrant/doc/uac_registrant.xml deleted file mode 100644 index 8a6d7c92a30..00000000000 --- a/modules/uac_registrant/doc/uac_registrant.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - UAC Registrant Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2011-2014 VoIP Embedded, Inc. - - - - diff --git a/modules/uac_registrant/doc/uac_registrant_admin.xml b/modules/uac_registrant/doc/uac_registrant_admin.xml deleted file mode 100644 index 80e98c845a3..00000000000 --- a/modules/uac_registrant/doc/uac_registrant_admin.xml +++ /dev/null @@ -1,692 +0,0 @@ - - - - - - &adminguide; - -
- Overview - - The module enable &osips; to register itself on a remote SIP registrar. - - - At startup, the registrant records are loaded into - a hash table in memory and a timer is started. - The hash index is computed over the AOR field. - - - The timer interval for checking records in a hash bucket is computed - by dividing the timer_interval module param by the number of hash buckets. - When the timer fires for the first time, the first hash bucket will be checked and - REGISTERs will be sent out for each record that is found. - On the next timeout fire, the second hash bucket will be checked and so on. - If the configured timer_interval module param is lower then the number of buckets, - the module will fail to start. - - - Example: setting the timer_interval module to 8 with a hash_size of 2, will result - in having 4 hash buckets (2^2=4) and buckets will be checked one by one every 2s (8/4=2). - - - Each registrant has it's own state. - Registrant's status can be inspected via "reg_list" MI comand. - - - UAC registrant states: - - - 0 - - NOT_REGISTERED_STATE - - the initial state (no REGISTER has been sent out yet); - - - 1 - - REGISTERING_STATE - waiting for a reply from the registrar - after a REGISTER without authentication header was sent; - - - 2 - - AUTHENTICATING_STATE - waiting for a reply from the registrar - after a REGISTER with authentication header was sent; - - - 3 - - REGISTERED_STATE - the uac is successfully registered; - - - 4 - - REGISTER_TIMEOUT_STATE : - no reply received from the registrar; - - - 5 - - INTERNAL_ERROR_STATE - - some errors were found/encountered during the - processing of a reply; - - - 6 - - WRONG_CREDENTIALS_STATE - - credentials rejected by the registrar; - - - 7 - - REGISTRAR_ERROR_STATE - - error reply received from the registrar; - - - 8 - - UNREGISTERING_STATE - waiting for a reply from the registrar - after an unREGISTER without authentication header was sent; - - - 9 - - AUTHENTICATING_UNREGISTER_STATE - waiting for a reply from the registrar - after an unREGISTER with authentication header was sent; - - - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - uac_auth - UAC authentication module - - - - -
- -
- External Libraries or Applications - None. -
-
- -
- Exported Parameters -
- <varname>hash_size</varname> (integer) - - The size of the hash table internally used to keep the registrants. - A larger table distributes better the registration load in time but consumes more memory. - The hash size is a power of number two. - - - - Default value is 1. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("uac_registrant", "hash_size", 2) -... - - -
- -
- <varname>timer_interval</varname> (integer) - - Defines the periodic timer for checking the registrations status. - - - - Default value is 100. - - - - Set <varname>timer_interval</varname> parameter - -... -modparam("uac_registrant", "timer_interval", 120) -... - - -
- -
- <varname>failure_retry_interval</varname> (integer) - - Defines a custom interval to retry the registration upon error/failure. - Normally, after any kind of failure (timeout, credentials, internal - error), the registration is re-taken after "expires" seconds. The - parameter here, if set, overrides that value. - - - - Default value is 0 (not set). - - - - Set <varname>failure_retry_interval</varname> parameter - -... -modparam("uac_registrant", "failure_retry_interval", 3600) -... - - -
- -
- <varname>enable_clustering</varname> (integer) - - This parameter enables the clustering support in the module. This is - used to share this registration between all the nodes in the cluster. - When using this option, you should define (for each registrant record) - a sharing tag - this sharing tag will control at the cluster level - which node is entitled to perform the registation (only the node having - that tag as active will do the registation, the onther nodes being - idle). - - - - Default value is 0 / off. - - - - Set <varname>enable_clustering</varname> parameter - -... -modparam("uac_registrant", "enable_clustering", 1) -... - - -
- -
- <varname>db_url</varname> (string) - - Database where to load the registrants from. - - - - Default value is NULL (use default DB URL from core). - - - - Set <quote>db_url</quote> parameter - -... -modparam("uac_registrant", "db_url", "mysql://user:passw@localhost/database") -... - - -
- -
- <varname>table_name</varname> (string) - - The database table that holds the registrant records. - - - - Default value is registrant. - - - - Set <quote>table_name</quote> parameter - -... -modparam("uac_registrant", "table_name", "my_registrant") -... - - -
-
- <varname>registrar_column</varname> (string) - - The column's name in the database storing the - URI pointing to the remote registrar (mandatory field). - &osips; expects a valid URI. - - - - Default value is registrar. - - - - Set <quote>registrar_column</quote> parameter - -... -modparam("uac_registrant", "registrar_column", "registrant_uri") -... - - -
-
- <varname>proxy_column</varname> (string) - - The column's name in the database storing the - URI pointing to the outbond proxy (not mandatory field). - An empty or NULL value means no outbound proxy, - otherwise &osips; expects a valid URI. - - - - Default value is proxy. - - - - Set <quote>proxy_column</quote> parameter - -... -modparam("uac_registrant", "proxy_column", "proxy_uri") -... - - -
-
- <varname>aor_column</varname> (string) - - The column's name in the database storing the - URI defining the address of record (mandatory field). - The URI stored here will be used in the To URI of the REGISTER. - &osips; expects a valid URI. - - - - Default value is aor. - - - - Set <quote>aor_column</quote> parameter - -... -modparam("uac_registrant", "aor_column", "to_uri") -... - - -
-
- <varname>third_party_registrant_column</varname> (string) - - The column's name in the database storing the - URI defining the third party registrant (not mandatory field). - The URI stored here will be used in the From URI of the REGISTER. - An empty or NULL value means no third party registration - (the From URI will be identical to To URI), - otherwise &osips; expects a valid URI. - - - - Default value is third_party_registrant. - - - - Set <quote>third_party_registrant_column</quote> parameter - -... -modparam("uac_registrant", "third_party_registrant_column", "from_uri") -... - - -
-
- <varname>username_column</varname> (string) - - The column's name in the database storing the - username for authentication (mandatory if the registrar requires authentication). - - - - Default value is username. - - - - Set <quote>username_column</quote> parameter - -... -modparam("uac_registrant", "username_column", "auth_username") -... - - -
-
- <varname>password_column</varname> (string) - - The column's name in the database storing the - password for authentication (mandatory if the registrar requires authntication). - - - - Default value is password. - - - - Set <quote>password_column</quote> parameter - -... -modparam("uac_registrant", "password_column", "auth_passowrd") -... - - -
-
- <varname>binding_URI_column</varname> (string) - - The column's name in the database storing the - binding URI in REGISTER (mandatory field). - The URI stored here will be used in the Contact URI of the REGISTER. - &osips; expects a valid URI. - - - - Default value is binding_URI. - - - - Set <quote>binding_URI_column</quote> parameter - -... -modparam("uac_registrant", "binding_URI_column", "contact_uri") -... - - -
-
- <varname>binding_params_column</varname> (string) - - The column's name in the database storing the - binding params in REGISTER (not mandatory field). - If not NULL or not empty, the string stored here will be added - as params to the Contact URI in REGISTER (it MUST start with ;. - - - If the following two params are present, then the binding will be enforced - to be unique (if two bindings are received in a 200ok, a complete binding - removal will be performed before re-registering): - - reg-id - +sip.instance - - Example of params that will force unique binding: - -;reg-id=1;+sip.instance="<urn:uuid:11111111-AABBCCDDEEFF>" - - - - - Default value is binding_params. - - - - Set <quote>binding_params_column</quote> parameter - -... -modparam("uac_registrant", "binding_params_column", "contact_params") -... - - -
- -
- <varname>expiry_column</varname> (string) - - The column's name in the database storing the - expiration time (not mandatory). - - - - Default value is expiry. - - - - Set <quote>expiry_column</quote> parameter - -... -modparam("uac_registrant", "expiry_column", "registration_timeout") -... - - -
- -
- <varname>forced_socket_column</varname> (string) - - The column's name in the database storing the - socket for sending the REGISTER (not mandatory). - If a forced socket is provided, the socket MUST be - explicitely set as a global listening socket in the config - (see listen core parameter). - - - - Default value is forced_socket. - - - - Set <quote>forced_socket_column</quote> parameter - -... -modparam("uac_registrant", "forced_socket_column", "fs") -... - - -
- -
- <varname>cluster_shtag_column</varname> (string) - - The column's name in the database storing the - cluster sharing tag in [tag_name/cluster_id] format (not mandatory). - If a cluster sharing tag is provided, the REGISTER requests will - be fired out only when the tag is active. - - - - Default value is cluster_shtag. - - - - Set <quote>cluster_shtag_column</quote> parameter - -... -modparam("uac_registrant", "cluster_shtag_column", "sh") -... - - -
- -
- <varname>state_column</varname> (string) - - The column's name in the database storing the current state of the - registrant. When a registrant is disabled, OpenSIPS will no longer send - REGISTERs for it. A value of 0 for this column means - enabled and 1 disabled. - - - - Default value is state. - - - - Set <quote>state_column</quote> parameter - -... -modparam("uac_registrant", "state_column", "status") -... - - -
- -
- -
- Exported Functions - None to be used in configuration file. -
- -
- Exported MI Functions -
- <function moreinfo="none">reg_list</function> - Lists the registrant records and their status. - Name: reg_list - Parameters: - - - aor (optional) - URI defining the address - of record. If provided, contact and - registrar parameters are also required and - only a specific record will be listed. - - - contact (optional) - Contact URI. If - provided, - aor and registrar - parameters are also required and only a specific record will - be listed. - - - registrar (optional) - URI pointing to the - remote registrar. If provided, aor and - contact parameters are also required and - only a specific record will be listed. - - - MI FIFO Command Format: - -opensips-cli -x mi reg_list -... -opensips-cli -x mi reg_list sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org - -
-
- <function moreinfo="none">reg_reload</function> - Reloads the registrant records from the database. - Name: reg_reload - Parameters: none - - - aor (optional) - URI defining the address - of record. If provided, contact and - registrar parameters are also required and - only a specific record will be reloaded. - - - contact (optional) - Contact URI. If - provided, - aor and registrar - parameters are also required and only a specific record will - be reloaded. - - - registrar (optional) - URI pointing to the - remote registrar. If provided, aor and - contact parameters are also required and - only a specific record will be reloaded. - - - MI FIFO Command Format: - -opensips-cli -x mi reg_reload -... -opensips-cli -x mi reg_leload sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org - -
- -
- <function moreinfo="none">reg_enable</function> - Enables a specific registrant. OpenSIPS will immediately send - a REGISTER if the registrant was previously disabled and will update - the state in the database. - Name: reg_enable - Parameters: none - - - aor - URI defining the address of record. - - - contact - Contact URI. - - - registrar - URI pointing to the remote registrar. - - - MI FIFO Command Format: - -opensips-cli -x mi reg_enable sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org - -
- -
- <function moreinfo="none">reg_disable</function> - Disables a specific registrant. OpenSIPS will immediately send - an unREGISTER if the registrant was previously enabled and will update - the state in the database. - Name: reg_disable - Parameters: none - - - aor - URI defining the address - of record. If provided, contact and - registrar parameters are also required and - only a specific record will be disabled. - - - contact - Contact URI. If provided, - aor and registrar - parameters are also required and only a specific record will - be disabled. - - - registrar - URI pointing to the remote - registrar. If provided, aor and - contact parameters are also required and - only a specific record will be disabled. - - - MI FIFO Command Format: - -opensips-cli -x mi reg_disable sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org - -
- -
- <function moreinfo="none">reg_force_register</function> - Forces the re-registration (or registation) of a specific - registrant (depending on its state). Note that the registrant must be - enabled. - Name: reg_force_register - Parameters: - - - aor - URI defining the address - of record. If provided, contact and - registrar parameters are also required and - only a specific record will be forced to re-register. - - - contact - Contact URI. If provided, - aor and registrar - parameters are also required and only a specific record will be - forced to re-register. - - - registrar - URI pointing to the remote - registrar. If provided, aor and - contact parameters are also required and - only a specific record will be forced to re-register. - - - MI FIFO Command Format: - -opensips-cli -x mi reg_force_register sip:alice@opensips.org sip:alice@127.0.0.1:5060 sip:opensips.org - -
- -
-
- diff --git a/modules/uac_registrant/reg_records.c b/modules/uac_registrant/reg_records.c index 36b1ab38e79..7bc2a2efc06 100644 --- a/modules/uac_registrant/reg_records.c +++ b/modules/uac_registrant/reg_records.c @@ -38,12 +38,13 @@ int send_unregister(unsigned int hash_index, reg_record_t *rec, str *auth_hdr, unsigned int all_contacts); void reg_print_record(reg_record_t *rec) { - LM_DBG("checking uac=[%p] state=[%d][%.*s] expires=[%d]" + LM_DBG("checking uac=[%p] state=[%d][%.*s] expires=[%d/%d]" " last_register_sent=[%d] registration_timeout=[%d]" " auth_user[%p][%d]->[%.*s] auth_password=[%p][%d]->[%.*s]" " sock=[%p] clustering=[%.*s/%d] enabled=[%s]\n", rec, rec->state, - uac_reg_state[rec->state].len, uac_reg_state[rec->state].s, rec->expires, + uac_reg_state[rec->state].len, uac_reg_state[rec->state].s, + rec->expires, rec->wanted_expires, (unsigned int)rec->last_register_sent, (unsigned int)rec->registration_timeout, rec->auth_user.s, rec->auth_user.len, rec->auth_user.len, rec->auth_user.s, rec->auth_password.s, rec->auth_password.len, @@ -189,6 +190,7 @@ int add_record(uac_reg_map_t *uac, str *now, unsigned int mode, memset(record, 0, size); + record->wanted_expires = uac->expires; record->expires = uac->expires; td = &(record->td); diff --git a/modules/uac_registrant/reg_records.h b/modules/uac_registrant/reg_records.h index a7b35cf3af4..f70d1765748 100644 --- a/modules/uac_registrant/reg_records.h +++ b/modules/uac_registrant/reg_records.h @@ -84,6 +84,7 @@ typedef struct reg_record { str auth_user; str auth_password; unsigned int state; + unsigned int wanted_expires; unsigned int expires; time_t last_register_sent; time_t registration_timeout; diff --git a/modules/uac_registrant/registrant.c b/modules/uac_registrant/registrant.c index 9bce900d172..839503a8048 100644 --- a/modules/uac_registrant/registrant.c +++ b/modules/uac_registrant/registrant.c @@ -691,12 +691,15 @@ int run_reg_tm_cback(void *e_data, void *data, void *r_data) LM_ERR("FAKED_REPLY\n"); goto done; } - if (0 == parse_min_expires(msg)) { - rec->expires = (unsigned int)(long)msg->min_expires->parsed; - if(send_register(cb_param->hash_index, rec, NULL)==1) + /* do we have a Min-Expires with a resonable value (a shorter than + * 5 seconds registration is not considered resonable) */ + if (0 == parse_min_expires(msg) && 5<=(unsigned int)(long)msg->min_expires->parsed) { + rec->wanted_expires = (unsigned int)(long)msg->min_expires->parsed; + if(send_register(cb_param->hash_index, rec, NULL)==1) { rec->state = REGISTERING_STATE; - else + } else { rec->state = INTERNAL_ERROR_STATE; + } } else { rec->state = REGISTRAR_ERROR_STATE; rec->registration_timeout = now + (failure_retry_interval?failure_retry_interval:rec->expires) - timer_interval; @@ -795,7 +798,7 @@ int send_register(unsigned int hash_index, reg_record_t *rec, str *auth_hdr) cb_param->uac = rec; /* get the string version of expires */ - expires = int2str((unsigned long)(rec->expires), &expires_len); + expires = int2str((unsigned long)(rec->wanted_expires), &expires_len); p = extra_hdrs.s; memcpy(p, contact_hdr.s, contact_hdr.len); diff --git a/modules/userblacklist/README b/modules/userblacklist/README deleted file mode 100644 index 85339a75e71..00000000000 --- a/modules/userblacklist/README +++ /dev/null @@ -1,320 +0,0 @@ -userblacklist Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. db_url (string) - 1.3.2. db_table (string) - 1.3.3. use_domain (integer) - - 1.4. Exported Functions - - 1.4.1. check_user_blacklist (user, domain, [number], - [table]) - - 1.4.2. check_blacklist (table) - - 1.5. Exported MI Functions - - 1.5.1. reload_blacklist - - 1.6. Installation and Running - - 1.6.1. Database setup - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set db_table parameter - 1.3. Set use_domain parameter - 1.4. check_user_blacklist usage - 1.5. check_blacklist usage - 1.6. reload_blacklists usage - 1.7. Example database content - globalblacklist table - 1.8. Example database content - userblacklist table - -Chapter 1. Admin Guide - -1.1. Overview - - The userblacklist module allows OpenSIPS to handle blacklists - on a per user basis. This information is stored in a database - table, which is queried to decide if the number (more exactly, - the request URI user) is blacklisted or not. - - An additional functionality that this module provides is the - ability to handle global blacklists. This lists are loaded on - startup into memory, thus providing a better performance then - in the userblacklist case. This global blacklists are useful to - only allow calls to certain international destinations, i.e. - block all not whitelisted numbers. They could also used to - prevent the blacklisting of important numbers, as whitelisting - is supported too. This is useful for example to prevent the - customer from blocking emergency call number or service - hotlines. - - The module exports two functions, check_blacklist and - check_user_blacklist for usage in the config file. Furthermore - its provide a FIFO function to reload the global blacklist - cache. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - * database -- Any database module - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * none - -1.3. Exported Parameters - -1.3.1. db_url (string) - - Url to the database containing the routing data. - - Default value is - “mysql://opensipsro:opensipsro@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("userblacklist", "db_url", "dbdriver://username:password@dbhost -/dbname") -... - -1.3.2. db_table (string) - - Name of the table where the user blacklist data is stored. - - Default value is “userblacklist”. - - Example 1.2. Set db_table parameter -... -modparam("userblacklist", "db_table", "userblacklist") -... - -1.3.3. use_domain (integer) - - If set to non-zero value, the domain column in the - userblacklist is used. - - Default value is “0”. - - Example 1.3. Set use_domain parameter -... -modparam("userblacklist", "use_domain", 0) -... - -1.4. Exported Functions - -1.4.1. check_user_blacklist (user, domain, [number], [table]) - - Finds the longest prefix that matches the request URI user (or - the number parameter) for the given user and domain name in the - database. If a match is found and it is not set to whitelist, - false is returned. Otherwise, true is returned. The number - parameter can be used to check for example against the from URI - user. - - Parameters: - * user (string) - description - * domain (string) - description - * number (string, optional) - If ommited, the defalut is - used. - * table (string, optional) - If ommited, the defalut is used. - - Example 1.4. check_user_blacklist usage -... -if (!check_user_blacklist("user", "domain.com")) - sl_send_reply(403, "Forbidden"); - exit; -} -... - -1.4.2. check_blacklist (table) - - Finds the longest prefix that matches the request URI for the - given table. If a match is found and it is not set to - whitelist, false is returned. Otherwise, true is returned. - - Parameters: - * table (string) - - Example 1.5. check_blacklist usage -... -if (!check_blacklist("global_blacklist"))) - sl_send_reply(403, "Forbidden"); - exit; -} -... - -1.5. Exported MI Functions - -1.5.1. reload_blacklist - - Reload the internal global blacklist cache. This is necessary - after the database tables for the global blacklist have been - changed. - - Example 1.6. reload_blacklists usage -... -opensips-cli -x mi reload_blacklist -... - -1.6. Installation and Running - -1.6.1. Database setup - - Before running OpenSIPS with userblacklist, you have to setup - the database table where the module will read the blacklist - data. For that, if the table was not created by the - installation script or you choose to install everything by - yourself you can use the userblacklist-create.sql SQL script in - the database directories in the opensips/scripts folder as - template. Database and table name can be set with module - parameters so they can be changed, but the name of the columns - must be as they are in the SQL script. You can also find the - complete database documentation on the project webpage, - https://opensips.org/docs/db/db-schema-devel.html. - - Example 1.7. Example database content - globalblacklist table -... -+----+-----------+-----------+ -| id | prefix | whitelist | -+----+-----------+-----------+ -| 1 | | 0 | -| 2 | 1 | 1 | -| 3 | 123456 | 0 | -| 4 | 123455787 | 0 | -+----+-----------+-----------+ -... - - This table will setup a global blacklist for all numbers, only - allowing calls starting with “1”. Numbers that starting with - “123456” and “123455787” are also blacklisted, because the - longest prefix will be matched. - - Example 1.8. Example database content - userblacklist table -... -+----+----------------+-------------+-----------+-----------+ -| id | username | domain | prefix | whitelist | -+----+----------------+-------------+-----------+-----------+ -| 23 | 49721123456788 | | 1234 | 0 | -| 22 | 49721123456788 | | 123456788 | 1 | -| 21 | 49721123456789 | | 12345 | 0 | -| 20 | 494675231 | | 499034133 | 1 | -| 19 | 494675231 | test | 499034132 | 0 | -| 18 | 494675453 | test.domain | 49901 | 0 | -| 17 | 494675454 | | 49900 | 0 | -+----+----------------+-------------+-----------+-----------+ -... - - This table will setup user specific blacklists for certain - usernames. For example for user “49721123456788” the prefix - “1234” will be not allowed, but the number “123456788” is - allowed. Additionally a domain could be specified that is used - for username matching if the “use_domain” parameter is set. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Bogdan-Andrei Iancu (@bogdan-iancu) 18 16 55 53 - 2. Liviu Chircu (@liviuchircu) 13 11 38 55 - 3. Hardy Kahl 12 1 1191 0 - 4. Razvan Crainea (@razvancrainea) 10 8 17 12 - 5. Henning Westerholt (@henningw) 9 5 204 72 - 6. Daniel-Constantin Mierla (@miconda) 8 6 17 12 - 7. Vlad Patrascu (@rvlad-patrascu) 8 4 82 151 - 8. Maksym Sobolyev (@sobomax) 4 2 4 5 - 9. Ruslan Bukin 3 1 21 10 - 10. Julián Moreno Patiño 3 1 1 1 - - All remaining contributors: Peter Lemenkov (@lemenkov), - UnixDev, Vlad Paiu (@vladpaiu), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 2. Liviu Chircu (@liviuchircu) Mar 2014 - Jul 2020 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2008 - Mar 2020 - 4. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 5. Vlad Patrascu (@rvlad-patrascu) May 2017 - Apr 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Julián Moreno Patiño Feb 2016 - Feb 2016 - 8. Vlad Paiu (@vladpaiu) Apr 2011 - Apr 2011 - 9. Ruslan Bukin Oct 2009 - Oct 2009 - 10. UnixDev Feb 2009 - Feb 2009 - - All remaining contributors: Henning Westerholt (@henningw), - Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, - Hardy Kahl. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Edson Gellert Schubert, Hardy Kahl. - - Documentation Copyrights: - - Copyright © 2008 1&1 Internet AG diff --git a/modules/userblacklist/README.md b/modules/userblacklist/README.md new file mode 100644 index 00000000000..2fbd6b2e495 --- /dev/null +++ b/modules/userblacklist/README.md @@ -0,0 +1,257 @@ +--- +title: "userblacklist Module" +description: "The userblacklist module allows OpenSIPS to handle blacklists on a per user basis." +--- + +## Admin Guide + + +### Overview + + +The userblacklist module allows OpenSIPS to handle blacklists +on a per user basis. This information is stored in a database +table, which is queried to decide if the number (more exactly, +the request URI user) is blacklisted or not. + + +An additional functionality that this module provides is the ability +to handle global blacklists. This lists are loaded on startup into +memory, thus providing a better performance then in the userblacklist +case. This global blacklists are useful to only allow calls to certain +international destinations, i.e. block all not whitelisted numbers. +They could also used to prevent the blacklisting of important +numbers, as whitelisting is supported too. This is useful for example +to prevent the customer from blocking emergency call number or service +hotlines. + + +The module exports two functions, *check_blacklist* +and *check_user_blacklist* for usage in the config +file. Furthermore its provide a FIFO function to reload the global +blacklist cache. + + +### Dependencies + + +#### OpenSIPS Modules + + +The module depends on the following modules (in the other words +the listed modules must be loaded before this module): + + +- *database* -- Any database module + + +#### External Libraries or Applications + + +The following libraries or applications must be installed +before running OpenSIPS with this module loaded: + + +- *none* + + +### Exported Parameters + + +#### db_url (string) + + +Url to the database containing the routing data. + + +*Default value is "mysql://opensipsro:opensipsro@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("userblacklist", "db_url", "dbdriver://username:password@dbhost/dbname") +... + +``` + + +#### db_table (string) + + +Name of the table where the user blacklist data is stored. + + +*Default value is "userblacklist".* + + +```opensips title="Set db_table parameter" +... +modparam("userblacklist", "db_table", "userblacklist") +... + +``` + + +#### use_domain (integer) + + +If set to non-zero value, the domain column in the userblacklist is used. + + +*Default value is "0".* + + +```opensips title="Set use_domain parameter" +... +modparam("userblacklist", "use_domain", 0) +... + +``` + + +### Exported Functions + + +#### check_user_blacklist (user, domain, [number], [table]) + + +Finds the longest prefix that matches the request URI user (or the number +parameter) for the given user and domain name in the database. +If a match is found and it is not set to whitelist, false is returned. +Otherwise, true is returned. The number parameter can be used to check +for example against the from URI user. + + +Parameters: + + +- *user* (string) - description +- *domain* (string) - description +- *number* (string, optional) - If ommited, +the defalut is used. +- *table* (string, optional) - If ommited, +the defalut is used. + + +```opensips title="check_user_blacklist usage" +... +if (!check_user_blacklist("user", "domain.com")) + sl_send_reply(403, "Forbidden"); + exit; +} +... + +``` + + +#### check_blacklist (table) + + +Finds the longest prefix that matches the request URI for the +given table. If a match is found and it is not set to whitelist, +false is returned. Otherwise, true is returned. + + +Parameters: + + +- *table* (string) + + +```opensips title="check_blacklist usage" +... +if (!check_blacklist("global_blacklist"))) + sl_send_reply(403, "Forbidden"); + exit; +} +... + +``` + + +### Exported MI Functions + + +#### reload_blacklist + + +Reload the internal global blacklist cache. This is necessary after +the database tables for the global blacklist have been changed. + + +```bash title="reload_blacklists usage" +... +opensips-cli -x mi reload_blacklist +... + +``` + + +### Installation and Running + + +#### Database setup + + +Before running OpenSIPS with userblacklist, you have to setup the database +table where the module will read the blacklist data. For that, if +the table was not created by the installation script or you choose +to install everything by yourself you can use the userblacklist-create.sql +SQL script in the database directories in the +opensips/scripts folder as template. +Database and table name can be set with module parameters so they +can be changed, but the name of the columns must be as they are +in the SQL script. +You can also find the complete database documentation on the +project webpage, https://opensips.org/docs/db/db-schema-devel.html. + + +```c title="Example database content - globalblacklist table" +... ++----+-----------+-----------+ +| id | prefix | whitelist | ++----+-----------+-----------+ +| 1 | | 0 | +| 2 | 1 | 1 | +| 3 | 123456 | 0 | +| 4 | 123455787 | 0 | ++----+-----------+-----------+ +... + +``` + + +This table will setup a global blacklist for all numbers, only allowing calls +starting with "1". Numbers that starting with "123456" +and "123455787" are also blacklisted, because the longest prefix +will be matched. + + +```c title="Example database content - userblacklist table" +... ++----+----------------+-------------+-----------+-----------+ +| id | username | domain | prefix | whitelist | ++----+----------------+-------------+-----------+-----------+ +| 23 | 49721123456788 | | 1234 | 0 | +| 22 | 49721123456788 | | 123456788 | 1 | +| 21 | 49721123456789 | | 12345 | 0 | +| 20 | 494675231 | | 499034133 | 1 | +| 19 | 494675231 | test | 499034132 | 0 | +| 18 | 494675453 | test.domain | 49901 | 0 | +| 17 | 494675454 | | 49900 | 0 | ++----+----------------+-------------+-----------+-----------+ +... + +``` + + +This table will setup user specific blacklists for certain usernames. For example +for user "49721123456788" the prefix "1234" will be not +allowed, but the number "123456788" is allowed. Additionally a domain +could be specified that is used for username matching if the "use_domain" +parameter is set. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/userblacklist/doc/contributors.xml b/modules/userblacklist/doc/contributors.xml deleted file mode 100644 index 1e988d6e0ae..00000000000 --- a/modules/userblacklist/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Bogdan-Andrei Iancu (@bogdan-iancu) - 18 - 16 - 55 - 53 - - - 2. - Liviu Chircu (@liviuchircu) - 13 - 11 - 38 - 55 - - - 3. - Hardy Kahl - 12 - 1 - 1191 - 0 - - - 4. - Razvan Crainea (@razvancrainea) - 10 - 8 - 17 - 12 - - - 5. - Henning Westerholt (@henningw) - 9 - 5 - 204 - 72 - - - 6. - Daniel-Constantin Mierla (@miconda) - 8 - 6 - 17 - 12 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - 8 - 4 - 82 - 151 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 4 - 5 - - - 9. - Ruslan Bukin - 3 - 1 - 21 - 10 - - - 10. - Julián Moreno Patiño - 3 - 1 - 1 - 1 - - - -
-All remaining contributors: Peter Lemenkov (@lemenkov), UnixDev, Vlad Paiu (@vladpaiu), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 2. - Liviu Chircu (@liviuchircu) - Mar 2014 - Jul 2020 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2008 - Mar 2020 - - - 4. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 5. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Apr 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Julián Moreno Patiño - Feb 2016 - Feb 2016 - - - 8. - Vlad Paiu (@vladpaiu) - Apr 2011 - Apr 2011 - - - 9. - Ruslan Bukin - Oct 2009 - Oct 2009 - - - 10. - UnixDev - Feb 2009 - Feb 2009 - - - -
-All remaining contributors: Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Hardy Kahl. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Edson Gellert Schubert, Hardy Kahl. -
- -
diff --git a/modules/userblacklist/doc/userblacklist.xml b/modules/userblacklist/doc/userblacklist.xml deleted file mode 100644 index d9aa9999380..00000000000 --- a/modules/userblacklist/doc/userblacklist.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - userblacklist Module - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2008 1&1 Internet AG - diff --git a/modules/userblacklist/doc/userblacklist_admin.xml b/modules/userblacklist/doc/userblacklist_admin.xml deleted file mode 100644 index 4645df317f2..00000000000 --- a/modules/userblacklist/doc/userblacklist_admin.xml +++ /dev/null @@ -1,280 +0,0 @@ - - &adminguide; - -
- Overview - - The userblacklist module allows OpenSIPS to handle blacklists - on a per user basis. This information is stored in a database - table, which is queried to decide if the number (more exactly, - the request URI user) is blacklisted or not. - - - An additional functionality that this module provides is the ability - to handle global blacklists. This lists are loaded on startup into - memory, thus providing a better performance then in the userblacklist - case. This global blacklists are useful to only allow calls to certain - international destinations, i.e. block all not whitelisted numbers. - They could also used to prevent the blacklisting of important - numbers, as whitelisting is supported too. This is useful for example - to prevent the customer from blocking emergency call number or service - hotlines. - - - The module exports two functions, check_blacklist - and check_user_blacklist for usage in the config - file. Furthermore its provide a FIFO function to reload the global - blacklist cache. - -
- -
- Dependencies -
- &osips; Modules - - The module depends on the following modules (in the other words - the listed modules must be loaded before this module): - - - - database -- Any database module - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed - before running &osips; with this module loaded: - - - - none - - -
-
- - -
- Exported Parameters -
- <varname>db_url</varname> (string) - - Url to the database containing the routing data. - - - - Default value is &defaultrodb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("userblacklist", "db_url", "&exampledb;") -... - - -
- -
- <varname>db_table</varname> (string) - - Name of the table where the user blacklist data is stored. - - - - Default value is userblacklist. - - - - Set <varname>db_table</varname> parameter - -... -modparam("userblacklist", "db_table", "userblacklist") -... - - -
- -
- <varname>use_domain</varname> (integer) - - If set to non-zero value, the domain column in the userblacklist is used. - - - - Default value is 0. - - - - Set <varname>use_domain</varname> parameter - -... -modparam("userblacklist", "use_domain", 0) -... - - -
-
-
- Exported Functions -
- - <function moreinfo="none">check_user_blacklist (user, domain, [number], [table])</function> - - - Finds the longest prefix that matches the request URI user (or the number - parameter) for the given user and domain name in the database. - If a match is found and it is not set to whitelist, false is returned. - Otherwise, true is returned. The number parameter can be used to check - for example against the from URI user. - - Parameters: - - - user (string) - description - - - domain (string) - description - - - number (string, optional) - If ommited, - the defalut is used. - - - table (string, optional) - If ommited, - the defalut is used. - - - - <function>check_user_blacklist</function> usage - -... -if (!check_user_blacklist("user", "domain.com")) - sl_send_reply(403, "Forbidden"); - exit; -} -... - - -
-
- - <function moreinfo="none">check_blacklist (table)</function> - - - Finds the longest prefix that matches the request URI for the - given table. If a match is found and it is not set to whitelist, - false is returned. Otherwise, true is returned. - - Parameters: - - - table (string) - - - - <function>check_blacklist</function> usage - -... -if (!check_blacklist("global_blacklist"))) - sl_send_reply(403, "Forbidden"); - exit; -} -... - - -
-
- -
- Exported MI Functions -
- - <function moreinfo="none">reload_blacklist</function> - - - Reload the internal global blacklist cache. This is necessary after - the database tables for the global blacklist have been changed. - - - <function>reload_blacklists</function> usage - -... -opensips-cli -x mi reload_blacklist -... - - -
-
-
- Installation and Running -
- Database setup - - Before running &osips; with userblacklist, you have to setup the database - table where the module will read the blacklist data. For that, if - the table was not created by the installation script or you choose - to install everything by yourself you can use the userblacklist-create.sql - SQL script in the database directories in the - opensips/scripts folder as template. - Database and table name can be set with module parameters so they - can be changed, but the name of the columns must be as they are - in the SQL script. - You can also find the complete database documentation on the - project webpage, &osipsdbdocs;. - - - - Example database content - globalblacklist table - -... -+----+-----------+-----------+ -| id | prefix | whitelist | -+----+-----------+-----------+ -| 1 | | 0 | -| 2 | 1 | 1 | -| 3 | 123456 | 0 | -| 4 | 123455787 | 0 | -+----+-----------+-----------+ -... - - - - This table will setup a global blacklist for all numbers, only allowing calls - starting with 1. Numbers that starting with 123456 - and 123455787 are also blacklisted, because the longest prefix - will be matched. - - - - Example database content - userblacklist table - -... -+----+----------------+-------------+-----------+-----------+ -| id | username | domain | prefix | whitelist | -+----+----------------+-------------+-----------+-----------+ -| 23 | 49721123456788 | | 1234 | 0 | -| 22 | 49721123456788 | | 123456788 | 1 | -| 21 | 49721123456789 | | 12345 | 0 | -| 20 | 494675231 | | 499034133 | 1 | -| 19 | 494675231 | test | 499034132 | 0 | -| 18 | 494675453 | test.domain | 49901 | 0 | -| 17 | 494675454 | | 49900 | 0 | -+----+----------------+-------------+-----------+-----------+ -... - - - - This table will setup user specific blacklists for certain usernames. For example - for user 49721123456788 the prefix 1234 will be not - allowed, but the number 123456788 is allowed. Additionally a domain - could be specified that is used for username matching if the use_domain - parameter is set. - -
-
-
diff --git a/modules/usrloc/README b/modules/usrloc/README deleted file mode 100644 index 2101b2de19d..00000000000 --- a/modules/usrloc/README +++ /dev/null @@ -1,1799 +0,0 @@ -usrloc Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Distributed SIP User Location - - 1.2.1. "Federation" Topology - 1.2.2. "Full Sharing" Topology - 1.2.3. "N Contact Pings" Problem - - 1.3. Contact matching - 1.4. Dependencies - - 1.4.1. OpenSIPS Modules - 1.4.2. External Libraries or Applications - - 1.5. Exported Parameters - - 1.5.1. nat_bflag (string) - 1.5.2. contact_id_column (string) - 1.5.3. user_column (string) - 1.5.4. domain_column (string) - 1.5.5. contact_column (string) - 1.5.6. expires_column (string) - 1.5.7. q_column (string) - 1.5.8. callid_column (string) - 1.5.9. cseq_column (string) - 1.5.10. methods_column (string) - 1.5.11. flags_column (string) - 1.5.12. cflags_column (string) - 1.5.13. user_agent_column (string) - 1.5.14. received_column (string) - 1.5.15. socket_column (string) - 1.5.16. path_column (string) - 1.5.17. sip_instance_column (string) - 1.5.18. kv_store_column (string) - 1.5.19. attr_column (string) - 1.5.20. use_domain (integer) - 1.5.21. desc_time_order (integer) - 1.5.22. timer_interval (integer) - 1.5.23. db_url (string) - 1.5.24. cachedb_url (string) - 1.5.25. db_mode (integer, deprecated) - 1.5.26. working_mode_preset (string) - 1.5.27. cluster_mode (string) - 1.5.28. restart_persistency (string) - 1.5.29. sql_write_mode (string) - 1.5.30. matching_mode (integer) - 1.5.31. cseq_delay (integer) - 1.5.32. location_cluster (integer) - 1.5.33. ha_cluster (integer) - 1.5.34. ha_shtag (string) - 1.5.35. skip_replicated_db_ops (int) - 1.5.36. max_contact_delete (int) - 1.5.37. hash_size (integer) - 1.5.38. regen_broken_contactid (integer) - 1.5.39. latency_event_min_us (integer) - 1.5.40. latency_event_min_us_delta (integer) - 1.5.41. pinging_mode (string) - 1.5.42. mi_dump_kv_store (integer) - 1.5.43. contact_refresh_timer (boolean) - - 1.6. Exported Functions - - 1.6.1. ul_add_key(domain, aor, key_name, - [key_value]) - - 1.6.2. ul_get_key(domain, aor, key_name, - destination) - - 1.6.3. ul_del_key(domain, aor, key_name) - - 1.7. Exported MI Functions - - 1.7.1. ul_rm - 1.7.2. ul_rm_contact - 1.7.3. ul_dump - 1.7.4. ul_flush - 1.7.5. ul_add - 1.7.6. ul_show_contact - 1.7.7. ul_sync - 1.7.8. ul_cluster_sync - - 1.8. Exported Statistics - - 1.8.1. users - 1.8.2. contacts - 1.8.3. expires - 1.8.4. registered_users - - 1.9. Exported Events - - 1.9.1. E_UL_AOR_INSERT - 1.9.2. E_UL_AOR_DELETE - 1.9.3. E_UL_CONTACT_INSERT - 1.9.4. E_UL_CONTACT_DELETE - 1.9.5. E_UL_CONTACT_UPDATE - 1.9.6. E_UL_CONTACT_REFRESH - 1.9.7. E_UL_LATENCY_UPDATE - - 2. Developer Guide - - 2.1. Available Functions - - 2.1.1. ul_register_domain(name) - 2.1.2. ul_insert_urecord(domain, aor, rec, - is_replicated) - - 2.1.3. ul_delete_urecord(domain, aor, is_replicated) - - 2.1.4. ul_get_urecord(domain, aor) - 2.1.5. ul_lock_udomain(domain) - 2.1.6. ul_unlock_udomain(domain) - 2.1.7. ul_release_urecord(record, is_replicated) - 2.1.8. ul_insert_ucontact(record, contact, - contact_info, contact, is_replicated) - - 2.1.9. ul_delete_ucontact (record, contact, - is_replicated) - - 2.1.10. ul_delete_ucontact_from_id (domain, - contact_id) - - 2.1.11. ul_get_ucontact(record, contact) - 2.1.12. ul_get_domain_ucontacts (domain, buf, len, - flags) - - 2.1.13. ul_get_all_ucontacts (buf, len, flags) - 2.1.14. ul_update_ucontact(record, contact, - contact_info, is_replicated) - - 2.1.15. ul_bind_ursloc( api ) - 2.1.16. ul_register_ulcb(type ,callback, param) - 2.1.17. ul_get_num_users() - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 1.1. Possible values for the "pinging_mode", depending on the - current "cluster_mode" - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set nat_bflag parameter - 1.2. Set contact_id_column parameter - 1.3. Set user_column parameter - 1.4. Set user_column parameter - 1.5. Set contact_column parameter - 1.6. Set expires_column parameter - 1.7. Set q_column parameter - 1.8. Set callid_column parameter - 1.9. Set cseq_column parameter - 1.10. Set methods_column parameter - 1.11. Set flags_column parameter - 1.12. Set cflags_column parameter - 1.13. Set user_agent_column parameter - 1.14. Set received_column parameter - 1.15. Set socket_column parameter - 1.16. Set path_column parameter - 1.17. Set sip_instance_column parameter - 1.18. Set kv_store_column parameter - 1.19. Set attr_column parameter - 1.20. Set use_domain parameter - 1.21. Set desc_time_order parameter - 1.22. Set timer_interval parameter - 1.23. Set db_url parameter - 1.24. Set cachedb_url parameter - 1.25. Set db_mode parameter - 1.26. Set working_mode_preset parameter - 1.27. Set cluster_mode parameter - 1.28. Set restart_persistency parameter - 1.29. Set sql_write_mode parameter - 1.30. Set matching_mode parameter - 1.31. Set cseq_delay parameter - 1.32. Setting the location_cluster parameter - 1.33. Setting the ha_cluster parameter - 1.34. Setting the ha_shtag parameter - 1.35. Setting the skip_replicated_db_ops parameter - 1.36. Setting the max_contact_delete parameter - 1.37. Set hash_size parameter - 1.38. Set regen_broken_contactid parameter - 1.39. Set latency_event_min_us parameter - 1.40. Set latency_event_min_us_delta parameter - 1.41. Set pinging_mode parameter - 1.42. Set mi_dump_kv_store parameter - 1.43. Set contact_refresh_timer parameter - 1.44. ul_add_key usage - 1.45. ul_get_key usage - 1.46. ul_del_key usage - -Chapter 1. Admin Guide - -1.1. Overview - - A SIP user location implementation. Its main purpose is to - store, manage and provide access to SIP registration bindings - (contacts) for other modules (e.g. registrar, mid-registrar, - nathelper, etc.). The module exports no functions that could be - directly used from the OpenSIPS script. - - At runtime, the contacts may reside in memory, in an SQL - database or in a NoSQL database. Combinations of two of the - above are also possible. For example, contacts may only be - directly manipulated in memory in order to guarantee fast - interactions while being asynchronously synchronized to an SQL - database. The latter helps achieve restart persistency. Consult - the working_mode_preset parameter for more details on all - possible runtime behaviors of the module. - - The OpenSIPS user location implementation is cluster-enabled. - On top of supporting traditional "single instance" setups, it - also allows multiple OpenSIPS user location nodes to form a - single, global user location cluster. This allows high-level - features such as startup synchronization (data tunneling) from - a random, healthy "donor" node and evenly distributed NAT - pinging workloads. - -1.2. Distributed SIP User Location - - Starting with OpenSIPS 2.4, the user location module offers - several optional data distribution models, each tailoring to - specific real-life production use cases. Built on top of the - OpenSIPS clustering module, these models take into account - service concerns such as high availability, geographical - distribution, horizontal scalability and NAT traversal. - - Depending on data locality, the distribution models are split - in two main categories: - -1.2.1. "Federation" Topology - - A federated user location keeps contact data local to the - original OpenSIPS node the contact initially registered to. In - order to share the reachability of these contacts with the - global OpenSIPS user location cluster, registrar nodes will - only publish some light "metadata" entries for any new - Addresses-of-Record which are reachable from them. These - entries will cause other nodes to also fork additional SIP - branches pointing to the publisher registrar upon receiving - calls for its advertised Addresses-of-Record. - - The federation topology is an optimized solution for the - following core problems: - * IP address restrictions - In some cases, calls routed - towards registered contacts must necessarily pass through - the original registration nodes of these contacts. A - classic example of this situation is when an OpenSIPS - registrar sitting at the edge of the platform is directly - facing a NAT device on the way to the contact. Unless calls - are sent out from this exact registrar, they will not be - able to traverse the NAT device and reach the contact. - * horizontal scalability - Avoiding global - replication/contact broadcasting within the cluster not - only dramatically improves contact storage performance, but - also leads to better service scalability. Different - geographical locations can be sized according to their - local subscriber populations (traffic may be balanced to - them using DNS SRV weights, for example), without losing - platform-wide reachability. - - Currently, the metadata information may be published to NoSQL - databases which support key/multi-value column-like - associations. Example known backends to support these - abstractions at the time of writing are MongoDB and Cassandra. - - The federated user location tutorial contains precise details - on how to achieve this setup (including High Availability - support). - -1.2.2. "Full Sharing" Topology - - A fully sharing user location broadcasts contact information to - all data nodes (OpenSIPS or NoSQL). The main assumption behind - this mode is that any routing restrictions have been alleviated - beforehand. Consequently, either SIP traffic egressing from a - "full sharing" OpenSIPS user location topology is being - intermediated by an additional SIP edge endpoint of our - platform, or there are no egress IP restrictions at all (for - example, if all SIP UAs have public IPs). In this setup, all - OpenSIPS user location nodes are equivalent to one another, as - they each have access to the same dataset and have no routing - restrictions. - - The full sharing topology is an appropriate solution for - multi-layer VoIP platforms, where the OpenSIPS registrar nodes - do not directly interact with external SIP endpoints. Moreover, - it can be configured to fully store contact data within a NoSQL - cluster (zero in-memory storage), thus taking full advantage of - the data sharing, sharding, migration and other capabilities of - a specialized distributed data handling engine. - - Additionally, a "full sharing" topology can be used to achieve - a basic "hot backup" high-availability setup with an - active-passive registrar nodes configuration, both of which - make use of a shared virtual IP. - - Registrations may optionally be fully managed inside NoSQL - databases which support key/multi-value column-like - associations. Example known backends to currently support these - abstractions are MongoDB and Apache Cassandra. - - The "full sharing" user location tutorial contains precise - details on how to achieve this setup (including full NoSQL - storage support). - -1.2.3. "N Contact Pings" Problem - - A long-standing problem caused by contact information being - replicated to multiple SIP registrar instances directly through - replication or indirectly through a globally reachable - database. As long as traditionally clusterized nodes are not - aware of each other, they will each scan the entire contact - dataset, thus periodically sending "N pings" instead of "1 - ping" for each contact. This difference directly affects - service scalability, as well as the amount of consumed - resources such as CPU and network bandwidth, both on the - service and client side. - - This problem is solved with the help of the OpenSIPS cluster - layer, which makes all nodes aware of each others' presence. - Thus, the distributed user location node topologies are able to - collectively partition the pinging workload and spread it - evenly across the current number of cluster nodes, at any given - point in time. The pinging_mode module parameter describes the - built-in pinging heuristics in more detail. - -1.3. Contact matching - - Contact matching (for the same Address-of-Record, AoR) is an - important aspect of a SIP user location service, especially in - the context of NAT traversal. The latter raises more problems, - since contacts from different phones of same users may overlap - (if behind NATs with identical configurations) or the - re-register Contact of the same SIP User Agent may be seen as a - new one (due to the request arriving via a new NAT binding). - - The SIP RFC 3261 publishes a matching algorithm based only on - the contact string with Call-ID and CSeq number extra checking - (if the Call-ID matches, it must have a higher CSeq number, - otherwise the registration is invalid). But as argumented - above, this is not enough in a NAT traversal context, so the - OpenSIPS implementation of contact matching offers more - algorithms: - * Contact based only - strict RFC 3261 compliancy - the - contact is matched as string and extra checked via Call-ID - and CSeq (if Call-ID is the same, it must have a higher - CSeq number, otherwise the registration is invalid). - * Contact and Call-ID based - an extension of the first case - - the Contact and Call-ID header field values must match as - strings; the CSeq must be higher than the previous one - so - be careful how you deal with REGISTER retransmissions in - this case. - - For more details on how to control/select the contact matching - algorithm, please go to matching_mode. - -1.4. Dependencies - -1.4.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * Optionally an SQL database module. - * Optionally a NoSQL database module. - * clusterer, if cluster_mode is different than "none". - -1.4.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * None. - -1.5. Exported Parameters - -1.5.1. nat_bflag (string) - - The name of the branch flag to be used as NAT marker (if the - contact is or not natted). This is a branch flag and it will be - imported and used by all other modules depending on the usrloc - module. - - Default value is NULL (not set). - - Example 1.1. Set nat_bflag parameter -... -modparam("usrloc", "nat_bflag", "NAT_BFLAG") -... - -1.5.2. contact_id_column (string) - - Name of the column holding the unique contact IDs. - - Default value is “contact_id”. - - Example 1.2. Set contact_id_column parameter -... -modparam("usrloc", "contact_id_column", "ctid") -... - -1.5.3. user_column (string) - - Name of column containing usernames. - - Default value is “username”. - - Example 1.3. Set user_column parameter -... -modparam("usrloc", "user_column", "username") -... - -1.5.4. domain_column (string) - - Name of column containing domains. - - Default value is “domain”. - - Example 1.4. Set user_column parameter -... -modparam("usrloc", "domain_column", "domain") -... - -1.5.5. contact_column (string) - - Name of column containing contacts. - - Default value is “contact”. - - Example 1.5. Set contact_column parameter -... -modparam("usrloc", "contact_column", "contact") -... - -1.5.6. expires_column (string) - - Name of column containing expires value. - - Default value is “expires”. - - Example 1.6. Set expires_column parameter -... -modparam("usrloc", "expires_column", "expires") -... - -1.5.7. q_column (string) - - Name of column containing q values. - - Default value is “q”. - - Example 1.7. Set q_column parameter -... -modparam("usrloc", "q_column", "q") -... - -1.5.8. callid_column (string) - - Name of column containing callid values. - - Default value is “callid”. - - Example 1.8. Set callid_column parameter -... -modparam("usrloc", "callid_column", "callid") -... - -1.5.9. cseq_column (string) - - Name of column containing cseq numbers. - - Default value is “cseq”. - - Example 1.9. Set cseq_column parameter -... -modparam("usrloc", "cseq_column", "cseq") -... - -1.5.10. methods_column (string) - - Name of column containing supported methods. - - Default value is “methods”. - - Example 1.10. Set methods_column parameter -... -modparam("usrloc", "methods_column", "methods") -... - -1.5.11. flags_column (string) - - Name of column to save the internal flags of the record. - - Default value is “flags”. - - Example 1.11. Set flags_column parameter -... -modparam("usrloc", "flags_column", "flags") -... - -1.5.12. cflags_column (string) - - Name of column to save the branch/contact flags of the record. - - Default value is “cflags”. - - Example 1.12. Set cflags_column parameter -... -modparam("usrloc", "cflags_column", "cflags") -... - -1.5.13. user_agent_column (string) - - Name of column containing user-agent values. - - Default value is “user_agent”. - - Example 1.13. Set user_agent_column parameter -... -modparam("usrloc", "user_agent_column", "user_agent") -... - -1.5.14. received_column (string) - - Name of column containing the source IP, port, and protocol - from the REGISTER message. - - Default value is “received”. - - Example 1.14. Set received_column parameter -... -modparam("usrloc", "received_column", "received") -... - -1.5.15. socket_column (string) - - Name of column containing the received socket information - (IP:port) for the REGISTER message. - - Default value is “socket”. - - Example 1.15. Set socket_column parameter -... -modparam("usrloc", "socket_column", "socket") -... - -1.5.16. path_column (string) - - Name of column containing the Path header. - - Default value is “path”. - - Example 1.16. Set path_column parameter -... -modparam("usrloc", "path_column", "path") -... - -1.5.17. sip_instance_column (string) - - Name of column containing the SIP instance. - - Default value is “NULL”. - - Example 1.17. Set sip_instance_column parameter -... -modparam("usrloc", "sip_instance_column", "sip_instance") -... - -1.5.18. kv_store_column (string) - - Name of column containing generic key-value data. - - Default value is “kv_store”. - - Example 1.18. Set kv_store_column parameter -... -modparam("usrloc", "kv_store_column", "json_data") -... - -1.5.19. attr_column (string) - - Name of column containing additional registration-related - information. - - Default value is “attr”. - - Example 1.19. Set attr_column parameter -... -modparam("usrloc", "attr_column", "attributes") -... - -1.5.20. use_domain (integer) - - If the domain part of the user should be also saved and used - for identifing the user (along with the username part). Useful - in multi domain scenarios. Non 0 value means true. - - Default value is “0 (false)”. - - Example 1.20. Set use_domain parameter -... -modparam("usrloc", "use_domain", 1) -... - -1.5.21. desc_time_order (integer) - - If the user's contacts should be kept timestamp ordered; - otherwise the contact will be ordered based on q value. Non 0 - value means true. - - Default value is “0 (false)”. - - Example 1.21. Set desc_time_order parameter -... -modparam("usrloc", "desc_time_order", 1) -... - -1.5.22. timer_interval (integer) - - Number of seconds between two timer runs. During each run, the - module will update/delete dirty/expired contacts from memory - and/or mirror these operations to the database, if configured - to do so. - -Warning - - In case of an OpenSIPS shutdown or even a crash, contacts which - are in memory only and have not been flushed yet to disk will - NOT get lost! OpenSIPS will try its best to do a last-minute - sync to DB right before shutting down. - - Default value is 60. - - Example 1.22. Set timer_interval parameter -... -modparam("usrloc", "timer_interval", 120) -... - -1.5.23. db_url (string) - - URL of the database that should be used. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.23. Set db_url parameter -... -modparam("usrloc", "db_url", "dbdriver://username:password@dbhost/dbname -") -... - -1.5.24. cachedb_url (string) - - URL of a NoSQL database to be used. Only required in a - cachedb-enabled cluster_mode. - - Default value is “none”. - - Example 1.24. Set cachedb_url parameter -... -modparam("usrloc", "cachedb_url", "mongodb://10.0.0.4:27017/opensipsDB.u -serlocation") -... - -1.5.25. db_mode (integer, deprecated) - - This parameter has been kept for backwards compatibility. It - acts as a working_mode_preset (which it also conflicts with), - overriding any cluster_mode, restart_persistency and - sql_write_mode settings. Possible values are: - - * 0, corresponding to "single-instance-no-db" (see below) - * 1, corresponding to "single-instance-sql-write-through" - * 2, corresponding to "single-instance-sql-write-back" - * 3, corresponding to "sql-only" - - Default value is "not set". - - Example 1.25. Set db_mode parameter -... -modparam("usrloc", "db_mode", 2) -... - -1.5.26. working_mode_preset (string) - - A pre-defined working mode for the usrloc module. Setting this - parameter will override any cluster_mode, restart_persistency - and sql_write_mode settings. - - * "single-instance-no-db" - This disables database - completely. Only memory will be used. Contacts will not - survive restart. Use this value if you need a really fast - usrloc and contact persistence is not necessary or is - provided by other means. - * "single-instance-sql-write-through" - Write-Through scheme. - All changes to usrloc are immediately reflected in database - too. This is very slow, but very reliable. Use this scheme - if speed is not your priority but need to make sure that no - registered contacts will be lost during crash or reboot. - * "single-instance-sql-write-back" - Write-Back scheme. This - is a combination of previous two schemes. All changes are - made to memory and database synchronization is done in the - timer. The timer deletes all expired contacts and flushes - all modified or new contacts to database. Use this scheme - if you encounter high-load peaks and want them to process - as fast as possible. The mode will not help at all if the - load is high all the time. The added latency on the SIP - signaling when using this asynchronous preset is much lower - than the one added by the safe but blocking, - "single-instance-sql-write-through" preset. - * "sql-only" - DB-Only scheme. No memory cache is kept, all - operations being directly performed with the database. The - timer deletes all expired contacts from database - cleans - after clients that didn't un-register or re-register. The - mode is useful if you configure more servers sharing the - same DB without any replication at SIP level. The mode may - be slower due the high number of DB operation. For example - NAT pinging is a killer since during each ping cycle all - nated contact are loaded from the DB; The lack of memory - caching also disable the statistics exports. - * "federation-cachedb-cluster" - OpenSIPS will run with a - "federation-cachedb" cluster_mode and "sync-from-cluster" - restart_persistency. This will require the configuration of - multiple "seed" nodes in the cluster. Refer to the - federated user location tutorial for more details. - * "full-sharing-cluster" - OpenSIPS will run with a - "full-sharing" cluster_mode and "sync-from-cluster" - restart_persistency. This will require the configuration of - one of the nodes in the cluster as a "seed" node in order - to bootstrap the syncing process. - * "full-sharing-cachedb-cluster" - OpenSIPS will run with a - "full-sharing-cachedb" cluster_mode, where all location - data strictly resides in a NoSQL database, thus it will - have natural restart persistency. - - Refer to section Distributed SIP User Location for details - regarding the clustering topologies and their behavior. - - Default value is "single-instance-no-db". - - Example 1.26. Set working_mode_preset parameter -... -modparam("usrloc", "working_mode_preset", "full-sharing-cachedb-cluster" -) -... - -1.5.27. cluster_mode (string) - - This parameter will get overridden if either - working_mode_preset or db_mode is set. - - The behavior of the global OpenSIPS user location cluster. - Refer to section Distributed SIP User Location for details. - - This parameter may take the following values: - * "none" - single instance mode. - * "federation-cachedb" - federation-based data sharing. Local - AoR metadata is published inside a NoSQL database, so other - cluster nodes can fork SIP traffic over to the current - node. Consequently, the location_cluster and cachedb_url - parameters are mandatory. - * "full-sharing" - Broadcast contact updates (full-mesh - mirroring) to all other OpenSIPS cluster participants. Each - node will hold the entire user location dataset. - Consequently, the location_cluster parameter is mandatory. - * "full-sharing-cachedb" - Full contact data management - through the use of a NoSQL database (somewhat resembling - the "sql-only" preset). The cluster layer is still required - in order to be able to partition and spread the pinging - workload evenly among participating OpenSIPS nodes. - Consequently, the location_cluster and cachedb_url - parameters are mandatory. - * "sql-only" - Multiple OpenSIPS boxes using a common db_url - without necessarily being aware of each other. - - Default value is "none" (single instance mode). - - Example 1.27. Set cluster_mode parameter -... -modparam("usrloc", "cluster_mode", "federation-cachedb") -... - -1.5.28. restart_persistency (string) - - This parameter will get overridden if either - working_mode_preset or db_mode are set. - - Controls the behavior of the OpenSIPS user location following a - restart. This parameter has no effect in some database-only - working mode presets, where restart persistency is naturally - ensured. - - This parameter may take the following values: - * "none" - no explicit data synchronization following a - restart. The node starts empty. - * "load-from-sql" - enable SQL-based restart persistency. - This causes all runtime in-memory writes (i.e. new - registrations, re-registrations or de-registrations) to - also propagate to an SQL database, from which all data will - be imported following a restart. Choosing this value will - make the db_url parameter mandatory, as well as cause - sql_write_mode to default to "write-back" instead of - "none". - * "sync-from-cluster" - enable cluster-based restart - persistency. Following a restart, an OpenSIPS cluster node - will search for a healthy "donor" node from which to mirror - the entire user location dataset via direct cluster sync - (TCP-based, binary-encoded data transfer). Depending on the - clustering mode and cluster topology, this will require the - configuration of one or multiple "seed" nodes in the - cluster. Choosing this value will make the location_cluster - parameter mandatory. - - Default value is "none" (no restart persistency). - - Example 1.28. Set restart_persistency parameter -... -modparam("usrloc", "restart_persistency", "sync-from-cluster") -... - -1.5.29. sql_write_mode (string) - - This parameter will get overridden if either - working_mode_preset or db_mode are set. - - Only valid if restart_persistency is enabled. Controls the - runtime behavior of OpenSIPS writes to the SQL database. - - This parameter may take the following values: - * "none" - do not perform any additional SQL writes at - runtime to an SQL database in order to specifically ensure - restart persistency. - * "write-through" - all in-memory writes (i.e. new - registrations, re-registrations or de-registrations) also - propagate into the SQL database, inline. While this will - definitely slow down registration performance (lookups are - served from memory!), it has the advantage of making the - instance crash-safe. - * "write-back" - all in-memory writes (i.e. new - registrations, re-registrations or de-registrations) - eventually also propagate into the SQL database, thanks to - a separate timer routine. This dramatically speeds up - registrations, but also introduces the possibility of - crashing before the latest contact changes are propagated - to the database. See the timer_interval for additional - configuration. - - Default value is "none" (no added SQL writes). - - Example 1.29. Set sql_write_mode parameter -... -modparam("usrloc", "sql_write_mode", "write-back") -... - -1.5.30. matching_mode (integer) - - What contact matching algorithm to be used. Refer to section - Contact Matching for the description of the algorithms. - - The parameter may take the following values: - * 0 - CONTACT ONLY based matching algorithm. - * 1 - CONTACT and CALLID based matching algorithm. - - Default value is 0 (CONTACT_ONLY). - - Example 1.30. Set matching_mode parameter -... -modparam("usrloc", "matching_mode", 1) -... - -1.5.31. cseq_delay (integer) - - Delay (in seconds) for accepting as retransmissions register - requests with same Call-ID and Cseq. The delay is calculated - starting from the receiving time of the first register with - that Call-ID and Cseq. - - Retransmissions within this delay interval will be accepted and - replied as the original request, but no update will be done in - location. If the delay is exceeded, error is reported. - - A value of 0 disable the retransmission detection. - - Default value is “20 seconds”. - - Example 1.31. Set cseq_delay parameter -... -modparam("usrloc", "cseq_delay", 5) -... - -1.5.32. location_cluster (integer) - - Specifies the cluster ID which this instance will send to and - receive from all user-location related information - (addresses-of-record, contacts), organized into specific events - (inserts, deletes or updates). - - This OpenSIPS cluster exposes the "usrloc-contact-repl" - capability in order to mark nodes as eligible for becoming data - donors during an arbitrary sync request. Consequently, the - cluster must have at least one node marked with the "seed" - value as the clusterer.flags column/property in order to be - fully functional. Consult the clusterer - Capabilities chapter - for more details. - - Default value is 0 (replication disabled). - - More details on the user location distribution mechanisms are - available under Distributed SIP User Location. - - Example 1.32. Setting the location_cluster parameter -... -modparam("usrloc", "location_cluster", 1) -... - -1.5.33. ha_cluster (integer) - - Only relevant in "federation-cachedb" cluster_mode. Denotes the - HA cluster ID to use in order to establish the active node - within the HA pair, such that only that node performs WRITE - operations to CacheDB. - - Default value is 0 (disabled). - - Example 1.33. Setting the ha_cluster parameter -... -modparam("usrloc", "ha_cluster", 4) -... - -1.5.34. ha_shtag (string) - - Only relevant in "federation-cachedb" cluster_mode. Denotes the - HA cluster sharing tag to use in order to establish the active - node within the HA pair, such that only that node performs - WRITE operations to CacheDB. - - Default value is NULL (disabled). - - Example 1.34. Setting the ha_shtag parameter -... -modparam("usrloc", "ha_shtag", "vip2") -... - -1.5.35. skip_replicated_db_ops (int) - - Prevent OpenSIPS from performing any DB-related contact - operations when events are received over the Binary Interface. - This is commonly used to prevent unneeded duplicate operations. - - Default value is "0" (upon receival of usrloc-related Binary - Interface events, DB queries may be freely performed) - - More details on the user location replication mechanism are - available in Distributed SIP User Location - - Example 1.35. Setting the skip_replicated_db_ops parameter -... -modparam("usrloc", "skip_replicated_db_ops", 1) -... - -1.5.36. max_contact_delete (int) - - Relevant only in WRITE_THROUGH or WRITE_BACK schemes. The - maximum number of contacts to be deleted from the database at - once. Will delete all of them, if fewer after passing through - all the contacts. - - Default value is "10" - - Example 1.36. Setting the max_contact_delete parameter -... -modparam("usrloc", "max_contact_delete", 10) -... - -1.5.37. hash_size (integer) - - The number of entries of the hash table used by usrloc to store - the location records is 2^hash_size. For hash_size=4, the - number of entries of the hash table is 16. Since version 2.2, - the maximu size of this parameter is 16, meaning that the hash - supports maximum 65536 entries. - - Default value is “9”. - - Example 1.37. Set hash_size parameter -... -modparam("usrloc", "hash_size", 10) -... - -1.5.38. regen_broken_contactid (integer) - - Since version 2.2, contact_id concept was introduced. Since - this parameter validates a contact each time OpenSIPS is - started, there are times when the value of this parameter - should be regenerated. That is when location table is being - migrated from a version older than 2.2 or when hash_size module - parameter is changed. Enabling this parameter will regenerate - broken contact id's based on current configurations. - - Default value is “0(not enabled)” - - Example 1.38. Set regen_broken_contactid parameter -... -modparam("usrloc", "regen_broken_contactid", 1) -... - -1.5.39. latency_event_min_us (integer) - - Defines a minimal pinging latency threshold, in microseconds, - past which contact pinging latency update events will get - raised. By default, an event is raised for each ping reply - (i.e. latency update). - - If both latency_event_min_us and latency_event_min_us_delta are - set, the event will get raised if either of them is true. - - Default value is “0 (no bottom limit set)”. - - Example 1.39. Set latency_event_min_us parameter -... -# raise an event for any 425+ ms pinging latency -modparam("usrloc", "latency_event_min_us", 425000) -... - -1.5.40. latency_event_min_us_delta (integer) - - Defines a minimal, absolute pinging latency difference, in - microseconds, past which contact pinging latency update events - will get raised. The difference is computed using the latencies - of the last two contact pinging replies. By default, an event - is raised for each ping reply (i.e. latency update). - - If both latency_event_min_us and latency_event_min_us_delta are - set, the event will get raised if either of them is true. - - Default value is “0 (no minimal latency delta set)”. - - Example 1.40. Set latency_event_min_us_delta parameter -... -# raise an event only if a contact has pinging latency swings of 300+ ms -modparam("usrloc", "latency_event_min_us_delta", 300000) -... - -1.5.41. pinging_mode (string) - - Depending on the cluster_mode, the module can perform contact - pinging using one of two possible heuristics: - * "ownership" - this instance will only attempt to ping a - contact if it decides it is the logical owner of the - contact. If a shared tag is attached to a contact, a node - will keep sending pings to that contact as long as it owns - the respective tag. If no shared tag has been specified for - a given contact, the default is to assume permanent - ownership of the contact and ping it upon request. - * "cooperation" - the assumption behind this pinging - heuristic is that all user location cluster nodes are - symmetrical (possibly front-ended by a SIP traffic - balancing entity), such that either of them can ping any - contact. Under this assumption, all currently online user - location cluster nodes will cooperate and evenly split the - pinging workload between them by hashing AoRs modulo - current_number_of_online_nodes, and only picking the ones - that they are responsible for. - - Table 1.1. Possible values for the "pinging_mode", depending on - the current "cluster_mode" - cluster_mode none federation-cachedb full-sharing - full-sharing-cachedb sql-only - pinging_mode ownership ownership cooperation / ownership - cooperation unmaintained - - Notice that only the "full-sharing" clustering mode allows some - flexibility -- all other modes are logically tied to a single - pinging logic. Any unaccepted value, according to the above - table, set for those modes will be silently discarded. - - Example 1.41. Set pinging_mode parameter -... -# prepare an active/backup "full-sharing" setup, with no front-end -modparam("usrloc", "pinging_mode", "ownership") -... - -1.5.42. mi_dump_kv_store (integer) - - Enable in order to include the "KV-Store" field in all usrloc - MI commands which output AoR or Contact representations. This - verbose field contains custom data attached to each of these - two entities. mid_registrar makes use of both of these holders, - for example. - - Default value is “0 (disabled)”. - - Example 1.42. Set mi_dump_kv_store parameter -... -# include the "KV-Store" key in all usrloc MI output -modparam("usrloc", "mi_dump_kv_store", 1) -... - -1.5.43. contact_refresh_timer (boolean) - - Enable a timer which will periodically scan a sorted list of - contacts and raise the E_UL_CONTACT_REFRESH for any of them - which are past their re-registration time interval limit. This - limit may given by registrar's pn_trigger_interval module - parameter, for example. - - Default value is “false (disabled)”. - - Example 1.43. Set contact_refresh_timer parameter -... -modparam("usrloc", "contact_refresh_timer", true) -... - -1.6. Exported Functions - -1.6.1. ul_add_key(domain, aor, key_name, [key_value]) - - Append a Key/Value to the Key-Value-Store of a Usrloc-Record. - - Returns false, if no record is found is usrloc. - - Meaning of the parameters is as follows: - * domain (string) - Domain of the AOR, e.g. "location" - * aor (string) - Address-of-Record, save the key for a - specific (registered) user. - * key (string) - The name of the key to be stored. - * value (string, optional) - The value to be stored. Not - providing the value or by providing an empty value, will - delete the entry. - - This function can be used in ANY route. - - Example 1.44. ul_add_key usage -... -ul_add_key("location", "$tU@$td", "service_route", "$hdr(Service-Route)" -); -... - -1.6.2. ul_get_key(domain, aor, key_name, destination) - - Retrieve a Key/Value from the Key-Value-Store of a - Usrloc-Record. - - Returns false, if no record is found is usrloc or no according - key is found. - - Meaning of the parameters is as follows: - * domain (string) - Domain of the AOR, e.g. "location" - * aor (string) - Address-of-Record, save the key for a - specific (registered) user. - * key (string) - The name of the key to be retrieved. - * destination (variable) - A variable, where to store the - retrieved key. - - This function can be used in ANY route. - - Example 1.45. ul_get_key usage -... -if (ul_get_key("location", "$tU@$td", "service_route", $avp(service_rout -e))) { - append_to_reply("Service-Route: $avp(service_route)\r\n"); -} -... - -1.6.3. ul_del_key(domain, aor, key_name) - - Deletes a Key/Value from the Key-Value-Store of a - Usrloc-Record. - - Returns false, if no record is found is usrloc. - - Meaning of the parameters is as follows: - * domain (string) - Domain of the AOR, e.g. "location" - * aor (string) - Address-of-Record, save the key for a - specific (registered) user. - * key (string) - The name of the key to be deleted. - - This function can be used in ANY route. - - Example 1.46. ul_del_key usage -... -ul_del_key("location", "$tU@$td", "service_route"); -... - -1.7. Exported MI Functions - -1.7.1. ul_rm - - Deletes an entire AOR record (including its contacts). - - Parameters: - * table_name - table where the AOR is removed from (Ex: - location). - * aor - user AOR in username[@domain] format (domain must be - supplied only if use_domain option is on). - -1.7.2. ul_rm_contact - - Deletes a contact from an AOR record. - - Parameters: - * table name - table where the AOR is removed from (Ex: - location). - * AOR - user AOR in username[@domain] format (domain must be - supplied only if use_domain option is on). - * contact - exact contact to be removed - -1.7.3. ul_dump - - Dumps the entire content of the USRLOC in memory cache - - Parameters: - * brief - (optional, may not be present); if equals to string - “brief”, a brief dump will be done (only AOR and contacts, - with no other details) - -1.7.4. ul_flush - - Force a flush of all pending usrloc cache changes to the - database. Normally, this routine runs every timer_interval - seconds. - -1.7.5. ul_add - - Adds a new contact for an user AOR. - - Parameters: - * table name (string) - table where the contact will be added - (Ex: "location"). - * aor (string) - user AOR in username[@domain] format (domain - must be supplied only if use_domain option is on). - * contact (string) - Contact URI to be added - * expires (int) - expires value of the contact - * q (string) - Q value of the contact - * flags (int) - internal USRLOC flags of the contact - * cflags (int) - per branch flags of the contact - * methods (int) - bitmask with supported requests of the - contact. To whitelist all SIP methods, simply use the value - 32767. For a breakdown of each method's value, see the - "request_method" internal enum. - -1.7.6. ul_show_contact - - Dumps the contacts of an user AOR. - - Parameters: - * table_name - table where the AOR resides (Ex: location). - * aor - user AOR in username[@domain] format (domain must be - supplied only if use_domain option is on). - -1.7.7. ul_sync - - Empty the location table, then synchronize it with all contacts - from memory. Note that this can not be used when no database is - specified or with the DB-Only scheme. - - Important: make sure that all your contacts are in memory - (ul_dump MI function) before executing this command. - - Parameters: - * table name - table where the AOR resides (Ex: location). - * AOR (optional) - only delete/sync this user AOR, not the - whole table. Format: "username[@domain]" (domain is - required only if use_domain option is on). - -1.7.8. ul_cluster_sync - - This command will only take effect if the target OpenSIPS - instance is paired with a hot backup instance, while running - under a cluster-enabled working_mode_preset. - - The current node will locate a healthy donor node within the - location_cluster and issue a sync request to it. The donor node - will then proceed to push all of its user location data over to - the current node, via the binary interface. The received data - will be merged with existing data. Conflicting contacts - (matched according to matching_mode) are overwritten only if - the sync data is newer than the current data. - -1.8. Exported Statistics - - Exported statistics are listed in the next sections. - -1.8.1. users - - Number of AOR existing in the USRLOC memory cache for that - domain - can not be resetted; this statistic will be register - for each used domain (Ex: location). - -1.8.2. contacts - - Number of contacts existing in the USRLOC memory cache for that - domain - can not be resetted; this statistic will be register - for each used domain (Ex: location). - -1.8.3. expires - - Total number of expired contacts for that domain - can be - resetted; this statistic will be register for each used domain - (Ex: location). - -1.8.4. registered_users - - Total number of AOR existing in the USRLOC memory cache for all - domains - can not be resetted. - -1.9. Exported Events - -1.9.1. E_UL_AOR_INSERT - - This event is raised when a new AOR is inserted in the USRLOC - memory cache. - - Parameters: - * domain - The name of the table. - * aor - The AOR of the inserted record. - -1.9.2. E_UL_AOR_DELETE - - This event is raised when a new AOR is deleted from the USRLOC - memory cache. - - Parameters: - * domain - The name of the table. - * aor - The AOR of the deleted record. - -1.9.3. E_UL_CONTACT_INSERT - - This event is raised when a new contact is inserted in any of - the existing AOR's contact list. For each new contact, if its - AOR does not exist in the memory, then both the E_UL_AOR_CREATE - and E_UL_CONTACT_INSERT events will be raised. - - Parameters: - * domain - The name of the table. - * aor - The AOR of the inserted contact. - * uri - The contact URI of the inserted contact. - * received - IP, port and protocol the registration message - was received from. If these have the same value as the - contact's address (see the address parameter) then the - received parameter will be an empty string. - * path - The PATH header value of the registration - message.(empty string if not present) - * qval - The Q value (priority) of the contact (as integer - value from 0 to 10). - * user_agent - The User-Agent header value. - NOTICE: Can contain spaces. - * socket - The SIP socket/listener (as string) used by - OpenSIPS to receive the contact registations. - * bflags - The branch flags (bflags) of the contact (in - integer value of the bitmask) - * expires - The expires value of the contact (as UNIX - timestamp integer). - * callid - The Call-ID header of the registration message. - * cseq - The cseq number as an int value. - * attr - The attributes string attached to the contact (the - custom attributes attached from the script level). As this - string is options, if missing in the contact, the event - will push the empty string for this event field. - * latency - The latency of the last successful ping for this - contact, in microseconds. Until the first ping reply for a - given contact arrives, its pinging latency will be 0. - * shtag - The shared tag of the contact, which helps - determine if the current node owns the contact (e.g. - possibly using the $cluster.sh_tag pseudo-variable in order - to perform the check). - NOTICE: If a contact has no shared tag attached to it, the - value of this parameter will be "" (empty string)! - -1.9.4. E_UL_CONTACT_DELETE - - This event is raised when a contact is deleted from an existing - AOR's contact list. If the contact is the only one in the list - then both the E_UL_AOR_DELETE and E_UL_CONTACT_DELETE events - will be raised. - - Parameters: same as the E_UL_CONTACT_INSERT event - -1.9.5. E_UL_CONTACT_UPDATE - - This event is raised when a contact's info is updated by - receiving another registration message. - - Parameters: same as the E_UL_CONTACT_INSERT event - -1.9.6. E_UL_CONTACT_REFRESH - - This event may only be raised for RFC 8599 (Push Notification) - enabled contacts. - - Set contact_refresh_timer to true in order to enable this - event. The event is raised within reasonable time before an RFC - 8599 enabled contact will expire, such that the script writer - can take action, possibly force a registration refresh from the - endpoint. - - Parameters: - * domain - The name of the table. - * aor - The AOR of the inserted contact. - * uri - The contact URI of the inserted contact. - * received - IP, port and protocol the registration message - was received from. If these have the same value as the - contact's address (see the address parameter) then the - received parameter will be an empty string. - * user_agent - The User-Agent header value. - NOTICE: Can contain spaces. - * socket - The SIP socket/listener (as string) used by - OpenSIPS to receive the contact registations. - * bflags - The branch flags (bflags) of the contact (in - integer value of the bitmask) - * expires - The expires value of the contact (as UNIX - timestamp integer). - * callid - The Call-ID header of the registration message. - * attr - The attributes string attached to the contact (the - custom attributes attached from the script level). As this - string is options, if missing in the contact, the event - will push the empty string for this event field. - * shtag - The shared tag of the contact, which helps - determine if the current node owns the contact (e.g. - possibly using the $cluster.sh_tag pseudo-variable in order - to perform the check). - * reason - the reason why the binding refresh event was - triggered. Possible values: - + "reg-refresh" - periodic refresh triggered by OpenSIPS - + "ini-INVITE", "ini-SUBSCRIBE", etc. - a refresh - triggered by an incoming initial SIP request - + "mid-INVITE", "mid-BYE", etc. - a refresh triggered by - an incoming mid-dialog SIP request - * req_callid - the Call-ID of the SIP request which triggered - this event, if any. This gives the ability to logically - link the pending request with the current event and access - useful data from that request (e.g. caller identity, dialed - number, etc.). - Using the req_callid, if a dialog has been created for the - pending request, this dialog may be temporarily loaded - inside the event_route using the load_dialog_ctx() and - unload_dialog_ctx() functions of the dialog module. - -1.9.7. E_UL_LATENCY_UPDATE - - This event is raised when a contact pinging latency matches - either of the latency_event_min_us or - latency_event_min_us_delta filters. If none of these filters is - set, this event will get raised for each successful contact - ping operation. - - Parameters: same as the E_UL_CONTACT_INSERT event - -Chapter 2. Developer Guide - -2.1. Available Functions - -2.1.1. ul_register_domain(name) - - The function registers a new domain. Domain is just another - name for table used in registrar. The function is called from - fixups in registrar. It gets name of the domain as a parameter - and returns pointer to a new domain structure. The fixup than - 'fixes' the parameter in registrar so that it will pass the - pointer instead of the name every time save() or lookup() is - called. Some usrloc functions get the pointer as parameter when - called. For more details see implementation of save function in - registrar. - - Meaning of the parameters is as follows: - * const char* name - Name of the domain (also called table) - to be registered. - -2.1.2. ul_insert_urecord(domain, aor, rec, is_replicated) - - The function creates a new record structure and inserts it in - the specified domain. The record is structure that contains all - the contacts for belonging to the specified username. - - Meaning of the parameters is as follows: - * udomain_t* domain - Pointer to domain returned by - ul_register_udomain. - * str* aor - Address of Record (aka username) of the new - record (at this time the record will contain no contacts - yet). - * urecord_t** rec - The newly created record structure. - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.3. ul_delete_urecord(domain, aor, is_replicated) - - The function deletes all the contacts bound with the given - Address Of Record. - - Meaning of the parameters is as follows: - * udomain_t* domain - Pointer to domain returned by - ul_register_udomain. - * str* aor - Address of record (aka username) of the record, - that should be deleted. - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.4. ul_get_urecord(domain, aor) - - The function returns pointer to record with given Address of - Record. - - Meaning of the parameters is as follows: - * udomain_t* domain - Pointer to domain returned by - ul_register_udomain. - - * str* aor - Address of Record of request record. - -2.1.5. ul_lock_udomain(domain) - - The function lock the specified domain, it means, that no other - processes will be able to access during the time. This prevents - race conditions. Scope of the lock is the specified domain, - that means, that multiple domain can be accessed - simultaneously, they don't block each other. - - Meaning of the parameters is as follows: - * udomain_t* domain - Domain to be locked. - -2.1.6. ul_unlock_udomain(domain) - - Unlock the specified domain previously locked by - ul_lock_udomain. - - Meaning of the parameters is as follows: - * udomain_t* domain - Domain to be unlocked. - -2.1.7. ul_release_urecord(record, is_replicated) - - Do some sanity checks - if all contacts have been removed, - delete the entire record structure. - - Meaning of the parameters is as follows: - * urecord_t* record - Record to be released. - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.8. ul_insert_ucontact(record, contact, contact_info, contact, -is_replicated) - - The function inserts a new contact in the given record with - specified parameters. - - Meaning of the parameters is as follows: - * urecord_t* record - Record in which the contact should be - inserted. - * str* contact - Contact URI. - * ucontact_info_t* contact_info - Single structure containing - the new contact information - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.9. ul_delete_ucontact (record, contact, is_replicated) - - The function deletes given contact from record. - - Meaning of the parameters is as follows: - * urecord_t* record - Record from which the contact should be - removed. - - * ucontact_t* contact - Contact to be deleted. - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.10. ul_delete_ucontact_from_id (domain, contact_id) - - The function deletes a contact with the given contact_id from - the given domain. - - Meaning of the parameters is as follows: - * udomain_t* domain - Domain where the contact can be found. - - * uint64_t contact_id - Contact_id identifying the contact to - be deleted. - -2.1.11. ul_get_ucontact(record, contact) - - The function tries to find contact with given Contact URI and - returns pointer to structure representing the contact. - - Meaning of the parameters is as follows: - * urecord_t* record - Record to be searched for the contact. - - * str_t* contact - URI of the request contact. - -2.1.12. ul_get_domain_ucontacts (domain, buf, len, flags) - - The function retrieves all contacts of all registered users - from the given doamin and returns them in the caller-supplied - buffer. If the buffer is too small, the function returns - positive value indicating how much additional space would be - necessary to accommodate all of them. Please note that the - positive return value should be used only as a “hint”, as there - is no guarantee that during the time between two subsequent - calls number of registered contacts will remain the same. - - If flag parameter is set to non-zero value then only contacts - that have the specified flags set will be returned. It is, for - example, possible to list only contacts that are behind NAT. - - Meaning of the parameters is as follows: - * udomaint_t* domain - Domain from which to get the contacts - - * void* buf - Buffer for returning contacts. - - * int len - Length of the buffer. - - * unsigned int flags - Flags that must be set. - -2.1.13. ul_get_all_ucontacts (buf, len, flags) - - The function retrieves all contacts of all registered users and - returns them in the caller-supplied buffer. If the buffer is - too small, the function returns positive value indicating how - much additional space would be necessary to accommodate all of - them. Please note that the positive return value should be used - only as a “hint”, as there is no guarantee that during the time - between two subsequent calls number of registered contacts will - remain the same. - - If flag parameter is set to non-zero value then only contacts - that have the specified flags set will be returned. It is, for - example, possible to list only contacts that are behind NAT. - - Meaning of the parameters is as follows: - * void* buf - Buffer for returning contacts. - - * int len - Length of the buffer. - - * unsigned int flags - Flags that must be set. - -2.1.14. ul_update_ucontact(record, contact, contact_info, -is_replicated) - - The function updates contact with new values. - - Meaning of the parameters is as follows: - * urecord_t* record - Record in which the contact should be - inserted. - * ucontact_t* contact - Contact URI. - * ucontact_info_t* contact_info - Single structure containing - the new contact information - * char is_replicated - Specifies whether this function will - be called from the context of a Binary Interface callback. - If uncertain, simply use 0. - -2.1.15. ul_bind_ursloc( api ) - - The function imports all functions that are exported by the - USRLOC module. Overs for other modules which want to user the - internal USRLOC API an easy way to load and access the - functions. - - Meaning of the parameters is as follows: - * usrloc_api_t* api - USRLOC API - -2.1.16. ul_register_ulcb(type ,callback, param) - - The function register with USRLOC a callback function to be - called when some event occures inside USRLOC. - - Meaning of the parameters is as follows: - * int types - type of event for which the callback should be - called (see usrloc/ul_callback.h). - * ul_cb f - callback function; see usrloc/ul_callback.h for - prototype. - * void *param - some parameter to be passed to the callback - each time when it is called. - -2.1.17. ul_get_num_users() - - The function loops through all domains summing up the number of - users. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Jan Janak (@janakj) 416 117 15689 10095 - 2. Liviu Chircu (@liviuchircu) 358 215 9395 3830 - 3. Bogdan-Andrei Iancu (@bogdan-iancu) 246 150 4232 3624 - 4. Vlad Patrascu (@rvlad-patrascu) 43 25 794 661 - 5. Ionut Ionita (@ionutrazvanionita) 41 24 1099 413 - 6. Daniel-Constantin Mierla (@miconda) 40 29 544 308 - 7. Jiri Kuthan (@jiriatipteldotorg) 36 25 975 120 - 8. Razvan Crainea (@razvancrainea) 31 24 427 159 - 9. Henning Westerholt (@henningw) 21 11 462 356 - 10. Maksym Sobolyev (@sobomax) 19 13 347 162 - - All remaining contributors: Andrei Pelinescu-Onciul, Vlad Paiu - (@vladpaiu), Walter Doekes (@wdoekes), Nils Ohlmeier, Eseanu - Marius Cristian (@eseanucristian), Ovidiu Sas (@ovidiusas), - Ionel Cerghit (@ionel-cerghit), Andrei Dragus, Anca Vamanu, - Alessio Garzi (@Ozzyboshi), Zero King (@l2dy), Dusan Klinec - (@ph4r05), Andrei Datcu (@andrei-datcu), Carsten Bock, Juha - Heinanen (@juha-h), Marcus Hunger, Jamey Hicks, Norman - Brandinger (@NormB), Peter Lemenkov (@lemenkov), Andreas - Granig, Shlomi Gutman, @jalung, Jeffrey Magder, Phil D'Amore, - David Sanders, Konstantin Bokarius, Klaus Darilion, Iouri - Kharon, Aron Podrigal (@ar45), Alexandra Titoc, Dan Pascu - (@danpascu), Gang Zhuo, Matthew M. Boedicker, UnixDev, Edson - Gellert Schubert, Alexey Vasilyev (@vasilevalex), Elena-Ramona - Modroiu, Stephane Alnet. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Norman Brandinger (@NormB) Aug 2006 - May 2025 - 2. Liviu Chircu (@liviuchircu) Jan 2013 - Feb 2025 - 3. Gang Zhuo Nov 2024 - Nov 2024 - 4. Alexandra Titoc Sep 2024 - Sep 2024 - 5. Carsten Bock Mar 2024 - Mar 2024 - 6. Maksym Sobolyev (@sobomax) Apr 2003 - Dec 2023 - 7. Vlad Paiu (@vladpaiu) Jun 2011 - Jul 2023 - 8. Vlad Patrascu (@rvlad-patrascu) Jul 2016 - Mar 2023 - 9. Razvan Crainea (@razvancrainea) Jul 2011 - Jan 2023 - 10. Bogdan-Andrei Iancu (@bogdan-iancu) Mar 2002 - Feb 2022 - - All remaining contributors: Walter Doekes (@wdoekes), Zero King - (@l2dy), Peter Lemenkov (@lemenkov), Alexey Vasilyev - (@vasilevalex), Aron Podrigal (@ar45), Alessio Garzi - (@Ozzyboshi), Dan Pascu (@danpascu), Shlomi Gutman, @jalung, - Ionut Ionita (@ionutrazvanionita), Ionel Cerghit - (@ionel-cerghit), Ovidiu Sas (@ovidiusas), Dusan Klinec - (@ph4r05), Eseanu Marius Cristian (@eseanucristian), David - Sanders, Andrei Datcu (@andrei-datcu), Stephane Alnet, Andrei - Dragus, Phil D'Amore, UnixDev, Daniel-Constantin Mierla - (@miconda), Henning Westerholt (@henningw), Iouri Kharon, - Konstantin Bokarius, Edson Gellert Schubert, Anca Vamanu, - Matthew M. Boedicker, Marcus Hunger, Elena-Ramona Modroiu, - Jeffrey Magder, Andreas Granig, Juha Heinanen (@juha-h), Klaus - Darilion, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri - Kuthan (@jiriatipteldotorg), Jamey Hicks, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Norman Brandinger (@NormB), Liviu Chircu - (@liviuchircu), Carsten Bock, Zero King (@l2dy), Alexey - Vasilyev (@vasilevalex), Vlad Patrascu (@rvlad-patrascu), Peter - Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), - Razvan Crainea (@razvancrainea), Ionut Ionita - (@ionutrazvanionita), Eseanu Marius Cristian (@eseanucristian), - Ovidiu Sas (@ovidiusas), Andrei Datcu (@andrei-datcu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert, Henning Westerholt (@henningw), Marcus - Hunger, Elena-Ramona Modroiu, Juha Heinanen (@juha-h), Jan - Janak (@janakj), Maksym Sobolyev (@sobomax), Nils Ohlmeier. - - Documentation Copyrights: - - Copyright © 2018 www.opensips-solutions.com - - Copyright © 2005-2008 Voice Sistem SRL - - Copyright © 2003 FhG FOKUS diff --git a/modules/usrloc/README.md b/modules/usrloc/README.md new file mode 100644 index 00000000000..aef196e5a17 --- /dev/null +++ b/modules/usrloc/README.md @@ -0,0 +1,2022 @@ +--- +title: "usrloc Module" +description: "A SIP user location implementation." +--- + +## Admin Guide + + +### Overview + + +A SIP user location implementation. Its main purpose is to store, +manage and provide access to SIP registration bindings (contacts) for +other modules (e.g. registrar, mid-registrar, nathelper, etc.). The +module exports no functions that could be directly used from the +OpenSIPS script. + + +At runtime, the contacts may reside in memory, in an SQL database or in +a NoSQL database. Combinations of two of the above are also possible. +For example, contacts may only be directly manipulated in memory in +order to guarantee fast interactions while being asynchronously +synchronized to an SQL database. The latter helps achieve restart +persistency. Consult the +**[working mode preset](#param_working_mode_preset)** +parameter for more details on all possible runtime behaviors of the +module. + + +The OpenSIPS user location implementation is cluster-enabled. On top of +supporting traditional "single instance" setups, it also allows multiple +OpenSIPS user location nodes to form a single, global user location cluster. +This allows high-level features such as startup synchronization (data +tunneling) from a random, healthy "donor" node and evenly distributed +NAT pinging workloads. + + +### Distributed SIP User Location + + +Starting with OpenSIPS 2.4, the user location module offers several optional +data distribution models, each tailoring to specific real-life production use cases. +Built on top of the OpenSIPS clustering module, these models take into +account service concerns such as *high availability, geographical +distribution, horizontal scalability and NAT traversal*. + + +Depending on data locality, the distribution models are split in two main +categories: + + +#### "Federation" Topology + + +A *federated* user location keeps contact data local +to the original OpenSIPS node the contact initially registered to. In +order to share the reachability of these contacts with the global +OpenSIPS user location cluster, registrar nodes will only publish some +light "metadata" entries for any new Addresses-of-Record which are +reachable from them. These entries will cause other nodes to also fork +additional SIP branches pointing to the publisher registrar upon +receiving calls for its advertised Addresses-of-Record. + + +The **federation** topology is an +optimized solution for the following core problems: + + +- **IP address restrictions** - In some +cases, calls routed towards registered contacts must necessarily +pass through the original registration nodes of these contacts. A +classic example of this situation is when an OpenSIPS registrar +sitting at the edge of the platform is directly facing a NAT device +on the way to the contact. Unless calls are sent out from this +exact registrar, they will not be able to traverse the NAT device +and reach the contact. +- **horizontal scalability** - Avoiding +global replication/contact broadcasting within the cluster not only +dramatically improves contact storage performance, but also leads +to better service scalability. Different geographical locations can +be sized according to their local subscriber populations (traffic +may be balanced to them using DNS SRV weights, for example), +without losing platform-wide reachability. + + +Currently, the metadata information may be published to NoSQL databases +which support key/multi-value column-like associations. Example known +backends to support these abstractions at the time of writing are +MongoDB and Cassandra. + + +The [federated user location tutorial](https://docs.opensips.org/tutorials/distributed-user-location-federation/) +contains precise details on how to achieve this setup (including High +Availability support). + + +#### "Full Sharing" Topology + + +A *fully sharing* user location broadcasts contact +information to all data nodes (OpenSIPS or NoSQL). +The main assumption behind this mode is that any routing +restrictions have been alleviated beforehand. Consequently, either SIP +traffic egressing from a "full sharing" +OpenSIPS user location topology is being intermediated by an +additional SIP edge endpoint of our platform, or there are no egress IP +restrictions at all (for example, if all SIP UAs have public IPs). In +this setup, all OpenSIPS user location nodes are +*equivalent* to one another, as they each have +access to the same dataset and have no routing restrictions. + + +The **full sharing** topology is +an appropriate solution for multi-layer VoIP platforms, where the +OpenSIPS registrar nodes do not directly interact with external SIP +endpoints. Moreover, it can be configured to fully store contact data +within a NoSQL cluster (zero in-memory storage), thus taking full +advantage of the data sharing, sharding, migration and other +capabilities of a specialized distributed data handling engine. + + +Additionally, a "full sharing" topology can be used to achieve a basic +"hot backup" high-availability setup with an active-passive registrar +nodes configuration, both of which make use of a shared virtual IP. + + +Registrations may optionally be fully managed inside NoSQL +databases which support key/multi-value column-like associations. +Example known backends to currently support these abstractions are MongoDB +and Apache Cassandra. + + +The ["full sharing" user location tutorial](https://docs.opensips.org/tutorials/distributed-user-location-full-sharing/) +contains precise details on how to achieve this setup (including full +NoSQL storage support). + + +#### "N Contact Pings" Problem + + +A long-standing problem caused by contact information being replicated +to multiple SIP registrar instances directly through replication or +indirectly through a globally reachable database. As long as +traditionally clusterized nodes are not aware of +each other, they will each scan the entire contact dataset, thus +periodically sending "N pings" instead of "1 ping" for each contact. +This difference directly affects service scalability, as well as the +amount of consumed resources such as CPU and network +bandwidth, both on the service and client side. + + +This problem is solved with the help of the OpenSIPS cluster layer, +which makes all nodes aware of each others' presence. Thus, the +distributed user location node topologies are able to collectively +partition the pinging workload and spread it evenly across the current +number of cluster nodes, at any given point in time. The +[pinging mode](#param_pinging_mode) module parameter describes the +built-in pinging heuristics in more detail. + + +### Contact matching + + +Contact matching (for the same Address-of-Record, AoR) is an important +aspect of a SIP user location service, especially in the context of NAT +traversal. The latter raises more problems, since contacts from different +phones of same users may overlap (if behind NATs with identical +configurations) or the re-register Contact of the same SIP User Agent may +be seen as a new one (due to the request arriving via a new NAT binding). + + +The SIP RFC 3261 publishes a matching algorithm based only on the +contact string with Call-ID and CSeq number extra checking (if the Call-ID +matches, it must have a higher CSeq number, otherwise the registration is +invalid). But as argumented above, this is not enough in a NAT traversal +context, so the OpenSIPS implementation of contact matching offers more +algorithms: + + +- *Contact based only* - strict RFC 3261 +compliancy - the contact is matched as string and extra checked +via Call-ID and CSeq (if Call-ID is the same, it must have a +higher CSeq number, otherwise the registration is invalid). +- *Contact and Call-ID based* - an extension +of the first case - the Contact and Call-ID header field values +must match as strings; the CSeq must be higher than the previous +one - so be careful how you deal with REGISTER retransmissions in +this case. + + +For more details on how to control/select the contact matching algorithm, +please go to +**[matching mode](#param_matching_mode)**. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *Optionally an SQL database module*. +- *Optionally a NoSQL database module*. +- *clusterer, if [cluster mode](#param_cluster_mode) +is different than "none".* + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### nat_bflag (string) + + +The name of the branch flag to be used as NAT marker (if the contact +is or not natted). This is a branch flag and it will be imported and +used by all other modules depending on the usrloc module. + + +*Default value is NULL (not set).* + + +```opensips title="Set nat_bflag parameter" +... +modparam("usrloc", "nat_bflag", "NAT_BFLAG") +... +``` + + +#### contact_id_column (string) + + +Name of the column holding the unique contact IDs. + + +*Default value is "contact_id".* + + +```opensips title="Set contact_id_column parameter" +... +modparam("usrloc", "contact_id_column", "ctid") +... +``` + + +#### user_column (string) + + +Name of column containing usernames. + + +*Default value is "username".* + + +```opensips title="Set user_column parameter" +... +modparam("usrloc", "user_column", "username") +... +``` + + +#### domain_column (string) + + +Name of column containing domains. + + +*Default value is "domain".* + + +```opensips title="Set user_column parameter" +... +modparam("usrloc", "domain_column", "domain") +... +``` + + +#### contact_column (string) + + +Name of column containing contacts. + + +*Default value is "contact".* + + +```opensips title="Set contact_column parameter" +... +modparam("usrloc", "contact_column", "contact") +... +``` + + +#### expires_column (string) + + +Name of column containing expires value. + + +*Default value is "expires".* + + +```opensips title="Set expires_column parameter" +... +modparam("usrloc", "expires_column", "expires") +... +``` + + +#### q_column (string) + + +Name of column containing q values. + + +*Default value is "q".* + + +```opensips title="Set q_column parameter" +... +modparam("usrloc", "q_column", "q") +... +``` + + +#### callid_column (string) + + +Name of column containing callid values. + + +*Default value is "callid".* + + +```opensips title="Set callid_column parameter" +... +modparam("usrloc", "callid_column", "callid") +... +``` + + +#### cseq_column (string) + + +Name of column containing cseq numbers. + + +*Default value is "cseq".* + + +```opensips title="Set cseq_column parameter" +... +modparam("usrloc", "cseq_column", "cseq") +... +``` + + +#### methods_column (string) + + +Name of column containing supported methods. + + +*Default value is "methods".* + + +```opensips title="Set methods_column parameter" +... +modparam("usrloc", "methods_column", "methods") +... +``` + + +#### flags_column (string) + + +Name of column to save the internal flags of the record. + + +*Default value is "flags".* + + +```opensips title="Set flags_column parameter" +... +modparam("usrloc", "flags_column", "flags") +... +``` + + +#### cflags_column (string) + + +Name of column to save the branch/contact flags of the record. + + +*Default value is "cflags".* + + +```opensips title="Set cflags_column parameter" +... +modparam("usrloc", "cflags_column", "cflags") +... +``` + + +#### user_agent_column (string) + + +Name of column containing user-agent values. + + +*Default value is "user_agent".* + + +```opensips title="Set user_agent_column parameter" +... +modparam("usrloc", "user_agent_column", "user_agent") +... +``` + + +#### received_column (string) + + +Name of column containing the source IP, port, and protocol from the REGISTER +message. + + +*Default value is "received".* + + +```opensips title="Set received_column parameter" +... +modparam("usrloc", "received_column", "received") +... +``` + + +#### socket_column (string) + + +Name of column containing the received socket information (IP:port) +for the REGISTER message. + + +*Default value is "socket".* + + +```opensips title="Set socket_column parameter" +... +modparam("usrloc", "socket_column", "socket") +... +``` + + +#### path_column (string) + + +Name of column containing the Path header. + + +*Default value is "path".* + + +```opensips title="Set path_column parameter" +... +modparam("usrloc", "path_column", "path") +... +``` + + +#### sip_instance_column (string) + + +Name of column containing the SIP instance. + + +*Default value is "NULL".* + + +```opensips title="Set sip_instance_column parameter" +... +modparam("usrloc", "sip_instance_column", "sip_instance") +... +``` + + +#### kv_store_column (string) + + +Name of column containing generic key-value data. + + +*Default value is "kv_store".* + + +```opensips title="Set kv_store_column parameter" +... +modparam("usrloc", "kv_store_column", "json_data") +... +``` + + +#### attr_column (string) + + +Name of column containing additional registration-related information. + + +*Default value is "attr".* + + +```opensips title="Set attr_column parameter" +... +modparam("usrloc", "attr_column", "attributes") +... +``` + + +#### use_domain (integer) + + +If the domain part of the user should be also saved and used for +identifing the user (along with the username part). Useful in +multi domain scenarios. Non 0 value means true. + + +*Default value is "0 (false)".* + + +```opensips title="Set use_domain parameter" +... +modparam("usrloc", "use_domain", 1) +... +``` + + +#### desc_time_order (integer) + + +If the user's contacts should be kept timestamp ordered; otherwise the +contact will be ordered based on q value. +Non 0 value means true. + + +*Default value is "0 (false)".* + + +```opensips title="Set desc_time_order parameter" +... +modparam("usrloc", "desc_time_order", 1) +... +``` + + +#### timer_interval (integer) + + +Number of seconds between two timer runs. During each run, the module +will update/delete dirty/expired contacts from memory and/or mirror +these operations to the database, if configured to do so. + + +> [!WARNING] +> In case of an OpenSIPS shutdown or even a crash, contacts which are in +memory only and have not been flushed yet to disk will NOT get lost! +OpenSIPS will try its best to do a last-minute sync to DB right before +shutting down. + + +*Default value is 60.* + + +```opensips title="Set timer_interval parameter" +... +modparam("usrloc", "timer_interval", 120) +... +``` + + +#### db_url (string) + + +URL of the database that should be used. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("usrloc", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### cachedb_url (string) + + +URL of a NoSQL database to be used. Only required in a +cachedb-enabled +**[cluster mode](#param_cluster_mode)**. + + +*Default value is "none".* + + +```opensips title="Set cachedb_url parameter" +... +modparam("usrloc", "cachedb_url", "mongodb://10.0.0.4:27017/opensipsDB.userlocation") +... +``` + + +#### db_mode (integer, deprecated) + + +This parameter has been kept for backwards compatibility. It acts as a +[working mode preset](#param_working_mode_preset) (which it also conflicts with), +overriding any [cluster mode](#param_cluster_mode), +[restart persistency](#param_restart_persistency) and +[sql write mode](#param_sql_write_mode) settings. Possible values are: + + +- 0, corresponding to "single-instance-no-db" (see below) +- 1, corresponding to "single-instance-sql-write-through" +- 2, corresponding to "single-instance-sql-write-back" +- 3, corresponding to "sql-only" + + +*Default value is "not set".* + + +```opensips title="Set db_mode parameter" +... +modparam("usrloc", "db_mode", 2) +... +``` + + +#### working_mode_preset (string) + + +A pre-defined working mode for the usrloc module. Setting this +parameter will override any [cluster mode](#param_cluster_mode), +[restart persistency](#param_restart_persistency) and +[sql write mode](#param_sql_write_mode) settings. + + +- **"single-instance-no-db"** - This +disables database completely. Only memory will be used. +Contacts will not survive restart. Use this value if you need a +really fast usrloc and contact persistence is not necessary or +is provided by other means. +- **"single-instance-sql-write-through"** + - Write-Through scheme. All changes to usrloc are immediately +reflected in database too. This is very slow, but very reliable. +Use this scheme if speed is not your priority but need to make +sure that no registered contacts will be lost during crash or +reboot. +- **"single-instance-sql-write-back"** + - Write-Back scheme. This is a combination of previous two +schemes. All changes are made to memory and database +synchronization is done in the timer. The timer deletes all +expired contacts and flushes all modified or new contacts to +database. Use this scheme if you encounter high-load peaks +and want them to process as fast as possible. The mode will +not help at all if the load is high all the time. The +added latency on the SIP signaling when using this asynchronous +preset is much lower than the one added by the safe but +blocking, "single-instance-sql-write-through" preset. +- **"sql-only"** - +DB-Only scheme. No memory cache is kept, all operations being +directly performed with the database. The timer deletes all +expired contacts from database - cleans after clients that didn't +un-register or re-register. The mode is useful if you configure +more servers sharing the same DB without any replication at SIP +level. The mode may be slower due the high number of DB operation. +For example NAT pinging is a killer since during each ping cycle +all nated contact are loaded from the DB; The lack of memory +caching also disable the statistics exports. +- **"federation-cachedb-cluster"** - +OpenSIPS will run with a "federation-cachedb" +[cluster mode](#param_cluster_mode) and +"sync-from-cluster" [restart persistency](#param_restart_persistency). +This will require the configuration of multiple "seed" nodes in +the cluster. Refer to the [federated user location tutorial](https://docs.opensips.org/tutorials/distributed-user-location-federation/) for more +details. +- **"full-sharing-cluster"** - +OpenSIPS will run with a "full-sharing" +[cluster mode](#param_cluster_mode) and +"sync-from-cluster" [restart persistency](#param_restart_persistency). +This will require the configuration of one of the nodes in the cluster +as a "seed" node in order to bootstrap the syncing process. +- **"full-sharing-cachedb-cluster"** - +OpenSIPS will run with a "full-sharing-cachedb" +[cluster mode](#param_cluster_mode), where all location data strictly +resides in a NoSQL database, thus it will have natural restart +persistency. + + +Refer to section +[distributed sip user location](#distributed_sip_user_location) for details +regarding the clustering topologies and their behavior. + + +*Default value is "single-instance-no-db".* + + +```opensips title="Set working_mode_preset parameter" +... +modparam("usrloc", "working_mode_preset", "full-sharing-cachedb-cluster") +... +``` + + +#### cluster_mode (string) + + +**This parameter will get overridden if either +[working mode preset](#param_working_mode_preset) or +[db mode](#param_db_mode) is set.** + + +The behavior of the global OpenSIPS user location cluster. Refer to +section [distributed sip user location](#distributed_sip_user_location) for details. + + +This parameter may take the following values: + + +- *"none"* - single instance mode. +- *"federation-cachedb"* - +federation-based data sharing. Local AoR metadata is published +inside a NoSQL database, so other cluster nodes can fork SIP +traffic over to the current node. Consequently, the +[location cluster](#param_location_cluster) and +[cachedb url](#param_cachedb_url) parameters are mandatory. +- *"full-sharing"* - +Broadcast contact updates (full-mesh mirroring) to all other +OpenSIPS cluster participants. Each node will hold the entire +user location dataset. Consequently, the +[location cluster](#param_location_cluster) parameter is mandatory. +- *"full-sharing-cachedb"* - +Full contact data management through the use of a NoSQL +database (somewhat resembling the "sql-only" preset). +The cluster layer is still required in order to +be able to partition and spread the pinging workload evenly +among participating OpenSIPS nodes. Consequently, the +[location cluster](#param_location_cluster) and +[cachedb url](#param_cachedb_url) parameters are mandatory. +- *"sql-only"* - +Multiple OpenSIPS boxes using a common +[db url](#param_db_url) without necessarily being aware +of each other. + + +*Default value is *"none" (single instance mode)*.* + + +```opensips title="Set cluster_mode parameter" +... +modparam("usrloc", "cluster_mode", "federation-cachedb") +... +``` + + +#### restart_persistency (string) + + +**This parameter will get overridden if either +[working mode preset](#param_working_mode_preset) or +[db mode](#param_db_mode) are set.** + + +Controls the behavior of the OpenSIPS user location following a +restart. This parameter has no effect in some database-only working +mode presets, where restart persistency is naturally ensured. + + +This parameter may take the following values: + + +- *"none"* - no explicit data +synchronization following a restart. The node starts empty. +- *"load-from-sql"* - enable +SQL-based restart persistency. This causes all runtime +in-memory writes (i.e. new registrations, re-registrations or +de-registrations) to also propagate to an SQL database, from +which all data will be imported following a restart. +Choosing this value will make the [db url](#param_db_url) +parameter mandatory, as well as cause +[sql write mode](#param_sql_write_mode) to default to "write-back" +instead of "none". +- *"sync-from-cluster"* - enable +cluster-based restart persistency. Following a restart, +an OpenSIPS cluster node will search for a healthy "donor" node +from which to mirror the entire user location dataset via +direct cluster sync (TCP-based, binary-encoded data transfer). +Depending on the clustering mode and cluster topology, this will +require the configuration of one or multiple "seed" nodes in the cluster. +Choosing this value will make the +[location cluster](#param_location_cluster) parameter mandatory. + + +*Default value is +*"none" (no restart persistency)*.* + + +```opensips title="Set restart_persistency parameter" +... +modparam("usrloc", "restart_persistency", "sync-from-cluster") +... +``` + + +#### sql_write_mode (string) + + +**This parameter will get overridden if either +[working mode preset](#param_working_mode_preset) or +[db mode](#param_db_mode) are set.** + + +Only valid if [restart persistency](#param_restart_persistency) is enabled. +Controls the runtime behavior of OpenSIPS writes to the SQL database. + + +This parameter may take the following values: + + +- *"none"* - do not perform any +additional SQL writes at runtime to an SQL database in order +to specifically ensure restart persistency. +- *"write-through"* - all in-memory +writes (i.e. new registrations, re-registrations or +de-registrations) also propagate into the SQL database, inline. +While this will definitely slow down registration performance +(lookups are served from memory!), it has the advantage of +making the instance crash-safe. +- *"write-back"* - all in-memory +writes (i.e. new registrations, re-registrations or +de-registrations) eventually also propagate into the SQL +database, thanks to a separate timer routine. This dramatically +speeds up registrations, but also introduces the +possibility of crashing before the latest contact changes are +propagated to the database. See the +[timer interval](#param_timer_interval) for additional configuration. + + +*Default value is *"none" (no added SQL writes)*.* + + +```opensips title="Set sql_write_mode parameter" +... +modparam("usrloc", "sql_write_mode", "write-back") +... +``` + + +#### matching_mode (integer) + + +What contact matching algorithm to be used. Refer to section +[contact matching](#contact_matching) for the description of the +algorithms. + + +The parameter may take the following values: + + +- *0* - CONTACT ONLY based matching +algorithm. +- *1* - CONTACT and CALLID based +matching algorithm. + + +*Default value is *0 (CONTACT_ONLY)*.* + + +```opensips title="Set matching_mode parameter" +... +modparam("usrloc", "matching_mode", 1) +... +``` + + +#### cseq_delay (integer) + + +Delay (in seconds) for accepting as retransmissions register requests +with same Call-ID and Cseq. The delay is calculated starting from the +receiving time of the first register with that Call-ID and Cseq. + + +Retransmissions within this delay interval will be accepted and replied +as the original request, but no update will be done in location. If the +delay is exceeded, error is reported. + + +A value of 0 disable the retransmission detection. + + +*Default value is "20 seconds".* + + +```opensips title="Set cseq_delay parameter" +... +modparam("usrloc", "cseq_delay", 5) +... +``` + + +#### location_cluster (integer) + + +Specifies the cluster ID which this instance will send to and receive +from all user-location related information +(*addresses-of-record*, *contacts*), +organized into specific events (inserts, deletes or updates). + + +This OpenSIPS cluster exposes the **"usrloc-contact-repl"** +capability in order to mark nodes as eligible for becoming data donors during an +arbitrary sync request. Consequently, the cluster must have *at least +one node* marked with the **"seed"** value +as the *clusterer.flags* column/property in order to be fully functional. +Consult the [clusterer - Capabilities](../clusterer#capabilities) +chapter for more details. + + +Default value is 0 (replication disabled). + + +More details on the user location distribution mechanisms are +available under [distributed sip user location](#distributed_sip_user_location). + + +```opensips title="Setting the location_cluster parameter" +... +modparam("usrloc", "location_cluster", 1) +... +``` + + +#### ha_cluster (integer) + + +Only relevant in **"federation-cachedb"** +[cluster mode](#param_cluster_mode). Denotes the HA cluster ID to use in +order to establish the active node within the HA pair, such that only +that node performs WRITE operations to CacheDB. + + +Default value is 0 (disabled). + + +```opensips title="Setting the ha_cluster parameter" +... +modparam("usrloc", "ha_cluster", 4) +... +``` + + +#### ha_shtag (string) + + +Only relevant in **"federation-cachedb"** +[cluster mode](#param_cluster_mode). Denotes the HA cluster sharing tag to +use in order to establish the active node within the HA pair, such that +only that node performs WRITE operations to CacheDB. + + +Default value is NULL (disabled). + + +```opensips title="Setting the ha_shtag parameter" +... +modparam("usrloc", "ha_shtag", "vip2") +... +``` + + +#### skip_replicated_db_ops (int) + + +Prevent OpenSIPS from performing any DB-related contact operations +when events are received over the *Binary Interface*. +This is commonly used to prevent unneeded duplicate operations. + + +Default value is "0" (upon receival of usrloc-related Binary Interface +events, DB queries may be freely performed) + + +More details on the user location replication mechanism are available +in [distributed sip user location](#distributed_sip_user_location) + + +```opensips title="Setting the skip_replicated_db_ops parameter" +... +modparam("usrloc", "skip_replicated_db_ops", 1) +... +``` + + +#### max_contact_delete (int) + + +Relevant only in WRITE_THROUGH or WRITE_BACK schemes. The maximum +number of contacts to be deleted from the database at once. Will delete +all of them, if fewer after passing through all the contacts. + + +Default value is "10" + + +```opensips title="Setting the max_contact_delete parameter" +... +modparam("usrloc", "max_contact_delete", 10) +... +``` + + +#### hash_size (integer) + + +The number of entries of the hash table used by usrloc to store the +location records is 2^hash_size. For hash_size=4, the number of entries +of the hash table is 16. Since version 2.2, the maximu size of this +parameter is 16, meaning that the hash supports maximum 65536 entries. + + +*Default value is "9".* + + +```opensips title="Set hash_size parameter" +... +modparam("usrloc", "hash_size", 10) +... +``` + + +#### regen_broken_contactid (integer) + + +Since version 2.2, **contact_id** concept +was introduced. Since this parameter validates a contact each time OpenSIPS +is started, there are times when the value of this parameter should be +regenerated. That is when **location** table +is being migrated from a version older than 2.2 or when +**hash_size** module parameter is changed. +Enabling this parameter will regenerate broken contact id's based on +current configurations. + + +*Default value is "0(not enabled)"* + + +```opensips title="Set regen_broken_contactid parameter" +... +modparam("usrloc", "regen_broken_contactid", 1) +... +``` + + +#### latency_event_min_us (integer) + + +Defines a minimal pinging latency threshold, in microseconds, past +which contact pinging latency update events will get raised. By +default, an event is raised for each ping reply (i.e. latency update). + + +If both [latency event min us](#param_latency_event_min_us) and +[latency event min us delta](#param_latency_event_min_us_delta) are set, the event +will get raised if either of them is true. + + +*Default value is "0 (no bottom limit set)".* + + +```opensips title="Set latency_event_min_us parameter" +... +# raise an event for any 425+ ms pinging latency +modparam("usrloc", "latency_event_min_us", 425000) +... +``` + + +#### latency_event_min_us_delta (integer) + + +Defines a minimal, absolute pinging latency difference, in +microseconds, past which contact pinging latency update events will get +raised. The difference is computed using the latencies of the last two +contact pinging replies. By default, an event is raised for each ping +reply (i.e. latency update). + + +If both [latency event min us](#param_latency_event_min_us) and +[latency event min us delta](#param_latency_event_min_us_delta) are set, the event +will get raised if either of them is true. + + +*Default value is "0 (no minimal latency delta set)".* + + +```opensips title="Set latency_event_min_us_delta parameter" +... +# raise an event only if a contact has pinging latency swings of 300+ ms +modparam("usrloc", "latency_event_min_us_delta", 300000) +... +``` + + +#### pinging_mode (string) + + +Depending on the [cluster mode](#param_cluster_mode), the module +can perform contact pinging using one of two possible heuristics: + + +- **"ownership"** - this instance +will only attempt to ping a contact if it decides it is the +logical owner of the contact. If a shared tag is attached to +a contact, a node will keep sending pings to that contact as +long as it owns the respective tag. If no shared tag has been +specified for a given contact, the default is to assume +permanent ownership of the contact and ping it upon request. +- **"cooperation"** - the +assumption behind this pinging heuristic is that all +user location cluster nodes are symmetrical (possibly +front-ended by a SIP traffic balancing entity), such that +**either** of them can ping +**any** contact. +Under this assumption, all currently online user location +cluster nodes will cooperate and evenly split the pinging +workload between them by hashing AoRs modulo +current_number_of_online_nodes, and only picking the ones that +they are responsible for. + + +**Possible values for the "pinging_mode", +depending on the current "cluster_mode"** + + +| | | | | | | +| --- | --- | --- | --- | --- | --- | +| [cluster mode](#param_cluster_mode) | none | federation-cachedb | full-sharing | full-sharing-cachedb | sql-only | +| [pinging mode](#param_pinging_mode) | **ownership** | **ownership** | **cooperation** / ownership | **cooperation** | *unmaintained* | + + +Notice that only the **"full-sharing"** +clustering mode allows some flexibility -- all other modes are +logically tied to a single pinging logic. Any unaccepted value, +according to the above table, set +for those modes will be silently discarded. + + +```opensips title="Set pinging_mode parameter" +... +# prepare an active/backup "full-sharing" setup, with no front-end +modparam("usrloc", "pinging_mode", "ownership") +... +``` + + +#### mi_dump_kv_store (integer) + + +Enable in order to include the "KV-Store" field in all usrloc MI +commands which output AoR or Contact representations. This verbose +field contains custom data attached to each of these two entities. +mid_registrar makes use of both of these holders, for example. + + +*Default value is "0 (disabled)".* + + +```opensips title="Set mi_dump_kv_store parameter" +... +# include the "KV-Store" key in all usrloc MI output +modparam("usrloc", "mi_dump_kv_store", 1) +... +``` + + +#### contact_refresh_timer (boolean) + + +Enable a timer which will periodically scan a sorted list of contacts +and raise the [E UL CONTACT REFRESH](#event_e_ul_contact_refresh) for any of +them which are past their re-registration time interval limit. This +limit may given by registrar's *pn_trigger_interval* +module parameter, for example. + + +*Default value is "false (disabled)".* + + +```opensips title="Set contact_refresh_timer parameter" +... +modparam("usrloc", "contact_refresh_timer", true) +... +``` + + +### Exported Functions + + +#### ul_add_key(domain, aor, key_name, [key_value]) + + +Append a Key/Value to the Key-Value-Store of a Usrloc-Record. + + +Returns false, if no record is found is usrloc. + + +Meaning of the parameters is as follows: + + +- *domain (string)* - Domain of the +AOR, e.g. "location" +- *aor (string)* - Address-of-Record, +save the key for a specific (registered) user. +- *key (string)* - The name of the +key to be stored. +- *value (string, optional)* + - The value to be stored. Not providing the value or +by providing an empty value, will delete the entry. + + +This function can be used in ANY route. + + +```opensips title="ul_add_key usage" +... +ul_add_key("location", "$tU@$td", "service_route", "$hdr(Service-Route)"); +... +``` + + +#### ul_get_key(domain, aor, key_name, destination) + + +Retrieve a Key/Value from the Key-Value-Store of a Usrloc-Record. + + +Returns false, if no record is found is usrloc or no according key is found. + + +Meaning of the parameters is as follows: + + +- *domain (string)* - Domain of the +AOR, e.g. "location" +- *aor (string)* - Address-of-Record, +save the key for a specific (registered) user. +- *key (string)* - The name of the +key to be retrieved. +- *destination (variable)* + - A variable, where to store the retrieved key. + + +This function can be used in ANY route. + + +```opensips title="ul_get_key usage" +... +if (ul_get_key("location", "$tU@$td", "service_route", $avp(service_route))) { + append_to_reply("Service-Route: $avp(service_route)\r\n"); +} +... +``` + + +#### ul_del_key(domain, aor, key_name) + + +Deletes a Key/Value from the Key-Value-Store of a Usrloc-Record. + + +Returns false, if no record is found is usrloc. + + +Meaning of the parameters is as follows: + + +- *domain (string)* - Domain of the +AOR, e.g. "location" +- *aor (string)* - Address-of-Record, +save the key for a specific (registered) user. +- *key (string)* - The name of the +key to be deleted. + + +This function can be used in ANY route. + + +```opensips title="ul_del_key usage" +... +ul_del_key("location", "$tU@$td", "service_route"); +... +``` + + +### Exported MI Functions + + +#### ul_rm + + +Deletes an entire AOR record (including its contacts). + + +Parameters: + + +- *table_name* - table where the AOR +is removed from (Ex: location). +- *aor* - user AOR in username[@domain] +format (domain must be supplied only if use_domain option +is on). + + +#### ul_rm_contact + + +Deletes a contact from an AOR record. + + +Parameters: + + +- *table name* - table where the AOR +is removed from (Ex: location). +- *AOR* - user AOR in username[@domain] +format (domain must be supplied only if use_domain option +is on). +- *contact* - exact contact to be removed + + +#### ul_dump + + +Dumps the entire content of the USRLOC in memory cache + + +Parameters: + + +- *brief* - (optional, may not be present); if +equals to string "brief", a brief dump will be +done (only AOR and contacts, with no other details) + + +#### ul_flush + + +Force a flush of all pending usrloc cache changes to the database. +Normally, this routine runs every +[timer interval](#param_timer_interval) seconds. + + +#### ul_add + + +Adds a new contact for an user AOR. + + +Parameters: + + +- *table name (string)* - table where the contact +will be added (Ex: "location"). +- *aor (string)* - user AOR in username[@domain] +format (domain must be supplied only if use_domain option +is on). +- *contact (string)* - Contact URI to be added +- *expires (int)* - expires value of the contact +- *q (string)* - Q value of the contact +- *flags (int)* - internal USRLOC flags of the +contact +- *cflags (int)* - per branch flags of the +contact +- *methods (int)* - bitmask with supported requests +of the contact. To whitelist all SIP methods, simply use the +value **32767**. For a breakdown +of each method's value, see the "request_method" internal enum. + + +#### ul_show_contact + + +Dumps the contacts of an user AOR. + + +Parameters: + + +- *table_name* - table where the AOR +resides (Ex: location). +- *aor* - user AOR in username[@domain] +format (domain must be supplied only if use_domain option +is on). + + +#### ul_sync + + +Empty the location table, then synchronize it with all contacts from +memory. Note that this can not be used when no database is specified +or with the DB-Only scheme. + + +Important: make sure that all your contacts are in memory +(*ul_dump* MI function) before executing this +command. + + +Parameters: + + +- *table name* - table where the AOR +resides (Ex: location). +- *AOR (optional)* - only delete/sync this +user AOR, not the whole table. Format: "username[@domain]" +(*domain* is required only if +[use domain](#param_use_domain) option is on). + + +#### ul_cluster_sync + + +This command will only take effect if the target OpenSIPS instance is +paired with a hot backup instance, while running under a +cluster-enabled [working mode preset](#param_working_mode_preset). + + +The current node will locate a healthy donor node within the +[location cluster](#param_location_cluster) and issue a sync request to +it. The donor node will then proceed to push all of its user location +data over to the current node, via the binary interface. The received +data will be merged with existing data. Conflicting contacts (matched +according to [matching mode](#param_matching_mode)) are overwritten +only if the sync data is newer than the current data. + + +### Exported Statistics + + +Exported statistics are listed in the next sections. + + +#### users + + +Number of AOR existing in the USRLOC memory cache for that domain + - can not be resetted; this statistic will be register for each +used domain (Ex: location). + + +#### contacts + + +Number of contacts existing in the USRLOC memory cache for that +domain - can not be resetted; this statistic will be register for +each used domain (Ex: location). + + +#### expires + + +Total number of expired contacts for that domain - can be resetted; +this statistic will be register for each used domain +(Ex: location). + + +#### registered_users + + +Total number of AOR existing in the USRLOC memory cache for all +domains - can not be resetted. + + +### Exported Events + + +#### E_UL_AOR_INSERT + + +This event is raised when a new AOR is inserted in the USRLOC +memory cache. + + +Parameters: + + +- *domain* - The name of the table. +- *aor* - The AOR of the inserted record. + + +#### E_UL_AOR_DELETE + + +This event is raised when a new AOR is deleted from the USRLOC +memory cache. + + +Parameters: + + +- *domain* - The name of the table. +- *aor* - The AOR of the deleted record. + + +#### E_UL_CONTACT_INSERT + + +This event is raised when a new contact is inserted in any of the +existing AOR's contact list. For each new contact, if its AOR does +not exist in the memory, then both the E_UL_AOR_CREATE and +E_UL_CONTACT_INSERT events will be raised. + + +Parameters: + + +- *domain* - The name of the table. +- *aor* - The AOR of the inserted contact. +- *uri* - The contact URI of the inserted +contact. +- *received* - IP, port and protocol the +registration message was received from. If these have the +same value as the contact's address (see the address parameter) +then the received parameter will be an empty string. +- *path* - The PATH header value of the +registration message.(empty string if not present) +- *qval* - The Q value (priority) of the +contact (as integer value from 0 to 10). +- *user_agent* - The User-Agent header +value. +*NOTICE:*Can contain spaces. +- *socket* - The SIP socket/listener +(as string) used by OpenSIPS to receive the contact +registations. +- *bflags* - The branch flags (bflags) of the +contact (in integer value of the bitmask) +- *expires* - The expires value of the +contact (as UNIX timestamp integer). +- *callid* - The Call-ID header of the +registration message. +- *cseq* - The cseq number as an int value. +- *attr* - The attributes string attached +to the contact (the custom attributes attached from the +script level). As this string is options, if missing in the +contact, the event will push the empty string for this event +field. +- *latency* - The latency of the last +successful ping for this contact, in microseconds. Until the +first ping reply for a given contact arrives, its pinging +latency will be 0. +- *shtag* - The shared tag of the contact, +which helps determine if the current node owns the contact +(e.g. possibly using the **$cluster.sh_tag** pseudo-variable in order to perform the check). +*NOTICE:*If a contact has no shared tag +attached to it, the value of this parameter will be "" (empty +string)! + + +#### E_UL_CONTACT_DELETE + + +This event is raised when a contact is deleted from an +existing AOR's contact list. If the contact is the only one in +the list then both the E_UL_AOR_DELETE and +E_UL_CONTACT_DELETE events will be raised. + + +Parameters: same as the +[E UL CONTACT INSERT](#event_e_ul_contact_insert) event + + +#### E_UL_CONTACT_UPDATE + + +This event is raised when a contact's info is updated by receiving +another registration message. + + +Parameters: same as the +[E UL CONTACT INSERT](#event_e_ul_contact_insert) event + + +#### E_UL_CONTACT_REFRESH + + +This event may only be raised for RFC 8599 (Push Notification) +enabled contacts. + + +Set [contact refresh timer](#param_contact_refresh_timer) to +*true* in order to enable this event. The event is +raised within reasonable time before an RFC 8599 enabled contact +will expire, such that the script writer can take action, +possibly force a registration refresh from the endpoint. + + +Parameters: + + +- *domain* - The name of the table. +- *aor* - The AOR of the inserted contact. +- *uri* - The contact URI of the inserted +contact. +- *received* - IP, port and protocol the +registration message was received from. If these have the +same value as the contact's address (see the address parameter) +then the received parameter will be an empty string. +- *user_agent* - The User-Agent header +value. +*NOTICE:*Can contain spaces. +- *socket* - The SIP socket/listener +(as string) used by OpenSIPS to receive the contact +registations. +- *bflags* - The branch flags (bflags) of the +contact (in integer value of the bitmask) +- *expires* - The expires value of the +contact (as UNIX timestamp integer). +- *callid* - The Call-ID header of the +registration message. +- *attr* - The attributes string attached +to the contact (the custom attributes attached from the +script level). As this string is options, if missing in the +contact, the event will push the empty string for this event +field. +- *shtag* - The shared tag of the contact, +which helps determine if the current node owns the contact +(e.g. possibly using the **$cluster.sh_tag** pseudo-variable in order to perform the check). +- *reason* - the reason why the binding refresh +event was triggered. Possible values: + - "reg-refresh" - periodic refresh triggered by OpenSIPS + - "ini-INVITE", "ini-SUBSCRIBE", etc. - a refresh + triggered by an incoming initial SIP request + - "mid-INVITE", "mid-BYE", etc. - a refresh triggered + by an incoming mid-dialog SIP request +- *req_callid* - the Call-ID of the SIP request +which triggered this event, if any. This gives the ability to +logically link the pending request with the current event and +access useful data from that request (e.g. caller identity, +dialed number, etc.). +Using the *req_callid*, if a dialog has been +created for the pending request, this dialog may be temporarily +loaded inside the event_route using the +[load_dialog_ctx()](../dialog#func_load_dialog_ctx) and +[unload_dialog_ctx()](../dialog#func_unload_dialog_ctx) +functions of the dialog module. + + +#### E_UL_LATENCY_UPDATE + + +This event is raised when a contact pinging latency matches either +of the [latency event min us](#param_latency_event_min_us) or +[latency event min us delta](#param_latency_event_min_us_delta) filters. If none of +these filters is set, this event will get raised for each successful +contact ping operation. + + +Parameters: same as the +[E UL CONTACT INSERT](#event_e_ul_contact_insert) event + + +## Developer Guide + + +### Available Functions + + +#### ul_register_domain(name) + + +The function registers a new domain. Domain is just another name for +table used in registrar. The function is called from fixups in +registrar. It gets name of the domain as a parameter and returns +pointer to a new domain structure. The fixup than 'fixes' the +parameter in registrar so that it will pass the pointer instead of the +name every time save() or lookup() is called. Some usrloc functions +get the pointer as parameter when called. For more details see +implementation of save function in registrar. + + +Meaning of the parameters is as follows: + + +- *const char* name* - Name of the domain +(also called table) to be registered. + + +#### ul_insert_urecord(domain, aor, rec, is_replicated) + + +The function creates a new record structure and inserts it in the +specified domain. The record is structure that contains all the +contacts for belonging to the specified username. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Pointer to domain +returned by ul_register_udomain. +- *str* aor* - Address of Record (aka +username) of the new record (at this time the record will +contain no contacts yet). +- *urecord_t** rec* - The newly created +record structure. +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_delete_urecord(domain, aor, is_replicated) + + +The function deletes all the contacts bound with the given Address +Of Record. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Pointer to domain +returned by ul_register_udomain. +- *str* aor* - Address of record (aka +username) of the record, that should be deleted. +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_get_urecord(domain, aor) + + +The function returns pointer to record with given Address of Record. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Pointer to domain +returned by ul_register_udomain. + + +- *str* aor* - Address of Record of request +record. + + +#### ul_lock_udomain(domain) + + +The function lock the specified domain, it means, that no other +processes will be able to access during the time. This prevents race +conditions. Scope of the lock is the specified domain, that means, +that multiple domain can be accessed simultaneously, they don't block +each other. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Domain to be locked. + + +#### ul_unlock_udomain(domain) + + +Unlock the specified domain previously locked by ul_lock_udomain. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Domain to be +unlocked. + + +#### ul_release_urecord(record, is_replicated) + + +Do some sanity checks - if all contacts have been removed, delete +the entire record structure. + + +Meaning of the parameters is as follows: + + +- *urecord_t* record* - Record to be +released. +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_insert_ucontact(record, contact, contact_info, contact, is_replicated) + + +The function inserts a new contact in the given record with +specified parameters. + + +Meaning of the parameters is as follows: + + +- *urecord_t* record* - Record in which +the contact should be inserted. +- *str* contact* - Contact URI. +- *ucontact_info_t* contact_info* - +Single structure containing the new contact information +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_delete_ucontact (record, contact, is_replicated) + + +The function deletes given contact from record. + + +Meaning of the parameters is as follows: + + +- *urecord_t* record* - Record from which +the contact should be removed. + + +- *ucontact_t* contact* - Contact to be +deleted. +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_delete_ucontact_from_id (domain, contact_id) + + +The function deletes a contact with the given contact_id from +the given domain. + + +Meaning of the parameters is as follows: + + +- *udomain_t* domain* - Domain where +the contact can be found. + + +- *uint64_t contact_id* - Contact_id +identifying the contact to be deleted. + + +#### ul_get_ucontact(record, contact) + + +The function tries to find contact with given Contact URI and +returns pointer to structure representing the contact. + + +Meaning of the parameters is as follows: + + +- *urecord_t* record* - Record to be +searched for the contact. + + +- *str_t* contact* - URI of the request +contact. + + +#### ul_get_domain_ucontacts (domain, buf, len, flags) + + +The function retrieves all contacts of all registered users from the +given doamin and returns them in the caller-supplied buffer. If the +buffer is too small, the function returns positive value indicating +how much additional space would be necessary to accommodate all of +them. Please note that the positive return value should be used only +as a "hint", as there is no guarantee that during the time +between two subsequent calls number of registered contacts will +remain the same. + + +If flag parameter is set to non-zero value then only contacts that +have the specified flags set will be returned. It is, for example, +possible to list only contacts that are behind NAT. + + +Meaning of the parameters is as follows: + + +- *udomaint_t* domain* - Domain from which +to get the contacts + + +- *void* buf* - Buffer for returning +contacts. + + +- *int len* - Length of the buffer. + + +- *unsigned int flags* - Flags that must +be set. + + +#### ul_get_all_ucontacts (buf, len, flags) + + +The function retrieves all contacts of all registered users and +returns them in the caller-supplied buffer. If the buffer is too small, +the function returns positive value indicating how much additional +space would be necessary to accommodate all of them. Please note +that the positive return value should be used only as a +"hint", as there is no guarantee that during the time +between two subsequent calls number of registered contacts will +remain the same. + + +If flag parameter is set to non-zero value then only contacts that +have the specified flags set will be returned. It is, for example, +possible to list only contacts that are behind NAT. + + +Meaning of the parameters is as follows: + + +- *void* buf* - Buffer for returning +contacts. + + +- *int len* - Length of the buffer. + + +- *unsigned int flags* - Flags that must +be set. + + +#### ul_update_ucontact(record, contact, contact_info, is_replicated) + + +The function updates contact with new values. + + +Meaning of the parameters is as follows: + + +- *urecord_t* record* - Record in which +the contact should be inserted. +- *ucontact_t* contact* - Contact URI. +- *ucontact_info_t* contact_info* - +Single structure containing the new contact information +- *char is_replicated* - Specifies whether +this function will be called from the context of a Binary Interface +callback. If uncertain, simply use 0. + + +#### ul_bind_ursloc( api ) + + +The function imports all functions that are exported by the +USRLOC module. Overs for other modules which want to user the +internal USRLOC API an easy way to load and access the functions. + + +Meaning of the parameters is as follows: + + +- *usrloc_api_t* api* - USRLOC API + + +#### ul_register_ulcb(type ,callback, param) + + +The function register with USRLOC a callback function to be called +when some event occures inside USRLOC. + + +Meaning of the parameters is as follows: + + +- *int types* - type of event for which +the callback should be called (see usrloc/ul_callback.h). +- *ul_cb f* - callback function; see +usrloc/ul_callback.h for prototype. +- *void *param* - some parameter to be +passed to the callback each time when it is called. + + +#### ul_get_num_users() + + +The function loops through all domains summing up the number of users. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/usrloc/doc/contributors.xml b/modules/usrloc/doc/contributors.xml deleted file mode 100644 index 6c60f0e9b70..00000000000 --- a/modules/usrloc/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Jan Janak (@janakj) - 416 - 117 - 15689 - 10095 - - - 2. - Liviu Chircu (@liviuchircu) - 358 - 215 - 9395 - 3830 - - - 3. - Bogdan-Andrei Iancu (@bogdan-iancu) - 246 - 150 - 4232 - 3624 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - 43 - 25 - 794 - 661 - - - 5. - Ionut Ionita (@ionutrazvanionita) - 41 - 24 - 1099 - 413 - - - 6. - Daniel-Constantin Mierla (@miconda) - 40 - 29 - 544 - 308 - - - 7. - Jiri Kuthan (@jiriatipteldotorg) - 36 - 25 - 975 - 120 - - - 8. - Razvan Crainea (@razvancrainea) - 31 - 24 - 427 - 159 - - - 9. - Henning Westerholt (@henningw) - 21 - 11 - 462 - 356 - - - 10. - Maksym Sobolyev (@sobomax) - 19 - 13 - 347 - 162 - - - -
-All remaining contributors: Andrei Pelinescu-Onciul, Vlad Paiu (@vladpaiu), Walter Doekes (@wdoekes), Nils Ohlmeier, Eseanu Marius Cristian (@eseanucristian), Ovidiu Sas (@ovidiusas), Ionel Cerghit (@ionel-cerghit), Andrei Dragus, Anca Vamanu, Alessio Garzi (@Ozzyboshi), Zero King (@l2dy), Dusan Klinec (@ph4r05), Andrei Datcu (@andrei-datcu), Carsten Bock, Juha Heinanen (@juha-h), Marcus Hunger, Jamey Hicks, Norman Brandinger (@NormB), Peter Lemenkov (@lemenkov), Andreas Granig, Shlomi Gutman, @jalung, Jeffrey Magder, Phil D'Amore, David Sanders, Konstantin Bokarius, Klaus Darilion, Iouri Kharon, Aron Podrigal (@ar45), Alexandra Titoc, Dan Pascu (@danpascu), Gang Zhuo, Matthew M. Boedicker, UnixDev, Edson Gellert Schubert, Alexey Vasilyev (@vasilevalex), Elena-Ramona Modroiu, Stephane Alnet. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Norman Brandinger (@NormB) - Aug 2006 - May 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jan 2013 - Feb 2025 - - - 3. - Gang Zhuo - Nov 2024 - Nov 2024 - - - 4. - Alexandra Titoc - Sep 2024 - Sep 2024 - - - 5. - Carsten Bock - Mar 2024 - Mar 2024 - - - 6. - Maksym Sobolyev (@sobomax) - Apr 2003 - Dec 2023 - - - 7. - Vlad Paiu (@vladpaiu) - Jun 2011 - Jul 2023 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - Jul 2016 - Mar 2023 - - - 9. - Razvan Crainea (@razvancrainea) - Jul 2011 - Jan 2023 - - - 10. - Bogdan-Andrei Iancu (@bogdan-iancu) - Mar 2002 - Feb 2022 - - - -
-All remaining contributors: Walter Doekes (@wdoekes), Zero King (@l2dy), Peter Lemenkov (@lemenkov), Alexey Vasilyev (@vasilevalex), Aron Podrigal (@ar45), Alessio Garzi (@Ozzyboshi), Dan Pascu (@danpascu), Shlomi Gutman, @jalung, Ionut Ionita (@ionutrazvanionita), Ionel Cerghit (@ionel-cerghit), Ovidiu Sas (@ovidiusas), Dusan Klinec (@ph4r05), Eseanu Marius Cristian (@eseanucristian), David Sanders, Andrei Datcu (@andrei-datcu), Stephane Alnet, Andrei Dragus, Phil D'Amore, UnixDev, Daniel-Constantin Mierla (@miconda), Henning Westerholt (@henningw), Iouri Kharon, Konstantin Bokarius, Edson Gellert Schubert, Anca Vamanu, Matthew M. Boedicker, Marcus Hunger, Elena-Ramona Modroiu, Jeffrey Magder, Andreas Granig, Juha Heinanen (@juha-h), Klaus Darilion, Jan Janak (@janakj), Andrei Pelinescu-Onciul, Jiri Kuthan (@jiriatipteldotorg), Jamey Hicks, Nils Ohlmeier. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Norman Brandinger (@NormB), Liviu Chircu (@liviuchircu), Carsten Bock, Zero King (@l2dy), Alexey Vasilyev (@vasilevalex), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Bogdan-Andrei Iancu (@bogdan-iancu), Razvan Crainea (@razvancrainea), Ionut Ionita (@ionutrazvanionita), Eseanu Marius Cristian (@eseanucristian), Ovidiu Sas (@ovidiusas), Andrei Datcu (@andrei-datcu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Henning Westerholt (@henningw), Marcus Hunger, Elena-Ramona Modroiu, Juha Heinanen (@juha-h), Jan Janak (@janakj), Maksym Sobolyev (@sobomax), Nils Ohlmeier. -
- -
diff --git a/modules/usrloc/doc/usrloc.xml b/modules/usrloc/doc/usrloc.xml deleted file mode 100644 index d77cbdef0e8..00000000000 --- a/modules/usrloc/doc/usrloc.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - -%docentities; - -]> - - - - usrloc Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2018 &osipssol; - ©right; 2005-2008 &voicesystem; - ©right; 2003 &fhg; - - diff --git a/modules/usrloc/doc/usrloc_admin.xml b/modules/usrloc/doc/usrloc_admin.xml deleted file mode 100644 index d68a3260d3b..00000000000 --- a/modules/usrloc/doc/usrloc_admin.xml +++ /dev/null @@ -1,2170 +0,0 @@ - - - - - &adminguide; - -
- Overview - - A SIP user location implementation. Its main purpose is to store, - manage and provide access to SIP registration bindings (contacts) for - other modules (e.g. registrar, mid-registrar, nathelper, etc.). The - module exports no functions that could be directly used from the - OpenSIPS script. - - - At runtime, the contacts may reside in memory, in an SQL database or in - a NoSQL database. Combinations of two of the above are also possible. - For example, contacts may only be directly manipulated in memory in - order to guarantee fast interactions while being asynchronously - synchronized to an SQL database. The latter helps achieve restart - persistency. Consult the - - parameter for more details on all possible runtime behaviors of the - module. - - - The OpenSIPS user location implementation is cluster-enabled. On top of - supporting traditional "single instance" setups, it also allows multiple - OpenSIPS user location nodes to form a single, global user location cluster. - This allows high-level features such as startup synchronization (data - tunneling) from a random, healthy "donor" node and evenly distributed - NAT pinging workloads. - -
- -
- Distributed SIP User Location - - Starting with OpenSIPS 2.4, the user location module offers several optional - data distribution models, each tailoring to specific real-life production use cases. - Built on top of the OpenSIPS clustering module, these models take into - account service concerns such as high availability, geographical - distribution, horizontal scalability and NAT traversal. - - - Depending on data locality, the distribution models are split in two main - categories: - -
- "Federation" Topology - - A federated user location keeps contact data local - to the original OpenSIPS node the contact initially registered to. In - order to share the reachability of these contacts with the global - OpenSIPS user location cluster, registrar nodes will only publish some - light "metadata" entries for any new Addresses-of-Record which are - reachable from them. These entries will cause other nodes to also fork - additional SIP branches pointing to the publisher registrar upon - receiving calls for its advertised Addresses-of-Record. - - - The federation topology is an - optimized solution for the following core problems: - - - - IP address restrictions - In some - cases, calls routed towards registered contacts must necessarily - pass through the original registration nodes of these contacts. A - classic example of this situation is when an OpenSIPS registrar - sitting at the edge of the platform is directly facing a NAT device - on the way to the contact. Unless calls are sent out from this - exact registrar, they will not be able to traverse the NAT device - and reach the contact. - - - - - horizontal scalability - Avoiding - global replication/contact broadcasting within the cluster not only - dramatically improves contact storage performance, but also leads - to better service scalability. Different geographical locations can - be sized according to their local subscriber populations (traffic - may be balanced to them using DNS SRV weights, for example), - without losing platform-wide reachability. - - - - - - Currently, the metadata information may be published to NoSQL databases - which support key/multi-value column-like associations. Example known - backends to support these abstractions at the time of writing are - MongoDB and Cassandra. - - - The - federated user location tutorial - contains precise details on how to achieve this setup (including High - Availability support). - -
-
- "Full Sharing" Topology - - A fully sharing user location broadcasts contact - information to all data nodes (OpenSIPS or NoSQL). - The main assumption behind this mode is that any routing - restrictions have been alleviated beforehand. Consequently, either SIP - traffic egressing from a "full sharing" - OpenSIPS user location topology is being intermediated by an - additional SIP edge endpoint of our platform, or there are no egress IP - restrictions at all (for example, if all SIP UAs have public IPs). In - this setup, all OpenSIPS user location nodes are - equivalent to one another, as they each have - access to the same dataset and have no routing restrictions. - - - The full sharing topology is - an appropriate solution for multi-layer VoIP platforms, where the - OpenSIPS registrar nodes do not directly interact with external SIP - endpoints. Moreover, it can be configured to fully store contact data - within a NoSQL cluster (zero in-memory storage), thus taking full - advantage of the data sharing, sharding, migration and other - capabilities of a specialized distributed data handling engine. - - - Additionally, a "full sharing" topology can be used to achieve a basic - "hot backup" high-availability setup with an active-passive registrar - nodes configuration, both of which make use of a shared virtual IP. - - - Registrations may optionally be fully managed inside NoSQL - databases which support key/multi-value column-like associations. - Example known backends to currently support these abstractions are MongoDB - and Apache Cassandra. - - - The - "full sharing" user location tutorial - contains precise details on how to achieve this setup (including full - NoSQL storage support). - -
-
- "N Contact Pings" Problem - - A long-standing problem caused by contact information being replicated - to multiple SIP registrar instances directly through replication or - indirectly through a globally reachable database. As long as - traditionally clusterized nodes are not aware of - each other, they will each scan the entire contact dataset, thus - periodically sending "N pings" instead of "1 ping" for each contact. - This difference directly affects service scalability, as well as the - amount of consumed resources such as CPU and network - bandwidth, both on the service and client side. - - - This problem is solved with the help of the OpenSIPS cluster layer, - which makes all nodes aware of each others' presence. Thus, the - distributed user location node topologies are able to collectively - partition the pinging workload and spread it evenly across the current - number of cluster nodes, at any given point in time. The - module parameter describes the - built-in pinging heuristics in more detail. - -
-
- -
- Contact matching - - Contact matching (for the same Address-of-Record, AoR) is an important - aspect of a SIP user location service, especially in the context of NAT - traversal. The latter raises more problems, since contacts from different - phones of same users may overlap (if behind NATs with identical - configurations) or the re-register Contact of the same SIP User Agent may - be seen as a new one (due to the request arriving via a new NAT binding). - - - The SIP RFC 3261 publishes a matching algorithm based only on the - contact string with Call-ID and CSeq number extra checking (if the Call-ID - matches, it must have a higher CSeq number, otherwise the registration is - invalid). But as argumented above, this is not enough in a NAT traversal - context, so the &osips; implementation of contact matching offers more - algorithms: - - - - - Contact based only - strict RFC 3261 - compliancy - the contact is matched as string and extra checked - via Call-ID and CSeq (if Call-ID is the same, it must have a - higher CSeq number, otherwise the registration is invalid). - - - - - Contact and Call-ID based - an extension - of the first case - the Contact and Call-ID header field values - must match as strings; the CSeq must be higher than the previous - one - so be careful how you deal with REGISTER retransmissions in - this case. - - - - - For more details on how to control/select the contact matching algorithm, - please go to - . - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - Optionally an SQL database module. - - - - - Optionally a NoSQL database module. - - - - - clusterer, if - is different than "none". - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
-
- Exported Parameters -
- <varname>nat_bflag</varname> (string) - - The name of the branch flag to be used as NAT marker (if the contact - is or not natted). This is a branch flag and it will be imported and - used by all other modules depending on the usrloc module. - - - - Default value is NULL (not set). - - - - Set <varname>nat_bflag</varname> parameter - -... -modparam("usrloc", "nat_bflag", "NAT_BFLAG") -... - - -
- -
- <varname>contact_id_column</varname> (string) - - Name of the column holding the unique contact IDs. - - - - Default value is contact_id. - - - - Set <varname>contact_id_column</varname> parameter - -... -modparam("usrloc", "contact_id_column", "ctid") -... - - -
- -
- <varname>user_column</varname> (string) - - Name of column containing usernames. - - - - Default value is username. - - - - Set <varname>user_column</varname> parameter - -... -modparam("usrloc", "user_column", "username") -... - - -
- -
- <varname>domain_column</varname> (string) - - Name of column containing domains. - - - - Default value is domain. - - - - Set <varname>user_column</varname> parameter - -... -modparam("usrloc", "domain_column", "domain") -... - - -
- -
- <varname>contact_column</varname> (string) - - Name of column containing contacts. - - - - Default value is contact. - - - - Set <varname>contact_column</varname> parameter - -... -modparam("usrloc", "contact_column", "contact") -... - - -
- -
- <varname>expires_column</varname> (string) - - Name of column containing expires value. - - - - Default value is expires. - - - - Set <varname>expires_column</varname> parameter - -... -modparam("usrloc", "expires_column", "expires") -... - - -
- -
- <varname>q_column</varname> (string) - - Name of column containing q values. - - - - Default value is q. - - - - Set <varname>q_column</varname> parameter - -... -modparam("usrloc", "q_column", "q") -... - - -
- -
- <varname>callid_column</varname> (string) - - Name of column containing callid values. - - - - Default value is callid. - - - - Set <varname>callid_column</varname> parameter - -... -modparam("usrloc", "callid_column", "callid") -... - - -
- -
- <varname>cseq_column</varname> (string) - - Name of column containing cseq numbers. - - - - Default value is cseq. - - - - Set <varname>cseq_column</varname> parameter - -... -modparam("usrloc", "cseq_column", "cseq") -... - - -
- -
- <varname>methods_column</varname> (string) - - Name of column containing supported methods. - - - - Default value is methods. - - - - Set <varname>methods_column</varname> parameter - -... -modparam("usrloc", "methods_column", "methods") -... - - -
- -
- <varname>flags_column</varname> (string) - - Name of column to save the internal flags of the record. - - - - Default value is flags. - - - - Set <varname>flags_column</varname> parameter - -... -modparam("usrloc", "flags_column", "flags") -... - - -
- -
- <varname>cflags_column</varname> (string) - - Name of column to save the branch/contact flags of the record. - - - - Default value is cflags. - - - - Set <varname>cflags_column</varname> parameter - -... -modparam("usrloc", "cflags_column", "cflags") -... - - -
- -
- <varname>user_agent_column</varname> (string) - - Name of column containing user-agent values. - - - - Default value is user_agent. - - - - Set <varname>user_agent_column</varname> parameter - -... -modparam("usrloc", "user_agent_column", "user_agent") -... - - -
- -
- <varname>received_column</varname> (string) - - Name of column containing the source IP, port, and protocol from the REGISTER - message. - - - - Default value is received. - - - - Set <varname>received_column</varname> parameter - -... -modparam("usrloc", "received_column", "received") -... - - -
- -
- <varname>socket_column</varname> (string) - - Name of column containing the received socket information (IP:port) - for the REGISTER message. - - - - Default value is socket. - - - - Set <varname>socket_column</varname> parameter - -... -modparam("usrloc", "socket_column", "socket") -... - - -
- -
- <varname>path_column</varname> (string) - - Name of column containing the Path header. - - - - Default value is path. - - - - Set <varname>path_column</varname> parameter - -... -modparam("usrloc", "path_column", "path") -... - - -
- -
- <varname>sip_instance_column</varname> (string) - - Name of column containing the SIP instance. - - - - Default value is NULL. - - - - Set <varname>sip_instance_column</varname> parameter - -... -modparam("usrloc", "sip_instance_column", "sip_instance") -... - - -
- -
- <varname>kv_store_column</varname> (string) - - Name of column containing generic key-value data. - - - - Default value is kv_store. - - - - Set <varname>kv_store_column</varname> parameter - -... -modparam("usrloc", "kv_store_column", "json_data") -... - - -
- -
- <varname>attr_column</varname> (string) - - Name of column containing additional registration-related information. - - - - Default value is attr. - - - - Set <varname>attr_column</varname> parameter - -... -modparam("usrloc", "attr_column", "attributes") -... - - -
- -
- <varname>use_domain</varname> (integer) - - If the domain part of the user should be also saved and used for - identifing the user (along with the username part). Useful in - multi domain scenarios. Non 0 value means true. - - - - Default value is 0 (false). - - - - Set <varname>use_domain</varname> parameter - -... -modparam("usrloc", "use_domain", 1) -... - - -
- -
- <varname>desc_time_order</varname> (integer) - - If the user's contacts should be kept timestamp ordered; otherwise the - contact will be ordered based on q value. - Non 0 value means true. - - - - Default value is 0 (false). - - - - Set <varname>desc_time_order</varname> parameter - -... -modparam("usrloc", "desc_time_order", 1) -... - - -
- -
- <varname>timer_interval</varname> (integer) - - Number of seconds between two timer runs. During each run, the module - will update/delete dirty/expired contacts from memory and/or mirror - these operations to the database, if configured to do so. - - - - In case of an OpenSIPS shutdown or even a crash, contacts which are in - memory only and have not been flushed yet to disk will NOT get lost! - OpenSIPS will try its best to do a last-minute sync to DB right before - shutting down. - - - - - Default value is 60. - - - - Set <varname>timer_interval</varname> parameter - -... -modparam("usrloc", "timer_interval", 120) -... - - -
- -
- <varname>db_url</varname> (string) - - &url; of the database that should be used. - - - - Default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("usrloc", "db_url", "&exampledb;") -... - - -
- -
- <varname>cachedb_url</varname> (string) - - &url; of a NoSQL database to be used. Only required in a - cachedb-enabled - . - - - - Default value is none. - - - - Set <varname>cachedb_url</varname> parameter - -... -modparam("usrloc", "cachedb_url", "&examplecdb;") -... - - -
- -
- <varname>db_mode</varname> (integer, deprecated) - - This parameter has been kept for backwards compatibility. It acts as a - (which it also conflicts with), - overriding any , - and - settings. Possible values are: - - - - - 0, corresponding to "single-instance-no-db" (see below) - - - 1, corresponding to "single-instance-sql-write-through" - - - 2, corresponding to "single-instance-sql-write-back" - - - 3, corresponding to "sql-only" - - - - - - Default value is "not set". - - - - Set <varname>db_mode</varname> parameter - -... -modparam("usrloc", "db_mode", 2) -... - - -
- -
- <varname>working_mode_preset</varname> (string) - - A pre-defined working mode for the usrloc module. Setting this - parameter will override any , - and - settings. - - - - - - "single-instance-no-db" - This - disables database completely. Only memory will be used. - Contacts will not survive restart. Use this value if you need a - really fast usrloc and contact persistence is not necessary or - is provided by other means. - - - - - "single-instance-sql-write-through" - - Write-Through scheme. All changes to usrloc are immediately - reflected in database too. This is very slow, but very reliable. - Use this scheme if speed is not your priority but need to make - sure that no registered contacts will be lost during crash or - reboot. - - - - - "single-instance-sql-write-back" - - Write-Back scheme. This is a combination of previous two - schemes. All changes are made to memory and database - synchronization is done in the timer. The timer deletes all - expired contacts and flushes all modified or new contacts to - database. Use this scheme if you encounter high-load peaks - and want them to process as fast as possible. The mode will - not help at all if the load is high all the time. The - added latency on the SIP signaling when using this asynchronous - preset is much lower than the one added by the safe but - blocking, "single-instance-sql-write-through" preset. - - - - - "sql-only" - - DB-Only scheme. No memory cache is kept, all operations being - directly performed with the database. The timer deletes all - expired contacts from database - cleans after clients that didn't - un-register or re-register. The mode is useful if you configure - more servers sharing the same DB without any replication at SIP - level. The mode may be slower due the high number of DB operation. - For example NAT pinging is a killer since during each ping cycle - all nated contact are loaded from the DB; The lack of memory - caching also disable the statistics exports. - - - - - "federation-cachedb-cluster" - - OpenSIPS will run with a "federation-cachedb" - and - "sync-from-cluster" . - This will require the configuration of multiple "seed" nodes in - the cluster. Refer to the - federated user location tutorial for more - details. - - - - - "full-sharing-cluster" - - OpenSIPS will run with a "full-sharing" - and - "sync-from-cluster" . - This will require the configuration of one of the nodes in the cluster - as a "seed" node in order to bootstrap the syncing process. - - - - - "full-sharing-cachedb-cluster" - - OpenSIPS will run with a "full-sharing-cachedb" - , where all location data strictly - resides in a NoSQL database, thus it will have natural restart - persistency. - - - - - - Refer to section - for details - regarding the clustering topologies and their behavior. - - - - Default value is "single-instance-no-db". - - - - Set <varname>working_mode_preset</varname> parameter - -... -modparam("usrloc", "working_mode_preset", "full-sharing-cachedb-cluster") -... - - -
- -
- <varname>cluster_mode</varname> (string) - - This parameter will get overridden if either - or - is set. - - - The behavior of the global OpenSIPS user location cluster. Refer to - section for details. - - - This parameter may take the following values: - - - - "none" - single instance mode. - - - - "federation-cachedb" - - federation-based data sharing. Local AoR metadata is published - inside a NoSQL database, so other cluster nodes can fork SIP - traffic over to the current node. Consequently, the - and - parameters are mandatory. - - - - "full-sharing" - - Broadcast contact updates (full-mesh mirroring) to all other - OpenSIPS cluster participants. Each node will hold the entire - user location dataset. Consequently, the - parameter is mandatory. - - - - "full-sharing-cachedb" - - Full contact data management through the use of a NoSQL - database (somewhat resembling the "sql-only" preset). - The cluster layer is still required in order to - be able to partition and spread the pinging workload evenly - among participating OpenSIPS nodes. Consequently, the - and - parameters are mandatory. - - - - "sql-only" - - Multiple OpenSIPS boxes using a common - without necessarily being aware - of each other. - - - - - - Default value is "none" (single instance mode). - - - - Set <varname>cluster_mode</varname> parameter - -... -modparam("usrloc", "cluster_mode", "federation-cachedb") -... - - -
- -
- <varname>restart_persistency</varname> (string) - - This parameter will get overridden if either - or - are set. - - - Controls the behavior of the OpenSIPS user location following a - restart. This parameter has no effect in some database-only working - mode presets, where restart persistency is naturally ensured. - - - This parameter may take the following values: - - - - "none" - no explicit data - synchronization following a restart. The node starts empty. - - - - "load-from-sql" - enable - SQL-based restart persistency. This causes all runtime - in-memory writes (i.e. new registrations, re-registrations or - de-registrations) to also propagate to an SQL database, from - which all data will be imported following a restart. - Choosing this value will make the - parameter mandatory, as well as cause - to default to "write-back" - instead of "none". - - - - "sync-from-cluster" - enable - cluster-based restart persistency. Following a restart, - an OpenSIPS cluster node will search for a healthy "donor" node - from which to mirror the entire user location dataset via - direct cluster sync (TCP-based, binary-encoded data transfer). - Depending on the clustering mode and cluster topology, this will - require the configuration of one or multiple "seed" nodes in the cluster. - Choosing this value will make the - parameter mandatory. - - - - - - Default value is - "none" (no restart persistency). - - - - Set <varname>restart_persistency</varname> parameter - -... -modparam("usrloc", "restart_persistency", "sync-from-cluster") -... - - -
- -
- <varname>sql_write_mode</varname> (string) - - This parameter will get overridden if either - or - are set. - - - Only valid if is enabled. - Controls the runtime behavior of OpenSIPS writes to the SQL database. - - - This parameter may take the following values: - - - - "none" - do not perform any - additional SQL writes at runtime to an SQL database in order - to specifically ensure restart persistency. - - - - "write-through" - all in-memory - writes (i.e. new registrations, re-registrations or - de-registrations) also propagate into the SQL database, inline. - While this will definitely slow down registration performance - (lookups are served from memory!), it has the advantage of - making the instance crash-safe. - - - - "write-back" - all in-memory - writes (i.e. new registrations, re-registrations or - de-registrations) eventually also propagate into the SQL - database, thanks to a separate timer routine. This dramatically - speeds up registrations, but also introduces the - possibility of crashing before the latest contact changes are - propagated to the database. See the - for additional configuration. - - - - - - Default value is "none" (no added SQL writes). - - - - Set <varname>sql_write_mode</varname> parameter - -... -modparam("usrloc", "sql_write_mode", "write-back") -... - - -
- -
- <varname>matching_mode</varname> (integer) - - What contact matching algorithm to be used. Refer to section - for the description of the - algorithms. - - - The parameter may take the following values: - - - - 0 - CONTACT ONLY based matching - algorithm. - - - - 1 - CONTACT and CALLID based - matching algorithm. - - - - - - Default value is 0 (CONTACT_ONLY). - - - - Set <varname>matching_mode</varname> parameter - -... -modparam("usrloc", "matching_mode", 1) -... - - -
- -
- <varname>cseq_delay</varname> (integer) - - Delay (in seconds) for accepting as retransmissions register requests - with same Call-ID and Cseq. The delay is calculated starting from the - receiving time of the first register with that Call-ID and Cseq. - - - Retransmissions within this delay interval will be accepted and replied - as the original request, but no update will be done in location. If the - delay is exceeded, error is reported. - - - A value of 0 disable the retransmission detection. - - - - Default value is 20 seconds. - - - - Set <varname>cseq_delay</varname> parameter - -... -modparam("usrloc", "cseq_delay", 5) -... - - -
- -
- <varname>location_cluster</varname> (integer) - - Specifies the cluster ID which this instance will send to and receive - from all user-location related information - (addresses-of-record, contacts), - organized into specific events (inserts, deletes or updates). - - - &clusterer_sync_cap_para; - - - Default value is 0 (replication disabled). - - - More details on the user location distribution mechanisms are - available under . - - - Setting the <varname>location_cluster</varname> parameter - -... -modparam("usrloc", "location_cluster", 1) -... - - -
- -
- <varname>ha_cluster</varname> (integer) - - Only relevant in "federation-cachedb" - . Denotes the HA cluster ID to use in - order to establish the active node within the HA pair, such that only - that node performs WRITE operations to CacheDB. - - - Default value is 0 (disabled). - - - Setting the <varname>ha_cluster</varname> parameter - -... -modparam("usrloc", "ha_cluster", 4) -... - - -
- -
- <varname>ha_shtag</varname> (string) - - Only relevant in "federation-cachedb" - . Denotes the HA cluster sharing tag to - use in order to establish the active node within the HA pair, such that - only that node performs WRITE operations to CacheDB. - - - Default value is NULL (disabled). - - - Setting the <varname>ha_shtag</varname> parameter - -... -modparam("usrloc", "ha_shtag", "vip2") -... - - -
- -
- <varname>skip_replicated_db_ops</varname> (int) - - Prevent &osips; from performing any DB-related contact operations - when events are received over the Binary Interface. - This is commonly used to prevent unneeded duplicate operations. - - - Default value is "0" (upon receival of usrloc-related Binary Interface - events, DB queries may be freely performed) - - - More details on the user location replication mechanism are available - in - - - Setting the <varname>skip_replicated_db_ops</varname> - parameter - -... -modparam("usrloc", "skip_replicated_db_ops", 1) -... - - -
- -
- <varname>max_contact_delete</varname> (int) - - Relevant only in WRITE_THROUGH or WRITE_BACK schemes. The maximum - number of contacts to be deleted from the database at once. Will delete - all of them, if fewer after passing through all the contacts. - - - Default value is "10" - - - Setting the <varname>max_contact_delete</varname> - parameter - -... -modparam("usrloc", "max_contact_delete", 10) -... - - -
- - -
- <varname>hash_size</varname> (integer) - - The number of entries of the hash table used by usrloc to store the - location records is 2^hash_size. For hash_size=4, the number of entries - of the hash table is 16. Since version 2.2, the maximu size of this - parameter is 16, meaning that the hash supports maximum 65536 entries. - - - - Default value is 9. - - - - Set <varname>hash_size</varname> parameter - -... -modparam("usrloc", "hash_size", 10) -... - - -
- -
- <varname>regen_broken_contactid</varname> (integer) - - Since version 2.2, contact_id concept - was introduced. Since this parameter validates a contact each time &osips; - is started, there are times when the value of this parameter should be - regenerated. That is when location table - is being migrated from a version older than 2.2 or when - hash_size module parameter is changed. - Enabling this parameter will regenerate broken contact id's based on - current configurations. - - - - Default value is 0(not enabled) - - - - - Set <varname>regen_broken_contactid</varname> parameter - -... -modparam("usrloc", "regen_broken_contactid", 1) -... - - -
- -
- <varname>latency_event_min_us</varname> (integer) - - Defines a minimal pinging latency threshold, in microseconds, past - which contact pinging latency update events will get raised. By - default, an event is raised for each ping reply (i.e. latency update). - - - If both and - are set, the event - will get raised if either of them is true. - - - - Default value is 0 (no bottom limit set). - - - - - Set <varname>latency_event_min_us</varname> parameter - -... -# raise an event for any 425+ ms pinging latency -modparam("usrloc", "latency_event_min_us", 425000) -... - - -
- -
- <varname>latency_event_min_us_delta</varname> (integer) - - Defines a minimal, absolute pinging latency difference, in - microseconds, past which contact pinging latency update events will get - raised. The difference is computed using the latencies of the last two - contact pinging replies. By default, an event is raised for each ping - reply (i.e. latency update). - - - If both and - are set, the event - will get raised if either of them is true. - - - - Default value is 0 (no minimal latency delta set). - - - - - Set <varname>latency_event_min_us_delta</varname> parameter - -... -# raise an event only if a contact has pinging latency swings of 300+ ms -modparam("usrloc", "latency_event_min_us_delta", 300000) -... - - -
- -
- <varname>pinging_mode</varname> (string) - - Depending on the , the module - can perform contact pinging using one of two possible heuristics: - - - "ownership" - this instance - will only attempt to ping a contact if it decides it is the - logical owner of the contact. If a shared tag is attached to - a contact, a node will keep sending pings to that contact as - long as it owns the respective tag. If no shared tag has been - specified for a given contact, the default is to assume - permanent ownership of the contact and ping it upon request. - - - - "cooperation" - the - assumption behind this pinging heuristic is that all - user location cluster nodes are symmetrical (possibly - front-ended by a SIP traffic balancing entity), such that - either of them can ping - any contact. - Under this assumption, all currently online user location - cluster nodes will cooperate and evenly split the pinging - workload between them by hashing AoRs modulo - current_number_of_online_nodes, and only picking the ones that - they are responsible for. - - - - - Possible values for the "pinging_mode", - depending on the current "cluster_mode" - - - - - none - federation-cachedb - full-sharing - full-sharing-cachedb - sql-only - - - - ownership - ownership - cooperation / ownership - cooperation - unmaintained - - - -
- - Notice that only the "full-sharing" - clustering mode allows some flexibility -- all other modes are - logically tied to a single pinging logic. Any unaccepted value, - according to the above table, set - for those modes will be silently discarded. - - - Set <varname>pinging_mode</varname> parameter - -... -# prepare an active/backup "full-sharing" setup, with no front-end -modparam("usrloc", "pinging_mode", "ownership") -... - - -
- -
- <varname>mi_dump_kv_store</varname> (integer) - - Enable in order to include the "KV-Store" field in all usrloc MI - commands which output AoR or Contact representations. This verbose - field contains custom data attached to each of these two entities. - mid_registrar makes use of both of these holders, for example. - - - - Default value is 0 (disabled). - - - - - Set <varname>mi_dump_kv_store</varname> parameter - -... -# include the "KV-Store" key in all usrloc MI output -modparam("usrloc", "mi_dump_kv_store", 1) -... - - -
- -
- <varname>contact_refresh_timer</varname> (boolean) - - Enable a timer which will periodically scan a sorted list of contacts - and raise the for any of - them which are past their re-registration time interval limit. This - limit may given by registrar's pn_trigger_interval - module parameter, for example. - - - - Default value is false (disabled). - - - - - Set <varname>contact_refresh_timer</varname> parameter - -... -modparam("usrloc", "contact_refresh_timer", true) -... - - -
- -
- -
- Exported Functions - -
- - <function moreinfo="none">ul_add_key(domain, aor, key_name, [key_value])</function> - - - Append a Key/Value to the Key-Value-Store of a Usrloc-Record. - - - Returns false, if no record is found is usrloc. - - Meaning of the parameters is as follows: - - - domain (string) - Domain of the - AOR, e.g. "location" - - - - aor (string) - Address-of-Record, - save the key for a specific (registered) user. - - - - key (string) - The name of the - key to be stored. - - - - value (string, optional) - - The value to be stored. Not providing the value or - by providing an empty value, will delete the entry. - - - - - This function can be used in ANY route. - - - <function>ul_add_key</function> usage - -... -ul_add_key("location", "$tU@$td", "service_route", "$hdr(Service-Route)"); -... - - -
- -
- - <function moreinfo="none">ul_get_key(domain, aor, key_name, destination)</function> - - - Retrieve a Key/Value from the Key-Value-Store of a Usrloc-Record. - - - Returns false, if no record is found is usrloc or no according key is found. - - Meaning of the parameters is as follows: - - - domain (string) - Domain of the - AOR, e.g. "location" - - - - aor (string) - Address-of-Record, - save the key for a specific (registered) user. - - - - key (string) - The name of the - key to be retrieved. - - - - destination (variable) - - A variable, where to store the retrieved key. - - - - - This function can be used in ANY route. - - - <function>ul_get_key</function> usage - -... -if (ul_get_key("location", "$tU@$td", "service_route", $avp(service_route))) { - append_to_reply("Service-Route: $avp(service_route)\r\n"); -} -... - - -
- -
- - <function moreinfo="none">ul_del_key(domain, aor, key_name)</function> - - - Deletes a Key/Value from the Key-Value-Store of a Usrloc-Record. - - - Returns false, if no record is found is usrloc. - - Meaning of the parameters is as follows: - - - domain (string) - Domain of the - AOR, e.g. "location" - - - - aor (string) - Address-of-Record, - save the key for a specific (registered) user. - - - - key (string) - The name of the - key to be deleted. - - - - - This function can be used in ANY route. - - - <function>ul_del_key</function> usage - -... -ul_del_key("location", "$tU@$td", "service_route"); -... - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">ul_rm</function> - - - Deletes an entire AOR record (including its contacts). - - Parameters: - - - table_name - table where the AOR - is removed from (Ex: location). - - - aor - user AOR in username[@domain] - format (domain must be supplied only if use_domain option - is on). - - -
- -
- - <function moreinfo="none">ul_rm_contact</function> - - - Deletes a contact from an AOR record. - - Parameters: - - - table name - table where the AOR - is removed from (Ex: location). - - - AOR - user AOR in username[@domain] - format (domain must be supplied only if use_domain option - is on). - - - contact - exact contact to be removed - - -
- -
- - <function moreinfo="none">ul_dump</function> - - - Dumps the entire content of the USRLOC in memory cache - - Parameters: - - - brief - (optional, may not be present); if - equals to string brief, a brief dump will be - done (only AOR and contacts, with no other details) - - -
- -
- - <function moreinfo="none">ul_flush</function> - - - Force a flush of all pending usrloc cache changes to the database. - Normally, this routine runs every - seconds. - -
- -
- - <function moreinfo="none">ul_add</function> - - - Adds a new contact for an user AOR. - - Parameters: - - - table name (string) - table where the contact - will be added (Ex: "location"). - - - aor (string) - user AOR in username[@domain] - format (domain must be supplied only if use_domain option - is on). - - - contact (string) - Contact URI to be added - - - expires (int) - expires value of the contact - - - q (string) - Q value of the contact - - - flags (int) - internal USRLOC flags of the - contact - - - cflags (int) - per branch flags of the - contact - - - methods (int) - bitmask with supported requests - of the contact. To whitelist all SIP methods, simply use the - value 32767. For a breakdown - of each method's value, see the "request_method" internal enum. - - -
- -
- - <function moreinfo="none">ul_show_contact</function> - - - Dumps the contacts of an user AOR. - - Parameters: - - - table_name - table where the AOR - resides (Ex: location). - - - aor - user AOR in username[@domain] - format (domain must be supplied only if use_domain option - is on). - - -
- -
- - <function moreinfo="none">ul_sync</function> - - - Empty the location table, then synchronize it with all contacts from - memory. Note that this can not be used when no database is specified - or with the DB-Only scheme. - - - Important: make sure that all your contacts are in memory - (ul_dump MI function) before executing this - command. - - Parameters: - - - table name - table where the AOR - resides (Ex: location). - - - AOR (optional) - only delete/sync this - user AOR, not the whole table. Format: "username[@domain]" - (domain is required only if - option is on). - - -
- -
- - <function moreinfo="none">ul_cluster_sync</function> - - - This command will only take effect if the target OpenSIPS instance is - paired with a hot backup instance, while running under a - cluster-enabled . - - - The current node will locate a healthy donor node within the - and issue a sync request to - it. The donor node will then proceed to push all of its user location - data over to the current node, via the binary interface. The received - data will be merged with existing data. Conflicting contacts (matched - according to ) are overwritten - only if the sync data is newer than the current data. - -
- -
- - -
- Exported Statistics - - Exported statistics are listed in the next sections. - -
- users - - Number of AOR existing in the USRLOC memory cache for that domain - - can not be resetted; this statistic will be register for each - used domain (Ex: location). - -
-
- contacts - - Number of contacts existing in the USRLOC memory cache for that - domain - can not be resetted; this statistic will be register for - each used domain (Ex: location). - -
-
- expires - - Total number of expired contacts for that domain - can be resetted; - this statistic will be register for each used domain - (Ex: location). - -
-
- registered_users - - Total number of AOR existing in the USRLOC memory cache for all - domains - can not be resetted. - -
-
- - -
- Exported Events -
- - <function moreinfo="none">E_UL_AOR_INSERT</function> - - - This event is raised when a new AOR is inserted in the USRLOC - memory cache. - - Parameters: - - - domain - The name of the table. - - - aor - The AOR of the inserted record. - - -
-
- - <function moreinfo="none">E_UL_AOR_DELETE</function> - - - This event is raised when a new AOR is deleted from the USRLOC - memory cache. - - Parameters: - - - domain - The name of the table. - - - aor - The AOR of the deleted record. - - -
-
- - <function moreinfo="none">E_UL_CONTACT_INSERT</function> - - - This event is raised when a new contact is inserted in any of the - existing AOR's contact list. For each new contact, if its AOR does - not exist in the memory, then both the E_UL_AOR_CREATE and - E_UL_CONTACT_INSERT events will be raised. - - Parameters: - - - domain - The name of the table. - - - aor - The AOR of the inserted contact. - - - uri - The contact URI of the inserted - contact. - - - received - IP, port and protocol the - registration message was received from. If these have the - same value as the contact's address (see the address parameter) - then the received parameter will be an empty string. - - - path - The PATH header value of the - registration message.(empty string if not present) - - - qval - The Q value (priority) of the - contact (as integer value from 0 to 10). - - - user_agent - The User-Agent header - value. - - NOTICE: Can contain spaces. - - - socket - The SIP socket/listener - (as string) used by OpenSIPS to receive the contact - registations. - - - bflags - The branch flags (bflags) of the - contact (in integer value of the bitmask) - - - expires - The expires value of the - contact (as UNIX timestamp integer). - - - callid - The Call-ID header of the - registration message. - - - cseq - The cseq number as an int value. - - - attr - The attributes string attached - to the contact (the custom attributes attached from the - script level). As this string is options, if missing in the - contact, the event will push the empty string for this event - field. - - - latency - The latency of the last - successful ping for this contact, in microseconds. Until the - first ping reply for a given contact arrives, its pinging - latency will be 0. - - - shtag - The shared tag of the contact, - which helps determine if the current node owns the contact - (e.g. possibly using the $cluster.sh_tag - pseudo-variable in order to perform the check). - - NOTICE: If a contact has no shared tag - attached to it, the value of this parameter will be "" (empty - string)! - - -
- -
- - <function moreinfo="none">E_UL_CONTACT_DELETE</function> - - - This event is raised when a contact is deleted from an - existing AOR's contact list. If the contact is the only one in - the list then both the E_UL_AOR_DELETE and - E_UL_CONTACT_DELETE events will be raised. - - Parameters: same as the - event -
- -
- - <function moreinfo="none">E_UL_CONTACT_UPDATE</function> - - - This event is raised when a contact's info is updated by receiving - another registration message. - - Parameters: same as the - event -
- -
- - <function moreinfo="none">E_UL_CONTACT_REFRESH</function> - - - This event may only be raised for RFC 8599 (Push Notification) - enabled contacts. - - - Set to - true in order to enable this event. The event is - raised within reasonable time before an RFC 8599 enabled contact - will expire, such that the script writer can take action, - possibly force a registration refresh from the endpoint. - - Parameters: - - - domain - The name of the table. - - - aor - The AOR of the inserted contact. - - - uri - The contact URI of the inserted - contact. - - - received - IP, port and protocol the - registration message was received from. If these have the - same value as the contact's address (see the address parameter) - then the received parameter will be an empty string. - - - user_agent - The User-Agent header - value. - - NOTICE: Can contain spaces. - - - socket - The SIP socket/listener - (as string) used by OpenSIPS to receive the contact - registations. - - - bflags - The branch flags (bflags) of the - contact (in integer value of the bitmask) - - - expires - The expires value of the - contact (as UNIX timestamp integer). - - - callid - The Call-ID header of the - registration message. - - - attr - The attributes string attached - to the contact (the custom attributes attached from the - script level). As this string is options, if missing in the - contact, the event will push the empty string for this event - field. - - - shtag - The shared tag of the contact, - which helps determine if the current node owns the contact - (e.g. possibly using the $cluster.sh_tag - pseudo-variable in order to perform the check). - - - reason - the reason why the binding refresh - event was triggered. Possible values: - - - "reg-refresh" - periodic refresh triggered by OpenSIPS - - - - "ini-INVITE", "ini-SUBSCRIBE", etc. - a refresh - triggered by an incoming initial SIP request - - - - "mid-INVITE", "mid-BYE", etc. - a refresh triggered - by an incoming mid-dialog SIP request - - - - - req_callid - the Call-ID of the SIP request - which triggered this event, if any. This gives the ability to - logically link the pending request with the current event and - access useful data from that request (e.g. caller identity, - dialed number, etc.). - - - Using the req_callid, if a dialog has been - created for the pending request, this dialog may be temporarily - loaded inside the event_route using the - load_dialog_ctx() and - unload_dialog_ctx() - functions of the dialog module. - - - -
- -
- - <function moreinfo="none">E_UL_LATENCY_UPDATE</function> - - - This event is raised when a contact pinging latency matches either - of the or - filters. If none of - these filters is set, this event will get raised for each successful - contact ping operation. - - Parameters: same as the - event -
- -
-
diff --git a/modules/usrloc/doc/usrloc_devel.xml b/modules/usrloc/doc/usrloc_devel.xml deleted file mode 100644 index 933c6c958f5..00000000000 --- a/modules/usrloc/doc/usrloc_devel.xml +++ /dev/null @@ -1,493 +0,0 @@ - - - - - &develguide; -
- Available Functions -
- - <function moreinfo="none">ul_register_domain(name)</function> - - - The function registers a new domain. Domain is just another name for - table used in registrar. The function is called from fixups in - registrar. It gets name of the domain as a parameter and returns - pointer to a new domain structure. The fixup than 'fixes' the - parameter in registrar so that it will pass the pointer instead of the - name every time save() or lookup() is called. Some usrloc functions - get the pointer as parameter when called. For more details see - implementation of save function in registrar. - - Meaning of the parameters is as follows: - - - const char* name - Name of the domain - (also called table) to be registered. - - - -
- -
- - <function moreinfo="none"> - ul_insert_urecord(domain, aor, rec, is_replicated)</function> - - - The function creates a new record structure and inserts it in the - specified domain. The record is structure that contains all the - contacts for belonging to the specified username. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Pointer to domain - returned by ul_register_udomain. - - - - str* aor - Address of Record (aka - username) of the new record (at this time the record will - contain no contacts yet). - - - - urecord_t** rec - The newly created - record structure. - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- - -
- - <function moreinfo="none"> - ul_delete_urecord(domain, aor, is_replicated)</function> - - - The function deletes all the contacts bound with the given Address - Of Record. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Pointer to domain - returned by ul_register_udomain. - - - - str* aor - Address of record (aka - username) of the record, that should be deleted. - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- -
- - <function moreinfo="none">ul_get_urecord(domain, aor)</function> - - - The function returns pointer to record with given Address of Record. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Pointer to domain - returned by ul_register_udomain. - - - - - - str* aor - Address of Record of request - record. - - - -
- -
- - <function moreinfo="none">ul_lock_udomain(domain)</function> - - - The function lock the specified domain, it means, that no other - processes will be able to access during the time. This prevents race - conditions. Scope of the lock is the specified domain, that means, - that multiple domain can be accessed simultaneously, they don't block - each other. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Domain to be locked. - - - -
- -
- - <function moreinfo="none">ul_unlock_udomain(domain)</function> - - - Unlock the specified domain previously locked by ul_lock_udomain. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Domain to be - unlocked. - - - -
- -
- - <function moreinfo="none"> - ul_release_urecord(record, is_replicated)</function> - - - Do some sanity checks - if all contacts have been removed, delete - the entire record structure. - - Meaning of the parameters is as follows: - - - urecord_t* record - Record to be - released. - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- -
- - <function moreinfo="none">ul_insert_ucontact(record, contact, - contact_info, contact, is_replicated)</function> - - - The function inserts a new contact in the given record with - specified parameters. - - Meaning of the parameters is as follows: - - - urecord_t* record - Record in which - the contact should be inserted. - - - - str* contact - Contact &uri;. - - - - ucontact_info_t* contact_info - - Single structure containing the new contact information - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- -
- - <function moreinfo="none">ul_delete_ucontact - (record, contact, is_replicated)</function> - - - The function deletes given contact from record. - - Meaning of the parameters is as follows: - - - urecord_t* record - Record from which - the contact should be removed. - - - - - - ucontact_t* contact - Contact to be - deleted. - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- -
- - <function moreinfo="none">ul_delete_ucontact_from_id - (domain, contact_id)</function> - - - The function deletes a contact with the given contact_id from - the given domain. - - Meaning of the parameters is as follows: - - - udomain_t* domain - Domain where - the contact can be found. - - - - - - uint64_t contact_id - Contact_id - identifying the contact to be deleted. - - - -
- - - -
- - <function moreinfo="none">ul_get_ucontact(record, contact)</function> - - - The function tries to find contact with given Contact &uri; and - returns pointer to structure representing the contact. - - Meaning of the parameters is as follows: - - - urecord_t* record - Record to be - searched for the contact. - - - - - - str_t* contact - &uri; of the request - contact. - - - -
- -
- - <function moreinfo="none">ul_get_domain_ucontacts - (domain, buf, len, flags)</function> - - - The function retrieves all contacts of all registered users from the - given doamin and returns them in the caller-supplied buffer. If the - buffer is too small, the function returns positive value indicating - how much additional space would be necessary to accommodate all of - them. Please note that the positive return value should be used only - as a hint, as there is no guarantee that during the time - between two subsequent calls number of registered contacts will - remain the same. - - - If flag parameter is set to non-zero value then only contacts that - have the specified flags set will be returned. It is, for example, - possible to list only contacts that are behind NAT. - - Meaning of the parameters is as follows: - - - udomaint_t* domain - Domain from which - to get the contacts - - - - - - void* buf - Buffer for returning - contacts. - - - - - - int len - Length of the buffer. - - - - - - unsigned int flags - Flags that must - be set. - - - -
- - - -
- - <function moreinfo="none">ul_get_all_ucontacts - (buf, len, flags)</function> - - - The function retrieves all contacts of all registered users and - returns them in the caller-supplied buffer. If the buffer is too small, - the function returns positive value indicating how much additional - space would be necessary to accommodate all of them. Please note - that the positive return value should be used only as a - hint, as there is no guarantee that during the time - between two subsequent calls number of registered contacts will - remain the same. - - - If flag parameter is set to non-zero value then only contacts that - have the specified flags set will be returned. It is, for example, - possible to list only contacts that are behind NAT. - - Meaning of the parameters is as follows: - - - void* buf - Buffer for returning - contacts. - - - - - - int len - Length of the buffer. - - - - - - unsigned int flags - Flags that must - be set. - - - -
- -
- - <function moreinfo="none">ul_update_ucontact(record, contact, - contact_info, is_replicated)</function> - - - The function updates contact with new values. - - Meaning of the parameters is as follows: - - - urecord_t* record - Record in which - the contact should be inserted. - - - - ucontact_t* contact - Contact &uri;. - - - - ucontact_info_t* contact_info - - Single structure containing the new contact information - - - - char is_replicated - Specifies whether - this function will be called from the context of a Binary Interface - callback. If uncertain, simply use 0. - - - -
- -
- - <function moreinfo="none">ul_bind_ursloc( api ) - </function> - - - The function imports all functions that are exported by the - USRLOC module. Overs for other modules which want to user the - internal USRLOC API an easy way to load and access the functions. - - Meaning of the parameters is as follows: - - - usrloc_api_t* api - USRLOC API - - - -
- -
- - <function moreinfo="none">ul_register_ulcb(type ,callback, param) - </function> - - - The function register with USRLOC a callback function to be called - when some event occures inside USRLOC. - - Meaning of the parameters is as follows: - - - int types - type of event for which - the callback should be called (see usrloc/ul_callback.h). - - - - ul_cb f - callback function; see - usrloc/ul_callback.h for prototype. - - - - void *param - some parameter to be - passed to the callback each time when it is called. - - - -
- -
- - <function moreinfo="none">ul_get_num_users() - </function> - - - The function loops through all domains summing up the number of users. - -
- -
- -
- diff --git a/modules/usrloc/kv_store.c b/modules/usrloc/kv_store.c index e70f50e0e27..3b2a39a9b63 100644 --- a/modules/usrloc/kv_store.c +++ b/modules/usrloc/kv_store.c @@ -103,6 +103,8 @@ void kv_del(map_t _store, const str* _key) if (val->is_str) shm_free(val->s.s); + + shm_free(val); } static int push_kv_to_json(void *param, str key, void *value) diff --git a/modules/usrloc/udomain.c b/modules/usrloc/udomain.c index 0ff40ae321f..a8495486e4a 100644 --- a/modules/usrloc/udomain.c +++ b/modules/usrloc/udomain.c @@ -1357,7 +1357,9 @@ int cdb_update_urecord_metadata(const str *_aor, int unpublish) * Create and insert a new record */ int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r, - char skip_replication) + char skip_replication, + ur_insert_pre_repl_cb_f pre_replicate_cb, + void *pre_replicate_info) { if (have_mem_storage()) { if (mem_insert_urecord(_d, _aor, _r) < 0) { @@ -1374,6 +1376,10 @@ int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r, _aor->len, _aor->s); } + if (pre_replicate_cb + && pre_replicate_cb(*_r, pre_replicate_info) != 0) + LM_ERR("urecord pre-replication callback returned non-zero\n"); + if (location_cluster) replicate_urecord_insert(*_r); } diff --git a/modules/usrloc/udomain.h b/modules/usrloc/udomain.h index e979dddba1e..af01407e15c 100644 --- a/modules/usrloc/udomain.h +++ b/modules/usrloc/udomain.h @@ -151,11 +151,18 @@ void unlock_ulslot(udomain_t* _d, int slot); /* ===== module interface ======= */ +/* Optional callback invoked by @insert_urecord between memory insertion and + * cluster replication, allowing the caller to populate record-level data + * (e.g. mid_registrar's kv_storage keys) so it ships in the INSERT packet. */ +typedef int (*ur_insert_pre_repl_cb_f)(struct urecord *r, void *info); + /*! \brief * Create and insert a new record */ int insert_urecord(udomain_t* _d, str* _aor, struct urecord** _r, - char skip_replication); + char skip_replication, + ur_insert_pre_repl_cb_f pre_replicate_cb, + void *pre_replicate_info); /*! \brief * Obtain a urecord pointer if the urecord exists in domain diff --git a/modules/usrloc/ul_cluster.c b/modules/usrloc/ul_cluster.c index 9a4d0f100b6..62b34c4bed0 100644 --- a/modules/usrloc/ul_cluster.c +++ b/modules/usrloc/ul_cluster.c @@ -428,6 +428,7 @@ static int receive_urecord_insert(bin_packet_t *packet) { str d, aor, kv_str; urecord_t *r; + map_t kv_storage; udomain_t *domain; int sl; short pkg_ver = get_bin_pkg_version(packet); @@ -449,7 +450,7 @@ static int receive_urecord_insert(bin_packet_t *packet) if (get_urecord(domain, &aor, &r) == 0) goto out; - if (insert_urecord(domain, &aor, &r, 1) != 0) { + if (insert_urecord(domain, &aor, &r, 1, NULL, NULL) != 0) { unlock_udomain(domain, &aor); goto out_err; } @@ -463,7 +464,11 @@ static int receive_urecord_insert(bin_packet_t *packet) if (pkg_ver >= UL_BIN_V5) { bin_pop_str(packet, &kv_str); - r->kv_storage = store_deserialize(&kv_str); + kv_storage = store_deserialize(&kv_str); + if (kv_storage) { + store_destroy(r->kv_storage); + r->kv_storage = kv_storage; + } } out: @@ -608,7 +613,7 @@ static int receive_ucontact_insert(bin_packet_t *packet) LM_INFO("failed to fetch local urecord - creating new one " "(ci: '%.*s') \n", callid.len, callid.s); - if (insert_urecord(domain, &aor, &record, 1) != 0) { + if (insert_urecord(domain, &aor, &record, 1, NULL, NULL) != 0) { LM_ERR("failed to insert new record\n"); unlock_udomain(domain, &aor); goto error; @@ -772,7 +777,7 @@ static int receive_ucontact_update(bin_packet_t *packet) LM_INFO("failed to fetch local urecord - create new record and contact" " (ci: '%.*s')\n", callid.len, callid.s); - if (insert_urecord(domain, &aor, &record, 1) != 0) { + if (insert_urecord(domain, &aor, &record, 1, NULL, NULL) != 0) { LM_ERR("failed to insert urecord\n"); unlock_udomain(domain, &aor); goto error; diff --git a/modules/usrloc/ul_mi.c b/modules/usrloc/ul_mi.c index 2b7f1d0eeb3..01823784c25 100644 --- a/modules/usrloc/ul_mi.c +++ b/modules/usrloc/ul_mi.c @@ -32,6 +32,7 @@ #include #include +#include #include "../../mi/mi.h" #include "../../dprint.h" #include "../../ut.h" @@ -115,7 +116,7 @@ static inline int mi_add_aor_node(mi_item_t *aor_item, urecord_t* r, if (add_mi_string(ct_item, MI_SSTR("Contact"), c->c.s, c->c.len) < 0) return -1; - if (add_mi_string_fmt(ct_item, MI_SSTR("ContactID"), "%lu", c->contact_id) < 0) + if (add_mi_string_fmt(ct_item, MI_SSTR("ContactID"), "%" PRIu64, c->contact_id) < 0) return -1; if (c->expires == 0) { @@ -520,7 +521,7 @@ mi_response_t *mi_usrloc_add(const mi_params_t *params, n = get_urecord( dom, &aor, &r); if ( n==1) { - if (insert_urecord( dom, &aor, &r, 0) < 0) + if (insert_urecord( dom, &aor, &r, 0, NULL, NULL) < 0) goto lock_error; c = 0; diff --git a/modules/usrloc/urecord.c b/modules/usrloc/urecord.c index 24c3c4f6c39..edd338a1e4a 100644 --- a/modules/usrloc/urecord.c +++ b/modules/usrloc/urecord.c @@ -728,7 +728,7 @@ static int cdb_build_ucontact_key(str* _ct, ucontact_info_t* _ci) } params[np] = puri.u_val[i]; - len += pnp->s.len; + len += params[np].len; } len += np - 1; /* add separators */ diff --git a/modules/usrloc/usrloc.h b/modules/usrloc/usrloc.h index 151843bbed8..e0977ed8a85 100644 --- a/modules/usrloc/usrloc.h +++ b/modules/usrloc/usrloc.h @@ -138,11 +138,17 @@ typedef struct usrloc_api { * @r: will hold the newly created object * @skip_replication: set to true in order to avoid replicating an AoR * insertion event to neighboring cluster nodes + * @pre_replicate_cb: optional callback fired after the urecord lives in + * memory but before it is replicated; use it to attach + * record-level kv_storage that must reach peers + * @pre_replicate_info: opaque context handed to @pre_replicate_cb * * Return: 0 (success), negative otherwise */ int (*insert_urecord) (udomain_t *d, str *aor, struct urecord **r, - char skip_replication); + char skip_replication, + ur_insert_pre_repl_cb_f pre_replicate_cb, + void *pre_replicate_info); /** * Fetch a key from record-level storage. diff --git a/modules/uuid/README b/modules/uuid/README deleted file mode 100644 index 78491679f6c..00000000000 --- a/modules/uuid/README +++ /dev/null @@ -1,172 +0,0 @@ -UUID Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Pseudo-Variables - - 1.4.1. $uuid - - 1.5. Exported Functions - - 1.5.1. uuid(out_var, [version], [namespace], [name]) - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. $uuid usage - -Chapter 1. Admin Guide - -1.1. Overview - - This module provides a way to generate universally unique - identifiers (UUID) as specified in RFC 4122. The UUID is - provided as a string representation by reading the $uuid - pseudo-variable or calling the uuid() script function. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - This module does not depend on other modules. - -1.2.2. External Libraries or Applications - - * libuuid - part of the util-linux package, can be downloaded - from: ftp://ftp.kernel.org/pub/linux/utils/util-linux/ - -1.3. Exported Parameters - - The module does not export any parameters. - -1.4. Exported Pseudo-Variables - -1.4.1. $uuid - - The $uuid variable returns a newly generated version 4 UUID - based on high-quality randomness from /dev/urandom, if - available. Otherwise, a version 1 UUID (based on current time - and the local ethernet MAC address) will be generated. - - Example 1.1. $uuid usage -xlog("generated uuid: $uuid\n"); - -1.5. Exported Functions - -1.5.1. uuid(out_var, [version], [namespace], [name]) - - Generates a new UUID. - * out_var (var) - an output variable to return the generated - UUID. - * version (string, optional) - UUID version number. The - supported values are: - + 0 - a RFC version 4 or version 1 UUID will be - generated, depending on the availability of - high-quality randomness from /dev/urandom. This is the - default behavior, if the version parameter is missing. - + 1 - version 1 UUID based on current time and the local - ethernet MAC address - + 3 - version 3 UUID generated by hashing a namespace - identifier and name via MD5. - + 4 - version 4 UUID based on a high-quality random - number generator. If not available, a pseudo-random - generator will be substituted. - + 5 - version 5 UUID generated by hashing a namespace - identifier and name via SHA-1. - + 7 - version 7 UUID generated by timestamp and - randomness. - * namespace (string, optional) - the namespace identifier - used with UUID version 3 and 5. This must be a valid UUID, - see RFC 4122 Appendix C for some predefined values. - * name (string, optional) - the name used with UUID version 3 - and 5. - - If UUID version 1 is used, the function will return the value 2 - if the UUID was generated in an unsafe manner. This refers to - the posibility of two concurrently running processes generating - the same UUID, in cases where synchronization mechanisms are - not available (more details can be found in the uuid_generate - man pages of libuuid). - - This function can be used from any route. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 9 4 368 4 - 2. John Burke (@john08burke) 5 3 63 15 - 3. Maksym Sobolyev (@sobomax) 5 3 5 5 - 4. Razvan Crainea (@razvancrainea) 4 2 2 1 - 5. Norman Brandinger (@NormB) 3 1 1 1 - 6. Aron Podrigal (@ar45) 2 1 38 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Aron Podrigal (@ar45) Sep 2024 - Sep 2024 - 2. Maksym Sobolyev (@sobomax) Feb 2023 - Nov 2023 - 3. Norman Brandinger (@NormB) Aug 2021 - Aug 2021 - 4. Vlad Patrascu (@rvlad-patrascu) Jun 2019 - Feb 2021 - 5. John Burke (@john08burke) Feb 2021 - Feb 2021 - 6. Razvan Crainea (@razvancrainea) Aug 2019 - Sep 2019 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Aron Podrigal (@ar45), Norman Brandinger - (@NormB), John Burke (@john08burke), Vlad Patrascu - (@rvlad-patrascu). - - Documentation Copyrights: - - Copyright © 2019 www.opensips-solutions.com diff --git a/modules/uuid/README.md b/modules/uuid/README.md new file mode 100644 index 00000000000..a0ea333b87a --- /dev/null +++ b/modules/uuid/README.md @@ -0,0 +1,113 @@ +--- +title: "UUID Module" +description: "This module provides a way to generate universally unique identifiers (UUID) as specified in RFC 4122." +--- + +## Admin Guide + + +### Overview + + +This module provides a way to generate universally unique identifiers +(UUID) as specified in RFC 4122. The UUID is provided as a string +representation by reading the [uuid](#pv_uuid) +pseudo-variable or calling the [uuid](#func_uuid) +script function. + + +### Dependencies + + +#### OpenSIPS Modules + + +This module does not depend on other modules. + + +#### External Libraries or Applications + + +- *libuuid* - part of the util-linux +package, can be downloaded from: +ftp://ftp.kernel.org/pub/linux/utils/util-linux/ + + +### Exported Parameters + + +The module does not export any parameters. + + +### Exported Pseudo-Variables + + +#### $uuid + + +The *$uuid* variable returns a newly generated +version 4 UUID based on high-quality randomness from /dev/urandom, +if available. Otherwise, a version 1 UUID (based on +current time and the local ethernet MAC address) will be generated. + + +```opensips title="$uuid usage" +xlog("generated uuid: $uuid\n"); +``` + + +### Exported Functions + + +#### uuid(out_var, [version], [namespace], [name]) + + +Generates a new UUID. + + +- *out_var* (var) - an output variable +to return the generated UUID. +- *version* (number, optional) - UUID version +number. The supported values are: + - *0* - a RFC version 4 or + version 1 UUID will be generated, depending on the + availability of high-quality randomness from + /dev/urandom. This is the default behavior, if the + *version* parameter is missing. + - *1* - version 1 UUID + based on current time and the local ethernet MAC + address + - *3* - version 3 UUID + generated by hashing a namespace identifier and name + via MD5. + - *4* - version 4 UUID + based on a high-quality random number generator. If + not available, a pseudo-random generator will be + substituted. + - *5* - version 5 UUID + generated by hashing a namespace identifier and name + via SHA-1. + - *7* - version 7 UUID + generated by timestamp and randomness. +- *namespace* (string, optional) - the namespace +identifier used with UUID version 3 and 5. This must be a valid +UUID, see RFC 4122 Appendix C for some predefined values. +- *name* (string, optional) - the name used with +UUID version 3 and 5. + + +If UUID version 1 is used, the function will return the value +*2* if the UUID was generated in an unsafe +manner. This refers to the posibility of two concurrently +running processes generating the same UUID, in cases where +synchronization mechanisms are not available (more details +can be found in the *uuid_generate* man pages +of *libuuid*). + + +This function can be used from any route. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/uuid/doc/contributors.xml b/modules/uuid/doc/contributors.xml deleted file mode 100644 index 842d4029b65..00000000000 --- a/modules/uuid/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 9 - 4 - 368 - 4 - - - 2. - John Burke (@john08burke) - 5 - 3 - 63 - 15 - - - 3. - Maksym Sobolyev (@sobomax) - 5 - 3 - 5 - 5 - - - 4. - Razvan Crainea (@razvancrainea) - 4 - 2 - 2 - 1 - - - 5. - Norman Brandinger (@NormB) - 3 - 1 - 1 - 1 - - - 6. - Aron Podrigal (@ar45) - 2 - 1 - 38 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Aron Podrigal (@ar45) - Sep 2024 - Sep 2024 - - - 2. - Maksym Sobolyev (@sobomax) - Feb 2023 - Nov 2023 - - - 3. - Norman Brandinger (@NormB) - Aug 2021 - Aug 2021 - - - 4. - Vlad Patrascu (@rvlad-patrascu) - Jun 2019 - Feb 2021 - - - 5. - John Burke (@john08burke) - Feb 2021 - Feb 2021 - - - 6. - Razvan Crainea (@razvancrainea) - Aug 2019 - Sep 2019 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Aron Podrigal (@ar45), Norman Brandinger (@NormB), John Burke (@john08burke), Vlad Patrascu (@rvlad-patrascu). -
- -
diff --git a/modules/uuid/doc/uuid.xml b/modules/uuid/doc/uuid.xml deleted file mode 100644 index 15d0f3cd24b..00000000000 --- a/modules/uuid/doc/uuid.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - UUID Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2019 &osipssol; - diff --git a/modules/uuid/doc/uuid_admin.xml b/modules/uuid/doc/uuid_admin.xml deleted file mode 100644 index 606db29b3d8..00000000000 --- a/modules/uuid/doc/uuid_admin.xml +++ /dev/null @@ -1,158 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module provides a way to generate universally unique identifiers - (UUID) as specified in RFC 4122. The UUID is provided as a string - representation by reading the - pseudo-variable or calling the - script function. - -
- -
- Dependencies - -
- &osips; Modules - - This module does not depend on other modules. - -
-
- External Libraries or Applications - - - libuuid - part of the util-linux - package, can be downloaded from: - ftp://ftp.kernel.org/pub/linux/utils/util-linux/ - - -
-
- -
- Exported Parameters - - The module does not export any parameters. - -
- -
- Exported Pseudo-Variables - -
- <varname>$uuid</varname> - - The $uuid variable returns a newly generated - version 4 UUID based on high-quality randomness from /dev/urandom, - if available. Otherwise, a version 1 UUID (based on - current time and the local ethernet MAC address) will be generated. - - - - $uuid usage - -xlog("generated uuid: $uuid\n"); - - - -
-
- -
- Exported Functions - -
- - <function moreinfo="none"> - uuid(out_var, [version], [namespace], [name]) - </function> - - - Generates a new UUID. - - - - - out_var (var) - an output variable - to return the generated UUID. - - - - - version (string, optional) - UUID version - number. The supported values are: - - - 0 - a RFC version 4 or - version 1 UUID will be generated, depending on the - availability of high-quality randomness from - /dev/urandom. This is the default behavior, if the - version parameter is missing. - - - 1 - version 1 UUID - based on current time and the local ethernet MAC - address - - - 3 - version 3 UUID - generated by hashing a namespace identifier and name - via MD5. - - - 4 - version 4 UUID - based on a high-quality random number generator. If - not available, a pseudo-random generator will be - substituted. - - - 5 - version 5 UUID - generated by hashing a namespace identifier and name - via SHA-1. - - - 7 - version 7 UUID - generated by timestamp and randomness. - - - - - - - namespace (string, optional) - the namespace - identifier used with UUID version 3 and 5. This must be a valid - UUID, see RFC 4122 Appendix C for some predefined values. - - - - - name (string, optional) - the name used with - UUID version 3 and 5. - - - - - If UUID version 1 is used, the function will return the value - 2 if the UUID was generated in an unsafe - manner. This refers to the posibility of two concurrently - running processes generating the same UUID, in cases where - synchronization mechanisms are not available (more details - can be found in the uuid_generate man pages - of libuuid). - - - This function can be used from any route. - - -
- -
- -
- diff --git a/modules/uuid/uuid.c b/modules/uuid/uuid.c index 593a512cab5..ba3edadad20 100644 --- a/modules/uuid/uuid.c +++ b/modules/uuid/uuid.c @@ -88,6 +88,7 @@ struct module_exports exports= { 0 }; +#ifdef UUID_TYPE_DCE_TIME_V7 static int gen_uuidv7(uuid_t value) { // random bytes if (getentropy(value, 16) != 0) { @@ -115,6 +116,8 @@ static int gen_uuidv7(uuid_t value) { return RET_OK; } +#endif + static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) { @@ -124,6 +127,13 @@ static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) #endif switch (vers) { + case UUID_VERS_7: + #ifdef UUID_TYPE_DCE_TIME_V7 + rc = gen_uuidv7(uuid); + break; + #else + LM_WARN("UUID version 7 not supported! Using algorithm 0\n"); + #endif case UUID_VERS_0: uuid_generate(uuid); break; @@ -163,9 +173,6 @@ static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) case UUID_VERS_4: uuid_generate_random(uuid); break; - case UUID_VERS_7: - rc = gen_uuidv7(uuid); - break; default: LM_BUG("Bad UUID generation algorithm selected\n"); return RET_ERR; @@ -215,6 +222,9 @@ static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param, str #endif #ifndef UUID_TYPE_DCE_SHA1 case UUID_VERS_5: + #endif + #ifndef UUID_TYPE_DCE_TIME_V7 + case UUID_VERS_7: #endif LM_WARN("UUID version: %d not supported! Using default algorithm\n", vers); @@ -226,7 +236,9 @@ static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param, str case UUID_VERS_3: #endif case UUID_VERS_4: + #ifdef UUID_TYPE_DCE_TIME_V7 case UUID_VERS_7: + #endif #ifdef UUID_TYPE_DCE_SHA1 case UUID_VERS_5: #endif diff --git a/modules/xcap/README b/modules/xcap/README deleted file mode 100644 index 06d58743579..00000000000 --- a/modules/xcap/README +++ /dev/null @@ -1,269 +0,0 @@ -XCAP Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - - 1.3. External Libraries or Applications - 1.4. Exported Parameters - - 1.4.1. db_url(str) - 1.4.2. xcap_table(str) - 1.4.3. integrated_xcap_server (int) - - 1.5. Exported Functions - - 2. Developer Guide - - 2.1. bind_xcap_api(xcap_api_t* api) - 2.2. normalize_xcap_uri - 2.3. parse_xcap_uri - 2.4. get_xcap_doc - 2.5. db_url - 2.6. xcap_table - 2.7. integrated_server - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set db_url parameter - 1.2. Set xcap_table parameter - 1.3. Set integrated_xcap_server parameter - 2.1. xcap_api structure - -Chapter 1. Admin Guide - -1.1. Overview - - The module contains several parameters and functions common to - all modules using XCAP capabilities. - - The module is currently used by the following modules: - presence_xml, rls and xcap_client. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * a database module. - -1.3. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml-dev. - -1.4. Exported Parameters - -1.4.1. db_url(str) - - The database url. - - Default value is - “mysql://opensips:opensipsrw@localhost/opensips”. - - Example 1.1. Set db_url parameter -... -modparam("xcap", "db_url", "dbdriver://username:password@dbhost/dbname") -... - -1.4.2. xcap_table(str) - - The name of the db table where XCAP documents are stored. - - Default value is “xcap”. - - Example 1.2. Set xcap_table parameter -... -modparam("xcap", "xcap_table", "xcap") -... - -1.4.3. integrated_xcap_server (int) - - This parameter is a flag for the type of XCAP server or servers - used. If integrated ones, like OpenXCAP from AG Projects, with - direct access to database table, the parameter should be set to - a positive value. Apart from updating in xcap table, the - integrated server must send an MI command refershWatchers - [pres_uri] [event] when a user modifies a rules document. - - Default value is “0”. - - Example 1.3. Set integrated_xcap_server parameter -... -modparam("xcap", "integrated_xcap_server", 1) -... - -1.5. Exported Functions - - None to be used in configuration file. - -Chapter 2. Developer Guide - - The module exports a number of parameters and functions that - are used in several other modules. - -2.1. bind_xcap_api(xcap_api_t* api) - - This function allows binding the needed functions. - - Example 2.1. xcap_api structure -... -typedef struct xcap_api { - int integrated_server; - str db_url; - str xcap_table; - normalize_sip_uri_t normalize_sip_uri; - parse_xcap_uri_t parse_xcap_uri; - get_xcap_doc_t get_xcap_doc; -} xcap_api_t; -... - -2.2. normalize_xcap_uri - - This function normalizes a SIP URI found in a XCAP document. It - un-escapes it and adds the SIP scheme in case it was missing. - Returns a statically allocated string buffer containing the - normalized form. - - Parameters: - * uri- the URI that needs to be normalized - -2.3. parse_xcap_uri - - This function parses the given XCAP URI. - - Parameters: - * uri- the URI that needs to be parsed in string format - * xcap_uri- xcap_uri_t structure that will be filled with the - parsed information -Parameter type: -... -typedef struct { - char buf[MAX_URI_SIZE]; - str uri; - str root; - str auid; - str tree; - str xui; - str filename; - str selector; -} xcap_uri_t; -... - -2.4. get_xcap_doc - - This function queries the local DB for the required XCAP - document. It will return the document and its corresponding - etag. - - Parameters: - * user- user part od the URI of the document owner - * domain- domain part od the URI of the document owner - * type- type of the requested document, represents the AUID, - can be one of PRES_RULES, RESOURCE_LISTS, RLS_SERVICES, - PIDF_MANIPULATION, OMA_PRES_RULES - * filename- if specified it will be used to match the - document filename, it defaults to 'index' - * match_etag- if specified the document is only returned its - etag matches this one - * doc- reference to the storage for the returned document - * etag- reference to the storage for the returned document's - etag - -2.5. db_url - - URL of the database to which the XCAP mdoules witll connect. - -2.6. xcap_table - - Name of the table used to store XCAP documents. Defaults to - 'xcap'. - -2.7. integrated_server - - Boolean flag indicating if the XCAP server has access to the - local database or xcap_client will be used to fetch documents. - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Saúl Ibarra Corretgé (@saghul) 15 3 1260 53 - 2. Liviu Chircu (@liviuchircu) 11 8 55 106 - 3. Razvan Crainea (@razvancrainea) 7 5 25 21 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) 5 3 6 10 - 5. Ovidiu Sas (@ovidiusas) 3 1 13 3 - 6. Maksym Sobolyev (@sobomax) 3 1 7 7 - 7. Ken Rice 3 1 3 3 - 8. Peter Lemenkov (@lemenkov) 3 1 2 2 - 9. Vlad Patrascu (@rvlad-patrascu) 2 1 2 0 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Ken Rice Sep 2025 - Sep 2025 - 2. Liviu Chircu (@liviuchircu) Jul 2014 - May 2024 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2014 - Mar 2020 - 5. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 6. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2017 - 8. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - 9. Saúl Ibarra Corretgé (@saghul) Nov 2012 - Jan 2013 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Saúl Ibarra Corretgé (@saghul). - - Documentation Copyrights: - - Copyright © 2012 AG Projects diff --git a/modules/xcap/README.md b/modules/xcap/README.md new file mode 100644 index 00000000000..f020fa52752 --- /dev/null +++ b/modules/xcap/README.md @@ -0,0 +1,223 @@ +--- +title: "XCAP Module" +description: "The module contains several parameters and functions common to all modules using XCAP capabilities." +--- + +## Admin Guide + + +### Overview + + +The module contains several parameters and functions common to all +modules using XCAP capabilities. + + +The module is currently used by the following modules: presence_xml, rls and xcap_client. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *a database module*. + + +### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml-dev*. + + +### Exported Parameters + + +#### db_url(str) + + +The database url. + + +*Default value is "mysql://opensips:opensipsrw@localhost/opensips".* + + +```opensips title="Set db_url parameter" +... +modparam("xcap", "db_url", "dbdriver://username:password@dbhost/dbname") +... +``` + + +#### xcap_table(str) + + +The name of the db table where XCAP documents are stored. + + +*Default value is "xcap".* + + +```opensips title="Set xcap_table parameter" +... +modparam("xcap", "xcap_table", "xcap") +... +``` + + +#### integrated_xcap_server (int) + + +This parameter is a flag for the type of XCAP server or servers +used. If integrated ones, like OpenXCAP from AG Projects, +with direct access to database table, the parameter should be +set to a positive value. Apart from updating in xcap table, +the integrated server must send an MI command refershWatchers +[pres_uri] [event] when a user modifies a rules document. + + +*Default value is "0".* + + +```opensips title="Set integrated_xcap_server parameter" +... +modparam("xcap", "integrated_xcap_server", 1) +... +``` + + +### Exported Functions + + +None to be used in configuration file. + + +## Developer Guide + + +The module exports a number of parameters and functions that are used +in several other modules. + + +### bind_xcap_api(xcap_api_t* api) + + +This function allows binding the needed functions. + + +```c title="xcap_api structure" +... +typedef struct xcap_api { + int integrated_server; + str db_url; + str xcap_table; + normalize_sip_uri_t normalize_sip_uri; + parse_xcap_uri_t parse_xcap_uri; + get_xcap_doc_t get_xcap_doc; +} xcap_api_t; +... +``` + + +### normalize_xcap_uri + + +This function normalizes a SIP URI found in a XCAP document. It un-escapes it and +adds the SIP scheme in case it was missing. Returns a statically allocated string +buffer containing the normalized form. + + +Parameters: + + +- *uri*- +the URI that needs to be normalized + + +### parse_xcap_uri + + +This function parses the given XCAP URI. + + +Parameters: + + +- *uri*- +the URI that needs to be parsed in string format +- *xcap_uri*- +xcap_uri_t structure that will be filled with the parsed information + ``` + Parameter type: + ... + typedef struct { + char buf[MAX_URI_SIZE]; + str uri; + str root; + str auid; + str tree; + str xui; + str filename; + str selector; + } xcap_uri_t; + ... + ``` + + +### get_xcap_doc + + +This function queries the local DB for the required XCAP document. It will return the document and its +corresponding etag. + + +Parameters: + + +- *user*- +user part od the URI of the document owner +- *domain*- +domain part od the URI of the document owner +- *type*- +type of the requested document, represents the AUID, can be one of PRES_RULES, RESOURCE_LISTS, +RLS_SERVICES, PIDF_MANIPULATION, OMA_PRES_RULES +- *filename*- +if specified it will be used to match the document filename, it defaults to 'index' +- *match_etag*- +if specified the document is only returned its etag matches this one +- *doc*- +reference to the storage for the returned document +- *etag*- +reference to the storage for the returned document's etag + + +### db_url + + +URL of the database to which the XCAP mdoules witll connect. + + +### xcap_table + + +Name of the table used to store XCAP documents. Defaults to 'xcap'. + + +### integrated_server + + +Boolean flag indicating if the XCAP server has access to the local database or +xcap_client will be used to fetch documents. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/xcap/doc/contributors.xml b/modules/xcap/doc/contributors.xml deleted file mode 100644 index 5118ff5ddb3..00000000000 --- a/modules/xcap/doc/contributors.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Saúl Ibarra Corretgé (@saghul) - 15 - 3 - 1260 - 53 - - - 2. - Liviu Chircu (@liviuchircu) - 11 - 8 - 55 - 106 - - - 3. - Razvan Crainea (@razvancrainea) - 7 - 5 - 25 - 21 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - 5 - 3 - 6 - 10 - - - 5. - Ovidiu Sas (@ovidiusas) - 3 - 1 - 13 - 3 - - - 6. - Maksym Sobolyev (@sobomax) - 3 - 1 - 7 - 7 - - - 7. - Ken Rice - 3 - 1 - 3 - 3 - - - 8. - Peter Lemenkov (@lemenkov) - 3 - 1 - 2 - 2 - - - 9. - Vlad Patrascu (@rvlad-patrascu) - 2 - 1 - 2 - 0 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Ken Rice - Sep 2025 - Sep 2025 - - - 2. - Liviu Chircu (@liviuchircu) - Jul 2014 - May 2024 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2014 - Mar 2020 - - - 5. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 6. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2017 - - - 8. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - 9. - Saúl Ibarra Corretgé (@saghul) - Nov 2012 - Jan 2013 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Saúl Ibarra Corretgé (@saghul). -
- -
diff --git a/modules/xcap/doc/xcap.xml b/modules/xcap/doc/xcap.xml deleted file mode 100644 index fb4059599df..00000000000 --- a/modules/xcap/doc/xcap.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - XCAP Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2012 AG Projects - - - - diff --git a/modules/xcap/doc/xcap_admin.xml b/modules/xcap/doc/xcap_admin.xml deleted file mode 100644 index c85138f02b4..00000000000 --- a/modules/xcap/doc/xcap_admin.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The module contains several parameters and functions common to all - modules using XCAP capabilities. - - - The module is currently used by the following modules: presence_xml, rls and xcap_client. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - a database module. - - - - -
-
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml-dev. - - - - -
- -
- Exported Parameters -
- <varname>db_url</varname>(str) - - The database url. - - - Default value is &defaultdb;. - - - - Set <varname>db_url</varname> parameter - -... -modparam("xcap", "db_url", "&exampledb;") -... - - -
-
- <varname>xcap_table</varname>(str) - - The name of the db table where XCAP documents are stored. - - - Default value is xcap. - - - - Set <varname>xcap_table</varname> parameter - -... -modparam("xcap", "xcap_table", "xcap") -... - - -
-
- <varname>integrated_xcap_server</varname> (int) - - This parameter is a flag for the type of XCAP server or servers - used. If integrated ones, like OpenXCAP from AG Projects, - with direct access to database table, the parameter should be - set to a positive value. Apart from updating in xcap table, - the integrated server must send an MI command refershWatchers - [pres_uri] [event] when a user modifies a rules document. - - - Default value is 0. - - - - Set <varname>integrated_xcap_server</varname> parameter - -... -modparam("xcap", "integrated_xcap_server", 1) -... - - -
-
- -
- Exported Functions - - None to be used in configuration file. - -
- -
- diff --git a/modules/xcap/doc/xcap_devel.xml b/modules/xcap/doc/xcap_devel.xml deleted file mode 100644 index 2d486cb642d..00000000000 --- a/modules/xcap/doc/xcap_devel.xml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - &develguide; - - The module exports a number of parameters and functions that are used - in several other modules. - -
- - <function moreinfo="none">bind_xcap_api(xcap_api_t* api)</function> - - - This function allows binding the needed functions. - - - <function>xcap_api</function> structure - -... -typedef struct xcap_api { - int integrated_server; - str db_url; - str xcap_table; - normalize_sip_uri_t normalize_sip_uri; - parse_xcap_uri_t parse_xcap_uri; - get_xcap_doc_t get_xcap_doc; -} xcap_api_t; -... - - -
- -
- - <function moreinfo="none">normalize_xcap_uri</function> - - - This function normalizes a SIP URI found in a XCAP document. It un-escapes it and - adds the SIP scheme in case it was missing. Returns a statically allocated string - buffer containing the normalized form. - - - Parameters: - - - - - uri- - the URI that needs to be normalized - - - -
- -
- - <function moreinfo="none">parse_xcap_uri</function> - - - This function parses the given XCAP URI. - - - Parameters: - - - - - uri- - the URI that needs to be parsed in string format - - - - - xcap_uri- - xcap_uri_t structure that will be filled with the parsed information - - -Parameter type: -... -typedef struct { - char buf[MAX_URI_SIZE]; - str uri; - str root; - str auid; - str tree; - str xui; - str filename; - str selector; -} xcap_uri_t; -... - - - -
- -
- - <function moreinfo="none">get_xcap_doc</function> - - - This function queries the local DB for the required XCAP document. It will return the document and its - corresponding etag. - - - Parameters: - - - - - user- - user part od the URI of the document owner - - - - - domain- - domain part od the URI of the document owner - - - - - type- - type of the requested document, represents the AUID, can be one of PRES_RULES, RESOURCE_LISTS, - RLS_SERVICES, PIDF_MANIPULATION, OMA_PRES_RULES - - - - - - filename- - if specified it will be used to match the document filename, it defaults to 'index' - - - - - match_etag- - if specified the document is only returned its etag matches this one - - - - - doc- - reference to the storage for the returned document - - - - - etag- - reference to the storage for the returned document's etag - - - -
- -
- - <parameter moreinfo="none">db_url</parameter> - - - URL of the database to which the XCAP mdoules witll connect. - -
- -
- - <parameter moreinfo="none">xcap_table</parameter> - - - Name of the table used to store XCAP documents. Defaults to 'xcap'. - -
- -
- - <parameter moreinfo="none">integrated_server</parameter> - - - Boolean flag indicating if the XCAP server has access to the local database or - xcap_client will be used to fetch documents. - -
- -
- diff --git a/modules/xcap_client/README b/modules/xcap_client/README deleted file mode 100644 index 5032f19e01a..00000000000 --- a/modules/xcap_client/README +++ /dev/null @@ -1,342 +0,0 @@ -XCAP_Client Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. periodical_query(int) - 1.3.2. query_period(int) - - 1.4. Exported Functions - 1.5. Exported MI Functions - - 1.5.1. refreshXcapDoc - - 2. Developer Guide - - 2.1. bind_xcap_client_api(xcap_client_api_t* api) - 2.2. get_elem - 2.3. register_xcb - - 3. Contributors - - 3.1. By Commit Statistics - 3.2. By Commit Activity - - 4. Documentation - - 4.1. Contributors - - List of Tables - - 3.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 3.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set periodical_query parameter - 1.2. Set query_period parameter - 2.1. xcap_client_api structure - -Chapter 1. Admin Guide - -1.1. Overview - - The modules is an XCAP client for OpenSIPS that can be used by - other modules. It fetches XCAP elements, either documents or - part of them, by sending HTTP GET requests. It also offers - support for conditional queries. It uses libcurl library as a - client-side HTTP transfer library. - - The module offers an xcap client interface with general - functions that allow requesting for an specific element from an - xcap server. In addition to that it also offers the service of - storing and update in database the documents it receives. In - this case only an initial request to the module is required - - xcapGetNewDoc-which is like a request to the module to handle - from that point on the referenced document so as to promise - that the newest version will always be present in database. - - The update method is also configurable, either through - periodical queries, applicable to any kind of xcap server or - with an MI command that should be sent by the server upon an - update. - - The module is currently used by the presence_xml module, if the - 'integrated_xcap_server' parameter is not set. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * xcap. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libxml-dev. - * libcurl-dev. - -1.3. Exported Parameters - -1.3.1. periodical_query(int) - - A flag to disable periodical query as an update method for the - documents the module is responsible for. It could be disabled - when the xcap server is capable to send the exported MI command - when a change occurs or when another module in OpenSIPS handles - updates. - - To disable it set this parameter to 0. - - Default value is “1”. - - Example 1.1. Set periodical_query parameter -... -modparam("xcap_client", "periodical_query", 0) -... - -1.3.2. query_period(int) - - Should be set if periodical query is not disabled. Represents - the time interval the xcap servers should be queried for an - update - - To disable it set this parameter to 0. - - Default value is “100”. - - Example 1.2. Set query_period parameter -... -modparam("xcap_client", "query_period", 50) -... - -1.4. Exported Functions - - None to be used in configuration file. - -1.5. Exported MI Functions - -1.5.1. refreshXcapDoc - - MI command that should be sent by an xcap server when a stored - document changes. - - Name: refreshXcapDoc - - Parameters: - * doc_uri: the uri of the document - * port: the port of the xcap server - - MI FIFO Command Format: -... -opensips-cli -x mi refreshXcapDoc /xcap-root/resource-lists/users/eyebea -m/buddies-resource-list.xml 8000 -... - -Chapter 2. Developer Guide - - The module exports a number of functions that allow selecting - and retrieving an element from an xcap server and also - registering a callback to be called when a MI command - refreshXcapDoc is received and the document in question is - retrieved. - -2.1. bind_xcap_client_api(xcap_client_api_t* api) - - This function allows binding the needed functions. - - Example 2.1. xcap_client_api structure -... -typedef struct xcap_client_api { - - /* xcap node selection and retrieving functions*/ - xcap_get_elem_t get_elem; - xcap_nodeSel_init_t int_node_sel; - xcap_nodeSel_add_step_t add_step; - xcap_nodeSel_add_terminal_t add_terminal; - xcap_nodeSel_free_t free_node_sel; - xcapGetNewDoc_t getNewDoc; /* an initial request for the module - fo fetch this document that does not exist in xcap db table - and handle its update*/ - - /* function to register a callback to document changes*/ - register_xcapcb_t register_xcb; -}xcap_client_api_t; -... - -2.2. get_elem - - Field type: -... -typedef char* (*xcap_get_elem_t)(char* xcap_root, -xcap_doc_sel_t* doc_sel, xcap_node_sel_t* node_sel); -... - - This function sends a HTTP request and gets the specified - information from the xcap server. - - The parameters signification: - * xcap_root- the XCAP server address; - * doc_sel- structure with document selection info; -Parameter type: -... -typedef struct xcap_doc_sel -{ - str auid; /* application defined Unique ID*/ - int type; /* the type of the path segment - after the AUID which must either - be GLOBAL_TYPE (for "global") or - USERS_TYPE (for "users") */ - str xid; /* the XCAP User Identifier - if type is USERS_TYPE */ - str filename; -}xcap_doc_sel_t; -... - - * node_sel- structure with node selection info; -Parameter type: -... -typedef struct xcap_node_sel -{ - step_t* steps; - step_t* last_step; - int size; - ns_list_t* ns_list; - ns_list_t* last_ns; - int ns_no; - -}xcap_node_sel_t; - -typedef struct step -{ - str val; - struct step* next; -}step_t; - -typedef struct ns_list -{ - int name; - str value; - struct ns_list* next; -}ns_list_t; -... - - - The node selector is represented like a list of steps that - will be represented in the path string separated by '/' - signs. The namespaces for the nodes are stored also in a - list, as an association of name and value, where the value - is to be included in the respective string val field of the - step. - To construct the node structure the following functions in - the xcap_api structure should be used: 'int_node_sel', - 'add_step' and if needed, 'add_terminal'. - If the intention is to retrieve the whole document this - argument must be NULL. - -2.3. register_xcb - - Field type: -... -typedef int (*register_xcapcb_t)(int types, xcap_cb f); -... - - - 'types' parameter can have a combined value of PRES_RULES, - RESOURCE_LISTS, RLS_SERVICES, OMA_PRES_RULES and - PIDF_MANIPULATION. - - -the callback function has type : -... -typedef int (xcap_cb)(int doc_type, str xid, char* doc); -... - -Chapter 3. Contributors - -3.1. By Commit Statistics - - Table 3.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Anca Vamanu 37 14 2155 193 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 18 15 56 63 - 3. Liviu Chircu (@liviuchircu) 12 10 30 50 - 4. Razvan Crainea (@razvancrainea) 12 10 18 18 - 5. Daniel-Constantin Mierla (@miconda) 9 7 22 19 - 6. Henning Westerholt (@henningw) 8 6 60 49 - 7. Saúl Ibarra Corretgé (@saghul) 6 3 55 89 - 8. Vlad Patrascu (@rvlad-patrascu) 5 3 20 33 - 9. Dan Pascu (@danpascu) 4 2 8 9 - 10. Peter Lemenkov (@lemenkov) 4 2 4 4 - - All remaining contributors: Romanov Vladimir, Ovidiu Sas - (@ovidiusas), Vlad Paiu (@vladpaiu), Maksym Sobolyev - (@sobomax), Konstantin Bokarius, Ken Rice, UnixDev, Edson - Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -3.2. By Commit Activity - - Table 3.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Peter Lemenkov (@lemenkov) Jun 2018 - Oct 2025 - 2. Ken Rice Sep 2025 - Sep 2025 - 3. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 4. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 5. Razvan Crainea (@razvancrainea) Sep 2011 - Sep 2019 - 6. Bogdan-Andrei Iancu (@bogdan-iancu) Feb 2008 - Apr 2019 - 7. Vlad Patrascu (@rvlad-patrascu) May 2017 - Dec 2018 - 8. Vlad Paiu (@vladpaiu) Mar 2014 - Mar 2014 - 9. Ovidiu Sas (@ovidiusas) Jan 2013 - Jan 2013 - 10. Saúl Ibarra Corretgé (@saghul) Nov 2012 - Jan 2013 - - All remaining contributors: Anca Vamanu, Romanov Vladimir, - UnixDev, Henning Westerholt (@henningw), Dan Pascu (@danpascu), - Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson - Gellert Schubert. - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 4. Documentation - -4.1. Contributors - - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu - (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl - Ibarra Corretgé (@saghul), Anca Vamanu, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert. - - Documentation Copyrights: - - Copyright © 2007 Voice Sistem SRL diff --git a/modules/xcap_client/README.md b/modules/xcap_client/README.md new file mode 100644 index 00000000000..e19179189eb --- /dev/null +++ b/modules/xcap_client/README.md @@ -0,0 +1,292 @@ +--- +title: "XCAP_Client Module" +description: "The modules is an XCAP client for OpenSIPS that can be used by other modules." +--- + +## Admin Guide + + +### Overview + + +The modules is an XCAP client for OpenSIPS that can be used by other modules. +It fetches XCAP elements, either documents or part of them, by sending +HTTP GET requests. It also offers support for conditional queries. +It uses libcurl library as a client-side HTTP transfer library. + + +The module offers an xcap client interface with general functions that +allow requesting for an specific element from an xcap server. +In addition to that it also offers the service of storing and update +in database the documents it receives. In this case only an initial +request to the module is required - xcapGetNewDoc-which is like a +request to the module to handle from that point on the referenced +document so as to promise that the newest version will always be +present in database. + + +The update method is also configurable, +either through periodical queries, applicable to any kind of xcap +server or with an MI command that should be sent by the server +upon an update. + + +The module is currently used by the presence_xml module, if the +'integrated_xcap_server' parameter is not set. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *xcap*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libxml-dev*. +- *libcurl-dev*. + + +### Exported Parameters + + +#### periodical_query(int) + + +A flag to disable periodical query as an update method for +the documents the module is responsible for. It could be +disabled when the xcap server is capable to send the exported +MI command when a change occurs or when another module in OpenSIPS +handles updates. + + +To disable it set this parameter to 0. + + +*Default value is "1".* + + +```opensips title="Set periodical_query parameter" +... +modparam("xcap_client", "periodical_query", 0) +... +``` + + +#### query_period(int) + + +Should be set if periodical query is not disabled. +Represents the time interval the xcap servers should be +queried for an update + + +To disable it set this parameter to 0. + + +*Default value is "100".* + + +```opensips title="Set query_period parameter" +... +modparam("xcap_client", "query_period", 50) +... +``` + + +### Exported Functions + + +None to be used in configuration file. + + +### Exported MI Functions + + +#### refreshXcapDoc + + +MI command that should be sent by an xcap server when a +stored document changes. + + +Name: *refreshXcapDoc* + + +Parameters: + + +- doc_uri: the uri of the document +- port: the port of the xcap server + + +MI FIFO Command Format: + + +```bash +... +opensips-cli -x mi refreshXcapDoc /xcap-root/resource-lists/users/eyebeam/buddies-resource-list.xml 8000 +... +``` + + +## Developer Guide + + +The module exports a number of functions that allow selecting +and retrieving an element from an xcap server and also registering +a callback to be called when a MI command refreshXcapDoc is received +and the document in question is retrieved. + + +### bind_xcap_client_api(xcap_client_api_t* api) + + +This function allows binding the needed functions. + + +```c title="xcap_client_api structure" +... +typedef struct xcap_client_api { + + /* xcap node selection and retrieving functions*/ + xcap_get_elem_t get_elem; + xcap_nodeSel_init_t int_node_sel; + xcap_nodeSel_add_step_t add_step; + xcap_nodeSel_add_terminal_t add_terminal; + xcap_nodeSel_free_t free_node_sel; + xcapGetNewDoc_t getNewDoc; /* an initial request for the module + fo fetch this document that does not exist in xcap db table + and handle its update*/ + + /* function to register a callback to document changes*/ + register_xcapcb_t register_xcb; +}xcap_client_api_t; +... +``` + + +### get_elem + + +Field type: + + +```c +... +typedef char* (*xcap_get_elem_t)(char* xcap_root, +xcap_doc_sel_t* doc_sel, xcap_node_sel_t* node_sel); +... +``` + + +This function sends a HTTP request and gets the specified information +from the xcap server. + + +The parameters signification: + + +- *xcap_root*- +the XCAP server address; +- *doc_sel*- +structure with document selection info; + ``` + Parameter type: + ... + typedef struct xcap_doc_sel + { + str auid; /* application defined Unique ID*/ + int type; /* the type of the path segment + after the AUID which must either + be GLOBAL_TYPE (for "global") or + USERS_TYPE (for "users") */ + str xid; /* the XCAP User Identifier + if type is USERS_TYPE */ + str filename; + }xcap_doc_sel_t; + ... + ``` +- *node_sel*- +structure with node selection info; + ``` + Parameter type: + ... + typedef struct xcap_node_sel + { + step_t* steps; + step_t* last_step; + int size; + ns_list_t* ns_list; + ns_list_t* last_ns; + int ns_no; + + }xcap_node_sel_t; + + typedef struct step + { + str val; + struct step* next; + }step_t; + + typedef struct ns_list + { + int name; + str value; + struct ns_list* next; + }ns_list_t; + ... + ``` +The node selector is represented like a list of steps that will +be represented in the path string separated by '/' signs. +The namespaces for the nodes are stored also in a list, as an +association of name and value, where the value is to be included +in the respective string val field of the step. +To construct the node structure the following functions in the xcap_api +structure should be used: 'int_node_sel', 'add_step' and if needed, +'add_terminal'. +If the intention is to retrieve the whole document this argument must +be NULL. + + +### register_xcb + + +Field type: + + +```c +... +typedef int (*register_xcapcb_t)(int types, xcap_cb f); +... +``` + + +- 'types' parameter can have a combined value of PRES_RULES, RESOURCE_LISTS, +RLS_SERVICES, OMA_PRES_RULES and PIDF_MANIPULATION. + + +- the callback function has type: + + +```c +... +typedef int (xcap_cb)(int doc_type, str xid, char* doc); +... +``` + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/xcap_client/doc/contributors.xml b/modules/xcap_client/doc/contributors.xml deleted file mode 100644 index f371a708a27..00000000000 --- a/modules/xcap_client/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Anca Vamanu - 37 - 14 - 2155 - 193 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 18 - 15 - 56 - 63 - - - 3. - Liviu Chircu (@liviuchircu) - 12 - 10 - 30 - 50 - - - 4. - Razvan Crainea (@razvancrainea) - 12 - 10 - 18 - 18 - - - 5. - Daniel-Constantin Mierla (@miconda) - 9 - 7 - 22 - 19 - - - 6. - Henning Westerholt (@henningw) - 8 - 6 - 60 - 49 - - - 7. - Saúl Ibarra Corretgé (@saghul) - 6 - 3 - 55 - 89 - - - 8. - Vlad Patrascu (@rvlad-patrascu) - 5 - 3 - 20 - 33 - - - 9. - Dan Pascu (@danpascu) - 4 - 2 - 8 - 9 - - - 10. - Peter Lemenkov (@lemenkov) - 4 - 2 - 4 - 4 - - - -
-All remaining contributors: Romanov Vladimir, Ovidiu Sas (@ovidiusas), Vlad Paiu (@vladpaiu), Maksym Sobolyev (@sobomax), Konstantin Bokarius, Ken Rice, UnixDev, Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Peter Lemenkov (@lemenkov) - Jun 2018 - Oct 2025 - - - 2. - Ken Rice - Sep 2025 - Sep 2025 - - - 3. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 4. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 5. - Razvan Crainea (@razvancrainea) - Sep 2011 - Sep 2019 - - - 6. - Bogdan-Andrei Iancu (@bogdan-iancu) - Feb 2008 - Apr 2019 - - - 7. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - Dec 2018 - - - 8. - Vlad Paiu (@vladpaiu) - Mar 2014 - Mar 2014 - - - 9. - Ovidiu Sas (@ovidiusas) - Jan 2013 - Jan 2013 - - - 10. - Saúl Ibarra Corretgé (@saghul) - Nov 2012 - Jan 2013 - - - -
-All remaining contributors: Anca Vamanu, Romanov Vladimir, UnixDev, Henning Westerholt (@henningw), Dan Pascu (@danpascu), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Razvan Crainea (@razvancrainea), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Bogdan-Andrei Iancu (@bogdan-iancu), Saúl Ibarra Corretgé (@saghul), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert. -
- -
diff --git a/modules/xcap_client/doc/xcap_client.xml b/modules/xcap_client/doc/xcap_client.xml deleted file mode 100644 index 9ea258618a8..00000000000 --- a/modules/xcap_client/doc/xcap_client.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - XCAP_Client Module - &osipsname; - - - - &admin; - &devel; - &faq; - &contrib; - - &docCopyrights; - ©right; 2007 &voicesystem; - - - - diff --git a/modules/xcap_client/doc/xcap_client_admin.xml b/modules/xcap_client/doc/xcap_client_admin.xml deleted file mode 100644 index a441c8991f5..00000000000 --- a/modules/xcap_client/doc/xcap_client_admin.xml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The modules is an XCAP client for OpenSIPS that can be used by other modules. - It fetches XCAP elements, either documents or part of them, by sending - HTTP GET requests. It also offers support for conditional queries. - It uses libcurl library as a client-side HTTP transfer library. - - - The module offers an xcap client interface with general functions that - allow requesting for an specific element from an xcap server. - In addition to that it also offers the service of storing and update - in database the documents it receives. In this case only an initial - request to the module is required - xcapGetNewDoc-which is like a - request to the module to handle from that point on the referenced - document so as to promise that the newest version will always be - present in database. - - - The update method is also configurable, - either through periodical queries, applicable to any kind of xcap - server or with an MI command that should be sent by the server - upon an update. - - - The module is currently used by the presence_xml module, if the - 'integrated_xcap_server' parameter is not set. - -
- -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - xcap. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libxml-dev. - - - - - libcurl-dev. - - - - -
-
- -
- Exported Parameters -
- <varname>periodical_query</varname>(int) - - A flag to disable periodical query as an update method for - the documents the module is responsible for. It could be - disabled when the xcap server is capable to send the exported - MI command when a change occurs or when another module in &osips; - handles updates. - - - To disable it set this parameter to 0. - - - Default value is 1. - - - - Set <varname>periodical_query</varname> parameter - -... -modparam("xcap_client", "periodical_query", 0) -... - - -
-
- <varname>query_period</varname>(int) - - Should be set if periodical query is not disabled. - Represents the time interval the xcap servers should be - queried for an update - - - To disable it set this parameter to 0. - - - Default value is 100. - - - - Set <varname>query_period</varname> parameter - -... -modparam("xcap_client", "query_period", 50) -... - - -
-
- -
- Exported Functions - - None to be used in configuration file. - -
- -
- Exported MI Functions -
- - <function moreinfo="none">refreshXcapDoc</function> - - - MI command that should be sent by an xcap server when a - stored document changes. - - - Name: refreshXcapDoc - - Parameters: - - - doc_uri: the uri of the document - - - port: the port of the xcap server - - - - - MI FIFO Command Format: - - -... -opensips-cli -x mi refreshXcapDoc /xcap-root/resource-lists/users/eyebeam/buddies-resource-list.xml 8000 -... - -
- -
- -
- diff --git a/modules/xcap_client/doc/xcap_client_devel.xml b/modules/xcap_client/doc/xcap_client_devel.xml deleted file mode 100644 index 8220b083a90..00000000000 --- a/modules/xcap_client/doc/xcap_client_devel.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - &develguide; - - The module exports a number of functions that allow selecting - and retrieving an element from an xcap server and also registering - a callback to be called when a MI command refreshXcapDoc is received - and the document in question is retrieved. - -
- - <function moreinfo="none">bind_xcap_client_api(xcap_client_api_t* api)</function> - - - This function allows binding the needed functions. - - - <function>xcap_client_api</function> structure - -... -typedef struct xcap_client_api { - - /* xcap node selection and retrieving functions*/ - xcap_get_elem_t get_elem; - xcap_nodeSel_init_t int_node_sel; - xcap_nodeSel_add_step_t add_step; - xcap_nodeSel_add_terminal_t add_terminal; - xcap_nodeSel_free_t free_node_sel; - xcapGetNewDoc_t getNewDoc; /* an initial request for the module - fo fetch this document that does not exist in xcap db table - and handle its update*/ - - /* function to register a callback to document changes*/ - register_xcapcb_t register_xcb; -}xcap_client_api_t; -... - - -
- -
- - <function moreinfo="none">get_elem</function> - - - Field type: - -... -typedef char* (*xcap_get_elem_t)(char* xcap_root, -xcap_doc_sel_t* doc_sel, xcap_node_sel_t* node_sel); -... - - - - This function sends a HTTP request and gets the specified information - from the xcap server. - - - The parameters signification: - - - - - xcap_root- - the XCAP server address; - - - - - doc_sel- - structure with document selection info; - - -Parameter type: -... -typedef struct xcap_doc_sel -{ - str auid; /* application defined Unique ID*/ - int type; /* the type of the path segment - after the AUID which must either - be GLOBAL_TYPE (for "global") or - USERS_TYPE (for "users") */ - str xid; /* the XCAP User Identifier - if type is USERS_TYPE */ - str filename; -}xcap_doc_sel_t; -... - - - - - -node_sel- -structure with node selection info; - - -Parameter type: -... -typedef struct xcap_node_sel -{ - step_t* steps; - step_t* last_step; - int size; - ns_list_t* ns_list; - ns_list_t* last_ns; - int ns_no; - -}xcap_node_sel_t; - -typedef struct step -{ - str val; - struct step* next; -}step_t; - -typedef struct ns_list -{ - int name; - str value; - struct ns_list* next; -}ns_list_t; -... - - - - The node selector is represented like a list of steps that will - be represented in the path string separated by '/' signs. - The namespaces for the nodes are stored also in a list, as an - association of name and value, where the value is to be included - in the respective string val field of the step. - - - To construct the node structure the following functions in the xcap_api - structure should be used: 'int_node_sel', 'add_step' and if needed, - 'add_terminal'. - - - If the intention is to retrieve the whole document this argument must - be NULL. - - - - -
-
- - <function moreinfo="none">register_xcb</function> - - - Field type: - -... -typedef int (*register_xcapcb_t)(int types, xcap_cb f); -... - - - - - 'types' parameter can have a combined value of PRES_RULES, RESOURCE_LISTS, - RLS_SERVICES, OMA_PRES_RULES and PIDF_MANIPULATION. - - - -the callback function has type : - -... -typedef int (xcap_cb)(int doc_type, str xid, char* doc); -... - - -
-
- diff --git a/modules/xml/README b/modules/xml/README deleted file mode 100644 index b498d02a68e..00000000000 --- a/modules/xml/README +++ /dev/null @@ -1,264 +0,0 @@ -XML Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - 1.4. Exported Pseudo-Variables - - 1.4.1. $xml(path) - - 1.5. Exported Functions - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Creating a document - 1.2. Inserting nodes with indentation - 1.3. Using script variables in path - -Chapter 1. Admin Guide - -1.1. Overview - - This module exposes a script variable that provides basic - parsing and manipulation of XML documents or blocks of XML - data. The variable provides ways to access entire XML elements, - their text content or their attributes. You can modify the - content and attributes as well as adding or removing nodes in - the XML tree. - - The processing does not take into account any DTDs or schemas - in terms of validation. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - This module does not depend on other modules. - -1.2.2. External Libraries or Applications - - * libxml2 Most Linux and BSD distributions include libxml but - the library can also be downloaded from: xmlsoft.org - -1.3. Exported Parameters - - The module does not export any parameters. - -1.4. Exported Pseudo-Variables - -1.4.1. $xml(path) - - This module exports the $xml(path) variable. - -1.4.1.1. Variable lifetime - - The xml variables will be available to the process that created - them from the moment they were initialized. They will not reset - per message or per transaction. If you want to use them on a - per message basis you should initialize them each time. - -1.4.1.2. Accessing the $xml(path) variable - - Accessing elements and attributes is based on the tree - representation of the XML document thus a complete path from - the root node is required. The in-memory equivalent of an XML - document is an "XML object" which must be initilized with a - well-formed block of XML data before use. In consequence, the - path must start with the object name, followed by any number of - nodes leading to the desired element. - - The grammar that describes the path is: - - path = name | name(identifier)+(acces)? - - identifier = element(index)? - - element = /string | /$var - - index = [integer] | [$var] - - access = .val | .attr/string | .attr/$var - - In order to select between nodes with identical names on a - certain level in the tree, an index can be provided, starting - from 0. - - The sequence of nodes in the path can be followed by .val in - order to access the last node's text content or by - .attr/attr_name in order to access it's attribute named - attr_name. Otherwise the entire element (start-tag, end-tag, - children elements and content) is accessed. - - Assiging NULL to the variable removes the entire element or - it's text content or attribute acording to the access mode. - - If you want to insert an element, you must assign a string - value (containg a well-formed block of XML data that has a root - node) to the parent node. Note that assigning a value directly - to a node does not replace it with that value. - - IMPORTANT: In XML all characters in the content of the document - are significant including blanks and formatting line breaks. An - element and it's content will be returned WITH all the - whitespaces and newlines and when adding a new node under an - existing one, if you want to insert it with indentation, you - must include the needed characters in the assigned string. - - Other script variables can be used as element names, attribute - names and indexes in the path. Variables that will be used as - indexes must contain integer values. Variables that will be - used as element or attribute names should contain string - values. - - Example 1.1. Creating a document -... -$xml(my_doc) = ""; # init object - -$xml(my_doc/doc) = ""; # add a "list" node - -$xml(my_doc/doc/list) = "some_value"; # add an "item" no -de to the list - -$xml(my_doc/doc/list) = "another_value"; # add another item - to the list - -$xml(my_doc/doc/list/item[1].val) = "new_val"; # set text content - of previous item - -$xml(my_doc/doc/list.attr/sort) = "asc"; # add attribute "s -ort" to list node - -$xml(my_doc/doc/list.attr/sort) = NULL; # remove previous -attribute - -$xml(my_doc/doc/list/item[1]) = NULL; # remove second it -em - -$xml(my_doc/doc/list.val) = "end"; # add text content - to list which now has - # mixed content - -$xml(my_doc/doc/list.val) = NULL; # remove the text -content - -xlog("$xml(my_doc/doc/list)\n"); # display the enti -re list - -xlog("$xml(my_doc)\n"); # display the enti -re document - -$xml(my_doc) = NULL; # clear the entire - document -... - - Example 1.2. Inserting nodes with indentation -... -$xml(my_doc) = "\n"; -$xml(my_doc/doc) = "\t\n"; -$xml(my_doc/doc/list) = "\n\t\t\n\t"; - -# this creates the following document: -# -# -# -# -# -# -# without the explicit formating characters the document would be: -# -... - - Example 1.3. Using script variables in path -... -# accessing the attribute of second item in list -$var(my_list) = "list"; -$var(my_idx) = 1; -$var(my_attr) = "sort"; -xlog("$xml(my_doc/doc/$var(my_list)/item[$var(my_idx)].attr/$var(my_attr -))\n"); -... - -1.5. Exported Functions - - The module does not export any script functions. - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Vlad Patrascu (@rvlad-patrascu) 28 14 1367 81 - 2. Liviu Chircu (@liviuchircu) 8 6 22 33 - 3. Razvan Crainea (@razvancrainea) 8 6 11 4 - 4. Maksym Sobolyev (@sobomax) 6 4 6 6 - 5. Bogdan-Andrei Iancu (@bogdan-iancu) 3 1 2 1 - 6. Peter Lemenkov (@lemenkov) 3 1 1 1 - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Maksym Sobolyev (@sobomax) Jan 2021 - Nov 2023 - 2. Vlad Patrascu (@rvlad-patrascu) Feb 2017 - Jul 2022 - 3. Razvan Crainea (@razvancrainea) Mar 2017 - Sep 2019 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Apr 2019 - Apr 2019 - 5. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 6. Liviu Chircu (@liviuchircu) Mar 2017 - Jun 2018 - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu - (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea - (@razvancrainea). - - Documentation Copyrights: - - Copyright © 2017 www.opensips-solutions.com diff --git a/modules/xml/README.md b/modules/xml/README.md new file mode 100644 index 00000000000..7de8acc27d3 --- /dev/null +++ b/modules/xml/README.md @@ -0,0 +1,164 @@ +--- +title: "XML Module" +description: "This module exposes a script variable that provides basic parsing and manipulation of XML documents or blocks of XML data." +--- + +## Admin Guide + + +### Overview + + +This module exposes a script variable that provides basic parsing and manipulation of XML documents or blocks of XML data. The variable provides ways to access entire XML elements, their text content or their attributes. You can modify the content and attributes as well as adding or removing nodes in the XML tree. + + +The processing does not take into account any DTDs or schemas in terms of validation. + + +### Dependencies + + +#### OpenSIPS Modules + + +This module does not depend on other modules. + + +#### External Libraries or Applications + + +- *libxml2* Most Linux and BSD distributions include libxml but the library can also be downloaded from: xmlsoft.org + + +### Exported Parameters + + +The module does not export any parameters. + + +### Exported Pseudo-Variables + + +#### $xml(path) + + +This module exports the *$xml(path)* variable. + + +##### Variable lifetime + + +The xml variables will be available to the +process that created them from the moment they were +initialized. They will not reset per message or per +transaction. If you want to use them on a per message +basis you should initialize them each time. + + +##### Accessing the $xml(path) variable + + +Accessing elements and attributes is based on the tree representation of the XML document thus a complete path from the root node is required. The in-memory equivalent of an XML document is an "XML object" which must be initilized with a well-formed block of XML data before use. In consequence, the path must start with the object name, followed by any number of nodes leading to the desired element. + + +The grammar that describes the path is: +- path = name | name(identifier)+(acces)? +- identifier = element(index)? +- element = /string | /$var +- index = [integer] | [$var] +- access = .val | .attr/string | .attr/$var + + +In order to select between nodes with identical names on a certain level in the tree, an index can be provided, starting from 0. + + +The sequence of nodes in the path can be followed by *.val* in order to access the last node's text content or by *.attr/attr_name* in order to access it's attribute named *attr_name*. Otherwise the entire element (start-tag, end-tag, children elements and content) is accessed. + + +Assiging NULL to the variable removes the entire element or it's text content or attribute acording to the access mode. + + +If you want to insert an element, you must assign a string value (containg a well-formed block of XML data that has a root node) to the parent node. Note that assigning a value directly to a node does not replace it with that value. + + +> [!IMPORTANT] +> In XML all characters in the content of the document are significant including blanks and formatting line breaks. An element and it's content will be returned WITH all the whitespaces and newlines and when adding a new node under an existing one, if you want to insert it with indentation, you must include the needed characters in the assigned string. + + +Other script variables can be used as element names, attribute names and indexes in the path. Variables that will be used as indexes must contain integer values. Variables that will be used as element or attribute names should contain string values. + + +```opensips title="Creating a document" +... +$xml(my_doc) = ""; # init object + +$xml(my_doc/doc) = ""; # add a "list" node + +$xml(my_doc/doc/list) = "some_value"; # add an "item" node to the list + +$xml(my_doc/doc/list) = "another_value"; # add another item to the list + +$xml(my_doc/doc/list/item[1].val) = "new_val"; # set text content of previous item + +$xml(my_doc/doc/list.attr/sort) = "asc"; # add attribute "sort" to list node + +$xml(my_doc/doc/list.attr/sort) = NULL; # remove previous attribute + +$xml(my_doc/doc/list/item[1]) = NULL; # remove second item + +$xml(my_doc/doc/list.val) = "end"; # add text content to list which now has + # mixed content + +$xml(my_doc/doc/list.val) = NULL; # remove the text content + +xlog("$xml(my_doc/doc/list)\n"); # display the entire list + +xlog("$xml(my_doc)\n"); # display the entire document + +$xml(my_doc) = NULL; # clear the entire document +... + +``` + + +```opensips title="Inserting nodes with indentation" +... +$xml(my_doc) = "\n"; +$xml(my_doc/doc) = "\t\n"; +$xml(my_doc/doc/list) = "\n\t\t\n\t"; + +# this creates the following document: +# +# +# +# +# +# +# without the explicit formating characters the document would be: +# +... + +``` + + +```opensips title="Using script variables in path" +... +# accessing the attribute of second item in list +$var(my_list) = "list"; +$var(my_idx) = 1; +$var(my_attr) = "sort"; +xlog("$xml(my_doc/doc/$var(my_list)/item[$var(my_idx)].attr/$var(my_attr))\n"); +... + +``` + + +### Exported Functions + + +The module does not export any script functions. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/xml/doc/contributors.xml b/modules/xml/doc/contributors.xml deleted file mode 100644 index 1150e19ab17..00000000000 --- a/modules/xml/doc/contributors.xml +++ /dev/null @@ -1,144 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Vlad Patrascu (@rvlad-patrascu) - 28 - 14 - 1367 - 81 - - - 2. - Liviu Chircu (@liviuchircu) - 8 - 6 - 22 - 33 - - - 3. - Razvan Crainea (@razvancrainea) - 8 - 6 - 11 - 4 - - - 4. - Maksym Sobolyev (@sobomax) - 6 - 4 - 6 - 6 - - - 5. - Bogdan-Andrei Iancu (@bogdan-iancu) - 3 - 1 - 2 - 1 - - - 6. - Peter Lemenkov (@lemenkov) - 3 - 1 - 1 - 1 - - - -
- - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Maksym Sobolyev (@sobomax) - Jan 2021 - Nov 2023 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - Feb 2017 - Jul 2022 - - - 3. - Razvan Crainea (@razvancrainea) - Mar 2017 - Sep 2019 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Apr 2019 - Apr 2019 - - - 5. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 6. - Liviu Chircu (@liviuchircu) - Mar 2017 - Jun 2018 - - - -
- - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Peter Lemenkov (@lemenkov), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Razvan Crainea (@razvancrainea). -
- -
diff --git a/modules/xml/doc/xml.xml b/modules/xml/doc/xml.xml deleted file mode 100644 index 1454c94d8a1..00000000000 --- a/modules/xml/doc/xml.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - -%docentities; - -]> - - - - XML Module - &osipsname; - - - - &admin; - &contrib; - - &docCopyrights; - ©right; 2017 &osipssol; - diff --git a/modules/xml/doc/xml_admin.xml b/modules/xml/doc/xml_admin.xml deleted file mode 100644 index eeaa19f1b5d..00000000000 --- a/modules/xml/doc/xml_admin.xml +++ /dev/null @@ -1,186 +0,0 @@ - - - - &adminguide; - -
- Overview - - This module exposes a script variable that provides basic parsing and manipulation of XML documents or blocks of XML data. The variable provides ways to access entire XML elements, their text content or their attributes. You can modify the content and attributes as well as adding or removing nodes in the XML tree. - - - The processing does not take into account any DTDs or schemas in terms of validation. - -
- -
- Dependencies - -
- &osips; Modules - - This module does not depend on other modules. - -
-
- External Libraries or Applications - - - libxml2 Most Linux and BSD distributions include libxml but the library can also be downloaded from: xmlsoft.org - - -
-
- -
- Exported Parameters - - The module does not export any parameters. - -
- -
- Exported Pseudo-Variables - -
- <varname>$xml(path)</varname> - - This module exports the $xml(path) variable. - - -
- Variable lifetime - - The xml variables will be available to the - process that created them from the moment they were - initialized. They will not reset per message or per - transaction. If you want to use them on a per message - basis you should initialize them each time. - -
- -
- Accessing the $xml(path) variable - - - Accessing elements and attributes is based on the tree representation of the XML document thus a complete path from the root node is required. The in-memory equivalent of an XML document is an "XML object" which must be initilized with a well-formed block of XML data before use. In consequence, the path must start with the object name, followed by any number of nodes leading to the desired element. - - - The grammar that describes the path is: - - - path = name | name(identifier)+(acces)? - - - identifier = element(index)? - - - element = /string | /$var - - - index = [integer] | [$var] - - - access = .val | .attr/string | .attr/$var - - - - In order to select between nodes with identical names on a certain level in the tree, an index can be provided, starting from 0. - - - The sequence of nodes in the path can be followed by .val in order to access the last node's text content or by .attr/attr_name in order to access it's attribute named attr_name. Otherwise the entire element (start-tag, end-tag, children elements and content) is accessed. - - - Assiging NULL to the variable removes the entire element or it's text content or attribute acording to the access mode. - - - If you want to insert an element, you must assign a string value (containg a well-formed block of XML data that has a root node) to the parent node. Note that assigning a value directly to a node does not replace it with that value. - - - IMPORTANT: In XML all characters in the content of the document are significant including blanks and formatting line breaks. An element and it's content will be returned WITH all the whitespaces and newlines and when adding a new node under an existing one, if you want to insert it with indentation, you must include the needed characters in the assigned string. - - - Other script variables can be used as element names, attribute names and indexes in the path. Variables that will be used as indexes must contain integer values. Variables that will be used as element or attribute names should contain string values. - - - - Creating a document - -... -$xml(my_doc) = "<doc></doc>"; # init object - -$xml(my_doc/doc) = "<list></list>"; # add a "list" node - -$xml(my_doc/doc/list) = "<item>some_value</item>"; # add an "item" node to the list - -$xml(my_doc/doc/list) = "<item>another_value</item>"; # add another item to the list - -$xml(my_doc/doc/list/item[1].val) = "new_val"; # set text content of previous item - -$xml(my_doc/doc/list.attr/sort) = "asc"; # add attribute "sort" to list node - -$xml(my_doc/doc/list.attr/sort) = NULL; # remove previous attribute - -$xml(my_doc/doc/list/item[1]) = NULL; # remove second item - -$xml(my_doc/doc/list.val) = "end"; # add text content to list which now has - # mixed content - -$xml(my_doc/doc/list.val) = NULL; # remove the text content - -xlog("$xml(my_doc/doc/list)\n"); # display the entire list - -xlog("$xml(my_doc)\n"); # display the entire document - -$xml(my_doc) = NULL; # clear the entire document -... - - - - - Inserting nodes with indentation - -... -$xml(my_doc) = "<doc>\n</doc>"; -$xml(my_doc/doc) = "\t<list></list>\n"; -$xml(my_doc/doc/list) = "\n\t\t<item></item>\n\t"; - -# this creates the following document: -# <doc> -# <list> -# <item></item> -# </list> -# </doc> -# -# without the explicit formating characters the document would be: -# <doc><list><item></item></list></doc> -... - - - - - Using script variables in path - -... -# accessing the attribute of second item in list -$var(my_list) = "list"; -$var(my_idx) = 1; -$var(my_attr) = "sort"; -xlog("$xml(my_doc/doc/$var(my_list)/item[$var(my_idx)].attr/$var(my_attr))\n"); -... - - - -
-
- - -
- -
- Exported Functions - The module does not export any script functions. -
- -
- diff --git a/modules/xmpp/README b/modules/xmpp/README deleted file mode 100644 index 6f3c5137f40..00000000000 --- a/modules/xmpp/README +++ /dev/null @@ -1,412 +0,0 @@ -xmpp Module - __________________________________________________________ - - Table of Contents - - 1. Admin Guide - - 1.1. Overview - 1.2. Dependencies - - 1.2.1. OpenSIPS Modules - 1.2.2. External Libraries or Applications - - 1.3. Exported Parameters - - 1.3.1. backend (string) - 1.3.2. xmpp_domain (string) - 1.3.3. xmpp_host (string) - 1.3.4. sip_domain (string) - 1.3.5. xmpp_port (integer) - 1.3.6. xmpp_password (string) - 1.3.7. outbound_proxy (string) - - 1.4. Exported Functions - - 1.4.1. xmpp_send_message() - - 1.5. Configuration - - 2. Contributors - - 2.1. By Commit Statistics - 2.2. By Commit Activity - - 3. Documentation - - 3.1. Contributors - - List of Tables - - 2.1. Top contributors by DevScore^(1), authored commits^(2) and - lines added/removed^(3) - - 2.2. Most recently active contributors^(1) to this module - - List of Examples - - 1.1. Set backend parameter - 1.2. Set xmpp_domain parameter - 1.3. Set xmpp_host parameter - 1.4. Set xmpp_host parameter - 1.5. Set xmpp_port parameter - 1.6. Set xmpp_password parameter - 1.7. Set outbound_proxy parameter - 1.8. xmpp_send_message() usage - -Chapter 1. Admin Guide - -1.1. Overview - - This modules is a gateway between OpenSIPS and a jabber server. - It enables the exchange of instant messages between SIP clients - and XMPP(jabber) clients. - - The gateway has two modes to run: - * the component-mode - the gateway requires a standalone XMPP - server amd the 'xmpp' module acts as a XMPP component - * the server-mode - the module acts itself as a XMPP server, - no requirement for another XMPP server in the system. NOTE: - this is limited implementation of a XMPP server, it does - not support SRV or TLS so far. This mode is in beta stage - for the moment. - - In the component mode, you need a local XMPP server - (recommended jabberd2 or ejabberd); the xmpp module will relay - all your connections to a tcp connection to the local jabber - server. - - After you have a running XMPP server, what you need to do is - set the following parameters in the OpenSIPS configuration - file: - * xmpp_domain and xmpp_host, which are explained in the - Exported Parameters section; - * socket= your ip; - * alias=opensips domain and alias=gateway domain; - * you can also change the jabber server password, which must - be the same as the xmpp_password parameter. - - A use case, for the component-mode, would look like this: - * OpenSIPS is running on sip-server.opensips.org; - * the jabber server is running on xmpp.opensips.org; - * the component is running on xmpp-sip.opensips.org. - - In the server mode, the xmpp module is a minimal jabber server, - thus you do not need to install another jabber server, the - gateway will connect to the jabber servers, where the users you - want to chat with have an account. - - If you want to change to server-mode, you have to change the - "backend" parameter, as shown in the Exported Parameters - section, from component to server. - - A use case, for the server-mode, would look like this: - * OpenSIPS is running on sip-server.opensips.org; - * the "XMPP server" is running on xmpp-sip.opensips.org. - -1.2. Dependencies - -1.2.1. OpenSIPS Modules - - The following modules must be loaded before this module: - * requires 'tm' module. - -1.2.2. External Libraries or Applications - - The following libraries or applications must be installed - before running OpenSIPS with this module loaded: - * libexpat1-devel - used for parsing/building XML. - -1.3. Exported Parameters - -1.3.1. backend (string) - - The mode you are using the module; it can be either component - or server. - - Default value is "component". - - Example 1.1. Set backend parameter -... - modparam("xmpp", "backend", "server") -... - -1.3.2. xmpp_domain (string) - - The xmpp domain of the component or the server, depending on - the mode we are in. - - Default value is "127.0.0.1". - - Example 1.2. Set xmpp_domain parameter -... - modparam("xmpp", "xmpp_domain", "xmpp.opensips.org") -... - -1.3.3. xmpp_host (string) - - The ip address or the name of the local jabber server, if the - backend is set to "component"; or the address to bind to in the - server mode. - - Default value is "127.0.0.1". - - Example 1.3. Set xmpp_host parameter -... - modparam("xmpp", "xmpp_host", "xmpp.opensips.org") -... - -1.3.4. sip_domain (string) - - This parameter must be set only if the xmpp module is used in - component mode and the domain that is the host for the jabber - server is the same as the domain of the sip server(when using - the same domain name for the SIP service and for the XMPP - service). In this case, if we were to add buddies in xmpp - accounts with that domain, then all the messages that will - reach the jabber server will be considered to be for local xmpp - users. It is necessary therefore to make a translate the sip - domain name into another domain when sending messages in xmpp. - This parameter is exactly the name that should be used as the - SIP domain name in XMPP. Usage example: If the sip and xmpp - domain is opensips.org and this parameter is set to - sip.opensips.org, than in all the requests sent in xmpp the sip - users will have the domain translated to sip.opensips.org. - Also, in XMPP account the SIP buddies must have this domain: - sip.opensips.org, and it will be translated to the real one - opensips.org when traversing the gateway. - - Default value is NULL. - - Example 1.4. Set xmpp_host parameter -... - modparam("xmpp", "sip_domain", "sip.opensips.org") -... - -1.3.5. xmpp_port (integer) - - In the component mode, this is the port of the jabber router we - connect to. In the server mode, it is the transport address to - bind to. - - Default value is "5347", if backend is set to "component" and - "5269", if backend is set to "server". - - Example 1.5. Set xmpp_port parameter -... - modparam("xmpp", "xmpp_port", 5269) -... - -1.3.6. xmpp_password (string) - - The password of the local jabber server. - - Default value is "secret"; if changed here, it must also be - changed in the c2s.xml, added by the jabber server. This is how - the default configuration for the jabberd2 looks like: - - ............... - ; - secret; ; - - Example 1.6. Set xmpp_password parameter -... - modparam("xmpp", "xmpp_password", "secret") -... - -1.3.7. outbound_proxy (string) - - The SIP address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or - when using a separate OpenSIPS instance for xmpp processing. If - not set, the message will be sent to the address in destination - URI. - - Default value is NULL. - - Example 1.7. Set outbound_proxy parameter -... - modparam("xmpp", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - -1.4. Exported Functions - -1.4.1. xmpp_send_message() - - Converts SIP messages to XMPP(jabber) messages, in order to be - relayed to a XMPP(jabber) client. - - Example 1.8. xmpp_send_message() usage -... -xmpp_send_message(); -... - -1.5. Configuration - - Next is presented a sample configuration file one can use to - implement a standalone SIP-to-XMPP gateway. You can run an - instance of OpenSIPS on a separate machine or on different port - with the following config, and have the main SIP server - configured to forward all SIP requests for XMPP world to it. -.... -# -# simple quick-start config script for XMPP GW -# -# make sure in your main SIP server that you send -# only the adequate SIP MESSAGES to XMPP GW -# -# -# ----------- global configuration parameters ------------------------ - -log_level=3 # debug level (cmd line: -dddddddddd) -stderror_enabled=no -syslog_enabled=yes - -/* Uncomment these line to enter debugging mode */ -#debug_mode=yes - -check_via=no # (cmd. line: -v) -dns=no # (cmd. line: -r) -rev_dns=no # (cmd. line: -R) -udp_workers=4 - -socket=udp:10.10.10.10:5076 -alias=sip-xmpp.opensips.org - -# ------------------ module loading ---------------------------------- - -mpath="/usr/local/opensips/lib/opensips/modules/" -loadmodule "sl.so" -loadmodule "tm.so" -loadmodule "rr.so" -loadmodule "maxfwd.so" -loadmodule "textops.so" -loadmodule "mi_fifo.so" - - -# XMPP -loadmodule "xmpp.so" - -modparam("xmpp", "xmpp_domain", "xmpp-sip.opensips.org") -modparam("xmpp", "xmpp_host", "xmpp.opensips.org") - -#modparam("xmpp", "backend", "server") -modparam("xmpp", "backend", "component") - -# ----------------- setting module-specific parameters --------------- - -# -- mi_fifo params -- - -modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo_xmpp") - -# ------------------------- request routing logic ------------------- - -# main routing logic - -route{ - - # initial sanity checks -- messages with - # max_forwards==0, or excessively long requests - if (!mf_process_maxfwd_header("10")) { - sl_send_reply(483,"Too Many Hops"); - exit; - }; - - ### absorb retransmissions ### - if (!t_newtran()) { - sl_reply_error(); - return; - } - if (is_method("MESSAGE")) { - log("*** xmpp-handled MESSAGE message.\n"); - if (xmpp_send_message()) { - t_reply(200, "Accepted"); - } else { - t_reply(404, "Not found"); - } - return; - } - - log("*** xmpp: unhandled message type\n"); - t_reply(503, "Service unavailable"); - return; -} - - -.... - -Chapter 2. Contributors - -2.1. By Commit Statistics - - Table 2.1. Top contributors by DevScore^(1), authored - commits^(2) and lines added/removed^(3) - Name DevScore Commits Lines ++ Lines -- - 1. Daniel-Constantin Mierla (@miconda) 69 16 5988 76 - 2. Bogdan-Andrei Iancu (@bogdan-iancu) 30 23 120 245 - 3. Anca Vamanu 20 9 438 398 - 4. Liviu Chircu (@liviuchircu) 14 11 56 98 - 5. Razvan Crainea (@razvancrainea) 9 7 31 23 - 6. Vlad Patrascu (@rvlad-patrascu) 6 4 9 5 - 7. Henning Westerholt (@henningw) 5 3 13 13 - 8. Maksym Sobolyev (@sobomax) 4 2 6 7 - 9. Sergio Gutierrez 3 1 5 5 - 10. Vlad Paiu (@vladpaiu) 3 1 3 2 - - All remaining contributors: Konstantin Bokarius, John Riordan, - Juha Heinanen (@juha-h), Peter Lemenkov (@lemenkov), Zero King - (@l2dy), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / - (project_lines_added / project_commits) + author_lines_deleted - / (project_lines_deleted / project_commits) - - (2) including any documentation-related commits, excluding - merge commits. Regarding imported patches/code, we do our best - to count the work on behalf of the proper owner, as per the - "fix_authors" and "mod_renames" arrays in - opensips/doc/build-contrib.sh. If you identify any - patches/commits which do not get properly attributed to you, - please submit a pull request which extends "fix_authors" and/or - "mod_renames". - - (3) ignoring whitespace edits, renamed files and auto-generated - files - -2.2. By Commit Activity - - Table 2.2. Most recently active contributors^(1) to this module - Name Commit Activity - 1. Liviu Chircu (@liviuchircu) Mar 2014 - May 2024 - 2. Vlad Patrascu (@rvlad-patrascu) May 2017 - May 2023 - 3. Maksym Sobolyev (@sobomax) Feb 2023 - Feb 2023 - 4. Bogdan-Andrei Iancu (@bogdan-iancu) Oct 2006 - Apr 2020 - 5. Zero King (@l2dy) Mar 2020 - Mar 2020 - 6. Razvan Crainea (@razvancrainea) Aug 2015 - Sep 2019 - 7. Peter Lemenkov (@lemenkov) Jun 2018 - Jun 2018 - 8. Vlad Paiu (@vladpaiu) Feb 2012 - Feb 2012 - 9. Anca Vamanu Oct 2007 - Sep 2010 - 10. John Riordan May 2009 - May 2009 - - All remaining contributors: Sergio Gutierrez, Henning - Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), - Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen - (@juha-h). - - (1) including any documentation-related commits, excluding - merge commits - -Chapter 3. Documentation - -3.1. Contributors - - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu - (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter - Lemenkov (@lemenkov), Anca Vamanu, Henning Westerholt - (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin - Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). - - Documentation Copyrights: - - Copyright © 2006-2008 Voice Sistem SRL diff --git a/modules/xmpp/README.md b/modules/xmpp/README.md new file mode 100644 index 00000000000..b9f27925c44 --- /dev/null +++ b/modules/xmpp/README.md @@ -0,0 +1,244 @@ +--- +title: "xmpp Module" +description: "This modules is a gateway between OpenSIPS and a jabber server." +--- + +## Admin Guide + + +### Overview + + +This modules is a gateway between OpenSIPS and a jabber server. It enables the exchange of instant messages between +SIP clients and XMPP(jabber) clients. + + +The gateway has two modes to run: + + +- **the component-mode** - the gateway requires a standalone XMPP server amd the 'xmpp' module acts as +a XMPP component +- **the server-mode** - the module acts itself as a XMPP server, no requirement for another XMPP server in the system. NOTE: this is limited implementation of a XMPP server, it does not support SRV or TLS so far. This mode is in beta stage for the moment. + + +In the component mode, you need a local XMPP server (recommended jabberd2 or ejabberd); the xmpp module will relay all your connections to a tcp connection to the local jabber server. + + +After you have a running XMPP server, what you need to do is set the following parameters in the OpenSIPS configuration file: + + +- xmpp_domain and xmpp_host, which are explained in the +[exported parameters](#exported_parameters) section; +- socket= your ip; +- alias=opensips domain and +alias=gateway domain; +- you can also change the jabber server password, which must be the same as the xmpp_password parameter. + + +A use case, for the component-mode, would look like this: + + +- OpenSIPS is running on sip-server.opensips.org; +- the jabber server is running on xmpp.opensips.org; +- the component is running on xmpp-sip.opensips.org. + + +In the server mode, the xmpp module is a minimal jabber server, thus you do not need to install another jabber server, the gateway will connect to the jabber servers, where the users you want to chat with have an account. + + +If you want to change to server-mode, you have to change the +"backend" parameter, as shown in the +[exported parameters](#exported_parameters) section, from component to server. + + +A use case, for the server-mode, would look like this: + + +- OpenSIPS is running on sip-server.opensips.org; +- the "XMPP server" is running on xmpp-sip.opensips.org. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *requires 'tm' module*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before running +OpenSIPS with this module loaded: + + +- *libexpat1-devel* - used for parsing/building XML. + + +### Exported Parameters + + +#### backend (string) + + +The mode you are using the module; it can be either component or server. + + +*Default value is "component".* + + +```opensips title="Set backend parameter" +... + modparam("xmpp", "backend", "server") +... +``` + + +#### xmpp_domain (string) + + +The xmpp domain of the component or the server, depending on the mode we are in. + + +*Default value is "127.0.0.1".* + + +```opensips title="Set xmpp_domain parameter" +... + modparam("xmpp", "xmpp_domain", "xmpp.opensips.org") +... +``` + + +#### xmpp_host (string) + + +The ip address or the name of the local jabber server, if the backend is set to "component"; or the address to bind to in the server mode. + + +*Default value is "127.0.0.1".* + + +```opensips title="Set xmpp_host parameter" +... + modparam("xmpp", "xmpp_host", "xmpp.opensips.org") +... +``` + + +#### sip_domain (string) + + +This parameter must be set only if the xmpp module is used in component mode and the domain +that is the host for the jabber server is the same as the domain of the sip server(when using +the same domain name for the SIP service and for the XMPP service). In this case, +if we were to add buddies in xmpp accounts with that domain, then all the messages that will +reach the jabber server will be considered to be for local xmpp users. It is necessary therefore +to make a translate the sip domain name into another domain when sending messages in xmpp. +This parameter is exactly the name that should be used as the SIP domain name in XMPP. +Usage example: If the sip and xmpp domain is opensips.org and this parameter is set to sip.opensips.org, +than in all the requests sent in xmpp the sip users will have the domain translated to sip.opensips.org. +Also, in XMPP account the SIP buddies must have this domain: sip.opensips.org, and it will be +translated to the real one opensips.org when traversing the gateway. + + +*Default value is NULL.* + + +```opensips title="Set xmpp_host parameter" +... + modparam("xmpp", "sip_domain", "sip.opensips.org") +... +``` + + +#### xmpp_port (integer) + + +In the component mode, this is the port of the jabber router we connect to. In the server mode, it is the transport address to bind to. + + +*Default value is "5347", if backend is set to "component" and "5269", if backend is set to "server".* + + +```opensips title="Set xmpp_port parameter" +... + modparam("xmpp", "xmpp_port", 5269) +... +``` + + +#### xmpp_password (string) + + +The password of the local jabber server. + + +*Default value is "secret"; if changed here, it must also be changed in the c2s.xml, added by the jabber server. This is how the default configuration for the jabberd2 looks like:* + + +``` + + ............... + ; + secret; ; +``` + + +```opensips title="Set xmpp_password parameter" +... + modparam("xmpp", "xmpp_password", "secret") +... +``` + + +#### outbound_proxy (string) + + +The SIP address used as next hop when sending the message. Very +useful when using OpenSIPS with a domain name not in DNS, or +when using a separate OpenSIPS instance for xmpp processing. If +not set, the message will be sent to the address in destination +URI. + + +*Default value is NULL.* + + +```opensips title="Set outbound_proxy parameter" +... + modparam("xmpp", "outbound_proxy", "sip:opensips.org;transport=tcp") +... +``` + + +### Exported Functions + + +#### xmpp_send_message() + + +Converts SIP messages to XMPP(jabber) messages, in order to be relayed to a XMPP(jabber) client. + + +```opensips title="xmpp_send_message() usage" +... +xmpp_send_message(); +... +``` + + +## Samples + +[samples](./samples/samples.md "include") + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/modules/xmpp/doc/contributors.xml b/modules/xmpp/doc/contributors.xml deleted file mode 100644 index ecdb8b6caa1..00000000000 --- a/modules/xmpp/doc/contributors.xml +++ /dev/null @@ -1,196 +0,0 @@ - - - &contributors; - -
- By Commit Statistics - - Top contributors by DevScore<superscript>(1)</superscript>, authored commits<superscript>(2)</superscript> and lines added/removed<superscript>(3)</superscript> - - - - - Name - DevScore - Commits - Lines ++ - Lines -- - - - - - 1. - Daniel-Constantin Mierla (@miconda) - 69 - 16 - 5988 - 76 - - - 2. - Bogdan-Andrei Iancu (@bogdan-iancu) - 30 - 23 - 120 - 245 - - - 3. - Anca Vamanu - 20 - 9 - 438 - 398 - - - 4. - Liviu Chircu (@liviuchircu) - 14 - 11 - 56 - 98 - - - 5. - Razvan Crainea (@razvancrainea) - 9 - 7 - 31 - 23 - - - 6. - Vlad Patrascu (@rvlad-patrascu) - 6 - 4 - 9 - 5 - - - 7. - Henning Westerholt (@henningw) - 5 - 3 - 13 - 13 - - - 8. - Maksym Sobolyev (@sobomax) - 4 - 2 - 6 - 7 - - - 9. - Sergio Gutierrez - 3 - 1 - 5 - 5 - - - 10. - Vlad Paiu (@vladpaiu) - 3 - 1 - 3 - 2 - - - -
-All remaining contributors: Konstantin Bokarius, John Riordan, Juha Heinanen (@juha-h), Peter Lemenkov (@lemenkov), Zero King (@l2dy), Edson Gellert Schubert. - - (1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits) - - - (2) including any documentation-related commits, excluding merge commits. Regarding imported patches/code, we do our best to count the work on behalf of the proper owner, as per the "fix_authors" and "mod_renames" arrays in opensips/doc/build-contrib.sh. If you identify any patches/commits which do not get properly attributed to you, please submit a pull request which extends "fix_authors" and/or "mod_renames". - - - (3) ignoring whitespace edits, renamed files and auto-generated files - -
- -
- By Commit Activity - - Most recently active contributors<superscript>(1)</superscript> to this module - - - - - Name - Commit Activity - - - - - 1. - Liviu Chircu (@liviuchircu) - Mar 2014 - May 2024 - - - 2. - Vlad Patrascu (@rvlad-patrascu) - May 2017 - May 2023 - - - 3. - Maksym Sobolyev (@sobomax) - Feb 2023 - Feb 2023 - - - 4. - Bogdan-Andrei Iancu (@bogdan-iancu) - Oct 2006 - Apr 2020 - - - 5. - Zero King (@l2dy) - Mar 2020 - Mar 2020 - - - 6. - Razvan Crainea (@razvancrainea) - Aug 2015 - Sep 2019 - - - 7. - Peter Lemenkov (@lemenkov) - Jun 2018 - Jun 2018 - - - 8. - Vlad Paiu (@vladpaiu) - Feb 2012 - Feb 2012 - - - 9. - Anca Vamanu - Oct 2007 - Sep 2010 - - - 10. - John Riordan - May 2009 - May 2009 - - - -
-All remaining contributors: Sergio Gutierrez, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). - - (1) including any documentation-related commits, excluding merge commits - -
- -
- - Documentation -
- Contributors - Last edited by: Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Bogdan-Andrei Iancu (@bogdan-iancu), Peter Lemenkov (@lemenkov), Anca Vamanu, Henning Westerholt (@henningw), Daniel-Constantin Mierla (@miconda), Konstantin Bokarius, Edson Gellert Schubert, Juha Heinanen (@juha-h). -
- -
diff --git a/modules/xmpp/doc/xmpp.xml b/modules/xmpp/doc/xmpp.xml deleted file mode 100644 index 189099e7a2a..00000000000 --- a/modules/xmpp/doc/xmpp.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - -%docentities; - -]> - - - - xmpp Module - &osipsname; - - - - &admin; - &faq; - &contrib; - - &docCopyrights; - ©right; 2006-2008 &voicesystem; - - diff --git a/modules/xmpp/doc/xmpp_admin.xml b/modules/xmpp/doc/xmpp_admin.xml deleted file mode 100644 index 8a342e62289..00000000000 --- a/modules/xmpp/doc/xmpp_admin.xml +++ /dev/null @@ -1,296 +0,0 @@ - - - - - &adminguide; - -
- Overview - This modules is a gateway between OpenSIPS and a jabber server. It enables the exchange of instant messages between - SIP clients and XMPP(jabber) clients. - The gateway has two modes to run: - - - - the component-mode - the gateway requires a standalone XMPP server amd the 'xmpp' module acts as - a XMPP component - - - the server-mode - the module acts itself as a XMPP server, no requirement for another XMPP server in the system. NOTE: this is limited implementation of a XMPP server, it does not support SRV or TLS so far. This mode is in beta stage for the moment. - - - In the component mode, you need a local XMPP server (recommended jabberd2 or ejabberd); the xmpp module will relay all your connections to a tcp connection to the local jabber server. - After you have a running XMPP server, what you need to do is set the following parameters in the OpenSIPS configuration file: - - - xmpp_domain and xmpp_host, which are explained in the - section; - - - - socket= your ip; - - - alias=opensips domain and - alias=gateway domain; - - - you can also change the jabber server password, which must be the same as the xmpp_password parameter. - - - A use case, for the component-mode, would look like this: - - - OpenSIPS is running on sip-server.opensips.org; - - - the jabber server is running on xmpp.opensips.org; - - - the component is running on xmpp-sip.opensips.org. - - - - In the server mode, the xmpp module is a minimal jabber server, thus you do not need to install another jabber server, the gateway will connect to the jabber servers, where the users you want to chat with have an account. - - If you want to change to server-mode, you have to change the - "backend" parameter, as shown in the - section, from component to server. - A use case, for the server-mode, would look like this: - - - OpenSIPS is running on sip-server.opensips.org; - - - the "XMPP server" is running on xmpp-sip.opensips.org. - - -
-
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - requires 'tm' module. - - - - -
-
- External Libraries or Applications - - The following libraries or applications must be installed before running - &osips; with this module loaded: - - - - libexpat1-devel - used for parsing/building XML. - - - - -
-
- -
- Exported Parameters -
- <varname>backend</varname> (string) - - The mode you are using the module; it can be either component or server. - - - - Default value is "component". - - - - Set <varname>backend</varname> parameter - -... - modparam("xmpp", "backend", "server") -... - - -
-
- <varname>xmpp_domain</varname> (string) - - The xmpp domain of the component or the server, depending on the mode we are in. - - - - Default value is "127.0.0.1". - - - - Set <varname>xmpp_domain</varname> parameter - -... - modparam("xmpp", "xmpp_domain", "xmpp.opensips.org") -... - - -
-
- <varname>xmpp_host</varname> (string) - - The ip address or the name of the local jabber server, if the backend is set to "component"; or the address to bind to in the server mode. - - - - Default value is "127.0.0.1". - - - - Set <varname>xmpp_host</varname> parameter - -... - modparam("xmpp", "xmpp_host", "xmpp.opensips.org") -... - - -
- -
- <varname>sip_domain</varname> (string) - - This parameter must be set only if the xmpp module is used in component mode and the domain - that is the host for the jabber server is the same as the domain of the sip server(when using - the same domain name for the SIP service and for the XMPP service). In this case, - if we were to add buddies in xmpp accounts with that domain, then all the messages that will - reach the jabber server will be considered to be for local xmpp users. It is necessary therefore - to make a translate the sip domain name into another domain when sending messages in xmpp. - This parameter is exactly the name that should be used as the SIP domain name in XMPP. - Usage example: If the sip and xmpp domain is opensips.org and this parameter is set to sip.opensips.org, - than in all the requests sent in xmpp the sip users will have the domain translated to sip.opensips.org. - Also, in XMPP account the SIP buddies must have this domain: sip.opensips.org, and it will be - translated to the real one opensips.org when traversing the gateway. - - - - Default value is NULL. - - - - Set <varname>xmpp_host</varname> parameter - -... - modparam("xmpp", "sip_domain", "sip.opensips.org") -... - - -
- -
- <varname>xmpp_port</varname> (integer) - - In the component mode, this is the port of the jabber router we connect to. In the server mode, it is the transport address to bind to. - - - - Default value is "5347", if backend is set to "component" and "5269", if backend is set to "server". - - - - Set <varname>xmpp_port</varname> parameter - -... - modparam("xmpp", "xmpp_port", 5269) -... - - -
- -
- <varname>xmpp_password</varname> (string) - The password of the local jabber server. - - - Default value is "secret"; if changed here, it must also be changed in the c2s.xml, added by the jabber server. This is how the default configuration for the jabberd2 looks like: - - - - ............... - ; - secret; ; ]]> - - - - Set <varname>xmpp_password</varname> parameter - -... - modparam("xmpp", "xmpp_password", "secret") -... - - -
-
- <varname>outbound_proxy</varname> (string) - - The SIP address used as next hop when sending the message. Very - useful when using OpenSIPS with a domain name not in DNS, or - when using a separate OpenSIPS instance for xmpp processing. If - not set, the message will be sent to the address in destination - URI. - - - - Default value is NULL. - - - - Set <varname>outbound_proxy</varname> parameter - -... - modparam("xmpp", "outbound_proxy", "sip:opensips.org;transport=tcp") -... - - -
-
- -
- Exported Functions -
- - <function moreinfo="none">xmpp_send_message()</function> - - - Converts SIP messages to XMPP(jabber) messages, in order to be relayed to a XMPP(jabber) client. - - - - <function>xmpp_send_message()</function> usage - -... -xmpp_send_message(); -... - - -
-
-
- Configuration - - Next is presented a sample configuration file one can use to implement a - standalone SIP-to-XMPP gateway. You can run an instance of OpenSIPS on a - separate machine or on different port with the following config, and have - the main SIP server configured to forward all SIP requests for XMPP world - to it. - - -.... -&cfg; -.... - - -
-
- diff --git a/modules/xmpp/network.c b/modules/xmpp/network.c index bd9a54f78be..d617a2aee04 100644 --- a/modules/xmpp/network.c +++ b/modules/xmpp/network.c @@ -37,6 +37,30 @@ #include "../../sr_module.h" #include "../../resolve.h" +static int net_resolve_ipv4(char *server, struct in_addr *addr) +{ + struct hostent *host; + + if (inet_aton(server, addr)) + return 0; + + LM_DBG("resolving %s...\n", server); + + host = resolvehost(server,0); + if (!host) { + LM_ERR("resolving %s failed (%s).\n", server, hstrerror(h_errno)); + return -1; + } + if (host->h_addrtype != AF_INET || host->h_length != sizeof(*addr) || + host->h_addr_list[0] == NULL) { + LM_ERR("invalid address family or length for %s\n", server); + return -1; + } + + memcpy(addr, host->h_addr_list[0], sizeof(*addr)); + return 0; +} + int net_listen(char *server, int port) { int fd; @@ -47,18 +71,8 @@ int net_listen(char *server, int port) sin.sin_family = AF_INET; sin.sin_port = htons(port); - if (!inet_aton(server, &sin.sin_addr)) { - struct hostent *host; - - LM_DBG("resolving %s...\n", server); - - if (!(host = resolvehost(server,0))) { - LM_ERR("resolving %s failed (%s).\n", server, - hstrerror(h_errno)); - return -1; - } - memcpy(&sin.sin_addr, host->h_addr_list[0], host->h_length); - } + if (net_resolve_ipv4(server, &sin.sin_addr) < 0) + return -1; if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { LM_ERR("socket() failed: %s\n", strerror(errno)); @@ -95,18 +109,8 @@ int net_connect(char *server, int port) sin.sin_family = AF_INET; sin.sin_port = htons(port); - if (!inet_aton(server, &sin.sin_addr)) { - struct hostent *host; - - LM_DBG("resolving %s...\n", server); - - if (!(host = resolvehost(server,0))) { - LM_ERR("resolving %s failed (%s).\n", server, - hstrerror(h_errno)); - return -1; - } - memcpy(&sin.sin_addr, host->h_addr_list[0], host->h_length); - } + if (net_resolve_ipv4(server, &sin.sin_addr) < 0) + return -1; if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { LM_ERR("socket() failed: %s\n", strerror(errno)); diff --git a/modules/xmpp/doc/opensips-xmpp.cfg b/modules/xmpp/samples/opensips-xmpp.cfg similarity index 100% rename from modules/xmpp/doc/opensips-xmpp.cfg rename to modules/xmpp/samples/opensips-xmpp.cfg diff --git a/modules/xmpp/samples/samples.md b/modules/xmpp/samples/samples.md new file mode 100644 index 00000000000..c2c538324a7 --- /dev/null +++ b/modules/xmpp/samples/samples.md @@ -0,0 +1,10 @@ +### OpenSIPS Config Script - XMPP Usage + +Next is presented a sample configuration file one can use to implement a +standalone SIP-to-XMPP gateway. You can run an instance of OpenSIPS on a +separate machine or on different port with the following config, and have +the main SIP server configured to forward all SIP requests for XMPP world +to it. + +[opensips-xmpp.cfg](./opensips-xmpp.cfg "include") + diff --git a/msg_translator.c b/msg_translator.c index 18d2478791e..b9d578bc86f 100644 --- a/msg_translator.c +++ b/msg_translator.c @@ -3069,6 +3069,7 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port, str *params,int *len) { int pos = 0; + int total_len; if (!len) { @@ -3088,6 +3089,21 @@ char *construct_uri(str *protocol,str *username,str *domain,str *port, return 0; } + total_len = protocol->len + 1 /* ':' */ + domain->len; + if (username && username->s && username->len != 0) + total_len += username->len + 1; /* '@' */ + if (port && port->s && port->len != 0) + total_len += port->len + 1; /* ':' */ + if (params && params->s && params->len != 0) + total_len += params->len + 1; /* ';' */ + total_len += 1; /* null terminator */ + + if (total_len > MAX_URI_LEN) { + LM_ERR("constructed URI too long (%d > %d)\n", + total_len, MAX_URI_LEN); + return 0; + } + memcpy(uri_buff,protocol->s,protocol->len); pos += protocol->len; uri_buff[pos++] = ':'; diff --git a/net/net_tcp.c b/net/net_tcp.c index ad2e05ceb79..ae8eed20416 100644 --- a/net/net_tcp.c +++ b/net/net_tcp.c @@ -51,6 +51,7 @@ #include "../reactor.h" #include "../timer.h" #include "../ipc.h" +#include "../cfg_reload.h" #include "tcp_passfd.h" #include "net_tcp_proc.h" @@ -1079,6 +1080,8 @@ static inline void tcpconn_destroy(struct tcp_connection* tcpconn) /* force timeout */ tcpconn->lifetime=0; tcpconn->state=S_CONN_BAD; + sh_log(tcpconn->hist, TCP_DEL_DELAY, "tcpconn_destroy delayed, (%d)", + tcpconn->refcnt); LM_DBG("delaying (%p, flags %04x) ref = %d ...\n", tcpconn, tcpconn->flags, tcpconn->refcnt); @@ -1388,6 +1391,9 @@ inline static int handle_tcp_worker(struct tcp_worker* tcp_c, int fd_i) tcpconn->flags&=~F_CONN_REMOVED_WRITE; break; case CONN_ERROR_TCPW: + LM_INFO("TCP_DBG - main: received conn %p / %u as faulty " + "(state %d, rfcnt=%d)\n", tcpconn, tcpconn->id, + tcpconn->state, tcpconn->refcnt); case CONN_DESTROY: case CONN_EOF: /* WARNING: this will auto-dec. refcnt! */ @@ -1541,8 +1547,11 @@ inline static int handle_worker(struct process_table* p, int fd_i) tcpconn->flags&=~F_CONN_REMOVED_WRITE; break; case ASYNC_WRITE_GENW: + sh_log(tcpconn->hist,TCP_UNREF,"ASYNC_WRITE_GENW, (%d)", + tcpconn->refcnt); if (tcpconn->state==S_CONN_BAD){ tcpconn->lifetime=0; + tcpconn_put(tcpconn); break; } tcpconn_put(tcpconn); @@ -2010,7 +2019,8 @@ static int fork_dynamic_tcp_process(void *foo) tcp_workers[r].pid = getpid(); if (tcp_worker_proc_reactor_init(tcp_workers[r].main_unix_sock)<0|| - init_child(20000) < 0) { + init_child(20000) || + self_update_routing_script() < 0) { goto error; } @@ -2299,6 +2309,7 @@ mi_response_t *mi_tcp_list_conns(const mi_params_t *params, /* add one node for each conn */ add_mi_number( conn_item, MI_SSTR("Alias port"), conn->con_aliases[j].port ); + } } diff --git a/net/net_tcp_proc.c b/net/net_tcp_proc.c index dd65c9ebb32..886602a3399 100644 --- a/net/net_tcp_proc.c +++ b/net/net_tcp_proc.c @@ -90,9 +90,11 @@ static void tcpconn_release(struct tcp_connection* c, long state, int writer, void tcp_conn_release(struct tcp_connection* c, int pending_data) { if (c->state==S_CONN_BAD) { + /* do more or less nothing, let the TCP READER owning the conn + * to trash it based on the S_CONN_BAD marker */ c->lifetime=0; - /* CONN_ERROR will auto-dec refcnt => we must not call tcpconn_put !!*/ - tcpconn_release(c, CONN_ERROR_GENW, 1, 0 /*not TCP, but GEN worker*/); + /* but be sure we unref the conn */ + tcpconn_put(c); return; } if (pending_data) { @@ -134,6 +136,8 @@ static void tcp_receive_timeout(void) if (con->state<0){ /* kill bad connections */ /* S_CONN_BAD or S_CONN_ERROR, remove it */ /* fd will be closed in tcpconn_release */ + LM_INFO("TCP_DBG - conn %p / %u found as bad, relasing back " + "to main\n", con, con->id); reactor_del_reader(con->fd, -1/*idx*/, IO_FD_CLOSING/*io_flags*/ ); tcpconn_check_del(con); @@ -141,8 +145,8 @@ static void tcp_receive_timeout(void) con->proc_id = -1; con->state=S_CONN_BAD; if (con->fd!=-1) { close(con->fd); con->fd = -1; } - sh_log(con->hist, TCP_SEND2MAIN, "state: %d, att: %d", - con->state, con->msg_attempts); + sh_log(con->hist, TCP_SEND2MAIN, "state: %d, att: %d, ref: %d", + con->state, con->msg_attempts, con->refcnt); tcpconn_release_error(con, 0, "Unknown reason"); continue; } diff --git a/net/net_udp.c b/net/net_udp.c index 2e347efeddb..b78a1f66b01 100644 --- a/net/net_udp.c +++ b/net/net_udp.c @@ -412,7 +412,8 @@ static int fork_dynamic_udp_process(void *si_filter) /* we first need to init the reactor to be able to add fd * into it in child_init routines */ if (udp_proc_reactor_init(si) < 0 || - init_child(10000/*FIXME*/) < 0) { + init_child(10000/*FIXME*/) < 0 || + self_update_routing_script() < 0) { goto error; } report_conditional_status( 1, 0); /*report success*/ diff --git a/net/proto_tcp/README.md b/net/proto_tcp/README.md new file mode 100644 index 00000000000..72197fe6a7b --- /dev/null +++ b/net/proto_tcp/README.md @@ -0,0 +1,387 @@ +--- +title: "proto_tcp Module" +description: "This module is a built-in transport module which implements SIP TCP-based communication. It does not handle TCP connections management, but only offers higher-level primitives to read and write SIP messages over TCP." +--- + +## Admin Guide + + +### Overview + + +The **proto_tcp** module is a built-in +transport module which implements SIP TCP-based communication. It does +not handle TCP connections management, but only offers higher-level +primitives to read and write SIP messages over TCP. + + +Once loaded, you will be able to define TCP listeners in your script, +by adding its IP, and optionally the listening port, in your configuration +file, similar to this example: + +```opensips +... +socket=tcp:127.0.0.1 # change the listening IP +socket=tcp:127.0.0.1:5080 # change with the listening IP and port +... +``` + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### tcp_port (integer) + + +The default port to be used for all TCP related operation. Be careful +as the default port impacts both the SIP listening part (if no port is +defined in the TCP listeners) and the SIP sending part (if the +destination URI has no explicit port). + + +If you want to change only the listening port for TCP, use the port +option in the SIP listener defintion. + + +*Default value is 5060.* + + +```c title="Set tcp_port parameter" +... +modparam("proto_tcp", "tcp_port", 5065) +... +``` + + +#### tcp_send_timeout (integer) + + +Time in milliseconds after a TCP connection will be closed if it is +not available for blocking writing in this interval (and OpenSIPS wants +to send something on it). + + +*Default value is 100 ms.* + + +```opensips title="Set tcp_send_timeout parameter" +... +modparam("proto_tcp", "tcp_send_timeout", 200) +... +``` + + +#### tcp_max_msg_chunks (integer) + + +The maximum number of chunks that a SIP message is expected to +arrive via TCP. If a packet is received more fragmented than this, +the connection is dropped (either the connection is very +overloaded and this leads to high fragmentation - or we are the +victim of an ongoing attack where the attacker is sending the +traffic very fragmented in order to decrease our performance). + + +*Default value is 4.* + + +```opensips title="Set tcp_max_msg_chunks parameter" +... +modparam("proto_tcp", "tcp_max_msg_chunks", 8) +... +``` + + +#### tcp_crlf_pingpong (integer) + + +Send CRLF pong (\r\n) to incoming CRLFCRLF ping messages over TCP. +By default it is enabled (1). + + +*Default value is 1 (enabled).* + + +```opensips title="Set tcp_crlf_pingpong parameter" +... +modparam("proto_tcp", "tcp_crlf_pingpong", 0) +... +``` + + +#### tcp_crlf_drop (integer) + + +Drop CRLF (\r\n) ping messages. When this parameter is enabled, +the TCP layer drops packets that contains a single CRLF message. +If a CRLFCRLF message is received, it is handled according to the +*tcp_crlf_pingpong* parameter. + + +*Default value is 0 (disabled).* + + +```opensips title="Set tcp_crlf_drop parameter" +... +modparam("proto_tcp", "tcp_crlf_drop", 1) +... +``` + + +#### tcp_async (integer) + + +If the TCP connect and write operations should be done in an +asynchronous mode (non-blocking connect and +write). If disabled, OpenSIPS will block and wait for TCP +operations like connect and write. + + +*Default value is 1 (enabled).* + + +```opensips title="Set tcp_async parameter" +... +modparam("proto_tcp", "tcp_async", 0) +... +``` + + +#### tcp_async_max_postponed_chunks (integer) + + +If *tcp_async* is enabled, this specifies the +maximum number of SIP messages that can be stashed for later/async +writing. If the connection pending writes exceed this number, the +connection will be marked as broken and dropped. + + +*Default value is 32.* + + +```opensips title="Set tcp_async_max_postponed_chunks parameter" +... +modparam("proto_tcp", "tcp_async_max_postponed_chunks", 16) +... +``` + + +#### tcp_async_local_connect_timeout (integer) + + +If *tcp_async* is enabled, this specifies the + number of milliseconds that a connect will be tried in blocking + mode (optimization). If the connect operation lasts more than + this, the connect will go to async mode and will be passed to TCP + MAIN for polling. + + +*Default value is 100 ms.* + + +```opensips title="Set tcp_async_local_connect_timeout parameter" +... +modparam("proto_tcp", "tcp_async_local_connect_timeout", 200) +... +``` + + +#### tcp_async_local_write_timeout (integer) + + +If *tcp_async* is enabled, this specifies the +number of milliseconds that a write op will be tried in blocking +mode (optimization). If the write operation lasts more than this, +the write will go to async mode and will be passed to TCP MAIN for +polling. + + +*Default value is 10 ms.* + + +```opensips title="Set tcp_async_local_write_timeout parameter" +... +modparam("proto_tcp", "tcp_async_local_write_timeout", 100) +... +``` + + +#### tcp_parallel_handling (integer) + + +This parameter says if the handling/processing (NOT READING) of the + SIP messages should be done in parallel (after one SIP msg is read, + while processing it, another READ op may be performed). + + +*Default value is 0 (disabled).* + + +```opensips title="Set tcp_parallel_handling parameter" +... +modparam("proto_tcp", "tcp_parallel_handling", 1) +... +``` + + +#### trace_destination (string) + + +Trace destination as defined in the tracing module. Currently +the only tracing module is **proto_hep**. +Network events such as connect, accept and connection closed events +shall be traced along with errors that could appear in the process. + + +> [!WARNING] +> A tracing module must be +> loaded in order for this parameter to work. (for example +> **proto_hep**). + + +*Default value is none(not defined).* + + +```opensips title="Set trace_destination parameter" +... +modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") + +modparam("proto_tcp", "trace_destination", "hep_dest") +... +``` + + +#### trace_on (int) + + +This controls whether tracing for tcp is on or not. You still need to define +[trace destination](#param_trace_destination) in order to work, but this value will be controlled using mi function [tcp trace](#mi_tcp_trace). + + +```opensips title="Set trace_on parameter" +... +modparam("proto_tcp", "trace_on", 1) +... +``` + + +#### trace_filter_route (string) + + +Define the name of a route in which you can filter which connections will +be trace and which connections won't be. In this route you will have +information regarding source and destination ips and ports for the current +connection. To disable tracing for a specific connection the last call in +this route must be **drop**, any other exit +mode resulting in tracing the current connection ( of course you still +have to define a [trace destination](#param_trace_destination) and trace must be +on at the time this connection is opened. + + +> [!IMPORTANT] +> Filtering on ip addresses and ports can be made using **$si** and **$sp** for matching +> either the entity that is connecting to OpenSIPS or the entity to which +> OpenSIPS is connecting. The name might be misleading (**$si** meaning the source ip if you read the docs) but in reality +> it is simply the socket other than the OpenSIPS socket. In order to match +> OpenSIPS interface (either the one that accepted the connection or the one +> that initiated a connection) **$socket_in(ip)** (ip) and +> **$socket_in(port)** (port) can be used. + + +> [!WARNING] +> If [trace on](#param_trace_on) is +> set to 0 or tracing is deactived via the mi command [tcp trace](#mi_tcp_trace) +> this route won't be called. + + +```opensips title="Set trace_filter_route parameter" +... +modparam("proto_tcp", "trace_filter_route", "tcp_filter") +... +/* all tcp connections will go through this route if tracing is activated + * and a trace destination is defined */ +route[tcp_filter] { + ... + /* all connections opened from/by ip 1.1.1.1:8000 will be traced + on interface 1.1.1.10:5060(opensips listener) + all the other connections won't be */ + if ( $si == "1.1.1.1" && $sp == 8000 && + $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) + exit; + else + drop; +} +... +``` + + +### Exported MI Functions + + +#### tcp_trace + + +Name: *tcp_trace* + + +Parameters: + + +- trace_mode(optional): set tcp tracing on and off. This parameter +can be missing and the command will show the current tracing +status for this module( on or off ). Possible values: + * on + * off + + +MI FIFO Command Format: + + +```bash + :tcp_trace:_reply_fifo_file_ + trace_mode + _empty_line_ + +``` + + +## Frequently Asked Questions + + +**Q: After switching to OpenSIPS 2.1, I'm getting this error: "listeners found for protocol tcp, but no module can handle it"** + + +You need to load the "proto_tcp" module. In your script, make sure you do a **loadmodule "proto_tcp.so"** after setting the **[mpath](https://docs.opensips.org/manual/3-6/script-coreparameters#mpath)**. + + +**Q: I cannot locate "proto_tcp.so". Where is it?** + + +The "proto_udp" and "proto_tcp" modules are simply built into the opensips binary by default. They are not available as shared libraries, but look like modules for code consistency reasons. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/net/proto_tcp/doc/proto_tcp.xml b/net/proto_tcp/doc/proto_tcp.xml deleted file mode 100644 index eafa51840db..00000000000 --- a/net/proto_tcp/doc/proto_tcp.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_tcp Module - &osipsname; - - - &osips; - Project -
- support@opensips.org -
-
- - Razvan - Crainea -
- razvan@opensips.org -
-
-
- - 2015 - &osips; Project - -
- - - &admin; - &faq; - -
diff --git a/net/proto_tcp/doc/proto_tcp_admin.xml b/net/proto_tcp/doc/proto_tcp_admin.xml deleted file mode 100644 index 7d120fbdca8..00000000000 --- a/net/proto_tcp/doc/proto_tcp_admin.xml +++ /dev/null @@ -1,439 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_tcp module is a built-in - transport module which implements SIP TCP-based communication. It does - not handle TCP connections management, but only offers higher-level - primitives to read and write SIP messages over TCP. - -
- - Once loaded, you will be able to define TCP listeners in your script, - by adding its IP, and optionally the listening port, in your configuration - file, similar to this example: - - -... -socket=tcp:127.0.0.1 # change the listening IP -socket=tcp:127.0.0.1:5080 # change with the listening IP and port -... - - - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>tcp_port</varname> (integer) - - The default port to be used for all TCP related operation. Be careful - as the default port impacts both the SIP listening part (if no port is - defined in the TCP listeners) and the SIP sending part (if the - destination URI has no explicit port). - - - If you want to change only the listening port for TCP, use the port - option in the SIP listener defintion. - - - - Default value is 5060. - - - - Set <varname>tcp_port</varname> parameter - -... -modparam("proto_tcp", "tcp_port", 5065) -... - - -
- -
- <varname>tcp_send_timeout</varname> (integer) - - Time in milliseconds after a TCP connection will be closed if it is - not available for blocking writing in this interval (and &osips; wants - to send something on it). - - - - Default value is 100 ms. - - - - Set <varname>tcp_send_timeout</varname> parameter - -... -modparam("proto_tcp", "tcp_send_timeout", 200) -... - - -
-
- <varname>tcp_max_msg_chunks</varname> (integer) - - The maximum number of chunks that a SIP message is expected to - arrive via TCP. If a packet is received more fragmented than this, - the connection is dropped (either the connection is very - overloaded and this leads to high fragmentation - or we are the - victim of an ongoing attack where the attacker is sending the - traffic very fragmented in order to decrease our performance). - - - - Default value is 4. - - - - Set <varname>tcp_max_msg_chunks</varname> parameter - -... -modparam("proto_tcp", "tcp_max_msg_chunks", 8) -... - - -
-
- <varname>tcp_crlf_pingpong</varname> (integer) - - Send CRLF pong (\r\n) to incoming CRLFCRLF ping messages over TCP. - By default it is enabled (1). - - - - Default value is 1 (enabled). - - - - Set <varname>tcp_crlf_pingpong</varname> parameter - -... -modparam("proto_tcp", "tcp_crlf_pingpong", 0) -... - - -
-
- <varname>tcp_crlf_drop</varname> (integer) - - Drop CRLF (\r\n) ping messages. When this parameter is enabled, - the TCP layer drops packets that contains a single CRLF message. - If a CRLFCRLF message is received, it is handled according to the - tcp_crlf_pingpong parameter. - - - - Default value is 0 (disabled). - - - - Set <varname>tcp_crlf_drop</varname> parameter - -... -modparam("proto_tcp", "tcp_crlf_drop", 1) -... - - -
-
- <varname>tcp_async</varname> (integer) - - If the TCP connect and write operations should be done in an - asynchronous mode (non-blocking connect and - write). If disabled, OpenSIPS will block and wait for TCP - operations like connect and write. - - - - Default value is 1 (enabled). - - - - Set <varname>tcp_async</varname> parameter - -... -modparam("proto_tcp", "tcp_async", 0) -... - - -
-
- <varname>tcp_async_max_postponed_chunks</varname> (integer) - - If tcp_async is enabled, this specifies the - maximum number of SIP messages that can be stashed for later/async - writing. If the connection pending writes exceed this number, the - connection will be marked as broken and dropped. - - - - Default value is 32. - - - - Set <varname>tcp_async_max_postponed_chunks</varname> parameter - -... -modparam("proto_tcp", "tcp_async_max_postponed_chunks", 16) -... - - -
-
- <varname>tcp_async_local_connect_timeout</varname> (integer) - - If tcp_async is enabled, this specifies the - number of milliseconds that a connect will be tried in blocking - mode (optimization). If the connect operation lasts more than - this, the connect will go to async mode and will be passed to TCP - MAIN for polling. - - - - Default value is 100 ms. - - - - Set <varname>tcp_async_local_connect_timeout</varname> parameter - -... -modparam("proto_tcp", "tcp_async_local_connect_timeout", 200) -... - - -
-
- <varname>tcp_async_local_write_timeout</varname> (integer) - - If tcp_async is enabled, this specifies the - number of milliseconds that a write op will be tried in blocking - mode (optimization). If the write operation lasts more than this, - the write will go to async mode and will be passed to TCP MAIN for - polling. - - - - Default value is 10 ms. - - - - Set <varname>tcp_async_local_write_timeout</varname> parameter - -... -modparam("proto_tcp", "tcp_async_local_write_timeout", 100) -... - - -
-
- <varname>tcp_parallel_handling</varname> (integer) - - This parameter says if the handling/processing (NOT READING) of the - SIP messages should be done in parallel (after one SIP msg is read, - while processing it, another READ op may be performed). - - - - Default value is 0 (disabled). - - - - Set <varname>tcp_parallel_handling</varname> parameter - -... -modparam("proto_tcp", "tcp_parallel_handling", 1) -... - - -
- -
- <varname>trace_destination</varname> (string) - - Trace destination as defined in the tracing module. Currently - the only tracing module is proto_hep. - Network events such as connect, accept and connection closed events - shall be traced along with errors that could appear in the process. - - - WARNING: A tracing module must be - loaded in order for this parameter to work. (for example - proto_hep). - - - - Default value is none(not defined). - - - - Set <varname>trace_destination</varname> parameter - -... -modparam("proto_hep", "hep_id", "[hep_dest]10.0.0.2;transport=tcp;version=3") - -modparam("proto_tcp", "trace_destination", "hep_dest") -... - - -
- -
- <varname>trace_on</varname> (int) - - This controls whether tracing for tcp is on or not. You still need to define - in order to work, but this value will be - controlled using mi function . - - - Default value is 0(tracing inactive). - - - Set <varname>trace_on</varname> parameter - -... -modparam("proto_tcp", "trace_on", 1) -... - - -
- -
- <varname>trace_filter_route</varname> (string) - - Define the name of a route in which you can filter which connections will - be trace and which connections won't be. In this route you will have - information regarding source and destination ips and ports for the current - connection. To disable tracing for a specific connection the last call in - this route must be drop, any other exit - mode resulting in tracing the current connection ( of course you still - have to define a and trace must be - on at the time this connection is opened. - - - IMPORTANT - Filtering on ip addresses and ports can be made using - $si and $sp for matching - either the entity that is connecting to &osips; or the entity to which - &osips; is connecting. The name might be misleading ( - $si meaning the source ip if you read the docs) but in reality - it is simply the socket other than the &osips; socket. In order to match - &osips; interface (either the one that accepted the connection or the one - that initiated a connection) $socket_in(ip) (ip) and - $socket_in(port) (port) can be used. - - - WARNING: IF is - set to 0 or tracing is deactived via the mi command - this route won't be called. - - - Default value is none(no route is set). - - - Set <varname>trace_filter_route</varname> parameter - -... -modparam("proto_tcp", "trace_filter_route", "tcp_filter") -... -/* all tcp connections will go through this route if tracing is activated - * and a trace destination is defined */ -route[tcp_filter] { - ... - /* all connections opened from/by ip 1.1.1.1:8000 will be traced - on interface 1.1.1.10:5060(opensips listener) - all the other connections won't be */ - if ( $si == "1.1.1.1" && $sp == 8000 && - $socket_in(ip) == "1.1.1.10" && $socket_in(port) == 5060) - exit; - else - drop; -} -... - - -
- -
- - -
- Exported MI Functions - -
- - <function moreinfo="none">tcp_trace</function> - - - - - - - Name: tcp_trace - - - Parameters: - - - trace_mode(optional): set tcp tracing on and off. This parameter - can be missing and the command will show the current tracing - status for this module( on or off ); - Possible values: - - on - off - - - - - - - MI FIFO Command Format: - - - :tcp_trace:_reply_fifo_file_ - trace_mode - _empty_line_ - -
-
-
diff --git a/net/proto_tcp/doc/proto_tcp_faq.xml b/net/proto_tcp/doc/proto_tcp_faq.xml deleted file mode 100644 index 80cb51c4b8e..00000000000 --- a/net/proto_tcp/doc/proto_tcp_faq.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - &faqguide; - - - - - After switching to OpenSIPS 2.1, I'm getting this error: - "listeners found for protocol tcp, but no module can handle it" - - - - - You need to load the "proto_tcp" module. In your script, make sure - you do a loadmodule "proto_tcp.so" after setting the mpath. - - - - - - - I cannot locate "proto_tcp.so". Where is it? - - - - - The "proto_udp" and "proto_tcp" modules are simply built into - the opensips binary by default. They are not available as shared - libraries, but look like modules for code consistency reasons. - - - - - - diff --git a/net/proto_tcp/proto_tcp.c b/net/proto_tcp/proto_tcp.c index c078678e119..7b1907dce77 100644 --- a/net/proto_tcp/proto_tcp.c +++ b/net/proto_tcp/proto_tcp.c @@ -451,7 +451,7 @@ static int proto_tcp_send(const struct socket_info* send_sock, * flow now (the actual write will be done when * connect will be completed */ LM_DBG("Successfully started async connection \n"); - sh_log(c->hist, TCP_SEND2MAIN, "send 1, (%d)", c->refcnt); + sh_log(c->hist, TCP_RELEASED, "send 1, (%d)", c->refcnt); tcp_conn_release(c, 0); return len; } @@ -527,7 +527,7 @@ static int proto_tcp_send(const struct socket_info* send_sock, LM_ERR("Failed to add another write chunk to %p\n",c); /* we failed due to internal errors - put the * connection back */ - sh_log(c->hist, TCP_SEND2MAIN, "send 2, (%d)", c->refcnt); + sh_log(c->hist, TCP_RELEASED, "send 2, (%d)", c->refcnt); tcp_conn_release(c, 0); return -1; } @@ -538,12 +538,14 @@ static int proto_tcp_send(const struct socket_info* send_sock, send_sock->last_real_ports->remote = c->rcv.src_port; /* we successfully added our write chunk - success */ - sh_log(c->hist, TCP_SEND2MAIN, "send 3, (%d)", c->refcnt); + sh_log(c->hist, TCP_RELEASED, "send 3, (%d)", c->refcnt); tcp_conn_release(c, 0); return len; } else { - /* return error, nothing to do about it */ - sh_log(c->hist, TCP_SEND2MAIN, "send 4, (%d)", c->refcnt); + /* the FD transfer failed (we have an established conn, + * but returned fd is -1) -> leave the conn alone, return error + * for the write op, nothing to do about it */ + sh_log(c->hist, TCP_RELEASED, "send 4, (%d)", c->refcnt); tcp_conn_release(c, 0); return -1; } @@ -566,12 +568,12 @@ static int proto_tcp_send(const struct socket_info* send_sock, LM_DBG("after write: c= %p n/len=%d/%d fd=%d\n",c, n, len, fd); /* LM_DBG("buf=\n%.*s\n", (int)len, buf); */ if (n<0){ - LM_ERR("failed to send\n"); + LM_ERR("failed to send on conn %p / %u\n", c, c->id); c->state=S_CONN_BAD; if (c->proc_id != process_no) close(fd); - sh_log(c->hist, TCP_SEND2MAIN, "send 5, (%d)", c->refcnt); + sh_log(c->hist, TCP_RELEASED, "send 5, (%d)", c->refcnt); tcp_conn_release(c, 0); return -1; } @@ -586,7 +588,8 @@ static int proto_tcp_send(const struct socket_info* send_sock, send_sock->last_real_ports->local = c->rcv.dst_port; send_sock->last_real_ports->remote = c->rcv.src_port; - sh_log(c->hist, TCP_SEND2MAIN, "send 6, (%d, async: %d)", c->refcnt, n < len); + if (n==len) + sh_log(c->hist, TCP_RELEASED, "send 6, (%d, async: %d)", c->refcnt, n < len); tcp_conn_release(c, (ncontent_len>=TCP_BUF_SIZE) { + LM_ERR("Content-Length value %d bigger than the " + "reading buffer\n", r->content_len); + r->error = TCP_REQ_BAD_LEN; + r->state = H_SKIP; + r->content_len = 0; + break; + } r->content_len=r->content_len*10+(*p-'0'); + if (r->content_len>=TCP_BUF_SIZE) { + LM_ERR("Content-Length value %d bigger than the " + "reading buffer\n", r->content_len); + r->error = TCP_REQ_BAD_LEN; + r->state = H_SKIP; + r->content_len = 0; + } break; case '\r': case ' ': diff --git a/net/proto_udp/README.md b/net/proto_udp/README.md new file mode 100644 index 00000000000..f0e50cd282c --- /dev/null +++ b/net/proto_udp/README.md @@ -0,0 +1,87 @@ +--- +title: "proto_udp Module" +description: "This module is a built-in transport module which exports the required logic in order to handle UDP-based communication (socket initialization and send/recv primitives to be used by higher-level network layers)." +--- + +## Admin Guide + + +### Overview + + +The **proto_udp** module is a built-in transport module which exports the required +logic in order to handle UDP-based communication. (socket initialization +and send/recv primitives to be used by higher-level network layers) + + +Once loaded, you will be able to define *"udp:"* listeners in your script. + + +### Dependencies + + +#### OpenSIPS Modules + + +The following modules must be loaded before this module: + + +- *None*. + + +#### External Libraries or Applications + + +The following libraries or applications must be installed before +running OpenSIPS with this module loaded: + + +- *None*. + + +### Exported Parameters + + +#### udp_port (integer) + + +The default port to be used for all UDP related operation. Be careful +as the default port impacts both the SIP listening part (if no port is +defined in the UDP listeners) and the SIP sending part (if the +destination URI has no explicit port). + + +If you want to change only the listening port for UDP, use the port +option in the SIP listener defintion. + + +*Default value is 5060.* + + +```opensips title="Set udp_port parameter" +... +modparam("proto_udp", "udp_port", 5070) +... +``` + + +## Frequently Asked Questions + + +**Q: After switching to OpenSIPS 2.1, I'm getting this error: "listeners found for protocol udp, but no module can handle it"** + + +You need to load the "proto_udp" module. In your script, make sure you do a **loadmodule "proto_udp.so"** after setting the **[mpath](https://docs.opensips.org/manual/3-6/script-coreparameters#mpath)**. + + +**Q: I cannot locate "proto_udp.so". Where is it?** + + +The "proto_udp" and "proto_tcp" modules are simply built into +the opensips binary by default. They are not available as shared +libraries, but look like modules for code consistency reasons. + + +### License + +All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0 diff --git a/net/proto_udp/doc/proto_udp.xml b/net/proto_udp/doc/proto_udp.xml deleted file mode 100644 index e92359ac941..00000000000 --- a/net/proto_udp/doc/proto_udp.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -%docentities; - -]> - - - - proto_udp Module - &osipsname; - - - &osips; - Project -
- support@opensips.org -
-
- - Liviu - Chircu -
- liviu@opensips.org -
-
-
- - 2015 - &osips; Project - -
- - - &admin; - &faq; - -
diff --git a/net/proto_udp/doc/proto_udp_admin.xml b/net/proto_udp/doc/proto_udp_admin.xml deleted file mode 100644 index aa651dff40a..00000000000 --- a/net/proto_udp/doc/proto_udp_admin.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - &adminguide; - -
- Overview - - The proto_udp module is a built-in transport module which exports the required - logic in order to handle UDP-based communication. (socket initialization - and send/recv primitives to be used by higher-level network layers) - -
- - Once loaded, you will be able to define "udp:" listeners in your script. - - -
- Dependencies -
- &osips; Modules - - The following modules must be loaded before this module: - - - - None. - - - - -
- -
- External Libraries or Applications - - The following libraries or applications must be installed before - running &osips; with this module loaded: - - - - None. - - - - -
-
- -
- Exported Parameters -
- <varname>udp_port</varname> (integer) - - The default port to be used for all UDP related operation. Be careful - as the default port impacts both the SIP listening part (if no port is - defined in the UDP listeners) and the SIP sending part (if the - destination URI has no explicit port). - - - If you want to change only the listening port for UDP, use the port - option in the SIP listener defintion. - - - - Default value is 5060. - - - - Set <varname>udp_port</varname> parameter - -... -modparam("proto_udp", "udp_port", 5070) -... - - -
-
- -
diff --git a/net/proto_udp/doc/proto_udp_faq.xml b/net/proto_udp/doc/proto_udp_faq.xml deleted file mode 100644 index 94b3b28e2a5..00000000000 --- a/net/proto_udp/doc/proto_udp_faq.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - &faqguide; - - - - - After switching to OpenSIPS 2.1, I'm getting this error: - "listeners found for protocol udp, but no module can handle it" - - - - - You need to load the "proto_udp" module. In your script, make sure - you do a loadmodule "proto_udp.so" after setting the mpath. - - - - - - - I cannot locate "proto_udp.so". Where is it? - - - - - The "proto_udp" and "proto_tcp" modules are simply built into - the opensips binary by default. They are not available as shared - libraries, but look like modules for code consistency reasons. - - - - - - diff --git a/net/tcp_common.c b/net/tcp_common.c index 863b10a996c..86c2a66e11d 100644 --- a/net/tcp_common.c +++ b/net/tcp_common.c @@ -531,8 +531,8 @@ int tcp_async_add_chunk(struct tcp_connection *con, char *buf, lock_get(&con->write_lock); if (con->async->allocated == con->async->pending) { - LM_ERR("We have reached the limit of max async postponed chunks %d\n", - con->async->pending); + LM_ERR("We have reached the limit of max async postponed chunks %d " + "on conn %p / %u\n", con->async->pending, con, con->id); if (lock) lock_release(&con->write_lock); shm_free(c); diff --git a/packaging/arch/Makefile.conf.template b/packaging/arch/Makefile.conf.template index 27a7ba8adbd..f0dc257b352 100644 --- a/packaging/arch/Makefile.conf.template +++ b/packaging/arch/Makefile.conf.template @@ -17,11 +17,11 @@ #db_postgres= Provides Postgres connectivity for OpenSIPS | PostgreSQL library and development library - tipically libpq5 and libpq-dev #db_sqlite= Provides SQLite connectivity for OpenSIPS | SQLite library and development library - tipically libsqlite3 and libsqlite3-dev #db_unixodbc= Allows to use the unixodbc package with OpenSIPS | ODBC library and ODBC development library -#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, tipically libpcre-dev +#dialplan= Implements generic string translations based on matching and replacement rules | PCRE development library, tipically libpcre2-dev #emergency= Provides emergency call treatment for OpenSIPS | CURL dev library - tipically libcurl4-openssl-dev #event_rabbitmq= Provides the implementation of a RabbitMQ client for the Event Interface | RabbitMQ development library, librabbitmq-dev #h350= Enables access to SIP account data stored in an LDAP [RFC4510] directory containing H.350 commObjects | OpenLDAP library & development files, tipically libldap and libldap-dev -#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, tipically libpcre-dev +#regex= Offers matching operations against regular expressions using the powerful PCRE library. | Development library for PCRE, tipically libpcre2-dev #identity= Adds support for SIP Identity (see RFC 4474). | SSL library, tipically libssl #jabber= Integrates XODE XML parser for parsing Jabber messages | Expat library. #json= Introduces a new type of variable that provides both serialization and de-serialization from JSON format. | JSON library, libjson diff --git a/packaging/arch/PKGBUILD.git b/packaging/arch/PKGBUILD.git index ad3387460c0..5ae277c47a5 100644 --- a/packaging/arch/PKGBUILD.git +++ b/packaging/arch/PKGBUILD.git @@ -93,12 +93,9 @@ build() { # create documentation targets make \ BASEDIR="$pkgdir" PREFIX=/usr LIBDIR=lib \ - doxygen \ - modules-docbook-html \ - modules-readme + doxygen # dbschema-docbook-html # dbschema-docbook-pdf \ - # modules-docbook-pdf \ } package_opensips-git() { @@ -128,7 +125,7 @@ package_opensips-git() { 'mongo-c-driver: C-Interface for Mongo-DB support' 'net-snmp: SNMP support' 'osptoolkit: OSP Toolkit support' - 'pcre: Perl Regular-Expression support' + 'pcre2: Perl Regular-Expression support' 'perl: Perl support' 'postgresql-libs: PostgreSQL-DB support' 'python2: Python v2 support' @@ -202,7 +199,7 @@ package_opensips-git-documentation() { msg2 "install documentation targets" make \ - BASEDIR="$pkgdir" PREFIX=/usr LIBDIR=lib install-doc install-modules-docbook + BASEDIR="$pkgdir" PREFIX=/usr LIBDIR=lib install-doc DOC_DIR="$pkgdir/usr/share/doc/${_pkgname}" diff --git a/packaging/debian/changelog b/packaging/debian/changelog index bc6276debb2..777a6345483 100644 --- a/packaging/debian/changelog +++ b/packaging/debian/changelog @@ -1,3 +1,31 @@ +opensips (3.6.7-1) stable; urgency=low + + * Minor Public Release. + + -- Liviu Chircu Wed, 17 Jun 2026 16:12:27 +0300 + + +opensips (3.6.6-1) stable; urgency=low + + * Minor Public Release. + + -- Liviu Chircu Wed, 20 May 2026 15:09:40 +0300 + + +opensips (3.6.5-1) stable; urgency=low + + * Minor Public Release. + + -- Liviu Chircu Wed, 06 May 2026 18:00:24 +0300 + + +opensips (3.6.4-1) stable; urgency=low + + * Minor Public Release. + + -- Liviu Chircu Wed, 18 Feb 2026 16:29:28 +0200 + + opensips (3.6.3-1) stable; urgency=low * Minor Public Release. diff --git a/packaging/debian/control b/packaging/debian/control index 56a7b558767..966fd93710d 100644 --- a/packaging/debian/control +++ b/packaging/debian/control @@ -9,7 +9,7 @@ Build-Depends: bison, dpkg-dev (>= 1.16.1.1), flex, libconfuse-dev, - libcurl4-gnutls-dev, + libcurl4-openssl-dev, libdb-dev (>= 4.6.19), libfdcore6 (>= 1.2.1) | base-files, libfdproto6 (>= 1.2.1) | base-files, @@ -29,7 +29,9 @@ Build-Depends: bison, libbson-dev | base-files, libmongoc-dev | base-files, libncurses5-dev, - libpcre3-dev, + opentelemetry-cpp-dev , + libpcre2-dev , + libpcre3-dev , libperl-dev, libpq-dev, librabbitmq-dev, @@ -119,7 +121,7 @@ Description: very fast and configurable SIP server XMLRPC Interface. . This package contains the main OpenSIPS binary along with the principal modules - and support binaries including opensipsmc configuration tool. + and support binaries. Package: opensips-auth-jwt-module Architecture: any diff --git a/packaging/debian/copyright b/packaging/debian/copyright index 13b1063d2df..5e5ea131e46 100644 --- a/packaging/debian/copyright +++ b/packaging/debian/copyright @@ -105,8 +105,8 @@ Copyright: 2002 Andrei Pelinescu-Onciul 2015-2017 Răzvan Crainea License: GPL-2+ -Files: doc/dbschema/xsl/pi_framework_mod.xsl - doc/dbschema/xsl/pi_framework_table.xsl +Files: docs/dbschema/xsl/pi_framework_mod.xsl + docs/dbschema/xsl/pi_framework_table.xsl Copyright: 2010-2014, VoIP Embedded, Inc License: GPL-2+ diff --git a/packaging/debian/opensips.examples b/packaging/debian/opensips.examples index e39721e20f0..c87f918b503 100644 --- a/packaging/debian/opensips.examples +++ b/packaging/debian/opensips.examples @@ -1 +1,4 @@ -examples/* +examples/*.cfg +examples/*.sh +examples/*.xml +examples/web_im diff --git a/packaging/debian/rules b/packaging/debian/rules index 9a12eb77cb2..c4406936b00 100755 --- a/packaging/debian/rules +++ b/packaging/debian/rules @@ -335,6 +335,17 @@ endif # Enable verbose compile logs VARS += NICER=0 +VARS += PYTHON=python + +# +# check pcre2 vs pcre3 profile +# +ifneq (,$(filter nopcre2,$(DEB_BUILD_PROFILES))) + VARS += PCRE_LIB=pcre +endif + +export WOLFSSL_EXTRA_CFLAGS=-Wno-stringop-overflow + # support parallel compiling NJOBS = diff --git a/packaging/freebsd/Makefile b/packaging/freebsd/Makefile index 4528c3b5915..39bce651842 100644 --- a/packaging/freebsd/Makefile +++ b/packaging/freebsd/Makefile @@ -6,7 +6,7 @@ # PORTNAME= opensips -PORTVERSION= 3.6.3 +PORTVERSION= 3.6.7 CATEGORIES= net MASTER_SITES= https://opensips.org/pub/opensips/${PORTVERSION}/ DISTNAME= ${PORTNAME}-${PORTVERSION}-tls_src @@ -135,26 +135,24 @@ post-patch: .endif @${REINPLACE_CMD} -e 's|-g -O9 ||' -e 's|-O9 ||' ${WRKSRC}/Makefile.defs @${REINPLACE_CMD} -e 's|/etc/opensips|${PREFIX}/etc/opensips|' \ - ${WRKSRC}/modules/mediaproxy/README \ - ${WRKSRC}/modules/cpl_c/README \ + ${WRKSRC}/modules/mediaproxy/README.md \ + ${WRKSRC}/modules/cpl_c/README.md \ ${WRKSRC}/INSTALL @${REINPLACE_CMD} -e 's|/usr/local/sbin/opensips|${PREFIX}/sbin/opensips|' \ ${WRKSRC}/INSTALL @${REINPLACE_CMD} -e 's|/usr/local|${PREFIX}|' \ ${WRKSRC}/etc/opensips.cfg \ - ${WRKSRC}/modules/acc/README \ - ${WRKSRC}/modules/avp_radius/README \ - ${WRKSRC}/modules/db_berkeley/README \ - ${WRKSRC}/modules/ldap/README \ - ${WRKSRC}/modules/osp/README \ - ${WRKSRC}/modules/perl/README \ - ${WRKSRC}/modules/snmpstats/README \ - ${WRKSRC}/modules/speeddial/README \ - ${WRKSRC}/modules/unixodbc/README + ${WRKSRC}/modules/acc/README.md \ + ${WRKSRC}/modules/db_berkeley/README.md \ + ${WRKSRC}/modules/ldap/README.md \ + ${WRKSRC}/modules/osp/README.md \ + ${WRKSRC}/modules/perl/README.md \ + ${WRKSRC}/modules/snmpstats/README.md \ + ${WRKSRC}/modules/speeddial/README.md @${REINPLACE_CMD} -e 's|/usr/local|${LOCALBASE}|' \ ${WRKSRC}/modules/acc/etc/radiusclient.conf @${REINPLACE_CMD} -e 's|/usr/local/etc/radiusclient|${PREFIX}/etc/opensips/acc|' \ - ${WRKSRC}/modules/acc/acc_mod.c ${WRKSRC}/modules/acc/README + ${WRKSRC}/modules/acc/acc_mod.c ${WRKSRC}/modules/acc/README.md post-install: ${INSTALL_DATA} ${WRKSRC}/etc/opensips.cfg \ diff --git a/packaging/freebsd/files/patch-Makefile b/packaging/freebsd/files/patch-Makefile index 49fc79801bf..aeaded0bf8d 100644 --- a/packaging/freebsd/files/patch-Makefile +++ b/packaging/freebsd/files/patch-Makefile @@ -66,12 +66,14 @@ mkdir -p $(modules-prefix)/$(lib-dir)/opensipsctl ; \ sed -e "s#/usr/local/share/opensips#$(data-target)#g" \ @@ -624,9 +611,7 @@ - if [ -f modules/"$$r"/README ]; then \ +- if [ -f modules/"$$r"/README ]; then \ ++ if [ -f modules/"$$r"/README.md ]; then \ $(INSTALL_TOUCH) $(doc-prefix)/$(doc-dir)/README ; \ - $(INSTALL_DOC) modules/"$$r"/README \ +- $(INSTALL_DOC) modules/"$$r"/README \ - $(doc-prefix)/$(doc-dir)/README ; \ - mv -f $(doc-prefix)/$(doc-dir)/README \ - $(doc-prefix)/$(doc-dir)/README."$$r" ; \ ++ $(INSTALL_DOC) modules/"$$r"/README.md \ + $(doc-prefix)/$(doc-dir)/README."$$r" ; \ fi ; \ fi ; \ diff --git a/packaging/netbsd/Makefile b/packaging/netbsd/Makefile index 60ac35fc687..1ff253d6734 100644 --- a/packaging/netbsd/Makefile +++ b/packaging/netbsd/Makefile @@ -6,9 +6,9 @@ COMMENT= "OpenSIPS" PORTNAME= opensips -PORTVERSION= 3.6.3 +PORTVERSION= 3.6.7 CATEGORIES= net -MASTER_SITES= https://opensips.org/pub/opensips/3.6.3/ +MASTER_SITES= https://opensips.org/pub/opensips/3.6.7/ MAINTAINER= bogdan@opensips.org diff --git a/packaging/openbsd/Makefile b/packaging/openbsd/Makefile index dd86b0fde34..1cf0a9a87e1 100644 --- a/packaging/openbsd/Makefile +++ b/packaging/openbsd/Makefile @@ -6,9 +6,9 @@ COMMENT= "OpenSIPS" PORTNAME= opensips -PORTVERSION= 3.6.3 +PORTVERSION= 3.6.7 CATEGORIES= net -MASTER_SITES= https://opensips.org/pub/opensips/3.6.3/ +MASTER_SITES= https://opensips.org/pub/opensips/3.6.7/ MAINTAINER= bogdan@opensips.org diff --git a/packaging/redhat_fedora/opensips.spec b/packaging/redhat_fedora/opensips.spec index c47be5d5a2a..04e9f234e6d 100644 --- a/packaging/redhat_fedora/opensips.spec +++ b/packaging/redhat_fedora/opensips.spec @@ -41,7 +41,7 @@ Summary: Very fast and configurable SIP server Name: opensips -Version: 3.6.3 +Version: 3.6.7 Release: 1%{?dist} License: GPLv2+ Group: System Environment/Daemons @@ -54,7 +54,11 @@ BuildRequires: bison BuildRequires: flex BuildRequires: subversion BuildRequires: which +%if 0%{?rhel} >= 10 +BuildRequires: mariadb-devel +%else BuildRequires: mysql-devel +%endif BuildRequires: postgresql-devel BuildRequires: autoconf BuildRequires: automake @@ -126,7 +130,7 @@ Module, Registrar and User Location, Load Balaning/Dispatching/LCR, XMLRPC Interface. . This package contains the main OpenSIPS binary along with the principal modules -and support binaries including opensipsmc configuration tool. +and support binaries. %if 0%{?_with_auth_jwt:1} %package auth-jwt-module @@ -528,7 +532,11 @@ This package provides the MSRP protocol support for OpenSIPS. Summary: MySQL database connectivity module for OpenSIPS Group: System Environment/Daemons Requires: %{name} = %{version}-%{release} +%if 0%{?rhel} >= 10 +Requires: mariadb-libs +%else Requires: mysql-libs +%endif %description mysql-module OpenSIPS is a very fast and flexible SIP (RFC3261) @@ -973,14 +981,16 @@ This package provides the SIP to XMPP IM translator module for OpenSIPS. %setup -q -n %{name}-%{version} %build -LOCALBASE=/usr NICER=0 CFLAGS="%{optflags}" LDFLAGS="%{?__global_ldflags}" %{?_with_python3:PYTHON=python3} %{?_with_db_oracle:ORAHOME="$ORACLE_HOME"} %{__make} all modules-readme %{?_smp_mflags} TLS=1 \ +LOCALBASE=/usr NICER=0 CFLAGS="%{optflags}" LDFLAGS="%{?__global_ldflags}" \ + %{?_with_python3:PYTHON=python3} %{?_with_db_oracle:ORAHOME="$ORACLE_HOME"} \ + %{__make} all %{?_smp_mflags} PCRE_LIB=pcre \ exclude_modules="%EXCLUDE_MODULES" \ cfg_target=%{_sysconfdir}/opensips/ \ modules_prefix=%{buildroot}%{_prefix} \ modules_dir=%{_lib}/%{name}/modules %install -%{__make} install TLS=1 LIBDIR=%{_lib} \ +%{__make} install PCRE_LIB=pcre LIBDIR=%{_lib} \ exclude_modules="%EXCLUDE_MODULES" \ basedir=%{buildroot} prefix=%{_prefix} \ cfg_prefix=%{buildroot} \ @@ -1092,9 +1102,13 @@ fi %dir %{_datadir}/opensips/ %dir %{_datadir}/opensips/dbtext/ %dir %{_datadir}/opensips/dbtext/opensips/ +%dir %{_datadir}/opensips/examples/ +%dir %{_datadir}/opensips/examples/templates/ %dir %{_datadir}/opensips/menuconfig_templates/ %{_datadir}/opensips/dbtext/opensips/* +%{_datadir}/opensips/examples/templates/*.m4 +%{_datadir}/opensips/examples/templates/README.md %{_datadir}/opensips/menuconfig_templates/*.m4 %{_mandir}/man5/opensips.cfg.5* @@ -1668,6 +1682,18 @@ fi %changelog +* Wed Jun 17 2026 Liviu Chircu - 3.6.7-1 +- OpenSIPS minor stable release: 3.6.7-1 + +* Wed May 20 2026 Liviu Chircu - 3.6.6-1 +- OpenSIPS minor stable release: 3.6.6-1 + +* Wed May 06 2026 Liviu Chircu - 3.6.5-1 +- OpenSIPS minor stable release: 3.6.5-1 + +* Wed Feb 18 2026 Liviu Chircu - 3.6.4-1 +- OpenSIPS minor stable release: 3.6.4-1 + * Thu Dec 18 2025 Liviu Chircu - 3.6.3-1 - OpenSIPS minor stable release: 3.6.3-1 @@ -2085,4 +2111,3 @@ fi * Tue Jul 24 2007 Peter Lemenkov 1.2.1-1 - Initial spec. - diff --git a/packaging/solaris/base-pkginfo b/packaging/solaris/base-pkginfo index caf9f6c7f80..a77f4a5a0c6 100644 --- a/packaging/solaris/base-pkginfo +++ b/packaging/solaris/base-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-base-dbg" NAME="Programmable SIP Server Base Install - Debugging Symbols" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="bogdan@opensips.org" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/berkeley-pkginfo b/packaging/solaris/berkeley-pkginfo index 014db2be985..7d5620667b3 100644 --- a/packaging/solaris/berkeley-pkginfo +++ b/packaging/solaris/berkeley-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-berkeley-dbg" NAME="Programmable SIP Server Berkeley Database Support - Debugging Symbols" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/carrierroute-pkginfo b/packaging/solaris/carrierroute-pkginfo index aad86a3847a..03eccc8c049 100644 --- a/packaging/solaris/carrierroute-pkginfo +++ b/packaging/solaris/carrierroute-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-carrierroute" NAME="Programmable SIP Server carrierroute Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/identity-pkginfo b/packaging/solaris/identity-pkginfo index c3c95b5c8ba..13f4d2b2486 100644 --- a/packaging/solaris/identity-pkginfo +++ b/packaging/solaris/identity-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-identity" NAME="Programmable SIP Server Identity Module" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/ldap-pkginfo b/packaging/solaris/ldap-pkginfo index 28be9900917..154faaa52fc 100644 --- a/packaging/solaris/ldap-pkginfo +++ b/packaging/solaris/ldap-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-ldap" NAME="Programmable SIP Server LDAP Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/mmgeoip-pkginfo b/packaging/solaris/mmgeoip-pkginfo index af19bed87f4..d0ff6649625 100644 --- a/packaging/solaris/mmgeoip-pkginfo +++ b/packaging/solaris/mmgeoip-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-geoip" NAME="Programmable SIP Server Address Location Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/mysql-pkginfo b/packaging/solaris/mysql-pkginfo index 81279f11dd2..502b968134d 100644 --- a/packaging/solaris/mysql-pkginfo +++ b/packaging/solaris/mysql-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-mysql" NAME="Programmable SIP Server MySQL Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/perl-pkginfo b/packaging/solaris/perl-pkginfo index 3816b05bc42..fa2644e1922 100644 --- a/packaging/solaris/perl-pkginfo +++ b/packaging/solaris/perl-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-perl" NAME="Programmable SIP Server PERL Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/pgsql-pkginfo b/packaging/solaris/pgsql-pkginfo index 66c2ee55031..e9825d6b4d8 100644 --- a/packaging/solaris/pgsql-pkginfo +++ b/packaging/solaris/pgsql-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-pgsql" NAME="Programmable SIP Server PostgreSQL Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/pkginfo b/packaging/solaris/pkginfo index d2199fa6cea..fc0e415a779 100644 --- a/packaging/solaris/pkginfo +++ b/packaging/solaris/pkginfo @@ -1,6 +1,6 @@ PKG=OpenSIPS ARCH=sparc -VERSION="3.6.3" +VERSION="3.6.7" CATEGORY=application EMAIL=bogdan@opensips.org NAME= OpenSIPS is a very fast and flexible SIP (RFC3261) server diff --git a/packaging/solaris/regex-pkginfo b/packaging/solaris/regex-pkginfo index 6132f056d6b..71274f56e16 100644 --- a/packaging/solaris/regex-pkginfo +++ b/packaging/solaris/regex-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-regex" NAME="Programmable SIP Server Regex Module" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/regex-preinstall b/packaging/solaris/regex-preinstall index 38d94c61f6c..79ca6da14c8 100644 --- a/packaging/solaris/regex-preinstall +++ b/packaging/solaris/regex-preinstall @@ -2,7 +2,7 @@ # Script for checking prerequisites for OpenSIPS-xmlrpc BASE="OpenSIPS-base" -LIBPCRE="libpcre.so" +LIBPCRE="libpcre2.so" TMPLIST="/tmp/.opensipspcre" pkginfo | grep -i $BASE > /dev/null diff --git a/packaging/solaris/snmp-pkginfo b/packaging/solaris/snmp-pkginfo index 68c34d10f2c..cfcf9eb521d 100644 --- a/packaging/solaris/snmp-pkginfo +++ b/packaging/solaris/snmp-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-snmp" NAME="Programmable SIP Server SNMP Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/tls-pkginfo b/packaging/solaris/tls-pkginfo index 2e5e0b33af7..93cf1873fc4 100644 --- a/packaging/solaris/tls-pkginfo +++ b/packaging/solaris/tls-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-base-TLS" NAME="Programmable SIP Server Base Install with TLS" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/packaging/solaris/xmlrpc-pkginfo b/packaging/solaris/xmlrpc-pkginfo index 7b5107dcbc4..4aea24b4b12 100644 --- a/packaging/solaris/xmlrpc-pkginfo +++ b/packaging/solaris/xmlrpc-pkginfo @@ -1,11 +1,11 @@ PKG="OpenSIPS-xmlrpc" NAME="Programmable SIP Server MI XMLRPC Support" -VERSION="3.6.3" +VERSION="3.6.7" ARCH="sparc" CLASSES="none" CATEGORY="utility" VENDOR="OpenSIPS Solutions" -PSTAMP="18thDec25" +PSTAMP="17thJun26" EMAIL="saguti@gmail.com" ISTATES="S s 1 2 3" RSTATES="S s 1 2 3" diff --git a/parser/msg_parser.c b/parser/msg_parser.c index 855229f9676..d6a659cb7ac 100644 --- a/parser/msg_parser.c +++ b/parser/msg_parser.c @@ -1236,7 +1236,7 @@ int rewrite_ruri(struct sip_msg *msg, str *sval, int ival, if (crt+len>end) goto error; memcpy(crt,tmp,len);crt+=len; - if (part==RW_RURI_PREFIX) { + if (part==RW_RURI_PREFIX && sval->len) { if (crt+sval->len>end) goto error; memcpy( crt, sval->s, sval->len); crt+=sval->len; diff --git a/parser/parse_body.c b/parser/parse_body.c index f559a938f44..f1e13565284 100644 --- a/parser/parse_body.c +++ b/parser/parse_body.c @@ -130,6 +130,10 @@ static char *find_line_delimiter(char* p, char* plimit, str delimiter) cp1 = l_memmem(cp, delimiterhead, plimit-cp, 2); if (cp1 == NULL) return NULL; + /* ensure enough room for the delimiter match */ + if (plimit - cp1 < 2 + delimiter.len) { + return NULL; + } /* We matched '--', * now let's match the boundary delimiter */ if (strncmp(cp1+2, delimiter.s, delimiter.len) == 0) @@ -141,8 +145,6 @@ static char *find_line_delimiter(char* p, char* plimit, str delimiter) } if (cp1[-1] == '\n' || cp1[-1] == '\r') return cp1; - if (plimit - cp1 < 2 + delimiter.len) - return NULL; cp = cp1 + 2 + delimiter.len; } } diff --git a/parser/sdp/sdp_helpr_funcs.c b/parser/sdp/sdp_helpr_funcs.c index dac1fee966b..7b9fd7f142f 100644 --- a/parser/sdp/sdp_helpr_funcs.c +++ b/parser/sdp/sdp_helpr_funcs.c @@ -329,30 +329,37 @@ int extract_bwidth(str *body, str *bwtype, str *bwwitdth) { char *cp, *cp1; int len; + str bline; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = (char*)l_memmem(cp, "b=", len, 2); - if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') + if (cp1 == NULL || cp1 == body->s || + cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) return -1; - bwtype->s = cp1 + 2; - bwtype->len = eat_line(bwtype->s, body->s + body->len - bwtype->s) - bwtype->s; - trim_len(bwtype->len, bwtype->s, *bwtype); + bline.s = cp1 + 2; + bline.len = eat_line(bline.s, body->s + body->len - bline.s) - bline.s; + trim_len(bline.len, bline.s, bline); - cp = bwtype->s; - len = bwtype->len; + cp = bline.s; + len = bline.len; cp1 = (char*)l_memmem(cp, ":", len, 1); + if (cp1 == NULL) { + LM_ERR("invalid encoding in `b=%.*s'\n", bline.len, bline.s); + return -1; + } len -= cp1 - cp; if (len <= 0) { - LM_ERR("invalid encoding in `b=%.*s'\n", bwtype->len, bwtype->s); + LM_ERR("invalid encoding in `b=%.*s'\n", bline.len, bline.s); return -1; } bwtype->len = cp1 - cp; + bwtype->s = cp; /* skip ':' */ bwwitdth->s = cp1 + 1; @@ -654,4 +661,3 @@ char* get_sdp_hdr_field(char* buf, char* end, struct hdr_field* hdr) hdr->len=tmp-hdr->name.s; return tmp; } - diff --git a/pvar.c b/pvar.c index 73c6b3a1b2d..33b595da892 100644 --- a/pvar.c +++ b/pvar.c @@ -1507,7 +1507,7 @@ static int pv_get_content_type(struct sip_msg *msg, pv_param_t *param, int idx=-1; int idxf=-1; int distance=0; - char buf[BUFLEN]; + static char buf[BUFLEN]; struct sip_msg_body* sbody; struct body_part* body_part; struct body_part* neg_index[2]; @@ -1580,26 +1580,27 @@ static int pv_get_content_type(struct sip_msg *msg, pv_param_t *param, } } else { /* copy main content type */ + if (msg->content_type->body.len >= BUFLEN) { + LM_ERR("Content-Type header too long for pvar buffer (%d >= %d)\n", + msg->content_type->body.len, BUFLEN); + return pv_get_null(msg, param, res); + } memcpy(buf, msg->content_type->body.s, msg->content_type->body.len); - buf[msg->content_type->body.len] = ','; - s.len = msg->content_type->body.len+1; + s.len = msg->content_type->body.len; /* copy all the other contenttypes */ body_part = &sbody->first; while (body_part) { s.s = convert_mime2string_CT(body_part->mime); - if (s.len + strlen(s.s) >= BUFLEN) { + if (1 + s.len + strlen(s.s) >= BUFLEN) { LM_CRIT("buffer overflow! Too many contenttypes!\n"); return pv_get_null(msg, param, res); } + buf[s.len++] = ','; memcpy( buf+s.len, s.s, strlen(s.s)); s.len += strlen(s.s); - /* delimiter only if something follows */ - if(body_part->next) - buf[s.len++] = ','; - body_part = body_part->next; } s.s = buf; @@ -5665,6 +5666,8 @@ void pv_spec_free(pv_spec_t *spec) /* TODO: free name if it is PV */ if(spec->trans) free_transformation((trans_t*)spec->trans); + if ((spec->pvp.pvv_flags & PV_PARAM_PVV_SHM) && spec->pvp.pvv.s) + shm_free(spec->pvp.pvv.s); pkg_free(spec); } diff --git a/pvar.h b/pvar.h index ecdc542f2f2..5b28bb5e4ea 100644 --- a/pvar.h +++ b/pvar.h @@ -59,6 +59,8 @@ #define PV_VAL_PKG 32 #define PV_VAL_SHM 64 +#define PV_PARAM_PVV_SHM 1 + /* @v: a (pv_value_t *) */ #define pvv_is_int(v) \ ((v)->flags & (PV_VAL_INT|PV_TYPE_INT) && \ @@ -178,6 +180,7 @@ typedef struct _pv_param pv_name_t pvn; /*!< PV name */ pv_index_t pvi; /*!< PV index */ str pvv; /*!< PV value buffer */ + int pvv_flags; /*!< ownership flags for pvv */ } pv_param_t, *pv_param_p; typedef int (*pv_getf_t) (struct sip_msg*, pv_param_t*, pv_value_t*); diff --git a/re.c b/re.c index e4cc424afa7..9b93600ac39 100644 --- a/re.c +++ b/re.c @@ -36,6 +36,7 @@ #include "dprint.h" #include "mem/mem.h" +#include "mem/shm_mem.h" #include "re.h" #include @@ -48,10 +49,15 @@ void subst_expr_free(struct subst_expr* se) if (se->replacement.s) pkg_free(se->replacement.s); if (se->re) { regfree(se->re); pkg_free(se->re); }; - for (i = 0; i < se->n_escapes; i++) - if (se->replace[i].type == REPLACE_SPEC - && se->replace[i].u.spec.pvp.pvi.type == PV_IDX_PVAR) - pv_spec_free(se->replace[i].u.spec.pvp.pvi.u.dval); + for (i = 0; i < se->n_escapes; i++) { + if (se->replace[i].type != REPLACE_SPEC) + continue; + if (se->replace[i].u.spec.pvp.pvi.type == PV_IDX_PVAR) + pv_spec_free(se->replace[i].u.spec.pvp.pvi.u.dval); + if ((se->replace[i].u.spec.pvp.pvv_flags & PV_PARAM_PVV_SHM) && + se->replace[i].u.spec.pvp.pvv.s) + shm_free(se->replace[i].u.spec.pvp.pvv.s); + } pkg_free(se); } diff --git a/reactor_proc.c b/reactor_proc.c index 919928268f2..1e62a275173 100644 --- a/reactor_proc.c +++ b/reactor_proc.c @@ -21,6 +21,7 @@ #include "cfg_reload.h" #include "reactor.h" #include "reactor_proc.h" +#include "mem/mem.h" int reactor_proc_init(char *name) @@ -59,12 +60,24 @@ int reactor_proc_add_fd(int fd, reactor_proc_cb_f func, void *param) if (reactor_add_reader( fd, F_GEN_PROC, RCT_PRIO_PROC, cb)<0){ LM_CRIT("failed to add fd to reactor <%s>\n", reactor_name()); + pkg_free(cb); return -1; } return 0; } +int reactor_proc_del_fd(int fd, int idx, int io_flags) +{ + struct fd_map *e; + + e = get_fd_map(&_worker_io, fd); + if (e && e->type == F_GEN_PROC && e->data) { + pkg_free(e->data); + e->data = NULL; + } + return reactor_del_reader(fd, idx, io_flags); +} inline static int handle_io(struct fd_map* fm, int idx,int event_type) { diff --git a/reactor_proc.h b/reactor_proc.h index 682049da9c4..cc71e4c9cc4 100644 --- a/reactor_proc.h +++ b/reactor_proc.h @@ -42,6 +42,11 @@ int reactor_proc_init(char *name); int reactor_proc_add_fd(int fd, reactor_proc_cb_f func, void *param); +/* Remove fd from reactor and free the callback (reactor_proc_cb) allocated by + * reactor_proc_add_fd. Use this instead of reactor_del_reader() for FDs + * that were added with reactor_proc_add_fd() to avoid a PKG memory leak. */ +int reactor_proc_del_fd(int fd, int idx, int io_flags); + int reactor_proc_loop(void); #endif diff --git a/resolve.c b/resolve.c index 01723e45bf0..5b44acfca1e 100644 --- a/resolve.c +++ b/resolve.c @@ -408,6 +408,9 @@ struct hostent* own_gethostbyname2(char *name,int af) struct hostent *cached_he; static union dns_query buff; int min_ttl = INT_MAX; + int cname_chain_depth = 0; + char *query_name; + static char cname_chain_name[DNS_MAX_NAME]; switch (af) { case AF_INET: @@ -439,16 +442,57 @@ struct hostent* own_gethostbyname2(char *name,int af) global_he.h_addrtype=af; global_he.h_length=size; - size=res_search(name, C_IN, type, buff.buff, sizeof(buff)); - if (size < 0) { - LM_DBG("Domain name not found\n"); - if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0) - LM_ERR("Failed to store %s - %d in cache\n",redact_pii(name),af); - return NULL; + query_name = name; + + /* Follow CNAME chain - RFC 1034 recommends max depth of ~8-16 */ + #define MAX_CNAME_CHAIN_DEPTH 10 + + while (cname_chain_depth < MAX_CNAME_CHAIN_DEPTH) { + size=res_search(query_name, C_IN, type, buff.buff, sizeof(buff)); + if (size < 0) { + LM_DBG("Domain name not found: %s\n", query_name); + if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0) + LM_ERR("Failed to store %s - %d in cache\n",redact_pii(name),af); + return NULL; + } + + if (get_dns_answer(&buff,size,query_name,type,&min_ttl) < 0) { + LM_ERR("Failed to get dns answer for %s\n", query_name); + return NULL; + } + + /* Check if we got actual addresses or just a CNAME */ + if (global_he.h_addr_list && global_he.h_addr_list[0] != NULL) { + /* We have addresses, done */ + LM_DBG("Resolved %s to addresses (CNAME chain depth: %d)\n", + name, cname_chain_depth); + break; + } + + /* No addresses - check if we have a CNAME to follow */ + if (global_he.h_name && strcmp(global_he.h_name, query_name) != 0) { + /* We have a CNAME, follow it */ + LM_DBG("Following CNAME: %s -> %s\n", query_name, global_he.h_name); + + /* Copy canonical name for next iteration */ + if (strlen(global_he.h_name) >= DNS_MAX_NAME) { + LM_ERR("CNAME target too long: %s\n", global_he.h_name); + return NULL; + } + strcpy(cname_chain_name, global_he.h_name); + query_name = cname_chain_name; + cname_chain_depth++; + } else { + /* No addresses and no CNAME to follow - this is an error */ + LM_WARN("No addresses and no CNAME for %s\n", query_name); + if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0) + LM_ERR("Failed to store %s - %d in cache\n",redact_pii(name),af); + return NULL; + } } - if (get_dns_answer(&buff,size,name,type,&min_ttl) < 0) { - LM_ERR("Failed to get dns answer\n"); + if (cname_chain_depth >= MAX_CNAME_CHAIN_DEPTH) { + LM_ERR("CNAME chain too deep for %s (depth: %d)\n", name, cname_chain_depth); return NULL; } diff --git a/scripts/build/apt_requirements.txt b/scripts/build/apt_requirements.txt index f094b73e3d2..420860c4c6e 100644 --- a/scripts/build/apt_requirements.txt +++ b/scripts/build/apt_requirements.txt @@ -1,7 +1,7 @@ bison flex libconfuse-dev -libcurl4-gnutls-dev +libcurl4-openssl-dev libdb-dev libexpat1-dev libgeoip-dev @@ -15,7 +15,7 @@ libmicrohttpd-dev libmnl-dev libmysqlclient-dev libncurses5-dev -libpcre3-dev +libpcre2-dev libperl-dev libpq-dev librabbitmq-dev @@ -27,7 +27,7 @@ libxml2-dev make odbcinst patch -python-dev +python3-dev unixodbc unixodbc-dev uuid-dev diff --git a/scripts/build/do_build.sh b/scripts/build/do_build.sh index f64be4cf624..603bfb71306 100755 --- a/scripts/build/do_build.sh +++ b/scripts/build/do_build.sh @@ -15,12 +15,19 @@ fi MAKE_ENV="FASTER=1 NICER=0" MAKE_CMD="${MAKE_ENV} make" +DEFAULT_CC_EXTRA_OPTS="-Werror" + +case "${COMPILER}" in +clang*) + DEFAULT_CC_EXTRA_OPTS="${DEFAULT_CC_EXTRA_OPTS} -Wno-atomic-alignment" + ;; +esac if [ ! -z "${ONE_MODULE}" ] then - env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"-Werror -Wno-atomic-alignment"}" ${MAKE_CMD} \ + env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"${DEFAULT_CC_EXTRA_OPTS}"}" ${MAKE_CMD} \ -C "modules/${ONE_MODULE}" else - env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"-Werror -Wno-atomic-alignment"}" ${MAKE_CMD} \ + env CC_EXTRA_OPTS="${CC_EXTRA_OPTS:-"${DEFAULT_CC_EXTRA_OPTS}"}" ${MAKE_CMD} \ exclude_modules="${EXCLUDE_MODULES}" "${@}" ${MAKE_TGT:-"all"} fi diff --git a/scripts/build/install_depends.sh b/scripts/build/install_depends.sh index a8b04c03279..f600dd040ae 100755 --- a/scripts/build/install_depends.sh +++ b/scripts/build/install_depends.sh @@ -9,7 +9,7 @@ PKGS=$(cat "$(dirname $0)/apt_requirements.txt") _PKGS="" for pkg in ${PKGS} do - if [ "${BUILD_OS}" != "ubuntu:20.04" -a "${BUILD_OS}" != "ubuntu:18.04" -a "${pkg}" = python-dev ] + if [ "${BUILD_OS}" != "ubuntu:18.04" -a "${pkg}" = python3-dev ] then pkg="python-dev-is-python3" fi diff --git a/sdp_ops.c b/sdp_ops.c index 477878fe19c..1032315403c 100644 --- a/sdp_ops.c +++ b/sdp_ops.c @@ -409,6 +409,12 @@ int sdp_ops_parse_lines(struct sdp_body_part_ops *ops, str *body) if (*p != sep || (sep_len == 2 && p < (lim-1) && *(p+1) != '\n')) continue; + if (i >= SDP_MAX_LINES) { + LM_ERR("SDP body exceeds maximum line count (%d)\n", + SDP_MAX_LINES); + return -1; + } + /* lines are stored *without* the ending separator */ ops->lines[i].line.s = start; ops->lines[i].line.len = p - start; @@ -419,6 +425,12 @@ int sdp_ops_parse_lines(struct sdp_body_part_ops *ops, str *body) /* edge-case: the very last SDP line does not include a separator... */ if (start < lim) { + if (i >= SDP_MAX_LINES) { + LM_ERR("SDP body exceeds maximum line count (%d)\n", + SDP_MAX_LINES); + return -1; + } + ops->lines[i].line.s = start; ops->lines[i].line.len = p - start; ops->lines[i++].newbuf = 0; diff --git a/shutdown.c b/shutdown.c index b2a3e9137fc..0f54b97a6d8 100644 --- a/shutdown.c +++ b/shutdown.c @@ -58,9 +58,11 @@ void cleanup(int show_status) #endif handle_ql_shutdown(); + /* TCP conn cleanup may call protocol/module callbacks, so it must run + * before module destroy handlers release module-owned connection state. */ + tcp_destroy(); destroy_modules(); udp_destroy(); - tcp_destroy(); destroy_timer(); if (shm_memlog_size) shm_mem_disable_dbg(); diff --git a/timer.c b/timer.c index ddae89ae3c8..618a1c60bf9 100644 --- a/timer.c +++ b/timer.c @@ -841,7 +841,8 @@ static int fork_dynamic_timer_process(void *si_filter) /* set a more detailed description */ set_proc_attrs("Timer handler"); if (timer_proc_reactor_init() < 0 || - init_child(20000) < 0) { + init_child(20000) < 0 || + self_update_routing_script() < 0) { goto error; } diff --git a/transformations.c b/transformations.c index 7afa6198b55..7e147061091 100644 --- a/transformations.c +++ b/transformations.c @@ -958,7 +958,8 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype, val->flags |= PV_VAL_STR; break; } - if(val->rs.len>TR_BUFFER_SIZE-1) { + if(val->rs.len>TR_BUFFER_SIZE-1 || + calc_base64_encode_len(val->rs.len)>TR_BUFFER_SIZE) { LM_ERR("b64encode value larger than buffer\n"); goto error; }